@accounter/server
Version:
Accounter GraphQL server
175 lines • 10.1 kB
JavaScript
// import { GraphQLError } from 'graphql';
import { GraphQLError } from 'graphql';
import { dateToTimelessDateString } from '../../../shared/helpers/index.js';
import { AdminContextProvider } from '../../admin-context/providers/admin-context.provider.js';
import { getChargeTransactionsMeta } from '../../charges/helpers/common.helper.js';
import { ChargesProvider } from '../../charges/providers/charges.provider.js';
import { DepreciationCategoriesProvider } from '../../depreciation/providers/depreciation-categories.provider.js';
import { DepreciationProvider } from '../../depreciation/providers/depreciation.provider.js';
import { calculateDepreciation } from '../helpers/depreciation-report.helper.js';
export const depreciationReportResolvers = {
Query: {
depreciationReport: async (_, { filters }, { injector }) => {
if (!filters) {
throw new GraphQLError('No filters provided');
}
const { year, financialEntityId: rawFinancialEntityId } = filters;
if (!year) {
throw new GraphQLError('Year filter is required');
}
if (typeof year !== 'number' || year < 2000 || year > new Date().getFullYear() + 5) {
throw new GraphQLError('Invalid year provided');
}
const { ownerId } = await injector.get(AdminContextProvider).getVerifiedAdminContext();
const financialEntityId = rawFinancialEntityId ?? ownerId;
if (!financialEntityId) {
throw new GraphQLError('Unable to resolve financial entity ID');
}
const yearBeginning = new Date(year, 0, 1);
const yearEnd = new Date(year, 11, 31);
const depreciationRecordsPromise = injector
.get(DepreciationProvider)
.getDepreciationRecordsByDates({
fromDate: yearBeginning,
toDate: yearEnd,
});
const depreciationCategoriesPromise = injector
.get(DepreciationCategoriesProvider)
.getAllDepreciationCategories();
const [depreciationRecords, depreciationCategories] = await Promise.all([
depreciationRecordsPromise,
depreciationCategoriesPromise,
]);
const categoryMap = new Map(depreciationCategories.map(category => [
category.id,
{
category,
assets: [],
originalCost: 0,
reportYearDelta: 0,
totalDepreciableCosts: 0,
reportYearClaimedDepreciation: 0,
pastYearsAccumulatedDepreciation: 0,
totalDepreciation: 0,
netValue: 0,
},
]));
await Promise.all(depreciationRecords.map(async (record) => {
const depreciationCategory = categoryMap.get(record.category);
if (!depreciationCategory) {
console.error('No depreciation category for depreciation record', record);
return;
}
const [charge, { transactionsMinDebitDate }] = await Promise.all([
injector.get(ChargesProvider).getChargeByIdLoader.load(record.charge_id),
getChargeTransactionsMeta(record.charge_id, injector),
]);
if (!charge || charge instanceof Error) {
console.error('No charge for depreciation record', record);
return;
}
const amount = Math.round(Number(record.amount));
const { yearlyDepreciationAmount, yearlyDepreciationRate, pastDepreciationAmount } = calculateDepreciation(Number(depreciationCategory.category.percentage), amount, record.activation_date, year, record.expiration_date ?? undefined);
const activationYear = record.activation_date.getFullYear();
const originalCost = activationYear === year ? 0 : amount;
const reportYearDelta = activationYear === year ? amount : 0;
const totalDepreciableCosts = originalCost + reportYearDelta;
const totalDepreciation = yearlyDepreciationAmount + pastDepreciationAmount;
const assetRecord = {
id: record.id,
chargeId: record.charge_id,
description: charge.user_description ?? undefined,
purchaseDate: dateToTimelessDateString(transactionsMinDebitDate ?? record.activation_date),
activationDate: dateToTimelessDateString(record.activation_date),
originalCost,
reportYearDelta,
totalDepreciableCosts,
statutoryDepreciationRate: Number(depreciationCategory.category.percentage),
claimedDepreciationRate: yearlyDepreciationRate,
reportYearClaimedDepreciation: yearlyDepreciationAmount,
pastYearsAccumulatedDepreciation: pastDepreciationAmount,
totalDepreciation,
netValue: totalDepreciableCosts - totalDepreciation,
};
depreciationCategory.assets.push(assetRecord);
depreciationCategory.originalCost += assetRecord.originalCost;
depreciationCategory.reportYearDelta += assetRecord.reportYearDelta;
depreciationCategory.totalDepreciableCosts += assetRecord.totalDepreciableCosts;
depreciationCategory.reportYearClaimedDepreciation +=
assetRecord.reportYearClaimedDepreciation;
depreciationCategory.pastYearsAccumulatedDepreciation +=
assetRecord.pastYearsAccumulatedDepreciation;
depreciationCategory.totalDepreciation += assetRecord.totalDepreciation;
depreciationCategory.netValue += assetRecord.netValue;
}));
const summary = {
originalCost: 0,
reportYearDelta: 0,
totalDepreciableCosts: 0,
reportYearClaimedDepreciation: 0,
pastYearsAccumulatedDepreciation: 0,
totalDepreciation: 0,
netValue: 0,
};
const categories = Array.from(categoryMap.values()).map(category => {
const categorySummary = {
id: `${financialEntityId}-${category.category.id}-${year}`,
category: category.category,
records: category.assets,
summary: {
id: `${financialEntityId}-${category.category.id}-${year}`,
originalCost: category.originalCost,
reportYearDelta: category.reportYearDelta,
totalDepreciableCosts: category.totalDepreciableCosts,
reportYearClaimedDepreciation: category.reportYearClaimedDepreciation,
pastYearsAccumulatedDepreciation: category.pastYearsAccumulatedDepreciation,
totalDepreciation: category.totalDepreciation,
netValue: category.netValue,
},
};
summary.originalCost += category.originalCost;
summary.reportYearDelta += category.reportYearDelta;
summary.totalDepreciableCosts += category.totalDepreciableCosts;
summary.reportYearClaimedDepreciation += category.reportYearClaimedDepreciation;
summary.pastYearsAccumulatedDepreciation += category.pastYearsAccumulatedDepreciation;
summary.totalDepreciation += category.totalDepreciation;
summary.netValue += category.netValue;
return categorySummary;
});
return {
id: `${financialEntityId}-${year}`,
categories,
summary: {
id: `${financialEntityId}-${year}`,
originalCost: summary.originalCost,
reportYearDelta: summary.reportYearDelta,
totalDepreciableCosts: summary.totalDepreciableCosts,
reportYearClaimedDepreciation: summary.reportYearClaimedDepreciation,
pastYearsAccumulatedDepreciation: summary.pastYearsAccumulatedDepreciation,
totalDepreciation: summary.totalDepreciation,
netValue: summary.netValue,
},
year,
};
},
},
DepreciationReportSummaryRecord: {
originalCost: record => (record.originalCost ? Math.round(record.originalCost) : null),
reportYearDelta: record => (record.reportYearDelta ? Math.round(record.reportYearDelta) : null),
totalDepreciableCosts: record => Math.round(record.totalDepreciableCosts),
reportYearClaimedDepreciation: record => Math.round(record.reportYearClaimedDepreciation),
pastYearsAccumulatedDepreciation: record => Math.round(record.pastYearsAccumulatedDepreciation),
totalDepreciation: record => Math.round(record.totalDepreciation),
netValue: record => Math.round(record.netValue),
},
DepreciationReportRecord: {
originalCost: record => (record.originalCost ? Math.round(record.originalCost) : null),
reportYearDelta: record => (record.reportYearDelta ? Math.round(record.reportYearDelta) : null),
totalDepreciableCosts: record => Math.round(record.totalDepreciableCosts),
reportYearClaimedDepreciation: record => Math.round(record.reportYearClaimedDepreciation),
pastYearsAccumulatedDepreciation: record => Math.round(record.pastYearsAccumulatedDepreciation),
totalDepreciation: record => Math.round(record.totalDepreciation),
netValue: record => Math.round(record.netValue),
},
};
//# sourceMappingURL=depreciation-report.resolver.js.map