RecompraBuybackRecompra
A recompra (buyback) devolve mercadoria do varejo para a companhia. Abre a partir da visita e tem dois lados: solicitar uma nova recompra (produtos + data + motivo) e executar as recompras já agendadas (aceitar, rejeitar ou reagendar a coleta). Ambos gravam via Dispatcher. Buyback returns goods from the retail back to the company. It opens from the visit and has two sides: requesting a new buyback (products + date + reason) and executing already scheduled buybacks (accept, reject or reschedule the collection). Both write through the Dispatcher. La recompra (buyback) devuelve mercadería del punto de venta a la compañía. Se abre desde la visita y tiene dos lados: solicitar una nueva recompra (productos + fecha + motivo) y ejecutar las recompras ya agendadas (aceptar, rechazar o reprogramar la recolección). Ambos graban vía Dispatcher.
O que é e para que serveWhat it is and what it's forQué es y para qué sirve
A Recompra é o fluxo em que o representante de vendas trata a devolução de mercadoria de um varejo para a companhia. Sempre no contexto de uma visita (é aberta pelo detalhe da visita), reúne três frentes: The Buyback is the flow where the sales rep handles goods being returned from a retail to the company. Always in the context of a visit (opened from the visit detail), it gathers three fronts: La Recompra es el flujo donde el representante de ventas gestiona la devolución de mercadería de un punto de venta a la compañía. Siempre en el contexto de una visita (se abre desde el detalle de la visita), reúne tres frentes:
Solicitar recompraRequest a buybackSolicitar recompra
Escolher produtos e quantidades por categoria, definir data de coleta e motivo, e enviar o pedido de devolução.Pick products and quantities by category, set a collection date and reason, and submit the return request.Elegir productos y cantidades por categoría, definir fecha de recolección y motivo, y enviar la solicitud de devolución.
Executar a coletaExecute the collectionEjecutar la recolección
Nas recompras já agendadas: aceitar, rejeitar ou reagendar a coleta (uplift).On already scheduled buybacks: accept, reject or reschedule the collection (uplift).En las recompras ya agendadas: aceptar, rechazar o reprogramar la recolección (uplift).
Acompanhar o statusTrack statusSeguir el estado
Cada recompra tem status (à espera, aceita, rejeitada, reagendada) e itens com quantidade por unidade.Each buyback has a status (waiting, accepted, rejected, rescheduled) and items with quantity per unit.Cada recompra tiene estado (en espera, aceptada, rechazada, reprogramada) e ítems con cantidad por unidad.
Feature de escritaWrite featureFeature de escritura Diferente da lista de pedidos (só leitura), a recompra envia transações: a solicitação vai como SalesReturnSEN e cada execução (aceitar/rejeitar/reagendar) como SalesReturnUplift, ambas pelo Dispatcher. Unlike the read-only order list, buyback submits transactions: the request goes as SalesReturnSEN and each execution (accept/reject/reschedule) as SalesReturnUplift, both via the Dispatcher. A diferencia de la lista de pedidos (solo lectura), la recompra envía transacciones: la solicitud va como SalesReturnSEN y cada ejecución (aceptar/rechazar/reprogramar) como SalesReturnUplift, ambas vía el Dispatcher.
Como acessarHow to openCómo acceder
- Abra uma visitaOpen a visitAbra una visitaA recompra é sempre por varejo/visita — entre no detalhe da visita do varejo.Buyback is always per retail/visit — go into the retail's visit detail.La recompra es siempre por punto de venta/visita — entre al detalle de la visita.
- Grade de ferramentasTools gridGrilla de herramientasToque em Recompra na grade de ferramentas da visita (só aparece onde o mercado habilita).Tap Buyback in the visit's tools grid (shown only where the market enables it).Toque Recompra en la grilla de herramientas de la visita (solo donde el mercado lo habilita).
- Menu da recompraBuyback menuMenú de la recompraAbre um menu com o cartão do varejo e duas opções: Solicitar e Coleta.A menu opens with the retail card and two options: Request and Collection.Se abre un menú con la tarjeta del punto de venta y dos opciones: Solicitar y Recolección.
Estrutura das telasScreen structureEstructura de las pantallas
A recompra são quatro telas encadeadas a partir do menu:Buyback is four screens chained from the menu:La recompra son cuatro pantallas encadenadas desde el menú:
- MenuMenuMenú
- Cartão do varejo + duas ações grandes: Solicitar (nova recompra) e Coleta (executar agendadas).Retail card + two large actions: Request (new buyback) and Collection (execute scheduled ones).Tarjeta del punto de venta + dos acciones grandes: Solicitar (nueva recompra) y Recolección (ejecutar las agendadas).
- SolicitaçãoRequestSolicitud
- Abas por categoria, filtro por marca e busca, cards de produto com controle de quantidade. Uma barra de resumo mostra itens + total e leva ao resumo.Category tabs, brand filter and search, product cards with a quantity control. A summary bar shows items + total and leads to the summary.Pestañas por categoría, filtro por marca y búsqueda, tarjetas de producto con control de cantidad. Una barra de resumen muestra ítems + total y lleva al resumen.
- ResumoSummaryResumen
- Lista dos itens escolhidos, quantidades por categoria, data de coleta (calendário) e motivo (dropdown). Botão Confirmar → envia.The chosen items, quantities per category, collection date (calendar) and reason (dropdown). Confirm button → submits.Los ítems elegidos, cantidades por categoría, fecha de recolección (calendario) y motivo (dropdown). Botón Confirmar → envía.
- ColetaCollectionRecolección
- Abas (todas / abertas / executadas / reagendadas), cards de recompra expansíveis (itens dentro) com status, e botões Rejeitar / Aceitar. Reagendar por swipe.Tabs (all / open / executed / rescheduled), expandable buyback cards (items inside) with status, and Reject / Accept buttons. Reschedule via swipe.Pestañas (todas / abiertas / ejecutadas / reprogramadas), tarjetas de recompra expandibles (ítems dentro) con estado, y botones Rechazar / Aceptar. Reprogramar por swipe.
Status da recompraBuyback statusesEstados de la recompra
Cada recompra na tela de coleta tem um status, que define a cor da tag e o que dá para fazer com ela (a lista completa está na seção técnica Enums):Each buyback in the collection screen has a status, which sets the tag color and what you can do with it (the full list is in the technical Enums section):Cada recompra en la pantalla de recolección tiene un estado, que define el color de la etiqueta y qué se puede hacer con ella (la lista completa está en la sección técnica Enums):
As abas agrupam por status: Abertas = à espera + reagendada; Executadas = aceita + rejeitada; Reagendadas = reagendada hoje. Só recompras que ainda podem ser executadas (canAccept/canReject) são selecionáveis.Tabs group by status: Open = waiting + rescheduled; Executed = accepted + rejected; Rescheduled = rescheduled today. Only buybacks that can still be executed (canAccept/canReject) are selectable.Las pestañas agrupan por estado: Abiertas = en espera + reprogramada; Ejecutadas = aceptada + rechazada; Reprogramadas = reprogramada hoy. Solo las recompras que aún se pueden ejecutar (canAccept/canReject) son seleccionables.
AçõesActionsAcciones
Solicitar uma recompraRequest a buybackSolicitar una recompra
Escolha os produtos e quantidades por categoria; a barra de resumo aparece com itens + total. Toque nela para ir ao resumo, defina a data de coleta (só dias úteis, janela de 60 dias) e o motivo, e confirme. Ao confirmar, envia a transação SalesReturnSEN e o rascunho é limpo.Pick products and quantities per category; the summary bar shows items + total. Tap it to reach the summary, set the collection date (business days only, 60-day window) and the reason, then confirm. On confirm it submits the SalesReturnSEN transaction and clears the draft.Elija productos y cantidades por categoría; la barra de resumen muestra ítems + total. Tóquela para llegar al resumen, defina la fecha de recolección (solo días hábiles, ventana de 60 días) y el motivo, y confirme. Al confirmar envía la transacción SalesReturnSEN y limpia el borrador.
Executar (aceitar / rejeitar)Execute (accept / reject)Ejecutar (aceptar / rechazar)
Na coleta, selecione uma recompra selecionável e toque em Aceitar ou Rejeitar. Um modal pede confirmação; ao confirmar, envia SalesReturnUplift (status F ou R) e o cache local é atualizado na hora (a recompra sai de selecionável).In the collection screen, select a selectable buyback and tap Accept or Reject. A modal asks for confirmation; on confirm it submits SalesReturnUplift (status F or R) and the local cache is updated immediately (the buyback stops being selectable).En la recolección, seleccione una recompra seleccionable y toque Aceptar o Rechazar. Un modal pide confirmación; al confirmar envía SalesReturnUplift (estado F o R) y el caché local se actualiza al instante (la recompra deja de ser seleccionable).
ReagendarRescheduleReprogramar
Quando canReschedule, o card revela por swipe a ação de reagendar: escolha a nova data (dias úteis, janela de 60 dias) e confirme. Envia SalesReturnUplift com status RS e a nova data de coleta. Detalhes do payload nas transações SalesReturnSEN e SalesReturnUplift.When canReschedule, the card reveals a reschedule action via swipe: pick the new date (business days, 60-day window) and confirm. It submits SalesReturnUplift with status RS and the new collection date. Payload details in the SalesReturnSEN and SalesReturnUplift transactions.Cuando canReschedule, la tarjeta revela la acción de reprogramar por swipe: elija la nueva fecha (días hábiles, ventana de 60 días) y confirme. Envía SalesReturnUplift con estado RS y la nueva fecha de recolección. Detalles del payload en las transacciones SalesReturnSEN y SalesReturnUplift.
Arquitetura e fluxo de dadosArchitecture & data flowArquitectura y flujo de datos
Clean Architecture + Riverpod + Freezed + gRPC + ObjectBox. A recompra tem leitura e escrita distintas. A leitura (recompras agendadas) usa um único RPC getBuybackCollection com cache write-through. A escrita não tem RPC próprio: passa pelo Dispatcher (DispatcherOrchestrator) como duas transações — solicitação e execução.Clean Architecture + Riverpod + Freezed + gRPC + ObjectBox. Buyback has distinct read and write sides. The read (scheduled buybacks) uses a single getBuybackCollection RPC with cache write-through. The write has no proto of its own: it goes through the Dispatcher (DispatcherOrchestrator) as two transactions — request and execution.Clean Architecture + Riverpod + Freezed + gRPC + ObjectBox. La recompra tiene lados lectura y escritura distintos. La lectura (recompras agendadas) usa un único RPC getBuybackCollection con cache write-through. La escritura no tiene proto propio: pasa por el Dispatcher (DispatcherOrchestrator) como dos transacciones — solicitud y ejecución.
Leitura — recompras agendadas (write-through)Read — scheduled buybacks (write-through)Lectura — recompras agendadas (write-through)
- BuybackCollectionReplygRPC proto
- toDTOBuybackCollectionDTODTO · Freezed
- toEntityBuybackCollectionEntitydomain
- toModelBuybackCollectionModelObjectBox
- toEntityBuybackCollectionEntitydomain · cache
- watchBuybackCollectionNotifier + State
- → UIBuybackCollectionPage
- watchBuybackCollectionNotifier + State
- toEntityBuybackCollectionEntitydomain · cache
- toModelBuybackCollectionModelObjectBox
- toEntityBuybackCollectionEntitydomain
- toDTOBuybackCollectionDTODTO · Freezed
Escrita — via Dispatcher (duas transações)Write — via Dispatcher (two transactions)Escritura — vía Dispatcher (dos transacciones)
- Draft / Buyback + ActionUI state
- build()Build…DispatcherPayloadUseCaserequest · execution
- DispatcherEnvelopeSubmitBuyback…UseCase
- dispatchDispatcherOrchestratorstore · tracking · retry
- sendTransactiongRPC · SalesReturnSEN / SalesReturnUplift
- dispatchDispatcherOrchestratorstore · tracking · retry
- DispatcherEnvelopeSubmitBuyback…UseCase
- build()Build…DispatcherPayloadUseCaserequest · execution
Modelo de dadosData modelModelo de datos
O lado de leitura segue as quatro representações — Proto (wire gRPC) → DTO (Freezed) → Model (ObjectBox) → Entity (domínio) — ligadas por mappers, com cache write-through. Muda muito pouco entre camadas: o status vira enum tipado só na Entity, o upliftDate é parseado para DateTime? no Model, e as listas viram relações ToMany.The read side follows the four representations — Proto (gRPC wire) → DTO (Freezed) → Model (ObjectBox) → Entity (domain) — linked by mappers, with cache write-through. Very little changes across layers: status becomes a typed enum only in the Entity, upliftDate is parsed to DateTime? in the Model, and lists become ToMany relations.El lado de lectura sigue las cuatro representaciones — Proto (wire gRPC) → DTO (Freezed) → Model (ObjectBox) → Entity (dominio) — unidas por mappers, con cache write-through. Cambia muy poco entre capas: status pasa a enum tipado solo en la Entity, upliftDate se parsea a DateTime? en el Model, y las listas pasan a relaciones ToMany.
A resposta chega num container BuybackCollectionEntity (lastSyncAt gerado no mapper + accounts[]); cada conta é um BuybackAccount com uma lista de Buyback (9 campos) e seus BuybackItem. O lado de escrita não usa este proto — monta JSON no builder a partir de entities cruas (ver UseCases). A seguir: o proto de leitura, as estruturas campo-a-campo e os mappers.The response arrives in a BuybackCollectionEntity container (lastSyncAt generated in the mapper + accounts[]); each account is a BuybackAccount with a list of Buyback (9 fields) and their BuybackItem. The write side doesn't use this proto — it builds JSON in the builder from raw entities (see UseCases). Next: the read proto, the field-by-field structures and the mappers.La respuesta llega en un container BuybackCollectionEntity (lastSyncAt generado en el mapper + accounts[]); cada cuenta es un BuybackAccount con una lista de Buyback (9 campos) y sus BuybackItem. El lado de escritura no usa este proto — arma JSON en el builder desde entities crudas (ver UseCases). A continuación: el proto de lectura, las estructuras campo a campo y los mappers.
Proto
BuybackCollectionConectaRep.proto · proto3 · package mn.bat.conectarep.streambridge. Um serviço (BuybackCollectionConectaRepService), um método unário:One service (BuybackCollectionConectaRepService), a single unary method:Un servicio (BuybackCollectionConectaRepService), un método unario:
getBuybackCollectionunaryrpc getBuybackCollection(BuybackCollectionRequest) returns (BuybackCollectionReply)
path /mn.bat.conectarep.streambridge.BuybackCollectionConectaRepService/getBuybackCollection
BuybackCollectionRequestlocationHierarchySfidstring· #1 · hierarquia do representante de vendas (resolvida no repository viacurrentResourceProvider)sales rep hierarchy (resolved in the repository viacurrentResourceProvider)jerarquía del representante de ventas (resuelta en el repository víacurrentResourceProvider)lastModifiedDatestring· #2 · optional (não enviado hoje)optional (not sent today)optional (no enviado hoy)
BuybackCollectionReplyrepeated BuybackAccount buybackCollection — as recompras agrupadas por conta. As estruturas estão detalhadas abaixo.buybacks grouped by account. The structures are detailed below.las recompras agrupadas por cuenta. Las estructuras están detalladas abajo.
Estruturas de dadosData structuresEstructuras de datos
Um dropdown por estrutura, aninhados pela hierarquia. Cada tabela tem uma coluna por camada — Proto · DTO · Model · Entity; o texto accent marca onde o tipo primeiro muda (enum na Entity, parse de data no Model, relação ToMany no Model, rename no Proto).One dropdown per structure, nested by hierarchy. Each table has one column per layer — Proto · DTO · Model · Entity; the accent text marks where the type first changes (enum in the Entity, date parse in the Model, ToMany relation in the Model, rename in the Proto).Un dropdown por estructura, anidados por jerarquía. Cada tabla tiene una columna por capa — Proto · DTO · Model · Entity; el texto accent marca dónde primero cambia el tipo (enum en la Entity, parse de fecha en el Model, relación ToMany en el Model, rename en el Proto).
BuybackCollection raiz 2 campos2 fields2 campos
Campo Proto DTO Model Entity lastSyncAt— DateTimeDateTime DateTime accountsrepeated BuybackAccount buybackCollectionList<…DTO> ToMany<…Model>List<…Entity> BuybackAccount BuybackCollection.accounts[] 2 campos2 fields2 campos
Campo Proto DTO Model Entity accountSfidstring String String String buybacksrepeated Buyback List<…DTO> ToMany<…Model>List<…Entity> Buyback BuybackAccount.buybacks[] 9 campos9 fields9 campos
Campo Proto DTO Model Entity sfidstring String String String namestring String String String statusstring String String BuybackStatusupliftDatestring String DateTime?DateTime? totalItemsQuantitydouble double double double canAcceptbool bool bool bool canRejectbool bool bool bool canReschedulebool bool bool bool itemsrepeated BuybackItem List<…DTO> ToMany<…Model>List<…Entity> BuybackItem Buyback.items[] 3 campos3 fields3 campos
Campo Proto DTO Model Entity productNamestring String String String uomstring String String String quantitydouble double double double
Mappers
As conversões entre as camadas, todas como extension (5 direções por tipo). Aqui o método DTO→Entity e Model→Entity chama-se toEntity() (não toDomain):The conversions between layers, all as extensions (5 directions per type). Here the DTO→Entity and Model→Entity method is toEntity() (not toDomain):Las conversiones entre capas, todas como extension (5 direcciones por tipo). Aquí el método DTO→Entity y Model→Entity se llama toEntity() (no toDomain):
| DireçãoDirectionDirección | MétodoMethodMétodo |
|---|---|
| JSON → DTO | static fromMap(Map) |
| Proto → DTO | toDTO() |
| DTO → Entity | toEntity() (resolve status via BuybackStatus.fromString; parseia upliftDate)(resolves status via BuybackStatus.fromString; parses upliftDate)(resuelve status vía BuybackStatus.fromString; parsea upliftDate) |
| Entity → Model | toModel() (status.value; popula ToMany)(status.value; fills ToMany)(status.value; llena ToMany) |
| Model → Entity | toEntity() |
Os únicos deltasThe only deltasLos únicos deltas
statusString→BuybackStatussó na Entity (viaBuybackStatus.fromString)only in the Entity (viaBuybackStatus.fromString)solo en la Entity (víaBuybackStatus.fromString)upliftDateString→DateTime?no Model (viaDateTimeUtils.tryParse)in the Model (viaDateTimeUtils.tryParse)en el Model (víaDateTimeUtils.tryParse)- rename do protoproto renamerename del proto
buybackCollection→accounts - relações (
accounts,buybacks,items) viramToManyno Modelrelations (accounts,buybacks,items) becomeToManyin the Modelrelaciones (accounts,buybacks,items) pasan aToManyen el Model lastSyncAtgerado no mapper comDateTimeUtils.now()(não vem do proto)generated in the mapper withDateTimeUtils.now()(not from the proto)generado en el mapper conDateTimeUtils.now()(no viene del proto)
Repository
BuybackCollectionRepositoryImpl implementaimplementsimplementa BuybackCollectionRepositoryInterface e injeta os 3 datasources (mock/local/remote) + ConnectivityService + a flag useMock + Ref. É só do lado de leitura — a escrita vive no Dispatcher. Método a método:and injects the 3 datasources (mock/local/remote) + ConnectivityService + the useMock flag + Ref. It's read-only — writes live in the Dispatcher. Method by method:e inyecta los 3 datasources (mock/local/remote) + ConnectivityService + la flag useMock + Ref. Es solo del lado de lectura — la escritura vive en el Dispatcher. Método a método:
getBuybackCollection({source}) mock / local / remote
RetornaReturnsDevuelve Result<BuybackCollectionEntity, Failure>
Ponto de entrada. Decide a fonte e mapeia com write-through:Entry point. Picks the source and maps with write-through:Punto de entrada. Elige la fuente y mapea con write-through:
useMock== true ouorosource == mock→_fetchFromMock(): lê o mock, mapeia, grava no cache.→_fetchFromMock(): reads the mock, maps, writes to cache.→_fetchFromMock(): lee el mock, mapea, graba en caché.source == localou offlineor offlineu offline→_fetchFromCacheOrFail(): cache; se vazio →Error(NetworkFailure).→_fetchFromCacheOrFail(): cache; if empty →Error(NetworkFailure).→_fetchFromCacheOrFail(): caché; si vacío →Error(NetworkFailure).- senão (remoto + conectado)otherwise (remote + connected)si no (remoto + conectado)→
_fetchFromRemoteWithFallback(): lêcurrentResourceProvider;nullcai pro cache; senão chama o remoto comlocationHierarchyId, mapeia, grava; em erro, fallback pro cache.→_fetchFromRemoteWithFallback(): readscurrentResourceProvider;nullfalls back to cache; else calls remote withlocationHierarchyId, maps, writes; on error, falls back to cache.→_fetchFromRemoteWithFallback(): leecurrentResourceProvider;nullcae al caché; si no llama al remoto conlocationHierarchyId, mapea, graba; en error, fallback al caché.
getCachedBuybackCollection() local
RetornaReturnsDevuelve Result<BuybackCollectionEntity?, Failure>
Só cache; null vira Success(null), não erro.Cache only; null becomes Success(null), not an error.Solo caché; null es Success(null), no error.
getCachedBuybackAccountBySfid({accountSfid}) local
RetornaReturnsDevuelve Result<BuybackAccountEntity?, Failure>
Lê o cache e filtra a conta pelo accountSfid (via accountFor). Cache-only (§28 cat. A).Reads cache and filters the account by accountSfid (via accountFor). Cache-only (§28 cat. A).Lee el caché y filtra la cuenta por accountSfid (vía accountFor). Cache-only (§28 cat. A).
getCachedBuybackCollectionLastSyncAt() local
RetornaReturnsDevuelve DateTime? (sem Result)(no Result)(sin Result)
Timestamp da última sincronização do container, para o DataLoadInfo.The container's last-sync timestamp, for DataLoadInfo.Timestamp de última sincronización del container, para DataLoadInfo.
saveBuybackCollection({entity}) local
RetornaReturnsDevuelve Result<void, Failure>
Destrutivo: clearBuybackCollection() + _box.put(entity.toModel()) (cascata de boxes filhas). Cache-writer após cada fetch bem-sucedido.Destructive: clearBuybackCollection() + _box.put(entity.toModel()) (child boxes cascade). Cache-writer after each successful fetch.Destructivo: clearBuybackCollection() + _box.put(entity.toModel()) (cascada de boxes hijas). Cache-writer tras cada fetch exitoso.
updateCachedBuyback({buyback}) atualização otimistaoptimistic updateactualización optimista
RetornaReturnsDevuelve Result<void, Failure>
Após uma execução (aceitar/rejeitar/reagendar) bem-sucedida, substitui a recompra no cache pela versão atualizada (_replaceBuyback) e regrava a coleção. É o que mantém a tela coerente sem novo fetch remoto.After a successful execution (accept/reject/reschedule), it replaces the buyback in the cache with the updated version (_replaceBuyback) and re-saves the collection. This keeps the screen consistent without a new remote fetch.Tras una ejecución (aceptar/rechazar/reprogramar) exitosa, reemplaza la recompra en el caché por la versión actualizada (_replaceBuyback) y regraba la colección. Es lo que mantiene la pantalla coherente sin un nuevo fetch remoto.
Datasources
Um card por datasource (dropdown). No corpo: método, envio, retorno, fluxo de uso e tratamento de erro.One card per datasource (dropdown). In the body: method, what it sends, return, usage flow and error handling.Un card por datasource (dropdown). En el cuerpo: método, envío, retorno, flujo de uso y manejo de errores.
Remote BuybackCollectionRemoteDataSource gRPC
getBuybackCollection({locationHierarchySfid, lastModifiedDate?})
- EnvioSendsEnvío
- monta
BuybackCollectionRequeste chama_client.getBuybackCollection(request)(BuybackCollectionConectaRepServiceClient, viabuybackCollectionServiceClientProvider).buildsBuybackCollectionRequestand calls_client.getBuybackCollection(request)(BuybackCollectionConectaRepServiceClient, viabuybackCollectionServiceClientProvider).armaBuybackCollectionRequesty llama_client.getBuybackCollection(request)(BuybackCollectionConectaRepServiceClient, víabuybackCollectionServiceClientProvider). - RetornoReturnRetorno
BuybackCollectionDTO(viaresponse.toDTO())(viaresponse.toDTO())(víaresponse.toDTO())- Fluxo de usoUsage flowFlujo de uso
- chamado pelo caminho remoto do repository quando online e sem mock; o resultado é gravado no cache.called by the repository's remote path when online and not mocking; the result is written to cache.llamado por el camino remoto del repository online y sin mock; el resultado se graba en caché.
- Tratamento de erroError handlingManejo de errores
GrpcError→GrpcExceptionHandler; outros →ServerException. Em erro, o repository faz fallback pro cache.GrpcError→GrpcExceptionHandler; others →ServerException. On error, the repository falls back to cache.GrpcError→GrpcExceptionHandler; otros →ServerException. En error, el repository hace fallback al caché.
Local BuybackCollectionLocalDataSource ObjectBox
Envio / fluxo: persistência local via ObjectBox, box raiz BuybackCollectionModel (+ BuybackAccountModel, BuybackModel, BuybackItemModel) — sem rede. Erro: falhas de persistência propagam como CacheException.Sends / flow: local persistence via ObjectBox, root box BuybackCollectionModel (+ BuybackAccountModel, BuybackModel, BuybackItemModel) — no network. Error: persistence failures propagate as CacheException.Envío / flujo: persistencia local vía ObjectBox, box raíz BuybackCollectionModel (+ BuybackAccountModel, BuybackModel, BuybackItemModel) — sin red. Error: fallos de persistencia propagan como CacheException.
getBuybackCollection()
- RetornoReturnRetorno
BuybackCollectionEntity?- ComportamentoBehaviorComportamiento
models.first.toEntity()— o agregado único, ounullse o cache está vazio.models.first.toEntity()— the single aggregate, ornullif the cache is empty.models.first.toEntity()— el agregado único, onullsi el caché está vacío.
getBuybackCollectionLastSyncAt()
- RetornoReturnRetorno
DateTime?- ComportamentoBehaviorComportamiento
models.first.lastSyncAt
saveBuybackCollection({entity})
- RetornoReturnRetorno
void- ComportamentoBehaviorComportamiento
- destrutivo:
clearBuybackCollection()+_box.put(entity.toModel()).destructive:clearBuybackCollection()+_box.put(entity.toModel()).destructivo:clearBuybackCollection()+_box.put(entity.toModel()).
clearBuybackCollection()
- RetornoReturnRetorno
void- ComportamentoBehaviorComportamiento
- limpa as boxes na ordem filhas→raiz (item → buyback → account → collection).clears the boxes children→root (item → buyback → account → collection).limpia las boxes hijas→raíz (item → buyback → account → collection).
Mock BuybackCollectionMockDataSource JSON
getBuybackCollection()
- EnvioSendsEnvío
- carrega o asset JSON
buyback_collection/buyback_collection(por mercado, real vs sintético viauseRealMockData) — sem rede.loads the JSON assetbuyback_collection/buyback_collection(per market, real vs synthetic viauseRealMockData) — no network.carga el asset JSONbuyback_collection/buyback_collection(por mercado, real vs sintético víauseRealMockData) — sin red. - RetornoReturnRetorno
BuybackCollectionDTO(viaBuybackCollectionDTOJsonMapper.fromMap)(viaBuybackCollectionDTOJsonMapper.fromMap)(víaBuybackCollectionDTOJsonMapper.fromMap)- Fluxo de usoUsage flowFlujo de uso
- usado quando
useMockestá ligado ousource == mock; grava no cache como um fetch normal.used whenuseMockis on orsource == mock; writes to cache like a normal fetch.usado cuandouseMockestá activo osource == mock; graba en caché como un fetch normal. - Tratamento de erroError handlingManejo de errores
- asset ausente ou JSON inválido propaga como
CacheException.missing asset or invalid JSON propagates asCacheException.asset ausente o JSON inválido propaga comoCacheException.
Escrita não tem datasourceWrite has no datasourceLa escritura no tiene datasource
Solicitação e execução não passam por estes datasources — vão pelo DispatcherOrchestrator (store + tracking + reenvio idempotente), que serializa o JSON e chama o RPC genérico sendTransaction.
Request and execution do not go through these datasources — they go via the DispatcherOrchestrator (store + tracking + idempotent retry), which serializes the JSON and calls the generic sendTransaction RPC.
Solicitud y ejecución no pasan por estos datasources — van vía el DispatcherOrchestrator (store + tracking + reenvío idempotente), que serializa el JSON y llama al RPC genérico sendTransaction.
Enums e labelsEnums & labelsEnums y labels
O status só existe tipado na Entity; em DTO/Model/Proto trafega como String. Lista completa de valores:The status is only typed in the Entity; in DTO/Model/Proto it travels as String. Full value list:El status solo está tipado en la Entity; en DTO/Model/Proto viaja como String. Lista completa de valores:
BuybackStatus 6 valores6 values6 valores
| case | value | cor / usocolor / usecolor / uso |
|---|---|---|
readyToReceive | "ready_to_receive" | onSurfaceTertiary · à esperawaitingen espera |
accepted | "accepted" | success |
rejected | "rejected" | error |
rescheduled | "rescheduled" | onSurfaceTertiary · à esperawaitingen espera |
rescheduledToday | "rescheduled_today" | warning |
unknown | "unknown" | onSurfaceTertiary · sem labelno labelsin label |
fromString normaliza e ainda mapeia tokens do backend: "confirmed by sap" → accepted, "rejected by sap" → rejected.fromString normalizes and also maps backend tokens: "confirmed by sap" → accepted, "rejected by sap" → rejected.fromString normaliza y además mapea tokens del backend: "confirmed by sap" → accepted, "rejected by sap" → rejected.
BuybackCollectionTab 4 · agrupam por status4 · group by status4 · agrupan por estado
| case | aceita statusaccepts statusesacepta estados |
|---|---|
all | todosalltodos |
open | readyToReceive · rescheduled |
executed | accepted · rejected |
rescheduled | rescheduledToday |
BuybackAction 3 · writeStatus3 · writeStatus3 · writeStatus
| case | writeStatus |
|---|---|
accept | "F" |
reject | "R" |
reschedule | "RS" |
BuybackRequestField 5 · campos do header por mercado (EMC)5 · header fields per market (EMC)5 · campos del header por mercado (EMC)
| case | value |
|---|---|
creditLimit | "creditLimit" |
ctLovId | "ctLovId" |
conversionMethod | "conversionMethod" |
returnGrantedPercentage | "returnGrantedPercentage" |
approvalStatus | "approvalStatus" |
A lista habilitada por mercado vem do buybackRequestConfig.fields do EMC — decide quais campos do SalesReturnHeader são preenchidos (o resto vai "").The per-market enabled list comes from the EMC's buybackRequestConfig.fields — it decides which SalesReturnHeader fields are filled (the rest go "").La lista habilitada por mercado viene del buybackRequestConfig.fields del EMC — decide qué campos del SalesReturnHeader se llenan (el resto va "").
UseCases
Um dropdown por UseCase. Os de leitura delegam ao repository; os de escrita seguem o padrão Dispatcher (§36): um builder puro que monta o DispatcherEnvelope a partir de um {X}DispatcherPayloadInput cru, e um submit que despacha pelo orchestrator.One dropdown per UseCase. Read ones delegate to the repository; write ones follow the Dispatcher pattern (§36): a pure builder that assembles the DispatcherEnvelope from a raw {X}DispatcherPayloadInput, and a submit that dispatches via the orchestrator.Un dropdown por UseCase. Los de lectura delegan al repository; los de escritura siguen el patrón Dispatcher (§36): un builder puro que arma el DispatcherEnvelope desde un {X}DispatcherPayloadInput crudo, y un submit que despacha vía el orchestrator.
GetBuybackCollectionUseCase 5 · a coleçãothe collectionla colección
| MétodoMethodMétodo | RetornaReturnsDevuelve | UsoUseUso |
|---|---|---|
execute({source}) | Result<BuybackCollectionEntity, Failure> | Ponto de entrada → repository.getBuybackCollection.Entry point → repository.getBuybackCollection.Punto de entrada → repository.getBuybackCollection. |
getCached() | Result<BuybackCollectionEntity?, Failure> | Só cache; null vira Success(null).Cache only; null becomes Success(null).Solo caché; null es Success(null). |
getCachedByAccountSfid({accountSfid}) | Result<BuybackAccountEntity?, Failure> | Conta do cache pelo sfid (§28 cat. A).Account from cache by sfid (§28 cat. A).Cuenta del caché por sfid (§28 cat. A). |
getCachedLastSyncAt() | DateTime? | Alimenta o DataLoadInfo.Feeds DataLoadInfo.Alimenta DataLoadInfo. |
updateCachedBuyback({buyback}) | Result<void, Failure> | Atualização otimista do cache após execução.Optimistic cache update after execution.Actualización optimista del caché tras ejecución. |
GetProductsForBuybackUseCase 1 · catálogo compartilhadoshared catalogcatálogo compartido
| MétodoMethodMétodo | RetornaReturnsDevuelve | UsoUseUso |
|---|---|---|
execute({source}) | Result<ProductCatalogEntity, Failure> | Catálogo filtrado por eligibility.isAvailableForBuyback (§29 — Repository neutro, um UseCase por consumidor).Catalog filtered by eligibility.isAvailableForBuyback (§29 — neutral Repository, one UseCase per consumer).Catálogo filtrado por eligibility.isAvailableForBuyback (§29 — Repository neutral, un UseCase por consumidor). |
GetBuybackReasonsUseCase 1 · reference_data
| MétodoMethodMétodo | RetornaReturnsDevuelve | UsoUseUso |
|---|---|---|
execute({source}) | Result<List<BuybackReasonEntity>, Failure> | Motivos (code + reason) do ReferenceData.buybackReasons — dropdown do resumo.Reasons (code + reason) from ReferenceData.buybackReasons — summary dropdown.Motivos (code + reason) de ReferenceData.buybackReasons — dropdown del resumen. |
GetBuybackDataUseCase 1 · reference_data
| MétodoMethodMétodo | RetornaReturnsDevuelve | UsoUseUso |
|---|---|---|
execute({source}) | Result<BuybackDataEntity, Failure> | limit + isSENApprovalActive do ReferenceData.moduleMaster.buybackData — decide o approvalStatus do header (Pending Approval quando o valor de retorno ≥ limite).limit + isSENApprovalActive from ReferenceData.moduleMaster.buybackData — decides the header's approvalStatus (Pending Approval when return value ≥ limit).limit + isSENApprovalActive de ReferenceData.moduleMaster.buybackData — decide el approvalStatus del header (Pending Approval cuando el valor de retorno ≥ límite). |
BuildBuybackRequestDispatcherPayloadUseCase builder · SalesReturnSENbuilder · SalesReturnSENbuilder · SalesReturnSEN
AssinaturaSignatureFirma build({BuybackRequestDispatcherPayloadInput input}) → DispatcherEnvelope
Monta o JSON { SalesReturnHeader[1], SalesReturnDetails[] } a partir do input cru. O header pega uid = PO, ResId (primary/secondary derivado no build), RetailerId, date_x/upliftDate (yyyy/MM/dd), ReturnValue e os campos condicionais por BuybackRequestField do EMC (CreditLimit, CTLovId, conversionMethod, returnGrantedPercentage, approvalStatus). Cada detalhe deriva UoM/quantidade via ProductUomUtils.splitHalfPack quando o mercado usa UoM secundária. Type DispatcherType.buybackRequest · serviceName SalesReturnSEN.Builds the JSON { SalesReturnHeader[1], SalesReturnDetails[] } from the raw input. The header takes uid = PO, ResId (primary/secondary derived in build), RetailerId, date_x/upliftDate (yyyy/MM/dd), ReturnValue and the conditional fields per EMC BuybackRequestField (CreditLimit, CTLovId, conversionMethod, returnGrantedPercentage, approvalStatus). Each detail derives UoM/quantity via ProductUomUtils.splitHalfPack when the market uses secondary UoM. Type DispatcherType.buybackRequest · serviceName SalesReturnSEN.Arma el JSON { SalesReturnHeader[1], SalesReturnDetails[] } desde el input crudo. El header toma uid = PO, ResId (primary/secondary derivado en build), RetailerId, date_x/upliftDate (yyyy/MM/dd), ReturnValue y los campos condicionales por BuybackRequestField del EMC (CreditLimit, CTLovId, conversionMethod, returnGrantedPercentage, approvalStatus). Cada detalle deriva UoM/cantidad vía ProductUomUtils.splitHalfPack cuando el mercado usa UoM secundaria. Type DispatcherType.buybackRequest · serviceName SalesReturnSEN.
BuildBuybackExecutionDispatcherPayloadUseCase builder · SalesReturnUpliftbuilder · SalesReturnUpliftbuilder · SalesReturnUplift
AssinaturaSignatureFirma build({BuybackExecutionDispatcherPayloadInput input}) → DispatcherEnvelope
Monta { UpliftReturnHeader[1] } com SalesreturnID = buyback.sfid, status = action.writeStatus (F/R/RS). No reagendamento (RS) preenche rescheduledTerritory (locationHierarchyId) e rescheduledUpliftDate (yyyy-MM-dd); os demais campos vão "". Type DispatcherType.buybackExecution · serviceName SalesReturnUplift.Builds { UpliftReturnHeader[1] } with SalesreturnID = buyback.sfid, status = action.writeStatus (F/R/RS). On reschedule (RS) it fills rescheduledTerritory (locationHierarchyId) and rescheduledUpliftDate (yyyy-MM-dd); the rest go "". Type DispatcherType.buybackExecution · serviceName SalesReturnUplift.Arma { UpliftReturnHeader[1] } con SalesreturnID = buyback.sfid, status = action.writeStatus (F/R/RS). En reprogramación (RS) llena rescheduledTerritory (locationHierarchyId) y rescheduledUpliftDate (yyyy-MM-dd); el resto va "". Type DispatcherType.buybackExecution · serviceName SalesReturnUplift.
SubmitBuybackRequestUseCase / SubmitBuybackExecutionUseCase submit
MétodoMethodMétodo submit({DispatcherEnvelope envelope}) → Future<Result<DispatcherAck, Failure>>
Finos: delegam ao DispatcherOrchestrator.dispatch(envelope:). Um por transação (request / execution).Thin: they delegate to DispatcherOrchestrator.dispatch(envelope:). One per transaction (request / execution).Finos: delegan a DispatcherOrchestrator.dispatch(envelope:). Uno por transacción (request / execution).
Notifiers & State
A feature tem quatro Notifiers de page — um por tela — mais um Provider cross-page que guarda o rascunho da solicitação (§33). Todos recebem só o visitSfid e re-buscam via UseCases; o contexto da visita vem do visitContextProvider.The feature has four page Notifiers — one per screen — plus a cross-page Provider holding the request draft (§33). All take only the visitSfid and re-fetch via UseCases; the visit context comes from visitContextProvider.La feature tiene cuatro Notifiers de page — uno por pantalla — más un Provider cross-page que guarda el borrador de la solicitud (§33). Todos reciben solo el visitSfid y re-buscan vía UseCases; el contexto de la visita viene de visitContextProvider.
NotifiersNotifiersNotifiers
BuybackMenuNotifier BuybackMenuState
build({visitSfid}) → _load(): monta account (do visit.accountData) + lastSyncAt (cache). refresh() dispara execute(remote) e recarrega. Só apresenta o menu.build({visitSfid}) → _load(): assembles account (from visit.accountData) + lastSyncAt (cache). refresh() triggers execute(remote) and reloads. Just presents the menu.build({visitSfid}) → _load(): arma account (de visit.accountData) + lastSyncAt (caché). refresh() dispara execute(remote) y recarga. Solo presenta el menú.
BuybackRequestPageNotifier BuybackRequestPageState
_load(): catálogo (GetProductsForBuyback) + categorias (EMC orderCreationConfig.categoryTabs) + lastSyncAt. Métodos: setActiveCategory, setBrandFilter, setSearchQuery, loadMore() (paginação visual de 20). Filtro/busca/paginação são getters do State._load(): catalog (GetProductsForBuyback) + categories (EMC orderCreationConfig.categoryTabs) + lastSyncAt. Methods: setActiveCategory, setBrandFilter, setSearchQuery, loadMore() (visual pagination of 20). Filter/search/pagination are State getters._load(): catálogo (GetProductsForBuyback) + categorías (EMC orderCreationConfig.categoryTabs) + lastSyncAt. Métodos: setActiveCategory, setBrandFilter, setSearchQuery, loadMore() (paginación visual de 20). Filtro/búsqueda/paginación son getters del State.
BuybackRequestSummaryNotifier BuybackRequestSummaryState · submit()
_load(): catálogo + motivos + categorias + lastSyncAt. submit() valida o rascunho (não vazio, data e motivo), monta as BuybackRequestLineInput, resolve resource + buybackData + EMC, gera o PO (OrderIdentifierUtils), chama o builder e o submit; em sucesso limpa o rascunho. Retorna Failure?._load(): catalog + reasons + categories + lastSyncAt. submit() validates the draft (non-empty, date and reason), builds the BuybackRequestLineInputs, resolves resource + buybackData + EMC, generates the PO (OrderIdentifierUtils), calls the builder and submit; on success clears the draft. Returns Failure?._load(): catálogo + motivos + categorías + lastSyncAt. submit() valida el borrador (no vacío, fecha y motivo), arma los BuybackRequestLineInput, resuelve resource + buybackData + EMC, genera el PO (OrderIdentifierUtils), llama al builder y al submit; en éxito limpia el borrador. Devuelve Failure?.
BuybackCollectionNotifier BuybackCollectionState · execução
_load(): recompras da conta ativa (value.accountFor). refresh({source}) preserva tab e seleção. selectTab, toggleSelection (só selecionáveis). acceptSelected()/rejectSelected()/rescheduleBuyback(...) chamam _runAction: resolve resource, monta o input, chama builder + submit; em sucesso computa o _nextBuyback (novo status, flags can* zeradas) e faz update otimista do cache + do State._load(): buybacks of the active account (value.accountFor). refresh({source}) preserves tab and selection. selectTab, toggleSelection (selectable only). acceptSelected()/rejectSelected()/rescheduleBuyback(...) call _runAction: resolves resource, builds the input, calls builder + submit; on success computes _nextBuyback (new status, can* flags cleared) and does an optimistic update of cache + State._load(): recompras de la cuenta activa (value.accountFor). refresh({source}) preserva pestaña y selección. selectTab, toggleSelection (solo seleccionables). acceptSelected()/rejectSelected()/rescheduleBuyback(...) llaman _runAction: resuelve resource, arma el input, llama builder + submit; en éxito computa _nextBuyback (nuevo estado, flags can* en cero) y hace update optimista del caché + del State.
BuybackRequest Provider cross-page · rascunhocross-page Provider · draftProvider cross-page · borrador
@Riverpod(keepAlive) por accountSfid. Guarda o BuybackRequestDraftEntity (quantities por produto, collectionDate, reasonCode) e sobrevive à navegação Solicitação → Resumo. Métodos: setQuantity/increment/decrement/removeProduct, setCollectionDate, setReasonCode, clear().@Riverpod(keepAlive) keyed by accountSfid. Holds the BuybackRequestDraftEntity (quantities per product, collectionDate, reasonCode) and survives the Request → Summary navigation. Methods: setQuantity/increment/decrement/removeProduct, setCollectionDate, setReasonCode, clear().@Riverpod(keepAlive) por accountSfid. Guarda el BuybackRequestDraftEntity (quantities por producto, collectionDate, reasonCode) y sobrevive a la navegación Solicitud → Resumen. Métodos: setQuantity/increment/decrement/removeProduct, setCollectionDate, setReasonCode, clear().
State disponível para as PagesState available to the PagesState disponible para las Pages
Campos por State 4 states + draft4 states + draft4 states + draft
| State | campos principaismain fieldscampos principales | getters |
|---|---|---|
BuybackMenuState | account, lastSyncAt? | — |
BuybackRequestPageState | accountSfid, account, lastSyncAt?, categories, products, activeCategoryRoute, brandFilter, searchQuery, visibleCount | brandOptions, filteredProducts, visibleProducts, totalFilteredProducts, hasMoreToLoad |
BuybackRequestSummaryState | accountSfid, account, lastSyncAt?, products, categories, reasons, visibleCount | productFor, reasonForCode |
BuybackCollectionState | account, buybacks, lastSyncAt?, selectedTab, selectedBuybackSfid? | buybacksForTab, selectedBuyback, hasSelection |
BuybackRequestDraftEntity | accountSfid, quantities, collectionDate?, reasonCode | quantityFor, isEmpty, itemCount, totalQuantity |
Pages e widgetsPages & widgetsPages y widgets
Quatro pages, todas ConsumerWidget sobre AppPageShell (com displayBackButton), com loading/erro globais via asyncState.when. Árvores de composição (modais aninhados sob quem os abre):Four pages, all ConsumerWidget over AppPageShell (with displayBackButton), with global loading/error via asyncState.when. Composition trees (modals nested under what opens them):Cuatro pages, todas ConsumerWidget sobre AppPageShell (con displayBackButton), con loading/error globales vía asyncState.when. Árboles de composición (modales anidados bajo quien los abre):
BuybackMenuPage
- BuybackMenuPage
- AppPageShell back button · data → CustomPullToRefresh
- CustomLoadingIndicator loading
- FailureStateView error → invalidate
- DataLoadInfo lastSyncAt
- AccountHeaderCard
- BuybackMenuHeaderWidget
- BuybackMenuActionsWidget MenuActionGrid
- Solicitar → goToBuybackRequest
- Coleta → goToBuybackCollection
- AppPageShell back button · data → CustomPullToRefresh
BuybackRequestPage → BuybackRequestSummaryPage
- BuybackRequestPage
- AppPageShell
- DataLoadInfo · AccountHeaderCard · BuybackRequestHeaderWidget
- BuybackRequestCategoriesWidget abas → setActiveCategory
- BuybackRequestFiltersWidget marca + busca → setBrandFilter / setSearchQuery
- BuybackRequestProductsSectionWidget
- BuybackRequestProductCard
- BuybackRequestQuantityControl → BuybackRequest.setQuantity
- BuybackRequestProductCard
- BuybackRequestFooterWidget CustomSummaryBar (itens + total) → goToBuybackRequestSummary
- BuybackRequestSummaryTableWidget conteúdo expandido
- AppPageShell
- BuybackRequestSummaryPage
- AppPageShell
- DataLoadInfo · AccountHeaderCard · BuybackRequestSummaryHeaderWidget
- BuybackRequestSummaryProductsWidget itens do rascunho
- BuybackRequestSummaryFooterWidget quantidades/categoria · data · motivo · Confirmar
- CustomCalendarModalContent modal · data de coleta → setCollectionDate
- CustomDropdown<BuybackReasonEntity> → setReasonCode
- BuybackRequestConfirmModalContent modal · confirma → submit() → SalesReturnSEN
- AppPageShell
BuybackCollectionPage
- BuybackCollectionPage
- AppPageShell back button · no drawer
- NestedScrollView
- DataLoadInfo · AccountHeaderCard · BuybackCollectionTitleRow
- BuybackCollectionTabBarWidget all/open/executed/rescheduled → selectTab
- BuybackCollectionColumnHeaderWidget
- TabBarView → _BuybackListSection
- CustomEmptyState tab vazia
- BuybackCollectionCardWidget expansível (itens) · CustomRadio → toggleSelection
- SwipeToRevealReschedule canReschedule → CustomCalendarModalContent → rescheduleBuyback → SalesReturnUplift (RS)
- BuybackCollectionActionButtonsWidget Rejeitar / Aceitar (enable = hasSelection)
- BuybackExecutionConfirmModalContent modal · confirma → accept/rejectSelected → SalesReturnUplift (F/R)
- NestedScrollView
- AppPageShell back button · no drawer
Notas por mercadoMarket notesNotas por mercado
A recompra é dirigida pelas transações do Dispatcher (DispatcherType.buybackRequest/buybackExecution), habilitadas em BR e CL. A ZA tem o bloco buybackRequestConfig no EMC, mas as transações SalesReturn não estão habilitadas lá — logo não é possível enviar. AR/PY/PE não têm configuração de recompra.Buyback is driven by the Dispatcher transactions (DispatcherType.buybackRequest/buybackExecution), enabled in BR and CL. ZA has the buybackRequestConfig block in the EMC, but the SalesReturn transactions aren't enabled there — so it can't submit. AR/PY/PE have no buyback config.La recompra se rige por las transacciones del Dispatcher (DispatcherType.buybackRequest/buybackExecution), habilitadas en BR y CL. ZA tiene el bloque buybackRequestConfig en el EMC, pero las transacciones SalesReturn no están habilitadas ahí — por lo que no puede enviar. AR/PY/PE no tienen configuración de recompra.
BrasilBrazilBrasil
Header do SalesReturnSEN preenche só CreditLimit (buybackRequestConfig.fields = ["creditLimit"]); usesSecondaryUomForAllCategories = false.
SalesReturnSEN header fills only CreditLimit (buybackRequestConfig.fields = ["creditLimit"]); usesSecondaryUomForAllCategories = false.
El header de SalesReturnSEN llena solo CreditLimit (buybackRequestConfig.fields = ["creditLimit"]); usesSecondaryUomForAllCategories = false.
ChileChileChile
Preenche os cinco campos (creditLimit, ctLovId, conversionMethod, returnGrantedPercentage, approvalStatus) — inclui o gate de aprovação SEN (approvalStatus = "Pending Approval" quando o valor de retorno ≥ limite). usesSecondaryUomForAllCategories = false.
Fills all five fields (creditLimit, ctLovId, conversionMethod, returnGrantedPercentage, approvalStatus) — includes the SEN approval gate (approvalStatus = "Pending Approval" when return value ≥ limit). usesSecondaryUomForAllCategories = false.
Llena los cinco campos (creditLimit, ctLovId, conversionMethod, returnGrantedPercentage, approvalStatus) — incluye el gate de aprobación SEN (approvalStatus = "Pending Approval" cuando el valor de retorno ≥ límite). usesSecondaryUomForAllCategories = false.
África do SulSouth AfricaSudáfrica
Tem buybackRequestConfig (fields = [], usesSecondaryUomForAllCategories = true), mas as transações SalesReturn não estão em enabledMarkets — a recompra não é enviável em ZA hoje.
Has buybackRequestConfig (fields = [], usesSecondaryUomForAllCategories = true), but the SalesReturn transactions are not in enabledMarkets — buyback can't be submitted in ZA today.
Tiene buybackRequestConfig (fields = [], usesSecondaryUomForAllCategories = true), pero las transacciones SalesReturn no están en enabledMarkets — la recompra no es enviable en ZA hoy.
Pendências / roadmapPending / roadmapPendientes / roadmap
Estado atual do código: (a) lastModifiedDate existe no request mas não é enviado (sem sync incremental); (b) a paginação da solicitação é apenas visual (todos os produtos já estão em memória); (c) o update pós-execução é otimista — reflete o novo status local sem re-fetch remoto; (d) ZA tem config mas transação desabilitada (acima).
Current code state: (a) lastModifiedDate exists in the request but is not sent (no incremental sync); (b) request pagination is visual-only (all products are already in memory); (c) the post-execution update is optimistic — it reflects the new local status without a remote re-fetch; (d) ZA has config but a disabled transaction (above).
Estado actual del código: (a) lastModifiedDate existe en el request pero no se envía (sin sync incremental); (b) la paginación de la solicitud es solo visual (todos los productos ya están en memoria); (c) la actualización post-ejecución es optimista — refleja el nuevo estado local sin re-fetch remoto; (d) ZA tiene config pero transacción deshabilitada (arriba).