| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- const express = require('express');
- const PDFDocument = require('pdfkit');
- const db = require('../db');
- const { authMiddleware } = require('../auth');
- const router = express.Router();
- router.use(authMiddleware);
- const MONTHS_FR = ['Janvier','Février','Mars','Avril','Mai','Juin','Juillet','Août','Septembre','Octobre','Novembre','Décembre'];
- router.get('/:paymentId', (req, res) => {
- const payment = db.prepare(`
- SELECT p.*,
- l.rent_amount, l.charges_amount, l.deposit_amount,
- pr.name as property_name, pr.address as property_address, pr.city as property_city, pr.zip_code as property_zip,
- t.first_name as tenant_first_name, t.last_name as tenant_last_name, t.email as tenant_email,
- u.name as owner_name, u.email as owner_email
- FROM payments p
- JOIN leases l ON p.lease_id = l.id
- JOIN properties pr ON l.property_id = pr.id
- JOIN tenants t ON l.tenant_id = t.id
- JOIN users u ON p.user_id = u.id
- WHERE p.id = ? AND p.user_id = ?
- `).get(req.params.paymentId, req.userId);
- if (!payment) return res.status(404).json({ error: 'Paiement non trouvé' });
- const doc = new PDFDocument({ size: 'A4', margin: 50 });
- res.setHeader('Content-Type', 'application/pdf');
- res.setHeader('Content-Disposition', `attachment; filename=quittance_${payment.period_year}_${String(payment.period_month).padStart(2,'0')}.pdf`);
- doc.pipe(res);
- const monthName = MONTHS_FR[payment.period_month - 1];
- const total = payment.rent_paid + payment.charges_paid;
- // Header
- doc.fontSize(22).font('Helvetica-Bold').text('QUITTANCE DE LOYER', { align: 'center' });
- doc.moveDown(0.3);
- doc.fontSize(14).font('Helvetica').text(`Période : ${monthName} ${payment.period_year}`, { align: 'center' });
- doc.moveDown(1.5);
- // Separator
- doc.moveTo(50, doc.y).lineTo(545, doc.y).strokeColor('#2563eb').lineWidth(2).stroke();
- doc.moveDown(1);
- // Bailleur
- doc.fontSize(12).font('Helvetica-Bold').text('BAILLEUR');
- doc.font('Helvetica').fontSize(11)
- .text(payment.owner_name)
- .text(payment.owner_email);
- doc.moveDown(1);
- // Locataire
- doc.fontSize(12).font('Helvetica-Bold').text('LOCATAIRE');
- doc.font('Helvetica').fontSize(11)
- .text(`${payment.tenant_first_name} ${payment.tenant_last_name}`)
- .text(payment.tenant_email || '');
- doc.moveDown(1);
- // Bien loué
- doc.fontSize(12).font('Helvetica-Bold').text('BIEN LOUÉ');
- doc.font('Helvetica').fontSize(11)
- .text(payment.property_name)
- .text(`${payment.property_address}`)
- .text(`${payment.property_zip} ${payment.property_city}`);
- doc.moveDown(1);
- // Separator
- doc.moveTo(50, doc.y).lineTo(545, doc.y).strokeColor('#e5e7eb').lineWidth(1).stroke();
- doc.moveDown(1);
- // Détail paiement
- doc.fontSize(12).font('Helvetica-Bold').text('DÉTAIL DU RÈGLEMENT');
- doc.moveDown(0.5);
- const tableTop = doc.y;
- const col1 = 50, col2 = 400;
- const drawRow = (label, value, bold = false) => {
- const y = doc.y;
- doc.font(bold ? 'Helvetica-Bold' : 'Helvetica').fontSize(11);
- doc.text(label, col1, y);
- doc.text(`${value.toFixed(2)} €`, col2, y, { width: 100, align: 'right' });
- doc.moveDown(0.6);
- };
- drawRow('Loyer hors charges', payment.rent_paid);
- drawRow('Charges', payment.charges_paid);
- doc.moveTo(50, doc.y).lineTo(545, doc.y).strokeColor('#e5e7eb').lineWidth(0.5).stroke();
- doc.moveDown(0.3);
- drawRow('TOTAL', total, true);
- doc.moveDown(0.5);
- // Mode et date de paiement
- const paymentMethods = { virement: 'Virement bancaire', cheque: 'Chèque', especes: 'Espèces', prelevement: 'Prélèvement automatique' };
- doc.font('Helvetica').fontSize(11)
- .text(`Mode de paiement : ${paymentMethods[payment.payment_method] || payment.payment_method}`)
- .text(`Date de paiement : ${new Date(payment.payment_date).toLocaleDateString('fr-FR')}`);
- if (payment.notes) {
- doc.moveDown(0.5).text(`Notes : ${payment.notes}`);
- }
- doc.moveDown(2);
- // Attestation
- doc.moveTo(50, doc.y).lineTo(545, doc.y).strokeColor('#e5e7eb').lineWidth(1).stroke();
- doc.moveDown(1);
- doc.font('Helvetica').fontSize(10).fillColor('#6b7280')
- .text(
- `Je soussigné(e) ${payment.owner_name}, bailleur, donne quittance à ${payment.tenant_first_name} ${payment.tenant_last_name} ` +
- `pour la somme de ${total.toFixed(2)} € correspondant au paiement du loyer et des charges du logement situé ` +
- `${payment.property_address}, ${payment.property_zip} ${payment.property_city}, ` +
- `pour la période de ${monthName} ${payment.period_year}.`,
- { align: 'justify' }
- );
- doc.moveDown(3);
- doc.fontSize(11).fillColor('#000000').text(`Fait le ${new Date().toLocaleDateString('fr-FR')}`);
- doc.moveDown(2);
- doc.text('Signature du bailleur :', { continued: false });
- doc.moveDown(1);
- doc.moveTo(50, doc.y).lineTo(200, doc.y).strokeColor('#000').lineWidth(1).stroke();
- doc.end();
- });
- module.exports = router;
|