UNPKG

@accounter/server

Version:

278 lines (252 loc) • 7.23 kB
import DataLoader from 'dataloader'; import { Injectable, Scope } from 'graphql-modules'; import { DBProvider } from '@modules/app-providers/db.provider.js'; import { sql } from '@pgtyped/runtime'; import type { Optional, TimelessDateString } from '@shared/types'; import type { IDeleteDocumentParams, IDeleteDocumentQuery, IGetAllDocumentsParams, IGetAllDocumentsQuery, IGetDocumentsByChargeIdQuery, IGetDocumentsByFiltersParams, IGetDocumentsByFiltersQuery, IGetDocumentsByFinancialEntityIdsParams, IGetDocumentsByFinancialEntityIdsQuery, IGetDocumentsByIdsQuery, IInsertDocumentsParams, IInsertDocumentsQuery, IReplaceDocumentsChargeIdParams, IReplaceDocumentsChargeIdQuery, IUpdateDocumentParams, IUpdateDocumentQuery, } from '../types.js'; const getAllDocuments = sql<IGetAllDocumentsQuery>` SELECT * FROM accounter_schema.documents ORDER BY created_at DESC; `; const getDocumentsByChargeId = sql<IGetDocumentsByChargeIdQuery>` SELECT * FROM accounter_schema.documents WHERE charge_id_new in $$chargeIds ORDER BY created_at DESC; `; const getDocumentsByFinancialEntityIds = sql<IGetDocumentsByFinancialEntityIdsQuery>` SELECT * FROM accounter_schema.documents WHERE charge_id_new IN( SELECT c.id as financial_entity_id FROM accounter_schema.charges c WHERE c.owner_id IN $$ownerIds ) ORDER BY created_at DESC; `; const getDocumentsByIds = sql<IGetDocumentsByIdsQuery>` SELECT * FROM accounter_schema.documents WHERE id IN $$Ids; `; const updateDocument = sql<IUpdateDocumentQuery>` UPDATE accounter_schema.documents SET charge_id_new = CASE WHEN $chargeId='00000000-0000-0000-0000-000000000000' THEN NULL ELSE COALESCE( $chargeId::UUID, charge_id_new, NULL ) END, currency_code = COALESCE( $currencyCode, currency_code, NULL ), date = COALESCE( $date, date, NULL ), file_url = COALESCE( $fileUrl, file_url, NULL ), id = COALESCE( id, id, NULL ), image_url = COALESCE( $imageUrl, image_url, NULL ), modified_at = NOW(), serial_number = COALESCE( $serialNumber, serial_number, NULL ), total_amount = COALESCE( $totalAmount, total_amount, NULL ), type = COALESCE( $type, type, NULL ), vat_amount = COALESCE( $vatAmount, vat_amount, NULL ), is_reviewed = COALESCE( $isReviewed, is_reviewed ), creditor_id = COALESCE( $creditorId, creditor_id ), debtor_id = COALESCE( $debtorId, debtor_id ) WHERE id = $documentId RETURNING *; `; const deleteDocument = sql<IDeleteDocumentQuery>` DELETE FROM accounter_schema.documents WHERE id = $documentId RETURNING id; `; const insertDocuments = sql<IInsertDocumentsQuery>` INSERT INTO accounter_schema.documents ( image_url, file_url, type, serial_number, date, total_amount, currency_code, vat_amount, charge_id_new ) VALUES $$document( image, file, documentType, serialNumber, date, amount, currencyCode, vat, chargeId ) RETURNING *;`; const getDocumentsByFilters = sql<IGetDocumentsByFiltersQuery>` SELECT d.* FROM accounter_schema.documents d LEFT JOIN accounter_schema.extended_charges c ON c.id = d.charge_id_new WHERE ($isIDs = 0 OR d.id IN $$IDs) AND ($fromDate ::TEXT IS NULL OR d.date::TEXT::DATE >= date_trunc('day', $fromDate ::DATE)) AND ($toDate ::TEXT IS NULL OR d.date::TEXT::DATE <= date_trunc('day', $toDate ::DATE)) AND ($isBusinessIDs = 0 OR d.debtor_id IN $$businessIDs OR d.creditor_id IN $$businessIDs) AND ($isOwnerIDs = 0 OR c.owner_id IN $$ownerIDs) AND ($isUnmatched = 0 OR c.transactions_count = 0 OR c.transactions_count IS NULL) ORDER BY created_at DESC; `; type IGetAdjustedDocumentsByFiltersParams = Optional< Omit<IGetDocumentsByFiltersParams, 'isIDs' | 'fromDate' | 'toDate' | 'isUnmatched'>, 'IDs' | 'businessIDs' | 'ownerIDs' > & { fromDate?: TimelessDateString | null; toDate?: TimelessDateString | null; unmatched?: boolean | null; }; const replaceDocumentsChargeId = sql<IReplaceDocumentsChargeIdQuery>` UPDATE accounter_schema.documents SET charge_id_new = $assertChargeID WHERE charge_id_new = $replaceChargeID RETURNING id; `; @Injectable({ scope: Scope.Singleton, global: true, }) export class DocumentsProvider { constructor(private dbProvider: DBProvider) {} public async getAllDocuments(params: IGetAllDocumentsParams) { return getAllDocuments.run(params, this.dbProvider); } private async batchDocumentsByChargeIds(chargeIds: readonly string[]) { const uniqueIDs = [...new Set(chargeIds)]; try { const docs = await getDocumentsByChargeId.run({ chargeIds: uniqueIDs }, this.dbProvider); return chargeIds.map(id => docs.filter(doc => doc.charge_id_new === id)); } catch (e) { console.error(e); return chargeIds.map(() => []); } } public getDocumentsByChargeIdLoader = new DataLoader( (keys: readonly string[]) => this.batchDocumentsByChargeIds(keys), { cache: false, }, ); public async getDocumentsByFinancialEntityIds(params: IGetDocumentsByFinancialEntityIdsParams) { return getDocumentsByFinancialEntityIds.run(params, this.dbProvider); } public async updateDocument(params: IUpdateDocumentParams) { return updateDocument.run(params, this.dbProvider); } public async deleteDocument(params: IDeleteDocumentParams) { return deleteDocument.run(params, this.dbProvider); } public async insertDocuments(params: IInsertDocumentsParams) { return insertDocuments.run(params, this.dbProvider); } public getDocumentsByFilters(params: IGetAdjustedDocumentsByFiltersParams) { const isIDs = !!params?.IDs?.filter(Boolean).length; const isBusinessIDs = !!params?.businessIDs?.filter(Boolean).length; const isOwnerIDs = !!params?.ownerIDs?.filter(Boolean).length; const fullParams: IGetDocumentsByFiltersParams = { isIDs: isIDs ? 1 : 0, isBusinessIDs: isBusinessIDs ? 1 : 0, isOwnerIDs: isOwnerIDs ? 1 : 0, fromDate: null, toDate: null, ...params, isUnmatched: params.unmatched ? 1 : 0, IDs: isIDs ? params.IDs! : [null], businessIDs: isBusinessIDs ? params.businessIDs! : [null], ownerIDs: isOwnerIDs ? params.ownerIDs! : [null], }; return getDocumentsByFilters.run(fullParams, this.dbProvider); } public async replaceDocumentsChargeId(params: IReplaceDocumentsChargeIdParams) { return replaceDocumentsChargeId.run(params, this.dbProvider); } private async batchDocumentsByIds(ids: readonly string[]) { const uniqueIDs = [...new Set(ids)]; try { const docs = await getDocumentsByIds.run({ Ids: uniqueIDs }, this.dbProvider); return ids.map(id => docs.find(doc => doc.id === id)); } catch (e) { console.error(e); return ids.map(() => null); } } public getDocumentsByIdLoader = new DataLoader( (keys: readonly string[]) => this.batchDocumentsByIds(keys), { cache: false, }, ); }