mirror of
https://github.com/inventree/InvenTree.git
synced 2025-10-29 12:27:41 +00:00
[feature] Project code per line (#10657)
* Add project code to line items * Refactor AbstractOrderSerialiazer * Refactor AbstractOrderLineItem serializer * Refactoring for AbstractExtraLineSerializer * UI elements for extra line item project code * UI for ReturnOrderLineItems * UI elements for SalesOrderLineItem * UI elements for PurchaseOrderLineItem * Docs updates * Update API version and CHANGELOG
This commit is contained in:
@@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Allow stock adjustments for "in production" items in [#10600](https://github.com/inventree/InvenTree/pull/10600)
|
||||
- Adds optional shipping address against individual sales order shipments in [#10650](https://github.com/inventree/InvenTree/pull/10650)
|
||||
- Adds UI elements to "check" and "uncheck" sales order shipments in [#10654](https://github.com/inventree/InvenTree/pull/10654)
|
||||
- Allow assigning project codes to order line items in [#10657](https://github.com/inventree/InvenTree/pull/10657)
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@@ -6,7 +6,18 @@ title: Project Codes
|
||||
|
||||
A project code is a unique identifier assigned to a specific project, which helps in tracking and organizing project-related activities and resources. It enables easy retrieval of project-related data and facilitates project management and reporting.
|
||||
|
||||
Individual orders (such as [Purchase Orders](../purchasing/purchase_order.md) or [Sales Orders](../sales/sales_order.md)) can be assigned a *Project Code* to allocate the order against a particular internal project.
|
||||
### Assigning to Orders
|
||||
|
||||
Project codes can be assigned to various orders within the system:
|
||||
|
||||
- [Build Orders](../manufacturing/build.md)
|
||||
- [Purchase Orders](../purchasing/purchase_order.md)
|
||||
- [Sales Orders](../sales/sales_order.md)
|
||||
- [Return Orders](../sales/return_order.md)
|
||||
|
||||
By assigning a project code to an order, users can easily track and manage orders associated with specific projects, enhancing project oversight and resource allocation.
|
||||
|
||||
For orders with external companies, which support individual line items, project codes can be assigned at the line item level, allowing for granular tracking of project-related activities. In such cases, the project code assigned to the order itself serves as a default for all line items, unless explicitly overridden at the line item level.
|
||||
|
||||
### Managing Project Codes
|
||||
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
"""InvenTree API version information."""
|
||||
|
||||
# InvenTree API version
|
||||
INVENTREE_API_VERSION = 417
|
||||
INVENTREE_API_VERSION = 418
|
||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||
|
||||
INVENTREE_API_TEXT = """
|
||||
|
||||
v418 -> 2025-10-24 : https://github.com/inventree/InvenTree/pull/10657
|
||||
- Add "project_code" field(s) to OrderLineItem API endpoint(s)
|
||||
- Add "project_code" field(s) to ExtraOrderLineItem API endpoint(s)
|
||||
|
||||
v417 -> 2025-10-22 : https://github.com/inventree/InvenTree/pull/10654
|
||||
- Adds "checked" filter to SalesOrderShipment API endpoint
|
||||
- Adds "order_status" filter to SalesOrdereShipment API endpoint
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
# Generated by Django 4.2.25 on 2025-10-24 01:15
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("common", "0039_emailthread_emailmessage"),
|
||||
("order", "0113_salesordershipment_shipment_address"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="purchaseorderextraline",
|
||||
name="project_code",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
help_text="Select project code for this order",
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="common.projectcode",
|
||||
verbose_name="Project Code",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="purchaseorderlineitem",
|
||||
name="project_code",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
help_text="Select project code for this order",
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="common.projectcode",
|
||||
verbose_name="Project Code",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="returnorderextraline",
|
||||
name="project_code",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
help_text="Select project code for this order",
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="common.projectcode",
|
||||
verbose_name="Project Code",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="returnorderlineitem",
|
||||
name="project_code",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
help_text="Select project code for this order",
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="common.projectcode",
|
||||
verbose_name="Project Code",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="salesorderextraline",
|
||||
name="project_code",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
help_text="Select project code for this order",
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="common.projectcode",
|
||||
verbose_name="Project Code",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="salesorderlineitem",
|
||||
name="project_code",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
help_text="Select project code for this order",
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="common.projectcode",
|
||||
verbose_name="Project Code",
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -1685,6 +1685,7 @@ class OrderLineItem(InvenTree.models.InvenTreeMetadataModel):
|
||||
Attributes:
|
||||
quantity: Number of items
|
||||
reference: Reference text (e.g. customer reference) for this line item
|
||||
project_code: Project code associated with this line item (optional)
|
||||
note: Annotation for the item
|
||||
target_date: An (optional) date for expected shipment of this line item.
|
||||
"""
|
||||
@@ -1768,6 +1769,15 @@ class OrderLineItem(InvenTree.models.InvenTreeMetadataModel):
|
||||
),
|
||||
)
|
||||
|
||||
project_code = models.ForeignKey(
|
||||
common_models.ProjectCode,
|
||||
on_delete=models.SET_NULL,
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name=_('Project Code'),
|
||||
help_text=_('Select project code for this order'),
|
||||
)
|
||||
|
||||
|
||||
class OrderExtraLine(OrderLineItem):
|
||||
"""Abstract Model for a single ExtraLine in a Order.
|
||||
@@ -1992,8 +2002,6 @@ class PurchaseOrderExtraLine(OrderExtraLine):
|
||||
|
||||
Attributes:
|
||||
order: Link to the PurchaseOrder that this line belongs to
|
||||
title: title of line
|
||||
price: The unit price for this OrderLine
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
@@ -2422,8 +2430,6 @@ class SalesOrderExtraLine(OrderExtraLine):
|
||||
|
||||
Attributes:
|
||||
order: Link to the SalesOrder that this line belongs to
|
||||
title: title of line
|
||||
price: The unit price for this OrderLine
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
|
||||
@@ -45,6 +45,7 @@ from InvenTree.helpers import (
|
||||
)
|
||||
from InvenTree.mixins import DataImportExportSerializerMixin
|
||||
from InvenTree.serializers import (
|
||||
FilterableCharField,
|
||||
FilterableSerializerMixin,
|
||||
InvenTreeCurrencySerializer,
|
||||
InvenTreeDecimalField,
|
||||
@@ -105,7 +106,9 @@ class DuplicateOrderSerializer(serializers.Serializer):
|
||||
)
|
||||
|
||||
|
||||
class AbstractOrderSerializer(DataImportExportSerializerMixin, serializers.Serializer):
|
||||
class AbstractOrderSerializer(
|
||||
DataImportExportSerializerMixin, FilterableSerializerMixin, serializers.Serializer
|
||||
):
|
||||
"""Abstract serializer class which provides fields common to all order types."""
|
||||
|
||||
export_exclude_fields = ['notes', 'duplicate']
|
||||
@@ -132,30 +135,46 @@ class AbstractOrderSerializer(DataImportExportSerializerMixin, serializers.Seria
|
||||
reference = serializers.CharField(required=True)
|
||||
|
||||
# Detail for point-of-contact field
|
||||
contact_detail = ContactSerializer(
|
||||
source='contact', many=False, read_only=True, allow_null=True
|
||||
contact_detail = enable_filter(
|
||||
ContactSerializer(
|
||||
source='contact', many=False, read_only=True, allow_null=True
|
||||
),
|
||||
True,
|
||||
)
|
||||
|
||||
# Detail for responsible field
|
||||
responsible_detail = OwnerSerializer(
|
||||
source='responsible', read_only=True, allow_null=True, many=False
|
||||
responsible_detail = enable_filter(
|
||||
OwnerSerializer(
|
||||
source='responsible', read_only=True, allow_null=True, many=False
|
||||
),
|
||||
True,
|
||||
)
|
||||
|
||||
project_code_label = serializers.CharField(
|
||||
source='project_code.code',
|
||||
read_only=True,
|
||||
label='Project Code Label',
|
||||
allow_null=True,
|
||||
project_code_label = enable_filter(
|
||||
FilterableCharField(
|
||||
source='project_code.code',
|
||||
read_only=True,
|
||||
label='Project Code Label',
|
||||
allow_null=True,
|
||||
),
|
||||
True,
|
||||
filter_name='project_code_detail',
|
||||
)
|
||||
|
||||
# Detail for project code field
|
||||
project_code_detail = ProjectCodeSerializer(
|
||||
source='project_code', read_only=True, many=False, allow_null=True
|
||||
project_code_detail = enable_filter(
|
||||
ProjectCodeSerializer(
|
||||
source='project_code', read_only=True, many=False, allow_null=True
|
||||
),
|
||||
True,
|
||||
)
|
||||
|
||||
# Detail for address field
|
||||
address_detail = AddressBriefSerializer(
|
||||
source='address', many=False, read_only=True, allow_null=True
|
||||
address_detail = enable_filter(
|
||||
AddressBriefSerializer(
|
||||
source='address', many=False, read_only=True, allow_null=True
|
||||
),
|
||||
True,
|
||||
)
|
||||
|
||||
# Boolean field indicating if this order is overdue (Note: must be annotated)
|
||||
@@ -204,15 +223,10 @@ class AbstractOrderSerializer(DataImportExportSerializerMixin, serializers.Seria
|
||||
'completed_lines',
|
||||
'link',
|
||||
'project_code',
|
||||
'project_code_label',
|
||||
'project_code_detail',
|
||||
'reference',
|
||||
'responsible',
|
||||
'responsible_detail',
|
||||
'contact',
|
||||
'contact_detail',
|
||||
'address',
|
||||
'address_detail',
|
||||
'status',
|
||||
'status_text',
|
||||
'status_custom_key',
|
||||
@@ -220,6 +234,12 @@ class AbstractOrderSerializer(DataImportExportSerializerMixin, serializers.Seria
|
||||
'barcode_hash',
|
||||
'overdue',
|
||||
'duplicate',
|
||||
# Extra detail fields
|
||||
'address_detail',
|
||||
'contact_detail',
|
||||
'project_code_detail',
|
||||
'project_code_label',
|
||||
'responsible_detail',
|
||||
*extra_fields,
|
||||
]
|
||||
|
||||
@@ -263,25 +283,103 @@ class AbstractOrderSerializer(DataImportExportSerializerMixin, serializers.Seria
|
||||
return instance
|
||||
|
||||
|
||||
class AbstractLineItemSerializer:
|
||||
class AbstractLineItemSerializer(FilterableSerializerMixin, serializers.Serializer):
|
||||
"""Abstract serializer for LineItem object."""
|
||||
|
||||
@staticmethod
|
||||
def line_fields(extra_fields):
|
||||
"""Construct a set of fields for this serializer."""
|
||||
return [
|
||||
'pk',
|
||||
'link',
|
||||
'notes',
|
||||
'order',
|
||||
'project_code',
|
||||
'quantity',
|
||||
'reference',
|
||||
'target_date',
|
||||
# Filterable detail fields
|
||||
'order_detail',
|
||||
'project_code_label',
|
||||
'project_code_detail',
|
||||
*extra_fields,
|
||||
]
|
||||
|
||||
target_date = serializers.DateField(
|
||||
required=False, allow_null=True, label=_('Target Date')
|
||||
)
|
||||
|
||||
project_code_label = enable_filter(
|
||||
FilterableCharField(
|
||||
source='project_code.code',
|
||||
read_only=True,
|
||||
label='Project Code Label',
|
||||
allow_null=True,
|
||||
),
|
||||
True,
|
||||
filter_name='project_code_detail',
|
||||
)
|
||||
|
||||
project_code_detail = enable_filter(
|
||||
ProjectCodeSerializer(
|
||||
source='project_code', read_only=True, many=False, allow_null=True
|
||||
),
|
||||
True,
|
||||
)
|
||||
|
||||
|
||||
class AbstractExtraLineSerializer(
|
||||
DataImportExportSerializerMixin, serializers.Serializer
|
||||
DataImportExportSerializerMixin, FilterableSerializerMixin, serializers.Serializer
|
||||
):
|
||||
"""Abstract Serializer for a ExtraLine object."""
|
||||
|
||||
@staticmethod
|
||||
def extra_line_fields(extra_fields):
|
||||
"""Construct a set of fields for this serializer."""
|
||||
return [
|
||||
'pk',
|
||||
'description',
|
||||
'link',
|
||||
'notes',
|
||||
'order',
|
||||
'price',
|
||||
'price_currency',
|
||||
'project_code',
|
||||
'quantity',
|
||||
'reference',
|
||||
'target_date',
|
||||
# Filterable detail fields
|
||||
'order_detail',
|
||||
'project_code_label',
|
||||
'project_code_detail',
|
||||
*extra_fields,
|
||||
]
|
||||
|
||||
quantity = serializers.FloatField()
|
||||
|
||||
price = InvenTreeMoneySerializer(allow_null=True)
|
||||
|
||||
price_currency = InvenTreeCurrencySerializer()
|
||||
|
||||
project_code_label = enable_filter(
|
||||
FilterableCharField(
|
||||
source='project_code.code',
|
||||
read_only=True,
|
||||
label='Project Code Label',
|
||||
allow_null=True,
|
||||
),
|
||||
True,
|
||||
filter_name='project_code_detail',
|
||||
)
|
||||
|
||||
# Detail for project code field
|
||||
project_code_detail = enable_filter(
|
||||
ProjectCodeSerializer(
|
||||
source='project_code', read_only=True, many=False, allow_null=True
|
||||
),
|
||||
True,
|
||||
)
|
||||
|
||||
|
||||
class AbstractExtraLineMeta:
|
||||
"""Abstract Meta for ExtraLine."""
|
||||
@@ -303,7 +401,6 @@ class AbstractExtraLineMeta:
|
||||
|
||||
@register_importer()
|
||||
class PurchaseOrderSerializer(
|
||||
FilterableSerializerMixin,
|
||||
NotesFieldMixin,
|
||||
TotalPriceMixin,
|
||||
InvenTreeCustomStatusSerializerMixin,
|
||||
@@ -460,7 +557,6 @@ class PurchaseOrderIssueSerializer(OrderAdjustSerializer):
|
||||
|
||||
@register_importer()
|
||||
class PurchaseOrderLineItemSerializer(
|
||||
FilterableSerializerMixin,
|
||||
DataImportExportSerializerMixin,
|
||||
AbstractLineItemSerializer,
|
||||
InvenTreeModelSerializer,
|
||||
@@ -471,35 +567,28 @@ class PurchaseOrderLineItemSerializer(
|
||||
"""Metaclass options."""
|
||||
|
||||
model = order.models.PurchaseOrderLineItem
|
||||
fields = [
|
||||
'pk',
|
||||
fields = AbstractLineItemSerializer.line_fields([
|
||||
'part',
|
||||
'quantity',
|
||||
'reference',
|
||||
'notes',
|
||||
'order',
|
||||
'order_detail',
|
||||
'build_order',
|
||||
'build_order_detail',
|
||||
'overdue',
|
||||
'part_detail',
|
||||
'supplier_part_detail',
|
||||
'received',
|
||||
'purchase_price',
|
||||
'purchase_price_currency',
|
||||
'auto_pricing',
|
||||
'destination',
|
||||
'destination_detail',
|
||||
'target_date',
|
||||
'total_price',
|
||||
'link',
|
||||
'merge_items',
|
||||
'sku',
|
||||
'mpn',
|
||||
'ipn',
|
||||
'internal_part',
|
||||
'internal_part_name',
|
||||
]
|
||||
# Filterable detail fields
|
||||
'build_order_detail',
|
||||
'destination_detail',
|
||||
'part_detail',
|
||||
'supplier_part_detail',
|
||||
])
|
||||
|
||||
def skip_create_fields(self):
|
||||
"""Return a list of fields to skip when creating a new object."""
|
||||
@@ -693,21 +782,22 @@ class PurchaseOrderLineItemSerializer(
|
||||
|
||||
@register_importer()
|
||||
class PurchaseOrderExtraLineSerializer(
|
||||
FilterableSerializerMixin, AbstractExtraLineSerializer, InvenTreeModelSerializer
|
||||
AbstractExtraLineSerializer, InvenTreeModelSerializer
|
||||
):
|
||||
"""Serializer for a PurchaseOrderExtraLine object."""
|
||||
|
||||
class Meta(AbstractExtraLineMeta):
|
||||
"""Metaclass options."""
|
||||
|
||||
model = order.models.PurchaseOrderExtraLine
|
||||
fields = AbstractExtraLineSerializer.extra_line_fields([])
|
||||
|
||||
order_detail = enable_filter(
|
||||
PurchaseOrderSerializer(
|
||||
source='order', many=False, read_only=True, allow_null=True
|
||||
)
|
||||
)
|
||||
|
||||
class Meta(AbstractExtraLineMeta):
|
||||
"""Metaclass options."""
|
||||
|
||||
model = order.models.PurchaseOrderExtraLine
|
||||
|
||||
|
||||
class PurchaseOrderLineItemReceiveSerializer(serializers.Serializer):
|
||||
"""A serializer for receiving a single purchase order line item against a purchase order."""
|
||||
@@ -956,7 +1046,6 @@ class PurchaseOrderReceiveSerializer(serializers.Serializer):
|
||||
|
||||
@register_importer()
|
||||
class SalesOrderSerializer(
|
||||
FilterableSerializerMixin,
|
||||
NotesFieldMixin,
|
||||
TotalPriceMixin,
|
||||
InvenTreeCustomStatusSerializerMixin,
|
||||
@@ -1047,7 +1136,6 @@ class SalesOrderIssueSerializer(OrderAdjustSerializer):
|
||||
|
||||
@register_importer()
|
||||
class SalesOrderLineItemSerializer(
|
||||
FilterableSerializerMixin,
|
||||
DataImportExportSerializerMixin,
|
||||
AbstractLineItemSerializer,
|
||||
InvenTreeModelSerializer,
|
||||
@@ -1058,29 +1146,22 @@ class SalesOrderLineItemSerializer(
|
||||
"""Metaclass options."""
|
||||
|
||||
model = order.models.SalesOrderLineItem
|
||||
fields = [
|
||||
'pk',
|
||||
fields = AbstractLineItemSerializer.line_fields([
|
||||
'allocated',
|
||||
'customer_detail',
|
||||
'quantity',
|
||||
'reference',
|
||||
'notes',
|
||||
'order',
|
||||
'order_detail',
|
||||
'overdue',
|
||||
'part',
|
||||
'part_detail',
|
||||
'sale_price',
|
||||
'sale_price_currency',
|
||||
'shipped',
|
||||
'target_date',
|
||||
'link',
|
||||
# Annotated fields for part stocking information
|
||||
'available_stock',
|
||||
'available_variant_stock',
|
||||
'building',
|
||||
'on_order',
|
||||
]
|
||||
# Filterable detail fields
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
def annotate_queryset(queryset):
|
||||
@@ -1795,7 +1876,7 @@ class SalesOrderShipmentAllocationSerializer(serializers.Serializer):
|
||||
|
||||
@register_importer()
|
||||
class SalesOrderExtraLineSerializer(
|
||||
FilterableSerializerMixin, AbstractExtraLineSerializer, InvenTreeModelSerializer
|
||||
AbstractExtraLineSerializer, InvenTreeModelSerializer
|
||||
):
|
||||
"""Serializer for a SalesOrderExtraLine object."""
|
||||
|
||||
@@ -1803,6 +1884,7 @@ class SalesOrderExtraLineSerializer(
|
||||
"""Metaclass options."""
|
||||
|
||||
model = order.models.SalesOrderExtraLine
|
||||
fields = AbstractExtraLineSerializer.extra_line_fields([])
|
||||
|
||||
order_detail = enable_filter(
|
||||
SalesOrderSerializer(
|
||||
@@ -1813,7 +1895,6 @@ class SalesOrderExtraLineSerializer(
|
||||
|
||||
@register_importer()
|
||||
class ReturnOrderSerializer(
|
||||
FilterableSerializerMixin,
|
||||
NotesFieldMixin,
|
||||
InvenTreeCustomStatusSerializerMixin,
|
||||
AbstractOrderSerializer,
|
||||
@@ -2004,7 +2085,6 @@ class ReturnOrderReceiveSerializer(serializers.Serializer):
|
||||
|
||||
@register_importer()
|
||||
class ReturnOrderLineItemSerializer(
|
||||
FilterableSerializerMixin,
|
||||
DataImportExportSerializerMixin,
|
||||
AbstractLineItemSerializer,
|
||||
InvenTreeModelSerializer,
|
||||
@@ -2015,24 +2095,16 @@ class ReturnOrderLineItemSerializer(
|
||||
"""Metaclass options."""
|
||||
|
||||
model = order.models.ReturnOrderLineItem
|
||||
fields = [
|
||||
'pk',
|
||||
'order',
|
||||
'order_detail',
|
||||
fields = AbstractLineItemSerializer.line_fields([
|
||||
'item',
|
||||
'item_detail',
|
||||
'quantity',
|
||||
'received_date',
|
||||
'outcome',
|
||||
'part_detail',
|
||||
'price',
|
||||
'price_currency',
|
||||
'link',
|
||||
'reference',
|
||||
'notes',
|
||||
'target_date',
|
||||
'link',
|
||||
]
|
||||
# Filterable detail fields
|
||||
'item_detail',
|
||||
'part_detail',
|
||||
])
|
||||
|
||||
order_detail = enable_filter(
|
||||
ReturnOrderSerializer(
|
||||
@@ -2062,7 +2134,7 @@ class ReturnOrderLineItemSerializer(
|
||||
|
||||
@register_importer()
|
||||
class ReturnOrderExtraLineSerializer(
|
||||
FilterableSerializerMixin, AbstractExtraLineSerializer, InvenTreeModelSerializer
|
||||
AbstractExtraLineSerializer, InvenTreeModelSerializer
|
||||
):
|
||||
"""Serializer for a ReturnOrderExtraLine object."""
|
||||
|
||||
@@ -2070,6 +2142,7 @@ class ReturnOrderExtraLineSerializer(
|
||||
"""Metaclass options."""
|
||||
|
||||
model = order.models.ReturnOrderExtraLine
|
||||
fields = AbstractExtraLineSerializer.extra_line_fields([])
|
||||
|
||||
order_detail = enable_filter(
|
||||
ReturnOrderSerializer(
|
||||
|
||||
@@ -2,6 +2,7 @@ import { IconUsers } from '@tabler/icons-react';
|
||||
import { useMemo, useState } from 'react';
|
||||
|
||||
import type { ApiFormFieldSet } from '@lib/types/Forms';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import type {
|
||||
StatusCodeInterface,
|
||||
StatusCodeListInterface
|
||||
@@ -83,6 +84,9 @@ export function extraLineItemFields(): ApiFormFieldSet {
|
||||
quantity: {},
|
||||
price: {},
|
||||
price_currency: {},
|
||||
project_code: {
|
||||
description: t`Select project code for this line item`
|
||||
},
|
||||
notes: {},
|
||||
link: {}
|
||||
};
|
||||
|
||||
@@ -121,6 +121,9 @@ export function usePurchaseOrderLineItemFields({
|
||||
value: autoPricing,
|
||||
onValueChange: setAutoPricing
|
||||
},
|
||||
project_code: {
|
||||
description: t`Select project code for this line item`
|
||||
},
|
||||
target_date: {
|
||||
icon: <IconCalendar />
|
||||
},
|
||||
|
||||
@@ -134,6 +134,9 @@ export function useReturnOrderLineItemFields({
|
||||
},
|
||||
price: {},
|
||||
price_currency: {},
|
||||
project_code: {
|
||||
description: t`Select project code for this line item`
|
||||
},
|
||||
target_date: {},
|
||||
notes: {},
|
||||
link: {}
|
||||
|
||||
@@ -157,6 +157,9 @@ export function useSalesOrderLineItemFields({
|
||||
value: partCurrency,
|
||||
onValueChange: setPartCurrency
|
||||
},
|
||||
project_code: {
|
||||
description: t`Select project code for this line item`
|
||||
},
|
||||
target_date: {},
|
||||
notes: {},
|
||||
link: {}
|
||||
|
||||
@@ -25,7 +25,8 @@ import {
|
||||
DecimalColumn,
|
||||
DescriptionColumn,
|
||||
LinkColumn,
|
||||
NoteColumn
|
||||
NoteColumn,
|
||||
ProjectCodeColumn
|
||||
} from '../ColumnRenderers';
|
||||
import { InvenTreeTable } from '../InvenTreeTable';
|
||||
|
||||
@@ -75,6 +76,7 @@ export default function ExtraLineItemTable({
|
||||
multiplier: record.quantity
|
||||
})
|
||||
},
|
||||
ProjectCodeColumn({}),
|
||||
NoteColumn({
|
||||
accessor: 'notes'
|
||||
}),
|
||||
|
||||
@@ -45,6 +45,7 @@ import {
|
||||
LocationColumn,
|
||||
NoteColumn,
|
||||
PartColumn,
|
||||
ProjectCodeColumn,
|
||||
ReferenceColumn,
|
||||
TargetDateColumn
|
||||
} from '../ColumnRenderers';
|
||||
@@ -150,6 +151,7 @@ export function PurchaseOrderLineItemTable({
|
||||
accessor: 'part_detail.description'
|
||||
}),
|
||||
ReferenceColumn({}),
|
||||
ProjectCodeColumn({}),
|
||||
{
|
||||
accessor: 'build_order',
|
||||
title: t`Build Order`,
|
||||
|
||||
@@ -34,6 +34,7 @@ import {
|
||||
LinkColumn,
|
||||
NoteColumn,
|
||||
PartColumn,
|
||||
ProjectCodeColumn,
|
||||
ReferenceColumn,
|
||||
StatusColumn
|
||||
} from '../ColumnRenderers';
|
||||
@@ -137,6 +138,7 @@ export default function ReturnOrderLineItemTable({
|
||||
title: t`Status`
|
||||
}),
|
||||
ReferenceColumn({}),
|
||||
ProjectCodeColumn({}),
|
||||
StatusColumn({
|
||||
model: ModelType.returnorderlineitem,
|
||||
sortable: true,
|
||||
|
||||
@@ -48,6 +48,7 @@ import {
|
||||
DecimalColumn,
|
||||
DescriptionColumn,
|
||||
LinkColumn,
|
||||
ProjectCodeColumn,
|
||||
RenderPartColumn
|
||||
} from '../ColumnRenderers';
|
||||
import { InvenTreeTable } from '../InvenTreeTable';
|
||||
@@ -106,6 +107,7 @@ export default function SalesOrderLineItemTable({
|
||||
sortable: false,
|
||||
switchable: true
|
||||
},
|
||||
ProjectCodeColumn({}),
|
||||
DecimalColumn({
|
||||
accessor: 'quantity',
|
||||
sortable: true
|
||||
|
||||
Reference in New Issue
Block a user