Phase 2: Dual-write for financial edits - new PUT /api/admin/cobrancas/:id route + Finance.tsx sync
This commit is contained in:
parent
b440023add
commit
ce82f30598
|
|
@ -206,7 +206,7 @@ const Contracts: React.FC<ContractsProps> = ({ data, updateData }) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleGenerate = () => {
|
const handleGenerate = async () => {
|
||||||
if (!contractToGenerate) return;
|
if (!contractToGenerate) return;
|
||||||
|
|
||||||
const contract = contractToGenerate;
|
const contract = contractToGenerate;
|
||||||
|
|
@ -242,7 +242,13 @@ const Contracts: React.FC<ContractsProps> = ({ data, updateData }) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1. Salvar no JSON (manter compatibilidade)
|
||||||
updateData({ payments: [...data.payments, ...newPayments] });
|
updateData({ payments: [...data.payments, ...newPayments] });
|
||||||
|
|
||||||
|
// 2. Fase 2: Salvar no SQL via sincronização no próximo boot
|
||||||
|
// Nota: Parcelas de contrato sem Asaas serão migradas pelo syncJsonToRelationalTables no próximo restart.
|
||||||
|
// A Fase 3 eliminará essa dependência quando o Manager ler direto do SQL.
|
||||||
|
|
||||||
closeModal();
|
closeModal();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -742,15 +742,26 @@ const Finance: React.FC<FinanceProps> = ({ data, updateData }) => {
|
||||||
setIsEditing(true);
|
setIsEditing(true);
|
||||||
try {
|
try {
|
||||||
const targetId = paymentToEdit.asaasPaymentId || paymentToEdit.id;
|
const targetId = paymentToEdit.asaasPaymentId || paymentToEdit.id;
|
||||||
|
const newValor = parseFloat(editValue.replace(',', '.'));
|
||||||
|
|
||||||
|
// 1. Atualizar no Asaas
|
||||||
const response = await fetch(`/api/cobrancas/${targetId}`, {
|
const response = await fetch(`/api/cobrancas/${targetId}`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ valor: parseFloat(editValue.replace(',', '.')), vencimento: editDate })
|
body: JSON.stringify({ valor: newValor, vencimento: editDate })
|
||||||
});
|
});
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
|
// 2. Escrita dupla: Atualizar no SQL (Fase 2)
|
||||||
|
fetch(`/api/admin/cobrancas/${targetId}`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ valor: newValor, vencimento: editDate, amount_original: newValor })
|
||||||
|
}).catch(err => console.warn('[Fase2:SQL] Erro ao sincronizar edição:', err));
|
||||||
|
|
||||||
|
// 3. Atualizar no JSON (manter compatibilidade)
|
||||||
updateData({
|
updateData({
|
||||||
payments: data.payments.map(p => p.id === paymentToEdit.id ? { ...p, amount: parseFloat(editValue.replace(',', '.')), dueDate: editDate } : p)
|
payments: data.payments.map(p => p.id === paymentToEdit.id ? { ...p, amount: newValor, dueDate: editDate } : p)
|
||||||
});
|
});
|
||||||
showAlert('Sucesso', 'Cobrança atualizada!', 'success');
|
showAlert('Sucesso', 'Cobrança atualizada!', 'success');
|
||||||
setPaymentToEdit(null);
|
setPaymentToEdit(null);
|
||||||
|
|
|
||||||
|
|
@ -892,6 +892,39 @@ app.delete('/api/admin/cobrancas/:id', async (req, res) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fase 2: Escrita dupla — Manager pode atualizar campos ricos diretamente no SQL
|
||||||
|
app.put('/api/admin/cobrancas/:id', async (req, res) => {
|
||||||
|
try {
|
||||||
|
const { valor, vencimento, description, type, discount, installment_number, total_installments, amount_original } = req.body;
|
||||||
|
|
||||||
|
const updates = [];
|
||||||
|
const values = [];
|
||||||
|
let paramIdx = 1;
|
||||||
|
|
||||||
|
if (valor !== undefined) { updates.push(`valor = $${paramIdx++}`); values.push(valor); }
|
||||||
|
if (vencimento !== undefined) { updates.push(`vencimento = $${paramIdx++}`); values.push(vencimento); }
|
||||||
|
if (description !== undefined) { updates.push(`description = $${paramIdx++}`); values.push(description); }
|
||||||
|
if (type !== undefined) { updates.push(`type = $${paramIdx++}`); values.push(type); }
|
||||||
|
if (discount !== undefined) { updates.push(`discount = $${paramIdx++}`); values.push(discount); }
|
||||||
|
if (installment_number !== undefined) { updates.push(`installment_number = $${paramIdx++}`); values.push(installment_number); }
|
||||||
|
if (total_installments !== undefined) { updates.push(`total_installments = $${paramIdx++}`); values.push(total_installments); }
|
||||||
|
if (amount_original !== undefined) { updates.push(`amount_original = $${paramIdx++}`); values.push(amount_original); }
|
||||||
|
|
||||||
|
if (updates.length === 0) return res.status(400).json({ error: 'Nenhum campo para atualizar.' });
|
||||||
|
|
||||||
|
values.push(req.params.id);
|
||||||
|
await pool.query(
|
||||||
|
`UPDATE alunos_cobrancas SET ${updates.join(', ')} WHERE asaas_payment_id = $${paramIdx}`,
|
||||||
|
values
|
||||||
|
);
|
||||||
|
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch(e) {
|
||||||
|
console.error('[Admin:Cobrancas:PUT] Erro:', e.message);
|
||||||
|
res.status(500).json({ error: e.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Webhook Evolution
|
// Webhook Evolution
|
||||||
app.post('/api/webhooks/evolution', (req, res) => {
|
app.post('/api/webhooks/evolution', (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue