2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-16 20:15:44 +00:00

Order start dates (#8966)

* Add 'start_date' field to orders

- PurchaseOrder
- SalesOrder
- ReturnOrder

* Add serializer field

* Add API filters

* Add table columns

* Add fields to forms

* Table filters

* Add validation check

* Refactor BuildOrderTable

* Update detail page

* Bump API version

* Allow sorting by start_date

* Fix for purchase order field

* Update detail pages

* Update playwright tests

* Updated playwright tests

* Documentation updates

* Updated playwright tests
This commit is contained in:
Oliver
2025-01-29 22:45:39 +11:00
committed by GitHub
parent 0c56a3132b
commit eee4916350
24 changed files with 317 additions and 45 deletions

View File

@ -1,13 +1,19 @@
"""InvenTree API version information."""
# InvenTree API version
INVENTREE_API_VERSION = 305
INVENTREE_API_VERSION = 306
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
INVENTREE_API_TEXT = """
v3-6 0 2025-01-28 : https://github.com/inventree/InvenTree/pull/8966
- Adds "start_date" to PurchasesOrder API
- Adds "start_date" to SalesOrder API
- Adds "start_date" to ReturnOrder API
- Updated API filters
v305 - 2025-01-26 : https://github.com/inventree/InvenTree/pull/8950
- Bug fixes for the SupplierPart API
- Refactoring for data export via API

View File

@ -181,6 +181,30 @@ class OrderFilter(rest_filters.FilterSet):
label=_('Created After'), field_name='creation_date', lookup_expr='gt'
)
has_start_date = rest_filters.BooleanFilter(
label=_('Has Start Date'), method='filter_has_start_date'
)
def filter_has_start_date(self, queryset, name, value):
"""Filter by whether or not the order has a start date."""
return queryset.filter(start_date__isnull=not str2bool(value))
start_date_before = InvenTreeDateFilter(
label=_('Start Date Before'), field_name='start_date', lookup_expr='lt'
)
start_date_after = InvenTreeDateFilter(
label=_('Start Date After'), field_name='start_date', lookup_expr='gt'
)
has_target_date = rest_filters.BooleanFilter(
label=_('Has Target Date'), method='filter_has_target_date'
)
def filter_has_target_date(self, queryset, name, value):
"""Filter by whether or not the order has a target date."""
return queryset.filter(target_date__isnull=not str2bool(value))
target_date_before = InvenTreeDateFilter(
label=_('Target Date Before'), field_name='target_date', lookup_expr='lt'
)
@ -336,6 +360,7 @@ class PurchaseOrderList(
'created_by',
'reference',
'supplier__name',
'start_date',
'target_date',
'complete_date',
'line_items',
@ -797,6 +822,7 @@ class SalesOrderList(
'customer__name',
'customer_reference',
'status',
'start_date',
'target_date',
'line_items',
'shipment_date',
@ -1383,6 +1409,7 @@ class ReturnOrderList(
'customer_reference',
'line_items',
'status',
'start_date',
'target_date',
'complete_date',
'project_code',

View File

@ -0,0 +1,28 @@
# Generated by Django 4.2.18 on 2025-01-27 12:50
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('order', '0105_auto_20241128_0431'),
]
operations = [
migrations.AddField(
model_name='purchaseorder',
name='start_date',
field=models.DateField(blank=True, help_text='Scheduled start date for this order', null=True, verbose_name='Start date'),
),
migrations.AddField(
model_name='returnorder',
name='start_date',
field=models.DateField(blank=True, help_text='Scheduled start date for this order', null=True, verbose_name='Start date'),
),
migrations.AddField(
model_name='salesorder',
name='start_date',
field=models.DateField(blank=True, help_text='Scheduled start date for this order', null=True, verbose_name='Start date'),
),
]

View File

@ -203,6 +203,8 @@ class Order(
creation_date: Automatic date of order creation
created_by: User who created this order (automatically captured)
issue_date: Date the order was issued
start_date: Date the order is scheduled to be started
target_date: Expected or desired completion date
complete_date: Date the order was completed
responsible: User (or group) responsible for managing the order
"""
@ -244,6 +246,13 @@ class Order(
'contact': _('Contact does not match selected company')
})
# Target date should be *after* the start date
if self.start_date and self.target_date and self.start_date > self.target_date:
raise ValidationError({
'target_date': _('Target date must be after start date'),
'start_date': _('Start date must be before target date'),
})
def clean_line_item(self, line):
"""Clean a line item for this order.
@ -310,6 +319,13 @@ class Order(
blank=True, verbose_name=_('Link'), help_text=_('Link to external page')
)
start_date = models.DateField(
null=True,
blank=True,
verbose_name=_('Start date'),
help_text=_('Scheduled start date for this order'),
)
target_date = models.DateField(
blank=True,
null=True,

View File

@ -186,8 +186,9 @@ class AbstractOrderSerializer(DataImportExportSerializerMixin, serializers.Seria
"""Construct a set of fields for this serializer."""
return [
'pk',
'creation_date',
'created_by',
'creation_date',
'start_date',
'target_date',
'description',
'line_items',