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).
Feature · Visita AdhocFeature · Adhoc VisitFeature · Visita Adhoc

Visita AdhocAdhoc VisitVisita Adhoc

Cria uma visita não planejada a um varejo, na hora, direto da Lista de varejos. Uma única chamada gRPC (getAdhocVisit) traz de volta tudo o que aquela visita precisa — visita, call tasks, pedidos, estoque, financeiro, pesquisas, promoções, merchandising, calculadora de margem e catálogo — e o app funde aditivamente esse reply em 11 caches locais. Feature online (sem mock), remote-first, sem tela própria: é um botão no card do varejo + um modal de confirmação. Creates an unplanned visit to a retail, on the spot, straight from the Retails list. A single gRPC call (getAdhocVisit) brings back everything that visit needs — visit, call tasks, orders, stock, financials, surveys, promotions, merchandising, margin calculator and catalog — and the app additively merges that reply into 11 local caches. An online feature (no mock), remote-first, with no screen of its own: a button on the retail card + a confirmation modal. Crea una visita no planificada a un punto de venta, al instante, directo desde la Lista de puntos de venta. Una única llamada gRPC (getAdhocVisit) trae de vuelta todo lo que esa visita necesita — visita, call tasks, pedidos, stock, financiero, encuestas, promociones, merchandising, calculadora de margen y catálogo — y la app fusiona aditivamente ese reply en 11 cachés locales. Feature online (sin mock), remote-first, sin pantalla propia: es un botón en la tarjeta del punto de venta + un modal de confirmación.

PúblicoAudiencePúblico
Representante · QA · Suporte · DevRep · QA · Support · DevRepresentante · QA · Soporte · Dev
Onde ficaWhereDónde
Lista de varejos → card do varejo → botão ADHOCRetails list → retail card → ADHOC buttonLista de puntos de venta → tarjeta → botón ADHOC
RelacionadoRelatedRelacionado
AtualizadoUpdatedActualizado
12/08/20262026-08-12
Disponível emAvailable inDisponible en BR CL ZA
01

O que é e para que serveWhat it is and what it's forQué es y para qué sirve

Nem toda visita está no roteiro. Quando o representante de vendas passa por um varejo que não estava planejado para o dia, a Visita Adhoc cria essa visita na hora: o app pede ao backend uma "fotografia" completa daquele varejo e a incorpora ao que já está no aparelho, para que o representante possa trabalhar a visita normalmente — abrir pedidos, checar estoque, responder call tasks, ver o financeiro etc. Not every visit is on the route. When the sales rep passes by a retail that wasn't planned for the day, the Adhoc Visit creates that visit on the spot: the app asks the backend for a full "snapshot" of that retail and merges it into whatever is already on the device, so the rep can work the visit normally — place orders, check stock, answer call tasks, see financials, etc. No toda visita está en la ruta. Cuando el representante de ventas pasa por un punto de venta que no estaba planificado para el día, la Visita Adhoc crea esa visita al instante: la app le pide al backend una "fotografía" completa de ese punto de venta y la incorpora a lo que ya está en el dispositivo, para que el representante trabaje la visita con normalidad — abrir pedidos, revisar stock, responder call tasks, ver el financiero, etc.

Na horaOn the spotAl instante

Um toque no botão ADHOC do card do varejo cria a visita — sem sair da Lista de varejos.One tap on the retail card's ADHOC button creates the visit — without leaving the Retails list.Un toque en el botón ADHOC de la tarjeta crea la visita — sin salir de la Lista de puntos de venta.

Traz tudoBrings everythingTrae todo

Uma só chamada devolve visita, pedidos, estoque, call tasks, financeiro, pesquisas, promoções, merchandising, margem e catálogo.A single call returns visit, orders, stock, call tasks, financials, surveys, promotions, merchandising, margin and catalog.Una sola llamada devuelve visita, pedidos, stock, call tasks, financiero, encuestas, promociones, merchandising, margen y catálogo.

Não apaga nadaErases nothingNo borra nada

O reply é fundido aditivamente: substitui só os dados daquele varejo/visita e preserva o resto do cache.The reply merges additively: it replaces only that retail/visit's data and keeps the rest of the cache.El reply se fusiona aditivamente: reemplaza solo los datos de ese punto/visita y conserva el resto del caché.

Adhoc ≠ Visita planejadaAdhoc ≠ Planned visitAdhoc ≠ Visita planificada A visita planejada já vem no roteiro sincronizado. A adhoc é criada em runtime para um varejo que não estava no roteiro — o VisitType.adhoc marca essas visitas. O botão só aparece nos varejos elegíveis (isAdhocVisitCreationAvailable). The planned visit already comes in the synced route. The adhoc one is created at runtime for a retail that wasn't on the route — VisitType.adhoc tags those visits. The button only shows on eligible retails (isAdhocVisitCreationAvailable). La visita planificada ya viene en la ruta sincronizada. La adhoc se crea en runtime para un punto de venta que no estaba en la ruta — VisitType.adhoc etiqueta esas visitas. El botón solo aparece en los puntos elegibles (isAdhocVisitCreationAvailable).

02

Como acessarHow to openCómo acceder

  1. Abra a Lista de varejosOpen the Retails listAbra la Lista de puntos de ventaNo menu lateral, entre em Varejos e ache o varejo desejado.From the drawer, open Retails and find the target retail.Desde el menú lateral, abra Puntos de venta y busque el punto deseado.
  2. Toque em ADHOCTap ADHOCToque ADHOCO botão ADHOC aparece no card do varejo somente quando ele é elegível. Toque para começar.The ADHOC button shows on the retail card only when it's eligible. Tap it to start.El botón ADHOC aparece en la tarjeta solo cuando es elegible. Tóquelo para empezar.
  3. Confirme no modalConfirm in the modalConfirme en el modalUm modal pede confirmação (nome do varejo). Ao confirmar, o app cria a visita e mostra um aviso verde de sucesso.A modal asks for confirmation (retail name). On confirm, the app creates the visit and shows a green success notice.Un modal pide confirmación (nombre del punto). Al confirmar, la app crea la visita y muestra un aviso verde de éxito.
03

Estrutura do fluxoFlow structureEstructura del flujo

A Visita Adhoc não tem tela própria. Ela é um botão + um modal na Lista de varejos, e o resultado alimenta as outras telas (Visitas, Detalhe da visita, Pedidos…). Três superfícies visíveis:The Adhoc Visit has no screen of its own. It's a button + a modal in the Retails list, and its result feeds the other screens (Visits, Visit detail, Orders…). Three visible surfaces:La Visita Adhoc no tiene pantalla propia. Es un botón + un modal en la Lista de puntos de venta, y su resultado alimenta las otras pantallas (Visitas, Detalle de la visita, Pedidos…). Tres superficies visibles:

Botão ADHOCADHOC buttonBotón ADHOC
Um badge/botão no card do varejo, visível só quando isAdhocVisitCreationAvailable. Enquanto cria, mostra estado de carregamento.A badge/button on the retail card, visible only when isAdhocVisitCreationAvailable. While creating, it shows a loading state.Un badge/botón en la tarjeta, visible solo cuando isAdhocVisitCreationAvailable. Mientras crea, muestra estado de carga.
Modal de confirmaçãoConfirmation modalModal de confirmación
Título "criar visita adhoc" com o nome do varejo, botão de confirmar e de cancelar."Create adhoc visit" title with the retail name, a confirm and a cancel button.Título "crear visita adhoc" con el nombre del punto, botón de confirmar y de cancelar.
Aviso de resultadoResult noticeAviso de resultado
Sucesso: aviso verde com nome + SAP do varejo. Falha (ex.: reply sem visita): aviso vermelho.Success: green notice with the retail name + SAP. Failure (e.g. a reply with no visit): red notice.Éxito: aviso verde con nombre + SAP del punto. Falla (ej.: reply sin visita): aviso rojo.
04

StatusStatusEstado

O fluxo tem quatro fases (AdhocVisitCreationPhase), por varejo:The flow has four phases (AdhocVisitCreationPhase), per retail:El flujo tiene cuatro fases (AdhocVisitCreationPhase), por punto de venta:

idle · nada em andamentoidle · nothing in progressidle · nada en curso creating · criando (loading)creating · in progress (loading)creating · creando (loading) completed · visita criadacompleted · visit createdcompleted · visita creada failed · errofailed · errorfailed · error

Anti reentrânciaNo re-entrySin reentrada Enquanto a fase for creating, um novo toque é ignorado — não dispara uma segunda chamada para o mesmo varejo. Ao completar, o app invalida retailsProvider e visitsProvider para as listas se atualizarem. While the phase is creating, a new tap is ignored — it won't fire a second call for the same retail. On completion, the app invalidates retailsProvider and visitsProvider so the lists refresh. Mientras la fase sea creating, un nuevo toque se ignora — no dispara una segunda llamada para el mismo punto. Al completar, la app invalida retailsProvider y visitsProvider para que las listas se actualicen.

05

Ações: criar visita adhocActions: create adhoc visitAcciones: crear visita adhoc

CriarCreateCrear
Confirmar no modal dispara a criação: o app lê a posição (geolocalização, quando disponível) e chama o backend com o varejo escolhido.Confirming in the modal fires creation: the app reads the position (geolocation, when available) and calls the backend with the chosen retail.Confirmar en el modal dispara la creación: la app lee la posición (geolocalización, cuando esté disponible) y llama al backend con el punto elegido.
FeedbackFeedbackFeedback
Sucesso mostra um aviso verde interpolando nome e SAP do varejo; falha mostra um aviso vermelho.Success shows a green notice interpolating the retail name and SAP; failure shows a red notice.El éxito muestra un aviso verde interpolando nombre y SAP del punto; la falla muestra un aviso rojo.
DepoisAfterDespués
A visita passa a existir em Visitas e nas demais telas — como qualquer visita — a partir dos caches recém-fundidos.The visit then exists in Visits and the other screens — like any visit — from the freshly merged caches.La visita pasa a existir en Visitas y en las demás pantallas — como cualquier visita — a partir de los cachés recién fusionados.

Precisa de redeNeeds networkNecesita red A Visita Adhoc é online-only: não há mock nem fallback de cache. Sem conexão (ou se o reply vier sem nenhuma visita), a criação falha com aviso vermelho — nada é gravado. The Adhoc Visit is online-only: there's no mock and no cache fallback. With no connection (or if the reply comes back with no visit at all), creation fails with a red notice — nothing is written. La Visita Adhoc es online-only: no hay mock ni fallback de caché. Sin conexión (o si el reply vuelve sin ninguna visita), la creación falla con aviso rojo — no se graba nada.

06

Arquitetura e fluxo de dadosArchitecture & data flowArquitectura y flujo de datos

Clean Architecture + Riverpod + Freezed + gRPC + ObjectBox. Um único fluxo remote-first de escrita-e-leitura: o botão dispara o provider, que chama o UseCase → Repository → RPC remoto getAdhocVisit. O reply vira AdhocVisitResultEntity (achatado) e o merge coordinator funde suas 15 listas em 11 datasources locais. Não há Local datasource nem Model próprios do agregado — ele é transiente e se dissolve nos caches de cada feature.Clean Architecture + Riverpod + Freezed + gRPC + ObjectBox. A single remote-first read-and-write flow: the button fires the provider, which calls the UseCase → Repository → remote RPC getAdhocVisit. The reply becomes an AdhocVisitResultEntity (flattened) and the merge coordinator merges its 15 lists into 11 local datasources. There is no Local datasource nor Model for the aggregate — it is transient and dissolves into each feature's caches.Clean Architecture + Riverpod + Freezed + gRPC + ObjectBox. Un único flujo remote-first de escritura-y-lectura: el botón dispara el provider, que llama al UseCase → Repository → RPC remoto getAdhocVisit. El reply se vuelve AdhocVisitResultEntity (aplanado) y el merge coordinator fusiona sus 15 listas en 11 datasources locales. No hay Local datasource ni Model propios del agregado — es transitorio y se disuelve en los cachés de cada feature.

  • RetailCardWidget · ADHOCUI
    • create(retailName, accountSapCustomerId)AdhocVisitCreationprovider · family(accountSfid)
      • execute(accountSfid, geo?)CreateAdhocVisitUseCase
        • createAdhocVisitAdhocVisitRepositoryImplremote-first · sem fallback
          • getAdhocVisit (gRPC)AdhocVisitRemoteDataSourceAdhocVisitReply → DTO
            • toDomainAdhocVisitResultEntity15 listas achatadas
              • merge(result, accountSfid)AdhocVisitMergeCoordinator→ 11 caches ObjectBox

Notas de implementaçãoImplementation notesNotas de implementación O provider é family por accountSfid e guarda contra reentrância na fase creating. O Repository resolve o ResourceEntity via currentResourceProvider — envia username e repSfid = resource.sfid (escrita identifica o representante, §25). Cada merge roda em ErrorUtils.runIsolated: um merge que falha não aborta os outros. Após sucesso, invalida retailsProvider + visitsProvider e marca retailRepository.markAdhocVisitCreated(accountSfid). The provider is family by accountSfid and guards re-entry in the creating phase. The Repository resolves the ResourceEntity via currentResourceProvider — sends username and repSfid = resource.sfid (a write identifies the sales rep, §25). Each merge runs in ErrorUtils.runIsolated: a failing merge does not abort the others. After success it invalidates retailsProvider + visitsProvider and marks retailRepository.markAdhocVisitCreated(accountSfid). El provider es family por accountSfid y protege la reentrada en la fase creating. El Repository resuelve el ResourceEntity vía currentResourceProvider — envía username y repSfid = resource.sfid (una escritura identifica al representante, §25). Cada merge corre en ErrorUtils.runIsolated: un merge que falla no aborta los demás. Tras el éxito invalida retailsProvider + visitsProvider y marca retailRepository.markAdhocVisitCreated(accountSfid).

07

Modelo de dadosData modelModelo de datos

A Visita Adhoc é um agregado de fronteira transiente: existe em três representaçõesProto (AdhocVisitReply, wire gRPC) → DTO (AdhocVisitResultDTO, Freezed) → Entity (AdhocVisitResultEntity, domínio) — ligadas por dois mappers. Não há Model ObjectBox nem JSON de mock para o agregado: ele nunca é persistido como uma unidade — cada uma de suas listas é fundida no cache da sua feature (a coluna Model de cada sub-estrutura vive no doc da feature dona).The Adhoc Visit is a transient boundary aggregate: it exists in three representationsProto (AdhocVisitReply, gRPC wire) → DTO (AdhocVisitResultDTO, Freezed) → Entity (AdhocVisitResultEntity, domain) — linked by two mappers. There is no ObjectBox Model nor mock JSON for the aggregate: it is never persisted as one unit — each of its lists is merged into its own feature's cache (each sub-structure's Model column lives in that feature's doc).La Visita Adhoc es un agregado de frontera transitorio: existe en tres representacionesProto (AdhocVisitReply, wire gRPC) → DTO (AdhocVisitResultDTO, Freezed) → Entity (AdhocVisitResultEntity, dominio) — unidas por dos mappers. No hay Model ObjectBox ni JSON de mock para el agregado: nunca se persiste como una unidad — cada una de sus listas se fusiona en el caché de su feature (la columna Model de cada sub-estructura vive en el doc de esa feature).

O AdhocVisitReply tem 11 campos; três deles são mensagens-wrapper (AdhocSurveys, AdhocMerchandising, AdhocFinancialManagement) que o mapper achata — por isso o DTO/Entity terminam com 15 listas. O CallTask vem do TasksConectaRep.proto (mesma estrutura da feature Call Task). A seguir: o proto, as estruturas e os mappers.The AdhocVisitReply has 11 fields; three of them are wrapper messages (AdhocSurveys, AdhocMerchandising, AdhocFinancialManagement) that the mapper flattens — that's why the DTO/Entity end up with 15 lists. CallTask comes from TasksConectaRep.proto (same structure as the Call Task feature). Next: the proto, the structures and the mappers.El AdhocVisitReply tiene 11 campos; tres de ellos son mensajes-wrapper (AdhocSurveys, AdhocMerchandising, AdhocFinancialManagement) que el mapper aplana — por eso el DTO/Entity terminan con 15 listas. El CallTask viene de TasksConectaRep.proto (misma estructura que la feature Call Task). A continuación: el proto, las estructuras y los mappers.

Proto

AdhocVisitConectaRep.proto · proto3 · package mn.bat.conectarep.streambridge. Um único RPC unário que agrega toda a visita:A single unary RPC that aggregates the whole visit:Un único RPC unario que agrega toda la visita:

getAdhocVisitunary
MétodoMethodMétodo

rpc getAdhocVisit(AdhocVisitRequest) returns (AdhocVisitReply)

path /mn.bat.conectarep.streambridge.AdhocVisitConectaRepService/getAdhocVisit

Request · AdhocVisitRequest
username
string · #1 · representante logadologged-in reprepresentante logueado
accountSfid
string · #2 · varejo alvotarget retailpunto de venta objetivo
repSfid
string · #3 · resource.sfid
geoLatitude
double · #4 · optional
geoLongitude
double · #5 · optional
Reply · AdhocVisitReply

11 campos agregados (as listas de uma visita completa):11 aggregated fields (the lists of a full visit):11 campos agregados (las listas de una visita completa):

visits
repeated Visit · #1
callTasks
repeated CallTask · #2
surveys
AdhocSurveys · #3 · wrapper (achatado)wrapper (flattened)wrapper (aplanado)
stockControl
repeated Stock · #4
promotions
repeated Promotion · #5
promotionSpots
repeated SpotPromotion · #6
orders
repeated Order · #7
merchandising
AdhocMerchandising · #8 · wrapper (achatado)wrapper (flattened)wrapper (aplanado)
marginCalculator
repeated MarginCalculatorProduct · #9
financialManagement
AdhocFinancialManagement · #10 · wrapper (achatado)wrapper (flattened)wrapper (aplanado)
productCatalog
repeated Product · #11

Estruturas de dadosData structuresEstructuras de datos

Um dropdown por estrutura. Como o agregado não é persistido, a tabela tem três colunas de camada — Proto (AdhocVisitReply) · DTO · Entity; o texto azul marca onde o dado primeiro muda (o achatamento das mensagens-wrapper acontece no toDTO, no Proto→DTO). Cada linha aponta o doc da feature onde vive o Model daquela lista.One dropdown per structure. Since the aggregate is not persisted, the table has three layer columns — Proto (AdhocVisitReply) · DTO · Entity; the blue text marks where the data first changes (the flattening of the wrapper messages happens in toDTO, at Proto→DTO). Each row points to the feature doc where that list's Model lives.Un dropdown por estructura. Como el agregado no se persiste, la tabla tiene tres columnas de capa — Proto (AdhocVisitReply) · DTO · Entity; el texto azul marca dónde primero cambia el dato (el aplanamiento de los wrappers ocurre en toDTO, en Proto→DTO). Cada fila apunta al doc de la feature donde vive el Model de esa lista.

  • AdhocVisitRequest request 5 camposfieldscampos
    CampoProtoDTOEntity
    usernamestring— (montado no datasource a partir do ResourceEntity)— (built in the datasource from the ResourceEntity)— (armado en el datasource desde el ResourceEntity)
    accountSfidstring— (parâmetro do UseCase)— (UseCase parameter)— (parámetro del UseCase)
    repSfidstringresource.sfid
    geoLatitudedouble¹— (posição do device)— (device position)— (posición del device)
    geoLongitudedouble¹— (posição do device)— (device position)— (posición del device)
  • AdhocVisitResult AdhocVisitReply → DTO/Entity 15 listaslistslistas
    CampoProto (Reply)DTOEntity
    visitsrepeated VisitList<VisitDTO>List<VisitEntity>
    callTasksrepeated CallTaskList<CallTaskDTO>List<CallTaskEntity>
    surveyssurveys.surveysList<SurveyDTO>List<SurveyEntity>
    stockControlrepeated StockList<StockDTO>List<StockEntity>
    promotionsrepeated PromotionList<PromotionDTO>List<PromotionEntity>
    promotionSpotsrepeated SpotPromotionList<SpotPromotionDTO>List<SpotPromotionEntity>
    ordersrepeated OrderList<OrderDTO>List<OrderEntity>
    merchandisingAssetsmerchandising.assetsList<MerchandisingAssetDTO>List<MerchandisingAssetEntity>
    merchandisingServiceOrdersmerchandising.serviceOrdersList<MerchandisingServiceOrderDTO>List<MerchandisingServiceOrderEntity>
    marginCalculatorrepeated MarginCalculatorProductList<MarginCalculatorProductDTO>List<MarginCalculatorProductEntity>
    debitOpenItemsfinancialManagement.debitOpenItemsList<DebitOpenItemDTO>List<DebitOpenItemEntity>
    banksfinancialManagement.banksList<BankDTO>List<BankEntity>
    paymentsfinancialManagement.paymentsList<PaymentDTO>List<PaymentEntity>
    creditNotesfinancialManagement.creditNotesList<CreditNoteDTO>List<CreditNoteEntity>
    productCatalogrepeated ProductList<ProductDTO>List<ProductEntity>

Campos do wrapper não usadosUnused wrapper fieldsCampos del wrapper no usados O AdhocMerchandising traz 4 listas no proto (assets, audits, digitalContent, serviceOrders), mas o mapper só achata assets e serviceOrdersaudits e digitalContent não são mapeados para o agregado adhoc hoje. AdhocMerchandising carries 4 lists in the proto (assets, audits, digitalContent, serviceOrders), but the mapper only flattens assets and serviceOrdersaudits and digitalContent are not mapped into the adhoc aggregate today. AdhocMerchandising trae 4 listas en el proto (assets, audits, digitalContent, serviceOrders), pero el mapper solo aplana assets y serviceOrdersaudits y digitalContent no se mapean al agregado adhoc hoy.

Mappers

O adhoc_visit_result_mapper.dart tem 2 direções (o agregado não tem Model, então não há toModel/Model→Entity); cada lista delega ao mapper da sua feature.The adhoc_visit_result_mapper.dart has 2 directions (the aggregate has no Model, so no toModel/Model→Entity); each list delegates to its feature's mapper.El adhoc_visit_result_mapper.dart tiene 2 direcciones (el agregado no tiene Model, así que no hay toModel/Model→Entity); cada lista delega al mapper de su feature.

DireçãoDirectionDirecciónExtensão · métodoExtension · methodExtensión · métodoDelegaçãoDelegationDelegación
Proto → DTOAdhocVisitReplyProtoMapper.toDTO()achata os wrappers; p/ call tasks chama CallTaskProtoMapper.toDTO() por item.flattens the wrappers; for call tasks calls CallTaskProtoMapper.toDTO() per item.aplana los wrappers; p/ call tasks llama CallTaskProtoMapper.toDTO() por ítem.
DTO → EntityAdhocVisitResultDTOMapper.toDomain()p/ call tasks chama CallTaskDTOMapper.toDomain() por item.for call tasks calls CallTaskDTOMapper.toDomain() per item.p/ call tasks llama CallTaskDTOMapper.toDomain() por ítem.

Os únicos deltasThe only deltasLos únicos deltas

  • Achatamento de wrappersurveys, merchandisingAssets, merchandisingServiceOrders, debitOpenItems, banks, payments, creditNotes saem de dentro das 3 mensagens-wrapper no toDTO (Proto→DTO).Wrapper flatteningsurveys, merchandisingAssets, merchandisingServiceOrders, debitOpenItems, banks, payments, creditNotes come out of the 3 wrapper messages in toDTO (Proto→DTO).Aplanamiento de wrappersurveys, merchandisingAssets, merchandisingServiceOrders, debitOpenItems, banks, payments, creditNotes salen de los 3 wrappers en toDTO (Proto→DTO).
  • Sem Model / sem persistência do agregado — o AdhocVisitResultEntity nunca vira um Model; cada lista é fundida no cache de outra feature pelo merge coordinator.No Model / no aggregate persistence — the AdhocVisitResultEntity never becomes a Model; each list is merged into another feature's cache by the merge coordinator.Sin Model / sin persistencia del agregado — el AdhocVisitResultEntity nunca se vuelve Model; cada lista se fusiona en el caché de otra feature por el merge coordinator.
  • Delegação por item — os campos internos (enums, datas parseadas de CallTask etc.) mudam dentro do mapper de cada feature, não aqui.Per-item delegation — inner fields (enums, parsed CallTask dates etc.) change inside each feature's mapper, not here.Delegación por ítem — los campos internos (enums, fechas parseadas de CallTask etc.) cambian dentro del mapper de cada feature, no aquí.
08

Repository

O AdhocVisitRepositoryImpl tem um único método. Apesar do nome "create", é uma operação remote-first de leitura-e-cache: busca o reply no servidor e o funde nos caches locais. Não há caminho de fallback para cache — sem varejo no reply, falha.The AdhocVisitRepositoryImpl has a single method. Despite the "create" name, it is a remote-first read-and-cache operation: it fetches the reply from the server and merges it into the local caches. There is no cache fallback path — with no visit in the reply, it fails.El AdhocVisitRepositoryImpl tiene un único método. A pesar del nombre "create", es una operación remote-first de lectura-y-caché: busca el reply en el servidor y lo fusiona en los cachés locales. No hay camino de fallback a caché — sin visita en el reply, falla.

createAdhocVisit({accountSfid, geoLatitude?, geoLongitude?}) remote-first

RetornaReturnsDevuelve Future<Result<AdhocVisitResultEntity, Failure>>

  • createAdhocVisit
    • currentResourceProvider == null → Error(UnknownFailure)
    • _useMock → mock.getAdhocVisit() (vazio) → toDomain → merge
    • senãoelsesi no → remote.getAdhocVisit(username, accountSfid, repSfid, geo?) → toDomain
    • entity.visits.isEmpty → log adhocReplyHadNoVisit · Error(BusinessFailure: retailsAdhocFailedToast)
    • senãoelsesi no → mergeCoordinator.merge(result, accountSfid) · log adhocCreated · Success(entity)

Erros mapeados por FailureMapper.fromException e logados em LogCategory.dataSync. O username e repSfid vêm do ResourceEntity (§25).Errors mapped via FailureMapper.fromException and logged under LogCategory.dataSync. username and repSfid come from the ResourceEntity (§25).Errores mapeados por FailureMapper.fromException y logueados en LogCategory.dataSync. El username y repSfid vienen del ResourceEntity (§25).

AdhocVisitMergeCoordinator.merge({result, accountSfid}) 11 merges aditivos11 additive merges11 merges aditivos

Funde as 15 listas em 11 datasources locais, cada merge dentro de ErrorUtils.runIsolated (um erro isolado não aborta os demais). Todos seguem o padrão aditivo escopado por chave: retêm no cache o que não pertence ao escopo e anexam o recebido (lastSyncAt preservado).Merges the 15 lists into 11 local datasources, each merge inside ErrorUtils.runIsolated (one isolated error doesn't abort the rest). All follow the additive, key-scoped pattern: retain in cache what does not belong to the scope and append the incoming (lastSyncAt preserved).Fusiona las 15 listas en 11 datasources locales, cada merge dentro de ErrorUtils.runIsolated (un error aislado no aborta los demás). Todos siguen el patrón aditivo por clave: retienen en caché lo que no pertenece al alcance y anexan lo recibido (lastSyncAt preservado).

MergeEscopo (chave de retenção)Scope (retention key)Alcance (clave de retención)
mergeAdhocVisitsvisitas com accountData.sfid ≠ accountSfidvisits with accountData.sfid ≠ accountSfidvisitas con accountData.sfid ≠ accountSfid
mergeAdhocCallTaskscall tasks com visitSfidrefreshedVisitSfids (Call Task)call tasks whose visitSfidrefreshedVisitSfids (Call Task)call tasks con visitSfidrefreshedVisitSfids (Call Task)
mergeAdhocOrdersaccountSfid ≠ accountSfid
mergeAdhocStockControlaccountId ≠ accountSfid
mergeAdhocFinancialManagementpor lista (debitOpenItems/payments por account; creditNotes por retailerId; banks dedup por sfid)per list (debitOpenItems/payments by account; creditNotes by retailerId; banks dedup by sfid)por lista (debitOpenItems/payments por account; creditNotes por retailerId; banks dedup por sfid)
mergeAdhocMerchandisingServiceOrdersaccountSfid ≠ accountSfid
mergeAdhocSurveysupsert por survey sfid; substitui só o accountData deste accountupsert by survey sfid; replaces only this account's accountDataupsert por survey sfid; reemplaza solo el accountData de este account
mergeAdhocPromotionCatalogupsert por promoção id; spots por accountSfidupsert by promotion id; spots by accountSfidupsert por promoción id; spots por accountSfid
mergeAdhocMarginCalculatorupsert por produto sfid; anexa accountSfid à listaupsert by product sfid; appends accountSfid to the listupsert por producto sfid; anexa accountSfid a la lista
mergeAdhocProductCatalogupsert por productSfid; substitui soq/salesHistory deste accountupsert by productSfid; replaces this account's soq/salesHistoryupsert por productSfid; reemplaza soq/salesHistory de este account
mergeAdhocMerchandisingAssetsupsert por asset sfid; substitui os items deste accountupsert by asset sfid; replaces this account's itemsupsert por asset sfid; reemplaza los items de este account

refreshedVisitSfids = união de result.visits.map(sfid)result.callTasks.map(visitSfid), sem strings vazias — usado apenas no mergeAdhocCallTasks (pois CallTask não tem accountSfid, o escopo é por visita).union of result.visits.map(sfid)result.callTasks.map(visitSfid), empty strings removed — used only in mergeAdhocCallTasks (since CallTask has no accountSfid, the scope is per visit).unión de result.visits.map(sfid)result.callTasks.map(visitSfid), sin strings vacías — usado solo en mergeAdhocCallTasks (como CallTask no tiene accountSfid, el alcance es por visita).

Manager Tasks não são fundidas — a fiação de ManagerTaskLocalDataSource foi removida do adhoc; o slot de tarefas de uma visita adhoc é sempre Call Tasks.Manager Tasks are not merged — the ManagerTaskLocalDataSource wiring was removed from adhoc; an adhoc visit's task slot is always Call Tasks.Las Manager Tasks no se fusionan — la conexión de ManagerTaskLocalDataSource se quitó del adhoc; el slot de tareas de una visita adhoc es siempre Call Tasks.

09

Datasources

dois datasources próprios: Remote (o RPC) e Mock (stub vazio). Não há Local datasource nem JSON de mock do agregado — a persistência acontece nos 11 datasources locais das outras features, pelo merge coordinator (seção 08).Only two datasources of its own: Remote (the RPC) and Mock (empty stub). There is no Local datasource nor mock JSON for the aggregate — persistence happens in the 11 local datasources of the other features, via the merge coordinator (section 08).Solo dos datasources propios: Remote (el RPC) y Mock (stub vacío). No hay Local datasource ni JSON de mock del agregado — la persistencia ocurre en los 11 datasources locales de las otras features, vía el merge coordinator (sección 08).

Remote AdhocVisitRemoteDataSource gRPC

Envio / fluxo: AdhocVisitConectaRepServiceClient. Erro: GrpcErrorGrpcExceptionHandler.handle; outros → ServerException.Sends / flow: AdhocVisitConectaRepServiceClient. Error: GrpcErrorGrpcExceptionHandler.handle; others → ServerException.Envío / flujo: AdhocVisitConectaRepServiceClient. Error: GrpcErrorGrpcExceptionHandler.handle; otros → ServerException.

getAdhocVisit({username, accountSfid, repSfid, geoLatitude?, geoLongitude?})
RetornoReturnRetorno
Future<AdhocVisitResultDTO>
EnvioSendsEnvío
AdhocVisitRequest (username + accountSfid + repSfid; geoLatitude/geoLongitude só quando presentes)
FluxoFlowFlujo
stub getAdhocVisit; response.toDTO().stub getAdhocVisit; response.toDTO().stub getAdhocVisit; response.toDTO().
Mock AdhocVisitMockDataSource stub vazioempty stubstub vacío
getAdhocVisit({accountSfid})
RetornoReturnRetorno
Future<AdhocVisitResultDTO>
ComportamentoBehaviorComportamiento
retorna const AdhocVisitResultDTO() (todas as listas vazias) — online-only por design, não lê asset. No modo mock a criação falha em visits.isEmpty.returns const AdhocVisitResultDTO() (all lists empty) — online-only by design, reads no asset. In mock mode creation fails at visits.isEmpty.retorna const AdhocVisitResultDTO() (todas las listas vacías) — online-only por diseño, no lee asset. En modo mock la creación falla en visits.isEmpty.
10

Enums e labelsEnums & labelsEnums y labels

AdhocVisitCreationPhase core/enums/adhoc_visit 4
casesignificadomeaningsignificado
idleestado inicial · nada em andamentoinitial · nothing in progressinicial · nada en curso
creatingcriando · loading; bloqueia reentrânciacreating · loading; blocks re-entrycreando · loading; bloquea reentrada
completedvisita criada com sucessovisit created successfullyvisita creada con éxito
failederro · carrega o Failureerror · carries the Failureerror · lleva el Failure
VisitType core/enums/visits valor adhocadhoc valuevalor adhoc

A visita criada carrega VisitType.adhoc (value "adhoc") — distingue-a das planejadas nas listas e no fim de jornada.The created visit carries VisitType.adhoc (value "adhoc") — it sets it apart from planned ones in the lists and at journey end.La visita creada lleva VisitType.adhoc (value "adhoc") — la distingue de las planificadas en las listas y al fin de jornada.

Labels · TranslationConstants i18n 7
keyusouseuso
retailsAdhocBadgebadge/botão ADHOC no cardADHOC badge/button on the cardbadge/botón ADHOC en la tarjeta
retailsCreateAdhocModalTitletítulo do modalmodal titletítulo del modal
retailsCreateAdhocOkbotão confirmarconfirm buttonbotón confirmar
retailsCreateAdhocCancelbotão cancelarcancel buttonbotón cancelar
retailsAdhocCreatedToastaviso de sucesso (interpola {name}/{sap})success notice (interpolates {name}/{sap})aviso de éxito (interpola {name}/{sap})
retailsAdhocFailedToastaviso de erroerror noticeaviso de error
endJourneyVisitTypeAdhocrótulo do tipo no fim de jornadatype label at journey endetiqueta del tipo al fin de jornada
11

UseCases

CreateAdhocVisitUseCase usecases/adhoc_visit
MétodoMethodMétodoRetornaReturnsDevuelveUsoUseUso
execute({accountSfid, geoLatitude?, geoLongitude?})Future<Result<AdhocVisitResultEntity, Failure>>encaminha ao repository.createAdhocVisit(...). Provider keepAlive.forwards to repository.createAdhocVisit(...). keepAlive provider.reenvía a repository.createAdhocVisit(...). Provider keepAlive.
12

Notifier & State

A Visita Adhoc é orquestrada por um provider cross-page (não um Notifier de tela): o AdhocVisitCreation, family por accountSfid e keepAlive, vive em presentation/shared/providers/visits/ porque é consumido pelos cards da Lista de varejos. O build devolve o State inicial; o método create conduz o fluxo.The Adhoc Visit is orchestrated by a cross-page provider (not a screen Notifier): AdhocVisitCreation, family by accountSfid and keepAlive, lives in presentation/shared/providers/visits/ because the Retails list cards consume it. build returns the initial State; the create method drives the flow.La Visita Adhoc es orquestada por un provider cross-page (no un Notifier de pantalla): el AdhocVisitCreation, family por accountSfid y keepAlive, vive en presentation/shared/providers/visits/ porque las tarjetas de la Lista de puntos de venta lo consumen. El build devuelve el State inicial; el método create conduce el flujo.

MétodosMethodsMétodos

create({retailName, accountSapCustomerId})

RetornoReturnRetorno Future<void>

Guarda contra reentrância (phase == creating → retorna). Seta creating com retailName/accountSapCustomerId, lê a posição via locationServiceProvider, chama createAdhocVisitUseCase.execute(accountSfid, geo?). SuccessretailRepository.markAdhocVisitCreated(accountSfid), invalida retailsProvider + visitsProvider, fase completed, toast verde. Error → fase failed + failure, toast vermelho.Guards re-entry (phase == creating → returns). Sets creating with retailName/accountSapCustomerId, reads position via locationServiceProvider, calls createAdhocVisitUseCase.execute(accountSfid, geo?). SuccessretailRepository.markAdhocVisitCreated(accountSfid), invalidates retailsProvider + visitsProvider, phase completed, green toast. Error → phase failed + failure, red toast.Protege la reentrada (phase == creating → retorna). Setea creating con retailName/accountSapCustomerId, lee la posición vía locationServiceProvider, llama createAdhocVisitUseCase.execute(accountSfid, geo?). SuccessretailRepository.markAdhocVisitCreated(accountSfid), invalida retailsProvider + visitsProvider, fase completed, toast verde. Error → fase failed + failure, toast rojo.

State disponível para a PageState available to the PageState disponible para la Page

AdhocVisitCreationState Freezed 4 camposfieldscampos
CampoTipoTypeTipoUsoUseUso
phaseAdhocVisitCreationPhasedefault idledefault idledefault idle
retailNameString?nome exibido nos avisosname shown in noticesnombre en los avisos
accountSapCustomerIdString?SAP exibido no aviso verdeSAP shown in the green noticeSAP en el aviso verde
failureFailure?preenchido em failedset on failedseteado en failed
13

Page e widgetsPage & widgetsPage y widgets

Sem page própria — a superfície é o card do varejo (na Lista de varejos) e o modal de confirmação.No page of its own — the surface is the retail card (in the Retails list) and the confirmation modal.Sin page propia — la superficie es la tarjeta del punto (en la Lista de puntos de venta) y el modal de confirmación.

  • RetailsPage Lista de varejos (host)Retails list (host)Lista de puntos de venta (host)
    • RetailCardWidget observa adhocVisitCreationProvider(accountSfid:)watches adhocVisitCreationProvider(accountSfid:)observa adhocVisitCreationProvider(accountSfid:)
      • _RetailActionBadge · ADHOC visível só se isAdhocVisitCreationAvailable; loading na fase creatingvisible only if isAdhocVisitCreationAvailable; loading in the creating phasevisible solo si isAdhocVisitCreationAvailable; loading en la fase creating
      • CreateAdhocVisitModalContent modal · confirma → provider.create(retailName, accountSapCustomerId)modal · confirm → provider.create(retailName, accountSapCustomerId)modal · confirmar → provider.create(retailName, accountSapCustomerId)

A RetailsPage passa o onAdhocTap que abre o CreateAdhocVisitModalContent via ConectaModal.show; ao confirmar, chama ref.read(adhocVisitCreationProvider(...).notifier).create(...). Abrir modal e navegar ficam no widget; o disparo é o método do provider (§39).The RetailsPage passes the onAdhocTap that opens CreateAdhocVisitModalContent via ConectaModal.show; on confirm it calls ref.read(adhocVisitCreationProvider(...).notifier).create(...). Opening the modal and navigating stay in the widget; the trigger is the provider method (§39).La RetailsPage pasa el onAdhocTap que abre el CreateAdhocVisitModalContent vía ConectaModal.show; al confirmar llama ref.read(adhocVisitCreationProvider(...).notifier).create(...). Abrir el modal y navegar quedan en el widget; el disparo es el método del provider (§39).

Notas por mercadoMarket notesNotas por mercado

A Visita Adhoc acompanha o ecossistema de Varejos/Visitas — ativa nos mercados vivos (BR/CL/ZA). O botão em si é por varejo (isAdhocVisitCreationAvailable, dado da entity), e o tipo adhoc é um valor de visita reconhecido no End Market Configuration.The Adhoc Visit follows the Retails/Visits ecosystem — active in the live markets (BR/CL/ZA). The button itself is per retail (isAdhocVisitCreationAvailable, entity data), and the adhoc type is a visit value recognized in the End Market Configuration.La Visita Adhoc acompaña el ecosistema de Puntos de venta/Visitas — activa en los mercados vivos (BR/CL/ZA). El botón en sí es por punto (isAdhocVisitCreationAvailable, dato de la entity), y el tipo adhoc es un valor de visita reconocido en el End Market Configuration.

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

AtivosActiveActivos Mercados vivos com Varejos/Visitas. O reply do getAdhocVisit traz Call Tasks no slot de tarefas (não Manager Tasks). A geolocalização é enviada quando o device a disponibiliza. Live markets with Retails/Visits. The getAdhocVisit reply carries Call Tasks in the task slot (not Manager Tasks). Geolocation is sent when the device provides it. Mercados vivos con Puntos de venta/Visitas. El reply de getAdhocVisit trae Call Tasks en el slot de tareas (no Manager Tasks). La geolocalización se envía cuando el device la provee.

AR · PY · PE Mercados PANGEA de configuração mínima: o ecossistema de Varejos/Visitas não está ativo, então a Visita Adhoc não existe — nenhum card exibe o botão ADHOC. PANGEA minimal-config markets: the Retails/Visits ecosystem is not active, so the Adhoc Visit doesn't exist — no card shows the ADHOC button. Mercados PANGEA de configuración mínima: el ecosistema de Puntos de venta/Visitas no está activo, así que la Visita Adhoc no existe — ninguna tarjeta muestra el botón ADHOC.

Pendências / roadmapPending / roadmapPendientes / roadmap (1) O agregado ignora merchandising.audits e merchandising.digitalContent do proto — só assets e serviceOrders são fundidos hoje. (2) Sem mock: em ambiente mock a criação sempre falha (reply vazio) — é online-only por design. (3) O merge coordinator é fire-and-persist sem transação atômica entre as 11 caches (cada merge é isolado por runIsolated). (1) The aggregate ignores the proto's merchandising.audits and merchandising.digitalContent — only assets and serviceOrders are merged today. (2) No mock: in mock mode creation always fails (empty reply) — it is online-only by design. (3) The merge coordinator is fire-and-persist with no atomic transaction across the 11 caches (each merge is isolated by runIsolated). (1) El agregado ignora merchandising.audits y merchandising.digitalContent del proto — solo assets y serviceOrders se fusionan hoy. (2) Sin mock: en modo mock la creación siempre falla (reply vacío) — es online-only por diseño. (3) El merge coordinator es fire-and-persist sin transacción atómica entre los 11 cachés (cada merge está aislado por runIsolated).