Actualizar server.js
This commit is contained in:
79
server.js
79
server.js
@@ -2018,6 +2018,85 @@ app.post("/public/assignment/:token/reject", async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// 💰 MOTOR FINANCIERO Y CONTABILIDAD (PREPARADO PARA ROBOT PDF)
|
||||||
|
// ==========================================
|
||||||
|
// Creamos la tabla financiera preparada para facturas y robots
|
||||||
|
pool.query(`
|
||||||
|
CREATE TABLE IF NOT EXISTS service_financials (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
scraped_id INT REFERENCES scraped_services(id) ON DELETE CASCADE UNIQUE,
|
||||||
|
amount DECIMAL(10,2) DEFAULT 0.00,
|
||||||
|
payment_method TEXT,
|
||||||
|
is_paid BOOLEAN DEFAULT false,
|
||||||
|
invoice_ref TEXT,
|
||||||
|
pdf_raw_data JSONB,
|
||||||
|
created_at TIMESTAMP DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMP DEFAULT NOW()
|
||||||
|
);
|
||||||
|
`).catch(console.error);
|
||||||
|
|
||||||
|
// Obtener toda la contabilidad
|
||||||
|
app.get("/financials", authMiddleware, async (req, res) => {
|
||||||
|
try {
|
||||||
|
// 1. Truco de magia: Si hay servicios que no tienen ficha financiera, se la creamos automáticamente.
|
||||||
|
// Si tiene compañía asignada, le ponemos "Cobro Banco" por defecto. Si no, "Pendiente".
|
||||||
|
await pool.query(`
|
||||||
|
INSERT INTO service_financials (scraped_id, payment_method)
|
||||||
|
SELECT id,
|
||||||
|
CASE WHEN raw_data->>'Compañía' IS NOT NULL AND raw_data->>'Compañía' != '' AND raw_data->>'Compañía' != 'Particular'
|
||||||
|
THEN 'Cobro Banco'
|
||||||
|
ELSE 'Pendiente' END
|
||||||
|
FROM scraped_services
|
||||||
|
WHERE owner_id = $1 AND id NOT IN (SELECT scraped_id FROM service_financials)
|
||||||
|
`, [req.user.accountId]);
|
||||||
|
|
||||||
|
// 2. Devolvemos la lista cruzando las finanzas con los datos del servicio
|
||||||
|
const q = await pool.query(`
|
||||||
|
SELECT f.*, s.service_ref, s.raw_data, s.status
|
||||||
|
FROM service_financials f
|
||||||
|
JOIN scraped_services s ON f.scraped_id = s.id
|
||||||
|
WHERE s.owner_id = $1
|
||||||
|
ORDER BY f.updated_at DESC
|
||||||
|
`, [req.user.accountId]);
|
||||||
|
|
||||||
|
res.json({ ok: true, financials: q.rows });
|
||||||
|
} catch(e) {
|
||||||
|
console.error("Error financiero:", e);
|
||||||
|
res.status(500).json({ ok: false });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Guardar un cobro/pago
|
||||||
|
app.put("/financials/:id", authMiddleware, async (req, res) => {
|
||||||
|
try {
|
||||||
|
const { amount, payment_method } = req.body;
|
||||||
|
const parsedAmount = parseFloat(amount) || 0;
|
||||||
|
|
||||||
|
// Si el importe es mayor que 0, se marca como pagado automáticamente
|
||||||
|
const isPaid = parsedAmount > 0;
|
||||||
|
|
||||||
|
await pool.query(`
|
||||||
|
UPDATE service_financials
|
||||||
|
SET amount = $1, payment_method = $2, is_paid = $3, updated_at = NOW()
|
||||||
|
WHERE scraped_id = $4
|
||||||
|
`, [parsedAmount, payment_method, isPaid, req.params.id]);
|
||||||
|
|
||||||
|
// LOG AUTOMÁTICO DE TRAZABILIDAD
|
||||||
|
const userQ = await pool.query("SELECT full_name FROM users WHERE id=$1", [req.user.sub]);
|
||||||
|
const userName = userQ.rows[0]?.full_name || "Sistema";
|
||||||
|
await pool.query(
|
||||||
|
"INSERT INTO scraped_service_logs (scraped_id, user_name, action, details) VALUES ($1, $2, $3, $4)",
|
||||||
|
[req.params.id, userName, "Cobro Actualizado", `Importe: ${parsedAmount}€ | Método: ${payment_method}`]
|
||||||
|
);
|
||||||
|
|
||||||
|
res.json({ ok: true, is_paid: isPaid });
|
||||||
|
} catch(e) {
|
||||||
|
console.error(e);
|
||||||
|
res.status(500).json({ ok: false });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// 📖 MOTOR DE TRAZABILIDAD (LOGS)
|
// 📖 MOTOR DE TRAZABILIDAD (LOGS)
|
||||||
|
|||||||
Reference in New Issue
Block a user