2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-07-01 11:10:54 +00:00

Refactor states/status (#4857)

* add file for states

* move general definition out

* add some tests and docs

* add tests for invalid definitions

* make status_label tag generic

* move templatetags

* remove unused tag

* rename test file

* make status label a lookup

* rename tags

* move import structure

* add missing tag

* collect states dynamically

* fix context function

* move api function out

* add tests for tags

* rename tests

* refactor imports

* Add test for API function

* improve errors and add tests for imporved errors

* make test calls simpler

* refactor definitions to use enums

* switch to enum

* refactor definitions to use enums

* fix lookup

* fix tag name

* make _TAG lookup a function

* cleanup BaseEnum

* make _TAG definition simpler

* restructure status codes to enum

* reduce LoC

* type status codes as int

* add specific function for template context

* Add definition for lookups

* fix filter lookup

* TEST: "fix" action lookup

* Add missing migrations

* Make all group code references explict

* change default on models to value

* switch to IntEnum

* move groups into a seperate class

* only request _TAG if it exsists

* use value and list

* use dedicated groups

* fix stock assigment

* fix order code

* more fixes

* fix borked change

* fix render lookup

* add group

* fix import

* fix syntax

* clenup

* fix migrations

* fix typo

* fix wrong value usage

* fix test

* remove group section

* remove group section

* add more test cases

* Add more docstring

* move choices out of migrations

* change import ordeR?

* last try before I revert

* Update part.migrations.0112

- Add custom migration class which handles errors

* Add unit test for migration

- Ensure that the new fields are added to the model

* Update reference to PR

---------

Co-authored-by: Oliver Walters <oliver.henry.walters@gmail.com>
This commit is contained in:
Matthias Mair
2023-06-09 02:27:26 +02:00
committed by GitHub
parent 005c8341bf
commit 5d1d8ec889
51 changed files with 677 additions and 586 deletions

View File

@ -16,15 +16,18 @@ from rest_framework.response import Response
from common.models import InvenTreeSetting, ProjectCode
from common.settings import settings
from company.models import SupplierPart
from generic.states import StatusView
from InvenTree.api import (APIDownloadMixin, AttachmentMixin,
ListCreateDestroyAPIView, MetadataView, StatusView)
ListCreateDestroyAPIView, MetadataView)
from InvenTree.filters import SEARCH_ORDER_FILTER, SEARCH_ORDER_FILTER_ALIAS
from InvenTree.helpers import DownloadFile, str2bool
from InvenTree.helpers_model import construct_absolute_url, get_base_url
from InvenTree.mixins import (CreateAPI, ListAPI, ListCreateAPI,
RetrieveUpdateDestroyAPI)
from InvenTree.status_codes import (PurchaseOrderStatus, ReturnOrderLineStatus,
ReturnOrderStatus, SalesOrderStatus)
from InvenTree.status_codes import (PurchaseOrderStatus,
PurchaseOrderStatusGroups,
ReturnOrderLineStatus, ReturnOrderStatus,
SalesOrderStatus, SalesOrderStatusGroups)
from order import models, serializers
from order.admin import (PurchaseOrderExtraLineResource,
PurchaseOrderLineItemResource, PurchaseOrderResource,
@ -431,9 +434,9 @@ class PurchaseOrderLineItemFilter(LineItemFilter):
"""Filter by "pending" status (order status = pending)"""
if str2bool(value):
return queryset.filter(order__status__in=PurchaseOrderStatus.OPEN)
return queryset.filter(order__status__in=PurchaseOrderStatusGroups.OPEN)
else:
return queryset.exclude(order__status__in=PurchaseOrderStatus.OPEN)
return queryset.exclude(order__status__in=PurchaseOrderStatusGroups.OPEN)
received = rest_filters.BooleanFilter(label='received', method='filter_received')
@ -448,7 +451,7 @@ class PurchaseOrderLineItemFilter(LineItemFilter):
return queryset.filter(q)
else:
# Only count "pending" orders
return queryset.exclude(q).filter(order__status__in=PurchaseOrderStatus.OPEN)
return queryset.exclude(q).filter(order__status__in=PurchaseOrderStatusGroups.OPEN)
class PurchaseOrderLineItemMixin:
@ -984,12 +987,12 @@ class SalesOrderAllocationList(ListAPI):
# Filter only "open" orders
# Filter only allocations which have *not* shipped
queryset = queryset.filter(
line__order__status__in=SalesOrderStatus.OPEN,
line__order__status__in=SalesOrderStatusGroups.OPEN,
shipment__shipment_date=None,
)
else:
queryset = queryset.exclude(
line__order__status__in=SalesOrderStatus.OPEN,
line__order__status__in=SalesOrderStatusGroups.OPEN,
shipment__shipment_date=None
)
@ -1471,21 +1474,21 @@ class OrderCalendarExport(ICalFeed):
if obj['include_completed'] is False:
# Do not include completed orders from list in this case
# Completed status = 30
outlist = models.PurchaseOrder.objects.filter(target_date__isnull=False).filter(status__lt=PurchaseOrderStatus.COMPLETE)
outlist = models.PurchaseOrder.objects.filter(target_date__isnull=False).filter(status__lt=PurchaseOrderStatus.COMPLETE.value)
else:
outlist = models.PurchaseOrder.objects.filter(target_date__isnull=False)
elif obj["ordertype"] == 'sales-order':
if obj['include_completed'] is False:
# Do not include completed (=shipped) orders from list in this case
# Shipped status = 20
outlist = models.SalesOrder.objects.filter(target_date__isnull=False).filter(status__lt=SalesOrderStatus.SHIPPED)
outlist = models.SalesOrder.objects.filter(target_date__isnull=False).filter(status__lt=SalesOrderStatus.SHIPPED.value)
else:
outlist = models.SalesOrder.objects.filter(target_date__isnull=False)
elif obj["ordertype"] == 'return-order':
if obj['include_completed'] is False:
# Do not include completed orders from list in this case
# Complete status = 30
outlist = models.ReturnOrder.objects.filter(target_date__isnull=False).filter(status__lt=ReturnOrderStatus.COMPLETE)
outlist = models.ReturnOrder.objects.filter(target_date__isnull=False).filter(status__lt=ReturnOrderStatus.COMPLETE.value)
else:
outlist = models.ReturnOrder.objects.filter(target_date__isnull=False)
else:

View File

@ -0,0 +1,19 @@
# Generated by Django 3.2.19 on 2023-06-04 17:43
from django.db import migrations, models
import InvenTree.status_codes
class Migration(migrations.Migration):
dependencies = [
('order', '0095_salesordershipment_delivery_date'),
]
operations = [
migrations.AlterField(
model_name='returnorderlineitem',
name='outcome',
field=models.PositiveIntegerField(choices=InvenTree.status_codes.ReturnOrderLineStatus.items(), default=10, help_text='Outcome for this line item', verbose_name='Outcome'),
),
]

View File

@ -41,9 +41,12 @@ from InvenTree.helpers_model import getSetting, notify_responsible
from InvenTree.models import (InvenTreeAttachment, InvenTreeBarcodeMixin,
InvenTreeNotesMixin, MetadataMixin,
ReferenceIndexingMixin)
from InvenTree.status_codes import (PurchaseOrderStatus, ReturnOrderLineStatus,
ReturnOrderStatus, SalesOrderStatus,
StockHistoryCode, StockStatus)
from InvenTree.status_codes import (PurchaseOrderStatus,
PurchaseOrderStatusGroups,
ReturnOrderLineStatus, ReturnOrderStatus,
ReturnOrderStatusGroups, SalesOrderStatus,
SalesOrderStatusGroups, StockHistoryCode,
StockStatus)
from part import models as PartModels
from plugin.events import trigger_event
@ -294,7 +297,7 @@ class PurchaseOrder(TotalPriceMixin, Order):
@classmethod
def get_status_class(cls):
"""Return the PurchasOrderStatus class"""
return PurchaseOrderStatus
return PurchaseOrderStatusGroups
@classmethod
def api_defaults(cls, request):
@ -333,10 +336,10 @@ class PurchaseOrder(TotalPriceMixin, Order):
return queryset
# Construct a queryset for "received" orders within the range
received = Q(status=PurchaseOrderStatus.COMPLETE) & Q(complete_date__gte=min_date) & Q(complete_date__lte=max_date)
received = Q(status=PurchaseOrderStatus.COMPLETE.value) & Q(complete_date__gte=min_date) & Q(complete_date__lte=max_date)
# Construct a queryset for "pending" orders within the range
pending = Q(status__in=PurchaseOrderStatus.OPEN) & ~Q(target_date=None) & Q(target_date__gte=min_date) & Q(target_date__lte=max_date)
pending = Q(status__in=PurchaseOrderStatusGroups.OPEN) & ~Q(target_date=None) & Q(target_date__gte=min_date) & Q(target_date__lte=max_date)
# TODO - Construct a queryset for "overdue" orders within the range
@ -361,7 +364,7 @@ class PurchaseOrder(TotalPriceMixin, Order):
]
)
status = models.PositiveIntegerField(default=PurchaseOrderStatus.PENDING, choices=PurchaseOrderStatus.items(),
status = models.PositiveIntegerField(default=PurchaseOrderStatus.PENDING.value, choices=PurchaseOrderStatus.items(),
help_text=_('Purchase order status'))
@property
@ -479,7 +482,7 @@ class PurchaseOrder(TotalPriceMixin, Order):
Order must be currently PENDING.
"""
if self.status == PurchaseOrderStatus.PENDING:
self.status = PurchaseOrderStatus.PLACED
self.status = PurchaseOrderStatus.PLACED.value
self.issue_date = datetime.now().date()
self.save()
@ -500,7 +503,7 @@ class PurchaseOrder(TotalPriceMixin, Order):
Order must be currently PLACED.
"""
if self.status == PurchaseOrderStatus.PLACED:
self.status = PurchaseOrderStatus.COMPLETE
self.status = PurchaseOrderStatus.COMPLETE.value
self.complete_date = datetime.now().date()
self.save()
@ -520,7 +523,7 @@ class PurchaseOrder(TotalPriceMixin, Order):
@property
def is_open(self):
"""Return True if the PurchaseOrder is 'open'"""
return self.status in PurchaseOrderStatus.OPEN
return self.status in PurchaseOrderStatusGroups.OPEN
def can_cancel(self):
"""A PurchaseOrder can only be cancelled under the following circumstances.
@ -537,7 +540,7 @@ class PurchaseOrder(TotalPriceMixin, Order):
def cancel_order(self):
"""Marks the PurchaseOrder as CANCELLED."""
if self.can_cancel():
self.status = PurchaseOrderStatus.CANCELLED
self.status = PurchaseOrderStatus.CANCELLED.value
self.save()
trigger_event('purchaseorder.cancelled', id=self.pk)
@ -574,7 +577,7 @@ class PurchaseOrder(TotalPriceMixin, Order):
return self.lines.count() > 0 and self.pending_line_items().count() == 0
@transaction.atomic
def receive_line_item(self, line, location, quantity, user, status=StockStatus.OK, **kwargs):
def receive_line_item(self, line, location, quantity, user, status=StockStatus.OK.value, **kwargs):
"""Receive a line item (or partial line item) against this PurchaseOrder."""
# Extract optional batch code for the new stock item
batch_code = kwargs.get('batch_code', '')
@ -701,7 +704,7 @@ class SalesOrder(TotalPriceMixin, Order):
@classmethod
def get_status_class(cls):
"""Return the SalesOrderStatus class"""
return SalesOrderStatus
return SalesOrderStatusGroups
@classmethod
def api_defaults(cls, request):
@ -739,10 +742,10 @@ class SalesOrder(TotalPriceMixin, Order):
return queryset
# Construct a queryset for "completed" orders within the range
completed = Q(status__in=SalesOrderStatus.COMPLETE) & Q(shipment_date__gte=min_date) & Q(shipment_date__lte=max_date)
completed = Q(status__in=SalesOrderStatusGroups.COMPLETE) & Q(shipment_date__gte=min_date) & Q(shipment_date__lte=max_date)
# Construct a queryset for "pending" orders within the range
pending = Q(status__in=SalesOrderStatus.OPEN) & ~Q(target_date=None) & Q(target_date__gte=min_date) & Q(target_date__lte=max_date)
pending = Q(status__in=SalesOrderStatusGroups.OPEN) & ~Q(target_date=None) & Q(target_date__gte=min_date) & Q(target_date__lte=max_date)
# TODO: Construct a queryset for "overdue" orders within the range
@ -783,7 +786,7 @@ class SalesOrder(TotalPriceMixin, Order):
return self.customer
status = models.PositiveIntegerField(
default=SalesOrderStatus.PENDING,
default=SalesOrderStatus.PENDING.value,
choices=SalesOrderStatus.items(),
verbose_name=_('Status'), help_text=_('Purchase order status')
)
@ -813,7 +816,7 @@ class SalesOrder(TotalPriceMixin, Order):
@property
def is_open(self):
"""Return True if this order is 'open' (either 'pending' or 'in_progress')"""
return self.status in SalesOrderStatus.OPEN
return self.status in SalesOrderStatusGroups.OPEN
@property
def stock_allocations(self):
@ -881,7 +884,7 @@ class SalesOrder(TotalPriceMixin, Order):
"""Change this order from 'PENDING' to 'IN_PROGRESS'"""
if self.status == SalesOrderStatus.PENDING:
self.status = SalesOrderStatus.IN_PROGRESS
self.status = SalesOrderStatus.IN_PROGRESS.value
self.issue_date = datetime.now().date()
self.save()
@ -892,7 +895,7 @@ class SalesOrder(TotalPriceMixin, Order):
if not self.can_complete(**kwargs):
return False
self.status = SalesOrderStatus.SHIPPED
self.status = SalesOrderStatus.SHIPPED.value
self.shipped_by = user
self.shipment_date = datetime.now()
@ -921,7 +924,7 @@ class SalesOrder(TotalPriceMixin, Order):
if not self.can_cancel():
return False
self.status = SalesOrderStatus.CANCELLED
self.status = SalesOrderStatus.CANCELLED.value
self.save()
for line in self.lines.all():
@ -1696,7 +1699,7 @@ class ReturnOrder(TotalPriceMixin, Order):
@classmethod
def get_status_class(cls):
"""Return the ReturnOrderStatus class"""
return ReturnOrderStatus
return ReturnOrderStatusGroups
@classmethod
def api_defaults(cls, request):
@ -1742,7 +1745,7 @@ class ReturnOrder(TotalPriceMixin, Order):
return self.customer
status = models.PositiveIntegerField(
default=ReturnOrderStatus.PENDING,
default=ReturnOrderStatus.PENDING.value,
choices=ReturnOrderStatus.items(),
verbose_name=_('Status'), help_text=_('Return order status')
)
@ -1773,7 +1776,7 @@ class ReturnOrder(TotalPriceMixin, Order):
@property
def is_open(self):
"""Return True if this order is outstanding"""
return self.status in ReturnOrderStatus.OPEN
return self.status in ReturnOrderStatusGroups.OPEN
@property
def is_received(self):
@ -1784,7 +1787,7 @@ class ReturnOrder(TotalPriceMixin, Order):
def cancel_order(self):
"""Cancel this ReturnOrder (if not already cancelled)"""
if self.status != ReturnOrderStatus.CANCELLED:
self.status = ReturnOrderStatus.CANCELLED
self.status = ReturnOrderStatus.CANCELLED.value
self.save()
trigger_event('returnorder.cancelled', id=self.pk)
@ -1794,7 +1797,7 @@ class ReturnOrder(TotalPriceMixin, Order):
"""Complete this ReturnOrder (if not already completed)"""
if self.status == ReturnOrderStatus.IN_PROGRESS:
self.status = ReturnOrderStatus.COMPLETE
self.status = ReturnOrderStatus.COMPLETE.value
self.complete_date = datetime.now().date()
self.save()
@ -1809,7 +1812,7 @@ class ReturnOrder(TotalPriceMixin, Order):
"""Issue this ReturnOrder (if currently pending)"""
if self.status == ReturnOrderStatus.PENDING:
self.status = ReturnOrderStatus.IN_PROGRESS
self.status = ReturnOrderStatus.IN_PROGRESS.value
self.issue_date = datetime.now().date()
self.save()
@ -1833,7 +1836,7 @@ class ReturnOrder(TotalPriceMixin, Order):
stock_item = line.item
deltas = {
'status': StockStatus.QUARANTINED,
'status': StockStatus.QUARANTINED.value,
'returnorder': self.pk,
'location': location.pk,
}
@ -1842,7 +1845,7 @@ class ReturnOrder(TotalPriceMixin, Order):
deltas['customer'] = stock_item.customer.pk
# Update the StockItem
stock_item.status = StockStatus.QUARANTINED
stock_item.status = StockStatus.QUARANTINED.value
stock_item.location = location
stock_item.customer = None
stock_item.sales_order = None
@ -1926,7 +1929,7 @@ class ReturnOrderLineItem(OrderLineItem):
return self.received_date is not None
outcome = models.PositiveIntegerField(
default=ReturnOrderLineStatus.PENDING,
default=ReturnOrderLineStatus.PENDING.value,
choices=ReturnOrderLineStatus.items(),
verbose_name=_('Outcome'), help_text=_('Outcome for this line item')
)

View File

@ -27,8 +27,9 @@ from InvenTree.serializers import (InvenTreeAttachmentSerializer,
InvenTreeDecimalField,
InvenTreeModelSerializer,
InvenTreeMoneySerializer)
from InvenTree.status_codes import (PurchaseOrderStatus, ReturnOrderStatus,
SalesOrderStatus, StockStatus)
from InvenTree.status_codes import (PurchaseOrderStatusGroups,
ReturnOrderStatus, SalesOrderStatusGroups,
StockStatus)
from part.serializers import PartBriefSerializer
from users.serializers import OwnerSerializer
@ -381,7 +382,7 @@ class PurchaseOrderLineItemSerializer(InvenTreeModelSerializer):
def validate_purchase_order(self, purchase_order):
"""Validation for the 'purchase_order' field"""
if purchase_order.status not in PurchaseOrderStatus.OPEN:
if purchase_order.status not in PurchaseOrderStatusGroups.OPEN:
raise ValidationError(_('Order is not open'))
return purchase_order
@ -518,8 +519,8 @@ class PurchaseOrderLineItemReceiveSerializer(serializers.Serializer):
)
status = serializers.ChoiceField(
choices=list(StockStatus.items()),
default=StockStatus.OK,
choices=StockStatus.items(),
default=StockStatus.OK.value,
label=_('Status'),
)
@ -906,7 +907,7 @@ class SalesOrderLineItemSerializer(InvenTreeModelSerializer):
queryset = queryset.annotate(
overdue=Case(
When(
Q(order__status__in=SalesOrderStatus.OPEN) & order.models.SalesOrderLineItem.OVERDUE_FILTER, then=Value(True, output_field=BooleanField()),
Q(order__status__in=SalesOrderStatusGroups.OPEN) & order.models.SalesOrderLineItem.OVERDUE_FILTER, then=Value(True, output_field=BooleanField()),
),
default=Value(False, output_field=BooleanField()),
)

View File

@ -7,7 +7,8 @@ from django.utils.translation import gettext_lazy as _
import common.notifications
import InvenTree.helpers_model
import order.models
from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus
from InvenTree.status_codes import (PurchaseOrderStatusGroups,
SalesOrderStatusGroups)
from InvenTree.tasks import ScheduledTask, scheduled_task
from plugin.events import trigger_event
@ -68,7 +69,7 @@ def check_overdue_purchase_orders():
overdue_orders = order.models.PurchaseOrder.objects.filter(
target_date=yesterday,
status__in=PurchaseOrderStatus.OPEN
status__in=PurchaseOrderStatusGroups.OPEN,
)
for po in overdue_orders:
@ -131,7 +132,7 @@ def check_overdue_sales_orders():
overdue_orders = order.models.SalesOrder.objects.filter(
target_date=yesterday,
status__in=SalesOrderStatus.OPEN
status__in=SalesOrderStatusGroups.OPEN,
)
for po in overdue_orders:

View File

@ -3,7 +3,7 @@
{% load i18n %}
{% load static %}
{% load inventree_extras %}
{% load status_codes %}
{% load generic %}
{% block page_title %}
{% inventree_title %} | {% trans "Purchase Order" %}
@ -121,7 +121,7 @@ src="{% static 'img/blank_image.png' %}"
<td><span class='fas fa-info'></span></td>
<td>{% trans "Order Status" %}</td>
<td>
{% purchase_order_status_label order.status %}
{% status_label 'purchase_order' order.status %}
{% if order.is_overdue %}
<span class='badge rounded-pill bg-danger'>{% trans "Overdue" %}</span>
{% endif %}

View File

@ -1,7 +1,7 @@
{% extends "order/order_base.html" %}
{% load inventree_extras %}
{% load status_codes %}
{% load generic %}
{% load i18n %}
{% load static %}

View File

@ -3,7 +3,7 @@
{% load i18n %}
{% load static %}
{% load inventree_extras %}
{% load status_codes %}
{% load generic %}
{% block page_title %}
{% inventree_title %} | {% trans "Return Order" %}
@ -113,7 +113,7 @@ src="{% static 'img/blank_image.png' %}"
<td><span class='fas fa-info'></span></td>
<td>{% trans "Order Status" %}</td>
<td>
{% return_order_status_label order.status %}
{% status_label 'return_order' order.status %}
{% if order.is_overdue %}
<span class='badge rounded-pill bg-danger'>{% trans "Overdue" %}</span>
{% endif %}

View File

@ -1,7 +1,7 @@
{% extends "order/return_order_base.html" %}
{% load inventree_extras %}
{% load status_codes %}
{% load generic %}
{% load i18n %}
{% load static %}

View File

@ -3,7 +3,7 @@
{% load i18n %}
{% load static %}
{% load inventree_extras %}
{% load status_codes %}
{% load generic %}
{% block page_title %}
{% inventree_title %} | {% trans "Sales Order" %}
@ -118,7 +118,7 @@ src="{% static 'img/blank_image.png' %}"
<td><span class='fas fa-info'></span></td>
<td>{% trans "Order Status" %}</td>
<td>
{% sales_order_status_label order.status %}
{% status_label 'sales_order' order.status %}
{% if order.is_overdue %}
<span class='badge rounded-pill bg-danger'>{% trans "Overdue" %}</span>
{% endif %}

View File

@ -1,7 +1,7 @@
{% extends "order/sales_order_base.html" %}
{% load inventree_extras %}
{% load status_codes %}
{% load generic %}
{% load i18n %}
{% load static %}

View File

@ -17,7 +17,7 @@ from common.settings import currency_codes
from company.models import Company
from InvenTree.status_codes import (PurchaseOrderStatus, ReturnOrderLineStatus,
ReturnOrderStatus, SalesOrderStatus,
StockStatus)
SalesOrderStatusGroups, StockStatus)
from InvenTree.unit_test import InvenTreeAPITestCase
from order import models
from part.models import Part
@ -562,7 +562,7 @@ class PurchaseOrderTest(OrderTest):
# Test without completed orders
response = self.get(url, expected_code=200, format=None)
number_orders = len(models.PurchaseOrder.objects.filter(target_date__isnull=False).filter(status__lt=PurchaseOrderStatus.COMPLETE))
number_orders = len(models.PurchaseOrder.objects.filter(target_date__isnull=False).filter(status__lt=PurchaseOrderStatus.COMPLETE.value))
# Transform content to a Calendar object
calendar = Calendar.from_ical(response.content)
@ -743,7 +743,7 @@ class PurchaseOrderReceiveTest(OrderTest):
# Mark the order as "placed" so we can receive line items
order = models.PurchaseOrder.objects.get(pk=1)
order.status = PurchaseOrderStatus.PLACED
order.status = PurchaseOrderStatus.PLACED.value
order.save()
def test_empty(self):
@ -944,7 +944,7 @@ class PurchaseOrderReceiveTest(OrderTest):
# Before posting "valid" data, we will mark the purchase order as "pending"
# In this case we do expect an error!
order = models.PurchaseOrder.objects.get(pk=1)
order.status = PurchaseOrderStatus.PENDING
order.status = PurchaseOrderStatus.PENDING.value
order.save()
response = self.post(
@ -956,7 +956,7 @@ class PurchaseOrderReceiveTest(OrderTest):
self.assertIn('can only be received against', str(response.data))
# Now, set the PurchaseOrder back to "PLACED" so the items can be received
order.status = PurchaseOrderStatus.PLACED
order.status = PurchaseOrderStatus.PLACED.value
order.save()
# Receive two separate line items against this order
@ -1388,7 +1388,7 @@ class SalesOrderTest(OrderTest):
# Test without completed orders
response = self.get(url, expected_code=200, format=None)
number_orders = len(models.SalesOrder.objects.filter(target_date__isnull=False).filter(status__lt=SalesOrderStatus.SHIPPED))
number_orders = len(models.SalesOrder.objects.filter(target_date__isnull=False).filter(status__lt=SalesOrderStatus.SHIPPED.value))
# Transform content to a Calendar object
calendar = Calendar.from_ical(response.content)
@ -1621,7 +1621,7 @@ class SalesOrderDownloadTest(OrderTest):
file,
required_cols=required_cols,
excluded_cols=excluded_cols,
required_rows=models.SalesOrder.objects.filter(status__in=SalesOrderStatus.OPEN).count(),
required_rows=models.SalesOrder.objects.filter(status__in=SalesOrderStatusGroups.OPEN).count(),
delimiter='\t',
)

View File

@ -109,7 +109,7 @@ class TestShipmentMigration(MigratorTestCase):
reference=f'SO{ii}',
customer=customer,
description='A sales order for stuffs',
status=SalesOrderStatus.PENDING,
status=SalesOrderStatus.PENDING.value,
)
order.save()