mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-28 19:46:46 +00:00
[PUI] Fix stock actions (#8569)
* Fix useAssignStockItems - Only allow "salable" parts * Assign item to customer * Adjust playwright tests
This commit is contained in:
parent
af39189e7e
commit
81e87a65e2
@ -870,6 +870,7 @@ function stockOperationModal({
|
|||||||
endpoint,
|
endpoint,
|
||||||
filters,
|
filters,
|
||||||
title,
|
title,
|
||||||
|
successMessage,
|
||||||
modalFunc = useCreateApiFormModal
|
modalFunc = useCreateApiFormModal
|
||||||
}: {
|
}: {
|
||||||
items?: object;
|
items?: object;
|
||||||
@ -880,6 +881,7 @@ function stockOperationModal({
|
|||||||
fieldGenerator: (items: any[]) => ApiFormFieldSet;
|
fieldGenerator: (items: any[]) => ApiFormFieldSet;
|
||||||
endpoint: ApiEndpoints;
|
endpoint: ApiEndpoints;
|
||||||
title: string;
|
title: string;
|
||||||
|
successMessage?: string;
|
||||||
modalFunc?: apiModalFunc;
|
modalFunc?: apiModalFunc;
|
||||||
}) {
|
}) {
|
||||||
const baseParams: any = {
|
const baseParams: any = {
|
||||||
@ -932,12 +934,13 @@ function stockOperationModal({
|
|||||||
fields: fields,
|
fields: fields,
|
||||||
title: title,
|
title: title,
|
||||||
size: '80%',
|
size: '80%',
|
||||||
|
successMessage: successMessage,
|
||||||
onFormSuccess: () => refresh()
|
onFormSuccess: () => refresh()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export type StockOperationProps = {
|
export type StockOperationProps = {
|
||||||
items?: object;
|
items?: any[];
|
||||||
pk?: number;
|
pk?: number;
|
||||||
filters?: any;
|
filters?: any;
|
||||||
model: ModelType.stockitem | 'location' | ModelType.part;
|
model: ModelType.stockitem | 'location' | ModelType.part;
|
||||||
@ -949,7 +952,8 @@ export function useAddStockItem(props: StockOperationProps) {
|
|||||||
...props,
|
...props,
|
||||||
fieldGenerator: stockAddFields,
|
fieldGenerator: stockAddFields,
|
||||||
endpoint: ApiEndpoints.stock_add,
|
endpoint: ApiEndpoints.stock_add,
|
||||||
title: t`Add Stock`
|
title: t`Add Stock`,
|
||||||
|
successMessage: t`Stock added`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -958,7 +962,8 @@ export function useRemoveStockItem(props: StockOperationProps) {
|
|||||||
...props,
|
...props,
|
||||||
fieldGenerator: stockRemoveFields,
|
fieldGenerator: stockRemoveFields,
|
||||||
endpoint: ApiEndpoints.stock_remove,
|
endpoint: ApiEndpoints.stock_remove,
|
||||||
title: t`Remove Stock`
|
title: t`Remove Stock`,
|
||||||
|
successMessage: t`Stock removed`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -967,7 +972,8 @@ export function useTransferStockItem(props: StockOperationProps) {
|
|||||||
...props,
|
...props,
|
||||||
fieldGenerator: stockTransferFields,
|
fieldGenerator: stockTransferFields,
|
||||||
endpoint: ApiEndpoints.stock_transfer,
|
endpoint: ApiEndpoints.stock_transfer,
|
||||||
title: t`Transfer Stock`
|
title: t`Transfer Stock`,
|
||||||
|
successMessage: t`Stock transferred`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -976,7 +982,8 @@ export function useCountStockItem(props: StockOperationProps) {
|
|||||||
...props,
|
...props,
|
||||||
fieldGenerator: stockCountFields,
|
fieldGenerator: stockCountFields,
|
||||||
endpoint: ApiEndpoints.stock_count,
|
endpoint: ApiEndpoints.stock_count,
|
||||||
title: t`Count Stock`
|
title: t`Count Stock`,
|
||||||
|
successMessage: t`Stock counted`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -985,7 +992,8 @@ export function useChangeStockStatus(props: StockOperationProps) {
|
|||||||
...props,
|
...props,
|
||||||
fieldGenerator: stockChangeStatusFields,
|
fieldGenerator: stockChangeStatusFields,
|
||||||
endpoint: ApiEndpoints.stock_change_status,
|
endpoint: ApiEndpoints.stock_change_status,
|
||||||
title: t`Change Stock Status`
|
title: t`Change Stock Status`,
|
||||||
|
successMessage: t`Stock status changed`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -994,16 +1002,24 @@ export function useMergeStockItem(props: StockOperationProps) {
|
|||||||
...props,
|
...props,
|
||||||
fieldGenerator: stockMergeFields,
|
fieldGenerator: stockMergeFields,
|
||||||
endpoint: ApiEndpoints.stock_merge,
|
endpoint: ApiEndpoints.stock_merge,
|
||||||
title: t`Merge Stock`
|
title: t`Merge Stock`,
|
||||||
|
successMessage: t`Stock merged`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useAssignStockItem(props: StockOperationProps) {
|
export function useAssignStockItem(props: StockOperationProps) {
|
||||||
|
// Filter items - only allow 'salable' items
|
||||||
|
const items = useMemo(() => {
|
||||||
|
return props.items?.filter((item) => item?.part_detail?.salable);
|
||||||
|
}, [props.items]);
|
||||||
|
|
||||||
return stockOperationModal({
|
return stockOperationModal({
|
||||||
...props,
|
...props,
|
||||||
|
items: items,
|
||||||
fieldGenerator: stockAssignFields,
|
fieldGenerator: stockAssignFields,
|
||||||
endpoint: ApiEndpoints.stock_assign,
|
endpoint: ApiEndpoints.stock_assign,
|
||||||
title: t`Assign Stock to Customer`
|
title: t`Assign Stock to Customer`,
|
||||||
|
successMessage: t`Stock assigned to customer`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1013,7 +1029,8 @@ export function useDeleteStockItem(props: StockOperationProps) {
|
|||||||
fieldGenerator: stockDeleteFields,
|
fieldGenerator: stockDeleteFields,
|
||||||
endpoint: ApiEndpoints.stock_item_list,
|
endpoint: ApiEndpoints.stock_item_list,
|
||||||
modalFunc: useDeleteApiFormModal,
|
modalFunc: useDeleteApiFormModal,
|
||||||
title: t`Delete Stock Items`
|
title: t`Delete Stock Items`,
|
||||||
|
successMessage: t`Stock deleted`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ import { UserRoles } from '../../enums/Roles';
|
|||||||
import {
|
import {
|
||||||
type StockOperationProps,
|
type StockOperationProps,
|
||||||
useAddStockItem,
|
useAddStockItem,
|
||||||
|
useAssignStockItem,
|
||||||
useCountStockItem,
|
useCountStockItem,
|
||||||
useRemoveStockItem,
|
useRemoveStockItem,
|
||||||
useStockFields,
|
useStockFields,
|
||||||
@ -588,7 +589,7 @@ export default function StockDetail() {
|
|||||||
|
|
||||||
const stockActionProps: StockOperationProps = useMemo(() => {
|
const stockActionProps: StockOperationProps = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
items: stockitem,
|
items: [stockitem],
|
||||||
model: ModelType.stockitem,
|
model: ModelType.stockitem,
|
||||||
refresh: refreshInstance,
|
refresh: refreshInstance,
|
||||||
filters: {
|
filters: {
|
||||||
@ -601,6 +602,7 @@ export default function StockDetail() {
|
|||||||
const addStockItem = useAddStockItem(stockActionProps);
|
const addStockItem = useAddStockItem(stockActionProps);
|
||||||
const removeStockItem = useRemoveStockItem(stockActionProps);
|
const removeStockItem = useRemoveStockItem(stockActionProps);
|
||||||
const transferStockItem = useTransferStockItem(stockActionProps);
|
const transferStockItem = useTransferStockItem(stockActionProps);
|
||||||
|
const assignToCustomer = useAssignStockItem(stockActionProps);
|
||||||
|
|
||||||
const serializeStockFields = useStockItemSerializeFields({
|
const serializeStockFields = useStockItemSerializeFields({
|
||||||
partId: stockitem.part,
|
partId: stockitem.part,
|
||||||
@ -731,7 +733,7 @@ export default function StockDetail() {
|
|||||||
{
|
{
|
||||||
name: t`Return`,
|
name: t`Return`,
|
||||||
tooltip: t`Return from customer`,
|
tooltip: t`Return from customer`,
|
||||||
hidden: !stockitem.sales_order,
|
hidden: !stockitem.customer,
|
||||||
icon: (
|
icon: (
|
||||||
<InvenTreeIcon
|
<InvenTreeIcon
|
||||||
icon='return_orders'
|
icon='return_orders'
|
||||||
@ -741,6 +743,17 @@ export default function StockDetail() {
|
|||||||
onClick: () => {
|
onClick: () => {
|
||||||
stockitem.pk && returnStockItem.open();
|
stockitem.pk && returnStockItem.open();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: t`Assign to Customer`,
|
||||||
|
tooltip: t`Assign to a customer`,
|
||||||
|
hidden: !!stockitem.customer,
|
||||||
|
icon: (
|
||||||
|
<InvenTreeIcon icon='customer' iconProps={{ color: 'blue' }} />
|
||||||
|
),
|
||||||
|
onClick: () => {
|
||||||
|
stockitem.pk && assignToCustomer.open();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
/>,
|
/>,
|
||||||
@ -874,6 +887,7 @@ export default function StockDetail() {
|
|||||||
{transferStockItem.modal}
|
{transferStockItem.modal}
|
||||||
{serializeStockItem.modal}
|
{serializeStockItem.modal}
|
||||||
{returnStockItem.modal}
|
{returnStockItem.modal}
|
||||||
|
{assignToCustomer.modal}
|
||||||
</Stack>
|
</Stack>
|
||||||
</InstanceDetail>
|
</InstanceDetail>
|
||||||
);
|
);
|
||||||
|
@ -604,7 +604,7 @@ export function StockItemTable({
|
|||||||
{
|
{
|
||||||
name: t`Assign to customer`,
|
name: t`Assign to customer`,
|
||||||
icon: <InvenTreeIcon icon='customer' />,
|
icon: <InvenTreeIcon icon='customer' />,
|
||||||
tooltip: t`Order new stock`,
|
tooltip: t`Assign items to a customer`,
|
||||||
disabled: !can_add_stock,
|
disabled: !can_add_stock,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
assignStock.open();
|
assignStock.open();
|
||||||
|
@ -189,7 +189,7 @@ test('Stock - Stock Actions', async ({ page }) => {
|
|||||||
await page.getByRole('button', { name: 'Cancel' }).click();
|
await page.getByRole('button', { name: 'Cancel' }).click();
|
||||||
|
|
||||||
// Find an item which has been sent to a customer
|
// Find an item which has been sent to a customer
|
||||||
await page.goto(`${baseUrl}/stock/item/1012/details`);
|
await page.goto(`${baseUrl}/stock/item/1014/details`);
|
||||||
await page.getByText('Batch Code: 2022-11-12').waitFor();
|
await page.getByText('Batch Code: 2022-11-12').waitFor();
|
||||||
await page.getByText('Unavailable').waitFor();
|
await page.getByText('Unavailable').waitFor();
|
||||||
await page.getByLabel('action-menu-stock-operations').click();
|
await page.getByLabel('action-menu-stock-operations').click();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user