From aa52e7d02ce9f75fac82f82bf332512f11106986 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Mon, 18 Sep 2023 10:15:55 +0200 Subject: [PATCH] feat(server): soft deleting tax rates --- .../20230810191606_create_tax_rates.js | 4 +- packages/server/src/models/TaxRate.ts | 8 ++ .../src/services/TaxRates/EditTaxRate.ts | 80 ++++++++++++++++--- 3 files changed, 77 insertions(+), 15 deletions(-) diff --git a/packages/server/src/database/migrations/20230810191606_create_tax_rates.js b/packages/server/src/database/migrations/20230810191606_create_tax_rates.js index d9a115ef9..6fed0a6fa 100644 --- a/packages/server/src/database/migrations/20230810191606_create_tax_rates.js +++ b/packages/server/src/database/migrations/20230810191606_create_tax_rates.js @@ -6,8 +6,8 @@ exports.up = (knex) => { table.string('code'); table.decimal('rate'); table.string('description'); - table.boolean('is_non_recoverable'); - table.boolean('is_compound'); + table.boolean('is_non_recoverable').defaultTo(false); + table.boolean('is_compound').defaultTo(false); table.boolean('active').defaultTo(false); table.date('deleted_at'); table.timestamps(); diff --git a/packages/server/src/models/TaxRate.ts b/packages/server/src/models/TaxRate.ts index b137a24d2..74df20e56 100644 --- a/packages/server/src/models/TaxRate.ts +++ b/packages/server/src/models/TaxRate.ts @@ -1,6 +1,7 @@ import { mixin, Model, raw } from 'objection'; import TenantModel from 'models/TenantModel'; import ModelSearchable from './ModelSearchable'; +import SoftDeleteQueryBuilder from '@/collection/SoftDeleteQueryBuilder'; export default class TaxRate extends mixin(TenantModel, [ModelSearchable]) { /** @@ -10,6 +11,13 @@ export default class TaxRate extends mixin(TenantModel, [ModelSearchable]) { return 'tax_rates'; } + /** + * Soft delete query builder. + */ + static get QueryBuilder() { + return SoftDeleteQueryBuilder; + } + /** * Timestamps columns. */ diff --git a/packages/server/src/services/TaxRates/EditTaxRate.ts b/packages/server/src/services/TaxRates/EditTaxRate.ts index 7ae9bbfd7..fc308a5c0 100644 --- a/packages/server/src/services/TaxRates/EditTaxRate.ts +++ b/packages/server/src/services/TaxRates/EditTaxRate.ts @@ -1,17 +1,18 @@ +import { Knex } from 'knex'; +import { Inject, Service } from 'typedi'; import { IEditTaxRateDTO, - ITaxRateCreatingPayload, + ITaxRate, ITaxRateEditedPayload, ITaxRateEditingPayload, } from '@/interfaces'; -import { Inject } from 'typedi'; import UnitOfWork from '../UnitOfWork'; import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; import HasTenancyService from '../Tenancy/TenancyService'; -import { Knex } from 'knex'; import { CommandTaxRatesValidators } from './CommandTaxRatesValidators'; import events from '@/subscribers/events'; +@Service() export class EditTaxRateService { @Inject() private tenancy: HasTenancyService; @@ -25,6 +26,57 @@ export class EditTaxRateService { @Inject() private validators: CommandTaxRatesValidators; + /** + * Detarmines whether the tax rate, name or code have been changed. + * @param {ITaxRate} taxRate + * @param {IEditTaxRateDTO} editTaxRateDTO + * @returns {boolean} + */ + private isTaxRateDTOChanged = ( + taxRate: ITaxRate, + editTaxRateDTO: IEditTaxRateDTO + ) => { + return ( + taxRate.rate !== editTaxRateDTO.rate || + taxRate.name !== editTaxRateDTO.name || + taxRate.code !== editTaxRateDTO.code + ); + }; + + /** + * Edits the given tax rate or creates a new if the rate or name have been changed. + * @param {number} tenantId + * @param {ITaxRate} oldTaxRate + * @param {IEditTaxRateDTO} editTaxRateDTO + * @param {Knex.Transaction} trx + * @returns {Promise} + */ + private async editTaxRateOrCreate( + tenantId: number, + oldTaxRate: ITaxRate, + editTaxRateDTO: any, + trx?: Knex.Transaction + ) { + const { TaxRate } = this.tenancy.models(tenantId); + const isTaxDTOChanged = this.isTaxRateDTOChanged( + oldTaxRate, + editTaxRateDTO + ); + if (isTaxDTOChanged) { + // Soft deleting the old tax rate. + await TaxRate.query(trx).findById(oldTaxRate.id).delete(); + + // Create a new tax rate with new edited data. + return TaxRate.query(trx).insertAndFetch({ + ...editTaxRateDTO, + }); + } else { + return TaxRate.query(trx).patchAndFetchById(oldTaxRate.id, { + ...editTaxRateDTO, + }); + } + } + /** * Edits the given tax rate. * @param {number} tenantId @@ -32,32 +84,34 @@ export class EditTaxRateService { * @param {IEditTaxRateDTO} taxRateEditDTO * @returns {Promise} */ - public editTaxRate( + public async editTaxRate( tenantId: number, taxRateId: number, editTaxRateDTO: IEditTaxRateDTO ) { const { TaxRate } = this.tenancy.models(tenantId); - const oldTaxRate = TaxRate.query().findById(taxRateId); + const oldTaxRate = await TaxRate.query().findById(taxRateId); // Validates the tax rate existance. this.validators.validateTaxRateExistance(oldTaxRate); return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => { - // Triggers `onTaxRateCreating` event. - await this.eventPublisher.emitAsync(events.taxRates.onCreating, { + // Triggers `onTaxRateEditing` event. + await this.eventPublisher.emitAsync(events.taxRates.onEditing, { editTaxRateDTO, tenantId, trx, } as ITaxRateEditingPayload); - const taxRate = await TaxRate.query(trx) - .findById(taxRateId) - .patch({ ...editTaxRateDTO }); - - // Triggers `onTaxRateCreated` event. - await this.eventPublisher.emitAsync(events.taxRates.onCreated, { + const taxRate = await this.editTaxRateOrCreate( + tenantId, + oldTaxRate, + editTaxRateDTO, + trx + ); + // Triggers `onTaxRateEdited` event. + await this.eventPublisher.emitAsync(events.taxRates.onEdited, { editTaxRateDTO, taxRate, tenantId,