Prompt (Van Sales)(Van Sales)(Van Sales)
Não é uma tela — é o ecossistema de venda direta da van: o representante carrega estoque no veículo e o pedido é atendido na hora (entrega no ato, faturamento imediato, pagamento no ponto de venda), em vez de virar entrega futura da logística. Este doc cobre o estado ATUAL do código: o pipeline de estoque da van, os ramos prompt no carrinho e no payload do pedido, a perna diferida de pagamento, o eixo do tipo de representante Prompt-sales Rep — e o que ainda não existe. Not a screen — it is the van-sales ecosystem: the rep carries stock in the vehicle and the order is fulfilled on the spot (delivered there and then, invoiced immediately, paid at the point of sale) instead of becoming a future logistics delivery. This doc covers the CURRENT state of the code: the van-stock pipeline, the prompt branches in the cart and in the order payload, the deferred payment leg, the Prompt-sales Rep resource-type axis — and what does not exist yet. No es una pantalla — es el ecosistema de venta directa desde la van: el representante carga stock en el vehículo y el pedido se atiende en el acto (entrega inmediata, facturación inmediata, pago en el punto de venta), en lugar de convertirse en una entrega futura de logística. Este doc cubre el estado ACTUAL del código: el pipeline de stock de la van, las ramas prompt en el carrito y en el payload del pedido, la pierna diferida de pago, el eje del tipo de representante Prompt-sales Rep — y lo que todavía no existe.
O que é e para que serveWhat it is and what it's forQué es y para qué sirve
Há dois modelos de venda no ConectaRep. No pré-venda (pre-sales, o modelo padrão hoje) o representante monta o pedido no varejo e a mercadoria é entregue depois, por logística, numa data de entrega negociada. No prompt (van sales / venda direta) o representante já está com a mercadoria na van: o pedido é atendido no mesmo momento, a quantidade não pode passar do que existe no veículo, a entrega é hoje e o dinheiro é recolhido ali. ConectaRep has two selling models. In pre-sales (today's default) the rep builds the order at the retail and the goods are delivered later, by logistics, on a negotiated delivery date. In prompt (van sales / direct selling) the rep already carries the goods in the van: the order is fulfilled on the spot, quantities cannot exceed what is in the vehicle, delivery is today and the money is collected right there. Hay dos modelos de venta en ConectaRep. En la preventa (pre-sales, el modelo estándar hoy) el representante arma el pedido en el punto de venta y la mercadería se entrega después, por logística, en una fecha de entrega negociada. En el prompt (van sales / venta directa) el representante ya lleva la mercadería en la van: el pedido se atiende en el mismo momento, la cantidad no puede superar lo que hay en el vehículo, la entrega es hoy y el dinero se cobra allí mismo.
Estoque da vanVan stockStock de la van
O que o representante pode vender é o que está no veículo, por lote de fabricação. A quantidade da linha é limitada ao disponível e cada linha registra de quais lotes saiu.What the rep can sell is what sits in the vehicle, per manufacturing batch. The line quantity is clamped to what is available and each line records which batches it came from.Lo que el representante puede vender es lo que está en el vehículo, por lote de fabricación. La cantidad de la línea se limita al disponible y cada línea registra de qué lotes salió.
Entrega é hojeDelivery is todayLa entrega es hoy
A data de entrega é fixada no dia do pedido e o seletor de data desaparece — não há prazo, lead time do fornecedor nem dia preferencial do varejo a respeitar.The delivery date is pinned to the order date and the date picker disappears — there is no lead time, supplier window or retail preferred weekday to respect.La fecha de entrega se fija en el día del pedido y el selector de fecha desaparece — no hay plazo, lead time del proveedor ni día preferido del punto de venta que respetar.
Dinheiro na horaMoney on the spotDinero en el momento
O pagamento é configurado antes de confirmar o pedido, com valor travado no total e um único método; depois vira relatório de caixa para o backend.Payment is configured before confirming the order, with the amount locked to the total and a single method; later it becomes a cash payment report to the backend.El pago se configura antes de confirmar el pedido, con el monto fijado al total y un único método; después se convierte en reporte de caja para el backend.
Construído no app, desligado no mercadoBuilt in the app, switched off per marketConstruido en la app, apagado en el mercado
O interruptor de entrada é a chave de configuração orderCreationConfig.enablePromptImplementation, e ela está false em BR, CL e ZA (e ausente em AR/PY/PE). Ou seja: hoje nenhum carrinho nasce prompt, então os ramos de estoque, data e faturamento descritos aqui não são exercidos em produção. O que está vivo: o eixo do tipo de representante Prompt-sales Rep (relatórios, fim de visita, fim de jornada), a leitura do estoque da van (sincronizada como qualquer outro dado) e a perna de pagamento do pedido — que hoje é alcançada pelo pagamento à vista do Chile, não pelo pedido prompt.
The entry switch is the config key orderCreationConfig.enablePromptImplementation, and it is false in BR, CL and ZA (and absent in AR/PY/PE). Meaning: no cart is born prompt today, so the stock, date and invoicing branches described here are not exercised in production. What is alive: the Prompt-sales Rep resource-type axis (reports, visit end, end of journey), the van-stock read (synced like any other data) and the order payment leg — which today is reached through Chile's pay-at-sight, not through a prompt order.
El interruptor de entrada es la clave de configuración orderCreationConfig.enablePromptImplementation, y está en false en BR, CL y ZA (y ausente en AR/PY/PE). Es decir: hoy ningún carrito nace prompt, así que las ramas de stock, fecha y facturación descritas aquí no se ejercitan en producción. Lo que sí está vivo: el eje del tipo de representante Prompt-sales Rep (reportes, fin de visita, fin de jornada), la lectura del stock de la van (sincronizada como cualquier otro dato) y la pierna de pago del pedido — que hoy se alcanza por el pago al contado de Chile, no por el pedido prompt.
Quando um pedido é promptWhen an order is promptCuándo un pedido es prompt
Não há botão "pedido prompt" e não há tela de venda direta. O modelo é decidido pela configuração do mercado no momento em que o carrinho é criado, e depois viaja junto com o carrinho e com o pedido:There is no "prompt order" button and no van-sales screen. The model is decided by market configuration at the moment the cart is created, and then travels with the cart and with the order:No hay botón de "pedido prompt" ni pantalla de venta directa. El modelo lo decide la configuración del mercado en el momento en que se crea el carrito, y después viaja junto con el carrito y con el pedido:
- A configuração do mercado decideMarket configuration decidesLa configuración del mercado decideAo abrir um carrinho novo para o varejo, o app lê
enablePromptImplementationda configuração de criação de pedido daquele mercado e marca o carrinho como prompt ou não. É uma decisão de mercado — não do representante, não do varejo, não por produto.When a new cart is opened for the retail, the app readsenablePromptImplementationfrom that market's order-creation config and stamps the cart as prompt or not. It is a market-wide decision — not per rep, not per retail, not per product.Al abrir un carrito nuevo para el punto de venta, la app leeenablePromptImplementationde la configuración de creación de pedido de ese mercado y marca el carrito como prompt o no. Es una decisión de mercado — no del representante, no del punto de venta, no por producto. - A marca acompanha o carrinhoThe stamp follows the cartLa marca acompaña al carritoA partir daí é o carrinho que carrega a marca. Cada mudança de quantidade passa a consultar o estoque da van, a data de entrega fica travada em hoje e o envio muda o status da transação.From there the cart carries the stamp. Every quantity change starts consulting van stock, the delivery date is locked to today and the submit changes the transaction status.A partir de ahí el carrito lleva la marca. Cada cambio de cantidad empieza a consultar el stock de la van, la fecha de entrega queda fijada en hoy y el envío cambia el estado de la transacción.
- O pedido guarda a marcaThe order keeps the stampEl pedido guarda la marcaO pedido enviado (e o pedido que volta do backend) guarda que era prompt, e é isso que faz o detalhe do pedido checar estoque da van antes de liberar.The submitted order (and the order that comes back from the backend) keeps the prompt mark, and that is what makes the order detail check van stock before releasing.El pedido enviado (y el pedido que vuelve del backend) guarda que era prompt, y eso es lo que hace que el detalle del pedido revise el stock de la van antes de liberar.
- O tipo do representante é um eixo separadoRep type is a separate axisEl tipo de representante es un eje aparteExiste um tipo de representante chamado Prompt-sales Rep. Ele controla o que a pessoa vê em Relatórios, no fim de visita e no fim de jornada — e funciona hoje, independentemente do interruptor acima. Ser um Prompt-sales Rep não faz o pedido virar prompt.There is a resource type called Prompt-sales Rep. It controls what the person sees in Reports, at visit end and at end of journey — and it works today, independently of the switch above. Being a Prompt-sales Rep does not make the order prompt.Existe un tipo de representante llamado Prompt-sales Rep. Controla lo que la persona ve en Reportes, en el fin de visita y en el fin de jornada — y funciona hoy, independientemente del interruptor de arriba. Ser un Prompt-sales Rep no convierte el pedido en prompt.
Três eixos que parecem umThree axes that look like oneTres ejes que parecen uno
Vale separar: (a) o modelo do pedido (a chave do mercado enablePromptImplementation) — é a única que muda o comportamento do pedido; (b) o tipo do representante (Prompt-sales Rep), que só governa visibilidade de relatórios e de pendências; (c) o atendimento prompt do varejo (hasPromptFulfillment, vindo do roteiro da conta), que hoje só afeta o respeito aos dias preferenciais de entrega. Existe ainda um quarto sinal de mesmo nome no cadastro do representante, que não é lido por nada (ver Pendências).
Worth separating: (a) the order model (the market key enablePromptImplementation) — the only one that changes order behavior; (b) the resource type (Prompt-sales Rep), which only governs visibility of reports and pendings; (c) the retail's prompt fulfillment (hasPromptFulfillment, from the account's route info), which today only affects whether preferred delivery weekdays are honored. There is also a fourth same-named signal on the rep record, which nothing reads (see Pending).
Conviene separar: (a) el modelo del pedido (la clave de mercado enablePromptImplementation) — la única que cambia el comportamiento del pedido; (b) el tipo de representante (Prompt-sales Rep), que solo gobierna la visibilidad de reportes y pendientes; (c) el atendimiento prompt del punto de venta (hasPromptFulfillment, del itinerario de la cuenta), que hoy solo afecta el respeto a los días preferidos de entrega. Existe además una cuarta señal con el mismo nombre en el registro del representante, que nadie lee (ver Pendientes).
O ecossistema em uma olhadaThe ecosystem at a glanceEl ecosistema de un vistazo
O prompt não tem casa própria: ele aparece como um comportamento diferente dentro de áreas que já existem. São cinco frentes:Prompt has no home of its own: it shows up as different behavior inside areas that already exist. Five fronts:El prompt no tiene casa propia: aparece como un comportamiento distinto dentro de áreas que ya existen. Son cinco frentes:
- Estoque da vanVan stockStock de la van
- Uma foto do que existe no veículo, por lote, trazida do backend pela hierarquia de localização do próprio representante (não pelo varejo). Traz quantidade inicial, aceita, disponível, reservada, total e descarregada. É a base do limite de quantidade e da alocação de lotes.A snapshot of what is in the vehicle, per batch, fetched from the backend by the rep's own location hierarchy (not by retail). It carries initial, accepted, available, reserved, total and unloaded quantities. It is the basis for quantity clamping and batch allocation.Una foto de lo que hay en el vehículo, por lote, traída del backend por la jerarquía de ubicación del propio representante (no por punto de venta). Trae cantidad inicial, aceptada, disponible, reservada, total y descargada. Es la base del límite de cantidad y de la asignación de lotes.
- CarrinhoCartCarrito
- Num carrinho prompt cada mudança de quantidade é limitada ao disponível na van, ganha a alocação de lotes, e a promoção passa a ver estoque real (a bonificação disputa o mesmo estoque da compra — ver Promoções). Fora do prompt, o estoque é tratado como ilimitado.In a prompt cart every quantity change is clamped to what is available in the van, gains a batch allocation, and promotions start seeing real stock (free-of-charge competes with the purchase for the same stock — see Promotions). Outside prompt, stock is treated as unlimited.En un carrito prompt cada cambio de cantidad se limita al disponible en la van, gana la asignación de lotes, y la promoción empieza a ver stock real (la bonificación compite con la compra por el mismo stock — ver Promociones). Fuera del prompt, el stock se trata como ilimitado.
- Pedido e transaçãoOrder & transactionPedido y transacción
- O envio do pedido muda em quatro pontos: data de entrega = data do pedido, sinalizador de faturamento ligado, sinalizador de alteração desligado e status da transação diferente (aprovação externa no Brasil, faturado-não-sincronizado no Chile e na África do Sul). O serviço de envio continua o mesmo do pré-venda.The order submit changes at four points: delivery date = order date, invoice flag on, altered flag off and a different transaction status (external approval in Brazil, invoiced-not-sync in Chile and South Africa). The submit service itself stays the pre-sales one.El envío del pedido cambia en cuatro puntos: fecha de entrega = fecha del pedido, indicador de facturación encendido, indicador de alteración apagado y un estado de transacción distinto (aprobación externa en Brasil, facturado-no-sincronizado en Chile y Sudáfrica). El servicio de envío sigue siendo el de preventa.
- PagamentoPaymentPago
- Existe uma área de configurar pagamento por parcela do pedido antes de confirmar. Ela usa a origem "pedido prompt": valor travado no total, um único método, sem título em aberto de verdade (o débito é sintético). Nada é enviado na hora — o pagamento fica registrado como pendente e só depois é sincronizado, gerando o relatório de caixa.There is an area to configure payment per order split before confirming. It uses the "prompt order" origin: amount locked to the total, a single method, no real open item (the debit is synthetic). Nothing is sent right away — the payment is registered as pending and only later synced, producing the cash payment report.Existe un área para configurar el pago por cuota del pedido antes de confirmar. Usa el origen "pedido prompt": monto fijado al total, un único método, sin documento abierto real (el débito es sintético). Nada se envía en el momento — el pago queda registrado como pendiente y solo después se sincroniza, generando el reporte de caja.
- Jornada, pendências e relatóriosJourney, pendings & reportsJornada, pendientes y reportes
- Aqui quem manda é o tipo do representante. Um Prompt-sales Rep é o único (junto com o Delivery Rep) que vê entregas e devoluções pendentes no fim da jornada, é o único que vê pagamentos pendentes no Chile, e é o único que vê o relatório de status de entrega — que o Pre-sales Rep não vê.Here the resource type rules. A Prompt-sales Rep is the only one (together with the Delivery Rep) who sees pending deliveries and buybacks at end of journey, the only one who sees pending payments in Chile, and the only one who sees the delivery status report — which the Pre-sales Rep does not see.Aquí manda el tipo de representante. Un Prompt-sales Rep es el único (junto con el Delivery Rep) que ve entregas y devoluciones pendientes al fin de la jornada, el único que ve pagos pendientes en Chile, y el único que ve el reporte de estado de entrega — que el Pre-sales Rep no ve.
Estados que o prompt produzStates prompt producesEstados que el prompt produce
- No envio do pedidoOn order submitEn el envío del pedido
- Um pedido prompt não sai "em espera" como o pré-venda. Ele sai como aguardando aprovação externa onde o mercado usa aprovação de fora (Brasil) ou direto como faturado, ainda não sincronizado (Chile e África do Sul). Cancelamento, pré-pagamento Pix e aprovação interna continuam tendo prioridade sobre isso.A prompt order does not leave as "on hold" like pre-sales. It leaves as pending external approval where the market uses outside approval (Brazil) or straight as invoiced, not yet synced (Chile and South Africa). Cancellation, Pix pre-payment and internal approval still take precedence over this.Un pedido prompt no sale "en espera" como el de preventa. Sale como esperando aprobación externa donde el mercado usa aprobación externa (Brasil) o directamente como facturado, aún no sincronizado (Chile y Sudáfrica). Cancelación, prepago Pix y aprobación interna siguen teniendo prioridad sobre esto.
- "Prompt Fulfillment" na lista de pedidos"Prompt Fulfillment" in the order list"Prompt Fulfillment" en la lista de pedidos
- O backend pode devolver um pedido com o status Prompt Fulfillment. Ele é exibido cru na etiqueta do pedido, entra no grupo "pedidos realizados" e pode ser escolhido no filtro de status da lista de pedidos. É um estado informativo: nenhuma regra do app se comporta diferente por causa dele.The backend may return an order with status Prompt Fulfillment. It is shown raw on the order tag, falls in the "ordered" group and can be picked in the status filter of the order list. It is an informational state: no app rule behaves differently because of it.El backend puede devolver un pedido con el estado Prompt Fulfillment. Se muestra crudo en la etiqueta del pedido, cae en el grupo "pedidos realizados" y puede elegirse en el filtro de estado de la lista de pedidos. Es un estado informativo: ninguna regla de la app se comporta distinto por él.
- O pagamento fica pendenteThe payment stays pendingEl pago queda pendiente
- Depois que todas as parcelas do pedido são enviadas com sucesso, o pagamento configurado é gravado como registro aguardando aprovação do pedido ou aguardando o título em aberto. Quando o título correspondente chega numa sincronização, o registro passa a pronto para sincronizar e o envio efetivo acontece pela central de dados.Once every order split is submitted successfully, the configured payment is stored as a register awaiting order approval or awaiting the open item. When the matching open item arrives in a sync, the register becomes ready to sync and the actual send happens from the data center.Después de que todas las cuotas del pedido se envían con éxito, el pago configurado se graba como registro esperando aprobación del pedido o esperando el documento abierto. Cuando el documento correspondiente llega en una sincronización, el registro pasa a listo para sincronizar y el envío efectivo ocurre desde la central de datos.
- Falta de estoque na vanMissing van stockFalta de stock en la van
- Ao liberar um pedido prompt no detalhe, o app compara linha por linha com o estoque atual da van e marca as linhas com problema de estoque (produto fora do catálogo ou quantidade insuficiente). A liberação só é permitida se sobrar pelo menos uma linha paga sem problema.When releasing a prompt order from the detail, the app compares line by line against current van stock and flags lines with a stock issue (product missing from the catalog or insufficient quantity). Release is only allowed if at least one paid line remains without an issue.Al liberar un pedido prompt desde el detalle, la app compara línea por línea contra el stock actual de la van y marca las líneas con problema de stock (producto fuera del catálogo o cantidad insuficiente). La liberación solo se permite si queda al menos una línea paga sin problema.
O que muda para o representanteWhat changes for the repQué cambia para el representante
- Adicionar produtoAdd productAgregar producto
- A quantidade que ele digita ou incrementa é cortada no disponível da van, sem aviso próprio: o carrinho simplesmente para de subir. Se não há estoque daquele produto, a linha fica em zero.The quantity typed or incremented is clamped to what is available in the van, with no dedicated warning: the cart simply stops going up. With no stock for that product, the line stays at zero.La cantidad que digita o incrementa se recorta al disponible de la van, sin aviso propio: el carrito simplemente deja de subir. Si no hay stock de ese producto, la línea queda en cero.
- Escolher a data de entregaPick a delivery dateElegir la fecha de entrega
- Não escolhe: na vitrine a seção de data de entrega não é exibida e a data vai como hoje. O intervalo de datas de crédito também passa a contar de hoje. Atenção: na revisão do carrinho e no pagamento a pílula de "entrega estimada" continua aparecendo — ela não é filtrada por prompt (ver Pendências).They don't: in the showcase the delivery-date section is not shown and the date goes out as today. The credit date range also starts counting from today. Note: in the cart review and in the payment step the "estimated delivery" pill still shows up — it isn't filtered by prompt (see Pending items).No la elige: en la vitrina la sección de fecha de entrega no se muestra y la fecha sale como hoy. El rango de fechas de crédito también empieza a contar desde hoy. Atención: en la revisión del carrito y en el pago la píldora de "entrega estimada" sigue apareciendo — no se filtra por prompt (ver Pendientes).
- Passar do limite de crédito com PixGo over the credit limit with PixPasar el límite de crédito con Pix
- Num pedido prompt o atalho de "Pix passa do limite" fica mais restrito: só vale se o total do carrinho não ultrapassar o limite de crédito do varejo.In a prompt order the "Pix bypasses the limit" shortcut gets tighter: it only applies if the cart total does not exceed the retail's credit limit.En un pedido prompt el atajo de "Pix pasa el límite" queda más restringido: solo vale si el total del carrito no supera el límite de crédito del punto de venta.
- Configurar o pagamentoConfigure the paymentConfigurar el pago
- No passo de pagamento aparece um bloco Configurar pagamento por parcela do pedido. Enquanto qualquer parcela estiver sem pagamento configurado, o botão de confirmar fica desabilitado. Dentro da tela de pagamento o valor não é editável, não é possível adicionar um segundo método e o botão diz Salvar (não Confirmar) — porque nada é enviado ali.In the payment step a Configure payment block appears per order split. While any split has no configured payment, the confirm button stays disabled. Inside the payment screen the amount is not editable, a second method cannot be added and the button reads Save (not Confirm) — because nothing is sent there.En el paso de pago aparece un bloque Configurar pago por cuota del pedido. Mientras alguna cuota esté sin pago configurado, el botón de confirmar queda deshabilitado. Dentro de la pantalla de pago el monto no es editable, no se puede agregar un segundo método y el botón dice Guardar (no Confirmar) — porque allí no se envía nada.
- Liberar ou editar o pedido depoisRelease or edit the order laterLiberar o editar el pedido después
- No detalhe do pedido, liberar um pedido prompt passa por uma checagem de estoque da van nos mercados que pedem isso; linhas sem estoque são apontadas e a liberação pode ser bloqueada. Cancelar não passa por essa checagem.In the order detail, releasing a prompt order goes through a van-stock check in the markets that ask for it; lines without stock are flagged and release may be blocked. Cancelling does not go through that check.En el detalle del pedido, liberar un pedido prompt pasa por una verificación de stock de la van en los mercados que lo piden; las líneas sin stock se señalan y la liberación puede bloquearse. Cancelar no pasa por esa verificación.
- Ver as pendências do diaSee the day's pendingsVer los pendientes del día
- Sendo um Prompt-sales Rep, o fim de jornada mostra categorias que outros tipos não veem — entregas pendentes, devoluções pendentes e, no Chile, pagamentos pendentes. Ver Jornada.As a Prompt-sales Rep, end of journey shows categories other types don't see — pending deliveries, pending buybacks and, in Chile, pending payments. See Journey.Siendo un Prompt-sales Rep, el fin de jornada muestra categorías que otros tipos no ven — entregas pendientes, devoluciones pendientes y, en Chile, pagos pendientes. Ver Jornada.
Quem alcança a área de pagamento hojeWho reaches the payment area todayQuién alcanza el área de pago hoy O bloco Configurar pagamento não é aberto por "ser um pedido prompt": ele aparece quando o carrinho está marcado como pagamento à vista e o módulo de criação de pagamento está habilitado no mercado — hoje, o caminho do Pago al Contado do Chile. A origem interna do pagamento, porém, é "pedido prompt", e é dela que vêm as regras de valor travado e método único. The Configure payment block is not opened by "being a prompt order": it appears when the cart is flagged as pay at sight and the payment-creation module is enabled for the market — today, Chile's Pago al Contado path. The internal payment origin, however, is "prompt order", and that is where the locked-amount and single-method rules come from. El bloque Configurar pago no se abre por "ser un pedido prompt": aparece cuando el carrito está marcado como pago al contado y el módulo de creación de pago está habilitado en el mercado — hoy, el camino del Pago al Contado de Chile. El origen interno del pago, sin embargo, es "pedido prompt", y de ahí vienen las reglas de monto fijado y método único.
Arquitetura e fluxo de dadosArchitecture & data flowArquitectura y flujo de datos
Clean Architecture + Riverpod + Freezed + gRPC + ObjectBox. O ecossistema tem dois fluxos independentes: a leitura do estoque da van (dado persistido, cache + remoto, com um orquestrador puro por cima) e a propagação do sinal prompt (uma flag de configuração que vira campo do carrinho, muda o payload do pedido e abre a perna diferida de pagamento).Clean Architecture + Riverpod + Freezed + gRPC + ObjectBox. The ecosystem has two independent flows: the van-stock read (persisted data, cache + remote, with a pure orchestrator on top) and the propagation of the prompt signal (a config flag that becomes a cart field, changes the order payload and opens the deferred payment leg).Clean Architecture + Riverpod + Freezed + gRPC + ObjectBox. El ecosistema tiene dos flujos independientes: la lectura del stock de la van (dato persistido, caché + remoto, con un orquestador puro encima) y la propagación de la señal prompt (una flag de configuración que se vuelve campo del carrito, cambia el payload del pedido y abre la pierna diferida de pago).
Estoque da van · cache + remotoVan stock · cache + remoteStock de la van · caché + remoto
Um RPC unário por hierarquia de localização do representante (não por conta) devolve o estoque por lote; o resultado vira StockControlEntity e é gravado no ObjectBox (write-through, box raiz + ToMany de lotes). Tudo que consome estoque durante o pedido lê só o cache; o refresh remoto é responsabilidade do DataSyncOrchestrator (tipo de sync stockControl, TTL de 900 s por dataFreshnessConfig):One unary RPC by the rep's location hierarchy (not by account) returns stock per batch; the result becomes a StockControlEntity and is written to ObjectBox (write-through, root box + a ToMany of batches). Everything that consumes stock during the order reads cache only; the remote refresh belongs to DataSyncOrchestrator (sync type stockControl, 900 s TTL from dataFreshnessConfig):Un RPC unario por jerarquía de ubicación del representante (no por cuenta) devuelve el stock por lote; el resultado se vuelve StockControlEntity y se graba en ObjectBox (write-through, box raíz + ToMany de lotes). Todo lo que consume stock durante el pedido lee solo caché; el refresh remoto es responsabilidad del DataSyncOrchestrator (tipo de sync stockControl, TTL de 900 s por dataFreshnessConfig):
- StockControlReplygRPC proto · repeated Stock
- toDTOStockControlDTODTO · Freezed
- toDomainStockControlEntitydomain · lastSyncAt gerado no mapper
- toModelStockControlModelObjectBox · ToMany<StockModel>
- toDomainStockControlEntitydomain · cache
- getCachedStockControlGetAvailableStockForProductUseCase+ Clamp · ValidateReward · AllocateBatches
- fachadaPromptOrchestratorpuro · sem I/O próprio
- → pedidoCartOrchestrator · OrderDetailNotifier
- fachadaPromptOrchestratorpuro · sem I/O próprio
- getCachedStockControlGetAvailableStockForProductUseCase+ Clamp · ValidateReward · AllocateBatches
- toDomainStockControlEntitydomain · cache
- toModelStockControlModelObjectBox · ToMany<StockModel>
- toDomainStockControlEntitydomain · lastSyncAt gerado no mapper
- toDTOStockControlDTODTO · Freezed
O sinal prompt · configuração → carrinho → transaçãoThe prompt signal · config → cart → transactionLa señal prompt · configuración → carrito → transacción
A flag do mercado é lida uma única vez, na criação do carrinho, e daí em diante o portador do sinal é o carrinho (campo persistido). No envio, o sinal muda o status da transação e três campos do payload; depois do envio bem-sucedido de todas as parcelas, o pagamento configurado é registrado sem despachar:The market flag is read exactly once, at cart creation, and from there the signal's carrier is the cart (a persisted field). On submit, the signal changes the transaction status and three payload fields; after every split submits successfully, the configured payment is registered without dispatching:La flag del mercado se lee una única vez, en la creación del carrito, y de ahí en adelante el portador de la señal es el carrito (campo persistido). En el envío, la señal cambia el estado de la transacción y tres campos del payload; después del envío exitoso de todas las cuotas, el pago configurado se registra sin despachar:
- orderCreationConfig.enablePromptImplementationEMC · por mercado
- getterCartOrchestrationContextEntity.isPromptOrder
- getEmptyCartCartEntity.isPromptOrderpersistido no CartModel
- quantidadeclampLineQuantity + allocateBatchesestoque da van por lote
- submitResolveOrderTransactionStatusUseCasependingExternalApproval | invoicedNotSync
- payloadBuildOrderPlacementDispatcherPayloadUseCaseDeliveryDate=orderDate · IFlag=1 · alteredFull=false
- dispatchDispatcherOrchestratorMobileorderAPI · IndirectOrderAPI · OrderApprovalUploadAPI
- após sucessoPaymentSubmissionOrchestratorisDeferred: true → PaymentRegister
- sync posteriorPaymentCollectionAPI + CashPaymentReportAPI
- após sucessoPaymentSubmissionOrchestratorisDeferred: true → PaymentRegister
- dispatchDispatcherOrchestratorMobileorderAPI · IndirectOrderAPI · OrderApprovalUploadAPI
- payloadBuildOrderPlacementDispatcherPayloadUseCaseDeliveryDate=orderDate · IFlag=1 · alteredFull=false
- submitResolveOrderTransactionStatusUseCasependingExternalApproval | invoicedNotSync
- quantidadeclampLineQuantity + allocateBatchesestoque da van por lote
- getEmptyCartCartEntity.isPromptOrderpersistido no CartModel
- getterCartOrchestrationContextEntity.isPromptOrder
Estoque só de leituraRead-only stockStock solo de lectura
O domínio de estoque da van é somente leitura. saveStockControl é um cache-writer: é chamado depois de um fetch remoto bem-sucedido e no merge de visita ad hoc — nunca por um envio de pedido. Não há reserva, decremento local nem devolução de estoque quando o pedido é rejeitado; o app depende do backend recalcular e do próximo sync trazer o novo disponível.
The van-stock domain is read-only. saveStockControl is a cache-writer: it runs after a successful remote fetch and in the ad-hoc visit merge — never from an order submit. There is no reservation, no local decrement and no stock give-back when an order is rejected; the app relies on the backend recomputing and the next sync bringing the new availability.
El dominio de stock de la van es solo lectura. saveStockControl es un cache-writer: corre después de un fetch remoto exitoso y en el merge de visita ad hoc — nunca desde un envío de pedido. No hay reserva, ni decremento local, ni devolución de stock cuando el pedido se rechaza; la app depende de que el backend recalcule y de que el próximo sync traiga la nueva disponibilidad.
Modelo de dadosData modelModelo de datos
O dado persistido do ecossistema é o estoque da van, e ele existe em quatro representações ao longo das camadas — Proto (wire gRPC) → DTO (Freezed) → Model (ObjectBox) → Entity (domínio) — cada fronteira atravessada por um mapper, com cache write-through. Os nomes se mantêm em todas as camadas; muda pouco (a relação ToMany no Model, o enum tipado na Entity e o lastSyncAt, que o proto não manda).The ecosystem's persisted data is the van stock, and it exists in four representations across the layers — Proto (gRPC wire) → DTO (Freezed) → Model (ObjectBox) → Entity (domain) — each boundary crossed by a mapper, with cache write-through. Names stay the same across layers; little changes (the ToMany relation in the Model, the typed enum in the Entity and lastSyncAt, which the proto does not send).El dato persistido del ecosistema es el stock de la van, y existe en cuatro representaciones a lo largo de las capas — Proto (wire gRPC) → DTO (Freezed) → Model (ObjectBox) → Entity (dominio) — cada frontera cruzada por un mapper, con caché write-through. Los nombres se mantienen en todas las capas; cambia poco (la relación ToMany en el Model, el enum tipado en la Entity y el lastSyncAt, que el proto no envía).
O dado chega num container StockControl (lastSyncAt + stocks[], §21 do CLAUDE.md), e cada Stock é um lote de fabricação de um produto (13 campos: identificação, SKU de comércio e de fabricação, lote, cinco quantidades, tipo e quantidade descarregada). O sinal prompt em si não é uma estrutura: são três booleanos que moram em agregados diferentes (configuração de mercado, carrinho/pedido e roteiro da conta) — a tabela do fim desta seção mapeia os três no wire. A seguir: o proto, as estruturas campo-a-campo, os mappers e os deltas.Data arrives in a StockControl container (lastSyncAt + stocks[], CLAUDE.md §21), and each Stock is one manufacturing batch of a product (13 fields: identification, trade and manufacturing SKU, batch, five quantities, type and unloaded quantity). The prompt signal itself is not a structure: it is three booleans living in different aggregates (market config, cart/order and the account's route info) — the table at the end of this section maps all three on the wire. Next: the proto, the field-by-field structures, the mappers and the deltas.El dato llega en un container StockControl (lastSyncAt + stocks[], §21 de CLAUDE.md), y cada Stock es un lote de fabricación de un producto (13 campos: identificación, SKU de comercio y de fabricación, lote, cinco cantidades, tipo y cantidad descargada). La señal prompt en sí no es una estructura: son tres booleanos que viven en agregados distintos (configuración de mercado, carrito/pedido e itinerario de la cuenta) — la tabla al final de esta sección mapea los tres en el wire. A continuación: el proto, las estructuras campo a campo, los mappers y los deltas.
Proto
StockControlConectaRep.proto · proto3 · package mn.bat.conectarep.streambridge · serviçoserviceservicio StockControlConectaRepService — um único RPC:a single RPC:un único RPC:
getStockControlunaryrpc getStockControl(StockControlRequest) returns (StockControlReply)
path /mn.bat.conectarep.streambridge.StockControlConectaRepService/getStockControl
StockControlRequestlocationHierarchySfidstring· #1 · a hierarquia de localização do representante de vendas (a van), resolvida no repository viacurrentResourceProviderthe sales rep's location hierarchy (the van), resolved in the repository viacurrentResourceProviderla jerarquía de ubicación del representante de ventas (la van), resuelta en el repository víacurrentResourceProviderdateReferencestring· #2 · optional — existe no datasource, mas o repository nunca preencheoptional — exists in the datasource, but the repository never fills itoptional — existe en el datasource, pero el repository nunca lo llenalastModifiedDatestring· #3 · optional — delta-sync previsto no contrato e não plumbado em nenhuma camada (ver Pendências)optional — delta-sync foreseen in the contract and not plumbed in any layer (see Pending)optional — delta-sync previsto en el contrato y no plumbado en ninguna capa (ver Pendientes)
StockControlReplyrepeated Stock stocks — os campos de Stock estão nas Estruturas abaixo.Stock's fields are in Structures below.los campos de Stock están en Estructuras abajo.
Estruturas de dadosData structuresEstructuras de datos
Um dropdown por estrutura, aninhados pela hierarquia. Cada tabela tem uma coluna por camada — Proto · DTO · Model · Entity; o delta (texto azul) marca onde o tipo primeiro muda (relação ToMany no Model, enum na Entity). ¹ = optional no proto.One dropdown per structure, nested by hierarchy. Each table has one column per layer — Proto · DTO · Model · Entity; the delta (blue text) marks where the type first changes (ToMany relation in the Model, enum in the Entity). ¹ = optional in the proto.Un dropdown por estructura, anidados por jerarquía. Cada tabla tiene una columna por capa — Proto · DTO · Model · Entity; el delta (texto azul) marca dónde primero cambia el tipo (relación ToMany en el Model, enum en la Entity). ¹ = optional en el proto.
-
StockControl raiz 2 camposfieldscampos
CampoFieldCampo Proto DTO Model Entity stocksrepeated StockList<StockDTO>ToMany<StockModel>List<StockEntity>lastSyncAt— — DateTimeDateTimeO proto não manda
lastSyncAt: ele é gerado no mapper de fronteira (StockControlDTO.toDomain()usaDateTimeUtils.now(), §21) e persistido no Model. Uma única linha na box raiz —saveStockControllimpa antes de gravar.The proto does not sendlastSyncAt: it is generated in the boundary mapper (StockControlDTO.toDomain()usesDateTimeUtils.now(), §21) and persisted in the Model. A single row in the root box —saveStockControlclears before writing.El proto no envíalastSyncAt: se genera en el mapper de frontera (StockControlDTO.toDomain()usaDateTimeUtils.now(), §21) y se persiste en el Model. Una única fila en la box raíz —saveStockControllimpia antes de grabar.-
Stock StockControl.stocks[] 13 camposfieldscampos
CampoFieldCampo Proto DTO Model Entity sfidstringStringStringStringnamestringStringStringStringproductTradeSKUstringStringStringStringproductManufacturingSKUstringStringStringStringbatchIdstringStringStringStringinitialQuantitydoubledoubledoubledoubleacceptedQuantitydoubledoubledoubledoubleavailableQuantitydoubledoubledoubledoublereservedQuantitydoubledoubledoubledoubletotalQuantitydoubledoubledoubledoubleunloadQuantity¹optional doubledouble?double?double?typestringStringStringStockTypeaccountIdstringStringStringString¹
optionalno proto.productTradeSKUé a chave de cruzamento com o produto (product.productSfid);batchIdé o que vai para a alocação de lotes da linha do carrinho.accountIdé usado pelo merge de visita ad hoc para substituir o estoque de uma conta.¹optionalin the proto.productTradeSKUis the join key against the product (product.productSfid);batchIdis what goes into the cart line's batch allocation.accountIdis used by the ad-hoc visit merge to replace one account's stock.¹optionalen el proto.productTradeSKUes la clave de cruce con el producto (product.productSfid);batchIdes lo que va a la asignación de lotes de la línea del carrito.accountIdlo usa el merge de visita ad hoc para reemplazar el stock de una cuenta.
-
O sinal prompt no wireThe prompt signal on the wireLa señal prompt en el wire
Quatro campos com nomes parecidos, em quatro protos diferentes. Uma linha por campo:Four similarly named fields, in four different protos. One row per field:Cuatro campos con nombres parecidos, en cuatro protos distintos. Una fila por campo:
| CampoFieldCampo | Proto | EntityEntityEntity | Quem lêWho reads itQuién lo lee |
|---|---|---|---|
enablePromptImplementation | nenhum — vem do EMC (Firebase Remote Config / asset JSON)none — comes from the EMC (Firebase Remote Config / JSON asset)ninguno — viene del EMC (Firebase Remote Config / asset JSON) | OrderCreationConfig · bool @Default(false) | CartOrchestrationContextEntity.isPromptOrder · CartOrchestrator.getEmptyCart |
enablePromptImplementation | ResourceConectaRep.proto · ResourceFeatureFlags · bool = 2 | ResourceFeatureFlagsEntity · required bool | ninguém — mapeado e persistido, sem leitornobody — mapped and persisted, no readernadie — mapeado y persistido, sin lector |
isPromptOrder | OrderConectaRep.proto · optional bool = 40 | OrderEntity · bool? · CartEntity · bool @Default(false) | carrinho, payload, status da transação, detalhe do pedidocart, payload, transaction status, order detailcarrito, payload, estado de la transacción, detalle del pedido |
isPromptFulfillment | OrderConectaRep.proto · optional bool = 41 | OrderEntity · bool? | ninguém — só round-trip pelos mappersnobody — only round-trips through the mappersnadie — solo round-trip por los mappers |
hasPromptFulfillment | VisitConectaRep.proto · RouteDelivery · bool = 4 | RouteDeliveryEntity · bool? | CartOrchestrationContextEntity.ignoresPreferredDeliveryDays |
Mappers
| DireçãoDirectionDirección | EntradaInputEntrada | SaídaOutputSalida | ObservaçãoNoteObservación |
|---|---|---|---|
| JSON → DTO | Map<String, dynamic> | StockControlDTO | fromMap — caminho mock; cada campo com default (""/0.0), unloadQuantity segue nulomock path; every field defaulted (""/0.0), unloadQuantity stays nullcamino mock; cada campo con default (""/0.0), unloadQuantity sigue nulo |
| Proto → DTO | StockControlReply · Stock | StockControlDTO | toDTO — cópia 1:1, sem transformação1:1 copy, no transformationcopia 1:1, sin transformación |
| DTO → Entity | StockControlDTO | StockControlEntity | toDomain — gera lastSyncAt e tipa StockType.fromStringgenerates lastSyncAt and types StockType.fromStringgenera lastSyncAt y tipa StockType.fromString |
| Entity → Model | StockControlEntity | StockControlModel | toModel — popula a relação ToMany e grava type.value como Stringfills the ToMany relation and stores type.value as a Stringllena la relación ToMany y graba type.value como String |
| Model → Entity | StockControlModel | StockControlEntity | toDomain — preserva o lastSyncAt gravado e retipa o enumpreserves the stored lastSyncAt and re-types the enumpreserva el lastSyncAt grabado y vuelve a tipar el enum |
Os únicos deltasThe only deltasLos únicos deltas
stocks—repeatedno proto eListno DTO/Entity vira relaçãoToManyno Model (é lá que o tipo primeiro diverge).stocks—repeatedin the proto and aListin DTO/Entity becomes aToManyrelation in the Model (that is where the type first diverges).stocks—repeateden el proto yListen DTO/Entity se vuelve relaciónToManyen el Model (ahí el tipo diverge primero).lastSyncAt— não existe no wire nem no DTO; nasce no mapper de fronteira e passa a existir do Model/Entity para cima.lastSyncAt— does not exist on the wire nor in the DTO; it is born in the boundary mapper and exists from Model/Entity upwards.lastSyncAt— no existe en el wire ni en el DTO; nace en el mapper de frontera y existe desde el Model/Entity hacia arriba.type— trafega comoStringem proto/DTO/Model e só é tipado comoStockTypena Entity.type— travels as aStringin proto/DTO/Model and is only typed asStockTypein the Entity.type— viaja comoStringen proto/DTO/Model y solo se tipa comoStockTypeen la Entity.unloadQuantity—optionalno proto e nulo em todas as camadas: não há delta, a nulidade atravessa inteira.unloadQuantity—optionalin the proto and nullable in every layer: no delta, nullability crosses intact.unloadQuantity—optionalen el proto y nulo en todas las capas: no hay delta, la nulidad atraviesa intacta.isPromptOrder—optional boolno proto do pedido ebool?naOrderEntity, mas non-null com@Default(false)naCartEntity: reconstruir um carrinho a partir de um pedido usaisPromptOrder ?? false.isPromptOrder—optional boolin the order proto andbool?onOrderEntity, but non-null with@Default(false)onCartEntity: rebuilding a cart from an order usesisPromptOrder ?? false.isPromptOrder—optional boolen el proto del pedido ybool?enOrderEntity, pero non-null con@Default(false)enCartEntity: reconstruir un carrito desde un pedido usaisPromptOrder ?? false.
Repository
StockControlRepositoryImpl implementaimplementsimplementa StockControlRepositoryInterface e injeta os 3 datasources (mock/local/remote) + ConnectivityService + a flag useMockData + Ref. Provider keepAlive. Não existe repository "de prompt": o único dado do ecossistema é o estoque da van. Método a método:and injects the 3 datasources (mock/local/remote) + ConnectivityService + the useMockData flag + Ref. keepAlive provider. There is no "prompt repository": the ecosystem's only data is the van stock. Method by method:e inyecta los 3 datasources (mock/local/remote) + ConnectivityService + la flag useMockData + Ref. Provider keepAlive. No existe un repository "de prompt": el único dato del ecosistema es el stock de la van. Método a método:
getStockControl({source = DataSourceType.local}) mock / local / remote
RetornaReturnsDevuelve Result<StockControlEntity, Failure>
Ponto de entrada do estoque (default source: local). Decide a fonte e grava no cache (write-through). Chamado hoje apenas pelo DataSyncOrchestrator, com a fonte forçada do sweep de freshness.Stock entry point (default source: local). Picks the source and writes to cache (write-through). Today it is called only by DataSyncOrchestrator, with the freshness sweep's forced source.Punto de entrada del stock (default source: local). Elige la fuente y graba en caché (write-through). Hoy lo llama solo el DataSyncOrchestrator, con la fuente forzada del sweep de freshness.
Árvore de decisão de fonteSource decision treeÁrbol de decisión de fuente
useMockDataouorosource == mock→_fetchFromMock(): lê o asset JSON destock_controldo mercado ativo (sintético ou real), mapeia porfromMap+toDomain(). Não grava cache.→_fetchFromMock(): reads the market'sstock_controlJSON asset (synthetic or real), maps viafromMap+toDomain(). No cache write.→_fetchFromMock(): lee el asset JSON destock_controldel mercado activo (sintético o real), mapea víafromMap+toDomain(). No graba caché.source == localou offlineor offlineu offline→_fetchFromCacheOrFail(): cache; se a box estiver vazia,Error(NetworkFailure).→_fetchFromCacheOrFail(): cache; if the box is empty,Error(NetworkFailure).→_fetchFromCacheOrFail(): caché; si la box está vacía,Error(NetworkFailure).- senão (remoto + conectado)otherwise (remote + connected)si no (remoto + conectado)→
_fetchFromRemoteWithFallback(): lêcurrentResourceProvider(null → cache), chama o remoto comresource.locationHierarchyId, mapeia, grava no cache; em erro, fallback pro cache (e só devolve o erro se o cache também estiver vazio).→_fetchFromRemoteWithFallback(): readscurrentResourceProvider(null → cache), calls remote withresource.locationHierarchyId, maps, writes cache; on error, falls back to cache (and only returns the error when the cache is empty too).→_fetchFromRemoteWithFallback(): leecurrentResourceProvider(null → caché), llama al remoto conresource.locationHierarchyId, mapea, graba caché; en error, fallback al caché (y solo devuelve el error si el caché también está vacío).
getCachedStockControl() local · o caminho do promptthe prompt pathel camino del prompt
RetornaReturnsDevuelve Result<StockControlEntity?, Failure>
Só cache; box vazia vira Success(null). É este o método que todo o fluxo de pedido prompt usa (via GetAvailableStockForProductUseCase.loadSnapshot e AllocateManufacturingBatchesUseCase) — nenhuma leitura de estoque durante a montagem do carrinho dispara rede.Cache only; an empty box becomes Success(null). This is the method the whole prompt order flow uses (via GetAvailableStockForProductUseCase.loadSnapshot and AllocateManufacturingBatchesUseCase) — no stock read during cart building hits the network.Solo caché; box vacía se vuelve Success(null). Es este el método que usa todo el flujo de pedido prompt (vía GetAvailableStockForProductUseCase.loadSnapshot y AllocateManufacturingBatchesUseCase) — ninguna lectura de stock durante el armado del carrito toca la red.
getCachedStockControlLastSyncAt() local
RetornaReturnsDevuelve DateTime? (sem Result; erro é logado e vira null)(no Result; an error is logged and becomes null)(sin Result; el error se loguea y se vuelve null)
Timestamp da última sincronização do estoque, consumido pelo sweep de freshness para decidir se o dado venceu (TTL de 900 s).The stock's last-sync timestamp, consumed by the freshness sweep to decide whether the data is stale (900 s TTL).Timestamp de la última sincronización del stock, consumido por el sweep de freshness para decidir si el dato venció (TTL de 900 s).
saveStockControl({stockControl}) local · cache-writer
RetornaReturnsDevuelve Result<void, Failure>
Destrutivo: o datasource local limpa a box raiz e os lotes antes de regravar. Chamado depois de um fetch remoto bem-sucedido — nunca por um envio de pedido. O merge de visita ad hoc não passa por aqui: ele entra pelo mergeAdhocStockControl do datasource local, que resolve o AdhocStockControlMerge e só então chama este saveStockControl.Destructive: the local datasource clears the root box and the batches before rewriting. Called after a successful remote fetch — never by an order submit. The ad-hoc visit merge does not come through here: it enters via the local datasource's mergeAdhocStockControl, which resolves AdhocStockControlMerge and only then calls this saveStockControl.Destructivo: el datasource local limpia la box raíz y los lotes antes de regrabar. Se llama tras un fetch remoto exitoso — nunca por un envío de pedido. El merge de visita ad hoc no pasa por aquí: entra por el mergeAdhocStockControl del datasource local, que resuelve el AdhocStockControlMerge y solo entonces llama a este saveStockControl.
Datasources
Um card por datasource (dropdown). No corpo: método, envio, retorno, fluxo de uso e tratamento de erro.One card per datasource (dropdown). In the body: method, what it sends, return, usage flow and error handling.Un card por datasource (dropdown). En el cuerpo: método, envío, retorno, flujo de uso y manejo de errores.
Remote StockControlRemoteDataSource gRPC
getStockControl({locationHierarchySfid, dateReference?})
- EnvioSendsEnvío
- monta
StockControlRequestcomlocationHierarchySfid(edateReferencesó se não for nulo) e disparagetStockControlnoStockControlConectaRepServiceClient.builds aStockControlRequestwithlocationHierarchySfid(anddateReferenceonly when non-null) and firesgetStockControlonStockControlConectaRepServiceClient.armaStockControlRequestconlocationHierarchySfid(ydateReferencesolo si no es nulo) y disparagetStockControlenStockControlConectaRepServiceClient. - RetornoReturnRetorno
StockControlDTO(viaresponse.toDTO())(viaresponse.toDTO())(víaresponse.toDTO())- Fluxo de usoUsage flowFlujo de uso
- caminho remoto do repository quando online e sem mock; o resultado é gravado no cache.
lastModifiedDate(#3) não é parâmetro deste método.the repository's remote path when online and not mocking; the result is written to cache.lastModifiedDate(#3) is not a parameter of this method.camino remoto del repository cuando está online y sin mock; el resultado se graba en caché.lastModifiedDate(#3) no es parámetro de este método. - Tratamento de erroError handlingManejo de errores
GrpcError→GrpcExceptionHandler; outros →ServerException(shouldLog: true). O repository faz fallback pro cache.GrpcError→GrpcExceptionHandler; others →ServerException(shouldLog: true). The repository falls back to cache.GrpcError→GrpcExceptionHandler; otros →ServerException(shouldLog: true). El repository hace fallback al caché.
Local StockControlLocalDataSource ObjectBox
Envio / fluxo: persistência local via ObjectBox — box raiz StockControlModel + box de lotes StockModel pela relação ToMany. Alimenta todos os caminhos de cache do repository. Erro: qualquer falha vira CacheException (shouldLog: true).Sends / flow: local persistence via ObjectBox — StockControlModel root box + StockModel batch box through the ToMany relation. Feeds every cache path of the repository. Error: any failure becomes a CacheException (shouldLog: true).Envío / flujo: persistencia local vía ObjectBox — box raíz StockControlModel + box de lotes StockModel por la relación ToMany. Alimenta todos los caminos de caché del repository. Error: cualquier falla se vuelve CacheException (shouldLog: true).
getStockControl()
- RetornoReturnRetorno
StockControlEntity?- ComportamentoBehaviorComportamiento
models.first.toDomain()ounullse a box estiver vazia.ornullwhen the box is empty.onullsi la box está vacía.
getStockControlLastSyncAt()
- RetornoReturnRetorno
DateTime?- ComportamentoBehaviorComportamiento
models.first.lastSyncAt
saveStockControl({entity})
- RetornoReturnRetorno
void- ComportamentoBehaviorComportamiento
clearStockControl()e depoisput(entity.toModel())— sempre uma única linha raiz.clearStockControl()thenput(entity.toModel())— always a single root row.clearStockControl()y luegoput(entity.toModel())— siempre una única fila raíz.
clearStockControl()
- RetornoReturnRetorno
void- ComportamentoBehaviorComportamiento
- limpa a box de lotes e a box raiz (usado internamente antes de gravar).clears the batch box and the root box (used internally before writing).limpia la box de lotes y la box raíz (uso interno antes de grabar).
mergeAdhocStockControl({incoming, accountSfid})
- RetornoReturnRetorno
void- ComportamentoBehaviorComportamiento
- é o ponto de entrada real do merge de visita ad hoc: lê o cache atual, delega a
AdhocStockControlMerge.merge(que substitui os lotes da conta recebida) e regrava porsaveStockControl— tudo dentro do datasource. O coordenador de merge ad hoc chama este método, não o repository.this is the real entry point of the ad-hoc visit merge: it reads the current cache, delegates toAdhocStockControlMerge.merge(which replaces the incoming account's batches) and rewrites throughsaveStockControl— all inside the datasource. The ad-hoc merge coordinator calls this method, not the repository.es el punto de entrada real del merge de visita ad hoc: lee el caché actual, delega aAdhocStockControlMerge.merge(que sustituye los lotes de la cuenta recibida) y regraba porsaveStockControl— todo dentro del datasource. El coordinador de merge ad hoc llama a este método, no al repository.
Mock StockControlMockDataSource assets JSON
getStockControl()
- EnvioSendsEnvío
- nenhum — lê o asset da pasta
stock_controlpor mercado (currentMarketProvider) e por modo de mock (useRealMockDataProvider: sintético vs dump real).none — reads the asset from thestock_controlfolder per market (currentMarketProvider) and per mock mode (useRealMockDataProvider: synthetic vs real dump).ninguno — lee el asset de la carpetastock_controlpor mercado (currentMarketProvider) y por modo de mock (useRealMockDataProvider: sintético vs dump real). - RetornoReturnRetorno
StockControlDTO(viaStockControlDTOMapper.fromMap)(viaStockControlDTOMapper.fromMap)(víaStockControlDTOMapper.fromMap)- Fluxo de usoUsage flowFlujo de uso
- modo mock; o arquivo existe para os seis mercados, mas só BR e CL têm conteúdo sintético — 5 lotes cada, com os três tipos convivendo (2
stock_count, 2van_load, 1stock_view). O sintético da África do Sul é um stub vazio, como os de AR, PY e PE. Nos dumps reais o quadro é outro: BR (6 lotes) e CL (12) são todosstock_view, e a África do Sul (35 lotes) é todastock_count— nenhumvan_loadem nenhum dump real.mock mode; the file exists for all six markets, but only BR and CL carry synthetic content — 5 batches each, with all three types coexisting (2stock_count, 2van_load, 1stock_view). South Africa's synthetic file is an empty stub, like AR, PY and PE. The real dumps look different: BR (6 batches) and CL (12) are allstock_view, and South Africa (35 batches) is allstock_count— novan_loadin any real dump.modo mock; el archivo existe para los seis mercados, pero solo BR y CL tienen contenido sintético — 5 lotes cada uno, con los tres tipos conviviendo (2stock_count, 2van_load, 1stock_view). El sintético de Sudáfrica es un stub vacío, como los de AR, PY y PE. En los dumps reales el cuadro es otro: BR (6 lotes) y CL (12) son todosstock_view, y Sudáfrica (35 lotes) es todostock_count— ningúnvan_loaden ningún dump real. - Tratamento de erroError handlingManejo de errores
- asset ausente ou JSON inválido →
CacheException.missing asset or invalid JSON →CacheException.asset ausente o JSON inválido →CacheException.
Enums e labelsEnums & labelsEnums y labels
Os enums do ecossistema. StockType e ResourceTypeItem só existem tipados na Entity (trafegam como String); OrderTransactionStatus é de saída (o app o escreve no payload) e PaymentCreationOrigin é interno, persistido no registro de pagamento. Lista completa de valores:The ecosystem's enums. StockType and ResourceTypeItem are only typed in the Entity (they travel as String); OrderTransactionStatus is outbound (the app writes it into the payload) and PaymentCreationOrigin is internal, persisted on the payment register. Full value list:Los enums del ecosistema. StockType y ResourceTypeItem solo existen tipados en la Entity (viajan como String); OrderTransactionStatus es de salida (la app lo escribe en el payload) y PaymentCreationOrigin es interno, persistido en el registro de pago. Lista completa de valores:
StockType 4
| case | value | SignificadoMeaningSignificado |
|---|---|---|
stockCount | "stock_count" | linha originada de uma contagem de estoquerow originated from a stock countfila originada de un conteo de stock |
vanLoad | "van_load" | carga da van — o bucket do modelo promptvan load — the prompt model's bucketcarga de la van — el bucket del modelo prompt |
stockView | "stock_view" | visão de estoque devolvida pelo backendstock view returned by the backendvista de stock devuelta por el backend |
unknown | "unknown" | valor não mapeadounmapped valuevalor no mapeado |
fromString é case-insensitive, mas com uma particularidade: string vazia cai em stockCount (não em unknown) — só um valor desconhecido não vazio vira unknown. Nenhum consumidor filtra por type hoje (ver Pendências).fromString is case-insensitive, with one quirk: an empty string falls into stockCount (not unknown) — only a non-empty unknown value becomes unknown. No consumer filters by type today (see Pending).fromString es case-insensitive, con una particularidad: una cadena vacía cae en stockCount (no en unknown) — solo un valor desconocido no vacío se vuelve unknown. Ningún consumidor filtra por type hoy (ver Pendientes).
OrderTransactionStatus 7
| case | value | Quando o app o escolheWhen the app picks itCuándo la app lo elige |
|---|---|---|
cancelled | "Cancelled" | intenção de cancelamento (tem prioridade máxima)cancellation intent (top priority)intención de cancelación (máxima prioridad) |
awaitingPixPayment | "Awaiting Pix Payment" | pré-pagamento PixPix pre-paymentprepago Pix |
pendingApproval | "PA" | aprovação interna, exceto pedido indiretointernal approval, except indirect orderaprobación interna, excepto pedido indirecto |
pendingExternalApproval | "Pending External Approval" | prompt + promptOrderUsesExternalApprovalprompt + promptOrderUsesExternalApprovalprompt + promptOrderUsesExternalApproval |
invoiced | "Invoiced" | nunca escolhido por este UseCase (valor do enum sem produtor no app)never picked by this UseCase (enum value with no producer in the app)nunca elegido por este UseCase (valor del enum sin productor en la app) |
invoicedNotSync | "Invoiced Not Sync" | prompt sem aprovação externaprompt without external approvalprompt sin aprobación externa |
onHold | "On-Hold" | o default do pré-vendathe pre-sales defaultel default de la preventa |
Membro derivado: isAwaitingApproval é true para pendingApproval e pendingExternalApproval — é ele que decide se o registro de pagamento diferido nasce aguardando a aprovação do pedido.Derived member: isAwaitingApproval is true for pendingApproval and pendingExternalApproval — it decides whether the deferred payment register is born awaiting order approval.Miembro derivado: isAwaitingApproval es true para pendingApproval y pendingExternalApproval — decide si el registro de pago diferido nace esperando la aprobación del pedido.
PaymentCreationOrigin 5 + 8 getters
| case | value |
|---|---|
financialManagement | "financial_management" |
collections | "collections" |
promptOrder | "prompt_order" |
delivery | "delivery" |
unknown | "unknown" |
Matriz de comportamento — uma linha por getterBehavior matrix — one row per getterMatriz de comportamiento — una fila por getter
| getter | financialManagement | collections | promptOrder | delivery | unknown |
|---|---|---|---|---|---|
requiresStartedVisit | true | false | false | false | false |
usesPreferredPaymentMethodAsDefault | false | true | false | false | false |
sendsOnConfirm | true | true | false | false | false |
allowsExcessRedirect | true | true | false | false | false |
hasEditableAmount | true | true | false | true | true |
requiresDebitOpenItem | true | true | false | true | true |
requiresFullAmountCoverage | false | false | false | true | false |
reportsCashPayment | false | false | true | true | false |
hasEditableAmount e requiresDebitOpenItem são escritos com != promptOrder, então o valor unknown herda o comportamento não-prompt (valor editável, título obrigatório) — uma origem corrompida no cache degrada para gestão financeira, não para prompt. fromString é case-sensitive (comparação exata do value) e loga o valor não mapeado.hasEditableAmount and requiresDebitOpenItem are written as != promptOrder, so unknown inherits the non-prompt behavior (editable amount, open item required) — a corrupted cached origin degrades to financial management, not to prompt. fromString is case-sensitive (exact value match) and logs the unmapped value.hasEditableAmount y requiresDebitOpenItem se escriben como != promptOrder, así que unknown hereda el comportamiento no-prompt (monto editable, documento obligatorio) — un origen corrupto en caché degrada a gestión financiera, no a prompt. fromString es case-sensitive (comparación exacta del value) y loguea el valor no mapeado.
PaymentRegisterStatus 5
| case | value | Significado no fluxo promptMeaning in the prompt flowSignificado en el flujo prompt |
|---|---|---|
awaitingOrderApproval | "ORDER_PA" | o pedido saiu aguardando aprovação (interna ou externa)the order left awaiting approval (internal or external)el pedido salió esperando aprobación (interna o externa) |
awaitingDebitOpenItem | "CREATED" | o pedido já está faturado, mas o título em aberto ainda não chegouthe order is already invoiced, but the open item has not arrived yetel pedido ya está facturado, pero el documento abierto aún no llegó |
readyToSync | "READY" | o título correspondente foi encontrado — pode despacharthe matching open item was found — ready to dispatchel documento correspondiente fue encontrado — listo para despachar |
sent | "SENT" | cobrança e relatório de caixa despachadoscollection and cash report dispatchedcobranza y reporte de caja despachados |
unknown | "unknown" | vazio ou não mapeado (com log)empty or unmapped (logged)vacío o no mapeado (con log) |
Membros derivados: isPending (os dois primeiros), isSyncable (readyToSync) e isSent. Este ciclo é fila de escrita local do app, não contrato de backend — os mesmos quatro códigos existiam no app legado.Derived members: isPending (the first two), isSyncable (readyToSync) and isSent. This lifecycle is the app's local write queue, not a backend contract — the same four codes existed in the legacy app.Miembros derivados: isPending (los dos primeros), isSyncable (readyToSync) e isSent. Este ciclo es cola de escritura local de la app, no contrato de backend — los mismos cuatro códigos existían en la app legada.
ResourceTypeItem 8
| case | value (wire) | normalize |
|---|---|---|
preSalesRep | "Pre-sales Rep" | pre_sales_rep |
promptSalesRep | "Prompt-sales Rep" | prompt_sales_rep |
universalRep | "Universal Rep" | universal_rep |
deliveryRep | "Delivery Rep" | delivery_rep |
telesalesAnalyst | "Telesales Analyst" | telesales_analyst |
webAgentDirect | "Web Agent - Direct" | web_agent_direct |
tradeMarketingRep | "Trade Marketing Rep" | trade_marketing_rep |
unknown | "unknown" | unknown |
normalize baixa a caixa e colapsa espaços/hífens em _, então tanto "Prompt-sales Rep" (usado nos JSONs reais) quanto "prompt_sales_rep" (usado no arquivo comentado de documentação do EMC) resolvem para o mesmo case. Valor não mapeado dispara logUnmappedEnumValue, que em debug/profile quebra por assert; em release degrada para unknown, que nunca consta de nenhuma lista de tipos permitidos.normalize lowercases and collapses spaces/hyphens into _, so both "Prompt-sales Rep" (used in the real JSONs) and "prompt_sales_rep" (used in the EMC's annotated documentation file) resolve to the same case. An unmapped value fires logUnmappedEnumValue, which in debug/profile throws via assert; in release it degrades to unknown, which is never present in any allowed-types list.normalize baja la caja y colapsa espacios/guiones en _, así que tanto "Prompt-sales Rep" (usado en los JSON reales) como "prompt_sales_rep" (usado en el archivo comentado de documentación del EMC) resuelven al mismo case. Un valor no mapeado dispara logUnmappedEnumValue, que en debug/profile rompe por assert; en release degrada a unknown, que nunca aparece en ninguna lista de tipos permitidos.
ResourceType 4
| case | value | items |
|---|---|---|
physical | "physical" | preSalesRep, promptSalesRep, universalRep, deliveryRep |
digital | "digital" | webAgentDirect |
telesales | "telesales" | telesalesAnalyst |
unknown | "unknown" | — |
Enum de canal, não de gating: agrupa os tipos acima e é usado em filtros de visitas/entregas e nas etiquetas F/D/TS. O Prompt-sales Rep é canal physical. tradeMarketingRep não pertence a nenhum grupo, então resolve para unknown. fromString aceita tanto o nome do grupo quanto qualquer valor de tipo contido nele, e não loga nem faz assert no fallback.A channel enum, not a gating one: it groups the types above and is used in visit/delivery filters and in the F/D/TS badges. The Prompt-sales Rep is channel physical. tradeMarketingRep belongs to no group, so it resolves to unknown. fromString accepts both the group name and any type value inside it, and does not log nor assert on fallback.Enum de canal, no de gating: agrupa los tipos de arriba y se usa en filtros de visitas/entregas y en las etiquetas F/D/TS. El Prompt-sales Rep es canal physical. tradeMarketingRep no pertenece a ningún grupo, así que resuelve a unknown. fromString acepta tanto el nombre del grupo como cualquier valor de tipo contenido en él, y no loguea ni hace assert en el fallback.
OrderStatus excerto · 1 de 31excerpt · 1 of 31excerpto · 1 de 31
| case | value | group |
|---|---|---|
promptFulfillment | "Prompt Fulfillment" | OrderStatusGroup.ordered |
Só o valor do ecossistema está aqui — os 31 valores completos de OrderStatus e os 4 de OrderStatusGroup vivem em Lista de pedidos §10. OrderStatus não tem chave de tradução: o value cru é renderizado na etiqueta. promptFulfillment é de entrada — vem do backend, aparece na etiqueta e no filtro de status, e nenhuma regra ramifica nele.Only the ecosystem's value is here — the full 31 values of OrderStatus and the 4 of OrderStatusGroup live in Order list §10. OrderStatus has no translation key: the raw value is rendered on the tag. promptFulfillment is inbound — it comes from the backend, shows on the tag and in the status filter, and no rule branches on it.Solo el valor del ecosistema está aquí — los 31 valores completos de OrderStatus y los 4 de OrderStatusGroup viven en Lista de pedidos §10. OrderStatus no tiene clave de traducción: el value crudo se renderiza en la etiqueta. promptFulfillment es de entrada — viene del backend, aparece en la etiqueta y en el filtro de estado, y ninguna regla ramifica en él.
DispatcherType recorte · 9 de 42excerpt · 9 of 42excerpto · 9 de 42
| case | serviceName | enabledMarkets | builder |
|---|---|---|---|
order | MobileorderAPI | BR · CL · ZA | simyessí — BuildOrderPlacementDispatcherPayloadUseCase |
orderIndirect | IndirectOrderAPI | ZA | simyessí — mesmo buildersame buildermismo builder |
orderApproval | OrderApprovalUploadAPI | BR · CL · ZA | simyessí — mesmo buildersame buildermismo builder |
payment | PaymentCollectionAPI | BR · CL | simyessí — BuildPaymentCollectionDispatcherPayloadUseCase |
cashPaymentReport | CashPaymentReportAPI | BR · CL | simyessí — BuildCashPaymentReportDispatcherPayloadUseCase |
orderInvoice | Invoiceupload | BR · CL | não — declarado, sem builderno — declared, no builderno — declarado, sin builder |
stockUnload | VanUnloadAPI | BR · CL | não — declarado, sem builderno — declared, no builderno — declarado, sin builder |
stockReconciliation | StockReconciliationAPI | BR · CL | não — declarado, sem builderno — declared, no builderno — declarado, sin builder |
stockRequest · stockAllocationExecution | StockProposalUploadAPI · StockAllocationUploadAPI | BR · CL | não — declarados, sem builderno — declared, no builderno — declarados, sin builder |
Recorte do enum de 42 valores (36 com builder, 6 sem). Um pedido prompt sai hoje pelos mesmos serviços do pré-venda — o serviço dedicado do legado (Invoiceupload) está declarado no enum mas não tem builder, e os quatro serviços de operação de van também não. Os cinco aparecem apenas na própria linha do enum e nas chaves de tradução da central de dados.Excerpt of the 42-value enum (36 with a builder, 6 without). A prompt order goes out today through the same services as pre-sales — the legacy dedicated service (Invoiceupload) is declared in the enum but has no builder, and neither do the four van-operation services. All five appear only on their own enum line and in the data-center translation keys.Excerpto del enum de 42 valores (36 con builder, 6 sin). Un pedido prompt sale hoy por los mismos servicios que la preventa — el servicio dedicado del legado (Invoiceupload) está declarado en el enum pero no tiene builder, y los cuatro servicios de operación de van tampoco. Los cinco aparecen solo en su propia línea del enum y en las claves de traducción de la central de datos.
Orquestrador e UseCasesOrchestrator & UseCasesOrquestador y UseCases
O PromptOrchestrator é o cérebro de estoque da van do fluxo de pedido: uma classe simples (provider keepAlive, função, não Notifier) que injeta 4 UseCases de stock_control e expõe 5 métodos síncronos ou quase — nenhum Result, nenhum repository, nenhum despacho. Ele é folha: o CartOrchestrator o compõe, e o notifier do detalhe do pedido o lê direto.The PromptOrchestrator is the order flow's van-stock brain: a plain class (keepAlive functional provider, not a Notifier) that injects 4 stock_control UseCases and exposes 5 mostly synchronous methods — no Result, no repository, no dispatch. It is a leaf: the CartOrchestrator composes it, and the order-detail notifier reads it directly.El PromptOrchestrator es el cerebro de stock de la van del flujo de pedido: una clase simple (provider keepAlive, funcional, no Notifier) que inyecta 4 UseCases de stock_control y expone 5 métodos síncronos o casi — ningún Result, ningún repository, ningún despacho. Es hoja: el CartOrchestrator lo compone, y el notifier del detalle del pedido lo lee directo.
PromptOrchestrator
loadStockSnapshot() 4 chamadorescallersllamadores
RetornaReturnsDevuelve Future<StockControlEntity?>
Chama GetAvailableStockForProductUseCase.loadSnapshot() (que é cache-only) e colapsa o Result: Success devolve o valor, Error devolve null. Ou seja, "cache vazio" e "falha de leitura" ficam indistinguíveis a partir daqui. Chamado 3× no CartOrchestrator (ao aplicar quantidade, ao avaliar o carrinho e ao avaliar o detalhe da promoção) e 1× no OrderDetailNotifier.Calls GetAvailableStockForProductUseCase.loadSnapshot() (cache-only) and collapses the Result: Success returns the value, Error returns null. So "empty cache" and "read failure" become indistinguishable from here on. Called 3× in CartOrchestrator (applying quantity, evaluating the cart and evaluating the promotion detail) and 1× in OrderDetailNotifier.Llama GetAvailableStockForProductUseCase.loadSnapshot() (solo caché) y colapsa el Result: Success devuelve el valor, Error devuelve null. O sea, "caché vacío" y "falla de lectura" quedan indistinguibles desde aquí. Se llama 3× en CartOrchestrator (al aplicar cantidad, al evaluar el carrito y al evaluar el detalle de la promoción) y 1× en OrderDetailNotifier.
availableStock({stockSnapshot, product, usesSecondaryUomForAllCategories}) 2 chamadorescallersllamadores
RetornaReturnsDevuelve double
Delegação pura para GetAvailableStockForProductUseCase.availableFor. Alimenta o contexto de promoção (estoque real por produto) e o mapa de disponibilidade do detalhe do pedido.A pure delegation to GetAvailableStockForProductUseCase.availableFor. It feeds the promotion context (real stock per product) and the order detail's availability map.Delegación pura a GetAvailableStockForProductUseCase.availableFor. Alimenta el contexto de promoción (stock real por producto) y el mapa de disponibilidad del detalle del pedido.
clampLineQuantity({stockSnapshot, product, usesSecondaryUomForAllCategories, requestedQuantity}) 1 chamadorcallerllamador
RetornaReturnsDevuelve double
Compõe dois UseCases: resolve o disponível e passa para ClampQuantityToStockUseCase. É o corte de quantidade da linha do carrinho.Composes two UseCases: resolves availability and hands it to ClampQuantityToStockUseCase. It is the cart line's quantity clamp.Compone dos UseCases: resuelve el disponible y lo pasa a ClampQuantityToStockUseCase. Es el recorte de cantidad de la línea del carrito.
grantableRewardQuantity({stockSnapshot, product, usesSecondaryUomForAllCategories, requestedRewardQuantity, cartItems, alreadyGrantedFoc}) 0 chamadorescallersllamadores
RetornaReturnsDevuelve double
O único método com regra própria: soma o que as linhas pagas do mesmo produto já consomem (ignora as linhas de bonificação) e passa isso como consumedByPurchase para ValidateRewardStockUseCase. Nenhum chamador hoje: quem faz esse cálculo no motor de promoções é o ApplyProductRewardUseCase, que injeta o ValidateRewardStockUseCase direto e mantém o próprio acumulador de bonificação concedida. Consequência: a dependência ValidateRewardStockUseCase do orquestrador existe só para alimentar este método.The only method with a rule of its own: it sums what the paid lines of the same product already consume (ignoring free-of-charge lines) and passes that as consumedByPurchase to ValidateRewardStockUseCase. No callers today: in the promotion engine that computation is done by ApplyProductRewardUseCase, which injects ValidateRewardStockUseCase directly and keeps its own granted-FoC accumulator. Consequence: the orchestrator's ValidateRewardStockUseCase dependency exists only to feed this method.El único método con regla propia: suma lo que las líneas pagas del mismo producto ya consumen (ignora las líneas de bonificación) y lo pasa como consumedByPurchase a ValidateRewardStockUseCase. Sin llamadores hoy: en el motor de promociones ese cálculo lo hace ApplyProductRewardUseCase, que inyecta ValidateRewardStockUseCase directo y mantiene su propio acumulador de bonificación concedida. Consecuencia: la dependencia ValidateRewardStockUseCase del orquestador existe solo para alimentar este método.
allocateBatches({stockSnapshot, product, usesSecondaryUomForAllCategories, quantity}) 1 chamadorcallerllamador
RetornaReturnsDevuelve List<CartItemBatchAllocationEntity>
Delega para o método puro AllocateManufacturingBatchesUseCase.allocate (o que recebe o snapshot), não para o execute que releria o repository.Delegates to the pure AllocateManufacturingBatchesUseCase.allocate (the one that takes the snapshot), not to the execute that would re-read the repository.Delega al método puro AllocateManufacturingBatchesUseCase.allocate (el que recibe el snapshot), no al execute que releería el repository.
UseCases de estoqueStock UseCasesUseCases de stock
GetStockControlUseCase 3 métodosmethodsmétodos
| MétodoMethodMétodo | RetornaReturnsDevuelve | UsoUseUso |
|---|---|---|
execute({source = local}) | Future<Result<StockControlEntity, Failure>> | refresh do sweep de freshnessfreshness sweep refreshrefresh del sweep de freshness |
getCached() | Future<Result<StockControlEntity?, Failure>> | sem chamador hojeno caller todaysin llamador hoy |
getCachedLastSyncAt() | Future<DateTime?> | TTL do sweep de freshnessfreshness sweep TTLTTL del sweep de freshness |
GetAvailableStockForProductUseCase 3 métodosmethodsmétodos
| MétodoMethodMétodo | RetornaReturnsDevuelve | UsoUseUso |
|---|---|---|
loadSnapshot() | Future<Result<StockControlEntity?, Failure>> | getCachedStockControl() — cache-onlycache-onlysolo caché |
execute({product, usesSecondaryUomForAllCategories}) | Future<Result<double, Failure>> | sem chamador hojeno caller todaysin llamador hoy |
availableFor({stockControl, product, usesSecondaryUomForAllCategories}) | double | o cálculo em si (puro)the computation itself (pure)el cálculo en sí (puro) |
Como o disponível é calculadoHow availability is computedCómo se calcula el disponible
- Sem snapshotNo snapshotSin snapshot
stockControl == null→0.0. Cache vazio equivale a "sem estoque".stockControl == null→0.0. An empty cache equals "no stock".stockControl == null→0.0. Caché vacío equivale a "sin stock". - Soma dos lotesSum of batchesSuma de los lotessoma
availableQuantityde todos os lotes comproductTradeSKU == product.productSfideavailableQuantity > 0. Não filtra portype— lotes devan_load,stock_countestock_viewentram no mesmo bolo (ver Pendências).sumsavailableQuantityacross every batch withproductTradeSKU == product.productSfidandavailableQuantity > 0. It does not filter bytype—van_load,stock_countandstock_viewbatches are pooled together (see Pending).sumaavailableQuantityde todos los lotes conproductTradeSKU == product.productSfidyavailableQuantity > 0. No filtra portype— los lotes devan_load,stock_countystock_viewentran en la misma bolsa (ver Pendientes). - Conversão de unidadeUnit conversionConversión de unidadse a categoria do produto usa unidade secundária (ou o mercado usa secundária para todas), converte o total pelo fator de conversão; senão arredonda pela regra de quantidade (
ProductUomUtils).if the product's category uses the secondary unit (or the market uses secondary for all), converts the total by the conversion factor; otherwise rounds by the quantity rule (ProductUomUtils).si la categoría del producto usa unidad secundaria (o el mercado usa secundaria para todas), convierte el total por el factor de conversión; si no, redondea por la regla de cantidad (ProductUomUtils).
ClampQuantityToStockUseCase 1 métodomethodmétodo
| MétodoMethodMétodo | RetornaReturnsDevuelve | UsoUseUso |
|---|---|---|
execute({requestedQuantity, availableQuantity}) | double | pedido ≤ 0 → 0.0; disponível negativo é tratado como 0; devolve o menor entre pedido e disponívelrequested ≤ 0 → 0.0; a negative availability is treated as 0; returns the lesser of requested and availablepedido ≤ 0 → 0.0; disponible negativo se trata como 0; devuelve el menor entre pedido y disponible |
Classe const, sem dependências — matemática pura.A const class with no dependencies — pure arithmetic.Clase const, sin dependencias — matemática pura.
ValidateRewardStockUseCase 1 métodomethodmétodo
| MétodoMethodMétodo | RetornaReturnsDevuelve | UsoUseUso |
|---|---|---|
execute({availableQuantity, requestedRewardQuantity, consumedByPurchase, alreadyGrantedFoc = 0.0}) | double | recompensa pedida ≤ 0 → 0.0; remaining = disponível − comprado − já bonificado; se ≤ 0 → 0.0; senão o menor entre pedido e restanterequested reward ≤ 0 → 0.0; remaining = available − purchased − already granted; if ≤ 0 → 0.0; otherwise the lesser of requested and remainingrecompensa pedida ≤ 0 → 0.0; remaining = disponible − comprado − ya bonificado; si ≤ 0 → 0.0; si no, el menor entre pedido y restante |
Consumido direto pelo ApplyProductRewardUseCase do motor de promoções — a compra tem prioridade sobre a bonificação, e o acumulador de bonificações já concedidas evita que duas promoções gastem o mesmo lote. Ver Promoções.Consumed directly by the promotion engine's ApplyProductRewardUseCase — the purchase has priority over the free-of-charge grant, and the already-granted accumulator prevents two promotions from spending the same batch. See Promotions.Consumido directo por el ApplyProductRewardUseCase del motor de promociones — la compra tiene prioridad sobre la bonificación, y el acumulador de bonificaciones ya concedidas evita que dos promociones gasten el mismo lote. Ver Promociones.
AllocateManufacturingBatchesUseCase 2 métodosmethodsmétodos
| MétodoMethodMétodo | RetornaReturnsDevuelve | UsoUseUso |
|---|---|---|
execute({product, usesSecondaryUomForAllCategories, quantity}) | Future<Result<List<CartItemBatchAllocationEntity>, Failure>> | relê o cache e delega ao allocate; sem chamador hojere-reads the cache and delegates to allocate; no caller todayrelee el caché y delega a allocate; sin llamador hoy |
allocate({stockControl, product, usesSecondaryUomForAllCategories, quantity}) | List<CartItemBatchAllocationEntity> | o caminho usado pelo orquestradorthe path the orchestrator usesel camino que usa el orquestador |
Regra de alocaçãoAllocation ruleRegla de asignación converte a quantidade pedida para a unidade primária, percorre os lotes do produto com disponível > 0 na ordem em que vieram do backend (sem ordenar por validade ou lote), tira de cada um o que couber, e devolve uma lista de {batchId, quantity} na unidade de edição. Snapshot nulo ou quantidade ≤ 0 → lista vazia.converts the requested quantity to the primary unit, walks the product's batches with availability > 0 in backend order (no sorting by expiry or batch), takes what fits from each, and returns a list of {batchId, quantity} in the edit unit. A null snapshot or quantity ≤ 0 → empty list.convierte la cantidad pedida a la unidad primaria, recorre los lotes del producto con disponible > 0 en el orden en que vinieron del backend (sin ordenar por vencimiento ni lote), toma de cada uno lo que quepa, y devuelve una lista de {batchId, quantity} en la unidad de edición. Snapshot nulo o cantidad ≤ 0 → lista vacía.
UseCases que leem o sinal promptUseCases that read the prompt signalUseCases que leen la señal prompt
ResolveOrderTransactionStatusUseCase o ramo prompt do statusthe status prompt branchla rama prompt del estado
RetornaReturnsDevuelve OrderTransactionStatus
Cascata de prioridades: cancelamento → pré-pagamento Pix → aprovação interna (exceto pedido indireto) → prompt (pendingExternalApproval se promptOrderUsesExternalApproval, senão invoicedNotSync) → onHold. O ramo prompt fica abaixo dos outros três, então um cancelamento ou uma aprovação pendente vence a marca de prompt.Priority cascade: cancellation → Pix pre-payment → internal approval (except indirect order) → prompt (pendingExternalApproval when promptOrderUsesExternalApproval, otherwise invoicedNotSync) → onHold. The prompt branch sits below the other three, so a cancellation or a pending approval outranks the prompt mark.Cascada de prioridades: cancelación → prepago Pix → aprobación interna (excepto pedido indirecto) → prompt (pendingExternalApproval si promptOrderUsesExternalApproval, si no invoicedNotSync) → onHold. La rama prompt queda debajo de las otras tres, así que una cancelación o una aprobación pendiente le gana a la marca prompt.
BuildOrderPlacementDispatcherPayloadUseCase 3 camposfieldscampos
O builder do payload lê a marca do carrinho em três lugares:The payload builder reads the cart's mark in three places:El builder del payload lee la marca del carrito en tres lugares:
DeliveryDate- prompt → a própria data do pedido; senão a data de entrega do carrinho formatada.prompt → the order date itself; otherwise the cart's formatted delivery date.prompt → la propia fecha del pedido; si no, la fecha de entrega del carrito formateada.
IFlag"1"em pedido prompt,"0"no pré-venda."1"on a prompt order,"0"on pre-sales."1"en pedido prompt,"0"en preventa.alteredFull!isPromptOrder && sendsAlteredFullFlag— prompt forçafalsemesmo onde o mercado envia a flag.!isPromptOrder && sendsAlteredFullFlag— prompt forcesfalseeven where the market sends the flag.!isPromptOrder && sendsAlteredFullFlag— prompt fuerzafalseincluso donde el mercado envía la flag.invoiceRefNo- indireto pelo status: preenchido com o número do pedido só quando
sendsInvoiceRefOnExternalApprovale o status épendingExternalApproval— na prática, o caminho prompt do Brasil.indirect through the status: filled with the order number only whensendsInvoiceRefOnExternalApprovaland the status ispendingExternalApproval— in practice, Brazil's prompt path.indirecto por el estado: se llena con el número del pedido solo cuandosendsInvoiceRefOnExternalApprovaly el estado espendingExternalApproval— en la práctica, el camino prompt de Brasil.
O DispatcherType é resolvido sem olhar a marca de prompt: indireto → orderIndirect, aprovação → orderApproval, senão order. Não há campo de record type no payload (ver Pendências).The DispatcherType is resolved without looking at the prompt mark: indirect → orderIndirect, approval → orderApproval, otherwise order. There is no record type field in the payload (see Pending).El DispatcherType se resuelve sin mirar la marca de prompt: indirecto → orderIndirect, aprobación → orderApproval, si no order. No hay campo de record type en el payload (ver Pendientes).
ResolveDeliveryDateUseCase · DeliveryDateRulesUseCase · ComputeCreditDateRangeUseCase data de entregadelivery datefecha de entrega
ResolveDeliveryDateUseCase- primeira linha do
execute: contexto prompt → devolvecontext.nowformatado, curto-circuitando lead time do fornecedor, dias preferenciais, feriados, fins de semana e janela máxima.first line ofexecute: a prompt context → returns formattedcontext.now, short-circuiting supplier lead time, preferred weekdays, holidays, weekends and the max-ahead window.primera línea delexecute: contexto prompt → devuelvecontext.nowformateado, cortocircuitando lead time del proveedor, días preferidos, feriados, fines de semana y ventana máxima. DeliveryDateRulesUseCaseisVisible: !context.isPromptOrdereisEditable: context.allowsDeliveryDateChange— a seção de data desaparece no prompt.isVisible: !context.isPromptOrderandisEditable: context.allowsDeliveryDateChange— the date section disappears under prompt.isVisible: !context.isPromptOrderyisEditable: context.allowsDeliveryDateChange— la sección de fecha desaparece en prompt.ComputeCreditDateRangeUseCase- a data-base do intervalo de crédito é
nowno prompt, e a data de entrega do carrinho no pré-venda.the credit range's base date isnowunder prompt, and the cart's delivery date under pre-sales.la fecha base del rango de crédito esnowen prompt, y la fecha de entrega del carrito en preventa.
ComputeCartLockRulesUseCase trava de créditocredit locktraba de crédito
No cálculo do atalho "Pix passa do limite de crédito", o pedido prompt adiciona a condição !(total > creditLimit). Fora do prompt essa cláusula é vacuamente verdadeira. Ou seja: o prompt restringe o bypass, não o amplia. Ver Carrinho para as demais travas.In the "Pix bypasses the credit limit" computation, a prompt order adds the condition !(total > creditLimit). Outside prompt that clause is vacuously true. In other words: prompt tightens the bypass, it does not widen it. See Cart for the other locks.En el cálculo del atajo "Pix pasa el límite de crédito", el pedido prompt agrega la condición !(total > creditLimit). Fuera del prompt esa cláusula es vacuamente verdadera. O sea: el prompt restringe el bypass, no lo amplía. Ver Carrito para las demás trabas.
DetectOrderActionStockIssuesUseCase liberação do pedidoorder releaseliberación del pedido
RetornaReturnsDevuelve List<OrderActionStockIssueEntity>
Recebe checkVanStock. Com false, a comparação de quantidade é pulada e só sobram os problemas de "produto ausente do catálogo"; com true, cada linha paga cuja quantidade excede o disponível vira um problema. O notifier do detalhe do pedido só permite liberar se o número de linhas pagas for maior que o número de linhas com problema.It receives checkVanStock. With false, the quantity comparison is skipped and only "product missing from catalog" issues remain; with true, every paid line whose quantity exceeds availability becomes an issue. The order-detail notifier only allows release when the number of paid lines exceeds the number of issue lines.Recibe checkVanStock. Con false, la comparación de cantidad se omite y solo quedan los problemas de "producto ausente del catálogo"; con true, cada línea paga cuya cantidad excede el disponible se vuelve un problema. El notifier del detalle del pedido solo permite liberar si el número de líneas pagas es mayor que el de líneas con problema.
BuildCashPaymentReportDispatcherPayloadUseCase CashPaymentReportAPI
Monta o relatório de caixa a partir do primeiro método do rascunho de pagamento: sapCustomerId, poNumber, orderAmount, username, paymentMethod, referenceNumber (primeira referência de cobrança), documentDate e dateCreated; data ou número de pedido ausentes viram o sentinela "-". A referência da transação é o número do pedido. Disparado quando a origem do registro reporta caixa — pedido prompt e entrega.Builds the cash report from the payment draft's first method: sapCustomerId, poNumber, orderAmount, username, paymentMethod, referenceNumber (first collection reference), documentDate and dateCreated; a missing date or order number becomes the "-" sentinel. The transaction reference is the order number. Fired when the register's origin reports cash — prompt order and delivery.Arma el reporte de caja a partir del primer método del borrador de pago: sapCustomerId, poNumber, orderAmount, username, paymentMethod, referenceNumber (primera referencia de cobranza), documentDate y dateCreated; fecha o número de pedido ausentes se vuelven el centinela "-". La referencia de la transacción es el número del pedido. Se dispara cuando el origen del registro reporta caja — pedido prompt y entrega.
Contexto, State e NotifiersContext, State & NotifiersContexto, State y Notifiers
O ecossistema não tem Notifier próprio — não há tela de prompt. O sinal vive em dois objetos de domínio (o contexto de orquestração e o carrinho) e é consumido por dois Notifiers de outras features. Primeiro os portadores do sinal, depois quem o consome.The ecosystem has no Notifier of its own — there is no prompt screen. The signal lives in two domain objects (the orchestration context and the cart) and is consumed by two Notifiers from other features. First the signal carriers, then the consumers.El ecosistema no tiene Notifier propio — no hay pantalla de prompt. La señal vive en dos objetos de dominio (el contexto de orquestación y el carrito) y es consumida por dos Notifiers de otras features. Primero los portadores de la señal, después quién la consume.
Portadores do sinalSignal carriersPortadores de la señal
CartOrchestrationContextEntity 4 getters relevantes4 relevant getters4 getters relevantes
Entidade Freezed montada pelo cartContextProvider por conta; carrega a configuração de criação de pedido inteira, o catálogo, as promoções e os dados de crédito do varejo. Os getters do ecossistema:A Freezed entity built by cartContextProvider per account; it carries the whole order-creation config, the catalog, the promotions and the retail's credit data. The ecosystem's getters:Entidad Freezed armada por el cartContextProvider por cuenta; carga toda la configuración de creación de pedido, el catálogo, las promociones y los datos de crédito del punto de venta. Los getters del ecosistema:
| getter | DefiniçãoDefinitionDefinición | EfeitoEffectEfecto |
|---|---|---|
isPromptOrder | orderConfig.enablePromptImplementation | o modelo do pedido — decisão de mercado, sem qualquer termo de representante ou de contathe order model — a market decision, with no rep or account term at allel modelo del pedido — decisión de mercado, sin ningún término de representante ni de cuenta |
allowsDeliveryDateChange | !isPromptOrder && !isIndirectOrder | edição da data de entregadelivery-date editingedición de la fecha de entrega |
ignoresPreferredDeliveryDays | isFlexibleDelivery && !hasPromptFulfillment | único uso do hasPromptFulfillment da conta: um varejo com atendimento prompt volta a respeitar os dias preferenciaisthe only use of the account's hasPromptFulfillment: a retail with prompt fulfillment goes back to honoring preferred weekdaysúnico uso del hasPromptFulfillment de la cuenta: un punto de venta con atendimiento prompt vuelve a respetar los días preferidos |
hasPromptFulfillment | @Default(false) bool | campo, não getter — preenchido pelo cartContextProvider a partir do roteiro de entrega da contaa field, not a getter — filled by cartContextProvider from the account's delivery route infocampo, no getter — llenado por el cartContextProvider desde el itinerario de entrega de la cuenta |
CartEntity 3 campos relevantes3 relevant fields3 campos relevantes
| CampoFieldCampo | TipoTypeTipo | OrigemOriginOrigen |
|---|---|---|
isPromptOrder | bool @Default(false) | gravado uma única vez em getEmptyCart; persistido no CartModel e reconstruído de um pedido com ?? falsewritten once in getEmptyCart; persisted on CartModel and rebuilt from an order with ?? falsegrabado una única vez en getEmptyCart; persistido en CartModel y reconstruido de un pedido con ?? false |
isOnTimePayment | bool @Default(false) | ligado pelo representante (intent de pagamento à vista) — ortogonal ao prompt, nunca combinado com ele numa mesma expressãoturned on by the rep (pay-at-sight intent) — orthogonal to prompt, never combined with it in a single expressionactivado por el representante (intent de pago al contado) — ortogonal al prompt, nunca combinado con él en una misma expresión |
items[].batchAllocations | List<CartItemBatchAllocationEntity> | preenchido só em carrinho prompt, pela alocação de lotes; {batchId, quantity}filled only on a prompt cart, by the batch allocation; {batchId, quantity}llenado solo en carrito prompt, por la asignación de lotes; {batchId, quantity} |
Quem consomeThe consumersQuién consume
CartOrchestrator compõe o PromptOrchestratorcomposes the PromptOrchestratorcompone el PromptOrchestrator
getEmptyCart- estampa
isPromptOrderno carrinho novo — o único ponto de decisão do modelo.stampsisPromptOrderon the new cart — the model's only decision point.estampaisPromptOrderen el carrito nuevo — el único punto de decisión del modelo. _applyQuantity- com carrinho prompt, produto conhecido e alvo > 0: carrega o snapshot, corta a quantidade e aloca os lotes antes de fazer o upsert da linha.on a prompt cart, with a known product and target > 0: loads the snapshot, clamps the quantity and allocates batches before upserting the line.con carrito prompt, producto conocido y objetivo > 0: carga el snapshot, recorta la cantidad y asigna los lotes antes de hacer el upsert de la línea.
_evaluate·evaluatePromotionDetail- carregam o snapshot só quando o carrinho é prompt e o injetam no contexto de promoção.load the snapshot only when the cart is prompt and inject it into the promotion context.cargan el snapshot solo cuando el carrito es prompt y lo inyectan en el contexto de promoción.
_availableStock- carrinho não-prompt devolve a constante
_unconstrainedStock(1e12) — "estoque infinito" para o motor de promoções; prompt devolve o disponível real por produto.a non-prompt cart returns the_unconstrainedStockconstant (1e12) — "infinite stock" for the promotion engine; prompt returns the real per-product availability.un carrito no-prompt devuelve la constante_unconstrainedStock(1e12) — "stock infinito" para el motor de promociones; prompt devuelve el disponible real por producto.
OrderDetailNotifier prepareAction
É o único consumidor de presentation do PromptOrchestrator (via ref.read). Em prepareAction: cancelamento retorna antes de qualquer checagem; para as demais intenções calcula checkVanStock = order.isPromptOrder == true && orderConfig.checksVanStockForPromptOrders, e se verdadeiro monta o mapa de disponível por produto (_availableStockByProductSfid: um loadStockSnapshot + um availableStock por linha paga, resolvendo o SFID do produto a partir do SKU da linha). O veredito vai para OrderActionPreparationEntity.canProceed.The only presentation consumer of the PromptOrchestrator (via ref.read). In prepareAction: cancellation returns before any check; for the other intents it computes checkVanStock = order.isPromptOrder == true && orderConfig.checksVanStockForPromptOrders, and when true builds the per-product availability map (_availableStockByProductSfid: one loadStockSnapshot plus one availableStock per paid line, resolving the product SFID from the line's SKU). The verdict goes into OrderActionPreparationEntity.canProceed.Es el único consumidor de presentation del PromptOrchestrator (vía ref.read). En prepareAction: la cancelación retorna antes de cualquier verificación; para las demás intenciones calcula checkVanStock = order.isPromptOrder == true && orderConfig.checksVanStockForPromptOrders, y si es verdadero arma el mapa de disponible por producto (_availableStockByProductSfid: un loadStockSnapshot más un availableStock por línea paga, resolviendo el SFID del producto desde el SKU de la línea). El veredicto va a OrderActionPreparationEntity.canProceed.
OrderPaymentState requiresPaymentConfiguration
GetterGetterGetter isPaymentCreationEnabled && splits.first.cart.isOnTimePayment
É este getter — e não isPromptOrder — que abre a área de configuração de pagamento do pedido. isPaymentCreationEnabled vem do módulo de criação de pagamento visível na configuração de gestão financeira do mercado; o segundo termo é a marca de pagamento à vista. O rascunho, porém, é chaveado e enviado como origem "pedido prompt".It is this getter — not isPromptOrder — that opens the order's payment configuration area. isPaymentCreationEnabled comes from the visible payment-creation module in the market's financial-management config; the second term is the pay-at-sight mark. The draft, however, is keyed and submitted under the "prompt order" origin.Es este getter — y no isPromptOrder — el que abre el área de configuración de pago del pedido. isPaymentCreationEnabled viene del módulo de creación de pago visible en la configuración de gestión financiera del mercado; el segundo término es la marca de pago al contado. El borrador, sin embargo, se clavea y se envía con origen "pedido prompt".
OrderSubmission · PaymentSubmissionOrchestrator pagamento diferidodeferred paymentpago diferido
Depois que todas as parcelas do pedido são despachadas com sucesso, _registerDeferredPayments percorre as parcelas, lê o rascunho prompt_order:<conta>:<índice> (pulando os vazios) e chama o orquestrador de pagamento com origin: promptOrder, isDeferred: true e isAwaitingOrderApproval: split.status.isAwaitingApproval. O orquestrador retorna cedo no caminho diferido: grava o registro de pagamento (ORDER_PA ou CREATED) e não despacha nada. Por fim o rascunho é limpo.After every order split is dispatched successfully, _registerDeferredPayments walks the splits, reads the prompt_order:<account>:<index> draft (skipping empty ones) and calls the payment orchestrator with origin: promptOrder, isDeferred: true and isAwaitingOrderApproval: split.status.isAwaitingApproval. The orchestrator returns early on the deferred path: it stores the payment register (ORDER_PA or CREATED) and dispatches nothing. The draft is then cleared.Después de que todas las cuotas del pedido se despachan con éxito, _registerDeferredPayments recorre las cuotas, lee el borrador prompt_order:<cuenta>:<índice> (salteando los vacíos) y llama al orquestador de pago con origin: promptOrder, isDeferred: true e isAwaitingOrderApproval: split.status.isAwaitingApproval. El orquestador retorna temprano en el camino diferido: graba el registro de pago (ORDER_PA o CREATED) y no despacha nada. Al final el borrador se limpia.
O despacho real (PaymentCollectionAPI, comprovante de pagamento e CashPaymentReportAPI) acontece depois, em syncRegister, disparado da central de dados — nunca no envio do pedido. Consequência: o relatório de caixa de um pedido prompt nunca sai pelo caminho imediato; só pelo de sincronização.The actual dispatch (PaymentCollectionAPI, proof of payment and CashPaymentReportAPI) happens later, in syncRegister, triggered from the data center — never at order submit. Consequence: a prompt order's cash report never goes out through the immediate path; only through the sync one.El despacho real (PaymentCollectionAPI, comprobante de pago y CashPaymentReportAPI) ocurre después, en syncRegister, disparado desde la central de datos — nunca en el envío del pedido. Consecuencia: el reporte de caja de un pedido prompt nunca sale por el camino inmediato; solo por el de sincronización.
DataSyncOrchestrator DataSyncType.stockControl
O estoque da van é um alvo de sync como qualquer outro: DataSyncType.stockControl (habilitado em BR, CL e ZA), dentro de um lote de sincronização, com getCachedLastSyncAt para o TTL (900 s) e execute(source:) para o refresh forçado. É o único caminho que traz estoque novo do backend.Van stock is a sync target like any other: DataSyncType.stockControl (enabled in BR, CL and ZA), inside a sync batch, with getCachedLastSyncAt for the TTL (900 s) and execute(source:) for the forced refresh. It is the only path that brings fresh stock from the backend.El stock de la van es un objetivo de sync como cualquier otro: DataSyncType.stockControl (habilitado en BR, CL y ZA), dentro de un lote de sincronización, con getCachedLastSyncAt para el TTL (900 s) y execute(source:) para el refresh forzado. Es el único camino que trae stock nuevo del backend.
Onde o prompt toca a UIWhere prompt touches the UIDónde el prompt toca la UI
Não existe lib/presentation/prompt/. O ecossistema aparece como comportamento dentro de telas de outras features — a árvore abaixo lista os pontos de toque reais, com o que muda em cada um:There is no lib/presentation/prompt/. The ecosystem shows up as behavior inside other features' screens — the tree below lists the real touchpoints, with what changes at each:No existe lib/presentation/prompt/. El ecosistema aparece como comportamiento dentro de pantallas de otras features — el árbol de abajo lista los puntos de contacto reales, con lo que cambia en cada uno:
- product_showcase vitrine de produtosproduct showcasevitrina de productos
- é aqui que vive o único widget prompt-aware de todo o fluxo de pedido:
ProductShowcaseDeliveryDateWidgetrepassa oisVisibledas regras de data, que é!isPromptOrder— logo a seção de data de entrega desaparece num pedido prompt. Fora dele, nenhum widget consulta o prompt: o corte de quantidade acontece no orquestrador, ao aplicar o intent, e a vitrine não mostra o disponível na van nem esconde produtos sem estoque.this is where the only prompt-aware widget of the whole order flow lives:ProductShowcaseDeliveryDateWidgetforwards the date rules'isVisible, which is!isPromptOrder— so the delivery-date section disappears on a prompt order. Apart from it, no widget consults prompt: the quantity clamp happens in the orchestrator when the intent is applied, and the showcase does not show van availability nor hide out-of-stock products.aquí vive el único widget prompt-aware de todo el flujo de pedido:ProductShowcaseDeliveryDateWidgetreenvía elisVisiblede las reglas de fecha, que es!isPromptOrder— así la sección de fecha de entrega desaparece en un pedido prompt. Fuera de él, ningún widget consulta el prompt: el recorte de cantidad ocurre en el orquestador, al aplicar el intent, y la vitrina no muestra el disponible en la van ni oculta productos sin stock.
- é aqui que vive o único widget prompt-aware de todo o fluxo de pedido:
- cart_review revisão do carrinhocart reviewrevisión del carrito
- zero referência a prompt. O que existe aqui é o botão de pagamento à vista (dirigido por
allowOrderPlacementWithCreditDays0), que liga a marcaisOnTimePaymente é, hoje, o que destrava a área de pagamento descrita abaixo.zero prompt references. What lives here is the pay-at-sight button (driven byallowOrderPlacementWithCreditDays0), which turns on theisOnTimePaymentmark and is, today, what unlocks the payment area described below.cero referencias a prompt. Lo que existe aquí es el botón de pago al contado (dirigido porallowOrderPlacementWithCreditDays0), que activa la marcaisOnTimePaymenty es, hoy, lo que destraba el área de pago descrita abajo. - a pílula de entrega estimada (
OrderPlacementDeliveryPill) é renderizada sem oisVisibledas regras de data — o parâmetro tem defaulttrue, então ela só desaparece se a data vier vazia. Num pedido prompt a data resolvida é hoje, logo a pílula aparece aqui e no pagamento, ao contrário da vitrine. É defeito de gating, registrado nas Pendências.the estimated delivery pill (OrderPlacementDeliveryPill) is rendered without the date rules'isVisible— the parameter defaults totrue, so it only disappears when the date comes in empty. On a prompt order the resolved date is today, so the pill does show here and in the payment step, unlike in the showcase. This is a gating defect, recorded under Pending items.la píldora de entrega estimada (OrderPlacementDeliveryPill) se renderiza sin elisVisiblede las reglas de fecha — el parámetro tiene defaulttrue, así que solo desaparece si la fecha viene vacía. En un pedido prompt la fecha resuelta es hoy, por lo tanto la píldora aparece aquí y en el pago, al contrario de la vitrina. Es defecto de gating, registrado en Pendientes.
- zero referência a prompt. O que existe aqui é o botão de pagamento à vista (dirigido por
- order_payment a única área com widget dedicadothe only area with a dedicated widgetla única área con widget dedicado
- OrderPaymentSplitBlockWidget — renderiza o bloco de configuração por parcela sem condição; o filho se auto-esconde (§27).renders the configuration block per split unconditionally; the child self-hides (§27).renderiza el bloque de configuración por cuota sin condición; el hijo se auto-oculta (§27).
- OrderPaymentConfigurePaymentWidget — sai cedo se
!requiresPaymentConfiguration. Configurado, mostra o visto verde; não configurado, o botão. Ao tocar, semeia um débito sintético (nome de tradução, valor = total da parcela,creditPeriod = -1, sem SFID de título) e navega para a criação de pagamento comorigin: promptOrder.bails out when!requiresPaymentConfiguration. Configured, it shows the green check; not configured, the button. On tap it seeds a synthetic debit (translated name, amount = split total,creditPeriod = -1, no open-item SFID) and navigates to payment creation withorigin: promptOrder.sale temprano si!requiresPaymentConfiguration. Configurado, muestra el visto verde; no configurado, el botón. Al tocar, siembra un débito sintético (nombre de traducción, monto = total de la cuota,creditPeriod = -1, sin SFID de documento) y navega a la creación de pago conorigin: promptOrder.- → payment_creation (tela de outra feature): com esta origem, valor não editável, um único método, sem entrada de link de pagamento, botão Salvar e nenhum despacho — o rascunho fica em memória.→ payment_creation (another feature's screen): with this origin, non-editable amount, a single method, no payment-link entry, Save button and no dispatch — the draft stays in memory.→ payment_creation (pantalla de otra feature): con este origen, monto no editable, un único método, sin entrada de link de pago, botón Guardar y ningún despacho — el borrador queda en memoria.
- OrderPaymentConfigurePaymentWidget — sai cedo se
- OrderPaymentFooterWidget — varre todas as parcelas; se qualquer rascunho estiver nulo ou sem método, desabilita o botão de confirmar.sweeps every split; if any draft is null or method-less, it disables the confirm button.recorre todas las cuotas; si algún borrador está nulo o sin método, deshabilita el botón de confirmar.
- OrderPaymentSplitBlockWidget — renderiza o bloco de configuração por parcela sem condição; o filho se auto-esconde (§27).renders the configuration block per split unconditionally; the child self-hides (§27).renderiza el bloque de configuración por cuota sin condición; el hijo se auto-oculta (§27).
- order_confirmation
- zero referência a prompt — o registro do pagamento diferido acontece antes desta tela, no fluxo de envio.zero prompt references — the deferred payment register happens before this screen, in the submit flow.cero referencias a prompt — el registro del pago diferido ocurre antes de esta pantalla, en el flujo de envío.
- order_detail liberar / editar / cancelarrelease / edit / cancelliberar / editar / cancelar
- a etiqueta de status renderiza o valor cru do pedido — é aqui que Prompt Fulfillment aparece.the status pill renders the order's raw value — this is where Prompt Fulfillment shows up.la etiqueta de estado renderiza el valor crudo del pedido — aquí es donde aparece Prompt Fulfillment.
- a preparação da ação roda a checagem de estoque da van e devolve as linhas problemáticas para o modal de confirmação. Ver Detalhe do pedido.action preparation runs the van-stock check and returns the problem lines to the confirmation modal. See Order detail.la preparación de la acción corre la verificación de stock de la van y devuelve las líneas problemáticas al modal de confirmación. Ver Detalle del pedido.
- orders
- etiqueta e filtro de status aceitam Prompt Fulfillment como qualquer outro valor; a cor vem do grupo (pedidos realizados). Ver Lista de pedidos.tag and status filter accept Prompt Fulfillment like any other value; the color comes from the group (ordered). See Order list.etiqueta y filtro de estado aceptan Prompt Fulfillment como cualquier otro valor; el color viene del grupo (pedidos realizados). Ver Lista de pedidos.
- journey · end_journey por tipo de representanteby resource typepor tipo de representante
- o notifier resolve o tipo do representante e pede ao EMC as categorias visíveis; um Prompt-sales Rep recebe categorias que outros tipos não recebem. As ações por categoria passam pelo mesmo filtro. Ver Jornada.the notifier resolves the rep type and asks the EMC for the visible categories; a Prompt-sales Rep gets categories other types don't. Per-category actions go through the same filter. See Journey.el notifier resuelve el tipo de representante y pide al EMC las categorías visibles; un Prompt-sales Rep recibe categorías que otros tipos no. Las acciones por categoría pasan por el mismo filtro. Ver Jornada.
- reports · visit_end
- a página de relatórios filtra as opções pelo tipo do representante — status de entrega é exclusivo de Prompt-sales e Universal. As categorias de fim de visita usam o mesmo mecanismo. Ver Relatórios e Pesquisas.the reports page filters options by rep type — delivery status is exclusive to Prompt-sales and Universal. Visit-end categories use the same mechanism. See Reports and Surveys.la página de reportes filtra las opciones por tipo de representante — estado de entrega es exclusivo de Prompt-sales y Universal. Las categorías de fin de visita usan el mismo mecanismo. Ver Reportes y Encuestas.
- data_center central de dadosdata centercentral de datos
- é de onde a sincronização dos registros de pagamento pendentes é disparada — o passo que finalmente despacha a cobrança e o relatório de caixa do pedido prompt. Ainda sem doc própria.this is where the sync of pending payment registers is triggered — the step that finally dispatches the prompt order's collection and cash report. No doc of its own yet.es desde donde se dispara la sincronización de los registros de pago pendientes — el paso que finalmente despacha la cobranza y el reporte de caja del pedido prompt. Aún sin doc propia.
- deliveries_of_the_day
- estrutura paralela e independente: usa a origem de pagamento entrega, com título em aberto real, e nunca consulta a marca de prompt do pedido. Ver Entregas do dia.a parallel, independent structure: it uses the delivery payment origin, with a real open item, and never consults the order's prompt mark. See Deliveries of the day.estructura paralela e independiente: usa el origen de pago entrega, con documento abierto real, y nunca consulta la marca de prompt del pedido. Ver Entregas del día.
Notas por mercadoMarket notesNotas por mercado
O ecossistema é dirigido por End Market Configuration (orderCreationConfig). Os três mercados ativos têm o bloco e as três chaves de prompt, mas o interruptor de entrada está desligado nos três; AR/PY/PE não têm orderCreationConfig (só quatro chaves de topo: version, updateConfig, newRetailConfig, visitsConfig):The ecosystem is driven by End Market Configuration (orderCreationConfig). The three active markets carry the block and the three prompt keys, but the entry switch is off in all three; AR/PY/PE have no orderCreationConfig (only four top-level keys: version, updateConfig, newRetailConfig, visitsConfig):El ecosistema se rige por End Market Configuration (orderCreationConfig). Los tres mercados activos tienen el bloque y las tres claves de prompt, pero el interruptor de entrada está apagado en los tres; AR/PY/PE no tienen orderCreationConfig (solo cuatro claves de tope: version, updateConfig, newRetailConfig, visitsConfig):
Matriz das chaves de orderCreationConfig que o ecossistema prompt lê ou altera — uma linha por chave (o bloco tem 33 chaves; as demais estão em Carrinho):Matrix of the orderCreationConfig keys the prompt ecosystem reads or changes — one row per key (the block has 33 keys; the rest are in Cart):Matriz de las claves de orderCreationConfig que el ecosistema prompt lee o altera — una fila por clave (el bloque tiene 33 claves; las demás están en Carrito):
| ChaveKeyClave | BR | CL | ZA | AR | PY | PE |
|---|---|---|---|---|---|---|
enablePromptImplementation | false | false | false | — | — | — |
checksVanStockForPromptOrders | true | true | false | — | — | — |
promptOrderUsesExternalApproval | true | false | false | — | — | — |
sendsInvoiceRefOnExternalApproval | true | false | false | — | — | — |
sendsAlteredFullFlag | true | false | true | — | — | — |
usesSecondaryUomForAllCategories | false | false | true | — | — | — |
allowOrderPlacementWithCreditDays0 | false | true | false | — | — | — |
allowPixOverCreditLimit | true | false | false | — | — | — |
Chaves adjacentes fora de orderCreationConfig, também exaustivas: dataFreshnessConfig.ttlSecondsByType.stockControl = 900 em BR/CL/ZA e ausente em AR/PY/PE (que têm dataFreshnessConfig nulo); financialManagementConfig.modules[financial_management_payment_creation] — presente e visível só no CL, ausente em BR/ZA — é a segunda condição para a área de pagamento do pedido existir.Adjacent keys outside orderCreationConfig, also exhaustive: dataFreshnessConfig.ttlSecondsByType.stockControl = 900 in BR/CL/ZA and absent in AR/PY/PE (whose dataFreshnessConfig is null); financialManagementConfig.modules[financial_management_payment_creation] — present and visible in CL only, absent in BR/ZA — is the second condition for the order payment area to exist at all.Claves adyacentes fuera de orderCreationConfig, también exhaustivas: dataFreshnessConfig.ttlSecondsByType.stockControl = 900 en BR/CL/ZA y ausente en AR/PY/PE (cuyo dataFreshnessConfig es nulo); financialManagementConfig.modules[financial_management_payment_creation] — presente y visible solo en CL, ausente en BR/ZA — es la segunda condición para que el área de pago del pedido exista.
Matriz do eixo Prompt-sales Rep — todos os itens do EMC com allowedResourceTypes, uma linha por item. A célula responde "um Prompt-sales Rep enxerga este item?": 🟢 sim · 🟠 não (lista restrita a outros tipos) · ⚪ item ou bloco ausente no mercado. Lista vazia significa "sem restrição de tipo" e portanto conta como 🟢.Matrix of the Prompt-sales Rep axis — every EMC item with allowedResourceTypes, one row per item. The cell answers "does a Prompt-sales Rep see this item?": 🟢 yes · 🟠 no (list restricted to other types) · ⚪ item or block absent in that market. An empty list means "no type restriction" and therefore counts as 🟢.Matriz del eje Prompt-sales Rep — todos los ítems del EMC con allowedResourceTypes, una fila por ítem. La celda responde "¿un Prompt-sales Rep ve este ítem?": 🟢 sí · 🟠 no (lista restringida a otros tipos) · ⚪ ítem o bloque ausente en el mercado. Lista vacía significa "sin restricción de tipo" y por lo tanto cuenta como 🟢.
| Área · itemArea · itemÁrea · ítem | BR | CL | ZA | AR | PY | PE |
|---|---|---|---|---|---|---|
reportsConfig.options[delivery_status] Prompt+Universal | x | x | — | — | — | — |
reportsConfig.options[daily_summary] Pre+Prompt+Universal | x | x | — | — | — | — |
journeyConfig.fields[odometer] [] | x | x | x | — | — | — |
journeyConfig.fields[car_license_plate] [] | x | — | — | — | — | — |
visitEndConfig.categories[mandatory_surveys] 6 | x | — | x | — | — | — |
visitEndConfig.categories[optional_surveys] 6 | x | — | x | — | — | — |
visitEndConfig.categories[stock_count] 6 | x | — | x | — | — | — |
visitEndConfig.categories[smart_investment] [] | x | — | — | — | — | — |
visitEndConfig.categories[pending_tasks] [] | x | x | x | — | — | — |
visitEndConfig.categories[unsynced_transactions] [] | x | x | x | — | — | — |
endJourneyConfig.categories[pending_visits] [] | x | x | x | — | — | — |
endJourneyConfig.categories[pending_orders] 6 BR/CL · [] ZA | x | x | x | — | — | — |
endJourneyConfig.categories[pending_deliveries] Prompt+Delivery | x | x | — | — | — | — |
endJourneyConfig.categories[pending_buybacks] Prompt+Delivery | x | x | — | — | — | — |
endJourneyConfig.categories[pending_payments] Prompt | — | x | — | — | — | — |
endJourneyConfig.categories[pending_collections] [] | — | x | — | — | — | — |
endJourneyConfig.categories[unsynced_transactions] [] | x | x | x | — | — | — |
endJourneyConfig…actions[no_buy_visit] 6 | x | x | x | — | — | — |
endJourneyConfig…actions[open_detail] [] | x | x | x | — | — | — |
endJourneyConfig…actions[cancel_visit] [] | x | x | x | — | — | — |
Nota de implementação: a opção de relatório é a única cujo predicado não tem escape para lista vazia — uma lista vazia em reportsConfig esconderia o relatório de todos os tipos, ao contrário das outras quatro áreas, onde vazio libera para todos.Implementation note: the report option is the only predicate without an empty-list escape — an empty list in reportsConfig would hide the report from every type, unlike the other four areas, where empty allows everyone.Nota de implementación: la opción de reporte es el único predicado sin escape para lista vacía — una lista vacía en reportsConfig ocultaría el reporte de todos los tipos, a diferencia de las otras cuatro áreas, donde vacío habilita a todos.
BrasilBrazilBrasil
O mercado mais preparado para prompt no papel: único com promptOrderUsesExternalApproval: true (o pedido prompt sairia como Pending External Approval) e o único com sendsInvoiceRefOnExternalApproval: true, que casa com esse status para preencher invoiceRefNo — as duas chaves são internamente consistentes. Também checa estoque da van na liberação (checksVanStockForPromptOrders: true). É o único mercado com car_license_plate na jornada, e o único onde o Prompt-sales Rep vê categorias de fim de visita restritas por tipo. Nada disso é exercido enquanto enablePromptImplementation for false.
On paper the market most prepared for prompt: the only one with promptOrderUsesExternalApproval: true (a prompt order would leave as Pending External Approval) and the only one with sendsInvoiceRefOnExternalApproval: true, which pairs with that status to fill invoiceRefNo — the two keys are internally consistent. It also checks van stock on release (checksVanStockForPromptOrders: true). It is the only market with car_license_plate in the journey, and the only one where the Prompt-sales Rep sees type-restricted visit-end categories. None of this is exercised while enablePromptImplementation is false.
En el papel, el mercado más preparado para prompt: el único con promptOrderUsesExternalApproval: true (el pedido prompt saldría como Pending External Approval) y el único con sendsInvoiceRefOnExternalApproval: true, que combina con ese estado para llenar invoiceRefNo — las dos claves son internamente consistentes. También revisa el stock de la van en la liberación (checksVanStockForPromptOrders: true). Es el único mercado con car_license_plate en la jornada, y el único donde el Prompt-sales Rep ve categorías de fin de visita restringidas por tipo. Nada de esto se ejercita mientras enablePromptImplementation sea false.
ChileChileChile
O único mercado onde a perna de pagamento do prompt roda hoje: é o único com allowOrderPlacementWithCreditDays0: true (o botão de pagamento à vista) e com o módulo de criação de pagamento visível — as duas condições do requiresPaymentConfiguration. Também checa estoque da van, mas sem aprovação externa: um pedido prompt sairia direto como Invoiced Not Sync. É o único com a categoria de fim de jornada pending_payments, exclusiva do Prompt-sales Rep (a única lista de um único tipo em todo o EMC), e o único que exige pagamento integral do Pre-sales Rep — poupando o Prompt-sales.
The only market where the prompt payment leg runs today: the only one with allowOrderPlacementWithCreditDays0: true (the pay-at-sight button) and the payment-creation module visible — the two conditions of requiresPaymentConfiguration. It also checks van stock, but without external approval: a prompt order would leave straight as Invoiced Not Sync. It is the only one with the pending_payments end-of-journey category, exclusive to the Prompt-sales Rep (the only single-type list in the whole EMC), and the only one requiring full payment from the Pre-sales Rep — sparing the Prompt-sales one.
El único mercado donde la pierna de pago del prompt corre hoy: es el único con allowOrderPlacementWithCreditDays0: true (el botón de pago al contado) y con el módulo de creación de pago visible — las dos condiciones del requiresPaymentConfiguration. También revisa el stock de la van, pero sin aprobación externa: un pedido prompt saldría directo como Invoiced Not Sync. Es el único con la categoría de fin de jornada pending_payments, exclusiva del Prompt-sales Rep (la única lista de un único tipo en todo el EMC), y el único que exige pago íntegro del Pre-sales Rep — eximiendo al Prompt-sales.
África do SulSouth AfricaSudáfrica
O menos preparado dos três: as três chaves de prompt existem, mas todas em false — um pedido prompt sairia como Invoiced Not Sync e a liberação não checaria estoque da van (só apontaria produto ausente do catálogo). Não tem reportsConfig, então nenhum tipo de representante vê relatório. Não tem as categorias de fim de jornada de entrega, devolução, pagamento e cobrança. Em compensação, é o único com usesSecondaryUomForAllCategories: true, o que faz todo o cálculo de disponível e de alocação de lotes passar pela conversão de unidade. Curiosidade dos dados: os únicos pedidos com status Prompt Fulfillment em todos os mocks são 4 pedidos do dump real de ZA.
The least prepared of the three: the three prompt keys exist, but all are false — a prompt order would leave as Invoiced Not Sync and release would not check van stock (only flagging products missing from the catalog). It has no reportsConfig, so no rep type sees any report. It lacks the end-of-journey categories for deliveries, buybacks, payments and collections. On the other hand it is the only one with usesSecondaryUomForAllCategories: true, which routes every availability and batch-allocation computation through the unit conversion. A data curiosity: the only orders with status Prompt Fulfillment across all mocks are 4 orders in the ZA real dump.
El menos preparado de los tres: las tres claves de prompt existen, pero todas en false — un pedido prompt saldría como Invoiced Not Sync y la liberación no revisaría el stock de la van (solo señalaría producto ausente del catálogo). No tiene reportsConfig, así que ningún tipo de representante ve reportes. Le faltan las categorías de fin de jornada de entrega, devolución, pago y cobranza. En cambio, es el único con usesSecondaryUomForAllCategories: true, lo que hace que todo el cálculo de disponible y de asignación de lotes pase por la conversión de unidad. Curiosidad de los datos: los únicos pedidos con estado Prompt Fulfillment en todos los mocks son 4 pedidos del dump real de ZA.
Argentina · Paraguai · PeruArgentina · Paraguay · PeruArgentina · Paraguay · Perú
Existem como mercados do app, mas o bloco orderCreationConfig está integralmente ausente nos três (config mínima PANGEA, com apenas quatro chaves de topo). Sem o bloco, as três chaves de prompt caem no @Default(false) e nada do ecossistema existe — não há criação de pedido, nem sync de estoque da van (dataFreshnessConfig é nulo), nem allowedResourceTypes em lugar nenhum.
They exist as app markets, but the orderCreationConfig block is entirely absent in all three (minimal PANGEA config, with only four top-level keys). Without the block, the three prompt keys fall back to @Default(false) and none of the ecosystem exists — no order creation, no van-stock sync (dataFreshnessConfig is null), no allowedResourceTypes anywhere.
Existen como mercados de la app, pero el bloque orderCreationConfig está integralmente ausente en los tres (config mínima PANGEA, con solo cuatro claves de tope). Sin el bloque, las tres claves de prompt caen en @Default(false) y nada del ecosistema existe — no hay creación de pedido, ni sync de stock de la van (dataFreshnessConfig es nulo), ni allowedResourceTypes en ninguna parte.
Pendências / roadmapPending / roadmapPendientes / roadmap
O que existe hoje é o lado de leitura do modelo van-sales (estoque por lote, corte de quantidade, alocação, data de hoje, status e campos de payload) — a fase de UI e operações Prompt está adiada por decisão de produto. Os itens abaixo são medidos no código atual ou levantados no legado flutter-bat-salesrep, e estão listados como ainda não portados — nunca como existentes:
What exists today is the read side of the van-sales model (stock per batch, quantity clamp, allocation, today's date, status and payload fields) — the Prompt UI & operations phase is deferred by product decision. The items below are measured in the current code or surveyed in the legacy flutter-bat-salesrep, and are listed as not yet ported — never as present:
Lo que existe hoy es el lado de lectura del modelo van-sales (stock por lote, recorte de cantidad, asignación, fecha de hoy, estado y campos de payload) — la fase de UI y operaciones Prompt está diferida por decisión de producto. Los ítems de abajo se miden en el código actual o se levantaron en el legado flutter-bat-salesrep, y se listan como aún no portados — nunca como existentes:
- O interruptor está desligado em todos os mercados e ambientes.
enablePromptImplementation: falseem BR/CL/ZA nos três arquivos de EMC (prod, UAT, preprod) e ausente em AR/PY/PE. Logo todo ramo prompt do carrinho e do payload está inerte hoje — inclusive o corte de quantidade: fora do prompt o disponível é a constante1e12. Uma exceção importante: o detalhe do pedido não depende desse interruptor — ele chaveia emorder.isPromptOrder, o campo que vem persistido do backend, cruzado comchecksVanStockForPromptOrders(true em BR/CL). Ou seja, qualquer pedido que chegue marcado como prompt já dispara a checagem de estoque da van hoje — e os dumps reais trazem 13 pedidos assim em BR e 11 em CL.The switch is off in every market and environment.enablePromptImplementation: falsein BR/CL/ZA across all three EMC files (prod, UAT, preprod) and absent in AR/PY/PE. So every prompt branch in the cart and in the payload is inert today — including the quantity clamp: outside prompt, availability is the1e12constant. One important exception: the order detail does not depend on that switch — it keys onorder.isPromptOrder, the field persisted from the backend, crossed withchecksVanStockForPromptOrders(true in BR/CL). Meaning any order arriving flagged as prompt already triggers the van-stock check today — and the real dumps carry 13 such orders in BR and 11 in CL.El interruptor está apagado en todos los mercados y ambientes.enablePromptImplementation: falseen BR/CL/ZA en los tres archivos de EMC (prod, UAT, preprod) y ausente en AR/PY/PE. Por lo tanto toda rama prompt del carrito y del payload está inerte hoy — incluido el recorte de cantidad: fuera del prompt el disponible es la constante1e12. Una excepción importante: el detalle del pedido no depende de ese interruptor — chavea enorder.isPromptOrder, el campo que llega persistido del backend, cruzado conchecksVanStockForPromptOrders(true en BR/CL). Es decir, cualquier pedido que llegue marcado como prompt ya dispara la verificación de stock de la van hoy — y los dumps reales traen 13 pedidos así en BR y 11 en CL. - Nenhuma tela de operação de van foi portada. O legado tem ~20 telas prompt (pedido de carga, resumo do pedido, alocação de estoque, visão de estoque, reconciliação, descarga total e parcial, seletor de lote de fabricação, itens pendentes, status de sincronização e 8 relatórios). No app novo não existe
lib/presentation/prompt/nem equivalente.No van-operation screen was ported. The legacy app has ~20 prompt screens (load request, request summary, stock allocation, stock view, reconciliation, full and partial unload, manufacturing-batch picker, pending items, sync status and 8 reports). In the new app there is nolib/presentation/prompt/nor equivalent.Ninguna pantalla de operación de van fue portada. El legado tiene ~20 pantallas prompt (pedido de carga, resumen del pedido, asignación de stock, vista de stock, reconciliación, descarga total y parcial, selector de lote de fabricación, ítems pendientes, estado de sincronización y 8 reportes). En la app nueva no existelib/presentation/prompt/ni equivalente. - Cinco transações declaradas sem builder.
orderInvoice(Invoiceupload— o serviço dedicado do pedido prompt no legado),stockUnload(VanUnloadAPI),stockReconciliation,stockRequestestockAllocationExecutionexistem no enumDispatcherType(BR/CL) mas não têmBuild*DispatcherPayloadUseCase, submitter, input nem UI. Hoje um pedido prompt sai pelos mesmos serviços do pré-venda, e o payload não tem o campo de record type ("Prompt Sales" vs "Pre Sales") que o legado enviava.Five declared transactions with no builder.orderInvoice(Invoiceupload— the legacy prompt order's dedicated service),stockUnload(VanUnloadAPI),stockReconciliation,stockRequestandstockAllocationExecutionexist in theDispatcherTypeenum (BR/CL) but have noBuild*DispatcherPayloadUseCase, submitter, input or UI. Today a prompt order goes out through the same services as pre-sales, and the payload has no record type field ("Prompt Sales" vs "Pre Sales") that legacy used to send.Cinco transacciones declaradas sin builder.orderInvoice(Invoiceupload— el servicio dedicado del pedido prompt en el legado),stockUnload(VanUnloadAPI),stockReconciliation,stockRequestystockAllocationExecutionexisten en el enumDispatcherType(BR/CL) pero no tienenBuild*DispatcherPayloadUseCase, submitter, input ni UI. Hoy un pedido prompt sale por los mismos servicios que la preventa, y el payload no tiene el campo de record type ("Prompt Sales" vs "Pre Sales") que el legado enviaba. - Não há escrita local de estoque, nem rastreio de pedido, nem devolução de estoque. O legado decrementava o estoque local depois que o pedido atingia um status confirmado, marcava o consumo como idempotente e devolvia o estoque quando a aprovação externa falhava ou o pedido era cancelado (com um websocket no Brasil acompanhando o status). No app novo não existe nada disso: o domínio de estoque é só leitura e o app espera o próximo sync.There is no local stock write, no order tracking and no stock give-back. Legacy decremented local stock after the order reached a confirmed status, marked the consumption idempotently and gave the stock back when external approval failed or the order was cancelled (with a websocket in Brazil watching the status). None of that exists in the new app: the stock domain is read-only and the app waits for the next sync.No hay escritura local de stock, ni rastreo de pedido, ni devolución de stock. El legado decrementaba el stock local después de que el pedido alcanzaba un estado confirmado, marcaba el consumo como idempotente y devolvía el stock cuando la aprobación externa fallaba o el pedido se cancelaba (con un websocket en Brasil siguiendo el estado). En la app nueva no existe nada de eso: el dominio de stock es solo lectura y la app espera el próximo sync.
- O disponível não distingue o tipo do lote. O cálculo soma
availableQuantityde todos os lotes do produto, sem filtrar porStockType— lotes devan_load,stock_countestock_viewentram no mesmo total. Nos mocks sintéticos de BR e CL os três tipos convivem, então o número que o corte de quantidade usaria não é só a carga da van. E nos dumps reais o efeito é mais forte ainda: nenhum deles tem um único lotevan_load— BR e CL são todosstock_viewe a África do Sul é todastock_count, ou seja, o "disponível na van" viria inteiro de contagem e visão de loja.Availability does not distinguish batch type. The computation sumsavailableQuantityacross all of the product's batches, without filtering byStockType—van_load,stock_countandstock_viewbatches land in the same total. In the BR and CL synthetic mocks the three types coexist, so the number the clamp would use is not only the van load. And in the real dumps the effect is stronger still: not one of them holds a singlevan_loadbatch — BR and CL are allstock_viewand South Africa is allstock_count, so "van availability" would come entirely from store counts and store views.El disponible no distingue el tipo del lote. El cálculo sumaavailableQuantityde todos los lotes del producto, sin filtrar porStockType— lotes devan_load,stock_countystock_viewcaen en el mismo total. En los mocks sintéticos de BR y CL los tres tipos conviven, así que el número que usaría el recorte no es solo la carga de la van. Y en los dumps reales el efecto es aún más fuerte: ninguno tiene un solo lotevan_load— BR y CL son todosstock_viewy Sudáfrica es todostock_count, o sea, el "disponible en la van" vendría íntegro de conteos y vistas de tienda. - A pílula de entrega estimada não é filtrada por prompt em dois dos três lugares onde aparece. Só a vitrine repassa o
isVisibledas regras de data (!isPromptOrder); na revisão do carrinho e no pagamento a pílula é construída sem esse parâmetro, cujo default étrue. Num pedido prompt a data resolvida é hoje, então o representante continua lendo "entrega estimada: hoje" exatamente onde o conceito não se aplica.The estimated-delivery pill isn't filtered by prompt in two of the three places it shows up. Only the showcase forwards the date rules'isVisible(!isPromptOrder); in the cart review and in the payment step the pill is built without that parameter, whose default istrue. On a prompt order the resolved date is today, so the rep keeps reading "estimated delivery: today" exactly where the concept doesn't apply.La píldora de entrega estimada no se filtra por prompt en dos de los tres lugares donde aparece. Solo la vitrina reenvía elisVisiblede las reglas de fecha (!isPromptOrder); en la revisión del carrito y en el pago la píldora se construye sin ese parámetro, cuyo default estrue. En un pedido prompt la fecha resuelta es hoy, así que el representante sigue leyendo "entrega estimada: hoy" justo donde el concepto no se aplica. - A segunda emissão da data de entrega no payload não tem ramo prompt. O builder emite a data em dois lugares: um deles aplica o curto-circuito do prompt, o outro escreve a data crua do carrinho. Esse segundo caminho atende edição e cancelamento — logo, se o interruptor for ligado, um pedido prompt editado sai com data de entrega inconsistente entre as duas chaves do mesmo payload.The payload's second delivery-date emission has no prompt branch. The builder writes the date in two places: one applies the prompt short-circuit, the other writes the cart's raw date. That second path serves editing and cancellation — so, once the switch is on, an edited prompt order goes out with an inconsistent delivery date between the two keys of the same payload.La segunda emisión de la fecha de entrega en el payload no tiene rama prompt. El builder emite la fecha en dos lugares: uno aplica el cortocircuito del prompt, el otro escribe la fecha cruda del carrito. Ese segundo camino atiende edición y cancelación — así que, si se enciende el interruptor, un pedido prompt editado sale con fecha de entrega inconsistente entre las dos claves del mismo payload.
- Não existe uma única chave de tradução de prompt. Nenhum texto localizado nomeia o modelo prompt, o estoque da van ou a venda direta em nenhum dos seis mercados — hoje isso não incomoda porque nada é exibido, mas ligar o interruptor sem antes criar as chaves nos seis mercados (§10 do padrão de código) deixaria a funcionalidade sem texto.There isn't a single prompt translation key. No localized text names the prompt model, the van stock or direct selling in any of the six markets — that goes unnoticed today because nothing is displayed, but turning the switch on without first creating the keys in all six markets (§10 of the code standard) would leave the feature with no copy.No existe ni una sola clave de traducción de prompt. Ningún texto localizado nombra el modelo prompt, el stock de la van ni la venta directa en ninguno de los seis mercados — hoy no molesta porque nada se muestra, pero encender el interruptor sin antes crear las claves en los seis mercados (§10 del estándar de código) dejaría la funcionalidad sin texto.
- Sem seleção manual de lote. A alocação percorre os lotes na ordem em que vieram do backend, sem ordenar por validade. No legado, um produto com mais de um lote abria uma tela de escolha manual — o app novo aloca em silêncio.No manual batch selection. Allocation walks the batches in backend order, without sorting by expiry. In legacy, a product with more than one batch opened a manual picker — the new app allocates silently.Sin selección manual de lote. La asignación recorre los lotes en el orden en que vinieron del backend, sin ordenar por vencimiento. En el legado, un producto con más de un lote abría una pantalla de elección manual — la app nueva asigna en silencio.
- Toda a pilha de nota fiscal eletrônica do Chile está fora. Geração/cancelamento/sincronização de documento no dispositivo, número legal, impressora térmica por Bluetooth e inicialização do contexto no início da jornada: zero equivalente no app novo. No legado isso era pré-requisito bloqueante do checkout prompt em CL.Chile's whole electronic-invoice stack is out. On-device document generation/cancellation/sync, legal number, Bluetooth thermal printer and context initialization at journey start: zero equivalent in the new app. In legacy that was a blocking prerequisite for the prompt checkout in CL.Toda la pila de factura electrónica de Chile está fuera. Generación/cancelación/sincronización de documento en el dispositivo, número legal, impresora térmica por Bluetooth e inicialización del contexto al inicio de la jornada: cero equivalente en la app nueva. En el legado eso era un prerrequisito bloqueante del checkout prompt en CL.
- Sem resumo de estoque de viagem nem travas de jornada por prompt. O legado enviava um resumo de estoque no início e no fim da jornada e só deixava fechar a jornada com zero pedidos prompt pendentes, zero devoluções, zero entregas do dia e a reconciliação executada. Nada disso existe hoje.No trip stock summary and no prompt-driven journey gates. Legacy sent a stock summary at journey start and end, and only allowed closing the journey with zero pending prompt orders, zero buybacks, zero deliveries of the day and the reconciliation executed. None of that exists today.Sin resumen de stock de viaje ni trabas de jornada por prompt. El legado enviaba un resumen de stock al inicio y al fin de la jornada y solo permitía cerrar la jornada con cero pedidos prompt pendientes, cero devoluciones, cero entregas del día y la reconciliación ejecutada. Nada de eso existe hoy.
- Sem gestão pós-envio do pedido prompt. O legado tinha, no detalhe do pedido, checagem de status, aprovar, cancelar com trava de 5 minutos, impressão da nota e restrição de que as ações só valiam no mesmo dia. O app novo tem só o fluxo genérico de liberar/editar/cancelar.No post-submit management of the prompt order. In legacy the order detail had status check, approve, cancel with a 5-minute hold, invoice printing, and the restriction that the actions were same-day only. The new app has only the generic release/edit/cancel flow.Sin gestión post-envío del pedido prompt. El legado tenía, en el detalle del pedido, verificación de estado, aprobar, cancelar con traba de 5 minutos, impresión de la factura y la restricción de que las acciones solo valían el mismo día. La app nueva tiene solo el flujo genérico de liberar/editar/cancelar.
- O flag do cadastro do representante não é lido por nada.
ResourceFeatureFlags.enablePromptImplementation(campo 2 do proto) atravessa proto → DTO → Entity → ObjectBox e volta, mas zero regra de negócio o consulta; o caminho de login por Salesforce ainda o constrói fixo emfalse— e vale dizer que isso não é descuido específico do prompt: nenhum campo deResourceFeatureFlagstem leitor de negócio hoje, todos são fixados no mesmo lugar. Ele nunca é combinado com a chave homônima do EMC, que é a única que gate de fato. No legado o gate era exatamente a conjunção "versão prompt + mercado BR/CL + tipo do representante = Prompt-sales Rep" — a decisão por representante não foi portada.The rep-record flag is read by nothing.ResourceFeatureFlags.enablePromptImplementation(proto field 2) travels proto → DTO → Entity → ObjectBox and back, but zero business rules consult it; the Salesforce login path still builds it hardcoded tofalse— and this is not a prompt-specific oversight: no field ofResourceFeatureFlagshas a business reader today, they are all hardcoded in the same place. It is never combined with the EMC key of the same name, which is the only one that actually gates. In legacy the gate was exactly the conjunction "prompt version + market BR/CL + rep type = Prompt-sales Rep" — the per-rep decision was not ported.La flag del registro del representante no la lee nadie.ResourceFeatureFlags.enablePromptImplementation(campo 2 del proto) atraviesa proto → DTO → Entity → ObjectBox y vuelve, pero cero reglas de negocio la consultan; el camino de login por Salesforce aún la construye fija enfalse— y vale decir que no es un descuido específico del prompt: ningún campo deResourceFeatureFlagstiene lector de negocio hoy, todos se fijan en el mismo lugar. Nunca se combina con la clave homónima del EMC, que es la única que realmente hace gate. En el legado el gate era exactamente la conjunción "versión prompt + mercado BR/CL + tipo de representante = Prompt-sales Rep" — la decisión por representante no fue portada. OrderEntity.isPromptFulfillmenté recebido e descartado. O campo 41 do proto do pedido atravessa todos os mappers e é persistido, mas nenhum UseCase, notifier ou widget o lê — o único uso do conceito é ohasPromptFulfillmentdo roteiro da conta, que é outro campo, em outro proto. Analogamente, o statusPrompt Fulfillmenté só exibição.OrderEntity.isPromptFulfillmentis received and discarded. Field 41 of the order proto crosses every mapper and is persisted, but no UseCase, notifier or widget reads it — the concept's only use is the account route'shasPromptFulfillment, which is a different field in a different proto. Likewise, thePrompt Fulfillmentstatus is display-only.OrderEntity.isPromptFulfillmentse recibe y se descarta. El campo 41 del proto del pedido cruza todos los mappers y se persiste, pero ningún UseCase, notifier o widget lo lee — el único uso del concepto es elhasPromptFulfillmentdel itinerario de la cuenta, que es otro campo, en otro proto. Análogamente, el estadoPrompt Fulfillmentes solo exhibición.- Um método da fachada e um UseCase inteiro sem chamador.
PromptOrchestrator.grantableRewardQuantitynão tem chamador (o motor de promoções injeta oValidateRewardStockUseCasedireto), e o mesmo vale paraGetAvailableStockForProductUseCase.execute,AllocateManufacturingBatchesUseCase.executeeGetStockControlUseCase.getCached. Além disso, o produto de carga de van tem UseCase próprio (GetProductsForVanLoadUseCase, filtrando pela elegibilidade de van load) sem nenhum consumidor.One facade method and a whole UseCase with no caller.PromptOrchestrator.grantableRewardQuantityhas no caller (the promotion engine injectsValidateRewardStockUseCasedirectly), and the same holds forGetAvailableStockForProductUseCase.execute,AllocateManufacturingBatchesUseCase.executeandGetStockControlUseCase.getCached. On top of that, the van-load product query has its own UseCase (GetProductsForVanLoadUseCase, filtering by the van-load eligibility flag) with no consumer at all.Un método de la fachada y un UseCase entero sin llamador.PromptOrchestrator.grantableRewardQuantityno tiene llamador (el motor de promociones inyecta elValidateRewardStockUseCasedirecto), y lo mismo vale paraGetAvailableStockForProductUseCase.execute,AllocateManufacturingBatchesUseCase.executeyGetStockControlUseCase.getCached. Además, la consulta de productos de carga de van tiene UseCase propio (GetProductsForVanLoadUseCase, filtrando por la elegibilidad de van load) sin ningún consumidor. - A área de pagamento chamada "prompt" não é aberta pelo prompt.
requiresPaymentConfigurationdepende deisOnTimePayment(pagamento à vista) e do módulo de criação de pagamento — não deisPromptOrder. Consequência prática: hoje a origemprompt_ordersó roda em pedidos não-prompt à vista do Chile. E como todo registro de prompt é criado como diferido, o relatório de caixa nunca passa pelo caminho imediato do orquestrador de pagamento — só pelo de sincronização.The payment area named "prompt" is not opened by prompt.requiresPaymentConfigurationdepends onisOnTimePayment(pay at sight) and on the payment-creation module — not onisPromptOrder. Practical consequence: today theprompt_orderorigin only runs on non-prompt pay-at-sight orders in Chile. And because every prompt register is created deferred, the cash report never goes through the payment orchestrator's immediate path — only through the sync one.El área de pago llamada "prompt" no la abre el prompt.requiresPaymentConfigurationdepende deisOnTimePayment(pago al contado) y del módulo de creación de pago — no deisPromptOrder. Consecuencia práctica: hoy el origenprompt_ordersolo corre en pedidos no-prompt al contado de Chile. Y como todo registro de prompt se crea diferido, el reporte de caja nunca pasa por el camino inmediato del orquestador de pago — solo por el de sincronización. - Duas dúvidas de contrato com o backend (não afirmadas como defeito):
StockControlRequest.lastModifiedDate(#3) existe no proto e não está plumbado em nenhuma camada — o delta-sync do estoque está inerte; edateReference(#2) é parâmetro do datasource que nenhum caller preenche. Confirmar se o backend depende de algum dos dois.Two contract questions for the backend (not asserted as defects):StockControlRequest.lastModifiedDate(#3) exists in the proto and is not plumbed in any layer — the stock delta-sync is inert; anddateReference(#2) is a datasource parameter that no caller fills. Confirm whether the backend depends on either.Dos dudas de contrato con el backend (no afirmadas como defecto):StockControlRequest.lastModifiedDate(#3) existe en el proto y no está plumbado en ninguna capa — el delta-sync del stock está inerte; ydateReference(#2) es parámetro del datasource que ningún caller llena. Confirmar si el backend depende de alguno de los dos. - Lacunas do motor de promoções ligadas a prompt (registradas na auditoria de promoções): a regra do legado que esconde uma promoção quando alvo e recompensa não têm estoque, e a regra do Chile que, em pedido prompt, só admite promoções exclusivas de dias de crédito — ambas não portadas. Ver Promoções.Prompt-related promotion-engine gaps (recorded in the promotions audit): the legacy rule that hides a promotion when target and reward have no stock, and Chile's rule that on a prompt order only credit-days-exclusive promotions are admitted — both not ported. See Promotions.Brechas del motor de promociones ligadas a prompt (registradas en la auditoría de promociones): la regla del legado que oculta una promoción cuando objetivo y recompensa no tienen stock, y la regla de Chile que, en pedido prompt, solo admite promociones exclusivas de días de crédito — ambas no portadas. Ver Promociones.
- Impressora e reconciliação de estoque estão declaradas mas vazias. O campo de MAC da impressora na jornada/configurações é previsto para BR/CL restrito a Prompt-sales Rep e não existe em nenhum EMC real (só no arquivo comentado de documentação); a categoria de pendência de reconciliação de estoque existe no enum de fim de jornada e devolve sempre lista vazia.Printer and stock reconciliation are declared but empty. The printer MAC field in journey/settings is foreseen for BR/CL restricted to Prompt-sales Rep and exists in no real EMC (only in the annotated documentation file); the stock-reconciliation pending category exists in the end-of-journey enum and always returns an empty list.Impresora y reconciliación de stock están declaradas pero vacías. El campo de MAC de la impresora en jornada/configuraciones está previsto para BR/CL restringido a Prompt-sales Rep y no existe en ningún EMC real (solo en el archivo comentado de documentación); la categoría de pendiente de reconciliación de stock existe en el enum de fin de jornada y devuelve siempre lista vacía.
- A cobertura de teste do prompt se resume à data de entrega. O único ponto coberto é a resolução da data (
resolve_delivery_date_use_case_test.dart), que assevera o curto-circuito "pedido prompt entrega hoje e ignora a seleção manual" e a interação com dias preferenciais. Nenhum orquestrador tem teste — nem oPromptOrchestrator—, echecksVanStockForPromptOrdersepromptOrderUsesExternalApprovalnão aparecem em teste nenhum.Prompt test coverage boils down to the delivery date. The only covered point is date resolution (resolve_delivery_date_use_case_test.dart), which asserts the "prompt order delivers today and ignores the manual selection" short-circuit and the interaction with preferred days. No orchestrator has tests — thePromptOrchestratorincluded — andchecksVanStockForPromptOrdersandpromptOrderUsesExternalApprovalappear in no test at all.La cobertura de test del prompt se limita a la fecha de entrega. El único punto cubierto es la resolución de la fecha (resolve_delivery_date_use_case_test.dart), que asevera el cortocircuito "el pedido prompt entrega hoy e ignora la selección manual" y la interacción con días preferenciales. Ningún orquestador tiene test — tampoco elPromptOrchestrator— ychecksVanStockForPromptOrdersypromptOrderUsesExternalApprovalno aparecen en ningún test.
Fora de escopo declarado (não são lacunas): programas de incentivo, e a numeração canônica das transações de van, que depende do backend. As transações do dispatcher citadas aqui ainda não têm doc própria — o setor está em construção.Declared out of scope (not gaps): incentive programs, and the canonical numbering of the van transactions, which depends on the backend. The dispatcher transactions cited here have no doc of their own yet — the sector is under construction.Fuera de alcance declarado (no son brechas): programas de incentivo, y la numeración canónica de las transacciones de van, que depende del backend. Las transacciones del dispatcher citadas aquí aún no tienen doc propia — el sector está en construcción.