DocumentaçãoDocumentationDocumentaciónOne Conecta
ÍndiceIndexÍndice
Baixar .mdDownload .mdBajar .md
Você está vendo esta documentação online. No topo você também pode baixar o PDF (mesmo conteúdo desta página, no idioma e modo atuais) e o Markdown (Funcional ou Técnica).You are viewing this documentation online. At the top you can also download the PDF (same content as this page, in the current language and mode) and the Markdown (Functional or Technical).Está viendo esta documentación en línea. Arriba también puede bajar el PDF (mismo contenido de esta página, en el idioma y modo actuales) y el Markdown (Funcional o Técnica).
Transação gRPC · DispatchergRPC transaction · DispatcherTransacción gRPC · Dispatcher

Contagem de estoqueStock countConteo de stock

A transação de escrita que envia ao backend o resultado da contagem de estoque feita pelo representante de vendas durante uma visita. Cada produto contado vira uma linha do payload, com a quantidade na unidade alta e na unidade baixa. Um único builder monta o payload; não há variantes. The write transaction that sends the backend the result of the stock count the sales rep does during a visit. Each counted product becomes a payload line, with the quantity in the high unit and the low unit. A single builder assembles the payload; there are no variants. La transacción de escritura que envía al backend el resultado del conteo de stock hecho por el representante de ventas durante una visita. Cada producto contado se vuelve una línea del payload, con la cantidad en la unidad alta y la unidad baja. Un único builder arma el payload; no hay variantes.

PúblicoAudiencePúblico
QA · Suporte · Produto · DevQA · Support · Product · DevQA · Soporte · Producto · Dev
CamadaLayerCapa
Escrita · DispatcherWrite · DispatcherEscritura · Dispatcher
RelacionadoRelatedRelacionado
AtualizadoUpdatedActualizado
17/08/20262026-08-17
Disponível emAvailable inDisponible en BR CL ZA
01

O que é e quando aconteceWhat it is and when it happensQué es y cuándo ocurre

Durante uma visita, o representante de vendas pode contar o estoque do varejo — quantas unidades de cada produto existem na prateleira/depósito. Ao concluir a contagem e enviar, o app dispara esta transação, que leva ao backend a lista de produtos contados com suas quantidades. É como o registro do estoque sai do dispositivo e passa a existir no sistema. During a visit, the sales rep can count the retail's stock — how many units of each product are on the shelf/back-store. When the count is finished and sent, the app fires this transaction, carrying the list of counted products with their quantities to the backend. It's how the stock record leaves the device and starts to exist in the system. Durante una visita, el representante de ventas puede contar el stock del punto de venta — cuántas unidades de cada producto hay en la góndola/bodega. Al terminar el conteo y enviar, la app dispara esta transacción, que lleva al backend la lista de productos contados con sus cantidades. Es cómo el registro de stock sale del dispositivo y pasa a existir en el sistema.

Uma linha por produtoOne line per productUna línea por producto

Só entram os produtos que o rep realmente contou. Produtos sem contagem não são enviados.Only the products the rep actually counted are included. Uncounted products aren't sent.Solo entran los productos que el rep realmente contó. Los productos sin conteo no se envían.

Unidade alta e baixaHigh and low unitUnidad alta y baja

A contagem tem duas colunas: Alta (ex.: caixa) e Baixa (ex.: unidade). As duas viajam no envio.The count has two columns: High (e.g. case) and Low (e.g. each). Both travel in the send.El conteo tiene dos columnas: Alta (p. ej. caja) y Baja (p. ej. unidad). Ambas viajan en el envío.

Sem variantesNo variantsSin variantes

Uma só forma de envio para todos os mercados. Para o rep, o gesto é sempre o mesmo — contar e enviar.One single send shape for all markets. For the rep, the gesture is always the same — count and send.Una sola forma de envío para todos los mercados. Para el rep, el gesto es siempre el mismo — contar y enviar.

02

Fluxo de telas que disparaScreen flow that fires itFlujo de pantallas que lo dispara

A transação é o último passo da contagem de estoque. As telas do caminho pertencem à feature de Contagem de estoque; aqui só situamos onde o envio acontece:The transaction is the last step of the stock count. The screens along the way belong to the Stock count feature; here we only place where the send happens:La transacción es el último paso del conteo de stock. Las pantallas del camino pertenecen a la feature de Conteo de stock; aquí solo situamos dónde ocurre el envío:

  1. Abrir a contagem na visitaOpen the count in the visitAbrir el conteo en la visitaA partir do detalhe da visita do varejo, o rep entra na tela de contagem de estoque.From the retail's visit detail, the rep opens the stock count screen.Desde el detalle de la visita del punto de venta, el rep entra a la pantalla de conteo de stock.
  2. Contar cada produtoCount each productContar cada productoPara cada produto, informa a quantidade em unidade Alta e/ou Baixa.For each product, enters the quantity in the High and/or Low unit.Para cada producto, ingresa la cantidad en unidad Alta y/o Baja.
  3. Enviar contagem → esta transaçãoSend count → this transactionEnviar conteo → esta transacciónAo tocar em enviar, o app dispara a Contagem de estoque. É este toque que aciona a transação.Tapping send fires Stock count. This tap is what triggers the transaction.Al tocar enviar, la app dispara el Conteo de stock. Este toque es lo que activa la transacción.
03

Depois do envioAfter sendingDespués del envío

Confirmação ao repConfirmation to the repConfirmación al rep
Quando o backend aceita, a contagem é confirmada e as quantidades contadas são limpas da tela — pronto para uma próxima contagem.When the backend accepts it, the count is confirmed and the counted quantities are cleared from the screen — ready for a next count.Cuando el backend lo acepta, el conteo se confirma y las cantidades contadas se limpian de la pantalla — listo para un próximo conteo.
Sem internetOfflineSin internet
O envio pode entrar em fila e ser reenviado quando a conexão volta — o rep não perde a contagem. Um identificador de transação evita que um reenvio duplique o registro.The send may be queued and retried when the connection returns — the rep doesn't lose the count. A transaction id prevents a retry from duplicating the record.El envío puede quedar en cola y reintentarse cuando vuelve la conexión — el rep no pierde el conteo. Un identificador de transacción evita que un reenvío duplique el registro.
Acompanhar o envioTracking the sendSeguir el envío
O status técnico do despacho (enviado, em fila, com erro) pode ser acompanhado na central de dados / tracking de despachos do app — útil para suporte investigar um envio.The dispatch's technical status (sent, queued, errored) can be followed in the app's data center / dispatch tracking — useful for support to investigate a send.El estado técnico del despacho (enviado, en cola, con error) puede seguirse en el centro de datos / tracking de despachos de la app — útil para que soporte investigue un envío.
04

Visão técnicaTechnical overviewVisión técnica

Contagem de estoque é a transação de saída que persiste no backend a contagem por produto feita numa visita. É disparada pelo notifier da feature de contagem de estoque. Um único DispatcherType (stockCount) e um único builder cobrem todos os mercados — não há variantes nem prefixo Promo_. Stock count is the outbound transaction that persists a per-product count from a visit in the backend. It's fired by the stock-count feature's notifier. A single DispatcherType (stockCount) and a single builder cover all markets — no variants, no Promo_ prefix. Conteo de stock es la transacción de salida que persiste en el backend el conteo por producto hecho en una visita. Se dispara desde el notifier de la feature de conteo de stock. Un único DispatcherType (stockCount) y un único builder cubren todos los mercados — sin variantes ni prefijo Promo_.

Payload planoFlat payloadPayload plano

O contrato wire é um único array — StockTrackingDeatils — de linhas de item. Sem cabeçalho, sem sub-blocos de pagamento ou promoção.The wire contract is a single array — StockTrackingDeatils — of item lines. No header, no payment or promotion sub-blocks.El contrato wire es un único array — StockTrackingDeatils — de líneas de ítem. Sin encabezado, sin sub-bloques de pago o promoción.

Alta e baixa (uom1/uom2)High and low (uom1/uom2)Alta y baja (uom1/uom2)

A contagem alta vai em uom1Quantity; a baixa em uom2Quantity. Os nomes das unidades saem do UoM do produto (primaryName/secondaryName).The high count goes in uom1Quantity; the low in uom2Quantity. The unit names come from the product's UoM (primaryName/secondaryName).El conteo alto va en uom1Quantity; el bajo en uom2Quantity. Los nombres de las unidades salen del UoM del producto (primaryName/secondaryName).

RPC genéricoGeneric RPCRPC genérico

Como toda transação, passa pelo mesmo sendTransaction, com o JSON serializado em message e serviceName = LocationStockUploadAPI como discriminador.Like every transaction, it goes through the same sendTransaction, with the JSON serialized into message and serviceName = LocationStockUploadAPI as the discriminator.Como toda transacción, pasa por el mismo sendTransaction, con el JSON serializado en message y serviceName = LocationStockUploadAPI como discriminador.

FontesSourcesFuentes BuildStockCountDispatcherPayloadUseCase + StockCountDispatcherPayloadInput + DispatcherType.stockCount + DispatcherConectaRep.proto. O input carrega entities cruas de domínio (CLAUDE.md §36); o build() constrói todo o wire. BuildStockCountDispatcherPayloadUseCase + StockCountDispatcherPayloadInput + DispatcherType.stockCount + DispatcherConectaRep.proto. The input carries raw domain entities (CLAUDE.md §36); build() constructs the entire wire. BuildStockCountDispatcherPayloadUseCase + StockCountDispatcherPayloadInput + DispatcherType.stockCount + DispatcherConectaRep.proto. El input lleva entities crudas de dominio (CLAUDE.md §36); build() construye todo el wire.

05

Transporte gRPCgRPC transportTransporte gRPC

DispatcherConectaRep.proto · proto3 · package mn.bat.conectarep.dispatcher. O serviço expõe um único RPC genérico — não existe mensagem por transação. TODA transação de escrita do app usa este mesmo sendTransaction; o que muda é o serviceName (discriminador) e o JSON dentro de message.The service exposes a single generic RPC — there's no per-transaction message. EVERY write transaction in the app uses this same sendTransaction; what changes is the serviceName (discriminator) and the JSON inside message.El servicio expone un único RPC genérico — no existe mensaje por transacción. TODA transacción de escritura de la app usa este mismo sendTransaction; lo que cambia es el serviceName (discriminador) y el JSON dentro de message.

sendTransactionunary
MétodoMethodMétodo

rpc sendTransaction(InboxTransactionRequest) returns (InboxTransactionReply)

path /mn.bat.conectarep.dispatcher.DispatcherConectaRepService/sendTransaction

Request · InboxTransactionRequest
endpoint
string · #1 · endpoint alvo (config de ambiente; destination salesforce)target endpoint (environment config; salesforce destination)endpoint destino (config de ambiente; destination salesforce)
serviceName
string · #2 · discriminadorLocationStockUploadAPI (sem prefixo Promo_)discriminatorLocationStockUploadAPI (no Promo_ prefix)discriminadorLocationStockUploadAPI (sin prefijo Promo_)
dateReference
string · #3 · AAAA-MM-DD do envio (submittedAt)YYYY-MM-DD of the submission (submittedAt)AAAA-MM-DD del envío (submittedAt)
transactionReference
string · #4 · o accountSfid do varejo (correlação)the retail's accountSfid (correlation)el accountSfid del punto de venta (correlación)
username
string · #5
message
string · #6 · o payload JSON serializado (a tabela da seção 08)the JSON payload serialized (the table in section 08)el payload JSON serializado (la tabla de la sección 08)
manufacturer
string · #7 · dado do dispositivodevice datadato del dispositivo
model
string · #8 · dado do dispositivodevice datadato del dispositivo
deviceUuid
string · #9 · literal provisório hoje (ver Pendências)provisional literal today (see Pending)literal provisional hoy (ver Pendientes)
deviceVersion
string · #10
tid
int64 · #11 · id de transação para idempotência/replaytransaction id for idempotency/replayid de transacción para idempotencia/replay
Reply · InboxTransactionReply
status
int32 · #1 · status do ack (0 = sucesso)ack status (0 = success)status del ack (0 = éxito)
message
string · #2 · mensagem do backendbackend messagemensaje del backend
transactionId
int32 · #3 · id atribuído pelo backend (correlação)backend-assigned id (correlation)id asignado por el backend (correlación)

Envelope → Request O builder devolve um DispatcherEnvelope (type, serviceName, payload, account, transactionReference, dateReference). O DispatcherGateway serializa payload em JSON para message, copia serviceName/dateReference/transactionReference, preenche os campos de dispositivo e o bearer token de auth, e chama o RPC. The builder returns a DispatcherEnvelope (type, serviceName, payload, account, transactionReference, dateReference). The DispatcherGateway serializes payload to JSON into message, copies serviceName/dateReference/transactionReference, fills in the device fields and the auth bearer token, and calls the RPC. El builder devuelve un DispatcherEnvelope (type, serviceName, payload, account, transactionReference, dateReference). El DispatcherGateway serializa payload a JSON en message, copia serviceName/dateReference/transactionReference, completa los campos del dispositivo y el bearer token de auth, y llama al RPC.

A Contagem de estoque não está na lista lightweight de DispatcherType.resendMayDuplicate, logo resendMayDuplicate == true: um reenvio (ex.: recuperação de fila offline) pode duplicar o registro no backend; a idempotência via tid é o que mitiga isso.Stock count is not in the lightweight set of DispatcherType.resendMayDuplicate, so resendMayDuplicate == true: a resend (e.g. offline-queue recovery) may duplicate the record on the backend; idempotency via tid is what mitigates it.El Conteo de stock no está en el conjunto lightweight de DispatcherType.resendMayDuplicate, por lo que resendMayDuplicate == true: un reenvío (p. ej. recuperación de cola offline) puede duplicar el registro en el backend; la idempotencia vía tid es lo que lo mitiga.

06

serviceName

um único DispatcherTypestockCount — sem variantes e sem campo de tipo no input. O ponto de atenção é o nome cruzado: o tipo do app se chama stockCount, mas o serviceName do contrato wire é LocationStockUploadAPI. É esse nome que o backend usa para rotear a transação.There's a single DispatcherTypestockCount — with no variants and no type field on the input. The thing to watch is the name crossover: the app type is called stockCount, but the wire-contract serviceName is LocationStockUploadAPI. That's the name the backend uses to route the transaction.Hay un único DispatcherTypestockCount — sin variantes y sin campo de tipo en el input. El punto de atención es el nombre cruzado: el tipo de la app se llama stockCount, pero el serviceName del contrato wire es LocationStockUploadAPI. Ese es el nombre que el backend usa para enrutar la transacción.

DispatcherType serviceName DestinoDestinationDestino MercadosMarketsMercados
stockCountLocationStockUploadAPIsalesforceBR · CL · ZA

Nome cruzadoName crossoverNombre cruzado stockCount (tipo do app) ≠ LocationStockUploadAPI (nome wire). Ao procurar essa transação no backend/logs, use LocationStockUploadAPI; no código do app, DispatcherType.stockCount. Não confundir com as outras transações de estoque (stockReconciliation, stockRequest, stockAllocationExecution, stockUnload), que têm serviceName próprio. stockCount (app type) ≠ LocationStockUploadAPI (wire name). When looking this transaction up on the backend/logs, use LocationStockUploadAPI; in the app code, DispatcherType.stockCount. Don't confuse it with the other stock transactions (stockReconciliation, stockRequest, stockAllocationExecution, stockUnload), which have their own serviceName. stockCount (tipo de la app) ≠ LocationStockUploadAPI (nombre wire). Al buscar esta transacción en el backend/logs, use LocationStockUploadAPI; en el código de la app, DispatcherType.stockCount. No confundir con las otras transacciones de stock (stockReconciliation, stockRequest, stockAllocationExecution, stockUnload), que tienen su propio serviceName.

O serviceName é resolvido por type.resolveServiceName(hasPromotion: false) — sempre false aqui, então nunca há prefixo Promo_.The serviceName is resolved by type.resolveServiceName(hasPromotion: false) — always false here, so there's never a Promo_ prefix.El serviceName se resuelve por type.resolveServiceName(hasPromotion: false) — siempre false aquí, así que nunca hay prefijo Promo_.

07

Como é disparadoHow it's firedCómo se dispara

A transação é orquestrada pelo StockCountNotifier.submit() (remote-first, §36). O notifier apenas reúne entities cruas e valores injetados; o builder é o dono único de todo join, rename e derivação wire. A cascata:The transaction is orchestrated by StockCountNotifier.submit() (remote-first, §36). The notifier only gathers raw entities and injected values; the builder is the sole owner of every join, rename and wire derivation. The cascade:La transacción se orquesta desde StockCountNotifier.submit() (remote-first, §36). El notifier solo reúne entities crudas y valores inyectados; el builder es el dueño único de todo join, rename y derivación wire. La cascada:

  • StockCountNotifiersubmit()
    • reúne entities cruas + injetadosgathers raw entities + injectedreúne entities crudas + inyectadosStockCountDispatcherPayloadInput
      • build()BuildStockCountDispatcherPayloadUseCasemonta o wireassembles the wirearma el wire
        • devolvereturnsdevuelveDispatcherEnvelope
          • SubmitStockCountUseCaseDispatcherOrchestrator
            • serializa + authserialize + authserializa + authDispatcherGateway
              • sendTransactionBackendgRPC

O input (entities cruas)The input (raw entities)El input (entities crudas)

StockCountDispatcherPayloadInput (Freezed). Carrega o dado como existe no domínio; nada de formato wire. O relógio chega como submittedAt (via DateTimeUtils.now()); a visita é resolvida do cache por accountSfid e o resource/market vêm dos providers de sessão.StockCountDispatcherPayloadInput (Freezed). Carries data as it exists in the domain; no wire shaping. The clock arrives as submittedAt (via DateTimeUtils.now()); the visit is resolved from cache by accountSfid and resource/market come from the session providers.StockCountDispatcherPayloadInput (Freezed). Lleva el dato como existe en el dominio; nada de formato wire. El reloj llega como submittedAt (vía DateTimeUtils.now()); la visita se resuelve del cache por accountSfid y resource/market vienen de los providers de sesión.

CampoFieldCampoTipoTypeTipoPapelRoleRol
accountSfidStringvarejo alvo (→ transactionReference e account.sfid)target retail (→ transactionReference and account.sfid)punto de venta objetivo (→ transactionReference y account.sfid)
entriesList<StockCountEntryEntity>contagens do rep por productSfid (highUomCount/lowUomCount)rep's counts by productSfid (highUomCount/lowUomCount)conteos del rep por productSfid (highUomCount/lowUomCount)
productsList<ProductEntity>catálogo contável (UoM, SKUs) — dirige a ordem das linhascountable catalog (UoM, SKUs) — drives line ordercatálogo contable (UoM, SKUs) — dirige el orden de las líneas
resourceResourceEntityrepresentante de vendas (cru — o builder deriva resourceId e location)sales rep (raw — the builder derives resourceId and location)representante de ventas (crudo — el builder deriva resourceId y location)
visitVisitEntity?visita do cache (→ visit, sapCustomerId, account.name); null quando não resolvidavisit from cache (→ visit, sapCustomerId, account.name); null when unresolvedvisita del cache (→ visit, sapCustomerId, account.name); null cuando no se resuelve
marketEndMarketmarketIso e currencyIsoCodemarketIso and currencyIsoCodemarketIso y currencyIsoCode
submittedAtDateTimerelógio do envio (→ dateReference em yyyy-MM-dd)submission clock (→ dateReference as yyyy-MM-dd)reloj del envío (→ dateReference en yyyy-MM-dd)
08

Payload (message)

O JSON serializado no campo message do request. É um objeto com uma única chaveStockTrackingDeatils (typo do contrato, mantido verbatim) — cujo valor é um array de linhas de item. Cada linha tem 24 campos e a tabela abaixo lista todos, com 4 colunasCampo JSON · Tipo · Origem do Dado · Regra. Campo, Tipo e Origem são código cru; só a Regra é prosa. Um exemplo completo (BR, 1 item) está em transaction_example.json, ao lado deste doc.The JSON serialized into the request's message field. It's an object with a single keyStockTrackingDeatils (contract typo, kept verbatim) — whose value is an array of item lines. Each line has 24 fields and the table below lists all of them, with 4 columnsJSON field · Type · Data source · Rule. Field, Type and Source are raw code; only Rule is prose. A full example (BR, 1 item) sits in transaction_example.json, next to this doc.El JSON serializado en el campo message del request. Es un objeto con una única claveStockTrackingDeatils (typo del contrato, mantenido verbatim) — cuyo valor es un array de líneas de ítem. Cada línea tiene 24 campos y la tabla abajo lista todos, con 4 columnasCampo JSON · Tipo · Origen del Dato · Regla. Campo, Tipo y Origen son código crudo; solo la Regla es prosa. Un ejemplo completo (BR, 1 ítem) está en transaction_example.json, junto a este doc.

  • StockTrackingDeatils array — 1 chave no topoarray — 1 top-level keyarray — 1 clave en el tope 1 campofieldcampo

    Única chave do payload. O valor é o array items: uma entrada por produto de input.products cujo productSfid tem uma entry correspondente com pelo menos uma contagem (entry.hasAnyCount). Produtos sem entrada, ou com entrada vazia, são pulados.The payload's only key. The value is the items array: one entry per product in input.products whose productSfid has a matching entry with at least one count (entry.hasAnyCount). Products without an entry, or with an empty entry, are skipped.La única clave del payload. El valor es el array items: una entrada por producto de input.products cuyo productSfid tenga una entry correspondiente con al menos un conteo (entry.hasAnyCount). Los productos sin entrada, o con entrada vacía, se omiten.

    • StockTrackingDeatils[] por produto contadoper counted productpor producto contado 24 camposfieldscampos

      highCount = entry.highUomCount ?? 0; lowCount = entry.lowUomCount ?? 0. sku = product.manufacturingSkus.first (ou null se vazio). sapCustomerId = visit?.accountData.customerCode ?? ""; visitSfid = visit?.sfid ?? ""; resourceSfid = primary/secondary conforme resource.isPrimaryResource.highCount = entry.highUomCount ?? 0; lowCount = entry.lowUomCount ?? 0. sku = product.manufacturingSkus.first (or null if empty). sapCustomerId = visit?.accountData.customerCode ?? ""; visitSfid = visit?.sfid ?? ""; resourceSfid = primary/secondary per resource.isPrimaryResource.highCount = entry.highUomCount ?? 0; lowCount = entry.lowUomCount ?? 0. sku = product.manufacturingSkus.first (o null si vacío). sapCustomerId = visit?.accountData.customerCode ?? ""; visitSfid = visit?.sfid ?? ""; resourceSfid = primary/secondary según resource.isPrimaryResource.

      Campo JSONTipoTypeTipoOrigem do DadoData sourceOrigen del DatoRegraRuleRegla
      orderPoNumberstringFixo: ""placeholder inerteinert placeholderplaceholder inerte
      stockIdstringFixo: ""placeholder inerteinert placeholderplaceholder inerte
      isAvailableboolCalculadohighCount > 0 || lowCount > 0highCount > 0 || lowCount > 0highCount > 0 || lowCount > 0
      availableQuantityinthighCountsó a contagem alta (ver Pendências)high count only (see Pending)solo el conteo alto (ver Pendientes)
      baseUOMstringproduct.uom.primaryNamenome da unidade altahigh unit namenombre de la unidad alta
      baseUOMQuatityinthighCountchave com typo (Quatity), verbatim; só a altamisspelled key (Quatity), verbatim; high onlyclave con typo (Quatity), verbatim; solo la alta
      batchIdstringsku?.batchId ?? ""1º SKU do produtoproduct's 1st SKU1er SKU del producto
      damageQuantitystringFixo: ""placeholder inerte (string vazia, não 0)inert placeholder (empty string, not 0)placeholder inerte (string vacío, no 0)
      defaultUOMstringproduct.uom.primaryName= baseUOM= baseUOM= baseUOM
      defaultUOMQuatityinthighCountchave com typo (Quatity), verbatim; só a altamisspelled key (Quatity), verbatim; high onlyclave con typo (Quatity), verbatim; solo la alta
      locationstringresource.locationSfid
      productIdstringproduct.productSfid
      SKUIdstringsku?.manufacturingSkuSfid ?? ""1º SKU do produtoproduct's 1st SKU1er SKU del producto
      uom1Quantitystringentry.highUomCount?.toString() ?? ""contagem alta como string; "" quando não contadahigh count as string; "" when uncountedconteo alto como string; "" cuando no contado
      uom2Quantitystringentry.lowUomCount?.toString() ?? ""contagem baixa como string; único campo que carrega a baixalow count as string; the only field carrying the low countconteo bajo como string; único campo que lleva la baja
      uom1Namestringproduct.uom.primaryNamenome da unidade altahigh unit namenombre de la unidad alta
      uom2Namestringproduct.uom.secondaryNamenome da unidade baixalow unit namenombre de la unidad baja
      currencyIsoCodestringCurrencyUtils.isoCode(market)BRL / CLP / ZAR conforme mercadoBRL / CLP / ZAR per marketBRL / CLP / ZAR según mercado
      typestringFixo: "Stock Check"constante _stockCheckType_stockCheckType constantconstante _stockCheckType
      visitstringvisit?.sfid ?? """" se a visita não foi resolvida"" if the visit wasn't resolved"" si la visita no se resolvió
      marketIsostringmarket.nameBR / CL / ZABR / CL / ZABR / CL / ZA
      sellableQuantityinthighCountsó a contagem alta (ver Pendências)high count only (see Pending)solo el conteo alto (ver Pendientes)
      sapCustomerIdstringvisit?.accountData.customerCode ?? ""código SAP do varejoretail's SAP codecódigo SAP del punto de venta
      resourceIdstringresource.primaryResourceSfid / secondaryResourceSfidprimary se isPrimaryResource, senão secondaryprimary if isPrimaryResource, else secondaryprimary si isPrimaryResource, si no secondary

ExemploExampleEjemplo Um payload completo (BR, 1 item, alta 5 / baixa 12) está em docs/public/dispatcher/19_stock_count/transaction_example.json — a forma exata serializada em message (sem wrapper gRPC). A complete payload (BR, 1 item, high 5 / low 12) is in docs/public/dispatcher/19_stock_count/transaction_example.json — the exact shape serialized into message (no gRPC wrapper). Un payload completo (BR, 1 ítem, alta 5 / baja 12) está en docs/public/dispatcher/19_stock_count/transaction_example.json — la forma exacta serializada en message (sin wrapper gRPC).

09

Regras de negócioBusiness rulesReglas de negocio

Inclusão de linhaLine inclusionInclusión de línea entry != null · hasAnyCount

O builder itera input.products (não as entries), indexando as contagens por productSfid. Uma linha só é emitida quando:The builder iterates input.products (not the entries), indexing the counts by productSfid. A line is emitted only when:El builder itera input.products (no las entries), indexando los conteos por productSfid. Una línea solo se emite cuando:

  • existe uma entry para o product.productSfid (senão continue);an entry exists for product.productSfid (else continue);existe una entry para product.productSfid (si no continue);
  • e entry.hasAnyCount é true — ou seja, highUomCount ou lowUomCount não é null (senão continue).and entry.hasAnyCount is true — i.e. highUomCount or lowUomCount is non-null (else continue).y entry.hasAnyCount es true — o sea, highUomCount o lowUomCount no es null (si no continue).
  • A ordem das linhas segue a ordem de input.products, não a ordem em que o rep digitou.Line order follows input.products, not the order the rep typed.El orden de las líneas sigue input.products, no el orden en que el rep escribió.
Unidade alta e baixaHigh and low unitUnidad alta y baja uom1 = high · uom2 = low

A contagem tem duas colunas (memória do projeto: as antigas colunas Stock/Venda foram reinterpretadas como Alta/Baixa, sem mudança de proto):The count has two columns (project note: the old Stock/Sale columns were reinterpreted as High/Low, with no proto change):El conteo tiene dos columnas (nota del proyecto: las antiguas columnas Stock/Venta fueron reinterpretadas como Alta/Baja, sin cambio de proto):

  • Altauom1Quantity (string) + uom1Name = primaryName.Highuom1Quantity (string) + uom1Name = primaryName.Altauom1Quantity (string) + uom1Name = primaryName.
  • Baixauom2Quantity (string) + uom2Name = secondaryName.Lowuom2Quantity (string) + uom2Name = secondaryName.Bajauom2Quantity (string) + uom2Name = secondaryName.
  • As quantidades uom1Quantity/uom2Quantity saem de entry.*.toString()"" quando o campo é null (não contado). Os demais campos numéricos usam o fallback ?? 0.The uom1Quantity/uom2Quantity come from entry.*.toString()"" when the field is null (uncounted). The other numeric fields use the ?? 0 fallback.Las cantidades uom1Quantity/uom2Quantity salen de entry.*.toString()"" cuando el campo es null (no contado). Los demás campos numéricos usan el fallback ?? 0.
resourceId primary/secondaryresourceId primary/secondaryresourceId primary/secondary isPrimaryResource

resourceId = resource.isPrimaryResource ? resource.primaryResourceSfid : resource.secondaryResourceSfid — mesma derivação de sfid do representante usada nas demais transações de escrita (§25/§36). O location vem de resource.locationSfid, direto.resourceId = resource.isPrimaryResource ? resource.primaryResourceSfid : resource.secondaryResourceSfid — the same rep-sfid derivation used in the other write transactions (§25/§36). location comes from resource.locationSfid, directly.resourceId = resource.isPrimaryResource ? resource.primaryResourceSfid : resource.secondaryResourceSfid — la misma derivación de sfid del representante usada en las demás transacciones de escritura (§25/§36). location viene de resource.locationSfid, directo.

Envelope e datasEnvelope & datesEnvelope y fechas dateReference · account · transactionReference
  • dateReference = DateTimeUtils.formatDate(dateTime: submittedAt) em yyyy-MM-dd (default DateFormatType.isoDate).dateReference = DateTimeUtils.formatDate(dateTime: submittedAt) as yyyy-MM-dd (default DateFormatType.isoDate).dateReference = DateTimeUtils.formatDate(dateTime: submittedAt) en yyyy-MM-dd (default DateFormatType.isoDate).
  • transactionReference = input.accountSfid (correlação).transactionReference = input.accountSfid (correlation).transactionReference = input.accountSfid (correlación).
  • account = DispatchAccountEntity(sfid: accountSfid, sapCode: sapCustomerId, name: visit?.accountData.name ?? "") — metadados do varejo para tracking.account = DispatchAccountEntity(sfid: accountSfid, sapCode: sapCustomerId, name: visit?.accountData.name ?? "") — retail metadata for tracking.account = DispatchAccountEntity(sfid: accountSfid, sapCode: sapCustomerId, name: visit?.accountData.name ?? "") — metadatos del punto de venta para tracking.
10

Pendências / roadmapPending / roadmapPendientes / roadmap

O que o builder envia inerte ou de forma parcial, documentado fiel ao estado atual do código (nunca descrito como se já existisse):What the builder ships inert or partially, documented faithfully to the current code state (never described as already existing):Lo que el builder envía inerte o de forma parcial, documentado fiel al estado actual del código (nunca descrito como si ya existiera):

Não portado / pendenteNot ported / pendingNo portado / pendiente

  • Campos numéricos só carregam a contagem alta: availableQuantity, baseUOMQuatity, defaultUOMQuatity e sellableQuantity são todos highCount. A contagem baixa (lowCount) só viaja como string em uom2Quantity — nenhum campo numérico a carrega.Numeric fields carry only the high count: availableQuantity, baseUOMQuatity, defaultUOMQuatity and sellableQuantity are all highCount. The low count (lowCount) only travels as a string in uom2Quantity — no numeric field carries it.Los campos numéricos solo llevan el conteo alto: availableQuantity, baseUOMQuatity, defaultUOMQuatity y sellableQuantity son todos highCount. El conteo bajo (lowCount) solo viaja como string en uom2Quantity — ningún campo numérico lo lleva.
  • StockTrackingDeatils e baseUOMQuatity/defaultUOMQuatity: chaves com typo (Deatils, Quatity) mantidas verbatim — contrato do backend.StockTrackingDeatils and baseUOMQuatity/defaultUOMQuatity: misspelled keys (Deatils, Quatity) kept verbatim — backend contract.StockTrackingDeatils y baseUOMQuatity/defaultUOMQuatity: claves con typo (Deatils, Quatity) mantenidas verbatim — contrato del backend.
  • orderPoNumber, stockId, damageQuantity: sempre "" — placeholders inertes do contrato, o app não os popula.orderPoNumber, stockId, damageQuantity: always "" — inert contract placeholders, the app doesn't populate them.orderPoNumber, stockId, damageQuantity: siempre "" — placeholders inertes del contrato, la app no los completa.
  • batchId e SKUId: usam só o manufacturingSku do produto (.first). Produtos com múltiplos SKUs contam com apenas um representado; "" quando o produto não tem SKU.batchId and SKUId: use only the product's 1st manufacturingSku (.first). Products with multiple SKUs have just one represented; "" when the product has no SKU.batchId y SKUId: usan solo el 1er manufacturingSku del producto (.first). Los productos con múltiples SKUs tienen solo uno representado; "" cuando el producto no tiene SKU.
  • isAvailable é derivado da própria contagem (> 0), não de uma disponibilidade real de estoque.isAvailable is derived from the count itself (> 0), not from a real stock availability.isAvailable se deriva del propio conteo (> 0), no de una disponibilidad real de stock.
  • Transporte: deviceUuid vai como literal provisório no gateway (pendência conhecida do Dispatcher).Transport: deviceUuid ships as a provisional literal in the gateway (known Dispatcher pending item).Transporte: deviceUuid va como literal provisional en el gateway (pendiente conocido del Dispatcher).

MercadosMarketsMercados

A disponibilidade da transação vem do DispatcherType.stockCount.enabledMarkets = BR/CL/ZA. O build() é market-agnostic: a estrutura do payload é idêntica nos três; só marketIso e currencyIsoCode variam por mercado. AR/PY/PE não têm dispatcher de contagem de estoque.Transaction availability comes from DispatcherType.stockCount.enabledMarkets = BR/CL/ZA. The build() is market-agnostic: the payload structure is identical across the three; only marketIso and currencyIsoCode vary per market. AR/PY/PE have no stock-count dispatcher.La disponibilidad de la transacción viene de DispatcherType.stockCount.enabledMarkets = BR/CL/ZA. El build() es market-agnostic: la estructura del payload es idéntica en los tres; solo marketIso y currencyIsoCode varían por mercado. AR/PY/PE no tienen dispatcher de conteo de stock.

BRx CLx ZAx AR PY PE
disponívelavailabledisponible presente, desligadopresent, offpresente, apagado ausenteabsentausente
BRCLZA

Mesma forma nos trêsSame shape in all threeMisma forma en los tres O builder não ramifica por mercado. A moeda (currencyIsoCode) e o ISO (marketIso) refletem o mercado ativo; os nomes de unidade (uom1Name/uom2Name) vêm do catálogo de cada mercado. The builder doesn't branch per market. The currency (currencyIsoCode) and ISO (marketIso) reflect the active market; the unit names (uom1Name/uom2Name) come from each market's catalog. El builder no ramifica por mercado. La moneda (currencyIsoCode) y el ISO (marketIso) reflejan el mercado activo; los nombres de unidad (uom1Name/uom2Name) vienen del catálogo de cada mercado.

AR · PY · PE Existem como mercados do app (config PANGEA mínima), mas não têm dispatcher de contagem de estoquestockCount.enabledMarkets não os lista. A contagem de estoque não é disparada nesses mercados. They exist as app markets (minimal PANGEA config), but have no stock-count dispatcherstockCount.enabledMarkets doesn't list them. Stock count is not fired in these markets. Existen como mercados de la app (config PANGEA mínima), pero no tienen dispatcher de conteo de stockstockCount.enabledMarkets no los lista. El conteo de stock no se dispara en estos mercados.