import { Inject, Service } from 'typedi'; import { ref } from 'objection'; import * as R from 'ramda'; import { ILandedCostTransactionsQueryDTO, ILandedCostTransaction, ILandedCostTransactionDOJO, ILandedCostTransactionEntry, ILandedCostTransactionEntryDOJO, } from '@/interfaces'; import TransactionLandedCost from './TransctionLandedCost'; import { formatNumber } from 'utils'; @Service() export default class LandedCostTranasctions { @Inject() private transactionLandedCost: TransactionLandedCost; /** * Retrieve the landed costs based on the given query. * @param {number} tenantId * @param {ILandedCostTransactionsQueryDTO} query * @returns {Promise} */ public getLandedCostTransactions = async ( tenantId: number, query: ILandedCostTransactionsQueryDTO ): Promise => { const { transactionType } = query; const Model = this.transactionLandedCost.getModel( tenantId, query.transactionType ); // Retrieve the model entities. const transactions = await Model.query().onBuild((q) => { q.where('allocated_cost_amount', '<', ref('landed_cost_amount')); if (query.transactionType === 'Bill') { q.withGraphFetched('entries.item'); } else if (query.transactionType === 'Expense') { q.withGraphFetched('categories.expenseAccount'); } }); const transformLandedCost = this.transactionLandedCost.transformToLandedCost(transactionType); return R.compose( this.transformLandedCostTransactions, R.map(transformLandedCost) )(transactions); }; /** * * @param transactions * @returns */ public transformLandedCostTransactions = ( transactions: ILandedCostTransaction[] ) => { return R.map(this.transformLandedCostTransaction)(transactions); }; /** * Transformes the landed cost transaction. * @param {ILandedCostTransaction} transaction */ public transformLandedCostTransaction = ( transaction: ILandedCostTransaction ): ILandedCostTransactionDOJO => { const { currencyCode } = transaction; // Formatted transaction amount. const formattedAmount = formatNumber(transaction.amount, { currencyCode }); // Formatted transaction unallocated cost amount. const formattedUnallocatedCostAmount = formatNumber( transaction.unallocatedCostAmount, { currencyCode } ); // Formatted transaction allocated cost amount. const formattedAllocatedCostAmount = formatNumber( transaction.allocatedCostAmount, { currencyCode } ); return { ...transaction, formattedAmount, formattedUnallocatedCostAmount, formattedAllocatedCostAmount, entries: R.map(this.transformLandedCostEntry(transaction))( transaction.entries ), }; }; /** * * @param {ILandedCostTransaction} transaction * @param {ILandedCostTransactionEntry} entry * @returns {ILandedCostTransactionEntryDOJO} */ public transformLandedCostEntry = R.curry( ( transaction: ILandedCostTransaction, entry: ILandedCostTransactionEntry ): ILandedCostTransactionEntryDOJO => { const { currencyCode } = transaction; // Formatted entry amount. const formattedAmount = formatNumber(entry.amount, { currencyCode }); // Formatted entry unallocated cost amount. const formattedUnallocatedCostAmount = formatNumber( entry.unallocatedCostAmount, { currencyCode } ); // Formatted entry allocated cost amount. const formattedAllocatedCostAmount = formatNumber( entry.allocatedCostAmount, { currencyCode } ); return { ...entry, formattedAmount, formattedUnallocatedCostAmount, formattedAllocatedCostAmount, }; } ); }