@accounter/server
Version:
Accounter GraphQL server
75 lines • 3.82 kB
JavaScript
import { GraphQLError } from 'graphql';
import { dateToTimelessDateString, formatFinancialAmount } from '../../../shared/helpers/index.js';
import { AdminContextProvider } from '../../admin-context/providers/admin-context.provider.js';
import { ExchangeProvider } from '../../exchange-rates/providers/exchange.provider.js';
import { getTransactionDebitDate } from '../../transactions/helpers/debit-date.helper.js';
import { TransactionsProvider } from '../../transactions/providers/transactions.provider.js';
export const chartsResolvers = {
Query: {
incomeExpenseChart: async (_, { filters }, { injector }) => {
try {
const { ownerId, defaultCryptoConversionFiatCurrency } = await injector
.get(AdminContextProvider)
.getVerifiedAdminContext();
const transactions = await injector.get(TransactionsProvider).getTransactionsByFilters({
fromDebitDate: filters.fromDate,
toDebitDate: filters.toDate,
ownerIDs: [ownerId],
});
const currency = filters.currency ?? defaultCryptoConversionFiatCurrency;
const monthDataMap = new Map();
await Promise.all(transactions.map(async (transaction) => {
const date = getTransactionDebitDate(transaction);
// convert amount to chart currency
const exchangeRate = await injector
.get(ExchangeProvider)
.getExchangeRates(transaction.currency, currency, date);
// add amount to relevant month
const monthTag = dateToTimelessDateString(new Date(date.getFullYear(), date.getMonth(), 1));
if (!monthDataMap.has(monthTag)) {
monthDataMap.set(monthTag, { income: 0, expense: 0, balance: 0 });
}
const monthData = monthDataMap.get(monthTag);
const amount = Number(transaction.amount);
if (amount > 0) {
monthData.income += Math.abs(amount) * exchangeRate;
}
else {
monthData.expense += Math.abs(amount) * exchangeRate;
}
}));
const INITIAL_BALANCE = 0;
let balance = INITIAL_BALANCE;
const orderedMonthInfo = Array.from(monthDataMap.entries()).sort(([dateA], [dateB]) => dateA.localeCompare(dateB));
const monthlyData = [];
for (const [date, data] of orderedMonthInfo) {
balance += data.income - data.expense;
const monthBalance = balance;
monthlyData.push({
date,
...data,
balance: monthBalance,
currency,
});
}
return {
fromDate: filters.fromDate,
toDate: filters.toDate,
currency,
monthlyData,
};
}
catch (e) {
console.error('Error fetching income/expense chart info', e);
throw new GraphQLError(e?.message ?? 'Error fetching chart info');
}
},
},
IncomeExpenseChartMonthData: {
date: proto => proto.date,
income: proto => formatFinancialAmount(proto.income, proto.currency),
expense: proto => formatFinancialAmount(proto.expense, proto.currency),
balance: proto => formatFinancialAmount(proto.balance, proto.currency),
},
};
//# sourceMappingURL=charts.resolver.js.map