Pular para o conteúdo principal

Compartilhamento e Relatórios

Última atualização: 16 de julho de 2026

Visão Geral

Diferente de faturamento, pagamento, assinatura e perda de cotação, o compartilhamento a partir da tela de detalhes é real e funcional em duas de suas três seções. O bottom sheet de compartilhamento (SaleShareSheet) monta até três blocos, dependendo do tipo e status da venda selecionada.

Arquivos-chave

ArquivoResponsabilidade
features/sale/components/sale-share-sheet/sale-share-sheet.tsxO bottom sheet de opções
services/pdf/sale/sale.pdf.service.tsGera o PDF "Layout Padrão" localmente
services/formatted-report/formatted-report.service.ts (via FormattedReportService)Lista relatórios reais do ERP
services/pdf/pdf.service.tsdownloadPdfOnline, baixa PDF gerado pelo ERP
features/sale/components/pdf-viewer-modal/pdf-viewer-modal.tsxExibe o PDF e aciona o share sheet nativo

Seção 1: "Layout Padrão", sempre disponível e gerado no cliente

Ao tocar em "Layout Padrão", o app gera um PDF localmente, sem chamada de rede, usando pdf-lib:

// sale-share-sheet.tsx
{
label: "Layout Padrão",
onPress: () => {
void onOpenQuotationPdf({ onError: onHandleErrorToast });
},
}

O gerador se comporta diferente conforme o tipo de venda:

  • Se for um rascunho ainda offline, usa o draft salvo (saleDraftService.getSavedDraftById) e salePdfService.createSaleDraftPdfBase64.
  • Se já for uma venda de fato (não-rascunho), primeiro converte o OrderHeader num SaleDraftRecord equivalente (buildDraftRecordFromSale) e usa o mesmo gerador de PDF via salePdfService.createSalePdfBase64FromSale.

Em ambos os casos, o serviço (services/pdf/sale/sale.pdf.service.ts) desenha um PDF completo: cabeçalho com dados da empresa e do cliente, tabela de itens com paginação automática, totais com IPI, substituição tributária e desconto, quebrando página quando o conteúdo não cabe. É gerado inteiramente no dispositivo, a partir dos dados reais da venda selecionada.

Seção 2: "Relatórios ERP / Online", só para venda já integrada

...(shouldShowErpOnlineFormattedReports
? [{
sectionTitle: "Relatórios ERP / Online",
options: erpOnlineFormattedReports.map((report) => ({
label: report.descricao,
onPress: () => void onOpenErpOnlineFormattedReport(report, { onError: onHandleErrorToast }),
})),
}]
: []),

Essa seção só aparece quando isErpIntegratedFinalizedSale(selectedSale) é verdadeiro e existe ao menos um relatório disponível. A lista de relatórios vem de uma chamada real, GET /relatorioFormatado, filtrada por tela "VENDAS". Ao escolher um relatório, o app faz POST /api/v1/document/relatorio/gerar no middleware e salva o PDF retornado localmente via fileStorageService.saveBase64File. É, de ponta a ponta, um PDF gerado pelo próprio ERP e baixado pelo app, não um documento local.

Seção 3: "Boletos", listada mas sem ação implementada

// sale-share-sheet.tsx
...(boletos.length > 0
? [{
sectionTitle: `Boletos (${boletos.length})`,
options: boletos.map((item) => ({
label: `Boleto: ${item.NUFIN} - Parcela: ${item.DESDOBRAMENTO}`,
onPress: () => {
// TODO: implementar compartilhamento de boleto
},
})),
}]
: []),

A seção aparece de verdade sempre que a venda tem boletos (selectedSale.BOLETOS, um campo real vindo da venda), com o número do boleto e da parcela corretos. Mas tocar em qualquer item não faz nada, o próprio código já deixa isso marcado como pendência (// TODO: implementar compartilhamento de boleto). É uma funcionalidade anunciada visualmente e ainda não implementada, não um bug.

Armadilhas conhecidas

Ao investigar por que "Relatórios ERP/Online" não aparece para uma venda específica, confirme primeiro se ela passa em isErpIntegratedFinalizedSale (não é rascunho, está finalizada, não é offline) antes de suspeitar de problema na API de relatórios formatados. E não prometa ao usuário final que compartilhar um boleto funciona, essa ação existe visualmente mas está vazia por dentro.