@accounter/server
Version:
Accounter GraphQL server
129 lines (113 loc) • 5.24 kB
text/typescript
import DataLoader from 'dataloader';
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 { stringArray } from '../../charges/types.js';
import type {
IDeleteBusinessTripExpenseMatchParams,
IDeleteBusinessTripExpenseMatchQuery,
IDeleteSpecificBusinessTripExpenseMatchParams,
IDeleteSpecificBusinessTripExpenseMatchQuery,
IGetBusinessTripsExpenseMatchesByExpenseIdsQuery,
IGetBusinessTripsExpenseMatchesByTransactionIdsQuery,
IInsertBusinessTripExpenseMatchParams,
IInsertBusinessTripExpenseMatchQuery,
} from '../types.js';
const getBusinessTripsExpenseMatchesByTransactionIds = sql<IGetBusinessTripsExpenseMatchesByTransactionIdsQuery>`
SELECT *
FROM accounter_schema.business_trips_transactions_match
WHERE transaction_id in $$transactionIds;`;
const getBusinessTripsExpenseMatchesByExpenseIds = sql<IGetBusinessTripsExpenseMatchesByExpenseIdsQuery>`
SELECT *
FROM accounter_schema.business_trips_transactions_match
WHERE business_trip_transaction_id in $$expenseIds;`;
const insertBusinessTripExpenseMatch = sql<IInsertBusinessTripExpenseMatchQuery>`
INSERT INTO accounter_schema.business_trips_transactions_match (business_trip_transaction_id, transaction_id, amount, owner_id)
VALUES($businessTripExpenseId, $transactionId, $amount, $ownerId)
RETURNING *;`;
const deleteBusinessTripExpenseMatch = sql<IDeleteBusinessTripExpenseMatchQuery>`
DELETE FROM accounter_schema.business_trips_transactions_match
WHERE business_trip_transaction_id = $businessTripExpenseId
RETURNING *;`;
const deleteSpecificBusinessTripExpenseMatch = sql<IDeleteSpecificBusinessTripExpenseMatchQuery>`
DELETE FROM accounter_schema.business_trips_transactions_match
WHERE business_trip_transaction_id = $businessTripExpenseId
AND transaction_id = $transactionId
RETURNING *;`;
({
scope: Scope.Operation,
global: true,
})
export class BusinessTripExpensesTransactionsMatchProvider {
constructor(
private db: TenantAwareDBClient,
private adminContextProvider: AdminContextProvider,
) {}
private async batchBusinessTripsExpenseMatchesByTransactionIds(
transactionIds: readonly string[],
) {
const businessTrips = await getBusinessTripsExpenseMatchesByTransactionIds.run(
{
transactionIds: transactionIds as stringArray,
},
this.db,
);
return transactionIds.map(id => businessTrips.filter(record => record.transaction_id === id));
}
public getBusinessTripsExpenseMatchesByTransactionIdLoader = new DataLoader(
(ids: readonly string[]) => this.batchBusinessTripsExpenseMatchesByTransactionIds(ids),
);
private async batchBusinessTripsExpenseMatchesByExpenseIds(expenseIds: readonly string[]) {
const businessTrips = await getBusinessTripsExpenseMatchesByExpenseIds.run(
{
expenseIds: expenseIds as stringArray,
},
this.db,
);
return expenseIds.map(id =>
businessTrips.filter(record => record.business_trip_transaction_id === id),
);
}
public getBusinessTripsExpenseMatchesByExpenseIdLoader = new DataLoader(
(ids: readonly string[]) => this.batchBusinessTripsExpenseMatchesByExpenseIds(ids),
);
public async insertBusinessTripExpenseMatch(params: IInsertBusinessTripExpenseMatchParams) {
if (params.businessTripExpenseId) {
this.getBusinessTripsExpenseMatchesByExpenseIdLoader.clear(params.businessTripExpenseId);
}
if (params.transactionId) {
this.getBusinessTripsExpenseMatchesByTransactionIdLoader.clear(params.transactionId);
}
const { ownerId } = await this.adminContextProvider.getVerifiedAdminContext();
return insertBusinessTripExpenseMatch.run(reassureOwnerIdExists(params, ownerId), this.db);
}
public async deleteBusinessTripExpenseMatch(params: IDeleteBusinessTripExpenseMatchParams) {
if (params.businessTripExpenseId) {
const expenses = await this.getBusinessTripsExpenseMatchesByExpenseIdLoader.load(
params.businessTripExpenseId,
);
expenses.map(expense => {
this.getBusinessTripsExpenseMatchesByTransactionIdLoader.clear(expense.transaction_id);
});
this.getBusinessTripsExpenseMatchesByExpenseIdLoader.clear(params.businessTripExpenseId);
}
return deleteBusinessTripExpenseMatch.run(params, this.db);
}
public async deleteSpecificBusinessTripExpenseMatch(
params: IDeleteSpecificBusinessTripExpenseMatchParams,
) {
if (params.businessTripExpenseId) {
this.getBusinessTripsExpenseMatchesByExpenseIdLoader.clear(params.businessTripExpenseId);
}
if (params.transactionId) {
this.getBusinessTripsExpenseMatchesByTransactionIdLoader.clear(params.transactionId);
}
return deleteSpecificBusinessTripExpenseMatch.run(params, this.db);
}
public clearCache() {
this.getBusinessTripsExpenseMatchesByTransactionIdLoader.clearAll();
this.getBusinessTripsExpenseMatchesByExpenseIdLoader.clearAll();
}
}