UNPKG

@accounter/server

Version:
164 lines (152 loc) • 6.92 kB
import { GraphQLError, GraphQLResolveInfo } from 'graphql'; import { Injector } from 'graphql-modules'; import type { CommonError, Maybe, ResolverFn, ResolversParentTypes, ResolversTypes, ResolverTypeWrapper, } from '../../../__generated__/types.js'; import { ChargeTypeEnum } from '../../../shared/enums.js'; import { LedgerRecordsProto } from '../../../shared/types/index.js'; import { AdminContextProvider } from '../../admin-context/providers/admin-context.provider.js'; import { BusinessTripAttendeesProvider } from '../../business-trips/providers/business-trips-attendees.provider.js'; import { getChargeType } from '../../charges/helpers/charge-type.js'; import type { IGetChargesByIdsResult } from '../../charges/types.js'; import { LedgerProvider } from '../providers/ledger.provider.js'; import { UnbalancedBusinessesProvider } from '../providers/unbalanced-businesses.provider.js'; import { generateLedgerRecordsForBankDeposit } from '../resolvers/ledger-generation/bank-deposit-ledger-generation.resolver.js'; import { generateLedgerRecordsForBusinessTrip } from '../resolvers/ledger-generation/business-trip-ledger-generation.resolver.js'; import { generateLedgerRecordsForCommonCharge } from '../resolvers/ledger-generation/common-ledger-generation.resolver.js'; import { generateLedgerRecordsForConversion } from '../resolvers/ledger-generation/conversion-ledger-generation.resolver.js'; import { generateLedgerRecordsForDividend } from '../resolvers/ledger-generation/dividend-ledger-generation.resolver.js'; import { generateLedgerRecordsForFinancialCharge } from '../resolvers/ledger-generation/financial-ledger-generation.resolver.js'; import { generateLedgerRecordsForForeignSecurities } from '../resolvers/ledger-generation/foreign-securities-ledger-generation.resolver.js'; import { generateLedgerRecordsForInternalTransfer } from '../resolvers/ledger-generation/internal-transfer-ledger-generation.resolver.js'; import { generateLedgerRecordsForMonthlyVat } from '../resolvers/ledger-generation/monthly-vat-ledger-generation.resolver.js'; import { generateLedgerRecordsForSalary } from '../resolvers/ledger-generation/salary-ledger-generation.resolver.js'; import { isChargeLocked } from './ledger-lock.js'; const resolveLockedCharge: ResolverFn< Maybe<ResolversTypes['GeneratedLedgerRecords']>, ResolversParentTypes['Charge'], GraphQLModules.Context, object > = async (charge, _, context, __) => { try { const records = await context.injector .get(LedgerProvider) .getLedgerRecordsByChargesIdLoader.load(charge.id); return { records, charge, balance: { isBalanced: true, unbalancedEntities: [], balanceSum: 0, financialEntities: [], }, errors: [], }; } catch (e) { console.error(e); throw new GraphQLError(`Error loading ledger records for charge ID="${charge.id}"`); } }; export async function ledgerGenerationByCharge( charge: IGetChargesByIdsResult, params: { insertLedgerRecordsIfNotExists: boolean; }, context: GraphQLModules.ModuleContext, info: GraphQLResolveInfo, ): Promise<Maybe<ResolverTypeWrapper<CommonError | LedgerRecordsProto>>> { const { injector } = context; const { ledgerLock } = await injector.get(AdminContextProvider).getVerifiedAdminContext(); if (await isChargeLocked(charge, injector, ledgerLock)) { return resolveLockedCharge(charge, params, context, info); } const chargeType = await getChargeType(charge, injector); type LedgerGenFunction = ResolverFn< Maybe<ResolverTypeWrapper<CommonError | LedgerRecordsProto>>, IGetChargesByIdsResult, GraphQLModules.ModuleContext, { insertLedgerRecordsIfNotExists: boolean; } >; const ledgerGenerationMap: Record<ChargeTypeEnum, LedgerGenFunction> = { [ChargeTypeEnum.Common]: generateLedgerRecordsForCommonCharge, [ChargeTypeEnum.Conversion]: generateLedgerRecordsForConversion, [ChargeTypeEnum.Salary]: generateLedgerRecordsForSalary, [ChargeTypeEnum.InternalTransfer]: generateLedgerRecordsForInternalTransfer, [ChargeTypeEnum.Dividend]: generateLedgerRecordsForDividend, [ChargeTypeEnum.BusinessTrip]: generateLedgerRecordsForBusinessTrip, [ChargeTypeEnum.MonthlyVat]: generateLedgerRecordsForMonthlyVat, [ChargeTypeEnum.BankDeposit]: generateLedgerRecordsForBankDeposit, [ChargeTypeEnum.ForeignSecurities]: generateLedgerRecordsForForeignSecurities, [ChargeTypeEnum.CreditcardBankCharge]: generateLedgerRecordsForCommonCharge, [ChargeTypeEnum.Financial]: generateLedgerRecordsForFinancialCharge, }; const generationFunction = ledgerGenerationMap[chargeType]; if (generationFunction) { return generationFunction(charge, params, context, info); } throw new Error(`Unknown charge type: ${chargeType}`); } export async function ledgerUnbalancedBusinessesByCharge( charge: IGetChargesByIdsResult, injector: Injector, ): Promise<Set<string> | undefined> { const chargeType = await getChargeType(charge, injector); switch (chargeType) { case 'CommonCharge': { const unbalancedBusinesses = await injector .get(UnbalancedBusinessesProvider) .getChargeUnbalancedBusinessesByChargeIds.load(charge.id); const allowedUnbalancedBusinesses = new Set( unbalancedBusinesses.map(({ business_id }) => business_id), ); return allowedUnbalancedBusinesses; } case 'ConversionCharge': return undefined; case 'SalaryCharge': { const unbalancedBusinesses = await injector .get(UnbalancedBusinessesProvider) .getChargeUnbalancedBusinessesByChargeIds.load(charge.id); const allowedUnbalancedBusinesses = new Set( unbalancedBusinesses.map(({ business_id }) => business_id), ); return allowedUnbalancedBusinesses; } case 'InternalTransferCharge': return undefined; case 'DividendCharge': /////////// // TODO // ////////// return undefined; case 'BusinessTripCharge': { const businessTripAttendees = await injector .get(BusinessTripAttendeesProvider) .getBusinessTripsAttendeesByChargeIdLoader.load(charge.id); const allowedUnbalancedBusinesses = new Set( businessTripAttendees.map(attendee => attendee.id), ); return allowedUnbalancedBusinesses; } case 'MonthlyVatCharge': return undefined; case 'BankDepositCharge': throw new Error('Bank Deposit Charge is not supported yet'); case 'ForeignSecuritiesCharge': throw new Error('Foreign Securities Charge is not supported yet'); case 'CreditcardBankCharge': throw new Error('Credit Card Bank Charge is not supported yet'); case 'FinancialCharge': throw new Error('Financial Charge is not supported yet'); default: throw new Error(`Unknown charge type: ${chargeType}`); } }