65 lines
3.1 KiB
JavaScript
65 lines
3.1 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.generateFinancialReport = generateFinancialReport;
|
|
exports.toCsv = toCsv;
|
|
const prisma_1 = require("../lib/prisma");
|
|
async function generateFinancialReport(companyId, startDate, endDate) {
|
|
const reservations = await prisma_1.prisma.reservation.findMany({
|
|
where: { companyId, status: { in: ['CONFIRMED', 'ACTIVE', 'COMPLETED'] }, startDate: { gte: startDate }, endDate: { lte: endDate } },
|
|
include: {
|
|
vehicle: { select: { make: true, model: true, year: true, licensePlate: true } },
|
|
customer: { select: { firstName: true, lastName: true, email: true } },
|
|
rentalPayments: { where: { status: 'SUCCEEDED' } },
|
|
insurances: true,
|
|
additionalDrivers: true,
|
|
},
|
|
orderBy: { startDate: 'asc' },
|
|
});
|
|
const summary = {
|
|
totalReservations: reservations.length,
|
|
totalRentalRevenue: reservations.reduce((s, r) => s + r.dailyRate * r.totalDays, 0),
|
|
totalDiscounts: reservations.reduce((s, r) => s + r.discountAmount, 0),
|
|
totalInsurance: reservations.reduce((s, r) => s + r.insuranceTotal, 0),
|
|
totalAdditionalDrivers: reservations.reduce((s, r) => s + r.additionalDriverTotal, 0),
|
|
totalPricingRulesAdj: reservations.reduce((s, r) => s + r.pricingRulesTotal, 0),
|
|
totalDeposits: reservations.reduce((s, r) => s + r.depositAmount, 0),
|
|
totalCollected: reservations.reduce((s, r) => s + r.totalAmount, 0),
|
|
averageRentalDays: reservations.length > 0 ? reservations.reduce((s, r) => s + r.totalDays, 0) / reservations.length : 0,
|
|
};
|
|
const rows = reservations.map((r) => ({
|
|
reservationId: r.id,
|
|
contractNumber: r.contractNumber ?? '—',
|
|
invoiceNumber: r.invoiceNumber ?? '—',
|
|
customerName: `${r.customer.firstName} ${r.customer.lastName}`,
|
|
vehicle: `${r.vehicle.year} ${r.vehicle.make} ${r.vehicle.model}`,
|
|
plate: r.vehicle.licensePlate,
|
|
startDate: r.startDate.toISOString().split('T')[0],
|
|
endDate: r.endDate.toISOString().split('T')[0],
|
|
days: r.totalDays,
|
|
dailyRate: r.dailyRate,
|
|
baseAmount: r.dailyRate * r.totalDays,
|
|
discount: r.discountAmount,
|
|
insurance: r.insuranceTotal,
|
|
additionalDriver: r.additionalDriverTotal,
|
|
pricingAdj: r.pricingRulesTotal,
|
|
deposit: r.depositAmount,
|
|
totalAmount: r.totalAmount,
|
|
paymentStatus: r.rentalPayments[0]?.status ?? 'UNPAID',
|
|
paymentMethod: r.rentalPayments[0]?.paymentMethod ?? '—',
|
|
source: r.source,
|
|
}));
|
|
return { summary, rows, period: { startDate, endDate } };
|
|
}
|
|
function toCsv(rows) {
|
|
if (rows.length === 0)
|
|
return '';
|
|
const headers = Object.keys(rows[0]);
|
|
return [
|
|
headers.join(','),
|
|
...rows.map((row) => headers.map((h) => {
|
|
const val = row[h] ?? '';
|
|
return typeof val === 'string' && val.includes(',') ? `"${val}"` : String(val);
|
|
}).join(',')),
|
|
].join('\n');
|
|
}
|
|
//# sourceMappingURL=financialReportService.js.map
|