mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 04:40:32 +00:00
fix(server): pull-request nodes
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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, {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user