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

Cadastro de novo varejoNew retail uploadAlta de nuevo punto de venta

A transação de escrita que envia ao backend o cadastro de um novo varejo (ponto de venda) montado no assistente Novo varejo. É o passo final do fluxo: o representante de vendas preenche tipo, documento, endereço, contatos, horários, categorias e fotos, e ao finalizar o app serializa tudo num único payload JSON de sete seções — conta, contatos, mapeamento de território, classificações e documentos — e o despacha. Toda a construção do contrato wire vive no builder. The write transaction that sends the backend the registration of a new retail (point of sale) assembled in the New retail wizard. It's the flow's final step: the sales rep fills in type, document, address, contacts, hours, categories and photos, and on finishing the app serializes everything into a single JSON payload of seven sections — account, contacts, territory mapping, classifications and documents — and dispatches it. All wire-contract construction lives in the builder. La transacción de escritura que envía al backend el alta de un nuevo punto de venta armado en el asistente Nuevo punto de venta. Es el paso final del flujo: el representante de ventas completa tipo, documento, dirección, contactos, horarios, categorías y fotos, y al finalizar la app serializa todo en un único payload JSON de siete secciones — cuenta, contactos, mapeo de territorio, clasificaciones y documentos — y lo despacha. Toda la construcción del contrato wire vive en el builder.

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

Quando o representante de vendas encontra um ponto de venda que ainda não existe na base, ele pode cadastrá-lo pelo app. O assistente de Novo varejo recolhe todos os dados do estabelecimento; esta transação é o que acontece no último toque, quando ele confirma o envio. É o momento em que o varejo recém-criado sai do dispositivo e passa a existir no sistema, para depois virar uma conta com a qual o rep pode agendar visitas e criar pedidos. When the sales rep finds a point of sale that does not yet exist in the base, they can register it from the app. The New retail wizard collects all of the outlet's data; this transaction is what happens on the final tap, when they confirm the send. It's the moment the brand-new retail leaves the device and starts to exist in the system, later becoming an account the rep can schedule visits for and create orders against. Cuando el representante de ventas encuentra un punto de venta que aún no existe en la base, puede darlo de alta desde la app. El asistente de Nuevo punto de venta recoge todos los datos del comercio; esta transacción es lo que ocurre en el último toque, cuando confirma el envío. Es el momento en que el comercio recién creado sale del dispositivo y pasa a existir en el sistema, para luego convertirse en una cuenta con la que el rep puede agendar visitas y crear pedidos.

O cadastro é enviado como um pacote único que descreve o varejo por inteiro:The registration is sent as a single package describing the whole retail:El alta se envía como un paquete único que describe el punto de venta por completo:

A lojaThe storeLa tienda

Documento, nome, endereço, horários de funcionamento, categorias vendidas e localização.Document, name, address, opening hours, categories sold and location.Documento, nombre, dirección, horarios de atención, categorías vendidas y ubicación.

As pessoasThe peopleLas personas

Os contatos do varejo (dono, gerente, balconista), com telefone, e-mail e função.The retail's contacts (owner, manager, clerk), with phone, e-mail and role.Los contactos del comercio (dueño, gerente, dependiente), con teléfono, correo y función.

Os documentosThe documentsLos documentos

As fotos dos documentos exigidos pelo mercado (ex.: frente e verso, comprovante de endereço).Photos of the documents required by the market (e.g. front and back, proof of address).Fotos de los documentos exigidos por el mercado (p. ej. frente y dorso, comprobante de domicilio).

Só criaçãoCreation onlySolo alta Esta transação cria um varejo do zero. Editar dados de um varejo que já existe é outra transação (atualização de varejo). Aqui não há variantes — o mesmo envio vale para Brasil, Chile e África do Sul; o que muda por país é apenas quais campos e documentos entram no pacote. This transaction creates a retail from scratch. Editing data of an already-existing retail is a different transaction (retail update). There are no variants here — the same send applies to Brazil, Chile and South Africa; what changes per country is only which fields and documents go into the package. Esta transacción crea un comercio desde cero. Editar datos de un comercio que ya existe es otra transacción (actualización de punto de venta). Aquí no hay variantes — el mismo envío aplica a Brasil, Chile y Sudáfrica; lo que cambia por país es solo qué campos y documentos entran en el paquete.

02

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

A transação é o último passo do assistente de Novo varejo. As telas do caminho pertencem a essa feature; aqui só situamos a jornada até o envio:The transaction is the last step of the New retail wizard. The screens along the way belong to that feature; here we only place the journey up to the send:La transacción es el último paso del asistente de Nuevo punto de venta. Las pantallas del camino pertenecen a esa feature; aquí solo situamos el recorrido hasta el envío:

  1. Abrir pela HomeOpen from HomeAbrir desde el HomeNo módulo Ações do representante, o rep toca em Criar varejo — o único ponto de entrada ativo do fluxo.In the Rep actions module, the rep taps Create retail — the flow's only active entry point.En el módulo Acciones del representante, el rep toca Crear PDV — el único punto de entrada activo del flujo.
  2. Tipo e documentoType and documentTipo y documentoEscolhe o tipo de varejo (que define os campos pedidos). No Brasil, uma tela extra valida o CPF/CNPJ no CRM antes de começar (exige internet).Picks the retail type (which decides the fields asked). In Brazil, an extra screen validates the CPF/CNPJ against the CRM before starting (requires internet).Elige el tipo de comercio (que define los campos pedidos). En Brasil, una pantalla extra valida el CPF/CNPJ en el CRM antes de empezar (requiere internet).
  3. Preencher o assistenteFill the wizardCompletar el asistenteInício/documentos (fotos), dados fiscais, endereço, dados operacionais (categorias, horários, banner, canal) e equipe do varejo (contatos).Start/documents (photos), tax data, address, operational data (categories, hours, banner, channel) and retail team (contacts).Inicio/documentos (fotos), datos fiscales, dirección, datos operativos (categorías, horarios, banner, canal) y equipo del comercio (contactos).
  4. RevisãoReviewRevisiónA tela de resumo mostra todas as seções preenchidas e permite voltar para editar qualquer uma.The summary screen shows all filled sections and lets the rep go back to edit any.La pantalla de resumen muestra todas las secciones completadas y permite volver a editar cualquiera.
  5. Finalizar → esta transaçãoFinish → this transactionFinalizar → esta transacciónAo tocar em Finalizar, abre um modal de confirmação; ao confirmar, o app dispara o Cadastro de novo varejo. É este toque que aciona a transação.Tapping Finish opens a confirmation modal; on confirming, the app fires the New retail upload. This tap is what triggers the transaction.Al tocar Finalizar se abre un modal de confirmación; al confirmar, la app dispara el Alta de nuevo punto de venta. Este toque es lo que activa la transacción.

As telas ficam na featureThe screens live in the featureLas pantallas viven en la feature O detalhe de cada tela, foto e validação está no doc de Novo varejo. Este doc cobre só o envio. The detail of each screen, photo and validation is in the New retail doc. This doc covers only the send. El detalle de cada pantalla, foto y validación está en el doc de Nuevo punto de venta. Este doc cubre solo el envío.

03

Depois do envioAfter sendingDespués del envío

Confirmação ao repConfirmation to the repConfirmación al rep
Um modal mostra o andamento e, quando o backend aceita, a mensagem de sucesso. Ao fechar, o app volta para a primeira tela do assistente e limpa tudo — isso é o que impede reenviar o mesmo cadastro por engano.A modal shows progress and, when the backend accepts it, the success message. On closing, the app returns to the wizard's first screen and clears everything — that is what prevents resubmitting the same registration by mistake.Un modal muestra el avance y, cuando el backend lo acepta, el mensaje de éxito. Al cerrar, la app vuelve a la primera pantalla del asistente y limpia todo — eso es lo que impide reenviar el mismo alta por error.
Código temporárioTemporary codeCódigo temporal
O app gera um código de cliente provisório na hora do envio. O código SAP definitivo é atribuído pelo backend depois de processar o cadastro.The app generates a provisional customer code at send time. The final SAP code is assigned by the backend after it processes the registration.La app genera un código de cliente provisional al enviar. El código SAP definitivo lo asigna el backend después de procesar el alta.
Sem internetOfflineSin internet
Diferente de outras transações, o cadastro de varejo não entra em fila: sem conexão o envio falha na hora e o modal mostra erro. O rep precisa estar online para concluir.Unlike other transactions, the retail registration is not queued: with no connection the send fails on the spot and the modal shows an error. The rep must be online to finish.A diferencia de otras transacciones, el alta de comercio no entra en cola: sin conexión el envío falla al instante y el modal muestra error. El rep debe estar en línea para concluir.
Acompanhar o envioTracking the sendSeguir el envío
O status técnico do despacho (enviado, com erro) pode ser acompanhado na Central de dados — útil para suporte investigar um envio.The dispatch's technical status (sent, errored) can be followed in the Data center — useful for support to investigate a send.El estado técnico del despacho (enviado, con error) puede seguirse en el Centro de datos — útil para que soporte investigue un envío.
04

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

Cadastro de novo varejo é a transação de saída que persiste um varejo recém-criado no backend (Salesforce). É disparada pelo NewRetailFlowNotifier.submitNewRetail() quando o representante de vendas finaliza o assistente. Uma única variante — DispatcherType.retailNew — cobre BR/CL/ZA; não há tipo indireto nem aprovação. New retail upload is the outbound transaction that persists a brand-new retail in the backend (Salesforce). It's fired by NewRetailFlowNotifier.submitNewRetail() when the sales rep finishes the wizard. A single variant — DispatcherType.retailNew — covers BR/CL/ZA; there is no indirect or approval type. Alta de nuevo punto de venta es la transacción de salida que persiste un comercio recién creado en el backend (Salesforce). La dispara NewRetailFlowNotifier.submitNewRetail() cuando el representante de ventas finaliza el asistente. Una única variante — DispatcherType.retailNew — cubre BR/CL/ZA; no hay tipo indirecto ni aprobación.

Payload de 7 seções7-section payloadPayload de 7 secciones

O JSON tem AccountData, ContactData, territoryStoreMapping, globalClassification, localClassification, localClassificationDefination e (condicional) DocumentData124 chaves no total.The JSON carries AccountData, ContactData, territoryStoreMapping, globalClassification, localClassification, localClassificationDefination and (conditional) DocumentData124 keys total.El JSON lleva AccountData, ContactData, territoryStoreMapping, globalClassification, localClassification, localClassificationDefination y (condicional) DocumentData124 claves en total.

Config dirige o wireConfig drives the wireConfig dirige el wire

Grande parte dos valores (record-type IDs, moeda, idioma, flags de envio) vem de NewRetailWireConfig, resolvido do End Market Configuration do mercado ativo.Much of the values (record-type IDs, currency, language, send flags) come from NewRetailWireConfig, resolved from the active market's End Market Configuration.Gran parte de los valores (record-type IDs, moneda, idioma, flags de envío) vienen de NewRetailWireConfig, resuelto del End Market Configuration del mercado activo.

RPC genéricoGeneric RPCRPC genérico

Não há RPC por cadastro: tudo passa pelo mesmo sendTransaction, com o JSON serializado no campo message e o serviceName AccountContactUploadAPI como discriminador.There's no per-registration RPC: everything goes through the same sendTransaction, with the JSON serialized into the message field and the AccountContactUploadAPI serviceName as the discriminator.No hay RPC por alta: todo pasa por el mismo sendTransaction, con el JSON serializado en el campo message y el serviceName AccountContactUploadAPI como discriminador.

FontesSourcesFuentes BuildNewRetailUploadDispatcherPayloadUseCase + NewRetailUploadDispatcherPayloadInput + DispatcherType + DispatcherConectaRep.proto. O input carrega entities cruas de domínio (CLAUDE.md §36); o build() constrói todo o wire. BuildNewRetailUploadDispatcherPayloadUseCase + NewRetailUploadDispatcherPayloadInput + DispatcherType + DispatcherConectaRep.proto. The input carries raw domain entities (CLAUDE.md §36); build() constructs the entire wire. BuildNewRetailUploadDispatcherPayloadUseCase + NewRetailUploadDispatcherPayloadInput + DispatcherType + 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)target endpoint (environment config)endpoint destino (config de ambiente)
serviceName
string · #2 · discriminadorAccountContactUploadAPI (sem prefixo Promo_: cadastro nunca tem promoção)discriminatorAccountContactUploadAPI (no Promo_ prefix: registration never has a promotion)discriminadorAccountContactUploadAPI (sin prefijo Promo_: el alta nunca tiene promoción)
dateReference
string · #3 · AAAA-MM-DD do envio (formatDate(submittedAt))YYYY-MM-DD of the submission (formatDate(submittedAt))AAAA-MM-DD del envío (formatDate(submittedAt))
transactionReference
string · #4 · o customerCode provisório (correlação)the provisional customerCode (correlation)el customerCode provisional (correlación)
username
string · #5
message
string · #6 · o payload JSON serializado (as tabelas da seção 08)the JSON payload serialized (the tables in section 08)el payload JSON serializado (las tablas 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 account é um DispatchAccountEntity(sapCode: customerCode, name: outletName). 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 account is a DispatchAccountEntity(sapCode: customerCode, name: outletName). 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 account es un DispatchAccountEntity(sapCode: customerCode, name: outletName). 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.

06

serviceName e a colisão 05 ↔ 07serviceName & the 05 ↔ 07 collisionserviceName y la colisión 05 ↔ 07

Esta transação usa DispatcherType.retailNew, cujo serviceName é AccountContactUploadAPI. Não há variantes nem prefixo Promo_ (resolveServiceName(hasPromotion: false) é chamado sempre). O destino é o Salesforce.This transaction uses DispatcherType.retailNew, whose serviceName is AccountContactUploadAPI. There are no variants and no Promo_ prefix (resolveServiceName(hasPromotion: false) is always called). The destination is Salesforce.Esta transacción usa DispatcherType.retailNew, cuyo serviceName es AccountContactUploadAPI. No hay variantes ni prefijo Promo_ (resolveServiceName(hasPromotion: false) se llama siempre). El destino es Salesforce.

Colisão de nomenclatura — leia antes de confundir 05, 06 e 07Naming collision — read before mixing up 05, 06 and 07Colisión de nomenclatura — lea antes de confundir 05, 06 y 07

Os nomes de arquivo dos builders e os serviceName se cruzam entre docs. Este doc (05) é o cadastro de um NOVO varejo (assistente new_retail), apesar de o serviceName se chamar AccountContactUploadAPI. Não confundir com a atualização de contatos da equipe (doc 07), cujo builder se chama build_account_contact_upload mas envia sob RetailerUploadAPI:The builder file names and the serviceNames cross over between docs. This doc (05) is the registration of a NEW retail (new_retail wizard), even though the serviceName is called AccountContactUploadAPI. Do not confuse it with the staff-contact update (doc 07), whose builder is named build_account_contact_upload yet sends under RetailerUploadAPI:Los nombres de archivo de los builders y los serviceName se cruzan entre docs. Este doc (05) es el alta de un NUEVO comercio (asistente new_retail), aunque el serviceName se llame AccountContactUploadAPI. No confundir con la actualización de contactos del equipo (doc 07), cuyo builder se llama build_account_contact_upload pero envía bajo RetailerUploadAPI:

Doc Builder (arquivo)Builder (file)Builder (archivo) DispatcherType serviceName O que fazWhat it doesQué hace
05 (este)(this)(este)account/build_new_retail_upload…retailNewAccountContactUploadAPICria um novo varejo (assistente new_retail)Creates a new retail (new_retail wizard)Crea un nuevo comercio (asistente new_retail)
06account/build_retailer_upload…retailUpdateRetailerUploadAPIAtualiza dados de um varejo existenteUpdates an existing retail's dataActualiza datos de un comercio existente
07staff/build_account_contact_upload…retailUpdateRetailerUploadAPIEnvia contato da equipe (compartilha type/serviceName com 06)Uploads a staff contact (shares type/serviceName with 06)Envía contacto del equipo (comparte type/serviceName con 06)

Resumo: 05 é o único a usar AccountContactUploadAPI; 06 e 07 compartilham retailUpdate/RetailerUploadAPI (dois builders, um mesmo type — docs que se cruzam). O nome do arquivo não indica o serviceName.Summary: 05 is the only one using AccountContactUploadAPI; 06 and 07 share retailUpdate/RetailerUploadAPI (two builders, one type — crossing docs). The file name does not indicate the serviceName.Resumen: 05 es el único que usa AccountContactUploadAPI; 06 y 07 comparten retailUpdate/RetailerUploadAPI (dos builders, un mismo type — docs que se cruzan). El nombre del archivo no indica el serviceName.

07

Como é disparadoHow it's firedCómo se dispara

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

  • NewRetailFlowNotifiersubmitNewRetail()
    • reúne entities cruas + injetadosgathers raw entities + injectedreúne entities crudas + inyectadosNewRetailUploadDispatcherPayloadInput
      • build()BuildNewRetailUploadDispatcherPayloadUseCasemonta o wireassembles the wirearma el wire
        • devolvereturnsdevuelveDispatcherEnvelope
          • SubmitNewRetailUploadUseCaseDispatcherOrchestrator
            • serializa + authserialize + authserializa + authDispatcherGateway
              • sendTransactionBackendgRPC · Salesforce

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

NewRetailUploadDispatcherPayloadInput (Freezed, ~46 campos). Carrega o dado como existe no domínio; nada de formato wire. O relógio chega como submittedAt (via DateTimeUtils.now(), capturado uma vez); imagesBase64 são os arquivos já lidos; lat/long vêm do LocationService (0.0 sem fix); customerCode é gerado no envio; wireConfig vem do EMC do mercado.NewRetailUploadDispatcherPayloadInput (Freezed, ~46 fields). Carries data as it exists in the domain; no wire shaping. The clock arrives as submittedAt (via DateTimeUtils.now(), captured once); imagesBase64 are the already-read files; lat/long come from LocationService (0.0 without a fix); customerCode is generated at send; wireConfig comes from the market's EMC.NewRetailUploadDispatcherPayloadInput (Freezed, ~46 campos). Lleva el dato como existe en el dominio; nada de formato wire. El reloj llega como submittedAt (vía DateTimeUtils.now(), capturado una vez); imagesBase64 son los archivos ya leídos; lat/long vienen del LocationService (0.0 sin fix); customerCode se genera al enviar; wireConfig viene del EMC del mercado.

CampoFieldCampoTipoTypeTipoPapelRoleRol
retailTypeNewRetailTypegeneric · individual · businessdefine pessoa física vs jurídica (isLegalEntity = retailType != individual)individual vs legal entity (isLegalEntity = retailType != individual)persona física vs jurídica (isLegalEntity = retailType != individual)
vatNumber / stateRegistrationStringdocumento fiscal (CNPJ/CPF/VAT) e inscrição estadual (BR)tax document (CNPJ/CPF/VAT) and state registration (BR)documento fiscal (CNPJ/CPF/VAT) e inscripción estatal (BR)
outletName / commercialNameStringrazão social e nome comerciallegal name and trade namerazón social y nombre comercial
countrySfid · stateCode · city · district · addressLine · number · addressContinue · postalCodeStringendereço completofull addressdirección completa
cellPhone · phone · emailStringcontatos da contaaccount contactscontactos de la cuenta
outletSubtypeSfidStringoutletSubtype
categoriesSoldList<CategoryForSale>categorias vendidas (labels)categories sold (labels)categorías vendidas (labels)
operatingDays · openingTime · closingTime · breakStart · breakEndList<String> / Stringdias e horários de funcionamentooperating days and hoursdías y horarios de atención
deliveryDay / salesmanVisitDayWeekDay?preferredDeliveryDay (wireAbbreviation) / PreferredDayForVisit (wireValue)
banner · propertyType · keyAccountType · giro · channelStringatributos comerciaiscommercial attributesatributos comerciales
isB2BCustomer · isDirectSales · isNetworkParentboolflags de conta (ver Regras/Pendências)account flags (see Rules/Pending)flags de cuenta (ver Reglas/Pendientes)
localClassificationName · …OptionSfid · …DefinitionSfid · …DefinitionTypeStringclassificação local (CL principalmente)local classification (mainly CL)clasificación local (CL sobre todo)
contactsList<NewRetailContactEntity>equipe do varejo → uma entrada de ContactData por contatoretail team → one ContactData entry per contactequipo del comercio → una entrada de ContactData por contacto
wireConfigNewRetailWireConfigconfig wire do mercado (record types, moeda, idioma, flags de envio)market wire config (record types, currency, language, send flags)config wire del mercado (record types, moneda, idioma, flags de envío)
resourceResourceEntityrepresentante de vendas (cru — o builder deriva salesTerritory/deliveryTerritory)sales rep (raw — the builder derives salesTerritory/deliveryTerritory)representante de ventas (crudo — el builder deriva salesTerritory/deliveryTerritory)
marketEndMarketmarketIso / MarketISO; formatação de CEPpostal-code formattingformateo de código postal
customerCodeStringcódigo provisório (stamp + ISO + 4 dígitos); vai em todas as seções + transactionReferenceprovisional code (stamp + ISO + 4 digits); goes in every section + transactionReferencecódigo provisional (stamp + ISO + 4 dígitos); va en todas las secciones + transactionReference
imagesBase64List<String>fotos já lidas em base64 (I/O resolvido pelo notifier) → DocumentDataphotos already read as base64 (I/O resolved by the notifier) → DocumentDatafotos ya leídas en base64 (I/O resuelto por el notifier) → DocumentData
latitude / longitudedoubleposição (LocationService; 0.0 quando indisponível)position (LocationService; 0.0 when unavailable)posición (LocationService; 0.0 cuando no disponible)
submittedAtDateTimerelógio único → dateReference, DocumentData.dateCreatesingle clock → dateReference, DocumentData.dateCreatereloj único → dateReference, DocumentData.dateCreate
08

Payload (message)

O JSON serializado no campo message do request. Cada tabela abaixo tem 4 colunasCampo JSON · Tipo · Origem do Dado · Regra — e lista toda chave que o build() emite (124 no total: 7 na raiz + 117 nos corpos das seções). Campo, Tipo e Origem são código cru; só a Regra é prosa. Um exemplo completo (varejo PJ/BR, 1 contato) está em transaction_example.json, ao lado deste doc.The JSON serialized into the request's message field. Each table below has 4 columnsJSON field · Type · Data source · Rule — and lists every key that build() emits (124 total: 7 at the root + 117 in the section bodies). Field, Type and Source are raw code; only Rule is prose. A full example (legal-entity/BR retail, 1 contact) sits in transaction_example.json, next to this doc.El JSON serializado en el campo message del request. Cada tabla abajo tiene 4 columnasCampo JSON · Tipo · Origen del Dato · Regla — y lista toda clave que build() emite (124 en total: 7 en la raíz + 117 en los cuerpos de las secciones). Campo, Tipo y Origen son código crudo; solo la Regla es prosa. Un ejemplo completo (comercio PJ/BR, 1 contacto) está en transaction_example.json, junto a este doc.

Raiz do payloadPayload rootRaíz del payload

Campo JSONTipoTypeTipoOrigem do DadoData sourceOrigen del DatoRegraRuleRegla
AccountDataarray_buildAccountDataarray de um único objeto (a conta)single-element array (the account)array de un solo objeto (la cuenta)
ContactDataarray_buildContactDatauma entrada por input.contactsone entry per input.contactsuna entrada por input.contacts
territoryStoreMappingarray_buildTerritoryStoreMappingarray de um único objetosingle-element arrayarray de un solo objeto
globalClassificationarray_buildGlobalClassificationarray de um único objetosingle-element arrayarray de un solo objeto
localClassificationarray_buildLocalClassificationarray de um único objetosingle-element arrayarray de un solo objeto
localClassificationDefinationarray_buildLocalClassificationDefinitionchave com typo "Defination" mantida verbatim (contrato)misspelled key "Defination" kept verbatim (contract)clave con typo "Defination" mantenida verbatim (contrato)
DocumentDataarray_buildDocumentDatacondicional — só quando wireConfig.sendsDocumentData (BR/CL); ausente em ZAconditional — only when wireConfig.sendsDocumentData (BR/CL); absent in ZAcondicional — solo cuando wireConfig.sendsDocumentData (BR/CL); ausente en ZA
  • AccountData objeto únicosingle objectobjeto único 59 camposfieldscampos
    Campo JSONTipoTypeTipoOrigem do DadoData sourceOrigen del DatoRegraRuleRegla
    VATRegistrationNostringtaxDocumentcondicional (sendsVatRegistrationNo); isLegalEntity ? vatNumber : ""conditional (sendsVatRegistrationNo); isLegalEntity ? vatNumber : ""condicional (sendsVatRegistrationNo); isLegalEntity ? vatNumber : ""
    taxIdstringtaxDocumentcondicional (sendsTaxId, default true); mesmo taxDocumentconditional (sendsTaxId, default true); same taxDocumentcondicional (sendsTaxId, default true); mismo taxDocument
    taxNumber2stringinput.vatNumberisLegalEntity ? "" : vatNumber (documento de pessoa física)isLegalEntity ? "" : vatNumber (individual's document)isLegalEntity ? "" : vatNumber (documento de persona física)
    taxNumber3stringinput.stateRegistration_digitsOnly (só dígitos); notifier só popula se o campo IE está visível_digitsOnly (digits only); notifier only populates it if the IE field is visible_digitsOnly (solo dígitos); el notifier solo lo puebla si el campo IE está visible
    namestringinput.outletName
    commercialNamestringinput.commercialName
    postCodestringinput.postalCodePostalCodeUtils.format; BR de 8 dígitos → NNNNN-NNN; outros → só dígitosPostalCodeUtils.format; BR 8-digit → NNNNN-NNN; others → digits onlyPostalCodeUtils.format; BR 8 dígitos → NNNNN-NNN; otros → solo dígitos
    addressLine1stringinput.addressLine + input.numbernumber vazio → só addressLine; senão "addressLine number".trim()number empty → addressLine alone; else "addressLine number".trim()number vacío → solo addressLine; si no "addressLine number".trim()
    addressLine2stringinput.addressContinue
    districtstringinput.district
    citystringinput.city
    Countrystringinput.countrySfid
    stateCodestringinput.stateCode
    categoriesSoldstringinput.categoriesSoldmap(category.label).join(";")map(category.label).join(";")map(category.label).join(";")
    outletSubtypestringinput.outletSubtypeSfid
    preferredDeliveryDaystringinput.deliveryDaydeliveryDay?.wireAbbreviation ?? "" (ex.: MON)deliveryDay?.wireAbbreviation ?? "" (e.g. MON)deliveryDay?.wireAbbreviation ?? "" (p. ej. MON)
    PreferredDayForVisitstringinput.salesmanVisitDaysalesmanVisitDay?.wireValue ?? "" (ex.: Monday)salesmanVisitDay?.wireValue ?? "" (e.g. Monday)salesmanVisitDay?.wireValue ?? "" (p. ej. Monday)
    daysOpenForBusinessstringinput.operatingDaysjoin(";")
    openingTimestringinput.openingTime
    closingTimestringinput.closingTime
    breakStartTimestringinput.breakStartcondicional — só quando breakStart não vazioconditional — only when breakStart is not emptycondicional — solo cuando breakStart no vacío
    breakEndTimestringinput.breakEndcondicional — só quando breakEnd não vazioconditional — only when breakEnd is not emptycondicional — solo cuando breakEnd no vacío
    mobilestringinput.cellPhone_digitsOnly
    telephone1stringinput.phone_digitsOnly
    contactEmailstringinput.email
    sapCustomerIdstringFixo: ""backend atribui o SAP definitivobackend assigns the final SAPel backend asigna el SAP definitivo
    recordTypeIdstringwireConfig.accountRecordTypeId
    statusstringFixo: "Active"
    activestringFixo: "Yes"
    marketIsostringmarket.name
    locationHierarchystringwireConfig.locationHierarchyId
    createdByIdstringFixo: ""
    isB2BCustomerstringinput.isB2BCustomer.toString()
    restrictedOrderEditstringwireConfig.restrictedOrderEdit
    isBillTostringFixo: "true"
    isShipTostringFixo: "true"
    isSoldTostringFixo: "true"
    isPayerstringFixo: "true"
    isPartialDeliverystringwireConfig.isPartialDelivery
    languagestringwireConfig.language
    salesTerritorystringresource.locationHierarchyId_salesTerritory(resource)
    deliveryTerritorystringresource.deliveryTerritory
    deliveryLeadTimestringFixo: "1"
    paymentMethodstringwireConfig.paymentMethod
    defaultPaymentMethodstringwireConfig.defaultPaymentMethod
    currencyIsoCodestringwireConfig.currencyIsoCode
    userQuotasstringwireConfig.userQuotas
    bannerstringinput.banner
    ownerShipTypestringinput.propertyType / wireConfig.ownerShipTypepropertyType vazio → wireConfig.ownerShipType; senão propertyTypepropertyType empty → wireConfig.ownerShipType; else propertyTypepropertyType vacío → wireConfig.ownerShipType; si no propertyType
    emlov1stringinput.giro
    emlov2stringinput.channel
    keyAccountTypestringinput.keyAccountType
    customerCodestringinput.customerCodecódigo provisórioprovisional codecódigo provisional
    istaxrequiredstringwireConfig.isTaxRequired
    isdirectsalesstringinput.isDirectSales / Fixo: "true"collectsDirectSales ? isDirectSales.toString() : "true"collectsDirectSales ? isDirectSales.toString() : "true"collectsDirectSales ? isDirectSales.toString() : "true"
    routeIDstringFixo: ""contrato · inertecontract · inertcontrato · inerte
    routeFrqstringFixo: ""contrato · inertecontract · inertcontrato · inerte
    latitudestringinput.latitude.toString()
    longitudestringinput.longitude.toString()
    • ContactData por contatoper contactpor contacto 22 camposfieldscampos

      Uma entrada por input.contacts (NewRetailContactEntity).One entry per input.contacts (NewRetailContactEntity).Una entrada por input.contacts (NewRetailContactEntity).

      Campo JSONTipoTypeTipoOrigem do DadoData sourceOrigen del DatoRegraRuleRegla
      firstNamestringcontact.firstName
      lastNamestringcontact.lastName
      recordTypeIdstringwireConfig.contactRecordTypeId
      mobilePhonestringcontact.cellPhone_digitsOnly
      salutationstringcontact.pronoun.wireValueMr. · Mrs. · Miss
      contactPositionstringCalculadoisNetworkParent && contact.isMainContact ? ContactRole.manager.label ("Manager") : ""isNetworkParent && contact.isMainContact ? ContactRole.manager.label ("Manager") : ""isNetworkParent && contact.isMainContact ? ContactRole.manager.label ("Manager") : ""
      rolestringcontact.role.labellabel cru do ContactRole (ex.: Owner)raw ContactRole label (e.g. Owner)label crudo de ContactRole (p. ej. Owner)
      isPrimaryContactstringcontact.isMainContact.toString()
      birthdatestringcontact.dateOfBirth_formatBirthdate: yyyy/MM/dd; null → ""_formatBirthdate: yyyy/MM/dd; null → ""_formatBirthdate: yyyy/MM/dd; null → ""
      mailingCountrystringwireConfig.mailingCountry
      PreferedLangstringwireConfig.contactPreferredLanguagechave com typo mantida verbatimmisspelled key kept verbatimclave con typo mantenida verbatim
      PreferedMethodtoContactstringFixo: "mobile"chave com typo mantida verbatimmisspelled key kept verbatimclave con typo mantenida verbatim
      b2bStatusstringwireConfig.contactB2bStatusdefault Inactivedefault Inactivedefault Inactive
      emailstringcontact.email
      customerCodestringinput.customerCode
      istaxrequiredstringFixo: "true"
      isdirectsalesstringFixo: "true"
      routeIDstringFixo: ""contrato · inertecontract · inertcontrato · inerte
      routeFrqstringFixo: ""contrato · inertecontract · inertcontrato · inerte
      latitudestringinput.latitude.toString()
      longitudestringinput.longitude.toString()
      languagePreferencestringcontact.preferredLanguage_languagePreferenceCode: isoCode (ex.: pt); vazio → fallback en_US_languagePreferenceCode: isoCode (e.g. pt); empty → en_US fallback_languagePreferenceCode: isoCode (p. ej. pt); vacío → fallback en_US
    • territoryStoreMapping objeto únicosingle objectobjeto único 6 camposfieldscampos
      Campo JSONTipoTypeTipoOrigem do DadoData sourceOrigen del DatoRegraRuleRegla
      CustomerCodestringinput.customerCode
      LocationIDstringresource.locationHierarchyId_salesTerritory(resource)
      MarketISOstringmarket.name
      assignTempResstringFixo: ""contrato · inertecontract · inertcontrato · inerte
      FromDatestringFixo: ""contrato · inertecontract · inertcontrato · inerte
      ToDatestringFixo: ""contrato · inertecontract · inertcontrato · inerte
    • globalClassification objeto únicosingle objectobjeto único 13 camposfieldscampos
      Campo JSONTipoTypeTipoOrigem do DadoData sourceOrigen del DatoRegraRuleRegla
      RecordTypeIDstringinput.categoriesSoldmap(label).join(":").replaceAll(" ", "_") (ex.: FMC:Vapour_Devices)map(label).join(":").replaceAll(" ", "_") (e.g. FMC:Vapour_Devices)map(label).join(":").replaceAll(" ", "_") (p. ej. FMC:Vapour_Devices)
      CustomerCodestringinput.customerCode
      MarketingAttractivenessstringFixo: ""contrato · inertecontract · inertcontrato · inerte
      sellinValperAnnumstringFixo: ""contrato · inertecontract · inertcontrato · inerte
      TotalsellinValperAnnumstringwireConfig.totalSellInValPerAnnumdirigido por config — varia por mercado (vazio no BR, "1" em CL/ZA)config-driven — varies by market (empty in BR, "1" in CL/ZA)dirigido por config — varía por mercado (vacío en BR, "1" en CL/ZA)
      FacingCapacitystringFixo: ""contrato · inertecontract · inertcontrato · inerte
      TotalfacingCapacitystringFixo: ""contrato · inertecontract · inertcontrato · inerte
      categorystringFixo: ""contrato · inertecontract · inertcontrato · inerte
      costofBusinessstringFixo: ""contrato · inertecontract · inertcontrato · inerte
      InStoreOppstringFixo: ""contrato · inertecontract · inertcontrato · inerte
      priceSegLowstringFixo: ""contrato · inertecontract · inertcontrato · inerte
      priceSegValuestringFixo: ""contrato · inertecontract · inertcontrato · inerte
      priceSegPremiumstringFixo: ""contrato · inertecontract · inertcontrato · inerte
    • localClassification objeto únicosingle objectobjeto único 5 camposfieldscampos
      Campo JSONTipoTypeTipoOrigem do DadoData sourceOrigen del DatoRegraRuleRegla
      currencyIsoCodestringwireConfig.currencyIsoCode
      customerCodestringinput.customerCode
      localClassNamestringinput.localClassificationName
      localClassOptIdstringinput.localClassificationOptionSfid
      localClassDefIdstringinput.localClassificationDefinitionSfid
    • localClassificationDefination objeto único · typo verbatimsingle object · verbatim typoobjeto único · typo verbatim 4 camposfieldscampos
      Campo JSONTipoTypeTipoOrigem do DadoData sourceOrigen del DatoRegraRuleRegla
      localClassDefNamestringinput.localClassificationName
      isActivestringFixo: "true"
      isMandatorystringFixo: "true"
      typestringinput.localClassificationDefinitionType
    • DocumentData objeto único · condicionalsingle object · conditionalobjeto único · condicional 8 camposfieldscampos

      Emitido só quando wireConfig.sendsDocumentData (BR/CL true; ZA false). Os índices em imagesBase64 dependem de PJ vs PF.Emitted only when wireConfig.sendsDocumentData (BR/CL true; ZA false). The imagesBase64 indices depend on legal-entity vs individual.Emitido solo cuando wireConfig.sendsDocumentData (BR/CL true; ZA false). Los índices en imagesBase64 dependen de PJ vs PF.

      Campo JSONTipoTypeTipoOrigem do DadoData sourceOrigen del DatoRegraRuleRegla
      namestringinput.outletName
      taxstringinput.vatNumber
      docFrontstringimagesBase64[0]_imageAt(0) · "" se ausente"" if absent"" si ausente
      docBackstringimagesBase64[1]_imageAt(1)
      addressProofstringimagesBase64[2 ou 3]PJ → índice 3; PF → índice 2legal entity → index 3; individual → index 2PJ → índice 3; PF → índice 2
      imageCNPJstringimagesBase64[2]PJ → índice 2; PF → ""legal entity → index 2; individual → ""PJ → índice 2; PF → ""
      customerCodestringinput.customerCode
      dateCreatestringinput.submittedAtformatTimestamp = DateTime.toString() (ex.: 2026-08-17 14:30:45.123456)formatTimestamp = DateTime.toString() (e.g. 2026-08-17 14:30:45.123456)formatTimestamp = DateTime.toString() (p. ej. 2026-08-17 14:30:45.123456)
09

Regras de negócioBusiness rulesReglas de negocio

Pessoa jurídica vs físicaLegal entity vs individualPersona jurídica vs física isLegalEntity · taxDocument

isLegalEntity = input.retailType != NewRetailType.individual (ou seja, generic e business contam como PJ). Deriva:isLegalEntity = input.retailType != NewRetailType.individual (i.e. generic and business both count as legal entity). Derives:isLegalEntity = input.retailType != NewRetailType.individual (es decir, generic y business cuentan como PJ). Deriva:

  • taxDocument = isLegalEntity ? vatNumber : "" → alimenta VATRegistrationNo e taxId.taxDocument = isLegalEntity ? vatNumber : "" → feeds VATRegistrationNo and taxId.taxDocument = isLegalEntity ? vatNumber : "" → alimenta VATRegistrationNo y taxId.
  • taxNumber2 = isLegalEntity ? "" : vatNumber — o documento de PF vai para taxNumber2, não para taxId.taxNumber2 = isLegalEntity ? "" : vatNumber — the individual's document goes to taxNumber2, not taxId.taxNumber2 = isLegalEntity ? "" : vatNumber — el documento de PF va a taxNumber2, no a taxId.
  • Fotos do DocumentData: PJ usa índices 0/1/2/3 (com imageCNPJ); PF usa 0/1/2 e imageCNPJ = "".DocumentData photos: legal entity uses indices 0/1/2/3 (with imageCNPJ); individual uses 0/1/2 and imageCNPJ = "".Fotos de DocumentData: PJ usa índices 0/1/2/3 (con imageCNPJ); PF usa 0/1/2 e imageCNPJ = "".
Flags dirigidas por configConfig-driven flagsFlags dirigidas por config isdirectsales · sendsDocumentData · sends*
  • isdirectsales: só usa o valor do rep se wireConfig.collectsDirectSales; senão força "true". Hoje só ZA coleta (collectsDirectSales = true); em BR e CL (false) o toggle do usuário é ignorado (ver Pendências).isdirectsales: uses the rep's value only if wireConfig.collectsDirectSales; otherwise forced to "true". Today only ZA collects it (collectsDirectSales = true); in BR and CL (false) the user's toggle is ignored (see Pending).isdirectsales: usa el valor del rep solo si wireConfig.collectsDirectSales; si no fuerza "true". Hoy solo ZA lo colecta (collectsDirectSales = true); en BR y CL (false) el toggle del usuario se ignora (ver Pendientes).
  • VATRegistrationNo / taxId: cada um só é emitido se o flag correspondente (sendsVatRegistrationNo / sendsTaxId) for true. BR: só taxId; outros mercados variam.VATRegistrationNo / taxId: each is emitted only if its flag (sendsVatRegistrationNo / sendsTaxId) is true. BR: only taxId; other markets vary.VATRegistrationNo / taxId: cada uno se emite solo si su flag (sendsVatRegistrationNo / sendsTaxId) es true. BR: solo taxId; otros mercados varían.
  • DocumentData: bloco inteiro só quando sendsDocumentData (BR/CL). Em ZA é false — as fotos são lidas mas o bloco não é enviado (ver Pendências).DocumentData: whole block only when sendsDocumentData (BR/CL). In ZA it's false — the photos are read but the block isn't sent (see Pending).DocumentData: bloque entero solo cuando sendsDocumentData (BR/CL). En ZA es false — las fotos se leen pero el bloque no se envía (ver Pendientes).
  • ownerShipType: propertyType do rep se preenchido; senão wireConfig.ownerShipType (ex.: ZA Independent).ownerShipType: rep's propertyType if filled; else wireConfig.ownerShipType (e.g. ZA Independent).ownerShipType: propertyType del rep si está lleno; si no wireConfig.ownerShipType (p. ej. ZA Independent).
Sanitização e formataçãoSanitization & formattingSanitización y formateo _digitsOnly · datas · CEP
  • _digitsOnly (replaceAll(RegExp(r"\D"), "")): aplicado a taxNumber3, mobile, telephone1 e mobilePhone — remove tudo que não for dígito._digitsOnly (replaceAll(RegExp(r"\D"), "")): applied to taxNumber3, mobile, telephone1 and mobilePhone — strips everything non-digit._digitsOnly (replaceAll(RegExp(r"\D"), "")): aplicado a taxNumber3, mobile, telephone1 y mobilePhone — quita todo lo no numérico.
  • Três formatos de data distintos: dateReference (envelope) = yyyy-MM-dd; birthdate = yyyy/MM/dd; DocumentData.dateCreate = DateTime.toString() (com hora e microssegundos).Three distinct date formats: dateReference (envelope) = yyyy-MM-dd; birthdate = yyyy/MM/dd; DocumentData.dateCreate = DateTime.toString() (with time and microseconds).Tres formatos de fecha distintos: dateReference (envelope) = yyyy-MM-dd; birthdate = yyyy/MM/dd; DocumentData.dateCreate = DateTime.toString() (con hora y microsegundos).
  • postCode: PostalCodeUtils.format só adiciona hífen para BR de 8 dígitos (NNNNN-NNN); qualquer outro mercado devolve só os dígitos.postCode: PostalCodeUtils.format only adds a hyphen for BR 8-digit (NNNNN-NNN); any other market returns digits only.postCode: PostalCodeUtils.format solo agrega guion para BR de 8 dígitos (NNNNN-NNN); cualquier otro mercado devuelve solo los dígitos.
  • preferredDeliveryDay usa wireAbbreviation (3 letras, MON); PreferredDayForVisit usa wireValue (nome completo, Monday) — formatos diferentes para dias da semana.preferredDeliveryDay uses wireAbbreviation (3 letters, MON); PreferredDayForVisit uses wireValue (full name, Monday) — different weekday formats.preferredDeliveryDay usa wireAbbreviation (3 letras, MON); PreferredDayForVisit usa wireValue (nombre completo, Monday) — formatos distintos para días de la semana.
Código de cliente provisórioProvisional customer codeCódigo de cliente provisional customerCode · NewRetailIdentifierUtils

Gerado no notifier por NewRetailIdentifierUtils.generateCustomerCode: {stamp}{market.name}{4 dígitos aleatórios}, onde stamp = formatDate(submittedAt, compactDateTime). É a mesma string usada como sapCode do envelope, transactionReference, e injetada em todas as seções (customerCode/CustomerCode). O SAP definitivo vem do backend depois.Generated in the notifier by NewRetailIdentifierUtils.generateCustomerCode: {stamp}{market.name}{4 random digits}, where stamp = formatDate(submittedAt, compactDateTime). It's the same string used as the envelope sapCode, transactionReference, and injected into every section (customerCode/CustomerCode). The final SAP comes from the backend afterwards.Generado en el notifier por NewRetailIdentifierUtils.generateCustomerCode: {stamp}{market.name}{4 dígitos aleatorios}, donde stamp = formatDate(submittedAt, compactDateTime). Es la misma string usada como sapCode del envelope, transactionReference, e inyectada en todas las secciones (customerCode/CustomerCode). El SAP definitivo viene del backend después.

Contato principal e redeMain contact & networkContacto principal y red contactPosition · isNetworkParent

contactPosition recebe ContactRole.manager.label ("Manager") quando o varejo é matriz de rede (isNetworkParent) e o contato é o principal (isMainContact); caso contrário "". O role de cada contato vai cru do ContactRole.label (wire, em inglês — decisão de produto, não é violação de i18n).contactPosition gets ContactRole.manager.label ("Manager") only when the retail is a network parent (isNetworkParent) and the contact is the main one (isMainContact); otherwise "". Each contact's role goes raw from ContactRole.label (wire, English — product decision, not an i18n violation).contactPosition recibe ContactRole.manager.label ("Manager") solo cuando el comercio es matriz de red (isNetworkParent) y el contacto es el principal (isMainContact); si no "". El role de cada contacto va crudo de ContactRole.label (wire, en inglés — decisión de producto, no es violación de i18n).

10

Pendências / roadmapPending / roadmapPendientes / roadmap

Comportamentos documentados fiéis ao estado atual do código (nunca descritos como se já fossem o ideal). Os itens abaixo são bugs de produto destapados ao documentar o fluxo, registrados no backlog do projeto.Behaviors documented faithfully to the current code state (never described as if already ideal). The items below are product bugs surfaced while documenting the flow, tracked in the project backlog.Comportamientos documentados fieles al estado actual del código (nunca descritos como si ya fueran lo ideal). Los ítems abajo son bugs de producto destapados al documentar el flujo, registrados en el backlog del proyecto.

Dado coletado que pode se perderCollected data that can be lostDato colectado que puede perderse

  • stateRegistration (Inscrição Estadual): hoje é enviado em taxNumber3, mas o notifier só o popula quando o campo IE está visível para o mercado/tipo — se o mercado não expõe o campo, o valor digitado (validado por UF) é descartado. Historicamente este campo não era enviado; o builder atual já o inclui.stateRegistration (state registration): today it is sent in taxNumber3, but the notifier only populates it when the IE field is visible for the market/type — if the market doesn't expose the field, the typed value (state-validated) is dropped. Historically this field was not sent; the current builder does include it.stateRegistration (inscripción estatal): hoy se envía en taxNumber3, pero el notifier solo lo puebla cuando el campo IE está visible para el mercado/tipo — si el mercado no expone el campo, el valor tipeado (validado por estado) se descarta. Históricamente este campo no se enviaba; el builder actual sí lo incluye.
  • Confirmação de isenção de IE: o modal de isenção devolve um bool usado apenas para liberar a navegação — não existe campo de isenção no input nem no payload. O dado se perde.IE exemption confirmation: the exemption modal returns a bool used only to unlock navigation — there's no exemption field in the input or payload. The data is lost.Confirmación de exención de IE: el modal de exención devuelve un bool usado solo para liberar la navegación — no existe campo de exención en el input ni en el payload. El dato se pierde.
  • isDirectSales: coletado no assistente, mas o payload só usa o valor do rep se wireConfig.collectsDirectSales. No estado atual, apenas ZA coleta (collectsDirectSales = true); em BR e CL (false) o toggle é forçado a "true" e, portanto, inerte.isDirectSales: collected in the wizard, but the payload uses the rep's value only if wireConfig.collectsDirectSales. As it stands today, only ZA collects it (collectsDirectSales = true); in BR and CL (false) the toggle is forced to "true" and therefore inert.isDirectSales: colectado en el asistente, pero el payload usa el valor del rep solo si wireConfig.collectsDirectSales. En el estado actual, solo ZA lo colecta (collectsDirectSales = true); en BR y CL (false) el toggle se fuerza a "true" y, por tanto, es inerte.
  • ZA lê fotos e descarta: com sendsDocumentData: false, o app ainda lê 3 fotos em base64 no envio, mas o bloco DocumentData nunca é montado — CPU/memória gastas sem destino.ZA reads photos and discards: with sendsDocumentData: false, the app still reads 3 photos as base64 at send, but the DocumentData block is never assembled — CPU/memory spent with no destination.ZA lee fotos y descarta: con sendsDocumentData: false, la app aún lee 3 fotos en base64 al enviar, pero el bloque DocumentData nunca se arma — CPU/memoria gastadas sin destino.

Contrato · inerte · transporteContract · inert · transportContrato · inerte · transporte

  • Vários campos são placeholders inertes fixos do contrato: globalClassification quase inteiro (MarketingAttractiveness, FacingCapacity, priceSeg*, etc. = ""), routeID/routeFrq, createdById, sapCustomerId, assignTempRes/FromDate/ToDate — o app não calcula nenhum.Several fields are fixed inert contract placeholders: almost the whole globalClassification (MarketingAttractiveness, FacingCapacity, priceSeg*, etc. = ""), routeID/routeFrq, createdById, sapCustomerId, assignTempRes/FromDate/ToDate — the app computes none.Varios campos son placeholders inertes fijos del contrato: casi todo globalClassification (MarketingAttractiveness, FacingCapacity, priceSeg*, etc. = ""), routeID/routeFrq, createdById, sapCustomerId, assignTempRes/FromDate/ToDate — la app no calcula ninguno.
  • Chaves com typo mantidas verbatim (contrato do backend): a seção localClassificationDefination, e em contato PreferedLang / PreferedMethodtoContact.Misspelled keys kept verbatim (backend contract): the localClassificationDefination section, and in contact PreferedLang / PreferedMethodtoContact.Claves con typo mantenidas verbatim (contrato del backend): la sección localClassificationDefination, y en contacto PreferedLang / PreferedMethodtoContact.
  • Sem fila offline: diferente da transação de visita, o cadastro de varejo não é enfileirado pelo DispatcherOrchestrator — sem conexão o envio falha na hora.No offline queue: unlike the visit transaction, the retail registration isn't queued by the DispatcherOrchestrator — with no connection the send fails on the spot.Sin cola offline: a diferencia de la transacción de visita, el alta de comercio no se encola en el DispatcherOrchestrator — sin conexión el envío falla al instante.
  • 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).

Docs irmãsSister docsDocs hermanas A feature completa (telas, fotos, validações) está em New retail. A atualização de varejo existente é a transação 06 · Retailer update (RetailerUploadAPI) — ver a colisão na seção 06. The full feature (screens, photos, validations) is in New retail. Updating an existing retail is transaction 06 · Retailer update (RetailerUploadAPI) — see the collision in section 06. La feature completa (pantallas, fotos, validaciones) está en New retail. La actualización de comercio existente es la transacción 06 · Retailer update (RetailerUploadAPI) — ver la colisión en la sección 06.

MercadosMarketsMercados

A disponibilidade da transação vem do DispatcherType.retailNew.enabledMarkets = BR/CL/ZA. AR/PY/PE existem como mercados do app (config PANGEA mínima) mas não têm dispatcher de cadastro de varejo. O que muda entre BR/CL/ZA é a NewRetailWireConfig e quais campos/fotos entram no pacote.Transaction availability comes from DispatcherType.retailNew.enabledMarkets = BR/CL/ZA. AR/PY/PE exist as app markets (minimal PANGEA config) but have no retail-registration dispatcher. What changes across BR/CL/ZA is the NewRetailWireConfig and which fields/photos go into the package.La disponibilidad de la transacción viene de DispatcherType.retailNew.enabledMarkets = BR/CL/ZA. AR/PY/PE existen como mercados de la app (config PANGEA mínima) pero no tienen dispatcher de alta de comercio. Lo que cambia entre BR/CL/ZA es la NewRetailWireConfig y qué campos/fotos entran en el paquete.

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

Config de wire por mercadoWire config per marketConfig de wire por mercado

NewRetailWireConfig BR CL ZA
currencyIsoCodeBRLCLPZAR
defaultPaymentMethodZGZEZH
languagePTESEN
sendsTaxIdtruetruefalse
sendsVatRegistrationNofalsefalsetrue
sendsDocumentDatatruetruefalse
collectsDirectSalesfalsefalsetrue
ownerShipTypevazioemptyvacíovazioemptyvacíoIndependent

Valores lidos do end_market_configuration.detailed.jsonc (newRetailConfig.wireConfig). A config atualiza ao vivo via Remote Config.Values read from end_market_configuration.detailed.jsonc (newRetailConfig.wireConfig). The config updates live via Remote Config.Valores leídos de end_market_configuration.detailed.jsonc (newRetailConfig.wireConfig). La config se actualiza en vivo vía Remote Config.

BR

Só no BrasilBrazil onlySolo Brasil CEP formatado com hífen (NNNNN-NNN); validação de CPF/CNPJ no CRM antes de iniciar; Inscrição Estadual (taxNumber3) validada por UF. DocumentData ativo, com imageCNPJ para pessoa jurídica. Postal code formatted with a hyphen (NNNNN-NNN); CPF/CNPJ validated against the CRM before starting; state registration (taxNumber3) validated by state. DocumentData active, with imageCNPJ for legal entities. Código postal formateado con guion (NNNNN-NNN); CPF/CNPJ validado en el CRM antes de iniciar; inscripción estatal (taxNumber3) validada por estado. DocumentData activo, con imageCNPJ para persona jurídica.

CL

Só no ChileChile onlySolo Chile Classificação local (localClassification/Defination) é o principal uso; DocumentData ativo. Como generic ≠ individual, a foto de "início de atividade" cai como PJ em docFront (ver backend-contracts). Local classification (localClassification/Defination) is the main use; DocumentData active. Since generic ≠ individual, the "start of activity" photo falls as legal entity into docFront (see backend-contracts). La clasificación local (localClassification/Defination) es el uso principal; DocumentData activo. Como generic ≠ individual, la foto de "inicio de actividad" cae como PJ en docFront (ver backend-contracts).

ZA

Só na África do SulSouth Africa onlySolo Sudáfrica sendsDocumentData: false — nenhum bloco DocumentData é enviado (as fotos ainda são lidas e descartadas, ver Pendências). ownerShipType default Independent; idioma de contato pode ser Afrikaans/Zulu/Xhosa etc. via languagePreference. sendsDocumentData: false — no DocumentData block is sent (photos are still read and discarded, see Pending). ownerShipType defaults to Independent; contact language may be Afrikaans/Zulu/Xhosa etc. via languagePreference. sendsDocumentData: false — no se envía ningún bloque DocumentData (las fotos aún se leen y se descartan, ver Pendientes). ownerShipType por defecto Independent; el idioma de contacto puede ser Afrikaans/Zulu/Xhosa etc. vía languagePreference.

AR · PY · PE Existem como mercados do app (config PANGEA mínima: só version + updateConfig + newRetailConfig.wireConfig + visitsConfig), mas não têm dispatcher de cadastro de varejoretailNew.enabledMarkets não os lista. They exist as app markets (minimal PANGEA config: only version + updateConfig + newRetailConfig.wireConfig + visitsConfig), but have no retail-registration dispatcherretailNew.enabledMarkets doesn't list them. Existen como mercados de la app (config PANGEA mínima: solo version + updateConfig + newRetailConfig.wireConfig + visitsConfig), pero no tienen dispatcher de alta de comercioretailNew.enabledMarkets no los lista.