mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Added data migration for existing SalesOrder instances
- If a SalesOrder is "PENDING" or there are allocations available, a shipment is created
This commit is contained in:
parent
2f7e0974b7
commit
ce5b47460a
@ -18,7 +18,6 @@ class Migration(migrations.Migration):
|
||||
name='SalesOrderShipment',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('status', models.PositiveIntegerField(choices=[(10, 'Pending'), (20, 'Shipped'), (40, 'Cancelled'), (50, 'Lost'), (60, 'Returned')], default=10, help_text='Shipment status', verbose_name='Status')),
|
||||
('shipment_date', models.DateField(blank=True, help_text='Date of shipment', null=True, verbose_name='Shipment Date')),
|
||||
('reference', models.CharField(blank=True, help_text='Shipment reference', max_length=100, verbose_name='Reference')),
|
||||
('notes', markdownx.models.MarkdownxField(blank=True, help_text='Shipment notes', verbose_name='Notes')),
|
||||
|
89
InvenTree/order/migrations/0055_auto_20211025_0645.py
Normal file
89
InvenTree/order/migrations/0055_auto_20211025_0645.py
Normal file
@ -0,0 +1,89 @@
|
||||
# Generated by Django 3.2.5 on 2021-10-25 06:45
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
from InvenTree.status_codes import SalesOrderStatus
|
||||
|
||||
|
||||
def add_shipment(apps, schema_editor):
|
||||
"""
|
||||
Create a SalesOrderShipment for each existing SalesOrder instance.
|
||||
|
||||
Any "allocations" are marked against that shipment.
|
||||
|
||||
For each existing SalesOrder instance, we create a default SalesOrderShipment,
|
||||
and associate each SalesOrderAllocation with this shipment
|
||||
"""
|
||||
|
||||
Allocation = apps.get_model('order', 'salesorderallocation')
|
||||
SalesOrder = apps.get_model('order', 'salesorder')
|
||||
Shipment = apps.get_model('order', 'salesordershipment')
|
||||
|
||||
n = 0
|
||||
|
||||
for order in SalesOrder.objects.all():
|
||||
|
||||
"""
|
||||
We only create an automatic shipment for "PENDING" orders,
|
||||
as SalesOrderAllocations were historically deleted for "SHIPPED" or "CANCELLED" orders
|
||||
"""
|
||||
|
||||
allocations = Allocation.objects.filter(
|
||||
line__order=order
|
||||
)
|
||||
|
||||
if allocations.count() == 0 and order.status != SalesOrderStatus.PENDING:
|
||||
continue
|
||||
|
||||
# Create a new Shipment instance against this order
|
||||
shipment = Shipment.objects.create(
|
||||
order=order,
|
||||
)
|
||||
|
||||
shipment.save()
|
||||
|
||||
# Iterate through each allocation associated with this order
|
||||
for allocation in allocations:
|
||||
allocation.shipment = shipment
|
||||
allocation.save()
|
||||
|
||||
n += 1
|
||||
|
||||
if n > 0:
|
||||
print(f"\nCreated SalesOrderShipment for {n} SalesOrder instances")
|
||||
|
||||
|
||||
def reverse_add_shipment(apps, schema_editor):
|
||||
"""
|
||||
Reverse the migration, delete and SalesOrderShipment instances
|
||||
"""
|
||||
|
||||
Allocation = apps.get_model('order', 'salesorderallocation')
|
||||
|
||||
# First, ensure that all SalesOrderAllocation objects point to a null shipment
|
||||
for allocation in Allocation.objects.exclude(shipment=None):
|
||||
allocation.shipment = None
|
||||
allocation.save()
|
||||
|
||||
SOS = apps.get_model('order', 'salesordershipment')
|
||||
|
||||
n = SOS.objects.count()
|
||||
|
||||
print(f"Deleting {n} SalesOrderShipment instances")
|
||||
|
||||
SOS.objects.all().delete()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('order', '0054_salesorderallocation_shipment'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(
|
||||
add_shipment,
|
||||
reverse_code=reverse_add_shipment,
|
||||
)
|
||||
]
|
@ -929,13 +929,6 @@ class SalesOrderShipment(models.Model):
|
||||
help_text=_('Sales Order'),
|
||||
)
|
||||
|
||||
status = models.PositiveIntegerField(
|
||||
default=SalesOrderStatus.PENDING,
|
||||
choices=SalesOrderStatus.items(),
|
||||
verbose_name=_('Status'),
|
||||
help_text=_('Shipment status'),
|
||||
)
|
||||
|
||||
shipment_date = models.DateField(
|
||||
null=True, blank=True,
|
||||
verbose_name=_('Shipment Date'),
|
||||
|
@ -5,6 +5,7 @@ Unit tests for the 'order' model data migrations
|
||||
from django_test_migrations.contrib.unittest_case import MigratorTestCase
|
||||
|
||||
from InvenTree import helpers
|
||||
from InvenTree.status_codes import SalesOrderStatus
|
||||
|
||||
|
||||
class TestForwardMigrations(MigratorTestCase):
|
||||
@ -57,3 +58,49 @@ class TestForwardMigrations(MigratorTestCase):
|
||||
|
||||
# The integer reference field must have been correctly updated
|
||||
self.assertEqual(order.reference_int, ii)
|
||||
|
||||
|
||||
class TestShipmentMigration(MigratorTestCase):
|
||||
"""
|
||||
Test data migration for the "SalesOrderShipment" model
|
||||
"""
|
||||
|
||||
migrate_from = ('order', '0051_auto_20211014_0623')
|
||||
migrate_to = ('order', '0055_auto_20211025_0645')
|
||||
|
||||
def prepare(self):
|
||||
"""
|
||||
Create an initial SalesOrder
|
||||
"""
|
||||
|
||||
Company = self.old_state.apps.get_model('company', 'company')
|
||||
|
||||
customer = Company.objects.create(
|
||||
name='My customer',
|
||||
description='A customer we sell stuff too',
|
||||
is_customer=True
|
||||
)
|
||||
|
||||
SalesOrder = self.old_state.apps.get_model('order', 'salesorder')
|
||||
|
||||
for ii in range(5):
|
||||
order = SalesOrder.objects.create(
|
||||
reference=f'SO{ii}',
|
||||
customer=customer,
|
||||
description='A sales order for stuffs',
|
||||
status=SalesOrderStatus.PENDING,
|
||||
)
|
||||
|
||||
order.save()
|
||||
|
||||
def test_shipment_creation(self):
|
||||
"""
|
||||
Check that a SalesOrderShipment has been created
|
||||
"""
|
||||
|
||||
SalesOrder = self.new_state.apps.get_model('order', 'salesorder')
|
||||
Shipment = self.new_state.apps.get_model('order', 'salesordershipment')
|
||||
|
||||
# Check that the correct number of Shipments have been created
|
||||
self.assertEqual(SalesOrder.objects.count(), 5)
|
||||
self.assertEqual(Shipment.objects.count(), 5)
|
||||
|
@ -1681,6 +1681,7 @@ function loadSalesOrderLineItemTable(table, options={}) {
|
||||
location_detail: true,
|
||||
in_stock: true,
|
||||
part: line_item.part,
|
||||
include_variants: false,
|
||||
exclude_so_allocation: options.order,
|
||||
},
|
||||
auto_fill: true,
|
||||
|
Loading…
Reference in New Issue
Block a user