Unit test fixes

This commit is contained in:
Oliver 2021-12-03 18:42:36 +11:00
parent d7c87300c6
commit 88fce1e813
5 changed files with 63 additions and 17 deletions

View File

@ -617,11 +617,34 @@ class SalesOrder(Order):
def is_completed(self): def is_completed(self):
""" """
Check if this order is "shipped" (all line items delivered), Check if this order is "shipped" (all line items delivered),
and mark it as "shipped" if so.
""" """
return self.lines.count() > 0 and all([line.is_completed() for line in self.lines.all()]) return self.lines.count() > 0 and all([line.is_completed() for line in self.lines.all()])
def complete_order(self, user):
"""
Mark this order as "complete"
"""
if self.lines.count() == 0:
# Order without line items cannot be completed
raise ValidationError(_('Order cannot be completed as no parts have been assigned'))
if self.status != SalesOrderStatus.PENDING:
# Only a PENDING order can be marked as SHIPPED
raise ValidationError(_('Only a pending order can be marked as complete'))
# Check if there are any incomplete shipments
for shipment in self.shipments.all():
if not shipment.shipment_date:
raise ValidationError(_('Order cannot be completed as there are pending shipments'))
self.status = SalesOrderStatus.SHIPPED
self.shipped_by = user
self.shipment_date = datetime.now()
self.save()
def can_cancel(self): def can_cancel(self):
""" """
Return True if this order can be cancelled Return True if this order can be cancelled
@ -988,6 +1011,9 @@ class SalesOrderShipment(models.Model):
help_text=_('Shipment tracking information'), help_text=_('Shipment tracking information'),
) )
def is_complete(self):
return self.shipment_date is not None
def check_can_complete(self): def check_can_complete(self):
if self.shipment_date: if self.shipment_date:

View File

@ -26,7 +26,7 @@ from InvenTree.serializers import InvenTreeModelSerializer
from InvenTree.serializers import InvenTreeDecimalField from InvenTree.serializers import InvenTreeDecimalField
from InvenTree.serializers import InvenTreeMoneySerializer from InvenTree.serializers import InvenTreeMoneySerializer
from InvenTree.serializers import ReferenceIndexingSerializerMixin from InvenTree.serializers import ReferenceIndexingSerializerMixin
from InvenTree.status_codes import StockStatus, SalesOrderStatus from InvenTree.status_codes import StockStatus
import order.models import order.models
@ -745,11 +745,11 @@ class SalesOrderCompleteSerializer(serializers.Serializer):
request = self.context['request'] request = self.context['request']
order = self.context['order'] order = self.context['order']
data = self.validated_data # data = self.validated_data
# Mark this order as complete! user = getattr(request, 'user', None)
order.status = SalesOrderStatus.SHIPPED
order.save() order.complete_order(user)
class SOShipmentAllocationSerializer(serializers.Serializer): class SOShipmentAllocationSerializer(serializers.Serializer):

View File

@ -4,7 +4,6 @@ Unit tests for the 'order' model data migrations
from django_test_migrations.contrib.unittest_case import MigratorTestCase from django_test_migrations.contrib.unittest_case import MigratorTestCase
from InvenTree import helpers
from InvenTree.status_codes import SalesOrderStatus from InvenTree.status_codes import SalesOrderStatus

View File

@ -10,7 +10,7 @@ from company.models import Company
from InvenTree import status_codes as status from InvenTree import status_codes as status
from order.models import SalesOrder, SalesOrderLineItem, SalesOrderAllocation from order.models import SalesOrder, SalesOrderLineItem, SalesOrderAllocation, SalesOrderShipment
from part.models import Part from part.models import Part
@ -42,6 +42,12 @@ class SalesOrderTest(TestCase):
customer_reference='ABC 55555' customer_reference='ABC 55555'
) )
# Create a Shipment against this SalesOrder
self.shipment = SalesOrderShipment.objects.create(
order=self.order,
reference='001',
)
# Create a line item # Create a line item
self.line = SalesOrderLineItem.objects.create(quantity=50, order=self.order, part=self.part) self.line = SalesOrderLineItem.objects.create(quantity=50, order=self.order, part=self.part)
@ -86,11 +92,13 @@ class SalesOrderTest(TestCase):
# Allocate stock to the order # Allocate stock to the order
SalesOrderAllocation.objects.create( SalesOrderAllocation.objects.create(
line=self.line, line=self.line,
shipment=self.shipment,
item=StockItem.objects.get(pk=self.Sa.pk), item=StockItem.objects.get(pk=self.Sa.pk),
quantity=25) quantity=25)
SalesOrderAllocation.objects.create( SalesOrderAllocation.objects.create(
line=self.line, line=self.line,
shipment=self.shipment,
item=StockItem.objects.get(pk=self.Sb.pk), item=StockItem.objects.get(pk=self.Sb.pk),
quantity=25 if full else 20 quantity=25 if full else 20
) )
@ -126,9 +134,9 @@ class SalesOrderTest(TestCase):
# Now try to ship it - should fail # Now try to ship it - should fail
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
self.order.ship_order(None) self.order.complete_order(None)
def test_ship_order(self): def test_complete_order(self):
# Allocate line items, then ship the order # Allocate line items, then ship the order
# Assert some stuff before we run the test # Assert some stuff before we run the test
@ -140,7 +148,22 @@ class SalesOrderTest(TestCase):
self.assertEqual(SalesOrderAllocation.objects.count(), 2) self.assertEqual(SalesOrderAllocation.objects.count(), 2)
self.order.ship_order(None) # Attempt to complete the order (but shipments are not completed!)
with self.assertRaises(ValidationError):
self.order.complete_order(None)
self.assertIsNone(self.shipment.shipment_date)
self.assertFalse(self.shipment.is_complete())
# Mark the shipments as complete
self.shipment.complete_shipment(None)
self.assertTrue(self.shipment.is_complete())
# Now, should be OK to ship
self.order.complete_order(None)
self.assertEqual(self.order.status, status.SalesOrderStatus.SHIPPED)
self.assertIsNotNone(self.order.shipment_date)
# There should now be 4 stock items # There should now be 4 stock items
self.assertEqual(StockItem.objects.count(), 4) self.assertEqual(StockItem.objects.count(), 4)
@ -162,12 +185,12 @@ class SalesOrderTest(TestCase):
self.assertEqual(sa.sales_order, None) self.assertEqual(sa.sales_order, None)
self.assertEqual(sb.sales_order, None) self.assertEqual(sb.sales_order, None)
# And no allocations # And the allocations still exist
self.assertEqual(SalesOrderAllocation.objects.count(), 0) self.assertEqual(SalesOrderAllocation.objects.count(), 2)
self.assertEqual(self.order.status, status.SalesOrderStatus.SHIPPED) self.assertEqual(self.order.status, status.SalesOrderStatus.SHIPPED)
self.assertTrue(self.order.is_fully_allocated()) self.assertTrue(self.order.is_fully_allocated())
self.assertTrue(self.line.is_fully_allocated()) self.assertTrue(self.line.is_fully_allocated())
self.assertEqual(self.line.fulfilled_quantity(), 50) self.assertEqual(self.line.fulfilled_quantity(), 50)
self.assertEqual(self.line.allocated_quantity(), 0) self.assertEqual(self.line.allocated_quantity(), 50)

View File

@ -792,14 +792,12 @@ class OrderParts(AjaxView):
order.add_line_item(supplier_part, quantity, purchase_price=purchase_price) order.add_line_item(supplier_part, quantity, purchase_price=purchase_price)
#### TODO: This class MUST be converted to the API forms!
#### TODO: We MUST select the shipment
class SalesOrderAssignSerials(AjaxView, FormMixin): class SalesOrderAssignSerials(AjaxView, FormMixin):
""" """
View for assigning stock items to a sales order, View for assigning stock items to a sales order,
by serial number lookup. by serial number lookup.
""" """
# TODO: Remove this class and replace with an API endpoint
model = SalesOrderAllocation model = SalesOrderAllocation
role_required = 'sales_order.change' role_required = 'sales_order.change'