diff --git a/packages/server/src/api/controllers/FinancialStatements/SalesTaxLiabilitySummary/index.ts b/packages/server/src/api/controllers/FinancialStatements/SalesTaxLiabilitySummary/index.ts index 399fbeb90..56c837288 100644 --- a/packages/server/src/api/controllers/FinancialStatements/SalesTaxLiabilitySummary/index.ts +++ b/packages/server/src/api/controllers/FinancialStatements/SalesTaxLiabilitySummary/index.ts @@ -40,7 +40,7 @@ export default class SalesTaxLiabilitySummary extends BaseFinancialReportControl } /* - * + * Retrieves the sales tax liability summary. * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - @@ -50,7 +50,7 @@ export default class SalesTaxLiabilitySummary extends BaseFinancialReportControl res: Response, next: NextFunction ) { - const { tenantId, settings } = req; + const { tenantId } = req; const filter = this.matchedQueryData(req); try { diff --git a/packages/server/src/api/controllers/Sales/SalesInvoices.ts b/packages/server/src/api/controllers/Sales/SalesInvoices.ts index 4a449f4ca..d90b94d8d 100644 --- a/packages/server/src/api/controllers/Sales/SalesInvoices.ts +++ b/packages/server/src/api/controllers/Sales/SalesInvoices.ts @@ -184,8 +184,15 @@ export default class SaleInvoicesController extends BaseController { .optional({ nullable: true }) .trim() .escape(), - check('entries.*.tax_code').optional({ nullable: true }).trim().escape(), - check('entries.*.tax_rate').optional().isNumeric().toFloat(), + check('entries.*.tax_code') + .optional({ nullable: true }) + .trim() + .escape() + .isString(), + check('entries.*.tax_rate_id') + .optional({ nullable: true }) + .isNumeric() + .toInt(), check('entries.*.warehouse_id') .optional({ nullable: true }) .isNumeric() diff --git a/packages/server/src/api/controllers/TaxRates/TaxRates.ts b/packages/server/src/api/controllers/TaxRates/TaxRates.ts index bb80985eb..f60c7e0e2 100644 --- a/packages/server/src/api/controllers/TaxRates/TaxRates.ts +++ b/packages/server/src/api/controllers/TaxRates/TaxRates.ts @@ -4,9 +4,10 @@ import { body, param } from 'express-validator'; import BaseController from '@/api/controllers/BaseController'; import asyncMiddleware from '@/api/middleware/asyncMiddleware'; import { TaxRatesApplication } from '@/services/TaxRates/TaxRatesApplication'; -import { HookNextFunction } from 'mongoose'; +import CheckAbilities from '@/api/middleware/CheckPolicies'; import { ServiceError } from '@/exceptions'; import { ERRORS } from '@/services/TaxRates/constants'; +import { AbilitySubject, TaxRateAction } from '@/interfaces'; @Service() export class TaxRatesController extends BaseController { @@ -21,6 +22,7 @@ export class TaxRatesController extends BaseController { router.post( '/', + CheckAbilities(TaxRateAction.CREATE, AbilitySubject.TaxRate), this.taxRateValidationSchema, this.validationResult, asyncMiddleware(this.createTaxRate.bind(this)), @@ -28,6 +30,7 @@ export class TaxRatesController extends BaseController { ); router.post( '/:id', + CheckAbilities(TaxRateAction.EDIT, AbilitySubject.TaxRate), [param('id').exists().toInt(), ...this.taxRateValidationSchema], this.validationResult, asyncMiddleware(this.editTaxRate.bind(this)), @@ -35,6 +38,7 @@ export class TaxRatesController extends BaseController { ); router.post( '/:id/active', + CheckAbilities(TaxRateAction.EDIT, AbilitySubject.TaxRate), [param('id').exists().toInt()], this.validationResult, asyncMiddleware(this.activateTaxRate.bind(this)), @@ -42,6 +46,7 @@ export class TaxRatesController extends BaseController { ); router.post( '/:id/inactive', + CheckAbilities(TaxRateAction.EDIT, AbilitySubject.TaxRate), [param('id').exists().toInt()], this.validationResult, asyncMiddleware(this.inactivateTaxRate.bind(this)), @@ -49,6 +54,7 @@ export class TaxRatesController extends BaseController { ); router.delete( '/:id', + CheckAbilities(TaxRateAction.DELETE, AbilitySubject.TaxRate), [param('id').exists().toInt()], this.validationResult, asyncMiddleware(this.deleteTaxRate.bind(this)), @@ -56,6 +62,7 @@ export class TaxRatesController extends BaseController { ); router.get( '/:id', + CheckAbilities(TaxRateAction.VIEW, AbilitySubject.TaxRate), [param('id').exists().toInt()], this.validationResult, asyncMiddleware(this.getTaxRate.bind(this)), @@ -63,6 +70,7 @@ export class TaxRatesController extends BaseController { ); router.get( '/', + CheckAbilities(TaxRateAction.VIEW, AbilitySubject.TaxRate), this.validationResult, asyncMiddleware(this.getTaxRates.bind(this)), this.handleServiceErrors @@ -81,7 +89,7 @@ export class TaxRatesController extends BaseController { body('description').optional().trim().isString(), body('is_non_recoverable').optional().isBoolean().default(false), body('is_compound').optional().isBoolean().default(false), - body('status').optional().toUpperCase().isIn(['ARCHIVED', 'ACTIVE']), + body('active').optional().isBoolean().default(false), ]; } @@ -242,12 +250,7 @@ export class TaxRatesController extends BaseController { * @param {Response} res * @param {NextFunction} next */ - private handleServiceErrors( - error: Error, - req: Request, - res: Response, - next: HookNextFunction - ) { + private handleServiceErrors(error: Error, req: Request, res: Response, next) { if (error instanceof ServiceError) { if (error.errorType === ERRORS.TAX_CODE_NOT_UNIQUE) { return res.boom.badRequest(null, { diff --git a/packages/server/src/api/controllers/TaxRates/index.ts b/packages/server/src/api/controllers/TaxRates/index.ts deleted file mode 100644 index e69de29bb..000000000 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 6fed0a6fa..f0270034a 100644 --- a/packages/server/src/database/migrations/20230810191606_create_tax_rates.js +++ b/packages/server/src/database/migrations/20230810191606_create_tax_rates.js @@ -19,8 +19,6 @@ exports.up = (knex) => { .unsigned() .references('id') .inTable('tax_rates'); - table.string('tax_code'); - table.decimal('tax_rate'); }) .table('sales_invoices', (table) => { table.boolean('is_inclusive_tax').defaultTo(false); @@ -35,7 +33,7 @@ exports.up = (knex) => { .inTable('tax_rates'); table.string('reference_type'); table.integer('reference_id'); - table.decimal('tax_amount'); + table.decimal('rate').unsigned(); table.integer('tax_account_id').unsigned(); }) .table('accounts_transactions', (table) => { diff --git a/packages/server/src/database/migrations/20230917105226_rename_balance_column_on_sale_invoices_table.js b/packages/server/src/database/migrations/20230917105226_rename_balance_column_on_sale_invoices_table.js deleted file mode 100644 index 6e34f1839..000000000 --- a/packages/server/src/database/migrations/20230917105226_rename_balance_column_on_sale_invoices_table.js +++ /dev/null @@ -1,7 +0,0 @@ -exports.up = function (knex) { - return knex.table('sales_invoices', (table) => { - table.renameColumn('balance', 'amount'); - }); -}; - -exports.down = function (knex) {}; diff --git a/packages/server/src/interfaces/Account.ts b/packages/server/src/interfaces/Account.ts index 4de176c37..2239448c1 100644 --- a/packages/server/src/interfaces/Account.ts +++ b/packages/server/src/interfaces/Account.ts @@ -153,3 +153,11 @@ export enum AccountAction { VIEW = 'View', TransactionsLocking = 'TransactionsLocking', } + + +export enum TaxRateAction { + CREATE = 'Create', + EDIT = 'Edit', + DELETE = 'Delete', + VIEW = 'View', +} \ No newline at end of file diff --git a/packages/server/src/interfaces/Item.ts b/packages/server/src/interfaces/Item.ts index 6e942fd81..748fccefb 100644 --- a/packages/server/src/interfaces/Item.ts +++ b/packages/server/src/interfaces/Item.ts @@ -54,14 +54,6 @@ export interface IItemDTO { sellDescription: string; purchaseDescription: string; - // Used as an override if the default Tax Code for the selected `costAccountId` is not correct - purchaseTaxCode: string; - purchaseTaxId: string; - - // Used as an override if the default Tax Code for the selected `sellAccountId` is not correct - saleTaxCode: string; - saleTaxId: string; - quantityOnHand: number; note: string; diff --git a/packages/server/src/interfaces/ItemEntry.ts b/packages/server/src/interfaces/ItemEntry.ts index aab0b154d..575c3ae44 100644 --- a/packages/server/src/interfaces/ItemEntry.ts +++ b/packages/server/src/interfaces/ItemEntry.ts @@ -38,7 +38,6 @@ export interface IItemEntry { projectRefInvoicedAmount?: number; taxRateId: number | null; - taxCode: string; taxRate: number; taxAmount: number; @@ -57,9 +56,8 @@ export interface IItemEntryDTO { projectRefType?: ProjectLinkRefType; projectRefInvoicedAmount?: number; - taxCodeId?: number; + taxRateId?: number; taxCode?: string; - taxRate?: number; } export enum ProjectLinkRefType { diff --git a/packages/server/src/interfaces/TaxRate.ts b/packages/server/src/interfaces/TaxRate.ts index 73fda18ea..7bd912877 100644 --- a/packages/server/src/interfaces/TaxRate.ts +++ b/packages/server/src/interfaces/TaxRate.ts @@ -76,6 +76,13 @@ export interface ITaxTransaction { taxRateId: number; referenceType: string; referenceId: number; - taxAmount: number; + rate: number; taxAccountId: number; } + +export enum TaxRateAction { + CREATE = 'Create', + EDIT = 'Edit', + DELETE = 'Delete', + VIEW = 'View', +} diff --git a/packages/server/src/loaders/eventEmitter.ts b/packages/server/src/loaders/eventEmitter.ts index 52f8c489d..df5724e83 100644 --- a/packages/server/src/loaders/eventEmitter.ts +++ b/packages/server/src/loaders/eventEmitter.ts @@ -80,8 +80,6 @@ import { ProjectBillableExpensesSubscriber } from '@/services/Projects/Projects/ import { ProjectBillableBillSubscriber } from '@/services/Projects/Projects/ProjectBillableBillSubscriber'; import { SyncActualTimeTaskSubscriber } from '@/services/Projects/Times/SyncActualTimeTaskSubscriber'; import { SaleInvoiceTaxRateValidateSubscriber } from '@/services/TaxRates/subscribers/SaleInvoiceTaxRateValidateSubscriber'; -import { SaleEstimateTaxRateValidateSubscriber } from '@/services/TaxRates/subscribers/SaleEstimateTaxRateValidateSubscriber'; -import { SaleReceiptTaxRateValidateSubscriber } from '@/services/TaxRates/subscribers/SaleReceiptTaxRateValidateSubscriber'; import { WriteInvoiceTaxTransactionsSubscriber } from '@/services/TaxRates/subscribers/WriteInvoiceTaxTransactionsSubscriber'; export default () => { @@ -192,8 +190,6 @@ export const susbcribers = () => { // Tax Rates SaleInvoiceTaxRateValidateSubscriber, - SaleEstimateTaxRateValidateSubscriber, - SaleReceiptTaxRateValidateSubscriber, - WriteInvoiceTaxTransactionsSubscriber + WriteInvoiceTaxTransactionsSubscriber, ]; }; diff --git a/packages/server/src/models/AccountTransaction.ts b/packages/server/src/models/AccountTransaction.ts index 47fbd62ec..368d57afa 100644 --- a/packages/server/src/models/AccountTransaction.ts +++ b/packages/server/src/models/AccountTransaction.ts @@ -29,30 +29,14 @@ export default class AccountTransaction extends TenantModel { * Virtual attributes. */ static get virtualAttributes() { - return ['referenceTypeFormatted']; - } - - /** - * Retrieves the credit amount in foreign currency. - * @return {number} - */ - get creditFcy() { - return this.credit; - } - - /** - * Retrieves the debit amount in foreign currency. - * @return {number} - */ - get debitFcy() { - return this.debit; + return ['referenceTypeFormatted', 'creditLocal', 'debitLocal']; } /** * Retrieves the credit amount in base currency. * @return {number} */ - get creditBcy() { + get creditLocal() { return this.credit * this.exchangeRate; } @@ -60,26 +44,10 @@ export default class AccountTransaction extends TenantModel { * Retrieves the debit amount in base currency. * @return {number} */ - get debitBcy() { + get debitLocal() { return this.debit * this.exchangeRate; } - /** - * Retrieves the tax amount in foreign currency. - * @return {number} - */ - get taxAmountFcy() { - return (this.creditFcy - this.debitFcy) * this.taxRate; - } - - /** - * Retrieves the tax amount in base currency. - * @return {number} - */ - get taxAmountBcy() { - return (this.creditBcy - this.debitBcy) * this.taxRate; - } - /** * Retrieve formatted reference type. * @return {string} diff --git a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTable.ts b/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTable.ts index 7da959a9a..add98b368 100644 --- a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTable.ts +++ b/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummaryTable.ts @@ -6,15 +6,11 @@ import { SalesTaxLiabilitySummaryTotal, } from '@/interfaces/SalesTaxLiabilitySummary'; import { tableRowMapper } from '@/utils'; -import { ITableColumn, ITableColumnAccessor, ITableRow } from '@/interfaces'; +import { ITableColumn, ITableRow } from '@/interfaces'; import { FinancialSheetStructure } from '../FinancialSheetStructure'; import { FinancialTable } from '../FinancialTable'; import AgingReport from '../AgingSummary/AgingReport'; - -enum IROW_TYPE { - TaxRate = 'TaxRate', - Total = 'Total', -} +import { IROW_TYPE } from './_constants'; export class SalesTaxLiabilitySummaryTable extends R.compose( FinancialSheetStructure, diff --git a/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/_constants.ts b/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/_constants.ts new file mode 100644 index 000000000..f030fd16c --- /dev/null +++ b/packages/server/src/services/FinancialStatements/SalesTaxLiabilitySummary/_constants.ts @@ -0,0 +1,4 @@ +export enum IROW_TYPE { + TaxRate = 'TaxRate', + Total = 'Total', +} diff --git a/packages/server/src/services/Sales/Invoices/CommandSaleInvoiceDTOTransformer.ts b/packages/server/src/services/Sales/Invoices/CommandSaleInvoiceDTOTransformer.ts index ddb942553..c8fcb867d 100644 --- a/packages/server/src/services/Sales/Invoices/CommandSaleInvoiceDTOTransformer.ts +++ b/packages/server/src/services/Sales/Invoices/CommandSaleInvoiceDTOTransformer.ts @@ -70,20 +70,25 @@ export class CommandSaleInvoiceDTOTransformer { isInclusiveTax: saleInvoiceDTO.isInclusiveTax, ...entry, })); - const entries = await composeAsync( + const asyncEntries = await composeAsync( // Associate tax rate id from tax code to entries. this.taxDTOTransformer.assocTaxRateIdFromCodeToEntries(tenantId), // Sets default cost and sell account to invoice items entries. this.itemsEntriesService.setItemsEntriesDefaultAccounts(tenantId) )(initialEntries); + const entries = R.compose( + // Remove tax code from entries. + R.map(R.omit(['taxCode'])) + )(asyncEntries); + const initialDTO = { ...formatDateFields( omit(saleInvoiceDTO, ['delivered', 'entries', 'fromEstimateId']), ['invoiceDate', 'dueDate'] ), // Avoid rewrite the deliver date in edit mode when already published. - amount, + balance: amount, currencyCode: customer.currencyCode, exchangeRate: saleInvoiceDTO.exchangeRate || 1, ...(saleInvoiceDTO.delivered && diff --git a/packages/server/src/services/TaxRates/ActivateTaxRate.ts b/packages/server/src/services/TaxRates/ActivateTaxRate.ts index 1fe516123..2384b901d 100644 --- a/packages/server/src/services/TaxRates/ActivateTaxRate.ts +++ b/packages/server/src/services/TaxRates/ActivateTaxRate.ts @@ -1,12 +1,12 @@ +import { Knex } from 'knex'; +import { Inject, Service } from 'typedi'; import { ITaxRateActivatedPayload, ITaxRateActivatingPayload, } from '@/interfaces'; -import { Inject, Service } 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'; @@ -25,7 +25,7 @@ export class ActivateTaxRateService { private validators: CommandTaxRatesValidators; /** - * Edits the given tax rate. + * Activates the given tax rate. * @param {number} tenantId * @param {number} taxRateId * @param {IEditTaxRateDTO} taxRateEditDTO diff --git a/packages/server/src/services/TaxRates/CommandTaxRatesValidators.ts b/packages/server/src/services/TaxRates/CommandTaxRatesValidators.ts index 49583cd56..9d7c2558e 100644 --- a/packages/server/src/services/TaxRates/CommandTaxRatesValidators.ts +++ b/packages/server/src/services/TaxRates/CommandTaxRatesValidators.ts @@ -59,6 +59,7 @@ export class CommandTaxRatesValidators { * Validates the tax codes of the given item entries DTO. * @param {number} tenantId * @param {IItemEntryDTO[]} itemEntriesDTO + * @throws {ServiceError} */ public async validateItemEntriesTaxCode( tenantId: number, @@ -92,17 +93,17 @@ export class CommandTaxRatesValidators { tenantId: number, itemEntriesDTO: IItemEntryDTO[] ) { - const filteredTaxEntries = itemEntriesDTO.filter((e) => e.taxCodeId); - const taxCodes = filteredTaxEntries.map((e) => e.taxCodeId); + const filteredTaxEntries = itemEntriesDTO.filter((e) => e.taxRateId); + const taxRatesIds = filteredTaxEntries.map((e) => e.taxRateId); // Can't validate if there is no tax codes. - if (taxCodes.length === 0) return; + if (taxRatesIds.length === 0) return; const { TaxRate } = this.tenancy.models(tenantId); - const foundTaxCodes = await TaxRate.query().whereIn('id', taxCodes); - const foundCodes = foundTaxCodes.map((tax) => tax.id); + const foundTaxCodes = await TaxRate.query().whereIn('id', taxRatesIds); + const foundTaxRatesIds = foundTaxCodes.map((tax) => tax.id); - const notFoundTaxCodes = difference(taxCodes, foundCodes); + const notFoundTaxCodes = difference(taxRatesIds, foundTaxRatesIds); if (notFoundTaxCodes.length > 0) { throw new ServiceError(ERRORS.ITEM_ENTRY_TAX_RATE_ID_NOT_FOUND); diff --git a/packages/server/src/services/TaxRates/CreateTaxRate.ts b/packages/server/src/services/TaxRates/CreateTaxRate.ts index b7bc19fc8..a7795a3c7 100644 --- a/packages/server/src/services/TaxRates/CreateTaxRate.ts +++ b/packages/server/src/services/TaxRates/CreateTaxRate.ts @@ -49,7 +49,9 @@ export class CreateTaxRate { trx, } as ITaxRateCreatingPayload); - const taxRate = await TaxRate.query(trx).insert({ ...createTaxRateDTO }); + const taxRate = await TaxRate.query(trx).insertAndFetch({ + ...createTaxRateDTO, + }); // Triggers `onTaxRateCreated` event. await this.eventPublisher.emitAsync(events.taxRates.onCreated, { diff --git a/packages/server/src/services/TaxRates/WriteTaxTransactionsItemEntries.ts b/packages/server/src/services/TaxRates/WriteTaxTransactionsItemEntries.ts index d5c654c4d..0e00471c8 100644 --- a/packages/server/src/services/TaxRates/WriteTaxTransactionsItemEntries.ts +++ b/packages/server/src/services/TaxRates/WriteTaxTransactionsItemEntries.ts @@ -2,6 +2,7 @@ import { sumBy, chain, keyBy } from 'lodash'; import { IItemEntry, ITaxTransaction } from '@/interfaces'; import HasTenancyService from '../Tenancy/TenancyService'; import { Inject, Service } from 'typedi'; +import { Knex } from 'knex'; @Service() export class WriteTaxTransactionsItemEntries { @@ -15,24 +16,51 @@ export class WriteTaxTransactionsItemEntries { */ public async writeTaxTransactionsFromItemEntries( tenantId: number, - itemEntries: IItemEntry[] + itemEntries: IItemEntry[], + trx?: Knex.Transaction ) { const { TaxRateTransaction, TaxRate } = this.tenancy.models(tenantId); const aggregatedEntries = this.aggregateItemEntriesByTaxCode(itemEntries); const entriesTaxRateIds = aggregatedEntries.map((entry) => entry.taxRateId); - const taxRates = await TaxRate.query().whereIn('id', entriesTaxRateIds); + const taxRates = await TaxRate.query(trx).whereIn('id', entriesTaxRateIds); const taxRatesById = keyBy(taxRates, 'id'); const taxTransactions = aggregatedEntries.map((entry) => ({ taxRateId: entry.taxRateId, referenceType: entry.referenceType, referenceId: entry.referenceId, - taxAmount: entry.taxRate || taxRatesById[entry.taxRateId]?.rate, + rate: entry.taxRate || taxRatesById[entry.taxRateId]?.rate, })) as ITaxTransaction[]; - await TaxRateTransaction.query().upsertGraph(taxTransactions); + await TaxRateTransaction.query(trx).upsertGraph(taxTransactions); + } + + /** + * Rewrites the tax rate transactions from the given item entries. + * @param {number} tenantId + * @param {IItemEntry[]} itemEntries + * @param {string} referenceType + * @param {number} referenceId + * @param {Knex.Transaction} trx + */ + public async rewriteTaxRateTransactionsFromItemEntries( + tenantId: number, + itemEntries: IItemEntry[], + referenceType: string, + referenceId: number, + trx?: Knex.Transaction + ) { + await Promise.all([ + this.removeTaxTransactionsFromItemEntries( + tenantId, + referenceId, + referenceType, + trx + ), + this.writeTaxTransactionsFromItemEntries(tenantId, itemEntries, trx), + ]); } /** @@ -59,11 +87,12 @@ export class WriteTaxTransactionsItemEntries { public async removeTaxTransactionsFromItemEntries( tenantId: number, referenceId: number, - referenceType: string + referenceType: string, + trx?: Knex.Transaction ) { const { TaxRateTransaction } = this.tenancy.models(tenantId); - await TaxRateTransaction.query() + await TaxRateTransaction.query(trx) .where({ referenceType, referenceId }) .delete(); } diff --git a/packages/server/src/services/TaxRates/subscribers/SaleEstimateTaxRateValidateSubscriber.ts b/packages/server/src/services/TaxRates/subscribers/SaleEstimateTaxRateValidateSubscriber.ts deleted file mode 100644 index e5f04e4a3..000000000 --- a/packages/server/src/services/TaxRates/subscribers/SaleEstimateTaxRateValidateSubscriber.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - ISaleEstimateCreatingPayload, - ISaleEstimateEditingPayload, - ISaleInvoiceCreatingPaylaod, - ISaleInvoiceEditingPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { CommandTaxRatesValidators } from '../CommandTaxRatesValidators'; - -@Service() -export class SaleEstimateTaxRateValidateSubscriber { - @Inject() - private taxRateDTOValidator: CommandTaxRatesValidators; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.saleEstimate.onCreating, - this.validateSaleEstimateEntriesTaxCodeExistanceOnCreating - ); - bus.subscribe( - events.saleEstimate.onEditing, - this.validateSaleEstimateEntriesTaxCodeExistanceOnEditing - ); - return bus; - } - - /** - * Validate invoice entries tax rate code existance. - * @param {ISaleInvoiceCreatingPaylaod} - */ - private validateSaleEstimateEntriesTaxCodeExistanceOnCreating = async ({ - estimateDTO, - tenantId, - }: ISaleEstimateCreatingPayload) => { - await this.taxRateDTOValidator.validateItemEntriesTaxCode( - tenantId, - estimateDTO.entries - ); - }; - - /** - * - * @param {ISaleInvoiceEditingPayload} - */ - private validateSaleEstimateEntriesTaxCodeExistanceOnEditing = async ({ - tenantId, - estimateDTO, - }: ISaleEstimateEditingPayload) => { - await this.taxRateDTOValidator.validateItemEntriesTaxCode( - tenantId, - estimateDTO.entries - ); - }; -} diff --git a/packages/server/src/services/TaxRates/subscribers/SaleInvoiceTaxRateValidateSubscriber.ts b/packages/server/src/services/TaxRates/subscribers/SaleInvoiceTaxRateValidateSubscriber.ts index ab8de770a..9a120629c 100644 --- a/packages/server/src/services/TaxRates/subscribers/SaleInvoiceTaxRateValidateSubscriber.ts +++ b/packages/server/src/services/TaxRates/subscribers/SaleInvoiceTaxRateValidateSubscriber.ts @@ -27,6 +27,10 @@ export class SaleInvoiceTaxRateValidateSubscriber { events.saleInvoice.onEditing, this.validateSaleInvoiceEntriesTaxCodeExistanceOnEditing ); + bus.subscribe( + events.saleInvoice.onEditing, + this.validateSaleInvoiceEntriesTaxIdExistanceOnEditing + ); return bus; } @@ -71,4 +75,18 @@ export class SaleInvoiceTaxRateValidateSubscriber { saleInvoiceDTO.entries ); }; + + /** + * Validates the invoice entries tax rate id existance when editing. + * @param {ISaleInvoiceEditingPayload} payload - + */ + private validateSaleInvoiceEntriesTaxIdExistanceOnEditing = async ({ + tenantId, + saleInvoiceDTO, + }: ISaleInvoiceEditingPayload) => { + await this.taxRateDTOValidator.validateItemEntriesTaxCodeId( + tenantId, + saleInvoiceDTO.entries + ); + }; } diff --git a/packages/server/src/services/TaxRates/subscribers/SaleReceiptTaxRateValidateSubscriber.ts b/packages/server/src/services/TaxRates/subscribers/SaleReceiptTaxRateValidateSubscriber.ts deleted file mode 100644 index d4c8e21b9..000000000 --- a/packages/server/src/services/TaxRates/subscribers/SaleReceiptTaxRateValidateSubscriber.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Inject, Service } from 'typedi'; -import { - ISaleReceiptCreatingPayload, - ISaleReceiptEditingPayload, -} from '@/interfaces'; -import events from '@/subscribers/events'; -import { CommandTaxRatesValidators } from '../CommandTaxRatesValidators'; - -@Service() -export class SaleReceiptTaxRateValidateSubscriber { - @Inject() - private taxRateDTOValidator: CommandTaxRatesValidators; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe( - events.saleReceipt.onCreating, - this.validateSaleReceiptEntriesTaxCodeExistanceOnCreating - ); - bus.subscribe( - events.saleReceipt.onEditing, - this.validateSaleReceiptEntriesTaxCodeExistanceOnEditing - ); - return bus; - } - - /** - * Validate receipt entries tax rate code existance. - * @param {ISaleInvoiceCreatingPaylaod} - */ - private validateSaleReceiptEntriesTaxCodeExistanceOnCreating = async ({ - tenantId, - saleReceiptDTO, - }: ISaleReceiptCreatingPayload) => { - await this.taxRateDTOValidator.validateItemEntriesTaxCode( - tenantId, - saleReceiptDTO.entries - ); - }; - - /** - * - * @param {ISaleInvoiceEditingPayload} - */ - private validateSaleReceiptEntriesTaxCodeExistanceOnEditing = async ({ - tenantId, - saleReceiptDTO, - }: ISaleReceiptEditingPayload) => { - await this.taxRateDTOValidator.validateItemEntriesTaxCode( - tenantId, - saleReceiptDTO.entries - ); - }; -} diff --git a/packages/server/src/services/TaxRates/subscribers/WriteInvoiceTaxTransactionsSubscriber.ts b/packages/server/src/services/TaxRates/subscribers/WriteInvoiceTaxTransactionsSubscriber.ts index eb0e1c9b3..b65dd7904 100644 --- a/packages/server/src/services/TaxRates/subscribers/WriteInvoiceTaxTransactionsSubscriber.ts +++ b/packages/server/src/services/TaxRates/subscribers/WriteInvoiceTaxTransactionsSubscriber.ts @@ -2,6 +2,7 @@ import { Inject, Service } from 'typedi'; import { ISaleInvoiceCreatedPayload, ISaleInvoiceDeletedPayload, + ISaleInvoiceEditedPayload, } from '@/interfaces'; import events from '@/subscribers/events'; import { WriteTaxTransactionsItemEntries } from '../WriteTaxTransactionsItemEntries'; @@ -19,6 +20,10 @@ export class WriteInvoiceTaxTransactionsSubscriber { events.saleInvoice.onCreated, this.writeInvoiceTaxTransactionsOnCreated ); + bus.subscribe( + events.saleInvoice.onEdited, + this.rewriteInvoiceTaxTransactionsOnEdited + ); bus.subscribe( events.saleInvoice.onDelete, this.removeInvoiceTaxTransactionsOnDeleted @@ -27,16 +32,36 @@ export class WriteInvoiceTaxTransactionsSubscriber { } /** - * Validate receipt entries tax rate code existance. + * Writes the invoice tax transactions on invoice created. * @param {ISaleInvoiceCreatingPaylaod} */ private writeInvoiceTaxTransactionsOnCreated = async ({ tenantId, saleInvoice, + trx }: ISaleInvoiceCreatedPayload) => { await this.writeTaxTransactions.writeTaxTransactionsFromItemEntries( tenantId, - saleInvoice.entries + saleInvoice.entries, + trx + ); + }; + + /** + * Rewrites the invoice tax transactions on invoice edited. + * @param {ISaleInvoiceEditedPayload} payload - + */ + private rewriteInvoiceTaxTransactionsOnEdited = async ({ + tenantId, + saleInvoice, + trx, + }: ISaleInvoiceEditedPayload) => { + await this.writeTaxTransactions.rewriteTaxRateTransactionsFromItemEntries( + tenantId, + saleInvoice.entries, + 'SaleInvoice', + saleInvoice.id, + trx ); }; @@ -47,11 +72,13 @@ export class WriteInvoiceTaxTransactionsSubscriber { private removeInvoiceTaxTransactionsOnDeleted = async ({ tenantId, oldSaleInvoice, + trx }: ISaleInvoiceDeletedPayload) => { await this.writeTaxTransactions.removeTaxTransactionsFromItemEntries( tenantId, oldSaleInvoice.id, - 'SaleInvoice' + 'SaleInvoice', + trx ); }; }