UNPKG

@accounter/server

Version:
130 lines 6.18 kB
import { differenceInDays } from 'date-fns'; import { GraphQLError } from 'graphql'; import { accommodationExpenseDataCollector, BusinessTripError, calculateTotalReportSummaryCategory, carRentalExpensesDataCollector, convertSummaryCategoryDataToRow, flightExpenseDataCollector, onlyUnique, otherExpensesDataCollector, travelAndSubsistenceExpensesDataCollector, } from '../helpers/business-trip-report.helper.js'; import { BusinessTripAttendeesProvider } from '../providers/business-trips-attendees.provider.js'; import { BusinessTripExpensesProvider } from '../providers/business-trips-expenses.provider.js'; import { BusinessTripTaxVariablesProvider } from '../providers/business-trips-tax-variables.provider.js'; export async function businessTripSummary(injector, dbBusinessTrip) { try { const attendees = await injector .get(BusinessTripAttendeesProvider) .getBusinessTripsAttendeesByBusinessTripIdLoader.load(dbBusinessTrip.id); if (!attendees?.length) { return { rows: [], errors: ['Attendees are not set'], }; } let fromDate; let toDate; attendees.map(attendee => { const { arrival, departure } = attendee; if (arrival && (!fromDate || arrival < fromDate)) { fromDate = arrival; } if (departure && (!toDate || departure > toDate)) { toDate = departure; } }); if (!fromDate || !toDate) { return { rows: [], errors: ['Business trip dates are not set'], }; } const expensesPromise = await injector .get(BusinessTripExpensesProvider) .getBusinessTripExtendedExpensesByBusinessTripId(dbBusinessTrip.id); const taxVariablesPromise = injector .get(BusinessTripTaxVariablesProvider) .getTaxVariablesByDateLoader.load(toDate); const [{ flightExpenses, accommodationsExpenses, travelAndSubsistenceExpenses, otherExpenses, carRentalExpenses, }, taxVariables,] = await Promise.all([expensesPromise, taxVariablesPromise]); if (!taxVariables) { return { rows: [], errors: ['Tax variables are not set'], }; } const summaryData = {}; const attendeesMap = new Map(); attendees.map(attendee => { const { arrival, departure } = attendee; let daysCount = 0; let nightsCount = 0; if (arrival && departure) { daysCount = differenceInDays(departure, arrival) + 1; nightsCount = daysCount - 1; } attendeesMap.set(attendee.id, { name: attendee.name, arrival, departure, daysCount, nightsCount, }); }); const errors = []; const [unAccommodatedDays] = await Promise.all([ accommodationExpenseDataCollector(injector, accommodationsExpenses, summaryData, dbBusinessTrip.destination, taxVariables, attendeesMap).catch(e => { if (e instanceof BusinessTripError) { errors.push(e.message); } else { console.error(`Error handling accommodation expenses`, e); throw new GraphQLError(e?.message ?? `Error handling accommodation expenses`); } }), ...flightExpenses.map(flightExpense => flightExpenseDataCollector(injector, flightExpense, summaryData).catch(e => { if (e instanceof BusinessTripError) { errors.push(e.message); } else { console.error(`Error handling flight expenses`, e); throw new GraphQLError(e?.message ?? `Error handling flight expenses`); } })), otherExpensesDataCollector(injector, otherExpenses, summaryData).catch(e => { if (e instanceof BusinessTripError) { errors.push(e.message); } else { console.error(`Error handling other expenses`, e); throw new GraphQLError(e?.message ?? `Error handling other expenses`); } }), carRentalExpensesDataCollector(injector, carRentalExpenses, summaryData, taxVariables, dbBusinessTrip.destination).catch(e => { if (e instanceof BusinessTripError) { errors.push(e.message); } else { console.error(`Error handling car rental expenses`, e); throw new GraphQLError(e?.message ?? `Error handling car rental expenses`); } }), ]); await travelAndSubsistenceExpensesDataCollector(injector, travelAndSubsistenceExpenses, summaryData, taxVariables, { destinationCode: dbBusinessTrip.destination, attendees: attendeesMap, unAccommodatedDays: unAccommodatedDays ?? 0, }).catch(e => { if (e instanceof BusinessTripError) { errors.push(e.message); } else { console.error(`Error handling travel and subsistence expenses`, e); throw new GraphQLError(e?.message ?? `Error handling travel and subsistence expenses`); } }); const totalSumCategory = calculateTotalReportSummaryCategory(summaryData); summaryData['TOTAL'] = totalSumCategory; return { rows: Object.entries(summaryData).map(([category, data]) => convertSummaryCategoryDataToRow(category, data)), errors: errors.length ? errors.filter(onlyUnique) : undefined, }; } catch (e) { console.error(`Error fetching business trip expenses`, e); throw new GraphQLError(e?.message ?? `Error fetching business trip expenses`); } } //# sourceMappingURL=business-trip-summary.resolver.js.map