mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-22 06:40:54 +00:00
Duplicate orders via API (#8145)
* Refactor API endpoint for duplicating line items from a purchase order - Previously was "hidden" (undocumented) - Cleanup / refactor code - Now matches part duplication options - Generic implementation supports all order types * Update forms * Refactor line item duplication * Implement front-end support for return orders * Enable duplication of sales orders from PUI * Bump API version
This commit is contained in:
src
backend
InvenTree
InvenTree
order
templates
js
translated
frontend
src
@ -138,14 +138,19 @@ export function usePurchaseOrderLineItemFields({
|
||||
/**
|
||||
* Construct a set of fields for creating / editing a PurchaseOrder instance
|
||||
*/
|
||||
export function usePurchaseOrderFields(): ApiFormFieldSet {
|
||||
export function usePurchaseOrderFields({
|
||||
duplicateOrderId
|
||||
}: {
|
||||
duplicateOrderId?: number;
|
||||
}): ApiFormFieldSet {
|
||||
return useMemo(() => {
|
||||
return {
|
||||
let fields: ApiFormFieldSet = {
|
||||
reference: {
|
||||
icon: <IconHash />
|
||||
},
|
||||
description: {},
|
||||
supplier: {
|
||||
disabled: duplicateOrderId !== undefined,
|
||||
filters: {
|
||||
is_supplier: true,
|
||||
active: true
|
||||
@ -187,7 +192,23 @@ export function usePurchaseOrderFields(): ApiFormFieldSet {
|
||||
icon: <IconUsers />
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Order duplication fields
|
||||
if (!!duplicateOrderId) {
|
||||
fields.duplicate = {
|
||||
children: {
|
||||
order_id: {
|
||||
hidden: true,
|
||||
value: duplicateOrderId
|
||||
},
|
||||
copy_lines: {},
|
||||
copy_extra_lines: {}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return fields;
|
||||
}, [duplicateOrderId]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,16 +1,88 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import { Flex, Table } from '@mantine/core';
|
||||
import { IconUsers } from '@tabler/icons-react';
|
||||
import { IconAddressBook, IconUser, IconUsers } from '@tabler/icons-react';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import RemoveRowButton from '../components/buttons/RemoveRowButton';
|
||||
import { ApiFormFieldSet } from '../components/forms/fields/ApiFormField';
|
||||
import {
|
||||
ApiFormAdjustFilterType,
|
||||
ApiFormFieldSet
|
||||
} from '../components/forms/fields/ApiFormField';
|
||||
import { TableFieldRowProps } from '../components/forms/fields/TableField';
|
||||
import { Thumbnail } from '../components/images/Thumbnail';
|
||||
import { ApiEndpoints } from '../enums/ApiEndpoints';
|
||||
import { useCreateApiFormModal } from '../hooks/UseForm';
|
||||
import { apiUrl } from '../states/ApiState';
|
||||
|
||||
export function useReturnOrderFields({
|
||||
duplicateOrderId
|
||||
}: {
|
||||
duplicateOrderId?: number;
|
||||
}): ApiFormFieldSet {
|
||||
return useMemo(() => {
|
||||
let fields: ApiFormFieldSet = {
|
||||
reference: {},
|
||||
description: {},
|
||||
customer: {
|
||||
disabled: duplicateOrderId != undefined,
|
||||
filters: {
|
||||
is_customer: true,
|
||||
active: true
|
||||
}
|
||||
},
|
||||
customer_reference: {},
|
||||
project_code: {},
|
||||
order_currency: {},
|
||||
target_date: {},
|
||||
link: {},
|
||||
contact: {
|
||||
icon: <IconUser />,
|
||||
adjustFilters: (value: ApiFormAdjustFilterType) => {
|
||||
return {
|
||||
...value.filters,
|
||||
company: value.data.customer
|
||||
};
|
||||
}
|
||||
},
|
||||
address: {
|
||||
icon: <IconAddressBook />,
|
||||
adjustFilters: (value: ApiFormAdjustFilterType) => {
|
||||
return {
|
||||
...value.filters,
|
||||
company: value.data.customer
|
||||
};
|
||||
}
|
||||
},
|
||||
responsible: {
|
||||
filters: {
|
||||
is_active: true
|
||||
},
|
||||
icon: <IconUsers />
|
||||
}
|
||||
};
|
||||
|
||||
// Order duplication fields
|
||||
if (!!duplicateOrderId) {
|
||||
fields.duplicate = {
|
||||
children: {
|
||||
order_id: {
|
||||
hidden: true,
|
||||
value: duplicateOrderId
|
||||
},
|
||||
copy_lines: {
|
||||
// Cannot duplicate lines from a return order!
|
||||
value: false,
|
||||
hidden: true
|
||||
},
|
||||
copy_extra_lines: {}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return fields;
|
||||
}, [duplicateOrderId]);
|
||||
}
|
||||
|
||||
export function useReturnOrderLineItemFields({
|
||||
orderId,
|
||||
customerId,
|
||||
|
@ -6,12 +6,17 @@ import {
|
||||
ApiFormFieldSet
|
||||
} from '../components/forms/fields/ApiFormField';
|
||||
|
||||
export function useSalesOrderFields(): ApiFormFieldSet {
|
||||
export function useSalesOrderFields({
|
||||
duplicateOrderId
|
||||
}: {
|
||||
duplicateOrderId?: number;
|
||||
}): ApiFormFieldSet {
|
||||
return useMemo(() => {
|
||||
return {
|
||||
let fields: ApiFormFieldSet = {
|
||||
reference: {},
|
||||
description: {},
|
||||
customer: {
|
||||
disabled: duplicateOrderId != undefined,
|
||||
filters: {
|
||||
is_customer: true,
|
||||
active: true
|
||||
@ -44,7 +49,23 @@ export function useSalesOrderFields(): ApiFormFieldSet {
|
||||
icon: <IconUsers />
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Order duplication fields
|
||||
if (!!duplicateOrderId) {
|
||||
fields.duplicate = {
|
||||
children: {
|
||||
order_id: {
|
||||
hidden: true,
|
||||
value: duplicateOrderId
|
||||
},
|
||||
copy_lines: {},
|
||||
copy_extra_lines: {}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return fields;
|
||||
}, [duplicateOrderId]);
|
||||
}
|
||||
|
||||
export function useSalesOrderLineItemFields({
|
||||
@ -125,47 +146,3 @@ export function useSalesOrderShipmentFields(): ApiFormFieldSet {
|
||||
};
|
||||
}, []);
|
||||
}
|
||||
|
||||
export function useReturnOrderFields(): ApiFormFieldSet {
|
||||
return useMemo(() => {
|
||||
return {
|
||||
reference: {},
|
||||
description: {},
|
||||
customer: {
|
||||
filters: {
|
||||
is_customer: true,
|
||||
active: true
|
||||
}
|
||||
},
|
||||
customer_reference: {},
|
||||
project_code: {},
|
||||
order_currency: {},
|
||||
target_date: {},
|
||||
link: {},
|
||||
contact: {
|
||||
icon: <IconUser />,
|
||||
adjustFilters: (value: ApiFormAdjustFilterType) => {
|
||||
return {
|
||||
...value.filters,
|
||||
company: value.data.customer
|
||||
};
|
||||
}
|
||||
},
|
||||
address: {
|
||||
icon: <IconAddressBook />,
|
||||
adjustFilters: (value: ApiFormAdjustFilterType) => {
|
||||
return {
|
||||
...value.filters,
|
||||
company: value.data.customer
|
||||
};
|
||||
}
|
||||
},
|
||||
responsible: {
|
||||
filters: {
|
||||
is_active: true
|
||||
},
|
||||
icon: <IconUsers />
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
}
|
||||
|
@ -81,7 +81,11 @@ export default function PurchaseOrderDetail() {
|
||||
);
|
||||
}, [order, globalSettings]);
|
||||
|
||||
const purchaseOrderFields = usePurchaseOrderFields();
|
||||
const purchaseOrderFields = usePurchaseOrderFields({});
|
||||
|
||||
const duplicatePurchaseOrderFields = usePurchaseOrderFields({
|
||||
duplicateOrderId: order.pk
|
||||
});
|
||||
|
||||
const editPurchaseOrder = useEditApiFormModal({
|
||||
url: ApiEndpoints.purchase_order_list,
|
||||
@ -96,7 +100,7 @@ export default function PurchaseOrderDetail() {
|
||||
const duplicatePurchaseOrder = useCreateApiFormModal({
|
||||
url: ApiEndpoints.purchase_order_list,
|
||||
title: t`Add Purchase Order`,
|
||||
fields: purchaseOrderFields,
|
||||
fields: duplicatePurchaseOrderFields,
|
||||
initialData: {
|
||||
...order,
|
||||
reference: undefined
|
||||
|
@ -34,7 +34,7 @@ import { formatCurrency } from '../../defaults/formatters';
|
||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||
import { ModelType } from '../../enums/ModelType';
|
||||
import { UserRoles } from '../../enums/Roles';
|
||||
import { useReturnOrderFields } from '../../forms/SalesOrderForms';
|
||||
import { useReturnOrderFields } from '../../forms/ReturnOrderForms';
|
||||
import {
|
||||
useCreateApiFormModal,
|
||||
useEditApiFormModal
|
||||
@ -304,7 +304,11 @@ export default function ReturnOrderDetail() {
|
||||
];
|
||||
}, [order, instanceQuery]);
|
||||
|
||||
const returnOrderFields = useReturnOrderFields();
|
||||
const returnOrderFields = useReturnOrderFields({});
|
||||
|
||||
const duplicateReturnOrderFields = useReturnOrderFields({
|
||||
duplicateOrderId: order.pk
|
||||
});
|
||||
|
||||
const editReturnOrder = useEditApiFormModal({
|
||||
url: ApiEndpoints.return_order_list,
|
||||
@ -319,7 +323,7 @@ export default function ReturnOrderDetail() {
|
||||
const duplicateReturnOrder = useCreateApiFormModal({
|
||||
url: ApiEndpoints.return_order_list,
|
||||
title: t`Add Return Order`,
|
||||
fields: returnOrderFields,
|
||||
fields: duplicateReturnOrderFields,
|
||||
initialData: {
|
||||
...order,
|
||||
reference: undefined
|
||||
|
@ -231,7 +231,7 @@ export default function SalesOrderDetail() {
|
||||
|
||||
const soStatus = useStatusCodes({ modelType: ModelType.salesorder });
|
||||
|
||||
const salesOrderFields = useSalesOrderFields();
|
||||
const salesOrderFields = useSalesOrderFields({});
|
||||
|
||||
const editSalesOrder = useEditApiFormModal({
|
||||
url: ApiEndpoints.sales_order_list,
|
||||
@ -243,10 +243,14 @@ export default function SalesOrderDetail() {
|
||||
}
|
||||
});
|
||||
|
||||
const duplicateOrderFields = useSalesOrderFields({
|
||||
duplicateOrderId: order.pk
|
||||
});
|
||||
|
||||
const duplicateSalesOrder = useCreateApiFormModal({
|
||||
url: ApiEndpoints.sales_order_list,
|
||||
title: t`Add Sales Order`,
|
||||
fields: salesOrderFields,
|
||||
fields: duplicateOrderFields,
|
||||
initialData: {
|
||||
...order,
|
||||
reference: undefined
|
||||
|
@ -121,7 +121,7 @@ export function PurchaseOrderTable({
|
||||
];
|
||||
}, []);
|
||||
|
||||
const purchaseOrderFields = usePurchaseOrderFields();
|
||||
const purchaseOrderFields = usePurchaseOrderFields({});
|
||||
|
||||
const newPurchaseOrder = useCreateApiFormModal({
|
||||
url: ApiEndpoints.purchase_order_list,
|
||||
|
@ -7,7 +7,7 @@ import { formatCurrency } from '../../defaults/formatters';
|
||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||
import { ModelType } from '../../enums/ModelType';
|
||||
import { UserRoles } from '../../enums/Roles';
|
||||
import { useReturnOrderFields } from '../../forms/SalesOrderForms';
|
||||
import { useReturnOrderFields } from '../../forms/ReturnOrderForms';
|
||||
import { useOwnerFilters, useProjectCodeFilters } from '../../hooks/UseFilter';
|
||||
import { useCreateApiFormModal } from '../../hooks/UseForm';
|
||||
import { useTable } from '../../hooks/UseTable';
|
||||
@ -112,7 +112,7 @@ export function ReturnOrderTable({ params }: Readonly<{ params?: any }>) {
|
||||
];
|
||||
}, []);
|
||||
|
||||
const returnOrderFields = useReturnOrderFields();
|
||||
const returnOrderFields = useReturnOrderFields({});
|
||||
|
||||
const newReturnOrder = useCreateApiFormModal({
|
||||
url: ApiEndpoints.return_order_list,
|
||||
|
@ -77,7 +77,7 @@ export function SalesOrderTable({
|
||||
];
|
||||
}, [projectCodeFilters.choices, responsibleFilters.choices]);
|
||||
|
||||
const salesOrderFields = useSalesOrderFields();
|
||||
const salesOrderFields = useSalesOrderFields({});
|
||||
|
||||
const newSalesOrder = useCreateApiFormModal({
|
||||
url: ApiEndpoints.sales_order_list,
|
||||
|
Reference in New Issue
Block a user