mirror of
https://github.com/inventree/InvenTree.git
synced 2026-08-16 02:06:29 +00:00
Allow bulk-edit for ReturnOrderLineItem (#12635)
* Allow bulk-edit for ReturnOrderLineItem - Allow bulk change of line item outcome * Update API version documentation with pull request links
This commit is contained in:
@@ -1,11 +1,14 @@
|
|||||||
"""InvenTree API version information."""
|
"""InvenTree API version information."""
|
||||||
|
|
||||||
# InvenTree API version
|
# InvenTree API version
|
||||||
INVENTREE_API_VERSION = 530
|
INVENTREE_API_VERSION = 531
|
||||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||||
|
|
||||||
INVENTREE_API_TEXT = """
|
INVENTREE_API_TEXT = """
|
||||||
|
|
||||||
|
v531 -> 2026-08-13 : https://github.com/inventree/InvenTree/pull/12635
|
||||||
|
- Adds "bulk update" support for the ReturnOrderLineItem API endpoint
|
||||||
|
|
||||||
v530 -> 2026-07-28 : https://github.com/inventree/InvenTree/pull/12487
|
v530 -> 2026-07-28 : https://github.com/inventree/InvenTree/pull/12487
|
||||||
- Adds searching against ReportSnippet API endpoint
|
- Adds searching against ReportSnippet API endpoint
|
||||||
|
|
||||||
|
|||||||
@@ -1793,6 +1793,7 @@ class ReturnOrderLineItemOutputOptions(OutputConfiguration):
|
|||||||
|
|
||||||
class ReturnOrderLineItemList(
|
class ReturnOrderLineItemList(
|
||||||
ReturnOrderLineItemMixin,
|
ReturnOrderLineItemMixin,
|
||||||
|
BulkUpdateMixin,
|
||||||
DataExportViewMixin,
|
DataExportViewMixin,
|
||||||
OutputOptionsMixin,
|
OutputOptionsMixin,
|
||||||
ListCreateDestroyAPIView,
|
ListCreateDestroyAPIView,
|
||||||
|
|||||||
@@ -3716,6 +3716,42 @@ class ReturnOrderLineItemTests(InvenTreeAPITestCase):
|
|||||||
|
|
||||||
self.assertEqual(models.ReturnOrderLineItem.objects.count(), n - 1)
|
self.assertEqual(models.ReturnOrderLineItem.objects.count(), n - 1)
|
||||||
|
|
||||||
|
def test_bulk_update(self):
|
||||||
|
"""Test that we can bulk update the 'outcome' field for multiple ReturnOrderLineItems via the API."""
|
||||||
|
ro = models.ReturnOrder.objects.get(pk=6)
|
||||||
|
|
||||||
|
# Create some extra line items against the same order, so we have multiple to update
|
||||||
|
models.ReturnOrderLineItem.objects.bulk_create([
|
||||||
|
models.ReturnOrderLineItem(order=ro, item_id=1006, quantity=1),
|
||||||
|
models.ReturnOrderLineItem(order=ro, item_id=1007, quantity=1),
|
||||||
|
])
|
||||||
|
|
||||||
|
items = list(
|
||||||
|
models.ReturnOrderLineItem.objects.filter(order=ro).values_list(
|
||||||
|
'pk', flat=True
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(len(items), 3)
|
||||||
|
|
||||||
|
for line in models.ReturnOrderLineItem.objects.filter(pk__in=items):
|
||||||
|
self.assertEqual(line.outcome, ReturnOrderLineStatus.PENDING)
|
||||||
|
|
||||||
|
url = reverse('api-return-order-line-list')
|
||||||
|
|
||||||
|
data = {'items': items, 'outcome': ReturnOrderLineStatus.REPAIR.value}
|
||||||
|
|
||||||
|
# Update should fail without the correct role
|
||||||
|
self.patch(url, data, expected_code=403)
|
||||||
|
|
||||||
|
self.assignRole('return_order.change')
|
||||||
|
|
||||||
|
response = self.patch(url, data, expected_code=200).data
|
||||||
|
self.assertEqual(len(response['items']), 3)
|
||||||
|
|
||||||
|
for line in models.ReturnOrderLineItem.objects.filter(pk__in=items):
|
||||||
|
self.assertEqual(line.outcome, ReturnOrderLineStatus.REPAIR.value)
|
||||||
|
|
||||||
def test_extra_line_bulk_delete(self):
|
def test_extra_line_bulk_delete(self):
|
||||||
"""Test that we can bulk delete multiple ReturnOrderExtraLine items via the API."""
|
"""Test that we can bulk delete multiple ReturnOrderExtraLine items via the API."""
|
||||||
ro = models.ReturnOrder.objects.first()
|
ro = models.ReturnOrder.objects.first()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { t } from '@lingui/core/macro';
|
import { t } from '@lingui/core/macro';
|
||||||
import { IconSquareArrowRight } from '@tabler/icons-react';
|
import { IconFlag, IconSquareArrowRight } from '@tabler/icons-react';
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { ActionButton } from '@lib/components/ActionButton';
|
import { ActionButton } from '@lib/components/ActionButton';
|
||||||
@@ -16,6 +16,7 @@ import { apiUrl } from '@lib/functions/Api';
|
|||||||
import useTable from '@lib/hooks/UseTable';
|
import useTable from '@lib/hooks/UseTable';
|
||||||
import type { TableFilter } from '@lib/types/Filters';
|
import type { TableFilter } from '@lib/types/Filters';
|
||||||
import type { TableColumn } from '@lib/types/Tables';
|
import type { TableColumn } from '@lib/types/Tables';
|
||||||
|
import { Alert } from '@mantine/core';
|
||||||
import {
|
import {
|
||||||
DateColumn,
|
DateColumn,
|
||||||
DescriptionColumn,
|
DescriptionColumn,
|
||||||
@@ -37,6 +38,7 @@ import {
|
|||||||
useReturnOrderLineItemFields
|
useReturnOrderLineItemFields
|
||||||
} from '../../forms/ReturnOrderForms';
|
} from '../../forms/ReturnOrderForms';
|
||||||
import {
|
import {
|
||||||
|
useBulkEditApiFormModal,
|
||||||
useCreateApiFormModal,
|
useCreateApiFormModal,
|
||||||
useDeleteApiFormModal,
|
useDeleteApiFormModal,
|
||||||
useEditApiFormModal
|
useEditApiFormModal
|
||||||
@@ -110,6 +112,21 @@ export default function ReturnOrderLineItemTable({
|
|||||||
table: table
|
table: table
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const setOutcome = useBulkEditApiFormModal({
|
||||||
|
url: ApiEndpoints.return_order_line_list,
|
||||||
|
items: table.selectedIds,
|
||||||
|
title: t`Set Outcome`,
|
||||||
|
preFormContent: (
|
||||||
|
<Alert color='blue'>
|
||||||
|
{t`Adjust the outcome for the selected line items.`}
|
||||||
|
</Alert>
|
||||||
|
),
|
||||||
|
fields: {
|
||||||
|
outcome: {}
|
||||||
|
},
|
||||||
|
onFormSuccess: table.refreshTable
|
||||||
|
});
|
||||||
|
|
||||||
const tableColumns: TableColumn[] = useMemo(() => {
|
const tableColumns: TableColumn[] = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
LineItemColumn({}),
|
LineItemColumn({}),
|
||||||
@@ -211,6 +228,16 @@ export default function ReturnOrderLineItemTable({
|
|||||||
receiveLineItems.open();
|
receiveLineItems.open();
|
||||||
}}
|
}}
|
||||||
disabled={table.selectedRecords.length == 0}
|
disabled={table.selectedRecords.length == 0}
|
||||||
|
/>,
|
||||||
|
<ActionButton
|
||||||
|
key='set-outcome'
|
||||||
|
tooltip={t`Set outcome for selected items`}
|
||||||
|
icon={<IconFlag />}
|
||||||
|
hidden={!editable || !user.hasChangeRole(UserRoles.return_order)}
|
||||||
|
onClick={() => {
|
||||||
|
setOutcome.open();
|
||||||
|
}}
|
||||||
|
disabled={table.selectedRecords.length == 0}
|
||||||
/>
|
/>
|
||||||
];
|
];
|
||||||
}, [user, editable, inProgress, orderId, table.selectedRecords]);
|
}, [user, editable, inProgress, orderId, table.selectedRecords]);
|
||||||
@@ -266,6 +293,7 @@ export default function ReturnOrderLineItemTable({
|
|||||||
{editLine.modal}
|
{editLine.modal}
|
||||||
{deleteLine.modal}
|
{deleteLine.modal}
|
||||||
{receiveLineItems.modal}
|
{receiveLineItems.modal}
|
||||||
|
{setOutcome.modal}
|
||||||
<InvenTreeTable
|
<InvenTreeTable
|
||||||
url={apiUrl(ApiEndpoints.return_order_line_list)}
|
url={apiUrl(ApiEndpoints.return_order_line_list)}
|
||||||
tableState={table}
|
tableState={table}
|
||||||
@@ -279,7 +307,7 @@ export default function ReturnOrderLineItemTable({
|
|||||||
},
|
},
|
||||||
defaultSortColumn: 'line',
|
defaultSortColumn: 'line',
|
||||||
enableSelection:
|
enableSelection:
|
||||||
inProgress && user.hasChangeRole(UserRoles.return_order),
|
editable && user.hasChangeRole(UserRoles.return_order),
|
||||||
enableBulkDelete:
|
enableBulkDelete:
|
||||||
editable && user.hasDeleteRole(UserRoles.return_order),
|
editable && user.hasDeleteRole(UserRoles.return_order),
|
||||||
afterBulkDelete: orderDetailRefresh,
|
afterBulkDelete: orderDetailRefresh,
|
||||||
|
|||||||
Reference in New Issue
Block a user