@accounter/server
Version:
Accounter GraphQL server
238 lines • 7.98 kB
JavaScript
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