2
0
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:
Oliver 2024-11-27 15:01:07 +11:00 committed by GitHub
parent af39189e7e
commit 81e87a65e2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 44 additions and 13 deletions

View File

@ -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`
}); });
} }

View File

@ -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>
); );

View File

@ -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();

View File

@ -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();