[feature] Line discount (#12393)

* Add "discount" support to order line items

* Fix total_price annotation for ExtraLineItem

* Add regression tests

* Add frontend support

* Updated documentation

* Added docs

* Bump API version and CHANGELOG

* Remove 'total_price' annotation

- Can be achieved using in-memory python methods

* Apply fix for migration testing

* Revert "Apply fix for migration testing"

This reverts commit 8d9f2dce8c.

* Different approach

* Adjust playwright threshold
This commit is contained in:
Oliver
2026-07-20 20:42:54 +10:00
committed by GitHub
parent 44d8d0e266
commit 4c4c86e180
23 changed files with 355 additions and 27 deletions
@@ -473,6 +473,22 @@ export function DecimalColumn(props: TableColumn): TableColumn {
};
}
export function PercentageColumn(props: TableColumn): TableColumn {
return {
sortable: true,
render: (record: any) => {
const value = resolveItem(record, props.accessor ?? '');
if (value == null || value === 0) {
return '-';
}
return `${formatDecimal(value)}%`;
},
...props
};
}
export function DescriptionColumn(props: TableColumnProps): TableColumn {
return {
accessor: 'description',
+1
View File
@@ -91,6 +91,7 @@ export function extraLineItemFields(): ApiFormFieldSet {
quantity: {},
price: {},
price_currency: {},
discount: {},
project_code: ProjectCodeField(),
notes: {},
link: {}
@@ -186,6 +186,7 @@ export function usePurchaseOrderLineItemFields({
value: purchasePriceCurrency,
onValueChange: setPurchasePriceCurrency
},
discount: {},
auto_pricing: {
default: create !== false,
value: autoPricing,
@@ -133,6 +133,7 @@ export function useReturnOrderLineItemFields({
},
price: {},
price_currency: {},
discount: {},
project_code: ProjectCodeField(),
target_date: {},
notes: {},
@@ -197,6 +197,7 @@ export function useSalesOrderLineItemFields({
value: partCurrency,
onValueChange: setPartCurrency
},
discount: {},
project_code: ProjectCodeField(),
target_date: {},
notes: {},
@@ -19,6 +19,7 @@ import {
LineItemColumn,
LinkColumn,
NoteColumn,
PercentageColumn,
ProjectCodeColumn
} from '../../components/tables/ColumnRenderers';
import { InvenTreeTable } from '../../components/tables/InvenTreeTable';
@@ -69,13 +70,17 @@ export default function ExtraLineItemTable({
currency: record.price_currency
})
},
PercentageColumn({
accessor: 'discount',
title: t`Discount`,
defaultVisible: false
}),
{
accessor: 'total_price',
title: t`Total Price`,
render: (record: any) =>
formatCurrency(record.price, {
currency: record.price_currency,
multiplier: record.quantity
formatCurrency(record.total_price, {
currency: record.price_currency
})
},
ProjectCodeColumn({}),
@@ -30,6 +30,7 @@ import {
LocationColumn,
NoteColumn,
PartColumn,
PercentageColumn,
ProjectCodeColumn,
ReferenceColumn,
TargetDateColumn
@@ -254,13 +255,17 @@ export function PurchaseOrderLineItemTable({
accessor: 'purchase_price',
title: t`Unit Price`
}),
PercentageColumn({
accessor: 'discount',
title: t`Discount`,
defaultVisible: false
}),
{
accessor: 'total_price',
title: t`Total Price`,
render: (record: any) =>
formatCurrency(record.purchase_price, {
currency: record.purchase_price_currency,
multiplier: record.quantity
formatCurrency(record.total_price, {
currency: record.purchase_price_currency
})
},
TargetDateColumn({}),
@@ -23,6 +23,7 @@ import {
LinkColumn,
NoteColumn,
PartColumn,
PercentageColumn,
ProjectCodeColumn,
ReferenceColumn,
StatusColumn,
@@ -148,6 +149,11 @@ export default function ReturnOrderLineItemTable({
render: (record: any) =>
formatCurrency(record.price, { currency: record.price_currency })
},
PercentageColumn({
accessor: 'discount',
title: t`Discount`,
defaultVisible: false
}),
DateColumn({
accessor: 'target_date',
title: t`Target Date`
@@ -36,6 +36,7 @@ import {
IPNColumn,
LineItemColumn,
LinkColumn,
PercentageColumn,
ProjectCodeColumn,
ReferenceColumn,
RenderPartColumn,
@@ -121,13 +122,18 @@ export default function SalesOrderLineItemTable({
currency: record.sale_price_currency
})
},
PercentageColumn({
accessor: 'discount',
title: t`Discount`,
defaultVisible: false
}),
{
accessor: 'total_price',
title: t`Total Price`,
render: (record: any) =>
formatCurrency(record.sale_price, {
currency: record.sale_price_currency,
multiplier: record.quantity
multiplier: record.quantity * (1 - (record.discount ?? 0) / 100)
})
},
DateColumn({
+1 -1
View File
@@ -157,7 +157,7 @@ test('Login - Cold vs Warm vs Hot Load', async ({ page }) => {
// Note: Vite server in dev mode is significantly slower than production build
const COLD_MS_THRESHOLD: number = 5000;
const WARM_MS_THRESHOLD: number = 4000;
const HOT_MS_THRESHOLD: number = 3000;
const HOT_MS_THRESHOLD: number = 3500;
const coldMs = await loginAndMeasure(page);