UNPKG

@accounter/server

Version:
238 lines • 7.98 kB
import { __decorate, __metadata } from "tslib"; import DataLoader from 'dataloader'; import { Injectable, Scope } from 'graphql-modules'; import { sql } from '@pgtyped/runtime'; import { reassureOwnerIdExists } from '../../../shared/helpers/index.js'; import { TenantAwareDBClient } from '../../app-providers/tenant-db-client.js'; import { AuthContextProvider } from '../../auth/providers/auth-context.provider.js'; import { BusinessesProvider } from '../../financial-entities/providers/businesses.provider.js'; const getAllOpenContracts = sql ` SELECT * FROM accounter_schema.clients_contracts WHERE is_active IS TRUE;`; const getContractsByIds = sql ` SELECT * FROM accounter_schema.clients_contracts WHERE id In $$ids;`; const getContractsByAdminBusinessIds = sql ` SELECT * FROM accounter_schema.clients_contracts WHERE owner_id IN $$adminBusinessIds;`; const getContractsByClientIds = sql ` SELECT * FROM accounter_schema.clients_contracts WHERE client_id IN $$clientIds;`; const deleteContract = sql ` DELETE FROM accounter_schema.clients_contracts WHERE id = $id;`; const updateContract = sql ` UPDATE accounter_schema.clients_contracts SET client_id = COALESCE( $clientId, client_id ), purchase_orders = COALESCE( $purchaseOrders, purchase_orders ), start_date = COALESCE( $startDate, start_date ), end_date = COALESCE( $endDate, end_date ), remarks = COALESCE( $remarks, remarks ), document_type = COALESCE( $documentType, document_type ), amount = COALESCE( $amount, amount ), currency = COALESCE( $currency, currency ), billing_cycle = COALESCE( $billingCycle, billing_cycle ), product = COALESCE( $product, product ), plan = COALESCE( $plan, plan ), is_active = COALESCE( $isActive, is_active ), ms_cloud = COALESCE( $msCloud, ms_cloud ), operations_count = COALESCE( $operationsLimit, operations_count ) WHERE id = $contractId RETURNING *; `; const insertContract = sql ` INSERT INTO accounter_schema.clients_contracts ( client_id, purchase_orders, start_date, end_date, remarks, document_type, amount, currency, billing_cycle, product, plan, is_active, ms_cloud, operations_count, owner_id ) VALUES ($clientId, $purchaseOrders, $startDate, $endDate, $remarks, $documentType, $amount, $currency, $billingCycle, $product, $plan, $isActive, $msCloud, $operationsLimit, $ownerId) RETURNING *;`; let ContractsProvider = class ContractsProvider { db; businessesProvider; authContextProvider; businessIdCache = null; constructor(db, businessesProvider, authContextProvider) { this.db = db; this.businessesProvider = businessesProvider; this.authContextProvider = authContextProvider; } async getBusinessId() { if (this.businessIdCache !== null) { return this.businessIdCache; } const authContext = await this.authContextProvider.getAuthContext(); this.businessIdCache = authContext?.tenant.businessId ?? null; return this.businessIdCache; } allOpenContractsCache = null; getAllOpenContracts() { if (this.allOpenContractsCache) { return this.allOpenContractsCache; } this.allOpenContractsCache = getAllOpenContracts.run(undefined, this.db).then(contracts => { if (contracts) { contracts.map(contract => { this.getContractsByIdLoader.prime(contract.id, contract); }); } return contracts; }); return this.allOpenContractsCache; } async contractsByIds(ids) { const contracts = await getContractsByIds.run({ ids }, this.db); return ids.map(id => contracts.find(contract => contract.id === id)); } getContractsByIdLoader = new DataLoader((ids) => this.contractsByIds(ids)); async contractsByAdminBusinessIds(adminBusinessIds) { const contracts = await getContractsByAdminBusinessIds.run({ adminBusinessIds }, this.db); contracts.map(contract => { this.getContractsByIdLoader.prime(contract.id, contract); }); return adminBusinessIds.map(adminBusinessId => contracts.filter(contract => contract.owner_id === adminBusinessId)); } getContractsByAdminBusinessIdLoader = new DataLoader((adminBusinessIds) => this.contractsByAdminBusinessIds(adminBusinessIds)); async contractsByClients(clientIds) { const contracts = await getContractsByClientIds.run({ clientIds }, this.db); contracts.map(contract => { this.getContractsByIdLoader.prime(contract.id, contract); }); return clientIds.map(clientId => contracts.filter(contract => contract.client_id === clientId)); } getContractsByClientIdLoader = new DataLoader((ids) => this.contractsByClients(ids)); async createContract(params) { const businessId = await this.getBusinessId(); if (!businessId) { throw new Error('Business ID is required for creating a contract'); } const [newContract] = await insertContract.run(reassureOwnerIdExists(params, businessId), this.db); this.getContractsByIdLoader.prime(newContract.id, newContract); // Invalidate list caches this.getContractsByClientIdLoader.clear(newContract.client_id); const business = await this.businessesProvider.getBusinessByIdLoader.load(newContract.client_id); if (business?.owner_id) { this.getContractsByAdminBusinessIdLoader.clear(business.owner_id); } return newContract; } async updateContract(params) { const [updatedContract] = await updateContract.run(params, this.db); if (params.contractId) { await this.invalidateCacheForContract(params.contractId); } else { this.clearCache(); } this.getContractsByIdLoader.prime(updatedContract.id, updatedContract); return updatedContract; } async deleteContract(contractId) { await deleteContract.run({ id: contractId }, this.db); await this.invalidateCacheForContract(contractId); return true; } async invalidateCacheForContract(contractId) { const contract = await this.getContractsByIdLoader.load(contractId); if (contract) { this.getContractsByClientIdLoader.clear(contract.client_id); const business = await this.businessesProvider.getBusinessByIdLoader.load(contract.client_id); if (business?.owner_id) { this.getContractsByAdminBusinessIdLoader.clear(business.owner_id); } } this.allOpenContractsCache = null; } clearCache() { this.getContractsByAdminBusinessIdLoader.clearAll(); this.getContractsByClientIdLoader.clearAll(); this.getContractsByIdLoader.clearAll(); this.allOpenContractsCache = null; } }; ContractsProvider = __decorate([ Injectable({ scope: Scope.Operation, global: true, }), __metadata("design:paramtypes", [TenantAwareDBClient, BusinessesProvider, AuthContextProvider]) ], ContractsProvider); export { ContractsProvider }; //# sourceMappingURL=contracts.provider.js.map