Pular para o conteúdo principal

Importação de Saídas Segregadas — Pedidos de Saída Segregada do SAP B1 para o WMS

📌 Descrição do Processo

A importação de saídas segregadas representa o fluxo de importação de pedidos de venda com saída segregada do SAP B1 para o WMS. O SAP B1 mantém os pedidos de venda abertos com linhas associadas a depósitos segregados, enquanto o WMS recebe esses pedidos como movimentações de saída segregada para separação e processamento.

A integração garante que os pedidos de venda com itens em depósitos segregados no SAP B1 sejam automaticamente importados como pedidos de saída segregada no WMS, com validação de lotes, filtragem por prefixos de produto e rastreabilidade via IntegrationTracking.

Importante

Este processo utiliza o padrão pooling com cursor incremental baseado em DocNum e DocDate — busca periodicamente pedidos abertos no SAP B1 desde a última execução. Apenas pedidos com itens em depósitos segregados configurados (padrão: 01.05, 01.04) são importados. Produtos com lotes obrigatórios (ManageBatchNumbers = 'tYES') que não possuem lotes definidos são rejeitados.


🔄 Fluxo de Importação

  1. Consulta de Pedidos de Venda no SAP B1 (Query)

    • O WMS consulta a API /Orders do SAP B1, filtrando pedidos com status bost_Open e DocNum/DocDate superiores ao cursor da última execução.
    • Para cada pedido retornado, o WMS busca os dados completos (linhas, lotes) via /Orders({docEntry}).
    • Os itens são validados: produtos com controle de lote (ManageBatchNumbers = 'tYES') devem ter lotes definidos — caso contrário, o pedido é rejeitado.
  2. Filtragem e Deduplicação

    • Pedidos já registrados no IntegrationTracking com tipo SegregatedExitsImport são filtrados para evitar duplicação.
    • Linhas de itens cujo código de produto não corresponde aos prefixos válidos configurados (padrão: MA, MP, PA, PI, UC, RV) são removidas. Pedidos sem linhas válidas remanescentes são descartados.
  3. Conversão para Pedidos do WMS (Parse)

    • Os pedidos do SAP B1 (B1OrderSegregatedResponse) são convertidos para OrderImport via AutoMapper.
    • A operação é fixada como SaidaSegregado (código 6).
    • Lotes são mapeados com datas de fabricação e validade. Itens sem lote recebem LOTE UNICO.
    • O código de operação logística padrão é injetado dos parâmetros B1.
  4. Salvamento no WMS (Send)

    • Os pedidos convertidos são salvos no WMS via RecordOrderService.
    • Registros de IntegrationTracking com tipo SegregatedExitsImport são criados.
    • O cursor é atualizado com o DocNum e Typing do último pedido processado.

🖥️ APIs Envolvidas

  • SAP B1 → WMS (GET)
    • /Orders?$select=DocEntry,DocumentStatus&$filter=DocumentStatus eq 'bost_Open' and DocNum gt {cursorDocNum} and DocDate ge '{cursorDate}'&$orderby=DocDate desc → retorna DocEntries de pedidos abertos para processamento incremental.
    • /Orders({docEntry}) → recupera os dados completos de cada pedido, incluindo DocumentLines com ItemCode, Quantity, UnitPrice, WarehouseCode, BatchNumbers.
    • /Items?$filter=ItemCode eq '{itemCode}'&$select=ItemCode,ManageBatchNumbers → valida se os itens possuem controle de lote obrigatório (consultado em chunks de 15).

📦 Exemplo de Importação (Objeto Fictício)

Cenário:

  • Cliente: Distribuidora XYZ S.A. (C00250)
  • Pedido SAP B1: DocNum 62000, DocEntry 62000
  • Produto: PA-789 – Bateria 60Ah (30 unidades, lote LT-2026-080)
  • Depósito segregado: 01.05
  • Data do pedido: 2026-03-26, hora: 14:30
  • Valor total: R$ 4.500,00

1. Pedido de Venda no SAP B1

{
"DocEntry": 62000,
"DocNum": 62000,
"DocDate": "2026-03-26",
"DocTime": "14:30",
"CardCode": "C00250",
"CardName": "Distribuidora XYZ S.A.",
"DocTotal": 4500.00,
"DocumentLines": [
{
"LineNum": 0,
"ItemCode": "PA-789",
"ItemDescription": "Bateria 60Ah",
"Quantity": 30,
"UnitPrice": 150.00,
"WarehouseCode": "01.05",
"LineStatus": "bost_Open",
"BatchNumbers": [
{
"BatchNumber": "LT-2026-080",
"Quantity": 30,
"ManufacturingDate": "2026-03-01",
"ExpiryDate": "2027-03-01"
}
]
}
]
}

2. Resultado no WMS

  • Pedido de saída segregada #62000 criado com operação SaidaSegregado (código 6).
  • Item PA-789: 30 unidades, lote LT-2026-080, classificação de origem 01.05, fabricação 2026-03-01, validade 2027-03-01.
  • Entidade relacionada: C00250 (Distribuidora XYZ S.A.).
  • Operação logística: 116 (código padrão).
  • IntegrationTracking registrado com tipo SegregatedExitsImport e RelatedId = 62000.
  • Cursor atualizado para DocNum = 62000, Timestamp = 2026-03-26 14:30.

✅ Regras de Negócio

  • Apenas pedidos com DocumentStatus = 'bost_Open' e DocNum/DocDate superiores ao cursor são consultados no SAP B1.
  • A importação é incremental via cursor — utiliza DocNum e DocDate para paginação, com tipo SegregatedExitsImport.
  • Pedidos já registrados no IntegrationTracking com tipo SegregatedExitsImport são filtrados, evitando duplicação.
  • Apenas linhas com WarehouseCode correspondente aos depósitos segregados configurados (padrão: 01.05, 01.04) são consideradas.
  • Linhas de itens cujo código não corresponde aos prefixos válidos configurados (padrão: MA, MP, PA, PI, UC, RV) são removidas. Pedidos sem linhas válidas são descartados.
  • Produtos com ManageBatchNumbers = 'tYES' no SAP B1 devem ter lotes definidos (BatchNumbers não vazio). Pedidos que violam essa regra são rejeitados.
  • Itens sem lotes definidos recebem lote padrão LOTE UNICO.
  • Para itens com lotes, as datas de fabricação (ManufacturingDate) e validade (ExpiryDate) são extraídas diretamente dos BatchNumbers da resposta do SAP B1.
  • A RelatedOriginClassification de cada lote é definida como o WarehouseCode da linha do pedido no SAP B1.
  • A operação é fixada como SaidaSegregado (código 6) e o código de operação logística padrão (DefaultLogisticOperationCode) é injetado dos parâmetros B1.
  • Após o salvamento, dígitos de procedimento são removidos via DigitCalculator.RemoveProcedureDigit().
  • Em caso de falha no salvamento de um grupo de integração, o erro é logado e o processamento continua para os próximos grupos.
  • O cursor é atualizado mesmo em caso de falha parcial — aponta para o último pedido processado (com ou sem erro).

Resumo

Esse fluxo garante que os pedidos de venda com itens em depósitos segregados no SAP B1 sejam automaticamente importados como pedidos de saída segregada no WMS, com validação de lotes, filtragem por prefixos de produto e rastreabilidade completa, preparando-os para separação e posterior faturamento.


⚙️ Especificações Técnicas

Fluxo de execução

  • Query: Consulta pedidos de venda abertos no SAP B1 via endpoint /Orders, valida lotes dos itens via /Items, filtra duplicatas contra IntegrationTracking e remove linhas com prefixos inválidos.
  • Parse: Converte pedidos do SAP B1 para OrderImport via AutoMapper, fixando operação SaidaSegregado, mapeando lotes com datas e injetando parâmetros B1 (operação logística padrão).
  • Send: Salva pedidos no WMS via RecordOrderService, remove dígitos de procedimento, registra IntegrationTracking e atualiza o cursor.

Detalhamento das Etapas

Query

B1SegregatedExitsIntegrator.Query()
└── B1SegregatedExitsService.GetSegregatedExitsFromB1Async()
├── ErpIntegrationsService.GetErpToIntegrateAsync(EDefIntegration.B1)
└── [Para cada integração ERP B1]
├── ErpIntegrationsService.GetErpIntegrationCursorAsync(erp, SegregatedExitsImport)
├── B1OrderConnector.GetSegregatedOrdersAsync(config, cursor, warehouseCodes)
│ ├── GET /Orders?$filter=DocumentStatus eq 'bost_Open'... [DocEntries]
│ ├── GET /Orders({docEntry}) [dados completos, por pedido]
│ └── GET /Items?$filter=ItemCode eq '...' [validação de lotes, chunks de 15]
├── [Filtragem contra IntegrationTracking existente]
└── [Filtragem por prefixos válidos de produto]
  • B1SegregatedExitsIntegrator.Query(): Ponto de entrada — delega a busca ao serviço.
  • B1SegregatedExitsService.GetSegregatedExitsFromB1Async(): Orquestra toda a consulta: obtém cursor, busca pedidos no SAP B1, valida lotes, filtra duplicatas e prefixos inválidos.
  • B1OrderConnector.GetSegregatedOrdersAsync(): Consulta inicial retorna apenas DocEntry/DocumentStatus de pedidos abertos. Para cada DocEntry, busca dados completos. Valida que produtos com controle de lote possuem BatchNumbers preenchidos.

Parse

B1SegregatedExitsIntegrator.Parse()
└── [Para cada integração]
├── ErpIntegration.GetParameters(b1ParametersProvider)
└── mapper.MapListWithB1Parameters<B1OrderSegregatedResponse, OrderImport>()
├── B1OrderSegregatedResponse → OrderImport
│ ├── DocNum → RelatedOrderCode
│ ├── DocTotal → Amount
│ ├── DocDate + DocTime → Typing
│ ├── Operation = 6 (SaidaSegregado)
│ ├── CardCode → RelationalEntityId
│ └── DefaultLogisticOperationCode → RelationalLogisticOperationId
└── B1OrderSegregatedLine → OrderItem
├── ItemCode → RelatedProductId
├── Quantity → Quantity
└── BatchNumbers → OrderItemVolumeLots
├── [Com lote]: BatchNumber, Quantity, WarehouseCode, datas
└── [Sem lote]: "LOTE UNICO", Quantity, WarehouseCode
  • B1SegregatedExitsIntegrator.Parse(): Para cada integração, obtém os parâmetros B1 e injeta no contexto do AutoMapper via MapListWithB1Parameters.
  • AutoMapper (B1SegregatedExitsProfile): Converte B1OrderSegregatedResponse para OrderImport com operação SaidaSegregado. Lotes são mapeados com datas de fabricação/validade; itens sem lote recebem LOTE UNICO. O WarehouseCode da linha é usado como RelatedOriginClassification.

Send

B1SegregatedExitsIntegrator.Send()
└── [Para cada grupo de integração]
└── B1SegregatedExitsService.SaveSegregatedExitsToWmsAsync()
├── RecordOrderService.RecordOrder(parsedOrders)
├── DigitCalculator.RemoveProcedureDigit() [por pedido salvo]
├── SaveIntegrationTrackings(erpIntegration, savedOrders)
│ └── OrderIntegrationService.SaveOrderIntegrationTrackingsAsync()
└── UpdateIntegrationCursorAsync()
└── ErpIntegrationsService.UpdateErpIntegrationCursorAsync()
  • B1SegregatedExitsIntegrator.Send(): Itera sobre cada grupo de integração. Falhas em um grupo não interrompem o processamento dos demais.
  • SaveSegregatedExitsToWmsAsync(): Salva pedidos no WMS, remove dígitos de procedimento, registra tracking e atualiza cursor.
  • UpdateIntegrationCursorAsync(): Atualiza cursor com LastId = DocNum e LastTimestamp = Typing do último pedido. Em caso de falha parcial, aponta para o último pedido com erro.

Resumo do Funcionamento

  • Busca incremental: Utiliza cursor baseado em DocNum e DocDate para processar apenas pedidos novos desde a última execução.
  • Validação de lotes: Produtos com controle de lote obrigatório no SAP B1 são validados — pedidos com lotes ausentes são rejeitados.
  • Filtragem em múltiplos níveis: Duplicatas são removidas via IntegrationTracking, linhas com prefixos inválidos são descartadas, e pedidos sem linhas válidas são ignorados.
  • Mapeamento via AutoMapper: Conversão padronizada com injeção de parâmetros B1 no contexto do mapper, permitindo configuração flexível da operação logística.
  • Rastreabilidade completa: Cada pedido importado gera um IntegrationTracking com tipo SegregatedExitsImport, permitindo auditoria e controle de idempotência.
  • Tratamento de erros: Falhas no salvamento de um grupo de integração são logadas sem interromper o processamento. O cursor é atualizado mesmo em cenários de falha parcial.