mirror of
https://github.com/inventree/InvenTree.git
synced 2026-09-27 22:26:00 +00:00
[UI] Suggested pricing (#10867)
* Refactor NumberField into separate component * Add helper func to ensure a number is a number * Use placeholder value for suggested sale price * Fix for auto-fill * Tweak price calculation * Add UI testing for sales order price breaks * Fix aria label name * Annotate price breaks to supplier part * Fetch price break data * Support price breaks for purchase order pricing * Fix required to prevent circular imports * Add playwright tests for purchase order price breaks * Bump API version * Re-add output options for SupplierPriceBreakList * Revert change * Simplify unit test
This commit is contained in:
@@ -34,6 +34,7 @@ import { StandaloneField } from '../components/forms/StandaloneField';
|
||||
|
||||
import { ProgressBar } from '@lib/components/ProgressBar';
|
||||
import { apiUrl } from '@lib/functions/Api';
|
||||
import { toNumber } from '@lib/functions/Conversion';
|
||||
import type {
|
||||
ApiFormAdjustFilterType,
|
||||
ApiFormFieldSet
|
||||
@@ -58,19 +59,59 @@ import { useGlobalSettingsState } from '../states/SettingsStates';
|
||||
export function usePurchaseOrderLineItemFields({
|
||||
supplierId,
|
||||
orderId,
|
||||
currency,
|
||||
create
|
||||
}: {
|
||||
supplierId?: number;
|
||||
orderId?: number;
|
||||
currency?: string;
|
||||
create?: boolean;
|
||||
}) {
|
||||
const globalSettings = useGlobalSettingsState();
|
||||
|
||||
const [purchasePrice, setPurchasePrice] = useState<string>('');
|
||||
const [autoPricing, setAutoPricing] = useState(true);
|
||||
const [purchasePriceCurrency, setPurchasePriceCurrency] = useState<string>(
|
||||
currency ?? ''
|
||||
);
|
||||
|
||||
const [autoPricing, setAutoPricing] = useState(false);
|
||||
|
||||
const [quantity, setQuantity] = useState<string>('1');
|
||||
|
||||
// Internal part information
|
||||
const [part, setPart] = useState<any>({});
|
||||
const [priceBreaks, setPriceBreaks] = useState<any[]>([]);
|
||||
const [suggestedPurchasePrice, setSuggestedPurchasePrice] = useState<
|
||||
string | undefined
|
||||
>(undefined);
|
||||
|
||||
// Update suggested purchase price when part, quantity, or price breaks change
|
||||
useEffect(() => {
|
||||
// Only attempt to set purchase price for new line items
|
||||
if (!create) return;
|
||||
|
||||
const qty = toNumber(quantity, null);
|
||||
|
||||
if (qty == null || qty <= 0) {
|
||||
setSuggestedPurchasePrice(undefined);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!part || !priceBreaks || priceBreaks.length === 0) {
|
||||
setSuggestedPurchasePrice(undefined);
|
||||
return;
|
||||
}
|
||||
|
||||
const applicablePriceBreaks = priceBreaks
|
||||
.filter((pb: any) => qty >= pb.quantity)
|
||||
.sort((a: any, b: any) => b.quantity - a.quantity);
|
||||
|
||||
if (applicablePriceBreaks.length) {
|
||||
setSuggestedPurchasePrice(applicablePriceBreaks[0].price);
|
||||
} else {
|
||||
setSuggestedPurchasePrice(undefined);
|
||||
}
|
||||
}, [create, part, quantity, priceBreaks]);
|
||||
|
||||
useEffect(() => {
|
||||
if (autoPricing) {
|
||||
@@ -95,9 +136,11 @@ export function usePurchaseOrderLineItemFields({
|
||||
part_detail: true,
|
||||
supplier_detail: true,
|
||||
active: true,
|
||||
part_active: true
|
||||
part_active: true,
|
||||
price_breaks: true
|
||||
},
|
||||
onValueChange: (value, record) => {
|
||||
setPriceBreaks(record?.price_breaks ?? []);
|
||||
setPart(record?.part_detail ?? {});
|
||||
},
|
||||
adjustFilters: (adjust: ApiFormAdjustFilterType) => {
|
||||
@@ -108,14 +151,22 @@ export function usePurchaseOrderLineItemFields({
|
||||
}
|
||||
},
|
||||
reference: {},
|
||||
quantity: {},
|
||||
quantity: {
|
||||
onValueChange: (value) => {
|
||||
setQuantity(value);
|
||||
}
|
||||
},
|
||||
purchase_price: {
|
||||
icon: <IconCurrencyDollar />,
|
||||
value: purchasePrice,
|
||||
placeholder: suggestedPurchasePrice,
|
||||
placeholderAutofill: true,
|
||||
onValueChange: setPurchasePrice
|
||||
},
|
||||
purchase_price_currency: {
|
||||
icon: <IconCoins />
|
||||
icon: <IconCoins />,
|
||||
value: purchasePriceCurrency,
|
||||
onValueChange: setPurchasePriceCurrency
|
||||
},
|
||||
auto_pricing: {
|
||||
value: autoPricing,
|
||||
@@ -162,7 +213,8 @@ export function usePurchaseOrderLineItemFields({
|
||||
globalSettings,
|
||||
supplierId,
|
||||
autoPricing,
|
||||
purchasePrice
|
||||
purchasePrice,
|
||||
suggestedPurchasePrice
|
||||
]);
|
||||
|
||||
return fields;
|
||||
|
||||
Reference in New Issue
Block a user