mirror of
https://github.com/inventree/InvenTree.git
synced 2025-11-13 11:26:42 +00:00
[UI] Order form improvements (#10802)
* Auto-fill supplier parts in order wizard * Copy supplier part SKU from order parts wizard * Add "on_order" filter to BuildLine table * Allow ordering by production and ordering quantities * Allow specification of purchase price * Bump API version * Adjust UI testings
This commit is contained in:
@@ -1,12 +1,16 @@
|
||||
"""InvenTree API version information."""
|
||||
|
||||
# InvenTree API version
|
||||
INVENTREE_API_VERSION = 424
|
||||
INVENTREE_API_VERSION = 425
|
||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||
|
||||
INVENTREE_API_TEXT = """
|
||||
|
||||
v424 -> 2025-11-05 : https://github.com/inventree/InvenTree/pull/10730
|
||||
v425 -> 2025-11-11 : https://github.com/inventree/InvenTree/pull/10802
|
||||
- Adds "on_order" filter to the BuildLine API endpoint
|
||||
- Allow BuildLine list to be ordered by "on_order" and "in_production" fields
|
||||
|
||||
v424 -> 2025-11-11 : https://github.com/inventree/InvenTree/pull/10730
|
||||
- Adds more lower / upper bounds to integer fields in the API schema due to bump to Django 5.2- no functional changes
|
||||
|
||||
v423 -> 2025-11-05 : https://github.com/inventree/InvenTree/pull/10772
|
||||
|
||||
@@ -520,6 +520,15 @@ class BuildLineFilter(FilterSet):
|
||||
return queryset.filter(flt)
|
||||
return queryset.exclude(flt)
|
||||
|
||||
on_order = rest_filters.BooleanFilter(label=_('On Order'), method='filter_on_order')
|
||||
|
||||
def filter_on_order(self, queryset, name, value):
|
||||
"""Filter by whether there is stock on order for each BuildLine."""
|
||||
if str2bool(value):
|
||||
return queryset.filter(on_order__gt=0)
|
||||
else:
|
||||
return queryset.filter(on_order=0)
|
||||
|
||||
|
||||
class BuildLineMixin(SerializerContextMixin):
|
||||
"""Mixin class for BuildLine API endpoints."""
|
||||
@@ -606,6 +615,8 @@ class BuildLineList(
|
||||
'trackable',
|
||||
'allow_variants',
|
||||
'inherited',
|
||||
'on_order',
|
||||
'scheduled_to_build',
|
||||
]
|
||||
|
||||
ordering_field_aliases = {
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
ActionIcon,
|
||||
Button,
|
||||
type DefaultMantineColor,
|
||||
type FloatingPosition,
|
||||
CopyButton as MantineCopyButton,
|
||||
type MantineSize,
|
||||
Text,
|
||||
@@ -16,12 +17,18 @@ import type { JSX } from 'react';
|
||||
export function CopyButton({
|
||||
value,
|
||||
label,
|
||||
tooltip,
|
||||
disabled,
|
||||
tooltipPosition,
|
||||
content,
|
||||
size,
|
||||
color = 'gray'
|
||||
}: Readonly<{
|
||||
value: any;
|
||||
label?: string;
|
||||
tooltip?: string;
|
||||
disabled?: boolean;
|
||||
tooltipPosition?: FloatingPosition;
|
||||
content?: JSX.Element;
|
||||
size?: MantineSize;
|
||||
color?: DefaultMantineColor;
|
||||
@@ -31,8 +38,13 @@ export function CopyButton({
|
||||
return (
|
||||
<MantineCopyButton value={value}>
|
||||
{({ copied, copy }) => (
|
||||
<Tooltip label={copied ? t`Copied` : t`Copy`} withArrow>
|
||||
<Tooltip
|
||||
label={copied ? t`Copied` : (tooltip ?? t`Copy`)}
|
||||
withArrow
|
||||
position={tooltipPosition}
|
||||
>
|
||||
<ButtonComponent
|
||||
disabled={disabled}
|
||||
color={copied ? 'teal' : color}
|
||||
onClick={copy}
|
||||
variant='transparent'
|
||||
|
||||
@@ -32,6 +32,7 @@ import { useCreateApiFormModal } from '../../hooks/UseForm';
|
||||
import { useInstance } from '../../hooks/UseInstance';
|
||||
import useWizard from '../../hooks/UseWizard';
|
||||
import { RenderPartColumn } from '../../tables/ColumnRenderers';
|
||||
import { CopyButton } from '../buttons/CopyButton';
|
||||
import RemoveRowButton from '../buttons/RemoveRowButton';
|
||||
import { StandaloneField } from '../forms/StandaloneField';
|
||||
import Expand from '../items/Expand';
|
||||
@@ -235,6 +236,8 @@ function SelectPartsStep({
|
||||
quantity: {
|
||||
// TODO: Auto-fill with the desired quantity
|
||||
},
|
||||
purchase_price: {},
|
||||
purchase_price_currency: {},
|
||||
merge_items: {}
|
||||
};
|
||||
}, [selectedRecord]);
|
||||
@@ -299,6 +302,7 @@ function SelectPartsStep({
|
||||
model: ModelType.supplierpart,
|
||||
placeholder: t`Select supplier part`,
|
||||
required: true,
|
||||
autoFill: true,
|
||||
value: record.supplier_part?.pk,
|
||||
onValueChange: (value, instance) => {
|
||||
onSelectSupplierPart(record.part.pk, instance);
|
||||
@@ -312,6 +316,12 @@ function SelectPartsStep({
|
||||
}}
|
||||
/>
|
||||
</Expand>
|
||||
<CopyButton
|
||||
disabled={!record.supplier_part?.pk}
|
||||
value={record.supplier_part?.SKU}
|
||||
tooltipPosition='top-end'
|
||||
tooltip={t`Copy supplier part number`}
|
||||
/>
|
||||
<AddItemButton
|
||||
tooltip={t`New supplier part`}
|
||||
tooltipAlignment='top-end'
|
||||
|
||||
@@ -107,8 +107,8 @@ export function usePurchaseOrderLineItemFields({
|
||||
};
|
||||
}
|
||||
},
|
||||
quantity: {},
|
||||
reference: {},
|
||||
quantity: {},
|
||||
purchase_price: {
|
||||
icon: <IconCurrencyDollar />,
|
||||
value: purchasePrice,
|
||||
|
||||
@@ -190,7 +190,7 @@ export default function BuildLineTable({
|
||||
{
|
||||
name: 'available',
|
||||
label: t`Available`,
|
||||
description: t`Show items with available stock`
|
||||
description: t`Show items with sufficient available stock`
|
||||
},
|
||||
{
|
||||
name: 'consumable',
|
||||
@@ -217,6 +217,11 @@ export default function BuildLineTable({
|
||||
label: t`Tracked`,
|
||||
description: t`Show tracked lines`
|
||||
},
|
||||
{
|
||||
name: 'on_order',
|
||||
label: t`On Order`,
|
||||
description: t`Show items with stock on order`
|
||||
},
|
||||
PartCategoryFilter()
|
||||
];
|
||||
}, []);
|
||||
@@ -455,6 +460,8 @@ export default function BuildLineTable({
|
||||
},
|
||||
{
|
||||
accessor: 'in_production',
|
||||
sortable: true,
|
||||
ordering: 'scheduled_to_build',
|
||||
render: (record: any) => {
|
||||
if (record.scheduled_to_build > 0) {
|
||||
return (
|
||||
@@ -471,7 +478,8 @@ export default function BuildLineTable({
|
||||
},
|
||||
DecimalColumn({
|
||||
accessor: 'on_order',
|
||||
defaultVisible: false
|
||||
defaultVisible: false,
|
||||
sortable: true
|
||||
}),
|
||||
{
|
||||
accessor: 'allocated',
|
||||
|
||||
@@ -263,7 +263,9 @@ test('Purchase Orders - Order Parts', async ({ browser }) => {
|
||||
|
||||
// Select supplier part
|
||||
await page.getByLabel('related-field-supplier_part').click();
|
||||
await page.getByText('WM1731-ND').click();
|
||||
await page
|
||||
.getByRole('option', { name: 'Thumbnail DigiKey WM1731-ND' })
|
||||
.click();
|
||||
|
||||
// Option to create a new supplier part
|
||||
await page.getByLabel('action-button-new-supplier-part').click();
|
||||
|
||||
Reference in New Issue
Block a user