UNPKG

@accounter/server

Version:
229 lines • 9.38 kB
import { DocumentType } from '../../../shared/enums.js'; import { formatFinancialAmount } from '../../../shared/helpers/index.js'; import { isInvoice, isReceipt } from '../../documents/helpers/common.helper.js'; import { basicDocumentValidation } from '../../documents/helpers/validate-document.helper.js'; import { DocumentsProvider } from '../../documents/providers/documents.provider.js'; import { TaxCategoriesProvider } from '../../financial-entities/providers/tax-categories.provider.js'; import { getLedgerMeta } from '../../ledger/helpers/common.helper.js'; import { LedgerProvider } from '../../ledger/providers/ledger.provider.js'; import { MiscExpensesProvider } from '../../misc-expenses/providers/misc-expenses.provider.js'; import { getTransactionsMeta } from '../../transactions/helpers/common.helper.js'; import { TransactionsProvider } from '../../transactions/providers/transactions.provider.js'; import { ChargesProvider } from '../providers/charges.provider.js'; export async function calculateTotalAmount(chargeId, injector, defaultLocalCurrency) { try { const [charge, { transactionsAmount, transactionsCurrency }, { documentsCurrency, documentsAmount },] = await Promise.all([ injector.get(ChargesProvider).getChargeByIdLoader.load(chargeId), getChargeTransactionsMeta(chargeId, injector), getChargeDocumentsMeta(chargeId, injector), ]); if (!charge) { throw new Error(`Charge ID="${chargeId}" not found`); } if (charge.type === 'PAYROLL' && transactionsAmount) { return formatFinancialAmount(transactionsAmount, defaultLocalCurrency); } if (documentsAmount && documentsCurrency) { return formatFinancialAmount(documentsAmount, documentsCurrency); } if (transactionsAmount && transactionsCurrency) { return formatFinancialAmount(transactionsAmount, transactionsCurrency); } return null; } catch (error) { console.error('Error calculating total amount for charge:', error); throw new Error('Failed to calculate total amount for charge', { cause: error }); } } export async function getChargeBusinesses(chargeId, injector) { const [charge, transactions, documents, ledgerRecords, miscExpenses] = await Promise.all([ injector.get(ChargesProvider).getChargeByIdLoader.load(chargeId), injector.get(TransactionsProvider).transactionsByChargeIDLoader.load(chargeId), injector.get(DocumentsProvider).getDocumentsByChargeIdLoader.load(chargeId), injector.get(LedgerProvider).getLedgerRecordsByChargesIdLoader.load(chargeId), injector.get(MiscExpensesProvider).getExpensesByChargeIdLoader.load(chargeId), ]); if (!charge) { throw new Error(`Charge ID="${chargeId}" not found`); } const allBusinessIdsSet = new Set(); const mainBusinessIdsSet = new Set(); transactions.map(t => { if (t.business_id) { allBusinessIdsSet.add(t.business_id); if (!t.is_fee) { mainBusinessIdsSet.add(t.business_id); } } }); documents.map(d => { [d.creditor_id, d.debtor_id].map(id => { if (id && id !== charge.owner_id) { allBusinessIdsSet.add(id); mainBusinessIdsSet.add(id); } }); }); ledgerRecords.map(lr => { [lr.credit_entity1, lr.credit_entity2, lr.debit_entity1, lr.debit_entity2].map(id => { if (id && id !== charge.owner_id) { allBusinessIdsSet.add(id); } }); }); miscExpenses.map(me => { [me.creditor_id, me.debtor_id].map(id => { if (id && id !== charge.owner_id) { allBusinessIdsSet.add(id); } }); }); const allBusinessIds = Array.from(allBusinessIdsSet); const mainBusinessIds = Array.from(mainBusinessIdsSet); let mainBusinessId = null; if (mainBusinessIds.length === 1) { mainBusinessId = mainBusinessIds[0]; } return { allBusinessIds, mainBusinessId, }; } export async function getChargeDocumentsMeta(chargeId, injector) { const [charge, documents] = await Promise.all([ injector.get(ChargesProvider).getChargeByIdLoader.load(chargeId), injector.get(DocumentsProvider).getDocumentsByChargeIdLoader.load(chargeId), ]); if (!charge) { throw new Error(`Charge ID="${chargeId}" not found`); } let invalidDocuments = false; let receiptAmount = 0; let receiptVatAmount = null; let receiptCount = 0; let invoiceAmount = 0; let invoiceVatAmount = null; let invoiceCount = 0; let proformaAmount = null; const currenciesSet = new Set(); const proformaCurrencySet = new Set(); let documentsMinAccountancyDate = null; let documentsMinAnyDate = null; let documentsMaxAccountancyDate = null; let documentsMaxDate = null; documents.map(d => { const amount = d.total_amount ?? 0; let factor = 1; if (d.debtor_id === charge.owner_id) { factor *= -1; } if (d.date) { documentsMinAnyDate ??= d.date; if (documentsMinAnyDate > d.date) { documentsMinAnyDate = d.date; } documentsMaxDate ??= d.date; if (documentsMaxDate < d.date) { documentsMaxDate = d.date; } } if (isInvoice(d.type)) { invoiceCount++; invoiceAmount += amount * factor; if (d.vat_amount != null) { invoiceVatAmount ??= 0; invoiceVatAmount += (d.vat_amount ?? 0) * factor; } if (d.date) { documentsMinAccountancyDate ??= d.date; if (documentsMinAccountancyDate > d.date) { documentsMinAccountancyDate = d.date; } documentsMaxAccountancyDate ??= d.date; if (documentsMaxAccountancyDate < d.date) { documentsMaxAccountancyDate = d.date; } } if (d.currency_code) { currenciesSet.add(d.currency_code); } } if (isReceipt(d.type)) { receiptCount++; receiptAmount += amount * factor; if (d.vat_amount != null) { receiptVatAmount ??= 0; receiptVatAmount += (d.vat_amount ?? 0) * factor; } if (d.date) { documentsMinAccountancyDate ??= d.date; if (documentsMinAccountancyDate > d.date) { documentsMinAccountancyDate = d.date; } documentsMaxAccountancyDate ??= d.date; if (documentsMaxAccountancyDate < d.date) { documentsMaxAccountancyDate = d.date; } } if (d.currency_code) { currenciesSet.add(d.currency_code); } } if (d.type === DocumentType.Proforma) { proformaAmount ??= 0; proformaAmount += amount * factor; if (d.currency_code) { proformaCurrencySet.add(d.currency_code); } } if (!basicDocumentValidation(d)) { invalidDocuments = true; } }); const currencies = currenciesSet.size > 0 ? Array.from(currenciesSet) : Array.from(proformaCurrencySet); const documentsAmount = invoiceCount > 0 ? invoiceAmount : receiptCount > 0 ? receiptAmount : proformaAmount; return { receiptAmount, receiptCount, invoiceAmount, invoiceCount, documentsAmount, documentsVatAmount: invoiceVatAmount == null ? receiptVatAmount : invoiceVatAmount, documentsCount: documents.length, documentsCurrency: currencies.length === 1 ? currencies[0] : null, invalidDocuments, documentsMinDate: documentsMinAccountancyDate ?? documentsMinAnyDate, documentsMaxDate: documentsMaxAccountancyDate ?? documentsMaxDate, }; } export async function getChargeTransactionsMeta(chargeId, injector) { const transactions = await injector .get(TransactionsProvider) .transactionsByChargeIDLoader.load(chargeId); return getTransactionsMeta(transactions); } export async function getChargeLedgerMeta(chargeId, injector) { const ledgerRecords = await injector .get(LedgerProvider) .getLedgerRecordsByChargesIdLoader.load(chargeId); return getLedgerMeta(ledgerRecords); } export async function getChargeTaxCategoryId(chargeId, injector) { const charge = await injector.get(ChargesProvider).getChargeByIdLoader.load(chargeId); if (!charge) { throw new Error(`Charge ID="${chargeId}" not found`); } if (charge.tax_category_id) { return charge.tax_category_id; } const { mainBusinessId } = await getChargeBusinesses(chargeId, injector); if (!mainBusinessId) { return null; } const taxCategory = await injector .get(TaxCategoriesProvider) .taxCategoryByBusinessIDsLoader.load(mainBusinessId); return taxCategory?.id ?? null; } //# sourceMappingURL=common.helper.js.map