Detalhe do pedidoOrder detailDetalle del pedido
O pedido inteiro numa tela: cabeçalho do varejo, avisos de bloqueio, status, dados gerais, pagamentos, itens (por categoria), bonificações, totais — e, diferente da lista, as três ações: liberar, editar e cancelar. A leitura é só do cache — a lista já trouxe o pedido. The whole order on one screen: retail header, lock warnings, status, general data, payments, items (by category), free-of-charge lines, totals — and, unlike the list, the three actions: release, edit and cancel. The read is cache-only — the list already fetched the order. El pedido entero en una pantalla: encabezado del punto de venta, avisos de bloqueo, estado, datos generales, pagos, ítems (por categoría), bonificaciones, totales — y, a diferencia de la lista, las tres acciones: liberar, editar y cancelar. La lectura es solo del caché — la lista ya trajo el pedido.
O que é e para que serveWhat it is and what it's forQué es y para qué sirve
O Detalhe do pedido é o que abre quando o representante de vendas toca num card da Lista de pedidos. Mostra tudo o que a lista resume: os itens (agrupados por categoria), as bonificações, os pagamentos e os totais. E acrescenta o que a lista não tem — as ações sobre o pedido. The Order detail is what opens when the sales rep taps a card in the Order list. It shows everything the list summarizes: the items (grouped by category), the free-of-charge lines, the payments and the totals. And it adds what the list doesn't have — the actions on the order. El Detalle del pedido es lo que abre cuando el representante de ventas toca una tarjeta de la Lista de pedidos. Muestra todo lo que la lista resume: los ítems (agrupados por categoría), las bonificaciones, los pagos y los totales. Y agrega lo que la lista no tiene — las acciones sobre el pedido.
O que tem no pedido?What's in the order?¿Qué hay en el pedido?
Itens por categoria, bonificações, pagamentos e a quebra dos totais.Items by category, free-of-charge lines, payments and the totals breakdown.Ítems por categoría, bonificaciones, pagos y el desglose de totales.
Está bloqueado?Is it blocked?¿Está bloqueado?
Se o pedido tem bloqueios (lock), um card de aviso os lista no topo.If the order has locks, a warning card lists them at the top.Si el pedido tiene bloqueos, una tarjeta de aviso los lista arriba.
O que posso fazer?What can I do?¿Qué puedo hacer?
Liberar, editar ou cancelar — quando o pedido permite cada uma.Release, edit or cancel — when the order allows each one.Liberar, editar o cancelar — cuando el pedido permite cada una.
Sem recarregarNo reloadSin recargar A tela lê o pedido do cache local — não vai à rede e não tem "puxar para atualizar". O dado é o que a Lista de pedidos já baixou; por isso abre instantâneo. The screen reads the order from the local cache — it does not hit the network and has no "pull to refresh". The data is what the Order list already downloaded; that's why it opens instantly. La pantalla lee el pedido del caché local — no va a la red y no tiene "deslizar para actualizar". El dato es el que la Lista de pedidos ya descargó; por eso abre al instante.
Como acessarHow to openCómo acceder
- Pela Lista de pedidosFrom the Order listDesde la Lista de pedidosToque em qualquer card na aba Pedidos. É o caminho principal.Tap any card in the Orders tab. This is the main path.Toque cualquier tarjeta en la pestaña Pedidos. Es el camino principal.
- Por outros fluxosFrom other flowsDesde otros flujosQualquer lista de pedidos de um varejo (ex: últimos pedidos no detalhe do PDV) também abre esta tela.Any retail's order list (e.g. last orders in the store detail) also opens this screen.Cualquier lista de pedidos de un punto de venta (ej: últimos pedidos en el detalle del PDV) también abre esta pantalla.
- A tela abreThe screen opensLa pantalla abreCom uma seta de voltar no topo. Rola de cima a baixo; as ações ficam no fim.With a back arrow at the top. It scrolls top to bottom; the actions sit at the end.Con una flecha de volver arriba. Se desplaza de arriba a abajo; las acciones están al final.
Estrutura da telaScreen structureEstructura de la pantalla
Uma coluna rolável, de cima para baixo:A single scrollable column, top to bottom:Una columna desplazable, de arriba a abajo:
- CabeçalhoHeaderEncabezado
- Data da última sincronização, o título "Detalhe do pedido" e o card do varejo (nome + SAP).Last sync date, the "Order detail" title and the retail card (name + SAP).Fecha de última sincronización, el título "Detalle del pedido" y la tarjeta del punto de venta (nombre + SAP).
- Aviso de bloqueioLock warningAviso de bloqueo
- Card com borda de atenção que só aparece se o pedido tem bloqueios; lista cada lock (tipo + mensagem).Attention-bordered card that appears only if the order has locks; lists each lock (type + message).Tarjeta con borde de atención que aparece solo si el pedido tiene bloqueos; lista cada lock (tipo + mensaje).
- Pílulas de número e statusNumber & status pillsPíldoras de número y estado
- Uma pílula com o número/PO do pedido e outra, colorida, com o status.One pill with the order number/PO and another, colored, with the status.Una píldora con el número/PO del pedido y otra, de color, con el estado.
- Dados geraisGeneral dataDatos generales
- Grade de rótulo/valor: número do pedido, PO do varejo, origem, representante, forma de pagamento e nota fiscal.Label/value grid: order number, retail PO, source, rep, payment method and invoice.Grilla de etiqueta/valor: número de pedido, PO del punto de venta, origen, representante, forma de pago y factura.
- PagamentosPaymentsPagos
- Uma linha por parcela (forma · valor · vencimento). Sem parcelas, mostra uma linha com o total e a data de entrega.One row per installment (method · value · due date). With no installments it shows one row with the total and delivery date.Una fila por cuota (forma · valor · vencimiento). Sin cuotas, muestra una fila con el total y la fecha de entrega.
- ItensItemsÍtems
- Os itens pagos, agrupados por categoria: SKU · valor · quantidade + unidade.The paid items, grouped by category: SKU · value · quantity + unit.Los ítems pagos, agrupados por categoría: SKU · valor · cantidad + unidad.
- BonificaçõesFree of chargeBonificaciones
- Seção separada, só quando há itens grátis: SKU · quantidade (sem valor).A separate section, only when there are free items: SKU · quantity (no value).Sección aparte, solo cuando hay ítems gratis: SKU · cantidad (sin valor).
- TotaisTotalsTotales
- Subtotal, desconto, taxa à vista, VAT e o total.Subtotal, discount, cash fee, VAT and the total.Subtotal, descuento, tarifa al contado, VAT y el total.
- AçõesActionsAcciones
- Uma linha com os botões Cancelar, Liberar e Editar — cada um só aparece se o pedido o permite. Some por completo se nenhum é permitido.A row with the Cancel, Release and Edit buttons — each shows only if the order allows it. The whole row disappears if none is allowed.Una fila con los botones Cancelar, Liberar y Editar — cada uno aparece solo si el pedido lo permite. La fila entera desaparece si ninguno está permitido.
Status do pedidoOrder statusEstado del pedido
O status é o mesmo da Lista de pedidos, exibido numa pílula colorida. Cada status pertence a um grupo que define a cor (a lista completa dos 31 status está na seção técnica Enums, idêntica à de Pedidos):The status is the same as in the Order list, shown in a colored pill. Each status belongs to a group that sets the color (the full list of 31 statuses is in the technical Enums section, identical to Orders):El estado es el mismo que en la Lista de pedidos, mostrado en una píldora de color. Cada estado pertenece a un grupo que define el color (la lista completa de 31 estados está en la sección técnica Enums, idéntica a Pedidos):
Idioma do statusStatus languageIdioma del estado O texto do status vem em inglês, direto do backend, e é exibido como está (não é traduzido) — é um código de negócio compartilhado entre times. The status text comes in English, straight from the backend, and is shown as-is (not translated) — it's a shared business code across teams. El texto del estado viene en inglés, directo del backend, y se muestra tal cual (no se traduce) — es un código de negocio compartido entre equipos.
Ações: liberar, editar, cancelarActions: release, edit, cancelAcciones: liberar, editar, cancelar
No fim da tela há até três botões. Qual aparece é decidido pelo backend, não pelo app — o pedido chega marcando o que é permitido. Cada ação pede uma confirmação antes de seguir.At the bottom there are up to three buttons. Which one appears is decided by the backend, not the app — the order arrives flagging what's allowed. Each action asks for a confirmation before proceeding.Al final hay hasta tres botones. Cuál aparece lo decide el backend, no la app — el pedido llega marcando lo que está permitido. Cada acción pide una confirmación antes de seguir.
- LiberarReleaseLiberar
- Envia o pedido para processamento. Antes, o app confere o estoque dos itens pagos (em pedidos prompt, onde o mercado verifica estoque de van); se faltar item demais, a liberação é bloqueada e o motivo aparece no modal.Sends the order for processing. First the app checks the paid items' stock (on prompt orders, where the market checks van stock); if too many items are missing, the release is blocked and the reason shows in the modal.Envía el pedido a procesamiento. Antes, la app verifica el stock de los ítems pagos (en pedidos prompt, donde el mercado verifica stock de van); si falta demasiado ítem, la liberación se bloquea y el motivo aparece en el modal.
- EditarEditEditar
- Reconstrói o carrinho a partir do pedido e abre a vitrine de produtos para alterá-lo. O envio final acontece depois, no fluxo do carrinho (como uma edição).Rebuilds the cart from the order and opens the product showcase to change it. The final submit happens later, in the cart flow (as an edit).Reconstruye el carrito a partir del pedido y abre la vitrina de productos para modificarlo. El envío final ocurre luego, en el flujo del carrito (como una edición).
- CancelarCancelCancelar
- Cancela o pedido. Não há verificação de estoque — só a confirmação.Cancels the order. No stock check — just the confirmation.Cancela el pedido. No hay verificación de stock — solo la confirmación.
- Toque na açãoTap the actionToque la acciónAbre um modal de confirmação, que também lista eventuais problemas de estoque.A confirmation modal opens, which also lists any stock issues.Abre un modal de confirmación, que también lista eventuales problemas de stock.
- ConfirmeConfirmConfirme"Voltar" desiste; "Prosseguir" segue (só existe se a ação é permitida naquele momento)."Come back" backs out; "Proceed" continues (only present if the action is allowed at that moment)."Volver" desiste; "Proseguir" sigue (solo existe si la acción está permitida en ese momento).
- Liberar / CancelarRelease / CancelLiberar / CancelarUm modal de progresso envia o pedido e leva à tela de confirmação. Editar apenas abre a vitrine.A progress modal submits the order and moves to the confirmation screen. Edit just opens the showcase.Un modal de progreso envía el pedido y lleva a la pantalla de confirmación. Editar solo abre la vitrina.
Arquitetura e fluxo de dadosArchitecture & data flowArquitectura y flujo de datos
Clean Architecture + Riverpod + Freezed + ObjectBox. Há dois fluxos distintos: a leitura (só cache) e a escrita (as ações, via Dispatcher).Clean Architecture + Riverpod + Freezed + ObjectBox. There are two distinct flows: the read (cache-only) and the write (the actions, via the Dispatcher).Clean Architecture + Riverpod + Freezed + ObjectBox. Hay dos flujos distintos: la lectura (solo caché) y la escritura (las acciones, vía Dispatcher).
Leitura · só cacheRead · cache-onlyLectura · solo caché
Nenhum RPC é chamado aqui. A Lista de pedidos já buscou e gravou o pedido no ObjectBox; o detalhe só o lê por sfid (getCachedBySfid) e pega o lastSyncAt do container da lista:No RPC is called here. The Order list already fetched and wrote the order to ObjectBox; the detail just reads it by sfid (getCachedBySfid) and takes lastSyncAt from the list container:Ningún RPC se llama aquí. La Lista de pedidos ya buscó y grabó el pedido en ObjectBox; el detalle solo lo lee por sfid (getCachedBySfid) y toma lastSyncAt del contenedor de la lista:
- OrderModelObjectBox · cache
- getOrderBySfidOrderLocalDataSource
- toDomainOrderEntitydomain
- getCachedBySfidGetOrdersUseCase
- build (cache-only)OrderDetailNotifier + State
- → UIOrderDetailPage
- build (cache-only)OrderDetailNotifier + State
- getCachedBySfidGetOrdersUseCase
- toDomainOrderEntitydomain
- getOrderBySfidOrderLocalDataSource
Escrita · ações via DispatcherWrite · actions via DispatcherEscritura · acciones vía Dispatcher
Liberar/cancelar reconstroem o carrinho e enviam pelo Dispatcher (gRPC dedicado). O status da transação é resolvido, o envelope é montado (com o DispatcherType certo) e despachado; splits em paralelo via Future.wait:Release/cancel rebuild the cart and submit through the Dispatcher (dedicated gRPC). The transaction status is resolved, the envelope is built (with the right DispatcherType) and dispatched; splits in parallel via Future.wait:Liberar/cancelar reconstruyen el carrito y envían por el Dispatcher (gRPC dedicado). El estado de la transacción se resuelve, el sobre se arma (con el DispatcherType correcto) y se despacha; splits en paralelo vía Future.wait:
- OrderDetailActionsWidgetUI
- submitActionOrderDetailNotifier
- submitCartOrderSubmissionprovider
- build(input)BuildOrderPlacementDispatcherPayloadUseCase→ DispatcherEnvelope
- submit(envelopes)SubmitOrderUseCase
- dispatchDispatcherOrchestratorgRPC dispatcher
- submit(envelopes)SubmitOrderUseCase
- build(input)BuildOrderPlacementDispatcherPayloadUseCase→ DispatcherEnvelope
- submitCartOrderSubmissionprovider
- submitActionOrderDetailNotifier
Notas de implementaçãoImplementation notesNotas de implementación
O OrderDetailNotifier é family por orderSfid e autoDispose; não tem refresh() nem _load() (o load mora no build()) — a única "recarga" é ref.invalidate no retry de erro da page. O lastSyncAt exibido vem do container da lista (OrdersEntity.lastSyncAt, via getCached()), não do OrderEntity individual. Editar não despacha na hora: reconstrói o carrinho e reabre a vitrine — o envio resolve intent = edit depois (via cart.isEditing).
OrderDetailNotifier is family by orderSfid and autoDispose; it has no refresh() nor _load() (loading lives in build()) — the only "reload" is ref.invalidate on the page's error retry. The displayed lastSyncAt comes from the list container (OrdersEntity.lastSyncAt, via getCached()), not from the individual OrderEntity. Edit doesn't dispatch right away: it rebuilds the cart and reopens the showcase — the submit resolves intent = edit later (via cart.isEditing).
OrderDetailNotifier es family por orderSfid y autoDispose; no tiene refresh() ni _load() (la carga vive en build()) — la única "recarga" es ref.invalidate en el retry de error de la page. El lastSyncAt mostrado viene del contenedor de la lista (OrdersEntity.lastSyncAt, vía getCached()), no del OrderEntity individual. Editar no despacha al instante: reconstruye el carrito y reabre la vitrina — el envío resuelve intent = edit luego (vía cart.isEditing).
Modelo de dadosData modelModelo de datos
O Detalhe reusa o mesmo modelo da Lista de pedidos — a mesma OrderEntity e sub-estruturas, mesmo proto, DTO, Model e mappers. Não há entity OrderDetail própria (§35). O dado existe em quatro representações quase idênticas — Proto (wire gRPC) → DTO (Freezed) → Model (ObjectBox) → Entity (domínio) — ligadas por mappers; os nomes se mantêm e muda muito pouco (enums tipados, datas, relações).Detail reuses the same model as the Order list — the same OrderEntity and sub-structures, same proto, DTO, Model and mappers. There's no dedicated OrderDetail entity (§35). The data exists in four near-identical representations — Proto (gRPC wire) → DTO (Freezed) → Model (ObjectBox) → Entity (domain) — linked by mappers; names stay the same and very little changes (typed enums, dates, relations).El Detalle reutiliza el mismo modelo que la Lista de pedidos — la misma OrderEntity y sub-estructuras, mismo proto, DTO, Model y mappers. No hay entity OrderDetail propia (§35). El dato existe en cuatro representaciones casi idénticas — Proto (wire gRPC) → DTO (Freezed) → Model (ObjectBox) → Entity (dominio) — unidas por mappers; los nombres se mantienen y cambia muy poco (enums tipados, fechas, relaciones).
A diferença do Detalhe é a origem: a leitura é cache-only — o pedido (Order, 52 campos, com pagamentos, itens, bloqueios e nota fiscal aninhados) sai do ObjectBox que a Lista já populou, sem chamar RPC. Os enums só existem tipados na Entity; em Proto/DTO/Model trafegam como String. A seguir, na ordem: o proto de origem, as estruturas de dados campo-a-campo por camada, e os mappers.Detail's difference is the origin: the read is cache-only — the order (Order, 52 fields, with nested payments, items, locks and invoice) comes from the ObjectBox the list already populated, no RPC call. Enums are only typed in the Entity; in Proto/DTO/Model they travel as String. Next, in order: the origin proto, the field-by-field data structures per layer, and the mappers.La diferencia del Detalle es el origen: la lectura es cache-only — el pedido (Order, 52 campos, con pagos, ítems, bloqueos y factura anidados) sale del ObjectBox que la Lista ya pobló, sin llamar RPC. Los enums solo están tipados en la Entity; en Proto/DTO/Model viajan como String. A continuación, en orden: el proto de origen, las estructuras de datos campo a campo por capa, y los mappers.
Proto
O modelo do Detalhe vem do proto da Lista — OrderConectaRep.proto · proto3 · package mn.bat.conectarep.streambridge. O Detalhe não chama esse método; lê o resultado do cache. A escrita (liberar/editar/cancelar) sai pelo Dispatcher (ver UseCases).Detail's model comes from the list's proto — OrderConectaRep.proto · proto3 · package mn.bat.conectarep.streambridge. Detail doesn't call this method; it reads the result from cache. Writes (release/edit/cancel) go out through the Dispatcher (see UseCases).El modelo del Detalle viene del proto de la Lista — OrderConectaRep.proto · proto3 · package mn.bat.conectarep.streambridge. El Detalle no llama este método; lee el resultado del caché. La escritura (liberar/editar/cancelar) sale por el Dispatcher (ver UseCases).
getOrderListunary · origem (cache)unary · origin (cache)unary · origen (caché)rpc getOrderList(OrderRequest) returns (OrderReply)
path /mn.bat.conectarep.streambridge.OrderConectaRepService/getOrderList
OrderRequestlocationHierarchySfidstring· #1 · hierarquia do representante de vendassales rep hierarchyjerarquía del representante de ventasdateReferencestring· #2 · optionallastModifiedDatestring· #3 · optional (não usado hoje)optional (not used today)optional (no usado hoy)
OrderReplyrepeated Order orderList — a lista de pedidos. O Detalhe pega um Order por sfid do cache; os 52 campos estão nas Estruturas de dados abaixo.the list of orders. Detail pulls one Order by sfid from cache; the 52 fields are in Data structures below.la lista de pedidos. El Detalle toma un Order por sfid del caché; los 52 campos están en Estructuras de datos abajo.
Estruturas de dadosData structuresEstructuras de datos
Um dropdown por estrutura, aninhados pela hierarquia (as linhas ligam pai e filhos). Cada tabela tem uma coluna por camada — Proto · DTO · Model · Entity; as células com borda marcam onde o tipo primeiro muda (relação ToMany/ToOne no Model, enum na Entity, rename no Proto). ¹ = optional no proto.One dropdown per structure, nested by hierarchy (lines link parent and children). Each table has one column per layer — Proto · DTO · Model · Entity; bordered cells mark where the type first changes (ToMany/ToOne relation in the Model, enum in the Entity, rename in the Proto). ¹ = optional in the proto.Un dropdown por estructura, anidados por jerarquía (las líneas unen padre e hijos). Cada tabla tiene una columna por capa — Proto · DTO · Model · Entity; las celdas con borde marcan dónde primero cambia el tipo (relación ToMany/ToOne en el Model, enum en la Entity, rename en el Proto). ¹ = optional en el proto.
Order raiz 52 campos
Campo Proto DTO Model Entity sfidstring String String String namestring String String String purchaseOrderNumberstring String String String retailerPoNumberstring String String String visitIdstring String String String filtersrepeated OrderFilterInfo List<…DTO> ToMany<…Model>List<…Entity> orderStatusstring String String OrderStatusdeliveryStatusstring String String String orderDatestring String String String deliveryDatestring String String String createdAtstring String String String lastModifiedAtstring String String String orderTypestring String String String orderSourcestring String String OrderSourceorderResourceTypestring String String ResourceTyperesourceNamestring String String String accountNamestring String String String accountSapIdstring String String String accountSfidstring String String String isTelesalesbool bool bool bool subtotaldouble double double double discountdouble double double double creditNotedouble double double double cashFeedouble¹ double? double? double? vatdouble¹ double? double? double? totaldouble double double double volumestring String String String volumeUnitstring String String String paymentMethodstring String String PaymentMode?creditDaysstring String String String paymentsrepeated OrderPayment List<…DTO> ToMany<…Model>List<…Entity> pixStatusstring String String String pixKeystring String String String pixQrCodestring String String String hasLocksbool bool bool bool locksrepeated OrderLock List<…DTO> ToMany<…Model>List<…Entity> isErrorbool bool bool bool errorMessagestring String? String? String? rejectionReasonstring String? String? String? lineItemsrepeated OrderLineItem List<…DTO> ToMany<…Model>List<…Entity> isPromptOrderbool¹ bool? bool? bool? isPromptFulfillmentbool¹ bool? bool? bool? canCancelbool bool bool bool canEditbool bool bool bool canReleasebool bool bool bool canCheckStatusbool bool bool bool canPrintInvoicebool¹ bool? bool? bool? canPrintBankSlipcanPrintBoleto¹bool? bool? bool? canGenerateInvoicePdfbool¹ bool? bool? bool? canTerminateVisitbool¹ bool? bool? bool? canSendToExternalApprovalbool¹ bool? bool? bool? invoiceoptional¹ OrderInvoice …DTO? ToOne<…Model>…Entity? OrderPayment Order.payments[] 6 campos
Campo Proto DTO Model Entity sfidstring String String String sequencestring String String String statusstring String String String valuedouble double double double dueDatestring String DateTime?DateTime? paymentMethodstring String String PaymentMode?OrderLineItem Order.lineItems[] · = InvoiceLineItem 9 campos
Campo Proto DTO Model Entity sfidstring String String String categorystring String String String skustring String String String unitstring String String String productTradeSKUstring String String String productManufacturingSKUstring String String String valuedouble double? double? double? qtyint32 int int int isFreeOfChargebool bool bool bool OrderLock Order.locks[] 4 campos
Campo Proto DTO Model Entity typestring String String OrderLockTypemessagestring String? String? String? productsrepeated LockProduct List<…DTO> ToMany<…Model>List<…Entity> categoriesrepeated LockCategory List<…DTO> ToMany<…Model>List<…Entity> LockProduct OrderLock.products[] 5 campos
Campo Proto DTO Model Entity skustring String String String targetdouble double double double requesteddouble double double double minimumGoaldouble double double double missingdouble double double double LockCategory OrderLock.categories[] 3 campos
Campo Proto DTO Model Entity categorystring String String String valuedouble double double double minimumdouble double double double
OrderInvoice Order.invoice 13 campos
Campo Proto DTO Model Entity sfidstring String String String invoiceNumberstring String String String invoiceStatusstring String String String invoiceDatestring String String String legalNumberstring String? String? String? subtotaldouble double double double discountdouble double double double creditNoteValuedouble double double double totaldouble double double double isVisitDeliverybool bool? bool? bool? isPickListedbool bool? bool? bool? lineItemsrepeated InvoiceLineItem List<…DTO> ToMany<…Model>List<…Entity> printingDataPrintingData¹— — — InvoiceLineItem OrderInvoice.lineItems[] 9 campos
Campo Proto DTO Model Entity sfidstring String String String categorystring String String String skustring String String String unitstring String String String productTradeSKUstring String String String productManufacturingSKUstring String String String valuedouble double? double? double? qtyint32 int int int isFreeOfChargebool bool bool bool
OrderFilterInfo Order.filters[] 2 campos
Campo Proto DTO Model Entity filterNamestring String String String valuestring String String String
Mappers
As conversões são as mesmas de Pedidos, todas como extension (5 direções por tipo). O Detalhe usa só a direção Model → Entity na leitura (cache) — as outras rodam no fetch da lista.The conversions are the same as Orders, all as extensions (5 directions per type). Detail uses only the Model → Entity direction on read (cache) — the others run in the list fetch.Las conversiones son las mismas que Pedidos, todas como extension (5 direcciones por tipo). El Detalle usa solo la dirección Model → Entity en la lectura (caché) — las otras corren en el fetch de la lista.
| DireçãoDirectionDirección | MétodoMethodMétodo |
|---|---|
| JSON → DTO | static fromMap(Map) |
| Proto → DTO | toDTO() |
| DTO → Entity | toDomain() (resolve enums: fromString/fromCode)(resolves enums: fromString/fromCode)(resuelve enums: fromString/fromCode) |
| Entity → Model | toModel() (enums → .value/.code; popula ToMany/ToOne)(enums → .value/.code; fills relations)(enums → .value/.code; llena relaciones) |
| Model → Entity | toDomain() ← usada pelo Detalhe← used by Detail← usada por el Detalle |
Os únicos deltasThe only deltasLos únicos deltas
- enums tipados só na Entity (
Stringnas outras)enums typed only in the Entity (Stringelsewhere)enums tipados solo en la Entity (Stringen las demás) dueDateString→DateTime?(no Model, viaDateTimeUtils.tryParse)(in the Model, viaDateTimeUtils.tryParse)(en el Model, víaDateTimeUtils.tryParse)- renamerenamerename
canPrintBoleto→canPrintBankSlip(no Proto)(in the Proto)(en el Proto) OrderInvoice.printingDatadescartado do DTO em diantedropped from the DTO onwarddescartado del DTO en adelante- relações viram
ToMany/ToOneno Modelrelations becomeToMany/ToOnein the Modelrelaciones pasan aToMany/ToOneen el Model lastSyncAtgerado no mapper comDateTimeUtils.now()generated in the mapper withDateTimeUtils.now()generado en el mapper conDateTimeUtils.now()
Repository
O Detalhe consome o mesmo OrderRepositoryImpl da lista, mas usa só o caminho cache-only. A escrita das ações não passa por este repository — vai pelo Dispatcher (ver UseCases).Detail consumes the same OrderRepositoryImpl as the list, but only the cache-only path. Action writes do not go through this repository — they go via the Dispatcher (see UseCases).El Detalle consume el mismo OrderRepositoryImpl de la lista, pero solo el camino cache-only. La escritura de las acciones no pasa por este repository — va por el Dispatcher (ver UseCases).
Um dropdown por método — assinatura, retorno e comportamento. O Detalhe usa só estes dois.One dropdown per method — signature, return and behavior. Detail uses only these two.Un dropdown por método — firma, retorno y comportamiento. El Detalle usa solo estos dos.
getCachedOrderBySfid({orderSfid}) local
RetornaReturnsDevuelve Result<OrderEntity, Failure>
Fonte do Detalhe. Só cache: delega a OrderLocalDataSource.getOrderBySfid; ausente → Error(CacheFailure). Nunca dispara remoto (§28 cat. A).Detail's source. Cache only: delegates to OrderLocalDataSource.getOrderBySfid; missing → Error(CacheFailure). Never triggers remote (§28 cat. A).Fuente del Detalle. Solo caché: delega a OrderLocalDataSource.getOrderBySfid; ausente → Error(CacheFailure). Nunca dispara remoto (§28 cat. A).
getCachedOrders() local
RetornaReturnsDevuelve Result<OrdersEntity?, Failure>
O container da lista, usado só para o lastSyncAt exibido no cabeçalho.The list container, used only for the lastSyncAt shown in the header.El container de la lista, usado solo para el lastSyncAt del encabezado.
Demais métodosOther methodsDemás métodosO OrderRepositoryImpl tem ainda getOrders, getCachedOrdersLastSyncAt, saveOrders, getOrdersForAccount etc. — descritos em Pedidos → Repository. O Detalhe não os usa.OrderRepositoryImpl also has getOrders, getCachedOrdersLastSyncAt, saveOrders, getOrdersForAccount etc. — described in Orders → Repository. Detail doesn't use them.OrderRepositoryImpl también tiene getOrders, getCachedOrdersLastSyncAt, saveOrders, getOrdersForAccount etc. — descritos en Pedidos → Repository. El Detalle no los usa.
Datasources
Para a leitura, o Detalhe toca só o datasource local. Não há datasource remoto nem mock de "um pedido" — o pedido único sai do box que a lista já populou.For the read, Detail touches only the local datasource. There's no remote nor mock "single order" datasource — the single order comes from the box the list already populated.Para la lectura, el Detalle toca solo el datasource local. No hay datasource remoto ni mock de "un pedido" — el pedido único sale del box que la lista ya pobló.
Local OrderLocalDataSource ObjectBox
Envio / fluxo: leitura local via ObjectBox (boxes OrdersModel/OrderModel) — sem rede; a lista já populou o box. Erro: no repository, ausência do pedido vira Error(CacheFailure); falhas de persistência propagam como exceção.Sends / flow: local read via ObjectBox (OrdersModel/OrderModel boxes) — no network; the list already populated the box. Error: in the repository, a missing order becomes Error(CacheFailure); persistence failures propagate as exceptions.Envío / flujo: lectura local vía ObjectBox (boxes OrdersModel/OrderModel) — sin red; la lista ya pobló el box. Error: en el repository, la ausencia del pedido es Error(CacheFailure); fallos de persistencia propagan como excepción.
getOrderBySfid({orderSfid})
- RetornoReturnRetorno
OrderEntity?- ComportamentoBehaviorComportamiento
- busca linear em
_orderBox.getAll()pelosfid. É o método que alimenta o Detalhe.linear search over_orderBox.getAll()bysfid. This is the method feeding Detail.búsqueda lineal en_orderBox.getAll()porsfid. Es el método que alimenta el Detalle.
getOrders()
- RetornoReturnRetorno
OrdersEntity?- ComportamentoBehaviorComportamiento
- o agregado único (
models.first.toDomain()), só para olastSyncAtdo container.the single aggregate (models.first.toDomain()), only for the containerlastSyncAt.el agregado único (models.first.toDomain()), solo para ellastSyncAtdel container.
Enums e labelsEnums & labelsEnums y labels
O Detalhe compartilha os enums de dado com Pedidos (OrderStatus, OrderStatusGroup, OrderLockType, PaymentMode) e adiciona os enums do fluxo de ação/transação (OrderSubmitIntent, OrderTransactionStatus, DispatcherType de pedido).Detail shares the data enums with Orders (OrderStatus, OrderStatusGroup, OrderLockType, PaymentMode) and adds the action/transaction flow enums (OrderSubmitIntent, OrderTransactionStatus, order DispatcherType).El Detalle comparte los enums de dato con Pedidos (OrderStatus, OrderStatusGroup, OrderLockType, PaymentMode) y agrega los enums del flujo de acción/transacción (OrderSubmitIntent, OrderTransactionStatus, DispatcherType de pedido).
OrderStatus 31 valores + grupo31 values + group31 valores + grupo
| case | value | group |
|---|---|---|
rejected | "Rejected" | rejected |
cancelled | "Cancelled" | rejected |
invalid | "Invalid" | rejected |
terminated | "Terminated" | rejected |
customerBlockedForOrder | "Customer is Blocked for Order" | rejected |
creditOverdueFailed | "Credit/ Overdue Failed" | rejected |
externalApprovalFailed | "External Approval Failed" | rejected |
rejectedBy3pl | "Rejected by 3PL" | rejected |
rejectedBySap | "Rejected by SAP" | rejected |
cancelledNotSync | "Cancelled Not Sync" | rejected |
partiallyFulfilled | "Partially Fulfilled" | rejected |
pendingApproval | "Pending Approval" | pending |
pendingExternalApproval | "Pending External Approval" | pending |
draft | "Draft" | pending |
replenishment | "Replenishment" | pending |
pendingRepApproval | "Pending Rep Approval" | pending |
approved | "Approved" | pending |
approvedNotSync | "Approved Not Sync" | pending |
awaitingPixPayment | "Awaiting Pix Payment" | pending |
ordered | "Ordered" | ordered |
invoiced | "Invoiced" | ordered |
onHold | "On-Hold" | ordered |
confirmedBySap | "Confirmed by SAP" | ordered |
released | "Released" | ordered |
promptFulfillment | "Prompt Fulfillment" | ordered |
onHoldForLpConversion | "On-Hold for LP Conversion" | ordered |
confirmedBy3pl | "Confirmed by 3PL" | ordered |
deliveredBy3pl | "Delivered by 3PL" | ordered |
paymentConfirmedBy3pl | "Payment Confirmed by 3PL" | ordered |
invoicedNotSync | "Invoiced Not Sync" | ordered |
unknown | "Unknown" | unknown |
OrderStatusGroup → cor 4
| group | cor |
|---|---|
pending | warning |
rejected | error |
ordered | success |
unknown | onSurfaceTertiary |
OrderSubmitIntent 4 · a açãothe actionla acción
| case | significadomeaningsignificado |
|---|---|
create | novo pedido (fluxo de carrinho, não o Detalhe)new order (cart flow, not Detail)nuevo pedido (flujo de carrito, no el Detalle) |
edit | reabre a vitrine com o carrinho reconstruído (isCreation=false)reopens the showcase with the rebuilt cart (isCreation=false)reabre la vitrina con el carrito reconstruido (isCreation=false) |
release | libera para processamento (com checagem de estoque)releases for processing (with stock check)libera a procesamiento (con verificación de stock) |
cancel | cancela (isCancellation=true)cancels (isCancellation=true)cancela (isCancellation=true) |
OrderTransactionStatus 7 · status resolvido no enviostatus resolved on submitestado resuelto al enviar
| case | value |
|---|---|
cancelled | "Cancelled" |
awaitingPixPayment | "Awaiting Pix Payment" |
pendingApproval | "PA" |
pendingExternalApproval | "Pending External Approval" |
invoiced | "Invoiced" |
invoicedNotSync | "Invoiced Not Sync" |
onHold | "On-Hold" |
DispatcherType · pedido 4 · serviceName + mercadosmarketsmercados
| case | serviceName | mercadosmarketsmercados | propósitopurposepropósito |
|---|---|---|---|
order | MobileorderAPI | BR · CL · ZA | pedido direto padrão (place/edit/release/cancel)standard direct order (place/edit/release/cancel)pedido directo estándar (place/edit/release/cancel) |
orderIndirect | IndirectOrderAPI | ZA | pedido indireto (distribuidor)indirect (distributor) orderpedido indirecto (distribuidor) |
orderApproval | OrderApprovalUploadAPI | BR · CL · ZA | pedido roteado para aprovaçãoorder routed to approvalpedido enrutado a aprobación |
orderInvoice | Invoiceupload | BR · CL | upload de nota (fora do builder de placement)invoice upload (outside the placement builder)upload de factura (fuera del builder de placement) |
OrderLockType · PaymentMode compartilhados com Pedidosshared with Orderscompartidos con Pedidos
OrderLockType (12 · traduzido) e PaymentMode (13 · code ZG/ZH/ZX…) são idênticos aos de Pedidos — lista completa em Pedidos → Enums. No Detalhe: OrderLockType.label(context:) rotula cada bloqueio no card de aviso; PaymentMode.label(context:) rotula a forma de pagamento na grade e nas parcelas.OrderLockType (12 · translated) and PaymentMode (13 · code ZG/ZH/ZX…) are identical to Orders — full list in Orders → Enums. In Detail: OrderLockType.label(context:) labels each lock in the warning card; PaymentMode.label(context:) labels the payment method in the grid and installments.OrderLockType (12 · traducido) y PaymentMode (13 · code ZG/ZH/ZX…) son idénticos a Pedidos — lista completa en Pedidos → Enums. En el Detalle: OrderLockType.label(context:) etiqueta cada bloqueo en la tarjeta de aviso; PaymentMode.label(context:) etiqueta la forma de pago en la grilla y las cuotas.
UseCases
Um dropdown por UseCase; dentro, cada método com assinatura, o que retorna e uso.One dropdown per UseCase; inside, each method with its signature, what it returns and use.Un dropdown por UseCase; dentro, cada método con su firma, qué devuelve y uso.
LeituraReadLectura
GetOrdersUseCase 2 · usados pelo Detalhe2 · used by Detail2 · usados por el Detalle
| MétodoMethodMétodo | RetornaReturnsDevuelve | UsoUseUso |
|---|---|---|
getCachedBySfid({orderSfid}) | Result<OrderEntity, Failure> | Fonte do Detalhe. Cache-only → repository.getCachedOrderBySfid (ausente → Error(CacheFailure)). Método na própria classe do agregado (§28 cat. A). Alimenta o build().Detail's source. Cache-only → repository.getCachedOrderBySfid (missing → Error(CacheFailure)). Method on the aggregate class itself (§28 cat. A). Feeds build().Fuente del Detalle. Cache-only → repository.getCachedOrderBySfid (ausente → Error(CacheFailure)). Método en la propia clase del agregado (§28 cat. A). Alimenta el build(). |
getCached() | Result<OrdersEntity?, Failure> | Container da lista, usado só para o lastSyncAt exibido no cabeçalho.The list container, used only for the lastSyncAt shown in the header.El container de la lista, usado solo para el lastSyncAt del encabezado. |
Os demais métodos do GetOrdersUseCase (execute, getCachedLastSyncAt) são da lista — ver Pedidos → UseCases.The other GetOrdersUseCase methods (execute, getCachedLastSyncAt) belong to the list — see Orders → UseCases.Los demás métodos de GetOrdersUseCase (execute, getCachedLastSyncAt) son de la lista — ver Pedidos → UseCases.
Ações (escrita)Actions (write)Acciones (escritura)
DetectOrderActionStockIssuesUseCase 1 · domíniodomaindominio
| MétodoMethodMétodo | RetornaReturnsDevuelve | UsoUseUso |
|---|---|---|
execute({order, products, availableStockByProductSfid, checkVanStock}) | List<OrderActionStockIssueEntity> | Usado por prepareAction em release/edit: detecta itens pagos faltantes ou com estoque ajustado. Puro domínio.Used by prepareAction on release/edit: detects missing paid items or adjusted stock. Pure domain.Usado por prepareAction en release/edit: detecta ítems pagos faltantes o con stock ajustado. Puro dominio. |
ResolveOrderTransactionStatusUseCase 1 · domíniodomaindominio
| MétodoMethodMétodo | RetornaReturnsDevuelve | UsoUseUso |
|---|---|---|
execute({cart, intent, context, isPixPrePayment, sendToPendingApproval}) | OrderTransactionStatus | Resolve o status que vai como "Status" no header do payload. Ordem: cancelamento → cancelled; pix pré-pago → awaitingPixPayment; pending approval (não indireto) → pendingApproval; prompt → pendingExternalApproval/invoicedNotSync; senão → onHold.Resolves the status sent as "Status" in the payload header. Order: cancellation → cancelled; prepaid pix → awaitingPixPayment; pending approval (non-indirect) → pendingApproval; prompt → pendingExternalApproval/invoicedNotSync; else → onHold.Resuelve el estado enviado como "Status" en el header del payload. Orden: cancelación → cancelled; pix prepago → awaitingPixPayment; pending approval (no indirecto) → pendingApproval; prompt → pendingExternalApproval/invoicedNotSync; si no → onHold. |
BuildOrderPlacementDispatcherPayloadUseCase 1 · builder
| MétodoMethodMétodo | RetornaReturnsDevuelve | UsoUseUso |
|---|---|---|
build({input: OrderPlacementDispatcherPayloadInput}) | DispatcherEnvelope | Um único builder para todas as transações (place/edit/release/cancel), implements DispatcherPayloadBuilder (§36). Input com entities cruas (cart, totals, context, resource, intent…). _resolveType: indireto → orderIndirect; pending approval → orderApproval; senão → order. Monta OrderHeader/OrderDetail/OrderPaymentInstruction/promos.A single builder for all transactions (place/edit/release/cancel), implements DispatcherPayloadBuilder (§36). Input carries raw entities (cart, totals, context, resource, intent…). _resolveType: indirect → orderIndirect; pending approval → orderApproval; else → order. Builds OrderHeader/OrderDetail/OrderPaymentInstruction/promos.Un único builder para todas las transacciones (place/edit/release/cancel), implements DispatcherPayloadBuilder (§36). Input con entities crudas (cart, totals, context, resource, intent…). _resolveType: indirecto → orderIndirect; pending approval → orderApproval; si no → order. Arma OrderHeader/OrderDetail/OrderPaymentInstruction/promos. |
SubmitOrderUseCase 1 · transportetransporttransporte
| MétodoMethodMétodo | RetornaReturnsDevuelve | UsoUseUso |
|---|---|---|
submit({envelopes}) | List<Result<DispatcherAck, Failure>> | Delegate de transporte fino: mapeia cada envelope para DispatcherOrchestrator.dispatch via Future.wait (um Result por envelope). Não decide DispatcherType (isso é do builder).Thin transport delegate: maps each envelope to DispatcherOrchestrator.dispatch via Future.wait (one Result per envelope). Doesn't decide DispatcherType (the builder does).Delegate de transporte fino: mapea cada envelope a DispatcherOrchestrator.dispatch vía Future.wait (un Result por envelope). No decide DispatcherType (eso es del builder). |
Onde a ação é orquestradaWhere the action is orchestratedDónde se orquesta la acciónQuem costura status → builder → submit é o OrderSubmission (provider orderSubmissionProvider, family por accountSfid), em presentation/shared/providers/order/ — cross-page (§33). O Detalhe chama submitCart(intent:, cart:); a tela de confirmação de carrinho chama submit(). Ambos caem no mesmo _submitResolved, que envia splits em paralelo.The one stitching status → builder → submit is OrderSubmission (provider orderSubmissionProvider, family by accountSfid), in presentation/shared/providers/order/ — cross-page (§33). Detail calls submitCart(intent:, cart:); the cart confirmation screen calls submit(). Both land in the same _submitResolved, which sends splits in parallel.Quien cose status → builder → submit es OrderSubmission (provider orderSubmissionProvider, family por accountSfid), en presentation/shared/providers/order/ — cross-page (§33). El Detalle llama submitCart(intent:, cart:); la pantalla de confirmación de carrito llama submit(). Ambos caen en el mismo _submitResolved, que envía splits en paralelo.
Notifier & State
O OrderDetailNotifier (@riverpod, family por orderSfid, autoDispose) é o cérebro da tela de detalhe. O build() monta o State a partir do cache (não há refresh()/_load() — a "recarga" é ref.invalidate no retry de erro da page). O State (OrderDetailState, Freezed) é a fonte única de verdade: guarda o pedido e o lastSyncAt, e expõe getters que particionam/agrupam os itens. Os demais métodos preparam e disparam as ações (liberar/editar/cancelar).The OrderDetailNotifier (@riverpod, family by orderSfid, autoDispose) is the detail screen's brain. build() assembles the State from cache (there's no refresh()/_load() — the "reload" is ref.invalidate on the page's error retry). The State (OrderDetailState, Freezed) is the single source of truth: it holds the order and lastSyncAt, and exposes getters that partition/group the items. The other methods prepare and fire the actions (release/edit/cancel).El OrderDetailNotifier (@riverpod, family por orderSfid, autoDispose) es el cerebro de la pantalla de detalle. build() arma el State desde el caché (no hay refresh()/_load() — la "recarga" es ref.invalidate en el retry de error de la page). El State (OrderDetailState, Freezed) es la fuente única de verdad: guarda el pedido y el lastSyncAt, y expone getters que particionan/agrupan los ítems. Los demás métodos preparan y disparan las acciones (liberar/editar/cancelar).
MétodosMethodsMétodos
build({orderSfid}) cache-only
RetornoReturnRetorno FutureOr<OrderDetailState>
Busca em paralelo o pedido por sfid (getCachedBySfid) e o container da lista (getCached(), só para o lastSyncAt). Lança BusinessFailure(orderDetailNotFound) se o sfid vier vazio, e retorna OrderDetailState(order, lastSyncAt). Cache-only — nunca dispara remoto.Fetches in parallel the order by sfid (getCachedBySfid) and the list container (getCached(), only for lastSyncAt). Throws BusinessFailure(orderDetailNotFound) if the sfid is empty, and returns OrderDetailState(order, lastSyncAt). Cache-only — never triggers remote.Busca en paralelo el pedido por sfid (getCachedBySfid) y el container de la lista (getCached(), solo para el lastSyncAt). Lanza BusinessFailure(orderDetailNotFound) si el sfid viene vacío, y retorna OrderDetailState(order, lastSyncAt). Cache-only — nunca dispara remoto.
prepareAction({intent})
RetornoReturnRetorno Future<OrderActionPreparationEntity>
Resolve accountSfid/visitSfid. Em cancel retorna canProceed: true sem checar estoque; em release/edit roda a checagem de estoque (estoque de van, se pedido prompt e o mercado exige) e calcula canProceed — só release pode ser bloqueado. Alimenta o modal de confirmação.Resolves accountSfid/visitSfid. On cancel returns canProceed: true without a stock check; on release/edit runs the stock check (van stock, if a prompt order and the market requires it) and computes canProceed — only release can be blocked. Feeds the confirmation modal.Resuelve accountSfid/visitSfid. En cancel retorna canProceed: true sin verificar stock; en release/edit corre la verificación de stock (stock de van, si pedido prompt y el mercado lo exige) y calcula canProceed — solo release puede bloquearse. Alimenta el modal de confirmación.
reconstructForEdit()
RetornoReturnRetorno Future<void>
Reconstrói o carrinho a partir do pedido (CartOrchestrator.reconstructFromOrder) para o fluxo de edição, antes de reabrir a vitrine de produtos.Rebuilds the cart from the order (CartOrchestrator.reconstructFromOrder) for the edit flow, before reopening the product showcase.Reconstruye el carrito a partir del pedido (CartOrchestrator.reconstructFromOrder) para el flujo de edición, antes de reabrir la vitrina de productos.
submitAction({intent})
RetornoReturnRetorno Future<void>
Reconstrói o carrinho e delega ao orderSubmissionProvider(accountSfid).submitCart(intent:, cart:) — o disparo real de release/cancel pelo Dispatcher (ver UseCases).Rebuilds the cart and delegates to orderSubmissionProvider(accountSfid).submitCart(intent:, cart:) — the actual release/cancel dispatch via the Dispatcher (see UseCases).Reconstruye el carrito y delega a orderSubmissionProvider(accountSfid).submitCart(intent:, cart:) — el disparo real de release/cancel por el Dispatcher (ver UseCases).
State disponível para a PageState available to the PageState disponible para la Page
OrderDetailState campos + gettersfields + getterscampos + getters
| campo | tipo | default |
|---|---|---|
order | OrderEntity | required |
lastSyncAt | DateTime? | null |
Getters: paidLineItems / freeOfChargeLineItems (partição por isFreeOfCharge), hasPaidItems, hasFreeOfChargeItems, paidItemGroups (agrupa itens pagos por CategoryGroup), displayPoRetail (PO do varejo ou "-"), displayInvoiceNumber (nº da nota ou "-").Getters: paidLineItems / freeOfChargeLineItems (partition by isFreeOfCharge), hasPaidItems, hasFreeOfChargeItems, paidItemGroups (groups paid items by CategoryGroup), displayPoRetail (retail PO or "-"), displayInvoiceNumber (invoice no. or "-").Getters: paidLineItems / freeOfChargeLineItems (partición por isFreeOfCharge), hasPaidItems, hasFreeOfChargeItems, paidItemGroups (agrupa ítems pagos por CategoryGroup), displayPoRetail (PO del punto de venta o "-"), displayInvoiceNumber (nº de factura o "-").
Categoria por índiceCategory by indexCategoría por índiceHoje paidItemGroups atribui a CategoryGroup pelo índice do item na lista (0→fmc, 1→nc, 2-4→otp…), não pela categoria real do lineItem — lógica placeholder a revisar quando o backend enviar a categoria confiável.Today paidItemGroups assigns the CategoryGroup by the item's list index (0→fmc, 1→nc, 2-4→otp…), not by the lineItem's real category — placeholder logic to revisit once the backend sends a reliable category.Hoy paidItemGroups asigna el CategoryGroup por el índice del ítem en la lista (0→fmc, 1→nc, 2-4→otp…), no por la categoría real del lineItem — lógica placeholder a revisar cuando el backend envíe la categoría confiable.
Page e widgetsPage & widgetsPage y widgets
A OrderDetailPage (ConsumerWidget) recebe só o orderSfid (§17), observa orderDetailProvider(orderSfid:) e monta os widgets numa coluna rolável. Loading e erro são globais (detailAsync.when); erro → FailureStateView com retry via ref.invalidate. Cada widget de seção decide sozinho se aparece (§27). Árvore de composição:OrderDetailPage (ConsumerWidget) takes only orderSfid (§17), watches orderDetailProvider(orderSfid:) and composes the widgets in a scrollable column. Loading and error are global (detailAsync.when); error → FailureStateView with retry via ref.invalidate. Each section widget decides its own visibility (§27). Composition tree:OrderDetailPage (ConsumerWidget) recibe solo orderSfid (§17), observa orderDetailProvider(orderSfid:) y compone los widgets en una columna desplazable. Loading y error son globales (detailAsync.when); error → FailureStateView con retry vía ref.invalidate. Cada widget de sección decide su propia visibilidad (§27). Árbol de composición:
- OrderDetailPage
- AppPageShell displayBackButton
- CustomLoadingIndicator loading
- FailureStateView error → ref.invalidate
- SingleChildScrollView → Column data
- DataLoadInfo state.lastSyncAt
- OrderDetailTitleWidget
- AccountHeaderCard nome + SAP
- OrderDetailWarningWidget shrink se sem locks
- _OrderLockRow por lock
- OrderDetailNumberPillWidget name / PO
- OrderDetailStatusPillWidget cor por statusGroup
- OrderDetailInfoGridWidget
- OrderDetailLabelValueWidget ×6
- OrderDetailPaymentSectionWidget parcelas ou placeholder
- OrderDetailItemsSectionWidget shrink se sem itens pagos
- _buildItemRow SKU · valor · qty
- OrderDetailFreeOfChargeSectionWidget shrink se sem FOC · SKU · qty
- OrderDetailTotalSectionWidget ConsumerWidget · currentMarket
- OrderDetailActionsWidget shrink se nenhuma ação
- _ActionButton Cancelar canCancel
- _ActionButton Liberar canRelease
- _ActionButton Editar canEdit
- OrderActionConfirmModalContent modal (widgets/modals/) · mensagem por intent + issues de estoque + Voltar (outlined) / Prosseguir (filled, só se canProceed)
- OrderSubmissionProgressModalContent modal · progresso release/cancel (enableClose/Dismiss: false) · onStart → submitAction → goToOrderConfirmation
- AppPageShell displayBackButton
Fluxo das ações: tocar num _ActionButton → OrderActionConfirmModalContent. Editar: reconstructForEdit() + AppRouter.goToProductShowcase(visitSfid:), sem modal de progresso. Liberar/Cancelar: OrderSubmissionProgressModalContent (onStart → submitAction) → AppRouter.goToOrderConfirmation. Modais e navegação ficam no widget por precisarem de BuildContext; a lógica de envio mora no Notifier (§39).Action flow: tapping an _ActionButton → OrderActionConfirmModalContent. Edit: reconstructForEdit() + AppRouter.goToProductShowcase(visitSfid:), no progress modal. Release/Cancel: OrderSubmissionProgressModalContent (onStart → submitAction) → AppRouter.goToOrderConfirmation. Modals and navigation stay in the widget because they need BuildContext; the submit logic lives in the Notifier (§39).Flujo de las acciones: tocar un _ActionButton → OrderActionConfirmModalContent. Editar: reconstructForEdit() + AppRouter.goToProductShowcase(visitSfid:), sin modal de progreso. Liberar/Cancelar: OrderSubmissionProgressModalContent (onStart → submitAction) → AppRouter.goToOrderConfirmation. Modales y navegación quedan en el widget porque necesitan BuildContext; la lógica de envío vive en el Notifier (§39).
Notas por mercadoMarket notesNotas por mercado
O Detalhe segue a habilitação de Pedidos (End Market Configuration) — está disponível nos três mercados onde a Lista de pedidos existe:Detail follows Orders' enablement (End Market Configuration) — it's available in the three markets where the Order list exists:El Detalle sigue la habilitación de Pedidos (End Market Configuration) — está disponible en los tres mercados donde existe la Lista de pedidos:
Só no BrasilBrazil onlySolo Brasil
Pix (pixStatus/pixKey/pixQrCode) e boleto/NF-e (canPrintBankSlip) são do Brasil. No envio, pagamento pré-pago via pix resolve o status para awaitingPixPayment.
Pix (pixStatus/pixKey/pixQrCode) and bank slip/e-invoice (canPrintBankSlip) are Brazil-specific. On submit, a prepaid pix payment resolves the status to awaitingPixPayment.
Pix (pixStatus/pixKey/pixQrCode) y boleto/factura electrónica (canPrintBankSlip) son de Brasil. En el envío, un pago pix prepago resuelve el estado a awaitingPixPayment.
África do SulSouth AfricaSudáfrica
Único mercado com pedido indireto (DispatcherType.orderIndirect). Usa unidade secundária para todas as categorias e verifica estoque de van em pedidos prompt (o que dispara a checagem no Liberar). VAT é relevante nos totais.
Only market with indirect orders (DispatcherType.orderIndirect). Uses secondary UoM for all categories and checks van stock for prompt orders (which triggers the check on Release). VAT is relevant in totals.
Único mercado con pedido indirecto (DispatcherType.orderIndirect). Usa unidad secundaria para todas las categorías y verifica stock de van en pedidos prompt (lo que dispara la verificación en Liberar). El VAT es relevante en los totales.
AR · PY · PE
Sem ordersConfig, não há Lista de pedidos e portanto não há Detalhe. A moeda dos totais é formatada por mercado (BR/CL/AR/PY estilo 1.234,56; ZA/PE estilo 1,234.56; CLP/PYG sem decimais) via CurrencyUtils.
With no ordersConfig, there's no Order list and therefore no Detail. Totals currency is formatted per market (BR/CL/AR/PY as 1.234,56; ZA/PE as 1,234.56; CLP/PYG without decimals) via CurrencyUtils.
Sin ordersConfig, no hay Lista de pedidos y por lo tanto no hay Detalle. La moneda de los totales se formatea por mercado (BR/CL/AR/PY como 1.234,56; ZA/PE como 1,234.56; CLP/PYG sin decimales) vía CurrencyUtils.