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

Ordem de serviço de merchandisingMerchandising service orderOrden de servicio de merchandising

A transação de escrita que gera a ordem de serviço de merchandising no backend, via o Dispatcher. Quando o representante de vendas conclui um serviço de merchandising cujo fluxo roda fora do CRM, este é o envio decisivo — o que cria a ordem em si e decide a conclusão. Ele carrega os códigos de atividade, serviço e motivo, as peças com quantidade e movimento, as fotos e o CNPJ do varejo. Toda a construção do contrato wire vive no builder. The write transaction that creates the merchandising service order on the backend, through the Dispatcher. When the sales rep finishes a merchandising service whose flow runs outside the CRM, this is the decisive send — the one that creates the order itself and decides completion. It carries the activity, service and reason codes, the pieces with quantity and movement, the photos and the retail's CNPJ. All wire-contract construction lives in the builder. La transacción de escritura que genera la orden de servicio de merchandising en el backend, vía el Dispatcher. Cuando el representante de ventas termina un servicio de merchandising cuyo flujo corre fuera del CRM, este es el envío decisivo — el que crea la orden en sí y decide la conclusión. Lleva los códigos de actividad, servicio y motivo, las piezas con cantidad y movimiento, las fotos y el CNPJ del punto de venta. 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
01

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

Merchandising é o material de ponto de venda — displays, geladeiras, expositores, cartazes — que a marca instala e mantém no varejo. Quando o representante de vendas conclui uma ordem de serviço de merchandising (o que foi instalado, mantido ou removido, com quantidade, foto e comentário), o app envia essa ordem ao backend por esta transação. É o envio que gera a ordem de serviço propriamente dita. Merchandising is the point-of-sale material — displays, coolers, racks, posters — that the brand installs and maintains at the retail. When the sales rep finishes a merchandising service order (what was installed, maintained or removed, with quantity, photo and comment), the app sends that order to the backend through this transaction. It's the send that creates the service order itself. Merchandising es el material de punto de venta — displays, refrigeradores, exhibidores, carteles — que la marca instala y mantiene en el punto de venta. Cuando el representante de ventas termina una orden de servicio de merchandising (lo que se instaló, mantuvo o retiró, con cantidad, foto y comentario), la app envía esa orden al backend por esta transacción. Es el envío que genera la orden de servicio propiamente dicha.

Cada envio carrega:Each send carries:Cada envío lleva:

Contexto do serviçoService contextContexto del servicio

A atividade, o serviço e o motivo escolhidos pelo rep, além do varejo em que ocorreu.The activity, service and reason the rep picked, plus the retail where it happened.La actividad, el servicio y el motivo que eligió el rep, además del punto de venta donde ocurrió.

Peças, fotos e movimentoPieces, photos & movementPiezas, fotos y movimiento

Cada peça vai com sua quantidade, o movimento (instalar, manter, remover) e as fotos tiradas no PDV.Each piece goes with its quantity, the movement (install, maintain, remove) and the photos taken at the point of sale.Cada pieza va con su cantidad, el movimiento (instalar, mantener, retirar) y las fotos tomadas en el punto de venta.

Sem escolhas do repNo rep choicesSin elecciones del rep

Não há variantes nem ramificações: o gesto é sempre o mesmo — concluir a ordem de serviço e enviar.There are no variants or branches: the gesture is always the same — finish the service order and send.No hay variantes ni ramificaciones: el gesto es siempre el mismo — terminar la orden de servicio y enviar.

Um par de enviosA pair of sendsUn par de envíos Ao concluir a ordem de serviço, o app dispara duas transações em sequência: primeiro a Criação de merchandising, que registra o retrato do serviço, e logo esta (Ordem de serviço), que gera a ordem e decide a conclusão. Para o rep é um único gesto. On finishing the service order, the app fires two transactions in sequence: first Merchandising creation, which records the service snapshot, and right after this one (Service order), which creates the order and decides completion. For the rep it's a single gesture. Al terminar la orden de servicio, la app dispara dos transacciones en secuencia: primero la Creación de merchandising, que registra el retrato del servicio, y enseguida esta (Orden de servicio), que crea la orden y decide la conclusión. Para el rep es un solo gesto.

02

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

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

  1. EspecificaçõesSpecificationsEspecificacionesO rep escolhe a atividade, o serviço e o motivo do merchandising.The rep picks the merchandising activity, service and reason.El rep elige la actividad, el servicio y el motivo del merchandising.
  2. Tipos de peçaPiece typesTipos de piezaSeleciona as peças, informa a quantidade e o movimento de cada uma e, para cada peça, tira fotos e escreve um comentário.Selects the pieces, sets each one's quantity and movement and, for each piece, takes photos and writes a comment.Selecciona las piezas, indica la cantidad y el movimiento de cada una y, para cada pieza, toma fotos y escribe un comentario.
  3. ResumoSummaryResumenConfere o serviço e as peças antes de enviar.Reviews the service and pieces before sending.Revisa el servicio y las piezas antes de enviar.
  4. Enviar → esta transaçãoSend → this transactionEnviar → esta transacciónAo tocar em enviar no resumo, o app dispara a Criação de merchandising e, na sequência, a Ordem de serviço. É este segundo envio que decide se a conclusão foi bem-sucedida.Tapping send on the summary fires Merchandising creation and, right after, the Service order. This second send is what decides whether completion succeeded.Al tocar enviar en el resumen, la app dispara la Creación de merchandising y, enseguida, la Orden de servicio. Este segundo envío es lo que decide si la conclusión fue exitosa.
03

Depois do envioAfter sendingDespués del envío

Confirmação ao repConfirmation to the repConfirmación al rep
Esta é a transação decisiva: a conclusão da ordem de serviço só é confirmada ao rep quando este envio é aceito pelo backend. Se ele falhar, a conclusão não se completa — diferente da Criação de merchandising, que é complementar e não bloqueia.This is the decisive transaction: finishing the service order is only confirmed to the rep when this send is accepted by the backend. If it fails, completion doesn't go through — unlike Merchandising creation, which is complementary and doesn't block.Esta es la transacción decisiva: la conclusión de la orden de servicio solo se confirma al rep cuando este envío es aceptado por el backend. Si falla, la conclusión no se completa — a diferencia de la Creación de merchandising, que es complementaria y no bloquea.
Sem internetOfflineSin internet
Sem conexão, este envio falha na hora — ele não fica numa fila automática (diferente do envio de visita). O rep vê o erro na confirmação e pode tentar de novo. Se um envio já saído for reenviado, em tese pode duplicar a ordem; o sistema usa um identificador de transação para reduzir isso.Without a connection, this send fails right away — it is not held in an automatic queue (unlike the visit send). The rep sees the error on the confirmation and can try again. If an already-sent dispatch is resent, it could in theory duplicate the order; the system uses a transaction id to reduce that.Sin conexión, este envío falla al instanteno queda en una cola automática (a diferencia del envío de visita). El rep ve el error en la confirmación y puede intentar de nuevo. Si un despacho ya enviado se reenvía, podría en teoría duplicar la orden; el sistema usa un identificador de transacción para reducir eso.
Acompanhar o envioTracking the sendSeguir el envío
O status técnico do despacho (enviado, em fila, com erro) pode ser acompanhado na central de dados / tracking de despachos do app — útil para suporte investigar um envio.The dispatch's technical status (sent, queued, errored) can be followed in the app's data center / dispatch tracking — useful for support to investigate a send.El estado técnico del despacho (enviado, en cola, con error) puede seguirse en el centro de datos / tracking de despachos de la app — útil para que soporte investigue un envío.
04

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

Ordem de serviço de merchandising (DispatcherType.merchandisingServiceOrder, serviceName BPOneServiceOrderUpsert) é a transação de saída que gera a ordem de serviço no backend. É disparada pelo notifier da ordem de serviço quando o fluxo roda fora do CRM, como segundo dos dois envelopes — e é a que decide a conclusão. Diferente da Criação de merchandising (que envia rótulos e fotos posicionais), aqui o payload envia códigos, quantidade, movimento, fotos em lista plana e o CNPJ do varejo. Merchandising service order (DispatcherType.merchandisingServiceOrder, serviceName BPOneServiceOrderUpsert) is the outbound transaction that creates the service order on the backend. It's fired by the service-order notifier when the flow runs outside the CRM, as the second of the two envelopes — and it's the one that decides completion. Unlike Merchandising creation (which sends labels and positional photos), here the payload sends codes, quantity, movement, photos in a flat list and the retail's CNPJ. Orden de servicio de merchandising (DispatcherType.merchandisingServiceOrder, serviceName BPOneServiceOrderUpsert) es la transacción de salida que genera la orden de servicio en el backend. Se dispara desde el notifier de la orden de servicio cuando el flujo corre fuera del CRM, como segundo de los dos envelopes — y es la que decide la conclusión. A diferencia de la Creación de merchandising (que envía etiquetas y fotos posicionales), aquí el payload envía códigos, cantidad, movimiento, fotos en lista plana y el CNPJ del punto de venta.

Payload enxutoLean payloadPayload compacto

10 chaves na raiz + parts (3 chaves por peça) — 13 no total. Sem cálculo monetário, sem variantes, sem campos inertes de contrato.10 root keys + parts (3 keys per piece) — 13 in total. No monetary computation, no variants, no inert contract fields.10 claves en la raíz + parts (3 claves por pieza) — 13 en total. Sin cálculo monetario, sin variantes, sin campos inertes de contrato.

Uma variante sóSingle variantUna sola variante

Um único DispatcherType, um único serviceName, sem prefixo Promo_ (hasPromotion: false fixo).A single DispatcherType, a single serviceName, no Promo_ prefix (hasPromotion: false fixed).Un único DispatcherType, un único serviceName, sin prefijo Promo_ (hasPromotion: false fijo).

RPC genéricoGeneric RPCRPC genérico

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

FontesSourcesFuentes BuildMerchandisingServiceOrderDispatcherPayloadUseCase + MerchandisingServiceOrderDispatcherPayloadInput + DispatcherType + DispatcherConectaRep.proto. O input carrega entities cruas de domínio (CLAUDE.md §36); o build() renomeia, compõe a mensagem, achata as fotos e limpa o CNPJ. BuildMerchandisingServiceOrderDispatcherPayloadUseCase + MerchandisingServiceOrderDispatcherPayloadInput + DispatcherType + DispatcherConectaRep.proto. The input carries raw domain entities (CLAUDE.md §36); build() renames, composes the message, flattens the photos and cleans the CNPJ. BuildMerchandisingServiceOrderDispatcherPayloadUseCase + MerchandisingServiceOrderDispatcherPayloadInput + DispatcherType + DispatcherConectaRep.proto. El input lleva entities crudas de dominio (CLAUDE.md §36); el build() renombra, compone el mensaje, aplana las fotos y limpia el CNPJ.

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. Aqui o serviceName é BPOneServiceOrderUpsert.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. Here the serviceName is BPOneServiceOrderUpsert.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. Aquí el serviceName es BPOneServiceOrderUpsert.

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 · discriminadorBPOneServiceOrderUpsert (sem prefixo Promo_)discriminatorBPOneServiceOrderUpsert (no Promo_ prefix)discriminadorBPOneServiceOrderUpsert (sin prefijo Promo_)
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 · vazio (envelope não preenche)empty (envelope leaves it blank)vacío (el envelope no lo completa)
username
string · #5
message
string · #6 · o payload JSON serializado (a tabela da seção 07)the JSON payload serialized (the table in section 07)el payload JSON serializado (la tabla de la sección 07)
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, dateReference). Aqui transactionReference e tid ficam no default do envelope. O account (DispatchAccountEntity: sfid, sapCode = customerCode, name) serve ao tracking, não ao payload. O DispatcherGateway serializa payload em JSON para message, copia serviceName/dateReference, preenche os campos de dispositivo e o bearer token de auth, e chama o RPC. The builder returns a DispatcherEnvelope (type, serviceName, payload, account, dateReference). Here transactionReference and tid keep the envelope default. The account (DispatchAccountEntity: sfid, sapCode = customerCode, name) feeds tracking, not the payload. The DispatcherGateway serializes payload to JSON into message, copies serviceName/dateReference, fills in the device fields and the auth bearer token, and calls the RPC. El builder devuelve un DispatcherEnvelope (type, serviceName, payload, account, dateReference). Aquí transactionReference y tid quedan en el default del envelope. El account (DispatchAccountEntity: sfid, sapCode = customerCode, name) alimenta el tracking, no el payload. El DispatcherGateway serializa payload a JSON en message, copia serviceName/dateReference, completa los campos del dispositivo y el bearer token de auth, y llama al RPC.

destination = none (sem roteamento externo específico) e resendMayDuplicate == true (não está no conjunto lightweight): um reenvio a partir do histórico de despachos não confirmados pode duplicar a ordem; a idempotência via tid é o que mitiga isso. Offline, o DispatcherOrchestrator só pré-enfileira (_recordPending) o tipo visit; para merchandisingServiceOrder um envio sem conexão retorna Error(NetworkFailure) na hora, sem fila local (ver Pendências).destination = none (no specific external routing) and resendMayDuplicate == true (not in the lightweight set): a resend from the unsent-dispatch history may duplicate the order; idempotency via tid is what mitigates it. Offline, the DispatcherOrchestrator only pre-queues (_recordPending) the visit type; for merchandisingServiceOrder an offline send returns Error(NetworkFailure) immediately, with no local queue (see Pending).destination = none (sin ruteo externo específico) y resendMayDuplicate == true (no está en el conjunto lightweight): un reenvío desde el historial de despachos no confirmados puede duplicar la orden; la idempotencia vía tid es lo que lo mitiga. Offline, el DispatcherOrchestrator solo pre-encola (_recordPending) el tipo visit; para merchandisingServiceOrder un envío sin conexión devuelve Error(NetworkFailure) al instante, sin cola local (ver Pendientes).

06

Como é disparadoHow it's firedCómo se dispara

A transação é orquestrada pelo notifier da ordem de serviço de merchandising. O notifier apenas reúne entities cruas (representante de vendas, varejo, atividade/serviço/motivo, peças) e valores injetados (relógio, fotos em base64); o builder é o dono único do rename, da composição da mensagem, do achatamento das fotos e da limpeza do CNPJ. A cascata:The transaction is orchestrated by the merchandising service-order notifier. The notifier only gathers raw entities (sales rep, retail, activity/service/reason, pieces) and injected values (clock, base64 photos); the builder is the sole owner of the rename, message composition, photo flattening and CNPJ cleaning. The cascade:La transacción se orquesta desde el notifier de la orden de servicio de merchandising. El notifier solo reúne entities crudas (representante de ventas, punto de venta, actividad/servicio/motivo, piezas) y valores inyectados (reloj, fotos en base64); el builder es el dueño único del rename, la composición del mensaje, el aplanamiento de las fotos y la limpieza del CNPJ. La cascada:

  • MerchandisingServiceOrderNotifiersubmitServiceOrder()
    • reúne entities cruas + injetadosgathers raw entities + injectedreúne entities crudas + inyectadosMerchandisingServiceOrderDispatcherPayloadInput
      • build()BuildMerchandisingServiceOrderDispatcherPayloadUseCasemonta o wireassembles the wirearma el wire
        • devolvereturnsdevuelveDispatcherEnvelope
          • SubmitMerchandisingServiceOrderUseCaseDispatcherRepository
            • serializa + authserialize + authserializa + authDispatcherGateway
              • sendTransactionBackendgRPC

O notifier dispara dois envelopes em sequência pelo mesmo SubmitMerchandisingServiceOrderUseCase: primeiro o creationEnvelope da Criação de merchandising (best-effort, só loga em caso de falha) e, na sequência, este serviceOrderEnvelope, cujo resultado decide a conclusão. Só percorre este caminho quando usesWorkflowOutsideCrm; caso contrário o notifier dispara o rastreamento de ativos (Asset item tracking).The notifier fires two envelopes in sequence through the same SubmitMerchandisingServiceOrderUseCase: first the Merchandising creation's creationEnvelope (best-effort, only logs on failure) and, right after, this serviceOrderEnvelope, whose result decides completion. It only takes this path when usesWorkflowOutsideCrm; otherwise the notifier fires asset tracking (Asset item tracking).El notifier dispara dos envelopes en secuencia por el mismo SubmitMerchandisingServiceOrderUseCase: primero el creationEnvelope de la Creación de merchandising (best-effort, solo registra en caso de falla) y, enseguida, este serviceOrderEnvelope, cuyo resultado decide la conclusión. Solo recorre este camino cuando usesWorkflowOutsideCrm; de lo contrario el notifier dispara el rastreo de activos (Asset item tracking).

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

MerchandisingServiceOrderDispatcherPayloadInput (Freezed). Carrega o dado como existe no domínio; nada de formato wire. A atividade, o serviço e o motivo chegam como entities (o builder extrai o .code); as fotos como base64 lidas pelo FileCaptureService; o relógio como submittedAt (DateTimeUtils.now()).MerchandisingServiceOrderDispatcherPayloadInput (Freezed). Carries data as it exists in the domain; no wire shaping. The activity, service and reason arrive as entities (the builder extracts the .code); the photos as base64 read by FileCaptureService; the clock as submittedAt (DateTimeUtils.now()).MerchandisingServiceOrderDispatcherPayloadInput (Freezed). Lleva el dato como existe en el dominio; nada de formato wire. La actividad, el servicio y el motivo llegan como entities (el builder extrae el .code); las fotos como base64 leídas por FileCaptureService; el reloj como submittedAt (DateTimeUtils.now()).

CampoFieldCampoTipoTypeTipoPapelRoleRol
resourceResourceEntityrepresentante de vendas (cru — o builder usa resource.username na mensagem)sales rep (raw — the builder uses resource.username in the message)representante de ventas (crudo — el builder usa resource.username en el mensaje)
accountAccountDataEntityvarejo (customerCodeclientId, taxCodecnpj; sfid/name vão no envelope)retail (customerCodeclientId, taxCodecnpj; sfid/name go in the envelope)punto de venta (customerCodeclientId, taxCodecnpj; sfid/name van en el envelope)
visitSfidStringnão emitido por esta transação (ver Pendências)not emitted by this transaction (see Pending)no emitido por esta transacción (ver Pendientes)
activityMerchandisingActivityEntityactivityCode (activity.code)activityCode (activity.code)activityCode (activity.code)
serviceMerchandisingServiceEntity?serviceCode (service?.code ?? "")serviceCode (service?.code ?? "")serviceCode (service?.code ?? "")
reasonMerchandisingReason?reasonCode (reason?.code ?? "")reasonCode (reason?.code ?? "")reasonCode (reason?.code ?? "")
piecesList<MerchandisingServiceOrderPieceInput>parts + photos + message (via comentários)parts + photos + message (via comments)parts + photos + message (vía comentarios)
submittedAtDateTimedateReference do envelope (DateTimeUtils.now())→ envelope dateReference (DateTimeUtils.now())dateReference del envelope (DateTimeUtils.now())

Cada MerchandisingServiceOrderPieceInput carrega asset (MerchandisingAssetEntity), quantity (int), movement (MerchandisingMovement), comment (String) e imagesBase64 (List<String>). O input é compartilhado com a Criação de merchandising; a Ordem de serviço usa asset.pieceCode, quantity, movement.wireValue, comment (na mensagem) e imagesBase64 (em photos) — asset.type/asset.name são ignorados aqui (a Criação os usa).Each MerchandisingServiceOrderPieceInput carries asset (MerchandisingAssetEntity), quantity (int), movement (MerchandisingMovement), comment (String) and imagesBase64 (List<String>). The input is shared with Merchandising creation; the Service order uses only asset.pieceCode, quantity, movement.wireValue, comment (in the message) and imagesBase64 (in photos) — asset.type/asset.name are ignored here (Creation uses them).Cada MerchandisingServiceOrderPieceInput lleva asset (MerchandisingAssetEntity), quantity (int), movement (MerchandisingMovement), comment (String) e imagesBase64 (List<String>). El input es compartido con la Creación de merchandising; la Orden de servicio usa solo asset.pieceCode, quantity, movement.wireValue, comment (en el mensaje) e imagesBase64 (en photos) — asset.type/asset.name se ignoran aquí (la Creación los usa).

07

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 (13 no total: 10 na raiz + 3 por peça em parts). Campo, Tipo e Origem são código cru; só a Regra é prosa. Um exemplo completo 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 (13 total: 10 at the root + 3 per piece in parts). Field, Type and Source are raw code; only Rule is prose. A full example 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 (13 en total: 10 en la raíz + 3 por pieza en parts). Campo, Tipo y Origen son código crudo; solo la Regla es prosa. Un ejemplo completo está en transaction_example.json, junto a este doc.

Raiz do payloadPayload rootRaíz del payload

Campo JSONTipoTypeTipoOrigem do DadoData sourceOrigen del DatoRegraRuleRegla
cycleintFixo: 7constante _cycle — ciclo do contrato_cycle constant — contract cycleconstante _cycle — ciclo del contrato
clientIdstringinput.account.customerCodecódigo SAP do varejoretail SAP codecódigo SAP del punto de venta
orderTypeCodestringFixo: "3"constante _orderTypeCode — tipo de ordem_orderTypeCode constant — order typeconstante _orderTypeCode — tipo de orden
messagestring_composeMessagecomentários das peças + " - " + oneId; máx. 255 (ver Regras)piece comments + " - " + oneId; max 255 (see Rules)comentarios de las piezas + " - " + oneId; máx. 255 (ver Reglas)
activityCodestringinput.activity.codecódigo da atividade selecionadaselected activity codecódigo de la actividad seleccionada
serviceCodestringinput.service?.code ?? ""código do serviço; "" se nenhum selecionadoservice code; "" if none selectedcódigo del servicio; "" si ninguno seleccionado
reasonCodestringinput.reason?.code ?? ""código do motivo; "" se nenhum selecionadoreason code; "" if none selectedcódigo del motivo; "" si ninguno seleccionado
partsarrayinput.piecesuma entrada por peça (ver tabela abaixo)one entry per piece (see table below)una entrada por pieza (ver tabla abajo)
photosarrayinput.pieces[*].imagesBase64lista plana — concatena as fotos base64 de todas as peças (não por peça)flat list — concatenates the base64 photos of all pieces (not per piece)lista plana — concatena las fotos base64 de todas las piezas (no por pieza)
cnpjstring_digitsOnly(input.account.taxCode ?? "")CNPJ do varejo, só dígitos (remove tudo que não é dígito)retail CNPJ, digits only (strips every non-digit)CNPJ del punto de venta, solo dígitos (quita todo lo que no es dígito)
  • parts por peçaper piecepor pieza 3 camposfieldscampos

    Uma entrada por MerchandisingServiceOrderPieceInput em input.pieces. Toda peça vira uma entrada — não há filtro por quantidade, movimento ou peça vazia. As fotos não ficam aqui: são achatadas na chave photos da raiz.One entry per MerchandisingServiceOrderPieceInput in input.pieces. Every piece becomes an entry — no filter by quantity, movement or empty piece. The photos are not here: they're flattened into the root photos key.Una entrada por MerchandisingServiceOrderPieceInput en input.pieces. Toda pieza se vuelve una entrada — no hay filtro por cantidad, movimiento o pieza vacía. Las fotos no están aquí: se aplanan en la clave photos de la raíz.

    Campo JSONTipoTypeTipoOrigem do DadoData sourceOrigen del DatoRegraRuleRegla
    partNumberstringpiece.asset.pieceCode ?? ""código da peça do ativo; "" se ausenteasset piece code; "" if absentcódigo de la pieza del activo; "" si ausente
    quantityintpiece.quantityquantidade da peça (cru, sem validação)piece quantity (raw, no validation)cantidad de la pieza (crudo, sin validación)
    movementstringpiece.movement.wireValue"" none · "M" maintenance · "R" remove · "I" install"" none · "M" maintenance · "R" remove · "I" install"" none · "M" maintenance · "R" remove · "I" install
08

Regras de negócioBusiness rulesReglas de negocio

Quando é disparadaWhen it firesCuándo se dispara usesWorkflowOutsideCrm · 2º envelope

submitServiceOrder() só dispara esta transação quando usesWorkflowOutsideCrm == true, como segundo dos dois envelopes:submitServiceOrder() only fires this transaction when usesWorkflowOutsideCrm == true, as the second of the two envelopes:submitServiceOrder() solo dispara esta transacción cuando usesWorkflowOutsideCrm == true, como segundo de los dos envelopes:

  • usesWorkflowOutsideCrm == true → dispara a Criação de merchandising (1º, best-effort) e, na sequência, esta Ordem de serviço (2º) — cujo resultado decide a conclusão.usesWorkflowOutsideCrm == true → fires Merchandising creation (1st, best-effort) and, right after, this Service order (2nd) — whose result decides completion.usesWorkflowOutsideCrm == true → dispara la Creación de merchandising (1º, best-effort) y, enseguida, esta Orden de servicio (2º) — cuyo resultado decide la conclusión.
  • false → dispara o rastreamento de ativos (Asset item tracking); a Ordem de serviço não é enviada.false → fires asset tracking (Asset item tracking); the Service order is not sent.false → dispara el rastreo de activos (Asset item tracking); la Orden de servicio no se envía.
Composição da mensagemMessage compositionComposición del mensaje _composeMessage · máx. 255
  • oneId: resource.username.split("@").first — a parte do username antes do @.oneId: resource.username.split("@").first — the part of the username before the @.oneId: resource.username.split("@").first — la parte del username antes del @.
  • body: os comment de cada peça, com trim() e descartando vazios, unidos por quebra de linha (\n).body: each piece's comment, trim()ed and dropping empties, joined by newline (\n).body: los comment de cada pieza, con trim() y descartando vacíos, unidos por salto de línea (\n).
  • Se body vazio → message = oneId. Senão → "{body} - {oneId}", com o body aparado para caber em _maxMessageLength = 255 (inclui o sufixo " - {oneId}").If body is empty → message = oneId. Else → "{body} - {oneId}", with body trimmed to fit _maxMessageLength = 255 (including the " - {oneId}" suffix).Si body está vacío → message = oneId. Si no → "{body} - {oneId}", con el body recortado para caber en _maxMessageLength = 255 (incluye el sufijo " - {oneId}").
Fotos em lista planaPhotos in a flat listFotos en lista plana photos · addAll

Diferente da Criação de merchandising (que mapeia até 3 fotos por peça em imageBase1..3), a Ordem de serviço achata todas as fotos: percorre as peças e faz photos.addAll(piece.imagesBase64), produzindo uma única lista na raiz. Não há limite de 3 nem associação foto→peça — todas as fotos de todas as peças entram em photos, na ordem das peças.Unlike Merchandising creation (which maps up to 3 photos per piece into imageBase1..3), the Service order flattens all photos: it walks the pieces and does photos.addAll(piece.imagesBase64), producing a single list at the root. There's no 3-cap and no photo→piece association — every photo of every piece goes into photos, in piece order.A diferencia de la Creación de merchandising (que mapea hasta 3 fotos por pieza en imageBase1..3), la Orden de servicio aplana todas las fotos: recorre las piezas y hace photos.addAll(piece.imagesBase64), produciendo una única lista en la raíz. No hay límite de 3 ni asociación foto→pieza — todas las fotos de todas las piezas entran en photos, en orden de piezas.

Códigos, não rótulosCodes, not labelsCódigos, no etiquetas activityCode · serviceCode · reasonCode

Diferente da Criação de merchandising (que envia os rótulos legíveis .label), a Ordem de serviço envia os códigos (.code) da atividade, do serviço e do motivo — é um comando estruturado, não um registro descritivo. service e reason são opcionais no input; ausentes viram "".Unlike Merchandising creation (which sends the human-readable .label), the Service order sends the codes (.code) of the activity, service and reason — it's a structured command, not a descriptive record. service and reason are optional on the input; absent ones become "".A diferencia de la Creación de merchandising (que envía las etiquetas legibles .label), la Orden de servicio envía los códigos (.code) de la actividad, el servicio y el motivo — es un comando estructurado, no un registro descriptivo. service y reason son opcionales en el input; los ausentes se vuelven "".

CNPJ só dígitosCNPJ digits onlyCNPJ solo dígitos _digitsOnly

cnpj = _digitsOnly(input.account.taxCode ?? ""): aplica replaceAll(RegExp(r"\D"), ""), removendo pontos, barras e hifens da máscara do CNPJ. taxCode nulo/vazio → "".cnpj = _digitsOnly(input.account.taxCode ?? ""): applies replaceAll(RegExp(r"\D"), ""), stripping the dots, slashes and hyphens of the CNPJ mask. Null/empty taxCode"".cnpj = _digitsOnly(input.account.taxCode ?? ""): aplica replaceAll(RegExp(r"\D"), ""), quitando los puntos, barras y guiones de la máscara del CNPJ. taxCode nulo/vacío → "".

Constantes do contratoContract constantsConstantes del contrato cycle · orderTypeCode
  • cycle = _cycle = 7 (constante fixa do builder).cycle = _cycle = 7 (fixed builder constant).cycle = _cycle = 7 (constante fija del builder).
  • orderTypeCode = _orderTypeCode = "3" (constante fixa do builder).orderTypeCode = _orderTypeCode = "3" (fixed builder constant).orderTypeCode = _orderTypeCode = "3" (constante fija del builder).
  • Nenhum arredondamento, nenhum campo inerte de contrato — o build() é uma projeção direta com composição de mensagem, achatamento de fotos e limpeza de CNPJ.No rounding, no inert contract field — build() is a direct projection with message composition, photo flattening and CNPJ cleaning.Sin redondeo, sin campo inerte de contrato — el build() es una proyección directa con composición de mensaje, aplanamiento de fotos y limpieza de CNPJ.
09

Pendências / roadmapPending / roadmapPendientes / roadmap

O que o builder ainda não aproveita ou onde o contrato limita, documentado fiel ao estado atual do código (nunca descrito como se já existisse):What the builder does not yet leverage, or where the contract limits, documented faithfully to the current code state (never described as already existing):Lo que el builder aún no aprovecha, o dónde el contrato limita, documentado fiel al estado actual del código (nunca descrito como si ya existiera):

Não aproveitado / limitadoNot leveraged / limitedNo aprovechado / limitado

  • input.visitSfid: presente no input mas não emitido no payload — o build() não gera nenhuma chave de visita. Fica disponível caso o contrato passe a exigir a visita.input.visitSfid: present on the input but not emitted in the payload — build() generates no visit key. It stays available in case the contract starts requiring the visit.input.visitSfid: presente en el input pero no emitido en el payload — el build() no genera ninguna clave de visita. Queda disponible por si el contrato pasa a exigir la visita.
  • Fotos sem associação à peça: photos é uma lista plana única; a informação de qual peça gerou cada foto se perde no achatamento (o contrato não tem foto por peça aqui).Photos without piece association: photos is a single flat list; the info of which piece produced each photo is lost in the flattening (the contract has no per-piece photo here).Fotos sin asociación a la pieza: photos es una única lista plana; la información de qué pieza generó cada foto se pierde en el aplanamiento (el contrato no tiene foto por pieza aquí).
  • quantity vai cru, sem validação: uma peça com quantity <= 0 é enviada como está (não há filtro por quantidade nem por peça vazia).quantity ships raw, without validation: a piece with quantity <= 0 is sent as-is (no filter by quantity or empty piece).quantity va crudo, sin validación: una pieza con quantity <= 0 se envía tal cual (no hay filtro por cantidad ni por pieza vacía).
  • message aparado por bytes/caracteres em 255 via substring: um corte pode cair no meio de uma palavra (ou de um caractere multibyte) — o contrato não prevê corte por palavra.message trimmed by chars to 255 via substring: a cut can land mid-word (or mid multi-byte char) — the contract has no word-boundary trim.message recortado por caracteres a 255 vía substring: un corte puede caer a mitad de palabra (o de un carácter multibyte) — el contrato no prevé corte por palabra.
  • Offline sem fila local: só o tipo visit é pré-enfileirado pelo DispatcherOrchestrator (_recordPending). Sem conexão, esta transação retorna Error(NetworkFailure) na hora — não há enfileiramento automático para reenvio posterior deste caminho.No offline local queue: only the visit type is pre-queued by the DispatcherOrchestrator (_recordPending). Offline, this transaction returns Error(NetworkFailure) right away — there's no automatic queueing for later resend on this path.Sin cola local offline: solo el tipo visit es pre-encolado por el DispatcherOrchestrator (_recordPending). Sin conexión, esta transacción devuelve Error(NetworkFailure) al instante — no hay encolamiento automático para reenvío posterior en este camino.
  • 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).

Transações irmãsSister transactionsTransacciones hermanas Domínio de merchandising (BR): 14 · Criação de merchandising (par desta, compartilha o input de peças), 16 · Asset item tracking (caminho alternativo), 13 · Image recognition e 17 · Annotation. Merchandising domain (BR): 14 · Merchandising creation (this one's pair, shares the piece input), 16 · Asset item tracking (alternate path), 13 · Image recognition and 17 · Annotation. Dominio de merchandising (BR): 14 · Creación de merchandising (par de esta, comparte el input de piezas), 16 · Asset item tracking (camino alternativo), 13 · Image recognition y 17 · Annotation.

MercadosMarketsMercados

A disponibilidade da transação vem do DispatcherType.merchandisingServiceOrder.enabledMarkets = [BR]. É uma transação só do Brasil; os demais mercados não a listam e não a disparam.Transaction availability comes from DispatcherType.merchandisingServiceOrder.enabledMarkets = [BR]. It's a Brazil-only transaction; the other markets don't list it and don't fire it.La disponibilidad de la transacción viene de DispatcherType.merchandisingServiceOrder.enabledMarkets = [BR]. Es una transacción solo de Brasil; los demás mercados no la listan y no la disparan.

BRx CL ZA AR PY PE
disponívelavailabledisponible presente, desligadopresent, offpresente, apagado ausenteabsentausente
BR

Só no BrasilBrazil onlySolo Brasil Toda a ordem de serviço de merchandising com fluxo fora do CRM (usesWorkflowOutsideCrm) é um cenário exclusivo do Brasil. O cnpj é o identificador fiscal brasileiro do varejo, e o destination é none (sem roteamento externo específico) — mesmo padrão das outras transações de merchandising BR. The whole merchandising service order with an outside-CRM flow (usesWorkflowOutsideCrm) is a Brazil-exclusive scenario. The cnpj is the retail's Brazilian tax id, and the destination is none (no specific external routing) — same pattern as the other BR merchandising transactions. Toda la orden de servicio de merchandising con flujo fuera del CRM (usesWorkflowOutsideCrm) es un escenario exclusivo de Brasil. El cnpj es el identificador fiscal brasileño del punto de venta, y el destination es none (sin ruteo externo específico) — mismo patrón de las otras transacciones de merchandising BR.

CL · ZA · AR · PY · PE Existem como mercados do app, mas não têm a transação de Ordem de serviço de merchandising — enabledMarkets lista apenas BR. Nesses mercados a ordem de serviço de merchandising com fluxo fora do CRM não é disparada. They exist as app markets, but don't have the Merchandising service order transaction — enabledMarkets lists only BR. In these markets the outside-CRM merchandising service order is not fired. Existen como mercados de la app, pero no tienen la transacción de Orden de servicio de merchandising — enabledMarkets lista solo BR. En estos mercados la orden de servicio de merchandising con flujo fuera del CRM no se dispara.