2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-12-16 09:18:10 +00:00

Add parameter support for orders

This commit is contained in:
Oliver Walters
2025-11-25 09:03:45 +00:00
parent 59f18f0f8f
commit 9e3f3b27db
3 changed files with 35 additions and 9 deletions

View File

@@ -28,7 +28,12 @@ import stock.models as stock_models
import stock.serializers as stock_serializers import stock.serializers as stock_serializers
from data_exporter.mixins import DataExportViewMixin from data_exporter.mixins import DataExportViewMixin
from generic.states.api import StatusView from generic.states.api import StatusView
from InvenTree.api import BulkUpdateMixin, ListCreateDestroyAPIView, MetadataView from InvenTree.api import (
BulkUpdateMixin,
ListCreateDestroyAPIView,
MetadataView,
ParameterListMixin,
)
from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration
from InvenTree.filters import ( from InvenTree.filters import (
SEARCH_ORDER_FILTER, SEARCH_ORDER_FILTER,
@@ -378,6 +383,7 @@ class PurchaseOrderList(
OrderCreateMixin, OrderCreateMixin,
DataExportViewMixin, DataExportViewMixin,
OutputOptionsMixin, OutputOptionsMixin,
ParameterListMixin,
ListCreateAPI, ListCreateAPI,
): ):
"""API endpoint for accessing a list of PurchaseOrder objects. """API endpoint for accessing a list of PurchaseOrder objects.
@@ -386,6 +392,7 @@ class PurchaseOrderList(
- POST: Create a new PurchaseOrder object - POST: Create a new PurchaseOrder object
""" """
parameter_model_class = models.PurchaseOrder
filterset_class = PurchaseOrderFilter filterset_class = PurchaseOrderFilter
filter_backends = SEARCH_ORDER_FILTER_ALIAS filter_backends = SEARCH_ORDER_FILTER_ALIAS
output_options = PurchaseOrderOutputOptions output_options = PurchaseOrderOutputOptions
@@ -847,6 +854,7 @@ class SalesOrderList(
OrderCreateMixin, OrderCreateMixin,
DataExportViewMixin, DataExportViewMixin,
OutputOptionsMixin, OutputOptionsMixin,
ParameterListMixin,
ListCreateAPI, ListCreateAPI,
): ):
"""API endpoint for accessing a list of SalesOrder objects. """API endpoint for accessing a list of SalesOrder objects.
@@ -855,10 +863,9 @@ class SalesOrderList(
- POST: Create a new SalesOrder - POST: Create a new SalesOrder
""" """
parameter_model_class = models.SalesOrder
filterset_class = SalesOrderFilter filterset_class = SalesOrderFilter
filter_backends = SEARCH_ORDER_FILTER_ALIAS filter_backends = SEARCH_ORDER_FILTER_ALIAS
output_options = SalesOrderOutputOptions output_options = SalesOrderOutputOptions
ordering_field_aliases = { ordering_field_aliases = {
@@ -1323,7 +1330,7 @@ class SalesOrderAllocationList(
class SalesOrderAllocationDetail(SalesOrderAllocationMixin, RetrieveUpdateDestroyAPI): class SalesOrderAllocationDetail(SalesOrderAllocationMixin, RetrieveUpdateDestroyAPI):
"""API endpoint for detali view of a SalesOrderAllocation object.""" """API endpoint for detail view of a SalesOrderAllocation object."""
class SalesOrderShipmentFilter(FilterSet): class SalesOrderShipmentFilter(FilterSet):
@@ -1374,7 +1381,7 @@ class SalesOrderShipmentFilter(FilterSet):
) )
def filter_order_status(self, queryset, name, value): def filter_order_status(self, queryset, name, value):
"""Filter by linked SalesOrderrder status.""" """Filter by linked SalesOrder status."""
q1 = Q(order__status=value, order__status_custom_key__isnull=True) q1 = Q(order__status=value, order__status_custom_key__isnull=True)
q2 = Q(order__status_custom_key=value) q2 = Q(order__status_custom_key=value)
@@ -1412,7 +1419,7 @@ class SalesOrderShipmentList(SalesOrderShipmentMixin, ListCreateAPI):
class SalesOrderShipmentDetail(SalesOrderShipmentMixin, RetrieveUpdateDestroyAPI): class SalesOrderShipmentDetail(SalesOrderShipmentMixin, RetrieveUpdateDestroyAPI):
"""API detail endpooint for SalesOrderShipment model.""" """API detail endpoint for SalesOrderShipment model."""
class SalesOrderShipmentComplete(CreateAPI): class SalesOrderShipmentComplete(CreateAPI):
@@ -1525,12 +1532,13 @@ class ReturnOrderList(
OrderCreateMixin, OrderCreateMixin,
DataExportViewMixin, DataExportViewMixin,
OutputOptionsMixin, OutputOptionsMixin,
ParameterListMixin,
ListCreateAPI, ListCreateAPI,
): ):
"""API endpoint for accessing a list of ReturnOrder objects.""" """API endpoint for accessing a list of ReturnOrder objects."""
parameter_model_class = models.ReturnOrder
filterset_class = ReturnOrderFilter filterset_class = ReturnOrderFilter
filter_backends = SEARCH_ORDER_FILTER_ALIAS filter_backends = SEARCH_ORDER_FILTER_ALIAS
output_options = ReturnOrderOutputOptions output_options = ReturnOrderOutputOptions
@@ -1964,7 +1972,7 @@ order_api_urls = [
), ),
]), ]),
), ),
# API endpoints for sales ordesr # API endpoints for sales orders
path( path(
'so/', 'so/',
include([ include([

View File

@@ -268,6 +268,7 @@ class ReturnOrderReportContext(report.mixins.BaseReportContext):
class Order( class Order(
StatusCodeMixin, StatusCodeMixin,
StateTransitionMixin, StateTransitionMixin,
InvenTree.models.InvenTreeParameterMixin,
InvenTree.models.InvenTreeAttachmentMixin, InvenTree.models.InvenTreeAttachmentMixin,
InvenTree.models.InvenTreeBarcodeMixin, InvenTree.models.InvenTreeBarcodeMixin,
InvenTree.models.InvenTreeNotesMixin, InvenTree.models.InvenTreeNotesMixin,
@@ -988,7 +989,7 @@ class PurchaseOrder(TotalPriceMixin, Order):
# Before we continue, validate that each line item is valid # Before we continue, validate that each line item is valid
# We validate this here because it is far more efficient, # We validate this here because it is far more efficient,
# after we have fetched *all* line itemes in a single DB query # after we have fetched *all* line items in a single DB query
for line_item in line_item_map.values(): for line_item in line_item_map.values():
if line_item.order != self: if line_item.order != self:
raise ValidationError({_('Line item does not match purchase order')}) raise ValidationError({_('Line item does not match purchase order')})

View File

@@ -22,6 +22,7 @@ from rest_framework.serializers import ValidationError
from sql_util.utils import SubqueryCount, SubquerySum from sql_util.utils import SubqueryCount, SubquerySum
import build.serializers import build.serializers
import common.serializers
import order.models import order.models
import part.filters as part_filters import part.filters as part_filters
import part.models as part_models import part.models as part_models
@@ -177,6 +178,12 @@ class AbstractOrderSerializer(
True, True,
) )
parameters = enable_filter(
common.serializers.ParameterSerializer(many=True, read_only=True),
False,
filter_name='parameters',
)
# Boolean field indicating if this order is overdue (Note: must be annotated) # Boolean field indicating if this order is overdue (Note: must be annotated)
overdue = serializers.BooleanField(read_only=True, allow_null=True) overdue = serializers.BooleanField(read_only=True, allow_null=True)
@@ -240,6 +247,7 @@ class AbstractOrderSerializer(
'project_code_detail', 'project_code_detail',
'project_code_label', 'project_code_label',
'responsible_detail', 'responsible_detail',
'parameters',
*extra_fields, *extra_fields,
] ]
@@ -444,6 +452,9 @@ class PurchaseOrderSerializer(
""" """
queryset = AbstractOrderSerializer.annotate_queryset(queryset) queryset = AbstractOrderSerializer.annotate_queryset(queryset)
# Annotate parametric data
queryset = order.models.PurchaseOrder.annotate_parameters(queryset)
queryset = queryset.annotate( queryset = queryset.annotate(
completed_lines=SubqueryCount( completed_lines=SubqueryCount(
'lines', filter=Q(quantity__lte=F('received')) 'lines', filter=Q(quantity__lte=F('received'))
@@ -1087,6 +1098,9 @@ class SalesOrderSerializer(
""" """
queryset = AbstractOrderSerializer.annotate_queryset(queryset) queryset = AbstractOrderSerializer.annotate_queryset(queryset)
# Annotate parametric data
queryset = order.models.SalesOrder.annotate_parameters(queryset)
queryset = queryset.annotate( queryset = queryset.annotate(
completed_lines=SubqueryCount('lines', filter=Q(quantity__lte=F('shipped'))) completed_lines=SubqueryCount('lines', filter=Q(quantity__lte=F('shipped')))
) )
@@ -1936,6 +1950,9 @@ class ReturnOrderSerializer(
"""Custom annotation for the serializer queryset.""" """Custom annotation for the serializer queryset."""
queryset = AbstractOrderSerializer.annotate_queryset(queryset) queryset = AbstractOrderSerializer.annotate_queryset(queryset)
# Annotate parametric data
queryset = order.models.ReturnOrder.annotate_parameters(queryset)
queryset = queryset.annotate( queryset = queryset.annotate(
completed_lines=SubqueryCount( completed_lines=SubqueryCount(
'lines', filter=~Q(outcome=ReturnOrderLineStatus.PENDING.value) 'lines', filter=~Q(outcome=ReturnOrderLineStatus.PENDING.value)