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:
@ -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
|
||||
|
@ -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',
|
||||
|
@ -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'),
|
||||
),
|
||||
]
|
@ -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,
|
||||
|
@ -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',
|
||||
|
Reference in New Issue
Block a user