import { Service, Inject } from 'typedi'; import { omit } from 'lodash'; import HasTenancyService from '@/services/Tenancy/TenancyService'; import { ICancelTransactionsLockingDTO, ITransactionLockingPartiallyDTO, ITransactionMeta, ITransactionsLockingAllDTO, ITransactionsLockingCanceled, ITransactionsLockingPartialUnlocked, TransactionsLockingGroup, TransactionsLockingType, } from '@/interfaces'; import TransactionsLockingRepository from './TransactionsLockingRepository'; import { ServiceError } from '@/exceptions'; import { ERRORS } from './constants'; import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; import events from '@/subscribers/events'; const Modules = ['all', 'sales', 'purchases', 'financial']; @Service() export default class TransactionsLockingService { @Inject() tenancy: HasTenancyService; @Inject() transactionsLockingRepo: TransactionsLockingRepository; @Inject() eventPublisher: EventPublisher; /** * Enable/disable all transacations locking. * @param {number} tenantId * @param {TransactionsLockingGroup} moduleGroup - * @param {Partial} allLockingDTO * @returns {Promise} */ public commandTransactionsLocking = async ( tenantId: number, module: TransactionsLockingGroup = TransactionsLockingGroup.All, transactionLockingDTO: Partial ): Promise => { // Validate the transaction locking module. this.validateTransactionsLockingModule(module); // Saves all transactions locking settings. await this.transactionsLockingRepo.saveTransactionsLocking( tenantId, module, { active: true, lockToDate: transactionLockingDTO.lockToDate, lockReason: transactionLockingDTO.reason, } ); // Flag transactions locking type. await this.transactionsLockingRepo.flagTransactionsLockingType( tenantId, module === TransactionsLockingGroup.All ? TransactionsLockingType.All : TransactionsLockingType.Partial ); // Triggers `onTransactionLockingPartialUnlocked` event. await this.eventPublisher.emitAsync( events.transactionsLocking.partialUnlocked, { tenantId, module, transactionLockingDTO, } as ITransactionsLockingPartialUnlocked ); // Retrieve the transaction locking meta of the given return this.transactionsLockingRepo.getTransactionsLocking( tenantId, module ); }; /** * Cancels the full transactions locking. * @param {number} tenantId * @param {TransactionsLockingGroup} moduleGroup * @param {ICancelTransactionsLockingDTO} cancelLockingDTO * @returns {Promise} */ public cancelTransactionLocking = async ( tenantId: number, module: TransactionsLockingGroup = TransactionsLockingGroup.All, cancelLockingDTO: ICancelTransactionsLockingDTO ): Promise => { // Validate the transaction locking module. this.validateTransactionsLockingModule(module); // Saves transactions locking. await this.transactionsLockingRepo.saveTransactionsLocking( tenantId, module, { active: false, unlockFromDate: '', unlockToDate: '', unlockReason: cancelLockingDTO.reason, } ); // Reset flag transactions locking type to partial. await this.transactionsLockingRepo.flagTransactionsLockingType( tenantId, TransactionsLockingType.Partial ); // Triggers `onTransactionLockingPartialUnlocked` event. await this.eventPublisher.emitAsync( events.transactionsLocking.partialUnlocked, { tenantId, module, cancelLockingDTO, } as ITransactionsLockingCanceled ); return this.transactionsLockingRepo.getTransactionsLocking( tenantId, module ); }; /** * Unlock tranactions locking partially. * @param {number} tenantId * @param {TransactionsLockingGroup} moduleGroup * @param {ITransactionLockingPartiallyDTO} partialTransactionLockingDTO * @returns {Promise} */ public unlockTransactionsLockingPartially = async ( tenantId: number, moduleGroup: TransactionsLockingGroup = TransactionsLockingGroup.All, partialTransactionLockingDTO: ITransactionLockingPartiallyDTO ): Promise => { // Validate the transaction locking module. this.validateTransactionsLockingModule(moduleGroup); // Retrieve the current transactions locking type. const lockingType = this.transactionsLockingRepo.getTransactionsLockingType(tenantId); if (moduleGroup !== TransactionsLockingGroup.All) { this.validateLockingTypeNotAll(lockingType); } // Saves transactions locking settings. await this.transactionsLockingRepo.saveTransactionsLocking( tenantId, moduleGroup, { ...omit(partialTransactionLockingDTO, ['reason']), partialUnlockReason: partialTransactionLockingDTO.reason, } ); // Retrieve transaction locking meta of the given module. return this.transactionsLockingRepo.getTransactionsLocking( tenantId, moduleGroup ); }; /** * Cancel partial transactions unlocking. * @param {number} tenantId * @param {TransactionsLockingGroup} moduleGroup */ public cancelPartialTransactionsUnlock = async ( tenantId: number, module: TransactionsLockingGroup = TransactionsLockingGroup.All ) => { // Validate the transaction locking module. this.validateTransactionsLockingModule(module); // Saves transactions locking settings. await this.transactionsLockingRepo.saveTransactionsLocking( tenantId, module, { unlockFromDate: '', unlockToDate: '', partialUnlockReason: '' } ); }; /** * Validates the transaction locking type not partial. * @param {number} tenantId */ public validateLockingTypeNotPartial = (lockingType: string) => { if (lockingType === TransactionsLockingType.Partial) { throw new ServiceError(ERRORS.TRANSACTION_LOCKING_PARTIAL); } }; /** * Validates the transaction locking type not all. * @param {number} tenantId */ public validateLockingTypeNotAll = (lockingType: string) => { if (lockingType === TransactionsLockingType.All) { throw new ServiceError(ERRORS.TRANSACTION_LOCKING_ALL); } }; /** * Validate transactions locking module. * @param {string} module */ public validateTransactionsLockingModule = (module: string) => { if (Modules.indexOf(module) === -1) { throw new ServiceError(ERRORS.TRANSACTIONS_LOCKING_MODULE_NOT_FOUND); } }; }