diff --git a/packages/server/src/api/controllers/Items/Items.ts b/packages/server/src/api/controllers/Items/Items.ts
index 66deaffe4..a77f991e9 100644
--- a/packages/server/src/api/controllers/Items/Items.ts
+++ b/packages/server/src/api/controllers/Items/Items.ts
@@ -149,6 +149,11 @@ export default class ItemsController extends BaseController {
.trim()
.escape()
.isLength({ max: DATATYPES_LENGTH.TEXT }),
+ check('sell_tax_rate_id').optional({ nullable: true }).isInt().toInt(),
+ check('purchase_tax_rate_id')
+ .optional({ nullable: true })
+ .isInt()
+ .toInt(),
check('category_id')
.optional({ nullable: true })
.isInt({ min: 0, max: DATATYPES_LENGTH.INT_10 })
@@ -508,6 +513,28 @@ export default class ItemsController extends BaseController {
],
});
}
+ if (error.errorType === 'PURCHASE_TAX_RATE_NOT_FOUND') {
+ return res.status(400).send({
+ errors: [
+ {
+ type: 'PURCHASE_TAX_RATE_NOT_FOUND',
+ message: 'Purchase tax rate has not found.',
+ code: 410,
+ },
+ ],
+ });
+ }
+ if (error.errorType === 'SELL_TAX_RATE_NOT_FOUND') {
+ return res.status(400).send({
+ errors: [
+ {
+ type: 'SELL_TAX_RATE_NOT_FOUND',
+ message: 'Sell tax rate is not found.',
+ code: 420,
+ },
+ ],
+ });
+ }
}
next(error);
}
diff --git a/packages/server/src/database/migrations/20231004020636_add_sell_purchase_tax_to_items_table.js b/packages/server/src/database/migrations/20231004020636_add_sell_purchase_tax_to_items_table.js
new file mode 100644
index 000000000..51b842df2
--- /dev/null
+++ b/packages/server/src/database/migrations/20231004020636_add_sell_purchase_tax_to_items_table.js
@@ -0,0 +1,18 @@
+exports.up = (knex) => {
+ return knex.schema.table('items', (table) => {
+ table
+ .integer('sell_tax_rate_id')
+ .unsigned()
+ .references('id')
+ .inTable('tax_rates');
+ table
+ .integer('purchase_tax_rate_id')
+ .unsigned()
+ .references('id')
+ .inTable('tax_rates');
+ });
+};
+
+exports.down = (knex) => {
+ return knex.schema.dropTableIfExists('tax_rates');
+};
diff --git a/packages/server/src/interfaces/Item.ts b/packages/server/src/interfaces/Item.ts
index 748fccefb..9fdfa374d 100644
--- a/packages/server/src/interfaces/Item.ts
+++ b/packages/server/src/interfaces/Item.ts
@@ -22,6 +22,9 @@ export interface IItem {
sellDescription: string;
purchaseDescription: string;
+ sellTaxRateId: number;
+ purchaseTaxRateId: number;
+
quantityOnHand: number;
note: string;
@@ -54,6 +57,9 @@ export interface IItemDTO {
sellDescription: string;
purchaseDescription: string;
+ sellTaxRateId: number;
+ purchaseTaxRateId: number;
+
quantityOnHand: number;
note: string;
diff --git a/packages/server/src/interfaces/TaxRate.ts b/packages/server/src/interfaces/TaxRate.ts
index 7bd912877..d1e27383d 100644
--- a/packages/server/src/interfaces/TaxRate.ts
+++ b/packages/server/src/interfaces/TaxRate.ts
@@ -36,6 +36,7 @@ export interface ITaxRateCreatedPayload {
}
export interface ITaxRateEditingPayload {
+ oldTaxRate: ITaxRate;
editTaxRateDTO: IEditTaxRateDTO;
tenantId: number;
trx: Knex.Transaction;
diff --git a/packages/server/src/loaders/eventEmitter.ts b/packages/server/src/loaders/eventEmitter.ts
index 47589de5f..fa1942b72 100644
--- a/packages/server/src/loaders/eventEmitter.ts
+++ b/packages/server/src/loaders/eventEmitter.ts
@@ -83,6 +83,7 @@ import { SaleInvoiceTaxRateValidateSubscriber } from '@/services/TaxRates/subscr
import { WriteInvoiceTaxTransactionsSubscriber } from '@/services/TaxRates/subscribers/WriteInvoiceTaxTransactionsSubscriber';
import { BillTaxRateValidateSubscriber } from '@/services/TaxRates/subscribers/BillTaxRateValidateSubscriber';
import { WriteBillTaxTransactionsSubscriber } from '@/services/TaxRates/subscribers/WriteBillTaxTransactionsSubscriber';
+import { SyncItemTaxRateOnEditTaxSubscriber } from '@/services/TaxRates/SyncItemTaxRateOnEditTaxSubscriber';
export default () => {
return new EventPublisher();
@@ -197,5 +198,7 @@ export const susbcribers = () => {
// Tax Rates - Bills
BillTaxRateValidateSubscriber,
WriteBillTaxTransactionsSubscriber,
+
+ SyncItemTaxRateOnEditTaxSubscriber
];
};
diff --git a/packages/server/src/models/Item.ts b/packages/server/src/models/Item.ts
index 4f2fe1fd5..45e5afd2f 100644
--- a/packages/server/src/models/Item.ts
+++ b/packages/server/src/models/Item.ts
@@ -65,6 +65,7 @@ export default class Item extends mixin(TenantModel, [
const ItemEntry = require('models/ItemEntry');
const WarehouseTransferEntry = require('models/WarehouseTransferEntry');
const InventoryAdjustmentEntry = require('models/InventoryAdjustmentEntry');
+ const TaxRate = require('models/TaxRate');
return {
/**
@@ -178,11 +179,35 @@ export default class Item extends mixin(TenantModel, [
to: 'media.id',
},
},
+
+ /**
+ * Item may has sell tax rate.
+ */
+ sellTaxRate: {
+ relation: Model.BelongsToOneRelation,
+ modelClass: TaxRate.default,
+ join: {
+ from: 'items.sellTaxRateId',
+ to: 'tax_rates.id',
+ },
+ },
+
+ /**
+ * Item may has purchase tax rate.
+ */
+ purchaseTaxRate: {
+ relation: Model.BelongsToOneRelation,
+ modelClass: TaxRate.default,
+ join: {
+ from: 'items.purchaseTaxRateId',
+ to: 'tax_rates.id',
+ },
+ },
};
}
/**
- *
+ *
*/
static get secureDeleteRelations() {
return [
diff --git a/packages/server/src/services/Items/CreateItem.ts b/packages/server/src/services/Items/CreateItem.ts
index ffebdae3d..4ecb984b3 100644
--- a/packages/server/src/services/Items/CreateItem.ts
+++ b/packages/server/src/services/Items/CreateItem.ts
@@ -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
+ );
+ }
}
/**
diff --git a/packages/server/src/services/Items/EditItem.ts b/packages/server/src/services/Items/EditItem.ts
index 8227f3b5f..6e230921f 100644
--- a/packages/server/src/services/Items/EditItem.ts
+++ b/packages/server/src/services/Items/EditItem.ts
@@ -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(
diff --git a/packages/server/src/services/Items/GetItem.ts b/packages/server/src/services/Items/GetItem.ts
index 7b078bac5..af07e6cca 100644
--- a/packages/server/src/services/Items/GetItem.ts
+++ b/packages/server/src/services/Items/GetItem.ts
@@ -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());
diff --git a/packages/server/src/services/Items/ItemValidators.ts b/packages/server/src/services/Items/ItemValidators.ts
index 486c08a8d..cdf8a652e 100644
--- a/packages/server/src/services/Items/ItemValidators.ts
+++ b/packages/server/src/services/Items/ItemValidators.ts
@@ -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);
+ }
+ }
}
diff --git a/packages/server/src/services/Items/constants.ts b/packages/server/src/services/Items/constants.ts
index e3dd283a7..1acbc70c6 100644
--- a/packages/server/src/services/Items/constants.ts
+++ b/packages/server/src/services/Items/constants.ts
@@ -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 = [];
diff --git a/packages/server/src/services/TaxRates/EditTaxRate.ts b/packages/server/src/services/TaxRates/EditTaxRate.ts
index c2d0e5c1a..210529026 100644
--- a/packages/server/src/services/TaxRates/EditTaxRate.ts
+++ b/packages/server/src/services/TaxRates/EditTaxRate.ts
@@ -115,6 +115,7 @@ export class EditTaxRateService {
// Triggers `onTaxRateEdited` event.
await this.eventPublisher.emitAsync(events.taxRates.onEdited, {
editTaxRateDTO,
+ oldTaxRate,
taxRate,
tenantId,
trx,
diff --git a/packages/server/src/services/TaxRates/SyncItemTaxRateOnEditTaxRate.ts b/packages/server/src/services/TaxRates/SyncItemTaxRateOnEditTaxRate.ts
new file mode 100644
index 000000000..aed00f9b7
--- /dev/null
+++ b/packages/server/src/services/TaxRates/SyncItemTaxRateOnEditTaxRate.ts
@@ -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,
+ });
+ };
+}
diff --git a/packages/server/src/services/TaxRates/SyncItemTaxRateOnEditTaxSubscriber.ts b/packages/server/src/services/TaxRates/SyncItemTaxRateOnEditTaxSubscriber.ts
new file mode 100644
index 000000000..4a7bc9263
--- /dev/null
+++ b/packages/server/src/services/TaxRates/SyncItemTaxRateOnEditTaxSubscriber.ts
@@ -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
+ );
+ });
+ };
+}
diff --git a/packages/webapp/src/components/TaxRates/TaxRatesSelect.tsx b/packages/webapp/src/components/TaxRates/TaxRatesSelect.tsx
new file mode 100644
index 000000000..f533c6cba
--- /dev/null
+++ b/packages/webapp/src/components/TaxRates/TaxRatesSelect.tsx
@@ -0,0 +1,62 @@
+// @ts-nocheck
+import * as R from 'ramda';
+import intl from 'react-intl-universal';
+import { FSelect } from '@/components';
+import { DialogsName } from '@/constants/dialogs';
+import withDialogActions from '@/containers/Dialog/withDialogActions';
+import { MenuItem } from '@blueprintjs/core';
+
+// Create new account renderer.
+const createNewItemRenderer = (query, active, handleClick) => {
+ return (
+
+ );
+};
+
+// Create new item from the given query string.
+const createNewItemFromQuery = (name) => ({ name });
+
+/**
+ * Tax rates select field binded with Formik form.
+ * @returns {JSX.Element}
+ */
+function TaxRatesSelectRoot({
+ // #withDialogActions
+ openDialog,
+
+ // #ownProps
+ allowCreate,
+
+ ...restProps
+}) {
+ // Maybe inject new item props to select component.
+ const maybeCreateNewItemRenderer = allowCreate ? createNewItemRenderer : null;
+ const maybeCreateNewItemFromQuery = allowCreate
+ ? createNewItemFromQuery
+ : null;
+
+ // Handles the create item click.
+ const handleCreateItemClick = () => {
+ openDialog(DialogsName.TaxRateForm);
+ };
+
+ return (
+
+ );
+}
+
+export const TaxRatesSelect = R.compose(withDialogActions)(TaxRatesSelectRoot);
diff --git a/packages/webapp/src/containers/Drawers/ItemDetailDrawer/ItemDetailHeader.tsx b/packages/webapp/src/containers/Drawers/ItemDetailDrawer/ItemDetailHeader.tsx
index 06b7ce5b4..5e10c3507 100644
--- a/packages/webapp/src/containers/Drawers/ItemDetailDrawer/ItemDetailHeader.tsx
+++ b/packages/webapp/src/containers/Drawers/ItemDetailDrawer/ItemDetailHeader.tsx
@@ -67,6 +67,14 @@ export default function ItemDetailHeader() {
label={intl.get('cost_account_id')}
children={defaultTo(item.cost_account?.name, '-')}
/>
+
+
{
// Update the rate, description and quantity data of the row.
const newRows = composeRowsOnNewRow(rowIndex, newRow, localValue);
diff --git a/packages/webapp/src/containers/Entries/utils.tsx b/packages/webapp/src/containers/Entries/utils.tsx
index bfc62138e..50f6555e3 100644
--- a/packages/webapp/src/containers/Entries/utils.tsx
+++ b/packages/webapp/src/containers/Entries/utils.tsx
@@ -1,5 +1,5 @@
// @ts-nocheck
-import React, { useCallback } from 'react';
+import React, { useCallback, useMemo } from 'react';
import * as R from 'ramda';
import { sumBy, isEmpty, last, keyBy, groupBy } from 'lodash';
import { useItem } from '@/hooks/query';
@@ -116,19 +116,20 @@ export function useFetchItemRow({ landedCost, itemType, notifyNewRow }) {
? item.purchase_description
: item.sell_description;
+ // Detarmines whether the landed cost checkbox should be disabled.
+ const landedCostDisabled = isLandedCostDisabled(item);
+
const taxRateId =
itemType === ITEM_TYPE.PURCHASABLE
? item.purchase_tax_rate_id
: item.sell_tax_rate_id;
- // Detarmines whether the landed cost checkbox should be disabled.
- const landedCostDisabled = isLandedCostDisabled(item);
-
// The new row.
const newRow = {
rate: price,
description,
quantity: 1,
+ tax_rate_id: taxRateId,
...(landedCost
? {
landed_cost: false,
@@ -164,13 +165,21 @@ export const composeRowsOnEditCell = R.curry(
/**
* Compose table rows when insert a new row to table rows.
*/
-export const composeRowsOnNewRow = R.curry((rowIndex, newRow, rows) => {
- return compose(
- orderingLinesIndexes,
- updateItemsEntriesTotal,
- updateTableRow(rowIndex, newRow),
- )(rows);
-});
+export const useComposeRowsOnNewRow = () => {
+ const { taxRates, isInclusiveTax } = useItemEntriesTableContext();
+
+ return React.useMemo(() => {
+ return R.curry((rowIndex, newRow, rows) => {
+ return compose(
+ assignEntriesTaxAmount(isInclusiveTax),
+ assignEntriesTaxRate(taxRates),
+ orderingLinesIndexes,
+ updateItemsEntriesTotal,
+ updateTableRow(rowIndex, newRow),
+ )(rows);
+ });
+ }, [isInclusiveTax, taxRates]);
+};
/**
* Associate tax rate to entries.
diff --git a/packages/webapp/src/containers/Items/ItemFormBody.tsx b/packages/webapp/src/containers/Items/ItemFormBody.tsx
index 5d7355ea8..7e5782599 100644
--- a/packages/webapp/src/containers/Items/ItemFormBody.tsx
+++ b/packages/webapp/src/containers/Items/ItemFormBody.tsx
@@ -29,14 +29,16 @@ import {
costPriceFieldShouldUpdate,
costAccountFieldShouldUpdate,
purchaseDescFieldShouldUpdate,
+ taxRateFieldShouldUpdate,
} from './utils';
import { compose, inputIntent } from '@/utils';
+import { TaxRatesSelect } from '@/components/TaxRates/TaxRatesSelect';
/**
* Item form body.
*/
function ItemFormBody({ organization: { base_currency } }) {
- const { accounts } = useItemFormContext();
+ const { accounts, taxRates } = useItemFormContext();
const { values } = useFormikContext();
return (
@@ -111,7 +113,20 @@ function ItemFormBody({ organization: { base_currency } }) {
filterByParentTypes={[ACCOUNT_PARENT_TYPE.INCOME]}
fill={true}
allowCreate={true}
- fastField={true}
+ fastField={true}
+ />
+
+
+ {/*------------- Sell Tax Rate ------------- */}
+
+
@@ -213,6 +228,24 @@ function ItemFormBody({ organization: { base_currency } }) {
/>
+ {/*------------- Purchase Tax Rate ------------- */}
+
+
+
+
{
);
};
+export const taxRateFieldShouldUpdate = (newProps, oldProps) => {
+ return (
+ newProps.shouldUpdateDeps.taxRates !== oldProps.shouldUpdateDeps.taxRates ||
+ defaultFastFieldShouldUpdate(newProps, oldProps)
+ );
+};
+
export function transformItemsTableState(tableState) {
return {
...transformTableStateToQuery(tableState),
diff --git a/packages/webapp/src/containers/Sales/Invoices/InvoiceForm/InvoiceItemsEntriesEditorField.tsx b/packages/webapp/src/containers/Sales/Invoices/InvoiceForm/InvoiceItemsEntriesEditorField.tsx
index 0a0270b58..08f3a1a81 100644
--- a/packages/webapp/src/containers/Sales/Invoices/InvoiceForm/InvoiceItemsEntriesEditorField.tsx
+++ b/packages/webapp/src/containers/Sales/Invoices/InvoiceForm/InvoiceItemsEntriesEditorField.tsx
@@ -5,6 +5,7 @@ import ItemsEntriesTable from '@/containers/Entries/ItemsEntriesTable';
import { useInvoiceFormContext } from './InvoiceFormProvider';
import { entriesFieldShouldUpdate } from './utils';
import { TaxType } from '@/interfaces/TaxRates';
+import { ITEM_TYPE } from '@/containers/Entries/utils';
/**
* Invoice items entries editor field.
@@ -31,6 +32,7 @@ export default function InvoiceItemsEntriesEditorField() {
}}
items={items}
taxRates={taxRates}
+ itemType={ITEM_TYPE.SELLABLE}
errors={error}
linesNumber={4}
currencyCode={values.currency_code}
diff --git a/packages/webapp/src/containers/TaxRates/dialogs/TaxRateFormDialog/TaxRateFormDialogBoot.tsx b/packages/webapp/src/containers/TaxRates/dialogs/TaxRateFormDialog/TaxRateFormDialogBoot.tsx
index 6c3981016..166b2ffe2 100644
--- a/packages/webapp/src/containers/TaxRates/dialogs/TaxRateFormDialog/TaxRateFormDialogBoot.tsx
+++ b/packages/webapp/src/containers/TaxRates/dialogs/TaxRateFormDialog/TaxRateFormDialogBoot.tsx
@@ -1,7 +1,7 @@
// @ts-nocheck
import React from 'react';
import { DialogContent } from '@/components';
-import { useTaxRate, useTaxRates } from '@/hooks/query/taxRates';
+import { useTaxRate } from '@/hooks/query/taxRates';
import { DialogsName } from '@/constants/dialogs';
const TaxRateFormDialogContext = React.createContext();
diff --git a/packages/webapp/src/hooks/query/taxRates.ts b/packages/webapp/src/hooks/query/taxRates.ts
index 6a731b4e0..8b4dc1f47 100644
--- a/packages/webapp/src/hooks/query/taxRates.ts
+++ b/packages/webapp/src/hooks/query/taxRates.ts
@@ -59,6 +59,8 @@ export function useEditTaxRate(props) {
onSuccess: (res, id) => {
commonInvalidateQueries(queryClient);
queryClient.invalidateQueries([QUERY_TYPES.TAX_RATES, id]);
+ queryClient.invalidateQueries(QUERY_TYPES.ITEM);
+ queryClient.invalidateQueries(QUERY_TYPES.ITEMS);
},
...props,
},
diff --git a/packages/webapp/src/lang/en/index.json b/packages/webapp/src/lang/en/index.json
index 68cb44364..1b2e25f1f 100644
--- a/packages/webapp/src/lang/en/index.json
+++ b/packages/webapp/src/lang/en/index.json
@@ -334,6 +334,8 @@
"currency_name_": "Currency name",
"cost_account_id": "Cost account",
"sell_account_id": "Sell account",
+ "item.details.sell_tax_rate": "Sell Tax Rate",
+ "item.details.purchase_tax_rate": "Purchase Tax Rate",
"item_type_": "Item type",
"item_name_": "Item name",
"organization_industry_": "Organization industry",