// SGAB v2 — Propostas (PTC), Financeiro, Estoque, Relatórios, Configurações
const { useState } = React;
// ═══════════════════════════════════════════════════════════════
// PROPOSTAS
// ═══════════════════════════════════════════════════════════════
function Propostas({ user, toast, onNav }) {
const [db, setDb] = useState(() => SGAB.getDB());
const [modal, setModal] = useState(false);
const [form, setForm] = useState({});
const [editItem, setEdit] = useState(null);
const [q, setQ] = useState('');
const { fmt } = SGAB;
const isAdmin = user.perfil === 'administrador' || user.perfil === 'administrativo';
function reload() { setDb(SGAB.getDB()); }
function F(k,v) { setForm(f=>({...f,[k]:v})); }
const lista = db.propostas.filter(p =>
!q || db.clientes.find(c=>c.id===p.clienteId)?.razaoSocial.toLowerCase().includes(q.toLowerCase()) ||
(p.numero||'').toLowerCase().includes(q.toLowerCase())
).sort((a,b)=>b.data.localeCompare(a.data));
function openNew() {
const ndb = SGAB.getDB();
const id = SGAB.nxtId(ndb,'prop'); SGAB.saveDB(ndb);
const vd = new Date(); vd.setDate(vd.getDate()+15);
setEdit(null);
setForm({ numero:`PTC_${new Date().getFullYear()}${String(id).padStart(4,'0')}`, status:'Em Elaboração',
data:fmt.today(), validade:vd.toISOString().slice(0,10), tipo:'Calibração RBC', equipIds:[], valor:'', desc:'' });
setModal(true);
}
function openEdit(p) { setEdit(p); setForm({...p}); setModal(true); }
function salvar() {
if (!form.clienteId) { toast('Selecione o cliente.','error'); return; }
if (!form.tipo) { toast('Selecione o tipo.','error'); return; }
const ndb = SGAB.getDB();
const obj = {...form, clienteId:+form.clienteId, valor:+form.valor||0, equipIds:(form.equipIds||[]).map(Number)};
if (editItem) { const i=ndb.propostas.findIndex(p=>p.id===editItem.id); if(i>=0) ndb.propostas[i]={...ndb.propostas[i],...obj}; }
else { ndb.propostas.push({id:SGAB.nxtId(ndb,'prop'),...obj}); }
SGAB.saveDB(ndb); reload(); setModal(false);
toast(editItem?'PTC atualizada!':'PTC criada!');
}
function excluir(p) {
if (!confirm(`Excluir ${p.numero}?`)) return;
const ndb=SGAB.getDB(); ndb.propostas=ndb.propostas.filter(x=>x.id!==p.id);
SGAB.saveDB(ndb); reload(); toast('PTC removida.','info');
}
function converterOS(p) {
if (!confirm(`Converter ${p.numero} em Ordem de Serviço?`)) return;
const ndb=SGAB.getDB();
const newOS = { id:SGAB.nxtId(ndb,'ordens'), numero:`OS_${new Date().getFullYear()}${String(ndb.nextIds.ordens).padStart(4,'0')}`,
clienteId:p.clienteId, equipIds:p.equipIds||[], tipo:p.tipo, status:'Agendada',
tecnicoId:db.usuarios.find(u=>u.perfil==='tecnico')?.id||1, data:fmt.today(),
desc:p.desc, valor:p.valor, pecas:[], hIni:'08:00', viagem:'0.5h', obs:`Gerado a partir de ${p.numero}` };
ndb.ordens.push(newOS);
const pi=ndb.propostas.findIndex(x=>x.id===p.id); if(pi>=0){ndb.propostas[pi].status='Aprovada';ndb.propostas[pi].osId=newOS.id;}
SGAB.saveDB(ndb); reload(); toast(`OS ${newOS.numero} criada com sucesso!`); onNav('ordens');
}
function printPTC(p) {
const cli = db.clientes.find(c=>c.id===p.clienteId);
const equips = db.equipamentos.filter(e=>(p.equipIds||[]).includes(e.id));
const config = db.config.empresa;
const html = `
${p.numero}
${config.nome}
${config.cnpj} | ${config.tel} | ${config.email}
${config.acred}
${p.numero}
PROPOSTA TÉCNICO-COMERCIAL
Emitida: ${fmt.date(p.data)} | Válida até: ${fmt.date(p.validade)}
01 — DADOS DO CLIENTE
| Razão Social | ${cli?.razaoSocial||'—'} | CNPJ | ${cli?.cnpj||'—'} |
| Endereço | ${cli?.endereco||'—'}, ${cli?.cidade||'—'}/${cli?.uf||'—'} |
| Contato | ${cli?.contato||'—'} | Depto | ${cli?.depto||'—'} |
| Telefone | ${cli?.tel||'—'} | E-mail | ${cli?.email||'—'} |
|---|
02 — OBJETO DA PROPOSTA
| Tipo de Serviço | ${p.tipo} |
|---|
| Descrição | ${p.desc||'—'} |
|---|
${equips.length>0?`03 — EQUIPAMENTOS
| TAG | Fabricante | Modelo | N° Série | Capacidade | Classe |
${equips.map(e=>`| ${e.tag} | ${e.fab} | ${e.modelo} | ${e.serie} | ${e.cap} | ${e.classe} |
`).join('')}
`:''}
04 — CONDIÇÕES COMERCIAIS
| Forma de Pagamento | PIX (5% desconto) | Cartão até 12x | Transferência Bancária |
| Prazo de Execução | 3 a 7 dias úteis após aprovação e pagamento do sinal (30%) |
| Garantia | Correção gratuita de bugs. 10 alterações simples sem prazo de expiração. |
| Validade da Proposta | ${fmt.date(p.validade)} |
|---|
VALOR TOTAL: ${fmt.money(p.valor)}
Aprovado pelo Cliente
${cli?.contato||'—'} — ${cli?.razaoSocial||'—'}
Responsável Comercial
${config.nome}
${config.email}