Faturamento

Dúvida: como faturar o pedido, o que a transação grava e quando a API recusa.

Dúvida: como faturar um pedido de venda?

Ambiente: tela /apps/sales/fulfill?salesOrderId= (também pelo monitor NF-e). API POST /sales-order/:id/fulfill. IPs BEFORE_FULFILL, ACTION.FULFILL, AFTER_FULFILL, FULFILL.SCREEN.ON_LOAD.

Pré-requisitos: pedido APPROVED (não ORCAMENTO, não PARKED agrupado, não REFUSED, não FULLY_SERVICED); disponível no ATP para a quantidade; condição de pagamento; destinatário fiscal se for NF-e 55.

Caminho na tela

  1. Abra o pedido → Faturar (ou a URL de fulfill).
  2. Informe quantidade por item (≤ restante qtdPackage − fulfilledQty).
  3. Opcional: movimentTypeCode, creditAmount (carteira), settledBy.
  4. Confirme. Clique dispara ACTION.FULFILL; o Core então roda os sete passos.

A API recusa se groupedIntoOrderId, status PARKED, REFUSED, FULLY_SERVICED ou documento ORCAMENTO.

DTO

{
  items: { salesOrderItemId: string; quantity: number }[];
  movimentTypeCode?: string;
  creditAmount?: number;  // carteira do cliente
  settledBy?: string;
}

Quantidade por item ≤ restante (qtdPackage − fulfilledQty). Entregas parciais acumulam; status vira PARTIALLY_SERVICED ou FULLY_SERVICED.

Sete passos

  1. Valida status e tipo de documento.
  2. Valida quantidades.
  3. Lock na Configuration → reserva código de ExitDocument.
  4. Cria FAT003.
  5. Por item: linha de saída, calcularImpostos, baixa estoque, consome FIFO. Com lote: FEFO / lot_id.
  6. Consome crédito (creditAmount) e gera CR: parcela quitada CUSTOMER_CREDIT + parcelas do restante pela condição de pagamento.
  7. Atualiza o pedido.

Agrupador: faturamento não gera CR, a menos que o group tenha generateFinancialTitle=true.

Destinatário NF-e 55 = FAT003.customer_id. Sem cadastro fiscal → NEED_FISCAL_CUSTOMER (não assina). NFC-e 65 omite dest.

IPs

Antes do commit: BEFORE_FULFILL (pode negar) e ACTION.FULFILL no clique. Depois: AFTER_FULFILL (canDeny=false). Tela: FULFILL.SCREEN.ON_LOAD.

Documento de saída: IP.SALES.EXIT.BEFORE_CONFIRM não wired.

Cancelamento

GET /sales-order/cancel-preview/:id lista saída, NF-e, CR, ticket, PDV, caixa e estoque.
POST /sales-order/cancel/:id — se já faturou, exige confirmed: true e justificativa SEFAZ quando houver NF autorizada no prazo. IPs BEFORE_CANCEL / AFTER_CANCEL / ACTION.CANCEL wired.

Exemplo

Pedido 4 500 UN de pão (HML, após OP): faturamento gerou NFS-4552. Lote FEFO do PA. ATP depois: 180 UN ACTIVE restantes. Relatório interno: docs/industrial/INDUSTRIAL-HML-RELATORIO.md.