saas-docs: doc da Emissao de recibo profissional (Fase 4 #14)

Doc 06 cobrindo o quick path de emissao de recibo:
- Quando o botao aparece (AgendaEventoFinanceiroPanel com record
  status=paid)
- O que vem auto-preenchido (paciente, sessao, valor, forma pgto,
  terapeuta+registro formatado, clinica+CNPJ, data)
- Registro profissional generico — CRP/CRM/CRFa/CREFITO/CRESS/CRN/
  Outro (variavel terapeuta_registro auto-formata)
- Valor por extenso (helper valorExtenso.js, ate 999 milhoes)
- Onde fica salvo (download + aba Documentos categoria 'Recibo')
- Quick path emitirReciboParaSessao() vs flow manual de Gerar
- Notas dev: service, helper, mapping, migration do template,
  localizacao do botao

12 FAQs cobrindo casos comuns: emitir recibo de sessao paga, por
que botao nao aparece, valor por extenso correto, suporte multi-
conselho, onde salva, recibo avulso, CRP vazio, CNPJ formatado,
corrigir valor, enviar pra assinar, data sessao vs emissao,
reemitir.

categoria='Financeiro', pagina_path='/melissa/agenda', ordem=6.
SQL import em database-novo/tmp/import-doc-recibo-profissional.sql.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Leonardo
2026-05-22 19:31:55 -03:00
parent 3a42b0696d
commit 34412c6883
2 changed files with 230 additions and 0 deletions
@@ -0,0 +1,143 @@
-- Importacao da doc Emissao de recibo profissional (Fase 4 #14)
-- Gerado a partir de development/saas-docs/06-recibo-profissional-melissa.json
BEGIN;
DO $IMPORT$
DECLARE
v_doc_id uuid;
BEGIN
INSERT INTO public.saas_docs (
titulo, conteudo, categoria, exibir_no_faq, tipo_acesso,
pagina_path, ordem, ativo, medias
) VALUES (
'Emissão de recibo profissional',
$HTML$<h2>Emissão de recibo profissional</h2>
<p>Quando uma sessão é registrada como <strong>paga</strong>, o sistema oferece um botão <em>Emitir recibo</em> que gera um PDF profissional pré-preenchido com todos os dados do paciente, terapeuta, clínica e da sessão sem precisar passar pelo fluxo "Gerar a partir de template" manual.</p>
<h3>1. Quando o botão aparece</h3>
<p>O botão <strong>Emitir recibo</strong> (outlined, ícone PDF) aparece no <em>painel financeiro do evento</em> (<code>AgendaEventoFinanceiroPanel</code>) dentro do modal de uma sessão somente quando:</p>
<ul>
<li>A sessão tem um <strong>financial_record vinculado</strong> (foi gerada cobrança via "Receber")</li>
<li>O status do record é <strong><code>paid</code></strong> (pagamento registrado)</li>
</ul>
<p>Em sessões de pacote (status='contrato'), sem cobrança gerada, pendente, ou cancelada o botão não aparece. Use o fluxo manual de <em>Gerar</em> na aba Documentos pra emitir recibos de casos especiais.</p>
<h3>2. O que o recibo traz preenchido automaticamente</h3>
<ul>
<li><strong>Paciente:</strong> nome, CPF, RG (do cadastro do paciente)</li>
<li><strong>Sessão:</strong> data e hora, modalidade</li>
<li><strong>Valor:</strong> número (R$ 150,00) <strong>e por extenso</strong> ("cento e cinquenta reais")</li>
<li><strong>Forma de pagamento:</strong> PIX, dinheiro, cartão, maquininha, etc vindo do financial_record</li>
<li><strong>Terapeuta:</strong> nome completo + registro profissional formatado ("CRP 12345/SP")</li>
<li><strong>Clínica:</strong> nome, endereço, telefone, CNPJ formatado</li>
<li><strong>Data atual:</strong> em formato curto (22/05/2026) e por extenso ("22 de maio de 2026")</li>
</ul>
<h3>3. Registro profissional genérico</h3>
<p>O sistema suporta <strong>qualquer conselho profissional</strong>, não CRP. A formatação é automática a partir do que está cadastrado no <em>Perfil Registro Profissional</em>:</p>
<ul>
<li><strong>CRP</strong> 12345/SP (psicologia)</li>
<li><strong>CRM</strong> 67890/RJ (medicina)</li>
<li><strong>CRFa</strong> 11111/MG (fonoaudiologia)</li>
<li><strong>CREFITO</strong> 22222/SP (fisioterapia)</li>
<li><strong>CRESS</strong> 33333/RS (serviço social)</li>
<li><strong>CRN</strong> 44444/SP (nutrição)</li>
<li>Ou personalizado via tipo "Outro" + nome livre</li>
</ul>
<p>No template, a variável <code>{{terapeuta_registro}}</code> sempre traz o registro formatado, independente do conselho. Tem também variáveis individuais: <code>{{terapeuta_registro_tipo}}</code>, <code>{{terapeuta_registro_numero}}</code>, <code>{{terapeuta_registro_uf}}</code> pra uso fino.</p>
<h3>4. Valor por extenso</h3>
<p>Helper interno (<code>src/utils/valorExtenso.js</code>) converte número pra extenso em pt-BR completo até 999 milhões:</p>
<div style="background: rgba(99,102,241,0.06); border: 1px solid rgba(99,102,241,0.2); border-radius: 10px; padding: 12px 14px; margin: 12px 0; font-family: 'IBM Plex Mono', monospace; font-size: 0.82rem;">
<strong>R$ 1,00</strong> "um real"<br>
<strong>R$ 150,00</strong> "cento e cinquenta reais"<br>
<strong>R$ 1.234,56</strong> "mil duzentos e trinta e quatro reais e cinquenta e seis centavos"<br>
<strong>R$ 0,50</strong> "cinquenta centavos"<br>
<strong>R$ 1.000.000,00</strong> "um milhão de reais"
</div>
<p>Pluralização correta (real/reais, centavo/centavos), tratamento de centavos isolados ("R$ 0,X"), milhar com "mil" sem "um", milhão/milhões.</p>
<h3>5. Onde o recibo é salvo</h3>
<p>Ao clicar <strong>Emitir recibo</strong>:</p>
<ol>
<li>Sistema busca o template global <code>recibo_pagamento</code></li>
<li>Carrega todas as variáveis (auto-fill descrito acima)</li>
<li>Gera o PDF</li>
<li>Faz upload pro bucket <code>generated-docs</code></li>
<li>Insere registros em <code>documents</code> e <code>document_generated</code> (com linkage)</li>
<li>Dispara <strong>download</strong> automático no browser</li>
<li>Toast "Recibo emitido — PDF baixado e salvo nos documentos do paciente"</li>
</ol>
<p>O recibo aparece na aba <em>Documentos</em> do prontuário do paciente sob a categoria <strong>Recibo</strong>. Pode ser editado in-place, compartilhado ou assinado eletronicamente normalmente.</p>
<h3>6. Quick path vs flow manual</h3>
<p>São <strong>2 caminhos</strong> pra gerar o mesmo PDF:</p>
<ul>
<li><strong>Quick path</strong> (este): clica num botão e pronto. Recibo da sessão paga, valor exato do record, forma de pagamento idem.</li>
<li><strong>Flow manual</strong>: aba Documentos Gerar escolhe template "Recibo de Pagamento" edita valores manualmente preview salva.</li>
</ul>
<p>Use o quick path no fluxo normal. Use o manual quando precisar emitir recibo de algo que não está vinculado a sessão (consulta avulsa) ou quando precisar ajustar valores.</p>
<h3> Notas pro desenvolvedor</h3>
<ul>
<li><strong>Service:</strong> <code>emitirReciboParaSessao(eventoId, { patientId?, valor?, formaPagamento? })</code> em <code>DocumentGenerate.service.js</code>. Quick path one-call: busca template, carrega vars, gera, salva, download.</li>
<li><strong>Helper extenso:</strong> <code>src/utils/valorExtenso.js</code> pt-BR até 999 milhões. Atenção: zero retorna "zero reais", inputs inválidos retornam string vazia.</li>
<li><strong>Mapeamento:</strong> <code>TEMPLATE_TYPE_TO_DOC_TYPE['recibo_pagamento'] = 'recibo'</code> garante que o doc gerado vai pra categoria certa na sidebar.</li>
<li><strong>Template:</strong> migration <code>20260521000008_recibo_uses_terapeuta_registro.sql</code> trocou <code>"Psicólogo(a) - CRP {{terapeuta_crp}}"</code> por <code>{{terapeuta_registro}}</code> no template global. Universal pra qualquer conselho.</li>
<li><strong>Botão UI:</strong> <code>AgendaEventoFinanceiroPanel.vue</code> linha ~320, branch <code>v-else-if="record.status === 'paid'"</code>.</li>
</ul>$HTML$,
'Financeiro',
true,
'usuario',
'/melissa/agenda',
6,
true,
'[{"tipo": "imagem", "url": ""}]'::jsonb
)
RETURNING id INTO v_doc_id;
INSERT INTO public.saas_faq_itens (doc_id, pergunta, resposta, ordem, ativo) VALUES
(v_doc_id, 'Como emito um recibo pra uma sessão que recebi o pagamento?',
$FAQ$Abra a sessão no calendário da agenda no painel <em>Cobrança</em> dentro do modal, com o pagamento registrado (status <strong>Pago</strong>), aparece o botão <strong>Emitir recibo</strong>. Clique uma vez. O sistema gera o PDF, salva nos documentos do paciente e dispara o download automaticamente. Toast confirma a operação.$FAQ$, 0, true),
(v_doc_id, 'Por que o botão "Emitir recibo" não aparece na minha sessão?',
$FAQ$O botão aparece quando o financial_record da sessão tem <strong>status = pago</strong>. Possíveis motivos: (1) você não gerou cobrança ainda clique em <em>Receber</em> pra registrar o pagamento primeiro; (2) cobrança está pendente registre o recebimento; (3) sessão é de pacote (status='contrato') pacotes não emitem recibo por sessão, use o fluxo manual em <em>Documentos Gerar</em>; (4) cobrança foi cancelada gere uma nova.$FAQ$, 1, true),
(v_doc_id, 'O valor por extenso vem certo ("cento e cinquenta reais")?',
$FAQ$Sim, com gramática pt-BR correta até 999 milhões. Exemplos: R$ 1,00 "um real", R$ 150,00 "cento e cinquenta reais", R$ 1.234,56 "mil duzentos e trinta e quatro reais e cinquenta e seis centavos", R$ 0,50 "cinquenta centavos". Pluralização real/reais e centavo/centavos automática.$FAQ$, 2, true),
(v_doc_id, 'O recibo funciona pra qualquer conselho profissional (CRM, CRFa…)?',
$FAQ$<strong>Sim.</strong> O template usa a variável <code>{{terapeuta_registro}}</code> que se adapta ao tipo de registro cadastrado no seu Perfil. Funciona pra CRP (psicologia), CRM (medicina), CRFa (fonoaudiologia), CREFITO (fisioterapia), CRESS (serviço social), CRN (nutrição), e qualquer outro conselho incluindo "Outro" com nome livre. A formatação genérica fica tipo "CRP 12345/SP", "CRM 67890/RJ", etc.$FAQ$, 3, true),
(v_doc_id, 'Onde o recibo fica salvo depois de emitido?',
$FAQ$Em <strong>2 lugares</strong>: (1) baixado automaticamente no seu computador via download do navegador; (2) salvo na aba <em>Documentos</em> do prontuário do paciente, na categoria <strong>Recibo</strong> da sidebar. Daí você pode reabrir, compartilhar com o paciente, enviar pra assinar, ou editar in-place se precisar ajustar.$FAQ$, 4, true),
(v_doc_id, 'Posso emitir recibo de algo que não é sessão (consulta avulsa, pacote)?',
$FAQ$Sim, mas pelo <strong>fluxo manual</strong>: na aba <em>Documentos</em> do paciente botão <strong>Gerar</strong> escolha o template <em>"Recibo de Pagamento"</em>. Você preenche os valores na mão (valor, forma de pagamento, descrição) que não vem de uma sessão específica. O resto (CRP, paciente, clínica) auto-completa igual.$FAQ$, 5, true),
(v_doc_id, 'Meu CRP/CRM aparece vazio no recibo, o que fazer?',
$FAQ$Cadastre seu registro profissional em <strong>Perfil Registro Profissional</strong>. Selecione o tipo (CRP/CRM/CRFa//Outro), número e UF. Salve. Próximos recibos gerados trazem formatado. Pra atualizar recibos antigos, abra o doc na aba Documentos do paciente e use <em>Editar</em> o sistema vai puxar o registro atualizado.$FAQ$, 6, true),
(v_doc_id, 'O CNPJ da clínica aparece formatado no recibo?',
$FAQ$Sim, automaticamente. Em <strong>Configurações Negócio (Tenant)</strong>, cadastre o CPF ou CNPJ no campo unificado. O sistema detecta pela quantidade de dígitos: 11 dígitos formata como CPF (XXX.XXX.XXX-XX), 14 como CNPJ (XX.XXX.XXX/XXXX-XX). O recibo usa a variável <code>{{clinica_cnpj}}</code> que sai formatada.$FAQ$, 7, true),
(v_doc_id, 'Errei o valor do recibo, posso corrigir sem gerar outro?',
$FAQ$Sim. na aba <em>Documentos</em> do paciente abra o recibo no preview clique em <strong>Editar</strong>. O dialog abre em modo edição com o template do recibo carregado e os valores anteriores preenchidos. Ajuste o que precisa <em>Substituir documento</em>. O PDF é regenerado e substitui o anterior, mantendo o mesmo ID e audit trail.$FAQ$, 8, true),
(v_doc_id, 'Posso enviar o recibo pro paciente assinar?',
$FAQ$Sim. Recibos são documentos como qualquer outro abra na aba Documentos preview botão <strong>Assinar</strong> na sidebar. Gera link público temporário, paciente abre sem login, marca aceite LGPD, assina. Útil pra recibos de valores altos ou contratos de pacote onde você quer registro formal da concordância.$FAQ$, 9, true),
(v_doc_id, 'Recibo de uma sessão antiga vai com a data de hoje ou a data da sessão?',
$FAQ$<strong>As duas</strong>. O recibo traz a <em>data da sessão</em> ("Referente ao atendimento de 15/03/2026") e a <em>data atual de emissão</em> ("São Carlos, 22 de maio de 2026") no rodapé. Importante pra fiscal a data de emissão indica quando o documento foi formalmente criado, mesmo que a sessão tenha sido meses atrás.$FAQ$, 10, true),
(v_doc_id, 'Posso reemitir um recibo que já foi emitido pra mesma sessão?',
$FAQ$Sim, mas com cuidado. Clicar em <strong>Emitir recibo</strong> de novo gera um <strong>novo PDF</strong> e salva como novo documento na aba você fica com 2 recibos da mesma sessão. Pra apenas atualizar (sem duplicar), edite o existente em <em>Documentos preview Editar</em>. Se duplicar por engano, exclua o antigo (soft-delete preserva por 5 anos no Lixo).$FAQ$, 11, true);
RAISE NOTICE 'Doc criada: id=%, faq_itens=12', v_doc_id;
END;
$IMPORT$;
COMMIT;
File diff suppressed because one or more lines are too long