mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 13:20:31 +00:00
feat: assign default sell/purchase tax rates to items (#261)
This commit is contained in:
@@ -55,6 +55,18 @@ export class CreateItem {
|
||||
itemDTO.inventoryAccountId
|
||||
);
|
||||
}
|
||||
if (itemDTO.purchaseTaxRateId) {
|
||||
await this.validators.validatePurchaseTaxRateExistance(
|
||||
tenantId,
|
||||
itemDTO.purchaseTaxRateId
|
||||
);
|
||||
}
|
||||
if (itemDTO.sellTaxRateId) {
|
||||
await this.validators.validateSellTaxRateExistance(
|
||||
tenantId,
|
||||
itemDTO.sellTaxRateId
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -76,6 +76,20 @@ export class EditItem {
|
||||
itemDTO.inventoryAccountId
|
||||
);
|
||||
}
|
||||
// Validate the purchase tax rate id existance.
|
||||
if (itemDTO.purchaseTaxRateId) {
|
||||
await this.validators.validatePurchaseTaxRateExistance(
|
||||
tenantId,
|
||||
itemDTO.purchaseTaxRateId
|
||||
);
|
||||
}
|
||||
// Validate the sell tax rate id existance.
|
||||
if (itemDTO.sellTaxRateId) {
|
||||
await this.validators.validateSellTaxRateExistance(
|
||||
tenantId,
|
||||
itemDTO.sellTaxRateId
|
||||
);
|
||||
}
|
||||
// Validate inventory account should be modified in inventory item
|
||||
// has inventory transactions.
|
||||
await this.validators.validateItemInvnetoryAccountModified(
|
||||
|
||||
@@ -27,6 +27,8 @@ export class GetItem {
|
||||
.withGraphFetched('category')
|
||||
.withGraphFetched('costAccount')
|
||||
.withGraphFetched('itemWarehouses.warehouse')
|
||||
.withGraphFetched('sellTaxRate')
|
||||
.withGraphFetched('purchaseTaxRate')
|
||||
.throwIfNotFound();
|
||||
|
||||
return this.transformer.transform(tenantId, item, new ItemTransformer());
|
||||
|
||||
@@ -241,4 +241,40 @@ export class ItemsValidators {
|
||||
throw new ServiceError(ERRORS.ITEM_CANNOT_CHANGE_INVENTORY_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the purchase tax rate id existance.
|
||||
* @param {number} tenantId -
|
||||
* @param {number} taxRateId -
|
||||
*/
|
||||
public async validatePurchaseTaxRateExistance(
|
||||
tenantId: number,
|
||||
taxRateId: number
|
||||
) {
|
||||
const { TaxRate } = this.tenancy.models(tenantId);
|
||||
|
||||
const foundTaxRate = await TaxRate.query().findById(taxRateId);
|
||||
|
||||
if (!foundTaxRate) {
|
||||
throw new ServiceError(ERRORS.PURCHASE_TAX_RATE_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the sell tax rate id existance.
|
||||
* @param {number} tenantId
|
||||
* @param {number} taxRateId
|
||||
*/
|
||||
public async validateSellTaxRateExistance(
|
||||
tenantId: number,
|
||||
taxRateId: number
|
||||
) {
|
||||
const { TaxRate } = this.tenancy.models(tenantId);
|
||||
|
||||
const foundTaxRate = await TaxRate.query().findById(taxRateId);
|
||||
|
||||
if (!foundTaxRate) {
|
||||
throw new ServiceError(ERRORS.SELL_TAX_RATE_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,10 @@ export const ERRORS = {
|
||||
TYPE_CANNOT_CHANGE_WITH_ITEM_HAS_TRANSACTIONS: 'TYPE_CANNOT_CHANGE_WITH_ITEM_HAS_TRANSACTIONS',
|
||||
INVENTORY_ACCOUNT_CANNOT_MODIFIED: 'INVENTORY_ACCOUNT_CANNOT_MODIFIED',
|
||||
|
||||
ITEM_HAS_ASSOCIATED_TRANSACTIONS: 'ITEM_HAS_ASSOCIATED_TRANSACTIONS'
|
||||
ITEM_HAS_ASSOCIATED_TRANSACTIONS: 'ITEM_HAS_ASSOCIATED_TRANSACTIONS',
|
||||
|
||||
PURCHASE_TAX_RATE_NOT_FOUND: 'PURCHASE_TAX_RATE_NOT_FOUND',
|
||||
SELL_TAX_RATE_NOT_FOUND: 'SELL_TAX_RATE_NOT_FOUND',
|
||||
};
|
||||
|
||||
export const DEFAULT_VIEW_COLUMNS = [];
|
||||
|
||||
@@ -115,6 +115,7 @@ export class EditTaxRateService {
|
||||
// Triggers `onTaxRateEdited` event.
|
||||
await this.eventPublisher.emitAsync(events.taxRates.onEdited, {
|
||||
editTaxRateDTO,
|
||||
oldTaxRate,
|
||||
taxRate,
|
||||
tenantId,
|
||||
trx,
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import { Knex } from 'knex';
|
||||
import { Inject, Service } from 'typedi';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
|
||||
@Service()
|
||||
export class SyncItemTaxRateOnEditTaxRate {
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
/**
|
||||
* Syncs the new tax rate created to item default sell tax rate.
|
||||
* @param {number} tenantId
|
||||
* @param {number} itemId
|
||||
* @param {number} sellTaxRateId
|
||||
*/
|
||||
public updateItemSellTaxRate = async (
|
||||
tenantId: number,
|
||||
oldSellTaxRateId: number,
|
||||
sellTaxRateId: number,
|
||||
trx?: Knex.Transaction
|
||||
) => {
|
||||
const { Item } = this.tenancy.models(tenantId);
|
||||
|
||||
// Can't continue if the old and new sell tax rate id are equal.
|
||||
if (oldSellTaxRateId === sellTaxRateId) return;
|
||||
|
||||
await Item.query().where('sellTaxRateId', oldSellTaxRateId).update({
|
||||
sellTaxRateId,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Syncs the new tax rate created to item default purchase tax rate.
|
||||
* @param {number} tenantId
|
||||
* @param {number} itemId
|
||||
* @param {number} purchaseTaxRateId
|
||||
*/
|
||||
public updateItemPurchaseTaxRate = async (
|
||||
tenantId: number,
|
||||
oldPurchaseTaxRateId: number,
|
||||
purchaseTaxRateId: number,
|
||||
trx?: Knex.Transaction
|
||||
) => {
|
||||
const { Item } = this.tenancy.models(tenantId);
|
||||
|
||||
// Can't continue if the old and new sell tax rate id are equal.
|
||||
if (oldPurchaseTaxRateId === purchaseTaxRateId) return;
|
||||
|
||||
await Item.query(trx)
|
||||
.where('purchaseTaxRateId', oldPurchaseTaxRateId)
|
||||
.update({
|
||||
purchaseTaxRateId,
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { SyncItemTaxRateOnEditTaxRate } from './SyncItemTaxRateOnEditTaxRate';
|
||||
import events from '@/subscribers/events';
|
||||
import { ITaxRateEditedPayload } from '@/interfaces';
|
||||
import { runAfterTransaction } from '../UnitOfWork/TransactionsHooks';
|
||||
|
||||
@Service()
|
||||
export class SyncItemTaxRateOnEditTaxSubscriber {
|
||||
@Inject()
|
||||
private syncItemRateOnEdit: SyncItemTaxRateOnEditTaxRate;
|
||||
|
||||
/**
|
||||
* Attaches events with handles.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.taxRates.onEdited,
|
||||
this.handleSyncNewTaxRateToItemTaxRate
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncs the new tax rate created to default item tax rates.
|
||||
* @param {ITaxRateEditedPayload} payload -
|
||||
*/
|
||||
private handleSyncNewTaxRateToItemTaxRate = async ({
|
||||
taxRate,
|
||||
tenantId,
|
||||
oldTaxRate,
|
||||
trx,
|
||||
}: ITaxRateEditedPayload) => {
|
||||
runAfterTransaction(trx, async () => {
|
||||
await this.syncItemRateOnEdit.updateItemPurchaseTaxRate(
|
||||
tenantId,
|
||||
oldTaxRate.id,
|
||||
taxRate.id
|
||||
);
|
||||
await this.syncItemRateOnEdit.updateItemSellTaxRate(
|
||||
tenantId,
|
||||
oldTaxRate.id,
|
||||
taxRate.id
|
||||
);
|
||||
});
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user