@accounter/server
Version:
Accounter GraphQL server
214 lines • 11.1 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import DataLoader from 'dataloader';
import { GraphQLError } from 'graphql';
import { Injectable, Scope } from 'graphql-modules';
import { sql } from '@pgtyped/runtime';
import { reassureOwnerIdExists } from '../../../shared/helpers/index.js';
import { AdminContextProvider } from '../../admin-context/providers/admin-context.provider.js';
import { TenantAwareDBClient } from '../../app-providers/tenant-db-client.js';
import { TransactionsProvider } from '../../transactions/providers/transactions.provider.js';
import { BusinessTripAccommodationsExpensesProvider } from './business-trips-expenses-accommodations.provider.js';
import { BusinessTripCarRentalExpensesProvider } from './business-trips-expenses-car-rental.provider.js';
import { BusinessTripFlightsExpensesProvider } from './business-trips-expenses-flights.provider.js';
import { BusinessTripOtherExpensesProvider } from './business-trips-expenses-other.provider.js';
import { BusinessTripTravelAndSubsistenceExpensesProvider } from './business-trips-expenses-travel-and-subsistence.provider.js';
import { BusinessTripsProvider } from './business-trips.provider.js';
const getBusinessTripsExpensesByBusinessTripIds = sql `
SELECT *
FROM accounter_schema.extended_business_trip_transactions
WHERE business_trip_id IN $$businessTripIds;`;
const getBusinessTripsExpensesByIds = sql `
SELECT *
FROM accounter_schema.extended_business_trip_transactions
WHERE id IN $$expenseIds;`;
const updateBusinessTripExpense = sql `
UPDATE accounter_schema.business_trips_transactions
SET
business_trip_id = COALESCE(
$businessTripId,
business_trip_id
),
category = COALESCE(
$category,
category
)
WHERE
id = $businessTripExpenseId
RETURNING *;
`;
const insertBusinessTripExpense = sql `
INSERT INTO accounter_schema.business_trips_transactions (business_trip_id, category, owner_id)
VALUES($businessTripId, $category, $ownerId)
RETURNING *;`;
const deleteBusinessTripExpense = sql `
DELETE FROM accounter_schema.business_trips_transactions
WHERE id = $businessTripExpenseId
RETURNING id;
`;
let BusinessTripExpensesProvider = class BusinessTripExpensesProvider {
db;
adminContextProvider;
businessTripsProvider;
flightExpensesProvider;
accommodationsExpensesProvider;
travelAndSubsistenceExpensesProvider;
otherExpensesProvider;
carRentalExpensesProvider;
transactionsProvider;
constructor(db, adminContextProvider, businessTripsProvider, flightExpensesProvider, accommodationsExpensesProvider, travelAndSubsistenceExpensesProvider, otherExpensesProvider, carRentalExpensesProvider, transactionsProvider) {
this.db = db;
this.adminContextProvider = adminContextProvider;
this.businessTripsProvider = businessTripsProvider;
this.flightExpensesProvider = flightExpensesProvider;
this.accommodationsExpensesProvider = accommodationsExpensesProvider;
this.travelAndSubsistenceExpensesProvider = travelAndSubsistenceExpensesProvider;
this.otherExpensesProvider = otherExpensesProvider;
this.carRentalExpensesProvider = carRentalExpensesProvider;
this.transactionsProvider = transactionsProvider;
}
async batchBusinessTripsExpensesByBusinessTripIds(businessTripIds) {
const businessTrips = await getBusinessTripsExpensesByBusinessTripIds.run({
businessTripIds,
}, this.db);
return businessTripIds.map(id => businessTrips.filter(record => record.business_trip_id === id));
}
getBusinessTripsExpensesByBusinessTripIdLoader = new DataLoader((ids) => this.batchBusinessTripsExpensesByBusinessTripIds(ids));
async batchBusinessTripsExpenseMatchesByIds(expenseIds) {
const businessTripsExpenses = await getBusinessTripsExpensesByIds.run({
expenseIds,
}, this.db);
return expenseIds.map(id => businessTripsExpenses.find(record => record.id === id));
}
getBusinessTripsExpensesByIdLoader = new DataLoader((ids) => this.batchBusinessTripsExpenseMatchesByIds(ids));
updateBusinessTripExpense(params) {
return updateBusinessTripExpense.run(params, this.db);
}
async insertBusinessTripExpense(params) {
if (params.businessTripId) {
this.invalidateByBusinessTripId(params.businessTripId);
}
const { ownerId } = await this.adminContextProvider.getVerifiedAdminContext();
return insertBusinessTripExpense.run(reassureOwnerIdExists(params, ownerId), this.db);
}
async getBusinessTripExtendedExpensesByChargeId(chargeId) {
const businessTrip = await this.businessTripsProvider.getBusinessTripsByChargeIdLoader.load(chargeId);
if (!businessTrip) {
throw new GraphQLError(`Business trip not found for charge id ${chargeId}`);
}
const [allExpenses, flightExpenses, accommodationsExpenses, travelAndSubsistenceExpenses, otherExpenses, carRentalExpenses,] = await Promise.all([
this.getBusinessTripsExpensesByBusinessTripIdLoader.load(businessTrip.id),
this.flightExpensesProvider.getBusinessTripsFlightsExpensesByBusinessTripIdLoader.load(businessTrip.id),
this.accommodationsExpensesProvider.getBusinessTripsAccommodationsExpensesByBusinessTripIdLoader.load(businessTrip.id),
this.travelAndSubsistenceExpensesProvider.getBusinessTripsTravelAndSubsistenceExpensesByBusinessTripIdLoader.load(businessTrip.id),
this.otherExpensesProvider.getBusinessTripsOtherExpensesByBusinessTripIdLoader.load(businessTrip.id),
this.carRentalExpensesProvider.getBusinessTripsCarRentalExpensesByBusinessTripIdLoader.load(businessTrip.id),
]);
const extendedIds = new Set([
...flightExpenses,
...accommodationsExpenses,
...travelAndSubsistenceExpenses,
...otherExpenses,
...carRentalExpenses,
].map(t => t.id));
return {
nonExtendedExpenses: allExpenses?.filter(t => !extendedIds.has(t.id)),
flightExpenses,
accommodationsExpenses,
travelAndSubsistenceExpenses,
otherExpenses,
carRentalExpenses,
};
}
async getBusinessTripExtendedExpensesByBusinessTripId(businessTripId) {
const [allExpenses, flightExpenses, accommodationsExpenses, travelAndSubsistenceExpenses, otherExpenses, carRentalExpenses,] = await Promise.all([
this.getBusinessTripsExpensesByBusinessTripIdLoader.load(businessTripId),
this.flightExpensesProvider.getBusinessTripsFlightsExpensesByBusinessTripIdLoader.load(businessTripId),
this.accommodationsExpensesProvider.getBusinessTripsAccommodationsExpensesByBusinessTripIdLoader.load(businessTripId),
this.travelAndSubsistenceExpensesProvider.getBusinessTripsTravelAndSubsistenceExpensesByBusinessTripIdLoader.load(businessTripId),
this.otherExpensesProvider.getBusinessTripsOtherExpensesByBusinessTripIdLoader.load(businessTripId),
this.carRentalExpensesProvider.getBusinessTripsCarRentalExpensesByBusinessTripIdLoader.load(businessTripId),
]);
const extendedIds = new Set([
...flightExpenses,
...accommodationsExpenses,
...travelAndSubsistenceExpenses,
...otherExpenses,
...carRentalExpenses,
].map(t => t.id));
return {
nonExtendedExpenses: allExpenses?.filter(t => !extendedIds.has(t.id)),
flightExpenses,
accommodationsExpenses,
travelAndSubsistenceExpenses,
otherExpenses,
carRentalExpenses,
};
}
async getTransactionsByBusinessTripId(businessTripId) {
const chargeIds = await this.businessTripsProvider.getChargeIdsByBusinessTripIdLoader.load(businessTripId);
return this.transactionsProvider.transactionsByChargeIDLoader
.loadMany(chargeIds)
.then(res => res.filter(r => !(r instanceof Error)).flat());
}
deleteBusinessTripExpense(params) {
if (params.businessTripExpenseId) {
this.invalidateById(params.businessTripExpenseId);
}
return deleteBusinessTripExpense.run(params, this.db);
}
invalidateExpenseExtensionsById(expenseId) {
this.flightExpensesProvider.invalidateById(expenseId);
this.accommodationsExpensesProvider.invalidateById(expenseId);
this.travelAndSubsistenceExpensesProvider.invalidateById(expenseId);
this.otherExpensesProvider.invalidateById(expenseId);
this.carRentalExpensesProvider.invalidateById(expenseId);
}
invalidateExpenseExtensionsByBusinessTripId(businessTripId) {
this.flightExpensesProvider.invalidateByBusinessTripId(businessTripId);
this.accommodationsExpensesProvider.invalidateByBusinessTripId(businessTripId);
this.travelAndSubsistenceExpensesProvider.invalidateByBusinessTripId(businessTripId);
this.otherExpensesProvider.invalidateByBusinessTripId(businessTripId);
this.carRentalExpensesProvider.invalidateByBusinessTripId(businessTripId);
}
async invalidateById(expenseId) {
const expense = await this.getBusinessTripsExpensesByIdLoader.load(expenseId);
if (expense?.business_trip_id) {
this.getBusinessTripsExpensesByBusinessTripIdLoader.clear(expense.business_trip_id);
this.invalidateExpenseExtensionsByBusinessTripId(expense.business_trip_id);
}
this.getBusinessTripsExpensesByIdLoader.clear(expenseId);
this.invalidateExpenseExtensionsById(expenseId);
}
async invalidateByBusinessTripId(businessTripId) {
const expenses = await this.getBusinessTripsExpensesByBusinessTripIdLoader.load(businessTripId);
for (const expense of expenses ?? []) {
if (expense.id) {
this.getBusinessTripsExpensesByIdLoader.clear(expense.id);
this.invalidateExpenseExtensionsById(expense.id);
}
}
this.getBusinessTripsExpensesByBusinessTripIdLoader.clear(businessTripId);
this.invalidateExpenseExtensionsByBusinessTripId(businessTripId);
}
clearCache() {
this.getBusinessTripsExpensesByBusinessTripIdLoader.clearAll();
this.getBusinessTripsExpensesByIdLoader.clearAll();
}
};
BusinessTripExpensesProvider = __decorate([
Injectable({
scope: Scope.Operation,
global: true,
}),
__metadata("design:paramtypes", [TenantAwareDBClient,
AdminContextProvider,
BusinessTripsProvider,
BusinessTripFlightsExpensesProvider,
BusinessTripAccommodationsExpensesProvider,
BusinessTripTravelAndSubsistenceExpensesProvider,
BusinessTripOtherExpensesProvider,
BusinessTripCarRentalExpensesProvider,
TransactionsProvider])
], BusinessTripExpensesProvider);
export { BusinessTripExpensesProvider };
//# sourceMappingURL=business-trips-expenses.provider.js.map