5) Retirada de Produtos

Este fluxo registra o recebimento de produtos pelo produtor. O produtor poderá confirmar toda a entrega através do QR Code da entrega gerado pela UTG ou, opcionalmente, realizar a conferência individual das embalagens antes de confirmar o recebimento. Todo o processo continua seguindo o padrão offline-first.

Auth: X-APP-KEY + X-DEVICE-TOKEN Offline-first QR Code ou código de barras Obrigatório: client_event_id Envio: sincronizacao_offline

Objetivo deste fluxo

Registrar que o produtor recebeu os produtos separados pela UTG. O recebimento poderá ser realizado de forma rápida, pela leitura do QR Code da entrega, ou por conferência individual das embalagens antes da confirmação.

O QR Code da entrega é gerado pelo aplicativo da UTG. Os QR Codes individuais das embalagens continuam sendo utilizados quando o produtor optar pela conferência detalhada.

Atualização — 01/09/2026

O recebimento de produtos pelo produtor passa a possuir duas formas de confirmação.

1) Recebimento rápido pelo QR Code da entrega

O produtor poderá optar por confirmar toda a entrega através de um único QR Code gerado pelo aplicativo da UTG.

  1. O produtor seleciona a opção de recebimento rápido.
  2. O aplicativo abre a câmera.
  3. O produtor lê o QR Code da entrega apresentado pela UTG.
  4. O aplicativo registra a confirmação no SQLite.
  5. Havendo internet, tenta sincronizar imediatamente.
  6. Sem internet, mantém o evento pendente para sincronização posterior.

Neste modo, o produtor assume que os produtos separados pela UTG estão corretos e não precisa conferir as embalagens individualmente.

2) Recebimento com conferência dos produtos

O produtor também poderá optar por conferir individualmente os produtos antes de confirmar o recebimento.

Para permitir a conferência inclusive sem internet, a sincronização deverá disponibilizar previamente ao aplicativo o manifesto da entrega pendente, contendo os QR Codes individuais pertencentes ao produtor.

Durante a conferência:

  • Verde: QR Code pertence ao produtor e ainda não havia sido lido. Registrar o produto como conferido.
  • Vermelho: QR Code não pertence àquela entrega ou ao produtor. Exibir a mensagem "Produto não pertence a você" e não registrar a leitura.
  • Laranja: QR Code já foi lido anteriormente na mesma conferência. Exibir a mensagem "Produto já foi lido" e não contabilizar novamente.

A tela deverá manter os totais de produtos esperados, produtos conferidos e produtos ainda faltantes.

Exemplo:

Esperados: 10
Conferidos: 8
Faltam: 2

Caso o produtor tente encerrar a conferência antes de ler todos os produtos, o aplicativo deverá avisar quantos produtos ainda estão faltando.

A conferência ainda está incompleta.

Faltam 2 produtos.

Deseja continuar conferindo?

Quando todos os produtos forem conferidos, o aplicativo poderá finalizar normalmente o recebimento da entrega.

Regras comuns aos dois modos

  • O funcionamento continua sendo offline-first.
  • Toda ação deve ser salva primeiro no SQLite.
  • O ERP continua sendo a fonte oficial dos dados.
  • A conferência individual utiliza somente os QR Codes pertencentes à entrega pendente sincronizada para aquele produtor.
  • O QR Code da entrega confirma o recebimento completo sem necessidade de leitura individual das embalagens.
  • Os QR Codes individuais das embalagens continuam existindo para rastreabilidade e utilização posterior na aplicação dos produtos.

Como funciona no aplicativo

  1. O produtor acessa o menu Retirar Produtos.
  2. O app abre a câmera para leitura do QR Code ou código de barras da embalagem.
  3. Após a leitura, o app gera um client_event_id único.
  4. O evento é salvo primeiro no SQLite com status pendente.
  5. O app registra data, hora, latitude, longitude e nome do aparelho.
  6. Havendo internet, o app tenta executar imediatamente a sincronização offline.
  7. Sem internet ou em caso de falha, o evento permanece na fila local.
  8. Nos reenvios, o app reutiliza o mesmo client_event_id.
  9. O evento somente sai da fila após confirmação explícita do ERP.

Endpoint utilizado

A retirada de produtos não possui endpoint próprio. Ela é enviada pelo endpoint geral de sincronização offline do aplicativo produtor.

POST https://agroecologia.grupoekos.com.br/router/action.php

Headers obrigatórios

X-APP-KEY: <APP_KEY_FIXA_DO_APP_PRODUTOR>
X-DEVICE-TOKEN: <DEVICE_TOKEN_DO_APARELHO>

Identificação da rota

action=apiG10bio_produtor
f=sincronizacao_offline

O ERP identifica os eventos de retirada pelo campo eventos_retirada enviado na sincronização.

Estrutura do evento no SQLite

Campo Obrigatório Descrição
client_event_id Sim UUID único do evento. Deve permanecer igual em todos os reenvios.
codigo_lido Sim Conteúdo bruto obtido pela câmera.
tipo_codigo Sim Tipo identificado pelo leitor, por exemplo qrcode ou codigo_barras.
data Sim Data da retirada no formato YYYY-MM-DD.
hora Sim Hora da retirada no formato HH:MM:SS.
latitude Sim Latitude capturada no momento da leitura.
longitude Sim Longitude capturada no momento da leitura.
device_name Sim Nome ou modelo do aparelho que registrou a retirada.
status_sincronizacao Local Controle interno do SQLite, por exemplo PENDENTE ou CONFIRMADO.

Exemplo do evento de retirada

{
  "client_event_id": "550e8400-e29b-41d4-a716-446655440000",
  "codigo_lido": "7891234567890",
  "tipo_codigo": "codigo_barras",
  "data": "2026-07-23",
  "hora": "08:30:00",
  "latitude": -21.864500,
  "longitude": -47.499700,
  "device_name": "Samsung Galaxy A15"
}

Envio dentro da sincronização offline

As retiradas pendentes devem ser agrupadas no array eventos_retirada.

{
  "action": "apiG10bio_produtor",
  "f": "sincronizacao_offline",
  "app_version": "1.0.0",
  "last_sync_at": "2026-07-23 08:00:00",
  "eventos_retirada": [
    {
      "client_event_id": "550e8400-e29b-41d4-a716-446655440000",
      "codigo_lido": "7891234567890",
      "tipo_codigo": "codigo_barras",
      "data": "2026-07-23",
      "hora": "08:30:00",
      "latitude": -21.864500,
      "longitude": -47.499700,
      "device_name": "Samsung Galaxy A15"
    }
  ],
  "sessoes_aplicacao": [],
  "pontos_aplicacao": []
}

Outros tipos de eventos também devem possuir seus próprios arrays dentro da mesma sincronização. Isso permite que o ERP identifique e processe cada grupo separadamente.

Processamento esperado no ERP

  1. Validar X-APP-KEY e X-DEVICE-TOKEN.
  2. Identificar o produtor vinculado ao aparelho.
  3. Localizar o vínculo ativo do produtor com o franqueado.
  4. Percorrer o array eventos_retirada.
  5. Validar os campos obrigatórios de cada item.
  6. Verificar se o client_event_id já foi processado.
  7. Se ainda não existir, registrar a retirada.
  8. Se já existir, não duplicar o registro.
  9. Retornar o client_event_id em eventos_confirmados.retiradas.

Confirmação esperada do ERP

{
  "success": true,
  "msg": "Sincronização realizada com sucesso.",
  "data": {
    "server_time": "2026-07-23 08:31:10",
    "eventos_confirmados": {
      "retiradas": [
        "550e8400-e29b-41d4-a716-446655440000"
      ],
      "sessoes_aplicacao": [],
      "pontos_aplicacao": []
    }
  }
}

O app deve remover da fila somente os eventos cujo client_event_id estiver presente em eventos_confirmados.retiradas.

Falhas e reenvio

  • Falha de internet: manter o evento pendente.
  • Timeout: manter o evento pendente.
  • Erro HTTP 500: manter o evento pendente.
  • Evento não confirmado na resposta: manter o evento pendente.
  • Reenviar sempre com o mesmo client_event_id.
  • Nunca gerar outro identificador para a mesma retirada.

Regras importantes

  • O evento deve nascer primeiro no SQLite.
  • O ERP é a fonte oficial dos dados.
  • O aplicativo não precisa baixar QR Codes antecipadamente.
  • O app não deve confiar em id_franqueado enviado localmente.
  • O vínculo atual deve ser identificado pelo ERP usando o produtor associado ao aparelho.
  • A leitura pode conter QR Code ou código de barras.
  • O conteúdo lido deve ser preservado sem alterações.
  • Somente eventos confirmados pelo ERP podem ser removidos da fila.

NÃO IMPLEMENTAR neste fluxo

  • Endpoint exclusivo para retirada de produtos.
  • QR Code aleatório gerado especificamente para a retirada.
  • Download indiscriminado de QR Codes. Somente os QR Codes pertencentes às entregas pendentes do próprio produtor poderão ser sincronizados para conferência.
  • Remoção da fila apenas porque a requisição retornou HTTP 200.
  • Alteração do client_event_id em tentativas posteriores.
  • Uso do controlador apiG10bio_franqueado.

Exemplo de chamada cURL

curl -X POST "https://agroecologia.grupoekos.com.br/router/action.php" \
  -H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" \
  -H "X-APP-KEY: SUA_APP_KEY" \
  -H "X-DEVICE-TOKEN: SEU_DEVICE_TOKEN" \
  --data-urlencode "action=apiG10bio_produtor" \
  --data-urlencode "f=sincronizacao_offline" \
  --data-urlencode "app_version=1.0.0" \
  --data-urlencode "last_sync_at=2026-07-23 08:00:00" \
  --data-urlencode 'eventos_retirada=[{"client_event_id":"550e8400-e29b-41d4-a716-446655440000","codigo_lido":"7891234567890","tipo_codigo":"codigo_barras","data":"2026-07-23","hora":"08:30:00","latitude":-21.864500,"longitude":-47.499700,"device_name":"Samsung Galaxy A15"}]' \
  --data-urlencode "sessoes_aplicacao=[]" \
  --data-urlencode "pontos_aplicacao=[]"