Atualização de varejoRetailer updateActualización de punto de venta
A transação de escrita que envia ao backend as mudanças cadastrais de um varejo — dados do estabelecimento, endereço, rota/frequência, classificação local e status (ativar/desativar). Um único builder monta o payload JSON; o que aparece nele é governado pelos módulos habilitados por mercado e pelo contexto do envio (edição comum, resposta EM LOV ou solicitação de rota). Toda a construção do contrato wire vive no builder. The write transaction that sends a retail's registration changes to the backend — outlet data, address, route/frequency, local classification and status (activate/deactivate). A single builder assembles the JSON payload; what shows up in it is governed by the modules enabled per market and by the send context (regular edit, EM LOV response or route request). All wire-contract construction lives in the builder. La transacción de escritura que envía al backend los cambios de registro de un punto de venta — datos del local, dirección, ruta/frecuencia, clasificación local y estado (activar/desactivar). Un único builder arma el payload JSON; lo que aparece en él lo gobiernan los módulos habilitados por mercado y el contexto del envío (edición común, respuesta EM LOV o solicitud de ruta). Toda la construcción del contrato wire vive en el builder.
O que é e quando aconteceWhat it is and when it happensQué es y cuándo ocurre
Quando o representante de vendas edita os dados de um varejo — o nome, o subtipo, os dias e horário de funcionamento, as categorias vendidas, o endereço, a frequência de visita/pedido/entrega, a classificação local ou o status (ativo/desativado) — o app envia essas mudanças ao backend por esta transação. É o momento em que a alteração feita no dispositivo passa a valer no sistema, refletindo depois no cadastro do varejo. When the sales rep edits a retail's data — its name, subtype, opening days and hours, categories sold, address, visit/order/delivery frequency, local classification or status (active/deactivated) — the app sends those changes to the backend through this transaction. It's the moment the change made on the device takes effect in the system, later reflecting on the retail's record. Cuando el representante de ventas edita los datos de un punto de venta — el nombre, el subtipo, los días y horario de atención, las categorías vendidas, la dirección, la frecuencia de visita/pedido/entrega, la clasificación local o el estado (activo/desactivado) — la app envía esos cambios al backend por esta transacción. Es el momento en que el cambio hecho en el dispositivo pasa a valer en el sistema, reflejándose luego en el registro del punto de venta.
Uma mesma transação cobre vários tipos de edição:A single transaction covers several kinds of edit:Una misma transacción cubre varios tipos de edición:
Cadastro do varejoRetail registrationRegistro del punto de venta
Nome, subtipo, categorias vendidas, dias e horário de funcionamento, endereço e classificação local.Name, subtype, categories sold, opening days and hours, address and local classification.Nombre, subtipo, categorías vendidas, días y horario de atención, dirección y clasificación local.
Rota e frequênciaRoute & frequencyRuta y frecuencia
Frequência de visita, de pedido e de entrega; dia preferido de visita e de entrega. A solicitação de rota é um caso próprio deste grupo.Visit, order and delivery frequency; preferred visit and delivery day. The route request is a case of its own in this group.Frecuencia de visita, de pedido y de entrega; día preferido de visita y de entrega. La solicitud de ruta es un caso propio de este grupo.
Status do varejoRetail statusEstado del punto de venta
Ativar, desativar temporariamente ou solicitar desativação permanente — com as datas correspondentes.Activate, temporarily deactivate or request permanent deactivation — with the matching dates.Activar, desactivar temporalmente o solicitar desactivación permanente — con las fechas correspondientes.
Resposta EM LOVEM LOV responseRespuesta EM LOV
Respostas a perguntas de mercado sobre o varejo — concorrência e produtos ilegais (só no Chile).Answers to market questions about the retail — competition and illegal products (Chile only).Respuestas a preguntas de mercado sobre el punto de venta — competencia y productos ilegales (solo Chile).
Uma transação, muitas ediçõesOne transaction, many editsUna transacción, muchas ediciones O rep não escolhe "que transação enviar": cada tela de edição salva e o app monta o envio certo. Editar só uma seção envia só o que aquela seção precisa — o resto do payload é preenchido a partir do cadastro atual do varejo. The rep doesn't pick "which transaction to send": each edit screen saves and the app assembles the right send. Editing a single section sends only what that section needs — the rest of the payload is filled from the retail's current record. El rep no elige "qué transacción enviar": cada pantalla de edición guarda y la app arma el envío correcto. Editar una sola sección envía solo lo que esa sección necesita — el resto del payload se completa a partir del registro actual del punto de venta.
Fluxo de telas que disparaScreen flow that fires itFlujo de pantallas que lo dispara
A edição de varejo é uma seção da feature de Retails (detalhe do varejo); mudanças de status também partem do detalhe da visita. Aqui só situamos onde o envio acontece:Retail editing is a section of the Retails feature (retail detail); status changes also start from the visit detail. Here we only place where the send happens:La edición de punto de venta es una sección de la feature de Retails (detalle del punto de venta); los cambios de estado también parten del detalle de la visita. Aquí solo situamos dónde ocurre el envío:
- Abrir o varejoOpen the retailAbrir el punto de ventaDa lista de varejos, o rep entra no detalhe do varejo que quer atualizar.From the retail list, the rep opens the detail of the retail to update.Desde la lista de puntos de venta, el rep entra en el detalle del que quiere actualizar.
- Escolher a seçãoPick the sectionElegir la secciónToca em editar uma seção — cadastro, endereço, dias de operação, categorias, classificação local ou frequência/rota.Taps to edit a section — registration, address, operating days, categories, local classification or frequency/route.Toca para editar una sección — registro, dirección, días de operación, categorías, clasificación local o frecuencia/ruta.
- Ajustar os camposAdjust the fieldsAjustar los camposFaz as mudanças; no endereço, o app também captura a localização atual.Makes the changes; on address, the app also captures the current location.Hace los cambios; en dirección, la app también captura la ubicación actual.
- Salvar → esta transaçãoSave → this transactionGuardar → esta transacciónAo salvar a seção, o app dispara a Atualização de varejo. Esse toque é o que aciona a transação.On saving the section, the app fires the Retailer update. That tap is what triggers the transaction.Al guardar la sección, la app dispara la Actualización de punto de venta. Ese toque es lo que activa la transacción.
Status e EM LOV na visitaStatus & EM LOV in the visitEstado y EM LOV en la visita Durante uma visita, o rep pode ativar/desativar o varejo ou responder perguntas de mercado (EM LOV) a partir do detalhe da visita. Essas ações disparam a mesma transação — muda só o que ela carrega. During a visit, the rep can activate/deactivate the retail or answer market questions (EM LOV) from the visit detail. These actions fire the same transaction — only what it carries changes. Durante una visita, el rep puede activar/desactivar el punto de venta o responder preguntas de mercado (EM LOV) desde el detalle de la visita. Estas acciones disparan la misma transacción — solo cambia lo que lleva.
Depois do envioAfter sendingDespués del envío
- Confirmação ao repConfirmation to the repConfirmación al rep
- Quando o backend aceita, a alteração é confirmada e o cadastro do varejo passa a refletir os novos dados. A mudança feita na tela vale a partir daí.When the backend accepts it, the change is confirmed and the retail's record reflects the new data. The on-screen change takes effect from then on.Cuando el backend lo acepta, el cambio se confirma y el registro del punto de venta refleja los nuevos datos. El cambio en pantalla vale desde entonces.
- Sem internetOfflineSin internet
- O envio é tentado na hora. Se falha (ex.: sem conexão), fica registrado com status de erro e pode ser reenviado quando a conexão volta — o rep não perde a edição.The send is attempted right away. If it fails (e.g. no connection), it is recorded with an error status and can be re-sent when the connection returns — the rep doesn't lose the edit.El envío se intenta en el momento. Si falla (p. ej. sin conexión), queda registrado con estado de error y puede reenviarse cuando vuelve la conexión — el rep no pierde la edición.
- Acompanhar o envioTracking the sendSeguir el envío
- O status técnico do despacho (enviado, com erro) aparece na central de dados / tracking de despachos do app — útil para suporte investigar uma atualização que não refletiu.The dispatch's technical status (sent, errored) shows in the app's data center / dispatch tracking — useful for support to investigate an update that didn't reflect.El estado técnico del despacho (enviado, con error) aparece en el centro de datos / tracking de despachos de la app — útil para que soporte investigue una actualización que no se reflejó.
Visão técnicaTechnical overviewVisión técnica
Atualização de varejo é a transação de saída que persiste no backend as mudanças cadastrais de uma conta (varejo). Ela é disparada por três notifiers de presentation — edição no detalhe do varejo, resposta EM LOV, e mudança de status/EM LOV na visita — todos passando pelo mesmo builder e pelo mesmo SubmitRetailerUploadUseCase.
Retailer update is the outbound transaction that persists an account's (retail's) registration changes in the backend. It's fired by three presentation notifiers — retail-detail edit, EM LOV response, and status/EM LOV change in the visit — all going through the same builder and the same SubmitRetailerUploadUseCase.
Actualización de punto de venta es la transacción de salida que persiste en el backend los cambios de registro de una cuenta (punto de venta). La disparan tres notifiers de presentation — edición en el detalle del punto de venta, respuesta EM LOV, y cambio de estado/EM LOV en la visita — todos por el mismo builder y el mismo SubmitRetailerUploadUseCase.
Payload modularModular payloadPayload modular
O payload tem sempre RetailerDetails + infoReport; blocos como accountSnapshot, address e localClassification entram só quando o mercado habilita o módulo (via RetailerUploadConfig).The payload always has RetailerDetails + infoReport; blocks like accountSnapshot, address and localClassification appear only when the market enables the module (via RetailerUploadConfig).El payload siempre tiene RetailerDetails + infoReport; bloques como accountSnapshot, address y localClassification entran solo cuando el mercado habilita el módulo (vía RetailerUploadConfig).
account vs currentAccountaccount vs currentAccountaccount vs currentAccount
O input carrega o rascunho editado (account) e o cadastro pré-edição (currentAccount). O builder decide campo a campo de qual dos dois cada chave sai.The input carries the edited draft (account) and the pre-edit record (currentAccount). The builder decides field by field which of the two each key comes from.El input lleva el borrador editado (account) y el registro pre-edición (currentAccount). El builder decide campo a campo de cuál de los dos sale cada clave.
RPC genéricoGeneric RPCRPC genérico
Não há RPC por atualização: tudo passa pelo mesmo sendTransaction, com o JSON no campo message e o serviceName RetailerUploadAPI como discriminador.There's no per-update RPC: everything goes through the same sendTransaction, with the JSON in the message field and the serviceName RetailerUploadAPI as the discriminator.No hay RPC por actualización: todo pasa por el mismo sendTransaction, con el JSON en el campo message y el serviceName RetailerUploadAPI como discriminador.
FontesSourcesFuentes
BuildRetailerUploadDispatcherPayloadUseCase + RetailerUploadDispatcherPayloadInput + DispatcherType.retailUpdate + DispatcherConectaRep.proto. O input carrega entities cruas de domínio (CLAUDE.md §36); o build() constrói todo o wire — rename, join, formatação de data e derivação.
BuildRetailerUploadDispatcherPayloadUseCase + RetailerUploadDispatcherPayloadInput + DispatcherType.retailUpdate + DispatcherConectaRep.proto. The input carries raw domain entities (CLAUDE.md §36); build() constructs the entire wire — rename, join, date formatting and derivation.
BuildRetailerUploadDispatcherPayloadUseCase + RetailerUploadDispatcherPayloadInput + DispatcherType.retailUpdate + DispatcherConectaRep.proto. El input lleva entities crudas de dominio (CLAUDE.md §36); build() construye todo el wire — rename, join, formateo de fecha y derivación.
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. Para a atualização de varejo, serviceName = "RetailerUploadAPI" e destino salesforce.The service exposes a single generic RPC — there's no per-transaction message. EVERY write transaction uses this same sendTransaction; what changes is the serviceName (discriminator) and the JSON inside message. For retail update, serviceName = "RetailerUploadAPI" and destination salesforce.El servicio expone un único RPC genérico — no existe mensaje por transacción. TODA transacción de escritura usa este mismo sendTransaction; lo que cambia es el serviceName (discriminador) y el JSON dentro de message. Para la actualización de punto de venta, serviceName = "RetailerUploadAPI" y destino salesforce.
sendTransactionunaryrpc sendTransaction(InboxTransactionRequest) returns (InboxTransactionReply)
path /mn.bat.conectarep.dispatcher.DispatcherConectaRepService/sendTransaction
InboxTransactionRequestendpointstring· #1 · destino (type.destination.value→"salesforce")destination (type.destination.value→"salesforce")destino (type.destination.value→"salesforce")serviceNamestring· #2 · discriminador —RetailerUploadAPI(prefixoPromo_não se aplica aqui)discriminator —RetailerUploadAPI(Promo_prefix does not apply here)discriminador —RetailerUploadAPI(el prefijoPromo_no aplica aquí)dateReferencestring· #3 ·AAAA-MM-DDdo envio (submittedAt)YYYY-MM-DDof the submission (submittedAt)AAAA-MM-DDdel envío (submittedAt)transactionReferencestring· #4 · osfiddo varejo (correlação)the retailsfid(correlation)elsfiddel punto de venta (correlación)usernamestring· #5 · usuário do rep (gateway)rep username (gateway)usuario del rep (gateway)messagestring· #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)manufacturerstring· #7 · dado do dispositivodevice datadato del dispositivomodelstring· #8 · dado do dispositivodevice datadato del dispositivodeviceUuidstring· #9 · literal provisório hoje (ver Pendências)provisional literal today (see Pending)literal provisional hoy (ver Pendientes)deviceVersionstring· #10tidint64· #11 · id de transação para idempotência/replaytransaction id for idempotency/replayid de transacción para idempotencia/replay
InboxTransactionReplystatusint32· #1 · status do ack (0 = sucesso)ack status (0 = success)status del ack (0 = éxito)messagestring· #2 · mensagem do backendbackend messagemensaje del backendtransactionIdint32· #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 (com re-tentativa em unauthenticated), 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 (retrying on unauthenticated), 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 (reintentando en unauthenticated), y llama al RPC.
Para a atualização de varejo, resendMayDuplicate == true: um reenvio (ex.: recuperação após erro) pode reprocessar a atualização no backend; a idempotência via tid é o que mitiga isso.For retail update, resendMayDuplicate == true: a resend (e.g. recovery after error) may reprocess the update on the backend; idempotency via tid is what mitigates it.Para la actualización de punto de venta, resendMayDuplicate == true: un reenvío (p. ej. recuperación tras error) puede reprocesar la actualización en el backend; la idempotencia vía tid es lo que lo mitiga.
serviceName e transação irmãserviceName & sister transactionserviceName y transacción hermana
A atualização de varejo é um único DispatcherType — retailUpdate — com serviceName = "RetailerUploadAPI". Como não há promoção envolvida, type.resolveServiceName(hasPromotion: false) devolve sempre "RetailerUploadAPI" (o prefixo Promo_ não é usado). O que varia não é a variante, e sim quais blocos o payload carrega — governados por módulos, mercado e contexto do envio.Retail update is a single DispatcherType — retailUpdate — with serviceName = "RetailerUploadAPI". Since no promotion is involved, type.resolveServiceName(hasPromotion: false) always returns "RetailerUploadAPI" (the Promo_ prefix is never used). What varies isn't a variant, but which blocks the payload carries — governed by modules, market and send context.La actualización de punto de venta es un único DispatcherType — retailUpdate — con serviceName = "RetailerUploadAPI". Como no hay promoción, type.resolveServiceName(hasPromotion: false) devuelve siempre "RetailerUploadAPI" (el prefijo Promo_ nunca se usa). Lo que varía no es la variante, sino qué bloques lleva el payload — gobernados por módulos, mercado y contexto del envío.
Mesmo tipo, dois buildersSame type, two buildersMismo tipo, dos builders
O tipo retailUpdate / serviceName RetailerUploadAPI é compartilhado com o envio de contato da equipe — documentado em 07 · Staff contact upload (doc separado). Mesmo endpoint e mesmo discriminador; o que distingue é a raiz do payload: aqui RetailerDetails/RouteDetails/infoReport/localClassification*; lá ContactDetails.
The retailUpdate type / RetailerUploadAPI serviceName is shared with staff contact upload — documented in 07 · Staff contact upload (separate doc). Same endpoint and same discriminator; what distinguishes them is the payload root: here RetailerDetails/RouteDetails/infoReport/localClassification*; there ContactDetails.
El tipo retailUpdate / serviceName RetailerUploadAPI es compartido con el envío de contacto del equipo — documentado en 07 · Staff contact upload (doc separado). Mismo endpoint y mismo discriminador; lo que los distingue es la raíz del payload: aquí RetailerDetails/RouteDetails/infoReport/localClassification*; allí ContactDetails.
Blocos do payload e o que os ligaPayload blocks and what gates themBloques del payload y qué los habilita
| BlocoBlockBloque | Presente quandoPresent whenPresente cuando | Governado porGated byGobernado por |
|---|---|---|
RetailerDetails | semprealwayssiempre | — |
infoReport | semprealwayssiempre | — |
RouteDetails | !isEmLovResponse | contexto do enviosend contextcontexto del envío |
RetailerDetails · bloco EMLov + lat/longEMLov + lat/long blockbloque EMLov + lat/long | market == CL | mercado (só Chile)market (Chile only)mercado (solo Chile) |
RetailerDetails · bloco accountSnapshotaccountSnapshot blockbloque accountSnapshot | includes(accountSnapshot) | RetailerUploadConfig (EMC) |
RetailerDetails · bloco addressaddress blockbloque address | includes(address) && addressState != null && addressCity != null | RetailerUploadConfig (EMC) |
localClassification · localClassificationDefination · localClassificationOption | includes(localClassification) && há definiçãodefinition presenthay definición | RetailerUploadConfig (EMC) |
RetailerUploadConfig.modules é uma lista resolvida por mercado (End Market Configuration, campo modules); includes(module:) testa a presença. O default é vazio (nenhum módulo). Os valores possíveis são accountSnapshot, address e localClassification.RetailerUploadConfig.modules is a per-market list (End Market Configuration, modules field); includes(module:) tests presence. The default is empty (no module). Possible values are accountSnapshot, address and localClassification.RetailerUploadConfig.modules es una lista por mercado (End Market Configuration, campo modules); includes(module:) prueba la presencia. El default es vacío (ningún módulo). Los valores posibles son accountSnapshot, address y localClassification.
Como é disparadoHow it's firedCómo se dispara
A transação é orquestrada por três notifiers de presentation, todos passando pelo SubmitRetailerUploadUseCase (remote-first, §36). O notifier apenas reúne entities cruas e flags de contexto; o builder é o dono único de todo join, rename, formatação de data e derivação wire. A cascata:The transaction is orchestrated by three presentation notifiers, all going through SubmitRetailerUploadUseCase (remote-first, §36). The notifier only gathers raw entities and context flags; the builder is the sole owner of every join, rename, date formatting and wire derivation. The cascade:La transacción se orquesta por tres notifiers de presentation, todos por el SubmitRetailerUploadUseCase (remote-first, §36). El notifier solo reúne entities crudas y flags de contexto; el builder es el dueño único de todo join, rename, formateo de fecha y derivación wire. La cascada:
- RetailDetail / Clave / VisitDetailnotifier
- reúne entities cruas + flagsgathers raw entities + flagsreúne entities crudas + flagsRetailerUploadDispatcherPayloadInput
- build()BuildRetailerUploadDispatcherPayloadUseCasemonta o wireassembles the wirearma el wire
- devolvereturnsdevuelveDispatcherEnvelope
- SubmitRetailerUploadUseCaseDispatcherOrchestratorregistra + despacharecords + dispatchesregistra + despacha
- DispatcherRepositoryDispatcherGatewayserializa + authserialize + authserializa + auth
- sendTransactionBackendgRPC · salesforce
- DispatcherRepositoryDispatcherGatewayserializa + authserialize + authserializa + auth
- SubmitRetailerUploadUseCaseDispatcherOrchestratorregistra + despacharecords + dispatchesregistra + despacha
- devolvereturnsdevuelveDispatcherEnvelope
- build()BuildRetailerUploadDispatcherPayloadUseCasemonta o wireassembles the wirearma el wire
- reúne entities cruas + flagsgathers raw entities + flagsreúne entities crudas + flagsRetailerUploadDispatcherPayloadInput
Contextos de disparoFiring contextsContextos de disparo
| Notifier · FeatureNotifier · FeatureNotifier · Feature | Ação do repRep actionAcción del rep | Flags do inputInput flagsFlags del input |
|---|---|---|
RetailDetailNotifier · retail_detail | edição de seção (cadastro, endereço, dias, categorias, classificação local) e solicitação de rotasection edit (registration, address, days, categories, local classification) and route requestedición de sección (registro, dirección, días, categorías, clasificación local) y solicitud de ruta | isRouteRequest = (section == registrationRequest); isEmLovResponse = false |
ClaveNotifier · clave | resposta de produtos ilegais (EM LOV — hasIllegalProducts)illegal-products response (EM LOV — hasIllegalProducts)respuesta de productos ilegales (EM LOV — hasIllegalProducts) | isEmLovResponse = true |
VisitDetailNotifier · visit_detail | resposta EM LOV na visita e mudança de status do varejo (ativar/desativar)EM LOV response in the visit and retail status change (activate/deactivate)respuesta EM LOV en la visita y cambio de estado del punto de venta (activar/desactivar) | isEmLovResponse = true (EM LOV); status: sem flagsstatus: no flagsstatus: sin flags |
O input (entities cruas)The input (raw entities)El input (entities crudas)
RetailerUploadDispatcherPayloadInput (Freezed). Carrega o dado como existe no domínio; nada de formato wire. O relógio chega como submittedAt (via DateTimeUtils.now()); lat/long vêm do LocationService na edição de endereço.RetailerUploadDispatcherPayloadInput (Freezed). Carries data as it exists in the domain; no wire shaping. The clock arrives as submittedAt (via DateTimeUtils.now()); lat/long come from LocationService on address edit.RetailerUploadDispatcherPayloadInput (Freezed). Lleva el dato como existe en el dominio; nada de formato wire. El reloj llega como submittedAt (vía DateTimeUtils.now()); lat/long vienen del LocationService en la edición de dirección.
| CampoFieldCampo | TipoTypeTipo | PapelRoleRol |
|---|---|---|
account | AccountDataEntity | rascunho editado — origem dos campos novos (nome, endereço, categorias, dias, frequência solicitada)edited draft — source of the new fields (name, address, categories, days, requested frequency)borrador editado — origen de los campos nuevos (nombre, dirección, categorías, días, frecuencia solicitada) |
currentAccount | AccountDataEntity | cadastro pré-edição — origem de identidade, status, datas, rota atual e EMLovpre-edit record — source of identity, status, dates, current route and EMLovregistro pre-edición — origen de identidad, estado, fechas, ruta actual y EMLov |
resource | ResourceEntity | representante de vendas (cru — o builder deriva resourceId primary/secondary)sales rep (raw — the builder derives primary/secondary resourceId)representante de ventas (crudo — el builder deriva resourceId primary/secondary) |
submittedAt | DateTime | relógio do envio → updateTime* e dateReferencesend clock → updateTime* and dateReferencereloj del envío → updateTime* y dateReference |
market | EndMarket | habilita o bloco CL; currencyIsoCode da classificação localenables the CL block; currencyIsoCode of local classificationhabilita el bloque CL; currencyIsoCode de la clasificación local |
retailerUploadConfig | RetailerUploadConfig · () | módulos habilitados (accountSnapshot/address/localClassification)enabled modules (accountSnapshot/address/localClassification)módulos habilitados (accountSnapshot/address/localClassification) |
outletSubtype | AccountOutletSubtypeEntity? | → outletSubtype (sfid) |
localClassificationDefinition | LocalClassificationDefinitionEntity? | só na edição de classificação localonly on local-classification editsolo en la edición de clasificación local |
localClassificationOption | LocalClassificationDefinitionOptionEntity? | opção escolhida (picklist → sfid; senão nome)chosen option (picklist → sfid; else name)opción elegida (picklist → sfid; si no nombre) |
addressState / addressCity | AddressStateEntity? / AddressCityEntity? | só na edição de endereço (gate do bloco address)only on address edit (gates the address block)solo en la edición de dirección (gate del bloque address) |
latitude / longitude | double? | posição (LocationService) na edição de endereçoposition (LocationService) on address editposición (LocationService) en la edición de dirección |
startDate | String · "" | → startDate / StartDate |
isRouteRequest | bool · false | edição de rota/frequência (requested vs current)route/frequency edit (requested vs current)edición de ruta/frecuencia (requested vs current) |
isEmLovResponse | bool · false | zera status wire e omite RouteDetailsblanks the wire status and omits RouteDetailsanula el status wire y omite RouteDetails |
Payload (message)
O JSON serializado no campo message do request. Cada tabela abaixo tem 4 colunas — Campo JSON · Tipo · Origem do Dado · Regra — e lista toda chave que o build() emite (67 no total, entre chaves sempre-presentes e condicionais). Campo, Tipo e Origem são código cru; só a Regra é prosa. Um exemplo completo (BR, com todos os módulos) está em transaction_example.json, ao lado deste doc.The JSON serialized into the request's message field. Each table below has 4 columns — JSON field · Type · Data source · Rule — and lists every key that build() emits (67 in total, across always-present and conditional keys). Field, Type and Source are raw code; only Rule is prose. A full example (BR, all modules) sits in transaction_example.json, next to this doc.El JSON serializado en el campo message del request. Cada tabla abajo tiene 4 columnas — Campo JSON · Tipo · Origen del Dato · Regla — y lista toda clave que build() emite (67 en total, entre claves siempre-presentes y condicionales). Campo, Tipo y Origen son código crudo; solo la Regla es prosa. Un ejemplo completo (BR, todos los módulos) está en transaction_example.json, junto a este doc.
RetailerDetails 1 objeto1 object1 objeto 28 camposfieldscampos
Array de um objeto. Os 11 campos base saem sempre; o bloco CL (4) só em
market == CL; o bloco accountSnapshot (5) e o bloco address (8) só quando o módulo é habilitado.latitude/longitudeaparecem em dois blocos distintos (CL e address) com origens diferentes.Array of one object. The 11 base fields always ship; the CL block (4) only whenmarket == CL; the accountSnapshot block (5) and address block (8) only when the module is enabled.latitude/longitudeappear in two distinct blocks (CL and address) with different sources.Array de un objeto. Los 11 campos base siempre salen; el bloque CL (4) solo enmarket == CL; el bloque accountSnapshot (5) y el bloque address (8) solo cuando el módulo está habilitado.latitude/longitudeaparecen en dos bloques distintos (CL y address) con orígenes diferentes.Campo JSON TipoTypeTipo Origem do DadoData sourceOrigen del Dato RegraRuleRegla retailerIDstring currentAccount.sfidsemprealwayssiempre categoriesSoldstring account.categoriesSoldlabels ( CategoryForSale.label) ordenados por index, excluiunknown, join";"CategoryForSale.labels sorted by index, excludesunknown, join";"CategoryForSale.labels ordenados por index, excluyeunknown, join";"outletSubtypestring input.outletSubtype?.sfid"" se ausente"" if absent"" si ausente statusstring statusWire"" se EM LOV response; senão transactionValue(oucurrentAccount.statuscru seunknown)"" if EM LOV response; elsetransactionValue(or rawcurrentAccount.statusifunknown)"" si EM LOV response; si notransactionValue(ocurrentAccount.statuscrudo siunknown)inactiveReasonstring dates.reasontemp → "Closed - Temporary"; permanente →account.inactiveReason; senão ""temp →"Closed - Temporary"; permanent →account.inactiveReason; else ""temp →"Closed - Temporary"; permanente →account.inactiveReason; si no ""PrefDelDaystring account.routeInfo?.delivery?.preferredDay"" se null"" if null"" si null callFreqstring callFrequencyValuemultiplicador da freq. de visita (ver Regras)visit-frequency multiplier (see Rules)multiplicador de la frec. de visita (ver Reglas) PrefVisitDaysstring account.routeInfo?.visit?.day"" se null"" if null"" si null DeActDatestring dates.deactivationDatedata de desativação (ver Regras)deactivation date (see Rules)fecha de desactivación (ver Reglas) ReActDatestring dates.reactivationDatedata de reativação (ver Regras)reactivation date (see Rules)fecha de reactivación (ver Reglas) TempDeActDatestring dates.tempDeactivationDatedata de desativação temporária (ver Regras)temporary deactivation date (see Rules)fecha de desactivación temporal (ver Reglas) EMLov3string currentAccount.hasCompetitionsó CL — "Yes"/"No"; null →"null"(concorrência)CL only —"Yes"/"No"; null →"null"(competition)solo CL —"Yes"/"No"; null →"null"(competencia)EMLov4string currentAccount.hasIllegalProductssó CL — "Yes"/"No"; null →"NULL"(produtos ilegais; casing difere do EMLov3)CL only —"Yes"/"No"; null →"NULL"(illegal products; casing differs from EMLov3)solo CL —"Yes"/"No"; null →"NULL"(productos ilegales; casing difiere de EMLov3)latitudestring currentAccount.latitude ?? 0só CL — como stringCL only — as stringsolo CL — como string longitudestring currentAccount.longitude ?? 0só CL — como stringCL only — as stringsolo CL — como string namestring account.namesó módulo accountSnapshotaccountSnapshotmodule onlysolo móduloaccountSnapshotcommercialNamestring account.commercialNamesó accountSnapshot; "" se nullaccountSnapshot only; "" if nullsolo accountSnapshot; "" si null daysOpenForBusinessstring account.operatingDayssó accountSnapshot; dias wire ordenados Mon→Sun ( WeekDay.sortWireValues), join";"accountSnapshot only; wire days sorted Mon→Sun (WeekDay.sortWireValues), join";"solo accountSnapshot; días wire ordenados Mon→Sun (WeekDay.sortWireValues), join";"openingTimestring account.openingTimesó accountSnapshot; "" se nullaccountSnapshot only; "" if nullsolo accountSnapshot; "" si null closingTimestring account.closingTimesó accountSnapshot; "" se nullaccountSnapshot only; "" if nullsolo accountSnapshot; "" si null latitudestring input.latitudesó módulo address(sobrepõe o bloco CL); "" se nulladdressmodule only (overrides CL block); "" if nullsolo móduloaddress(sobrepone el bloque CL); "" si nulllongitudestring input.longitudesó address; "" se nulladdress only; "" if nullsolo address; "" si null citySfidstring input.addressCity!.sfidsó address (gate exige city != null)address only (gate requires city != null)solo address (el gate exige city != null) stateSfidstring input.addressState!.sfidsó address (gate exige state != null)address only (gate requires state != null)solo address (el gate exige state != null) streetstring account.address?.streetsó address; "" se nulladdress only; "" if nullsolo address; "" si null addressLine2string account.address?.streetComplementsó address; "" se nulladdress only; "" if nullsolo address; "" si null neighborhoodstring account.address?.neighborhoodsó address; "" se nulladdress only; "" if nullsolo address; "" si null zipcodestring account.address?.postalCodesó address; "" se nulladdress only; "" if nullsolo address; "" si null infoReport 1 objeto1 object1 objeto 16 camposfieldscampos
Sempre presente. Traz o par "atual vs solicitado" da rota: campos sem prefixo vêm de
currentAccount; osrequested*vêm deaccount(rascunho).Always present. Carries the route's "current vs requested" pair: unprefixed fields come fromcurrentAccount; therequested*ones come fromaccount(draft).Siempre presente. Trae el par "actual vs solicitado" de la ruta: los campos sin prefijo vienen decurrentAccount; losrequested*vienen deaccount(borrador).Campo JSON TipoTypeTipo Origem do DadoData sourceOrigen del Dato RegraRuleRegla resourceIdstring resourceSfidsfid primary/secondary do rep (ver §07)rep primary/secondary sfid (see §07)sfid primary/secondary del rep (ver §07) accountNamestring account.name— geoFrequencystring currentAccount.routeInfo?.ordercomposta "code|sfid"(code padLeft 4); só o code se faltar sfid (ver Regras)compound"code|sfid"(code padLeft 4); code only if sfid missing (see Rules)compuesta"code|sfid"(code padLeft 4); solo el code si falta sfid (ver Reglas)callFrequencystring currentAccount.routeInfo?.visitcomposta "code|sfid"da visita (ver Regras)visit compound"code|sfid"(see Rules)compuesta"code|sfid"de la visita (ver Reglas)preferredDaysForVisitstring currentAccount.routeInfo?.visit?.day"" se null"" if null"" si null preferredDeliveryDaystring currentAccount.routeInfo?.delivery?.preferredDay"" se null"" if null"" si null deliveryLeadTimedouble | string currentAccount.routeInfo?.delivery?.leadTime?.toDouble()"" se null"" if null"" si null requestedGeoFrequencystring geoFrequencyValuemultiplicador solicitado (ver Regras)requested multiplier (see Rules)multiplicador solicitado (ver Reglas) requestedCallFrequencystring callFrequencyValuemultiplicador solicitado (ver Regras)requested multiplier (see Rules)multiplicador solicitado (ver Reglas) requestedPreferredDaysForVisitstring account.routeInfo?.visit?.day"" se null"" if null"" si null requestedPreferredDeliveryDaystring account.routeInfo?.delivery?.preferredDay"" se null"" if null"" si null startDatestring input.startDate"" default"" default"" default updateTimeFullstring "$dateReference $updateTimeHour"data + hora do enviosend date + timefecha + hora del envío updateTimeDatestring dateReferencesubmittedAtformatado (data)formattedsubmittedAt(date)submittedAtformateado (fecha)updateTimeHourstring updateTimeHoursubmittedAthoraHH:mmsubmittedAttimeHH:mmsubmittedAthoraHH:mmisFlexiblebool account.routeInfo?.delivery?.isFlexiblefalsese nullfalseif nullfalsesi nullRouteDetails 1 objeto ·
!isEmLovResponse1 object ·!isEmLovResponse1 objeto ·!isEmLovResponse11 camposfieldscamposPresente exceto em resposta EM LOV. As sequências de dia (
MonSeq…SunSeq) são placeholders inertes (ver Pendências).Present except on EM LOV response. The day sequences (MonSeq…SunSeq) are inert placeholders (see Pending).Presente excepto en respuesta EM LOV. Las secuencias de día (MonSeq…SunSeq) son placeholders inertes (ver Pendientes).Campo JSON TipoTypeTipo Origem do DadoData sourceOrigen del Dato RegraRuleRegla RouteIdstring routeId"" em route request; senão currentAccount.routeInfo?.order?.sfid"" on route request; elsecurrentAccount.routeInfo?.order?.sfid"" en route request; si nocurrentAccount.routeInfo?.order?.sfidgeoFreqstring geoFrequencyValuemultiplicador (ver Regras)multiplier (see Rules)multiplicador (ver Reglas) RetailerIdstring currentAccount.sfid— MonSeqstring Fixo: ""contrato · inertecontract · inertcontrato · inerte TueSeqstring Fixo: ""contrato · inertecontract · inertcontrato · inerte WedSeqstring Fixo: ""contrato · inertecontract · inertcontrato · inerte ThurSeqstring Fixo: ""contrato · inertecontract · inertcontrato · inerte FriSeqstring Fixo: ""contrato · inertecontract · inertcontrato · inerte SatSeqstring Fixo: ""contrato · inertecontract · inertcontrato · inerte SunSeqstring Fixo: ""contrato · inertecontract · inertcontrato · inerte StartDatestring input.startDate"" default"" default"" default localClassification bloco ·
includes(localClassification)block ·includes(localClassification)bloque ·includes(localClassification)12 camposfieldscamposTrês arrays irmãos, emitidos juntos só quando o módulo
localClassificationestá habilitado e hálocalClassificationDefinition. Se não houver definição, o bloco inteiro é omitido.Three sibling arrays, emitted together only when thelocalClassificationmodule is enabled and alocalClassificationDefinitionexists. If there's no definition, the whole block is omitted.Tres arrays hermanos, emitidos juntos solo cuando el módulolocalClassificationestá habilitado y haylocalClassificationDefinition. Si no hay definición, todo el bloque se omite.localClassification[]— 6 camposlocalClassification[]— 6 fieldslocalClassification[]— 6 camposCampo JSON TipoTypeTipo Origem do DadoData sourceOrigen del Dato RegraRuleRegla currencyIsoCodestring CurrencyUtils.isoCode(input.market)BRL / CLP / ZARBRL / CLP / ZARBRL / CLP / ZAR retailerIdstring currentAccount.sfid— locClassIdstring currentAccount.localClassification?.localClassificationSfid"" se null"" if null"" si null localClassNamestring definition.name— localClassOptIdstring optionIdpicklist → option.sfid; senãooption.namepicklist →option.sfid; elseoption.namepicklist →option.sfid; si nooption.namelocalClassDefIdstring definition.sfid— localClassificationDefination[]— 4 campos (chave com typo mantida verbatim)localClassificationDefination[]— 4 fields (misspelled key kept verbatim)localClassificationDefination[]— 4 campos (clave con typo mantenida verbatim)Campo JSON TipoTypeTipo Origem do DadoData sourceOrigen del Dato RegraRuleRegla localClassDefNamestring definition.name— isActivestring Fixo: "true"string literal (ver Pendências)string literal (see Pending)string literal (ver Pendientes) isMandatorystring Fixo: "true"string literal (ver Pendências)string literal (see Pending)string literal (ver Pendientes) typestring definition.type.transactionValuePicklist/Number/TextPicklist/Number/TextPicklist/Number/TextlocalClassificationOption[]— 2 camposlocalClassificationOption[]— 2 fieldslocalClassificationOption[]— 2 camposCampo JSON TipoTypeTipo Origem do DadoData sourceOrigen del Dato RegraRuleRegla localClassOptionNamestring input.localClassificationOption?.name"" se null"" if null"" si null localClassDefIdstring definition.sfid—
ExemploExampleEjemplo
Um payload completo (BR, com accountSnapshot + address + localClassification, status Active) está em docs/public/dispatcher/06_retail_update/transaction_example.json — a forma exata serializada em message (sem wrapper gRPC). Os campos EMLov3/EMLov4 não aparecem por serem só de CL.
A complete payload (BR, with accountSnapshot + address + localClassification, status Active) is in docs/public/dispatcher/06_retail_update/transaction_example.json — the exact shape serialized into message (no gRPC wrapper). The EMLov3/EMLov4 fields are absent because they're CL only.
Un payload completo (BR, con accountSnapshot + address + localClassification, estado Active) está en docs/public/dispatcher/06_retail_update/transaction_example.json — la forma exacta serializada en message (sin wrapper gRPC). Los campos EMLov3/EMLov4 no aparecen por ser solo de CL.
Regras de negócioBusiness rulesReglas de negocio
Resolução de StatusStatus resolutionResolución de Status AccountStatus → statusWire
Em resposta EM LOV (isEmLovResponse), status = "". Senão, AccountStatus.fromString(currentAccount.status) → transactionValue; se cair em unknown, envia o currentAccount.status cru.On EM LOV response (isEmLovResponse), status = "". Otherwise, AccountStatus.fromString(currentAccount.status) → transactionValue; if it lands on unknown, the raw currentAccount.status is sent.En respuesta EM LOV (isEmLovResponse), status = "". Si no, AccountStatus.fromString(currentAccount.status) → transactionValue; si cae en unknown, se envía el currentAccount.status crudo.
| AccountStatus | value | transactionValue |
|---|---|---|
active | active | Active |
temporarilyDeactivated | temporarily_deactivated | Temporarily Deactivated |
permanentDeactivationRequest | permanent_deactivation_request | Permanent Deactivation Requested |
disablePermanent | disable_permanent | Permanently Deactivated |
unknown | unknown | "" (usa status cru)"" (uses raw status)"" (usa status crudo) |
Datas de desativação / reativaçãoDeactivation / reactivation datesFechas de desactivación / reactivación _accountDates
_accountDates resolve as três datas + o motivo a partir do AccountStatus e das datas cruas de currentAccount (now = submittedAt formatado):_accountDates resolves the three dates + the reason from the AccountStatus and currentAccount's raw dates (now = formatted submittedAt):_accountDates resuelve las tres fechas + el motivo a partir del AccountStatus y las fechas crudas de currentAccount (now = submittedAt formateado):
DeActDate:nowse desativação permanente (isPermanentDeactivation); senão aaccount.deactivationDateformatada (ou "").DeActDate:nowif permanent deactivation (isPermanentDeactivation); else the formattedaccount.deactivationDate(or "").DeActDate:nowsi desactivación permanente (isPermanentDeactivation); si no laaccount.deactivationDateformateada (o "").ReActDate:nowseactive;account.reactivationDatesetemporarilyDeactivated; senão a data formatada (ou "").ReActDate:nowifactive;account.reactivationDateiftemporarilyDeactivated; else the formatted date (or "").ReActDate:nowsiactive;account.reactivationDatesitemporarilyDeactivated; si no la fecha formateada (o "").TempDeActDate+inactiveReason: setemporarilyDeactivated→now+"Closed - Temporary"; senãoTempDeActDate=account.deactivationDateformatada einactiveReason=account.inactiveReasonsó em desativação permanente.TempDeActDate+inactiveReason: iftemporarilyDeactivated→now+"Closed - Temporary"; elseTempDeActDate= formattedaccount.deactivationDateandinactiveReason=account.inactiveReasononly on permanent deactivation.TempDeActDate+inactiveReason: sitemporarilyDeactivated→now+"Closed - Temporary"; si noTempDeActDate=account.deactivationDateformateada einactiveReason=account.inactiveReasonsolo en desactivación permanente.
Frequência — multiplicador e compostaFrequency — multiplier & compoundFrecuencia — multiplicador y compuesta GeoCallFrequency · _compoundFrequency
- Multiplicador (
callFreq,geoFreq,requested*):GeoCallFrequency.fromWire(frequency)?.multipliercomo string —weekly(0001)→1,biweekly(0002)→2,monthly(0004)→4,bimonthly(0008)→8; "" se não mapear.Multiplier (callFreq,geoFreq,requested*):GeoCallFrequency.fromWire(frequency)?.multiplieras string —weekly(0001)→1,biweekly(0002)→2,monthly(0004)→4,bimonthly(0008)→8; "" if unmapped.Multiplicador (callFreq,geoFreq,requested*):GeoCallFrequency.fromWire(frequency)?.multipliercomo string —weekly(0001)→1,biweekly(0002)→2,monthly(0004)→4,bimonthly(0008)→8; "" si no mapea. - Composta (
geoFrequency,callFrequencyeminfoReport):_compoundFrequency="${code.padLeft(4,"0")}|$sfid"; se code ou sfid vazio, devolve só o code.Compound (geoFrequency,callFrequencyininfoReport):_compoundFrequency="${code.padLeft(4,"0")}|$sfid"; if code or sfid empty, returns the code only.Compuesta (geoFrequency,callFrequencyeninfoReport):_compoundFrequency="${code.padLeft(4,"0")}|$sfid"; si code o sfid vacío, devuelve solo el code. - Route request (
isRouteRequest):requestedGeoFrequency/requestedCallFrequencysaem só quando a frequência mudou (draft ≠ current); senão "".RouteIdvira "". Fora de route request, usam a frequência decurrentAccounteRouteId=order.sfid.Route request (isRouteRequest):requestedGeoFrequency/requestedCallFrequencyship only when the frequency changed (draft ≠ current); else "".RouteIdbecomes "". Outside a route request, they usecurrentAccount's frequency andRouteId=order.sfid.Route request (isRouteRequest):requestedGeoFrequency/requestedCallFrequencysalen solo cuando la frecuencia cambió (draft ≠ current); si no "".RouteIdqueda "". Fuera de route request, usan la frecuencia decurrentAccountyRouteId=order.sfid.
Categorias e dias de operaçãoCategories & operating daysCategorías y días de operación categoriesSold · daysOpenForBusiness
categoriesSold: excluiCategoryForSale.unknown, ordena porindex, mapeia para.label(ex.:FMC,THP Sticks,Vapour Devices) e junta com";".categoriesSold: excludesCategoryForSale.unknown, sorts byindex, maps to.label(e.g.FMC,THP Sticks,Vapour Devices) and joins with";".categoriesSold: excluyeCategoryForSale.unknown, ordena porindex, mapea a.label(p. ej.FMC,THP Sticks,Vapour Devices) y une con";".daysOpenForBusiness:WeekDay.sortWireValuesordena os dias wire deMondayaSunday(não reconhecidos ao fim) e junta com";".daysOpenForBusiness:WeekDay.sortWireValuessorts the wire days fromMondaytoSunday(unrecognized sink to the end) and joins with";".daysOpenForBusiness:WeekDay.sortWireValuesordena los días wire deMondayaSunday(no reconocidos al final) y une con";".
EM LOV (Chile)EM LOV (Chile)EM LOV (Chile) EMLov3 · EMLov4 · isEmLovResponse
EMLov3(concorrência,hasCompetition) eEMLov4(produtos ilegais,hasIllegalProducts): só no bloco CL._emLovValuedevolve"Yes"/"No"; para null usaemptyValue—"null"(EMLov3) vs"NULL"(EMLov4), casing verbatim do contrato.EMLov3(competition,hasCompetition) andEMLov4(illegal products,hasIllegalProducts): CL block only._emLovValuereturns"Yes"/"No"; for null it usesemptyValue—"null"(EMLov3) vs"NULL"(EMLov4), casing verbatim from the contract.EMLov3(competencia,hasCompetition) yEMLov4(productos ilegales,hasIllegalProducts): solo bloque CL._emLovValuedevuelve"Yes"/"No"; para null usaemptyValue—"null"(EMLov3) vs"NULL"(EMLov4), casing verbatim del contrato.- Numa resposta EM LOV (
isEmLovResponse), ostatusvai""e o blocoRouteDetailsé omitido — o envio carrega só a informação da resposta.On an EM LOV response (isEmLovResponse),statusships""and theRouteDetailsblock is omitted — the send carries only the response information.En una respuesta EM LOV (isEmLovResponse), elstatusva""y el bloqueRouteDetailsse omite — el envío lleva solo la información de la respuesta.
resourceId primary/secondaryprimary/secondary resourceIdresourceId primary/secondary resource.isPrimaryResource
resourceId (em infoReport) é derivado no builder: resource.isPrimaryResource ? resource.primaryResourceSfid : resource.secondaryResourceSfid. O notifier passa a ResourceEntity crua; a escolha primary/secondary é do build() (CLAUDE.md §25/§36).resourceId (in infoReport) is derived in the builder: resource.isPrimaryResource ? resource.primaryResourceSfid : resource.secondaryResourceSfid. The notifier passes the raw ResourceEntity; the primary/secondary pick belongs to build() (CLAUDE.md §25/§36).resourceId (en infoReport) se deriva en el builder: resource.isPrimaryResource ? resource.primaryResourceSfid : resource.secondaryResourceSfid. El notifier pasa la ResourceEntity cruda; la elección primary/secondary es del build() (CLAUDE.md §25/§36).
Pendências / roadmapPending / roadmapPendientes / roadmap
O que o builder envia inerte ou fixo, documentado fiel ao estado atual do código (nunca descrito como se já existisse):What the builder ships inert or fixed, documented faithfully to the current code state (never described as already existing):Lo que el builder envía inerte o fijo, documentado fiel al estado actual del código (nunca descrito como si ya existiera):
Não portado / pendenteNot ported / pendingNo portado / pendiente
RouteDetails.MonSeq…SunSeq: sempre""— a sequência de dias por rota nunca é populada.RouteDetails.MonSeq…SunSeq: always""— the per-route day sequence is never populated.RouteDetails.MonSeq…SunSeq: siempre""— la secuencia de días por ruta nunca se puebla.localClassificationDefination.isActiveeisMandatory: literais fixos"true"— os flags reais de ativo/obrigatório da definição não são consultados.localClassificationDefination.isActiveandisMandatory: fixed literals"true"— the definition's real active/mandatory flags aren't consulted.localClassificationDefination.isActiveeisMandatory: literales fijos"true"— los flags reales de activo/obligatorio de la definición no se consultan.EMLov4usaemptyValue"NULL"enquantoEMLov3usa"null"— inconsistência de casing mantida verbatim do contrato do backend.EMLov4usesemptyValue"NULL"whileEMLov3uses"null"— casing inconsistency kept verbatim from the backend contract.EMLov4usaemptyValue"NULL"mientrasEMLov3usa"null"— inconsistencia de casing mantenida verbatim del contrato del backend.- Chave do wire
localClassificationDefinationcom typo (falta o "i") mantida verbatim — é o nome esperado pelo backend.The wire keylocalClassificationDefinationis misspelled (missing the "i") but kept verbatim — it's the name the backend expects.La clave del wirelocalClassificationDefinationtiene typo (falta la "i") pero se mantiene verbatim — es el nombre que el backend espera. - Transporte:
deviceUuidvai como literal provisório no gateway (pendência conhecida do Dispatcher).Transport:deviceUuidships as a provisional literal in the gateway (known Dispatcher pending item).Transporte:deviceUuidva como literal provisional en el gateway (pendiente conocido del Dispatcher).
Transação irmãSister transactionTransacción hermana
O serviceName RetailerUploadAPI é compartilhado com o envio de contato da equipe — documentado em 07 · Staff contact upload (doc separado, mesmo tipo retailUpdate).
The RetailerUploadAPI serviceName is shared with staff contact upload — documented in 07 · Staff contact upload (separate doc, same retailUpdate type).
El serviceName RetailerUploadAPI es compartido con el envío de contacto del equipo — documentado en 07 · Staff contact upload (doc separado, mismo tipo retailUpdate).
MercadosMarketsMercados
A disponibilidade vem do DispatcherType.retailUpdate.enabledMarkets = [BR, CL, ZA]. AR/PY/PE não têm este dispatcher. O conteúdo do payload por mercado é governado pelos módulos do RetailerUploadConfig (EMC) e pelo bloco CL.Availability comes from DispatcherType.retailUpdate.enabledMarkets = [BR, CL, ZA]. AR/PY/PE don't have this dispatcher. The payload's content per market is governed by the RetailerUploadConfig modules (EMC) and the CL block.La disponibilidad viene de DispatcherType.retailUpdate.enabledMarkets = [BR, CL, ZA]. AR/PY/PE no tienen este dispatcher. El contenido del payload por mercado lo gobiernan los módulos de RetailerUploadConfig (EMC) y el bloque CL.
Só no ChileChile onlySolo Chile
O bloco EMLov3/EMLov4 (concorrência / produtos ilegais) e as coordenadas latitude/longitude de currentAccount em RetailerDetails só saem quando market == CL. A resposta EM LOV (via ClaveNotifier/VisitDetailNotifier) alimenta esse bloco.
The EMLov3/EMLov4 block (competition / illegal products) and the latitude/longitude coordinates from currentAccount in RetailerDetails ship only when market == CL. The EM LOV response (via ClaveNotifier/VisitDetailNotifier) feeds this block.
El bloque EMLov3/EMLov4 (competencia / productos ilegales) y las coordenadas latitude/longitude de currentAccount en RetailerDetails solo salen cuando market == CL. La respuesta EM LOV (vía ClaveNotifier/VisitDetailNotifier) alimenta ese bloque.
Módulos por mercadoModules per marketMódulos por mercado
Nos três mercados, os blocos accountSnapshot, address e localClassification entram no payload conforme os modules declarados no End Market Configuration daquele mercado — não é hardcode no builder. currencyIsoCode segue o mercado (BRL/CLP/ZAR).
In all three markets, the accountSnapshot, address and localClassification blocks enter the payload per the modules declared in that market's End Market Configuration — not hardcoded in the builder. currencyIsoCode follows the market (BRL/CLP/ZAR).
En los tres mercados, los bloques accountSnapshot, address y localClassification entran en el payload según los modules declarados en el End Market Configuration de ese mercado — no hardcode en el builder. currencyIsoCode sigue el mercado (BRL/CLP/ZAR).
AR · PY · PE
Existem como mercados do app (config PANGEA mínima), mas não têm este dispatcher — retailUpdate.enabledMarkets não os lista. A atualização de varejo não é disparada nesses mercados.
They exist as app markets (minimal PANGEA config), but have no this dispatcher — retailUpdate.enabledMarkets doesn't list them. Retail update is not fired in these markets.
Existen como mercados de la app (config PANGEA mínima), pero no tienen este dispatcher — retailUpdate.enabledMarkets no los lista. La actualización de punto de venta no se dispara en estos mercados.