From 73850991947b587db59df51286a3ab1ed6707e55 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 21 Apr 2020 10:14:55 +1000 Subject: [PATCH] Add a model to map multiple StockItem objects to a single SalesOrderLineItem --- ...0024_salesorderlineitemstockassociation.py | 23 +++++++++++++++++++ InvenTree/order/models.py | 17 +++++++++++++- .../templates/order/sales_order_detail.html | 2 ++ InvenTree/part/templates/part/tabs.html | 2 +- 4 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 InvenTree/order/migrations/0024_salesorderlineitemstockassociation.py diff --git a/InvenTree/order/migrations/0024_salesorderlineitemstockassociation.py b/InvenTree/order/migrations/0024_salesorderlineitemstockassociation.py new file mode 100644 index 0000000000..bad3914a74 --- /dev/null +++ b/InvenTree/order/migrations/0024_salesorderlineitemstockassociation.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.5 on 2020-04-21 00:14 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0026_stockitem_uid'), + ('order', '0023_auto_20200420_2309'), + ] + + operations = [ + migrations.CreateModel( + name='SalesOrderLineItemStockAssociation', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('line', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='stock_items', to='order.SalesOrderLineItem')), + ('stock_item', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='sales_order', to='stock.StockItem')), + ], + ), + ] diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index 2e5cdc3372..1490b45d98 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -291,7 +291,7 @@ class SalesOrderAttachment(InvenTreeAttachment): Model for storing file attachments against a SalesOrder object """ - def getSubDir(self): + def getSubdir(self): return os.path.join("so_files", str(self.order.id)) order = models.ForeignKey(SalesOrder, on_delete=models.CASCADE, related_name='attachments') @@ -372,3 +372,18 @@ class SalesOrderLineItem(OrderLineItem): part = models.ForeignKey(Part, on_delete=models.SET_NULL, related_name='sales_order_line_items', null=True, help_text=_('Part'), limit_choices_to={'salable': True}) + +class SalesOrderLineItemStockAssociation(models.Model): + """ + Associates StockItem objects with a SalesOrderLineItem. + This model is used to match stock items with a sales order, + for the purpose of sale / packing / shipping etc. + + Attributes: + line: ForeignKey link to a SalesOrderLineItem object -> A single SalesOrderLineItem can have multiple associated StockItem objects + stock: OneToOne link to a StockItem object -> A StockItem object can only be mapped to a single SalesOrderLineItem + """ + + line = models.ForeignKey(SalesOrderLineItem, on_delete=models.CASCADE, related_name='stock_items') + + stock_item = models.OneToOneField(StockItem, on_delete=models.CASCADE, related_name='sales_order') diff --git a/InvenTree/order/templates/order/sales_order_detail.html b/InvenTree/order/templates/order/sales_order_detail.html index 9d092a5f45..907effebc7 100644 --- a/InvenTree/order/templates/order/sales_order_detail.html +++ b/InvenTree/order/templates/order/sales_order_detail.html @@ -51,10 +51,12 @@ $("#so-lines-table").inventreeTable({ visible: false, }, { + field: 'line', title: 'Line', formatter: function(value, row, index, field) { return index + 1; }, + width: 50, }, { sortable: true, diff --git a/InvenTree/part/templates/part/tabs.html b/InvenTree/part/templates/part/tabs.html index 0f894a5942..4f23e345b6 100644 --- a/InvenTree/part/templates/part/tabs.html +++ b/InvenTree/part/templates/part/tabs.html @@ -25,7 +25,7 @@ {% trans "BOM" %}{{ part.bom_count }} - {% trans "Build" %}{{ part.builds|length }} + {% trans "Build" %}{{ part.active_builds|length }} {% endif %} {% if part.component or part.used_in_count > 0 %}