import { Service, Inject } from 'typedi'; import { Knex } from 'knex'; import { ILedger } from '@/interfaces'; import { LedgerContactsBalanceStorage } from './LedgerContactStorage'; import { LedegrAccountsStorage } from './LedgetAccountStorage'; import { LedgerEntriesStorage } from './LedgerEntriesStorage'; import HasTenancyService from '@/services/Tenancy/TenancyService'; import Ledger from './Ledger'; @Service() export default class LedgerStorageService { @Inject() private ledgerEntriesService: LedgerEntriesStorage; @Inject() private ledgerContactsBalance: LedgerContactsBalanceStorage; @Inject() private ledgerAccountsBalance: LedegrAccountsStorage; @Inject() private tenancy: HasTenancyService; /** * Commit the ledger to the storage layer as one unit-of-work. * @param {number} tenantId * @param {ILedger} ledger * @returns {Promise} */ public commit = async ( tenantId: number, ledger: ILedger, trx?: Knex.Transaction ): Promise => { const tasks = [ // Saves the ledger entries. this.ledgerEntriesService.saveEntries(tenantId, ledger, trx), // Mutates the associated accounts balances. this.ledgerAccountsBalance.saveAccountsBalance(tenantId, ledger, trx), // Mutates the associated contacts balances. this.ledgerContactsBalance.saveContactsBalance(tenantId, ledger, trx), ]; await Promise.all(tasks); }; /** * Deletes the given ledger and revert balances. * @param {number} tenantId * @param {ILedger} ledger * @param {Knex.Transaction} trx * @returns {Promise} */ public delete = async ( tenantId: number, ledger: ILedger, trx?: Knex.Transaction ) => { const tasks = [ // Deletes the ledger entries. this.ledgerEntriesService.deleteEntries(tenantId, ledger, trx), // Mutates the associated accounts balances. this.ledgerAccountsBalance.saveAccountsBalance(tenantId, ledger, trx), // Mutates the associated contacts balances. this.ledgerContactsBalance.saveContactsBalance(tenantId, ledger, trx), ]; await Promise.all(tasks); }; /** * @param tenantId * @param referenceId * @param referenceType * @param trx */ public deleteByReference = async ( tenantId: number, referenceId: number | number[], referenceType: string | string[], trx?: Knex.Transaction ) => { const { transactionsRepository } = this.tenancy.repositories(tenantId); // Retrieves the transactions of the given reference. const transactions = await transactionsRepository.getTransactionsByReference( referenceId, referenceType ); // Creates a new ledger from transaction and reverse the entries. const reversedLedger = Ledger.fromTransactions(transactions).reverse(); // Deletes and reverts the balances. await this.delete(tenantId, reversedLedger, trx); }; }