mirror of
https://github.com/inventree/InvenTree.git
synced 2026-04-14 15:28:52 +00:00
Order line number (#11692)
* Add "line number" field for external orders * Updated serializers * Add columns to UI tables * Update form fields * Adds API ordering * Bump API version * Update CHANGELOG.md
This commit is contained in:
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Added
|
||||
|
||||
- [#11692](https://github.com/inventree/InvenTree/pull/11692) adds line item numbering for external orders (purchase, sales and return orders). This allows users to specify a line number for each line item on the order, which can be used for reference purposes. The line number is optional, and can be left blank if not required. The line number is stored as a string, to allow for more flexible formatting (e.g. "1", "1.1", "A", etc).
|
||||
- [#11641](https://github.com/inventree/InvenTree/pull/11641) adds support for custom parameters against the SalesOrderShipment model.
|
||||
- [#11527](https://github.com/inventree/InvenTree/pull/11527) adds a new API endpoint for monitoring the status of a particular background task. This endpoint allows clients to check the status of a background task and receive updates when the task is complete. This is useful for long-running tasks that may take some time to complete, allowing clients to provide feedback to users about the progress of the task.
|
||||
- [#11405](https://github.com/inventree/InvenTree/pull/11405) adds default table filters, which hide inactive items by default. The default table filters are overridden by user filter selection, and only apply to the table view initially presented to the user. This means that users can still view inactive items if they choose to, but they will not be shown by default.
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
"""InvenTree API version information."""
|
||||
|
||||
# InvenTree API version
|
||||
INVENTREE_API_VERSION = 472
|
||||
INVENTREE_API_VERSION = 473
|
||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||
|
||||
INVENTREE_API_TEXT = """
|
||||
|
||||
v473 -> 2026-04-08 : https://github.com/inventree/InvenTree/pull/11692
|
||||
- Adds "line" field to PurchaseOrderLineItem and PurchaseOrderExtraLineItem API endpoints
|
||||
- Adds "line" field to SalesOrderLineItem and SalesOrderExtraLineItem API endpoints
|
||||
- Adds "line" field to ReturnOrderLineItem and ReturnOrderExtraLineItem API endpoints
|
||||
|
||||
v472 -> 2026-04-01 : https://github.com/inventree/InvenTree/pull/xxxx
|
||||
- Fixes writable fields on the user detail endpoint
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ class GeneralExtraLineList(SerializerContextMixin, DataExportViewMixin):
|
||||
|
||||
filter_backends = SEARCH_ORDER_FILTER
|
||||
|
||||
ordering_fields = ['quantity', 'notes', 'reference']
|
||||
ordering_fields = ['quantity', 'notes', 'reference', 'line']
|
||||
|
||||
search_fields = ['quantity', 'notes', 'reference', 'description']
|
||||
|
||||
@@ -717,6 +717,7 @@ class PurchaseOrderLineItemList(
|
||||
'order': 'order__reference',
|
||||
'status': 'order__status',
|
||||
'complete_date': 'order__complete_date',
|
||||
'line': ['line', 'part__SKU'],
|
||||
}
|
||||
|
||||
ordering_fields = [
|
||||
@@ -733,6 +734,7 @@ class PurchaseOrderLineItemList(
|
||||
'order',
|
||||
'status',
|
||||
'complete_date',
|
||||
'line',
|
||||
]
|
||||
|
||||
search_fields = [
|
||||
@@ -1067,6 +1069,7 @@ class SalesOrderLineItemList(
|
||||
'reference',
|
||||
'sale_price',
|
||||
'target_date',
|
||||
'line',
|
||||
]
|
||||
|
||||
ordering_field_aliases = {
|
||||
@@ -1074,6 +1077,7 @@ class SalesOrderLineItemList(
|
||||
'part': 'part__name',
|
||||
'IPN': 'part__IPN',
|
||||
'order': 'order__reference',
|
||||
'line': ['line', 'part__name'],
|
||||
}
|
||||
|
||||
search_fields = ['part__name', 'quantity', 'reference']
|
||||
@@ -1720,9 +1724,11 @@ class ReturnOrderLineItemList(
|
||||
'reference',
|
||||
'target_date',
|
||||
'received_date',
|
||||
'line',
|
||||
]
|
||||
|
||||
ordering_field_aliases = {
|
||||
'line': ['line', 'item__part__name'],
|
||||
'part': 'item__part__name',
|
||||
'IPN': 'item__part__IPN',
|
||||
'stock': ['item__quantity', 'item__serial_int', 'item__serial'],
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
# Generated by Django 5.2.12 on 2026-04-08 03:24
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("order", "0115_purchaseorder_updated_at_returnorder_updated_at_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="purchaseorderextraline",
|
||||
name="line",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
help_text="Line number for this item (optional)",
|
||||
max_length=20,
|
||||
verbose_name="Line Number",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="purchaseorderlineitem",
|
||||
name="line",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
help_text="Line number for this item (optional)",
|
||||
max_length=20,
|
||||
verbose_name="Line Number",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="returnorderextraline",
|
||||
name="line",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
help_text="Line number for this item (optional)",
|
||||
max_length=20,
|
||||
verbose_name="Line Number",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="returnorderlineitem",
|
||||
name="line",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
help_text="Line number for this item (optional)",
|
||||
max_length=20,
|
||||
verbose_name="Line Number",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="salesorderextraline",
|
||||
name="line",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
help_text="Line number for this item (optional)",
|
||||
max_length=20,
|
||||
verbose_name="Line Number",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="salesorderlineitem",
|
||||
name="line",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
help_text="Line number for this item (optional)",
|
||||
max_length=20,
|
||||
verbose_name="Line Number",
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -1793,6 +1793,15 @@ class OrderLineItem(InvenTree.models.InvenTreeMetadataModel):
|
||||
if self.price:
|
||||
return self.quantity * self.price
|
||||
|
||||
line = models.CharField(
|
||||
max_length=20,
|
||||
blank=True,
|
||||
default='',
|
||||
null=False,
|
||||
verbose_name=_('Line Number'),
|
||||
help_text=_('Line number for this item (optional)'),
|
||||
)
|
||||
|
||||
reference = models.CharField(
|
||||
max_length=100,
|
||||
blank=True,
|
||||
|
||||
@@ -276,6 +276,7 @@ class AbstractLineItemSerializer(FilterableSerializerMixin, serializers.Serializ
|
||||
"""Construct a set of fields for this serializer."""
|
||||
return [
|
||||
'pk',
|
||||
'line',
|
||||
'link',
|
||||
'notes',
|
||||
'order',
|
||||
@@ -309,6 +310,7 @@ class AbstractExtraLineSerializer(
|
||||
"""Construct a set of fields for this serializer."""
|
||||
return [
|
||||
'pk',
|
||||
'line',
|
||||
'description',
|
||||
'link',
|
||||
'notes',
|
||||
|
||||
@@ -83,6 +83,7 @@ export function extraLineItemFields(): ApiFormFieldSet {
|
||||
order: {
|
||||
hidden: true
|
||||
},
|
||||
line: {},
|
||||
reference: {},
|
||||
description: {},
|
||||
quantity: {},
|
||||
|
||||
@@ -144,6 +144,7 @@ export function usePurchaseOrderLineItemFields({
|
||||
};
|
||||
}
|
||||
},
|
||||
line: {},
|
||||
reference: {},
|
||||
quantity: {
|
||||
onValueChange: (value) => {
|
||||
|
||||
@@ -128,8 +128,9 @@ export function useReturnOrderLineItemFields({
|
||||
part_detail: true
|
||||
}
|
||||
},
|
||||
quantity: {},
|
||||
line: {},
|
||||
reference: {},
|
||||
quantity: {},
|
||||
outcome: {
|
||||
hidden: create == true
|
||||
},
|
||||
|
||||
@@ -169,6 +169,7 @@ export function useSalesOrderLineItemFields({
|
||||
},
|
||||
onValueChange: (_: any, record?: any) => setPart(record)
|
||||
},
|
||||
line: {},
|
||||
reference: {},
|
||||
quantity: {
|
||||
onValueChange: (value) => {
|
||||
|
||||
@@ -767,3 +767,13 @@ export function TotalPriceColumn(): TableColumn {
|
||||
title: t`Total Price`
|
||||
});
|
||||
}
|
||||
|
||||
export function LineItemColumn(props: TableColumnProps): TableColumn {
|
||||
return {
|
||||
accessor: 'line',
|
||||
title: t`Line Item`,
|
||||
sortable: true,
|
||||
switchable: true,
|
||||
...props
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import { useUserState } from '../../states/UserState';
|
||||
import {
|
||||
DecimalColumn,
|
||||
DescriptionColumn,
|
||||
LineItemColumn,
|
||||
LinkColumn,
|
||||
NoteColumn,
|
||||
ProjectCodeColumn
|
||||
@@ -50,6 +51,7 @@ export default function ExtraLineItemTable({
|
||||
|
||||
const tableColumns: TableColumn[] = useMemo(() => {
|
||||
return [
|
||||
LineItemColumn({}),
|
||||
{
|
||||
accessor: 'reference',
|
||||
switchable: false
|
||||
@@ -177,6 +179,7 @@ export default function ExtraLineItemTable({
|
||||
params: {
|
||||
order: orderId
|
||||
},
|
||||
defaultSortColumn: 'line',
|
||||
rowActions: rowActions,
|
||||
tableActions: tableActions
|
||||
}}
|
||||
|
||||
@@ -36,11 +36,11 @@ import {
|
||||
import useStatusCodes from '../../hooks/UseStatusCodes';
|
||||
import { useTable } from '../../hooks/UseTable';
|
||||
import { useImporterState } from '../../states/ImporterState';
|
||||
import { useGlobalSettingsState } from '../../states/SettingsStates';
|
||||
import { useUserState } from '../../states/UserState';
|
||||
import {
|
||||
CurrencyColumn,
|
||||
DescriptionColumn,
|
||||
LineItemColumn,
|
||||
LinkColumn,
|
||||
LocationColumn,
|
||||
NoteColumn,
|
||||
@@ -74,7 +74,6 @@ export function PurchaseOrderLineItemTable({
|
||||
}>) {
|
||||
const table = useTable('purchase-order-line-item');
|
||||
|
||||
const globalSettings = useGlobalSettingsState();
|
||||
const navigate = useNavigate();
|
||||
const user = useUserState();
|
||||
const openImporter = useImporterState((state) => state.openImporter);
|
||||
@@ -134,6 +133,7 @@ export function PurchaseOrderLineItemTable({
|
||||
|
||||
const tableColumns: TableColumn[] = useMemo(() => {
|
||||
return [
|
||||
LineItemColumn({}),
|
||||
PartColumn({
|
||||
part: 'part_detail',
|
||||
ordering: 'part_name'
|
||||
@@ -435,6 +435,7 @@ export function PurchaseOrderLineItemTable({
|
||||
props={{
|
||||
enableSelection: true,
|
||||
enableDownload: true,
|
||||
defaultSortColumn: 'line',
|
||||
params: {
|
||||
...params,
|
||||
order: orderId,
|
||||
|
||||
@@ -31,6 +31,7 @@ import { useUserState } from '../../states/UserState';
|
||||
import {
|
||||
DateColumn,
|
||||
DescriptionColumn,
|
||||
LineItemColumn,
|
||||
LinkColumn,
|
||||
NoteColumn,
|
||||
PartColumn,
|
||||
@@ -110,6 +111,7 @@ export default function ReturnOrderLineItemTable({
|
||||
|
||||
const tableColumns: TableColumn[] = useMemo(() => {
|
||||
return [
|
||||
LineItemColumn({}),
|
||||
PartColumn({
|
||||
part: 'part_detail',
|
||||
ordering: 'part'
|
||||
@@ -267,6 +269,7 @@ export default function ReturnOrderLineItemTable({
|
||||
item_detail: true,
|
||||
order_detail: true
|
||||
},
|
||||
defaultSortColumn: 'line',
|
||||
enableSelection:
|
||||
inProgress && user.hasChangeRole(UserRoles.return_order),
|
||||
tableActions: tableActions,
|
||||
|
||||
@@ -48,6 +48,7 @@ import {
|
||||
DecimalColumn,
|
||||
DescriptionColumn,
|
||||
IPNColumn,
|
||||
LineItemColumn,
|
||||
LinkColumn,
|
||||
ProjectCodeColumn,
|
||||
ReferenceColumn,
|
||||
@@ -77,6 +78,7 @@ export default function SalesOrderLineItemTable({
|
||||
|
||||
const tableColumns: TableColumn[] = useMemo(() => {
|
||||
return [
|
||||
LineItemColumn({}),
|
||||
{
|
||||
accessor: 'part',
|
||||
sortable: true,
|
||||
@@ -539,6 +541,7 @@ export default function SalesOrderLineItemTable({
|
||||
order: orderId,
|
||||
part_detail: true
|
||||
},
|
||||
defaultSortColumn: 'line',
|
||||
rowActions: rowActions,
|
||||
tableActions: tableActions,
|
||||
tableFilters: tableFilters,
|
||||
|
||||
Reference in New Issue
Block a user