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.
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.
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:
- 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.
- 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.
- 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.
- 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.
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 instante — no 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.
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.
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.
sendTransactionunaryrpc sendTransaction(InboxTransactionRequest) returns (InboxTransactionReply)
path /mn.bat.conectarep.dispatcher.DispatcherConectaRepService/sendTransaction
InboxTransactionRequestendpointstring· #1 · endpoint alvo (config de ambiente)target endpoint (environment config)endpoint destino (config de ambiente)serviceNamestring· #2 · discriminador —BPOneServiceOrderUpsert(sem prefixoPromo_)discriminator —BPOneServiceOrderUpsert(noPromo_prefix)discriminador —BPOneServiceOrderUpsert(sin prefijoPromo_)dateReferencestring· #3 ·AAAA-MM-DDdo envio (formatDate(submittedAt))YYYY-MM-DDof the submission (formatDate(submittedAt))AAAA-MM-DDdel envío (formatDate(submittedAt))transactionReferencestring· #4 · vazio (envelope não preenche)empty (envelope leaves it blank)vacío (el envelope no lo completa)usernamestring· #5messagestring· #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)manufacturerstring· #7 · dado do dispositivodevice datadato del dispositivomodelstring· #8 · dado do dispositivodevice datadato del dispositivodeviceUuidstring· #9 · literal provisório hoje (ver Pendências)provisional literal today (see Pending)literal provisional hoy (ver Pendientes)deviceVersionstring· #10tidint64· #11 · id de transação para idempotência/replaytransaction id for idempotency/replayid de transacción para idempotencia/replay
InboxTransactionReplystatusint32· #1 · status do ack (0 = sucesso)ack status (0 = success)status del ack (0 = éxito)messagestring· #2 · mensagem do backendbackend messagemensaje del backendtransactionIdint32· #3 · id atribuído pelo backend (correlação)backend-assigned id (correlation)id asignado por el backend (correlación)
Envelope → Request
O builder devolve um DispatcherEnvelope (type, serviceName, payload, account, 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).
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
- serializa + authserialize + authserializa + authDispatcherGateway
- SubmitMerchandisingServiceOrderUseCaseDispatcherRepository
- devolvereturnsdevuelveDispatcherEnvelope
- build()BuildMerchandisingServiceOrderDispatcherPayloadUseCasemonta o wireassembles the wirearma el wire
- reúne entities cruas + injetadosgathers raw entities + injectedreúne entities crudas + inyectadosMerchandisingServiceOrderDispatcherPayloadInput
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()).
| CampoFieldCampo | TipoTypeTipo | PapelRoleRol |
|---|---|---|
resource | ResourceEntity | representante 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) |
account | AccountDataEntity | varejo (customerCode → clientId, taxCode → cnpj; sfid/name vão no envelope)retail (customerCode → clientId, taxCode → cnpj; sfid/name go in the envelope)punto de venta (customerCode → clientId, taxCode → cnpj; sfid/name van en el envelope) |
visitSfid | String | não emitido por esta transação (ver Pendências)not emitted by this transaction (see Pending)no emitido por esta transacción (ver Pendientes) |
activity | MerchandisingActivityEntity | → activityCode (activity.code)→ activityCode (activity.code)→ activityCode (activity.code) |
service | MerchandisingServiceEntity? | → serviceCode (service?.code ?? "")→ serviceCode (service?.code ?? "")→ serviceCode (service?.code ?? "") |
reason | MerchandisingReason? | → reasonCode (reason?.code ?? "")→ reasonCode (reason?.code ?? "")→ reasonCode (reason?.code ?? "") |
pieces | List<MerchandisingServiceOrderPieceInput> | → parts + photos + message (via comentários)→ parts + photos + message (via comments)→ parts + photos + message (vía comentarios) |
submittedAt | DateTime | → dateReference 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 só 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).
Payload (message)
O JSON serializado no campo message do request. Cada tabela abaixo tem 4 colunas — Campo JSON · Tipo · Origem do Dado · Regra — e lista toda chave que o build() emite (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 columns — JSON 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 columnas — Campo 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 JSON | TipoTypeTipo | Origem do DadoData sourceOrigen del Dato | RegraRuleRegla |
|---|---|---|---|
cycle | int | Fixo: 7 | constante _cycle — ciclo do contrato_cycle constant — contract cycleconstante _cycle — ciclo del contrato |
clientId | string | input.account.customerCode | código SAP do varejoretail SAP codecódigo SAP del punto de venta |
orderTypeCode | string | Fixo: "3" | constante _orderTypeCode — tipo de ordem_orderTypeCode constant — order typeconstante _orderTypeCode — tipo de orden |
message | string | _composeMessage | comentá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) |
activityCode | string | input.activity.code | código da atividade selecionadaselected activity codecódigo de la actividad seleccionada |
serviceCode | string | input.service?.code ?? "" | código do serviço; "" se nenhum selecionadoservice code; "" if none selectedcódigo del servicio; "" si ninguno seleccionado |
reasonCode | string | input.reason?.code ?? "" | código do motivo; "" se nenhum selecionadoreason code; "" if none selectedcódigo del motivo; "" si ninguno seleccionado |
parts | array | input.pieces | uma entrada por peça (ver tabela abaixo)one entry per piece (see table below)una entrada por pieza (ver tabla abajo) |
photos | array | input.pieces[*].imagesBase64 | lista 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) |
cnpj | string | _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
MerchandisingServiceOrderPieceInputeminput.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 chavephotosda raiz.One entry perMerchandisingServiceOrderPieceInputininput.pieces. Every piece becomes an entry — no filter by quantity, movement or empty piece. The photos are not here: they're flattened into the rootphotoskey.Una entrada porMerchandisingServiceOrderPieceInputeninput.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 clavephotosde la raíz.Campo JSON TipoTypeTipo Origem do DadoData sourceOrigen del Dato RegraRuleRegla partNumberstring piece.asset.pieceCode ?? ""código da peça do ativo; ""se ausenteasset piece code;""if absentcódigo de la pieza del activo;""si ausentequantityint piece.quantityquantidade da peça (cru, sem validação)piece quantity (raw, no validation)cantidad de la pieza (crudo, sin validación) movementstring piece.movement.wireValue""none ·"M"maintenance ·"R"remove ·"I"install""none ·"M"maintenance ·"R"remove ·"I"install""none ·"M"maintenance ·"R"remove ·"I"install
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
commentde cada peça, comtrim()e descartando vazios, unidos por quebra de linha (\n).body: each piece'scomment,trim()ed and dropping empties, joined by newline (\n).body: loscommentde cada pieza, contrim()y descartando vacíos, unidos por salto de línea (\n). - Se
bodyvazio →message=oneId. Senão →"{body} - {oneId}", com obodyaparado para caber em_maxMessageLength = 255(inclui o sufixo" - {oneId}").Ifbodyis empty →message=oneId. Else →"{body} - {oneId}", withbodytrimmed to fit_maxMessageLength = 255(including the" - {oneId}"suffix).Sibodyestá vacío →message=oneId. Si no →"{body} - {oneId}", con elbodyrecortado 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 — elbuild()es una proyección directa con composición de mensaje, aplanamiento de fotos y limpieza de CNPJ.
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 — obuild()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 — elbuild()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:photosis 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:photoses 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í). quantityvai cru, sem validação: uma peça comquantity <= 0é enviada como está (não há filtro por quantidade nem por peça vazia).quantityships raw, without validation: a piece withquantity <= 0is sent as-is (no filter by quantity or empty piece).quantityva crudo, sin validación: una pieza conquantity <= 0se envía tal cual (no hay filtro por cantidad ni por pieza vacía).messageaparado por bytes/caracteres em 255 viasubstring: um corte pode cair no meio de uma palavra (ou de um caractere multibyte) — o contrato não prevê corte por palavra.messagetrimmed by chars to 255 viasubstring: a cut can land mid-word (or mid multi-byte char) — the contract has no word-boundary trim.messagerecortado por caracteres a 255 víasubstring: 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 peloDispatcherOrchestrator(_recordPending). Sem conexão, esta transação retornaError(NetworkFailure)na hora — não há enfileiramento automático para reenvio posterior deste caminho.No offline local queue: only thevisittype is pre-queued by theDispatcherOrchestrator(_recordPending). Offline, this transaction returnsError(NetworkFailure)right away — there's no automatic queueing for later resend on this path.Sin cola local offline: solo el tipovisites pre-encolado por elDispatcherOrchestrator(_recordPending). Sin conexión, esta transacción devuelveError(NetworkFailure)al instante — no hay encolamiento automático para reenvío posterior en este camino. - Transporte:
deviceUuidvai como literal provisório no gateway (pendência conhecida do Dispatcher).Transport:deviceUuidships as a provisional literal in the gateway (known Dispatcher pending item).Transporte:deviceUuidva como literal provisional en el gateway (pendiente conocido del Dispatcher).
Transaçõ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.
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.