feat(protese): avançar etapas pela clínica + recibo térmico/laser + abas reordenadas

- Aba "Linha do tempo" movida para o FINAL (entregue/cancelar continuam nela).
- Etapas agora avançáveis também pela clínica (não só pelo lab): nova lista "Etapas do
  trabalho" na 1ª aba, com botão "Avançar" por etapa. Backend: avanço da produção passa
  a aceitar lab OU clínica de origem (auditado por actor). 'entregue' segue na timeline
  (exige foto).
- Impressão por etapa em DOIS formatos: térmica (bobina 80mm) e laser (A4), com os dados
  da OS preenchidos no recibo (paciente, trabalho, dentista, lab, dentes, material/cor,
  componentes, prazo, local atual + assinaturas).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
VPS 4 Builder
2026-06-24 02:06:29 +02:00
parent 8cf4a83161
commit f4f433b14c
2 changed files with 51 additions and 37 deletions
+3 -1
View File
@@ -4122,7 +4122,9 @@ app.post('/api/protese/os/:id/status', authGuard, async (req, res) => {
// Entregue/cancelado são da clínica; estados de produção são do laboratório.
const estadosClinica = ['entregue', 'cancelado'];
if (estadosClinica.includes(novo) && !isClinic) return res.status(403).json({ error: 'Só a clínica de origem marca entregue/cancelado.' });
if (!estadosClinica.includes(novo) && !isLab) return res.status(403).json({ error: 'Só o laboratório avança a produção.' });
// Etapas de produção (recebido→…→finalizado): lab OU clínica de origem podem avançar
// (o coordenador da clínica acompanha o trabalho). Auditado por actor no histórico.
if (!estadosClinica.includes(novo) && !isLab && !isClinic) return res.status(403).json({ error: 'Sem acesso para avançar a produção.' });
// Garantia com fotos: para ENTREGAR é obrigatório ter ao menos 1 foto do trabalho (evidência da garantia).
let garantiaAte = null, finId = os.financeiro_id || null, finLabId = os.financeiro_lab_id || null;
if (novo === 'entregue') {