@accounter/server
Version:
Accounter GraphQL server
87 lines • 3.61 kB
JavaScript
import { GraphQLError } from 'graphql';
import { Currency } from '../../../shared/enums.js';
import { dateToTimelessDateString } from '../../../shared/helpers/index.js';
import { FiatExchangeProvider } from '../providers/fiat-exchange.provider.js';
export function defineConversionBaseAndQuote(transactions) {
if (transactions.length < 2) {
throw new GraphQLError('Conversion charges must have at least two ledger records');
}
let baseTransaction = undefined;
let quoteTransaction = undefined;
const miscTransactions = [];
for (const transaction of transactions) {
if (transaction.is_fee || transaction.source_description?.includes('Fee:')) {
miscTransactions.push(transaction);
continue;
}
if (!transaction.debit_date) {
throw new GraphQLError(`Transaction ID="${transaction.id}" is missing debit date`);
}
if (Number(transaction.amount) > 0) {
if (quoteTransaction) {
throw new GraphQLError('Conversion charges must have only one quote transaction');
}
quoteTransaction = transaction;
}
else {
if (baseTransaction) {
throw new GraphQLError('Conversion charges must have only one base transaction');
}
baseTransaction = transaction;
}
}
if (!baseTransaction || !quoteTransaction) {
throw new GraphQLError('Conversion charges must have a base and a quote transactions');
}
if (baseTransaction.debit_date.getTime() !== quoteTransaction.debit_date.getTime()) {
throw new GraphQLError('Conversion transactions must have matching value dates');
}
return { baseTransaction, quoteTransaction, miscTransactions };
}
export function getRateForCurrency(currencyCode, exchangeRates, defaultLocalCurrency) {
if (currencyCode === defaultLocalCurrency) {
return 1;
}
if (currencyCode &&
[
Currency.Usd,
Currency.Eur,
Currency.Gbp,
Currency.Cad,
Currency.Jpy,
Currency.Aud,
Currency.Sek,
].includes(currencyCode)) {
const currencyKey = currencyCode.toLowerCase();
const rate = parseFloat(exchangeRates[currencyKey] ?? '');
if (Number.isNaN(rate)) {
throw new Error(`Exchange rates for date ${exchangeRates.exchange_date}, currency ${currencyCode} not found`);
}
return rate;
}
throw new Error(`New account currency ${currencyCode}`);
}
export function getClosestRateForDate(date, rates) {
const sortedRates = rates.sort((a, b) => {
return (b.exchange_date?.getTime() ?? 0) - (a.exchange_date?.getTime() ?? 0);
});
const stringifiedDate = dateToTimelessDateString(new Date(date));
const exchangeRate = sortedRates.find(rate => dateToTimelessDateString(rate.exchange_date) <= stringifiedDate);
if (!exchangeRate) {
throw new Error(`No exchange rate for date ${stringifiedDate}`);
}
return exchangeRate;
}
export function isCryptoCurrency(currency) {
return currency === Currency.Grt || currency === Currency.Usdc || currency === Currency.Eth;
}
export async function getFiatExchangeRate(injector, timelessDate, currency) {
const exchangeRates = await injector
.get(FiatExchangeProvider)
.getExchangeRatesByDatesLoader.load(new Date(timelessDate));
if (!exchangeRates?.[currency]) {
return null;
}
return parseFloat(exchangeRates[currency]);
}
//# sourceMappingURL=exchange.helper.js.map