diff --git a/InvenTree/InvenTree/api_version.py b/InvenTree/InvenTree/api_version.py index e44aedf10b..993c7e9980 100644 --- a/InvenTree/InvenTree/api_version.py +++ b/InvenTree/InvenTree/api_version.py @@ -4,11 +4,14 @@ InvenTree API version information # InvenTree API version -INVENTREE_API_VERSION = 50 +INVENTREE_API_VERSION = 51 """ Increment this API version number whenever there is a significant change to the API that any clients need to know about +v51 -> 2022-05-24 : https://github.com/inventree/InvenTree/pull/3058 + - Adds new fields to the SalesOrderShipment model + v50 -> 2022-05-18 : https://github.com/inventree/InvenTree/pull/2912 - Implement Attachments for manufacturer parts diff --git a/InvenTree/order/migrations/0069_auto_20220524_0508.py b/InvenTree/order/migrations/0069_auto_20220524_0508.py new file mode 100644 index 0000000000..ff37522332 --- /dev/null +++ b/InvenTree/order/migrations/0069_auto_20220524_0508.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.13 on 2022-05-24 05:08 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('order', '0068_alter_salesorderallocation_unique_together'), + ] + + operations = [ + migrations.AddField( + model_name='salesordershipment', + name='invoice_number', + field=models.CharField(blank=True, help_text='Reference number for associated invoice', max_length=100, verbose_name='Invoice Number'), + ), + migrations.AddField( + model_name='salesordershipment', + name='link', + field=models.URLField(blank=True, help_text='Link to external page', verbose_name='Link'), + ), + ] diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index 550070e5df..0a5f05ba0f 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -1202,6 +1202,20 @@ class SalesOrderShipment(models.Model): help_text=_('Shipment tracking information'), ) + invoice_number = models.CharField( + max_length=100, + blank=True, + unique=False, + verbose_name=_('Invoice Number'), + help_text=_('Reference number for associated invoice'), + ) + + link = models.URLField( + blank=True, + verbose_name=_('Link'), + help_text=_('Link to external page') + ) + def is_complete(self): return self.shipment_date is not None @@ -1253,6 +1267,18 @@ class SalesOrderShipment(models.Model): if tracking_number is not None: self.tracking_number = tracking_number + # Was an invoice number provided? + invoice_number = kwargs.get('invoice_number', None) + + if invoice_number is not None: + self.invoice_number = invoice_number + + # Was a link provided? + link = kwargs.get('link', None) + + if link is not None: + self.link = link + self.save() trigger_event('salesordershipment.completed', id=self.pk) diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py index 685697f99f..0743d95c33 100644 --- a/InvenTree/order/serializers.py +++ b/InvenTree/order/serializers.py @@ -886,6 +886,8 @@ class SalesOrderShipmentSerializer(InvenTreeModelSerializer): 'checked_by', 'reference', 'tracking_number', + 'invoice_number', + 'link', 'notes', ] @@ -899,8 +901,10 @@ class SalesOrderShipmentCompleteSerializer(serializers.ModelSerializer): model = order.models.SalesOrderShipment fields = [ - 'tracking_number', 'shipment_date', + 'tracking_number', + 'invoice_number', + 'link', ] def validate(self, data): @@ -928,15 +932,14 @@ class SalesOrderShipmentCompleteSerializer(serializers.ModelSerializer): request = self.context['request'] user = request.user - # Extract provided tracking number (optional) - tracking_number = data.get('tracking_number', shipment.tracking_number) - # Extract shipping date (defaults to today's date) shipment_date = data.get('shipment_date', datetime.now()) shipment.complete_shipment( user, - tracking_number=tracking_number, + tracking_number=data.get('tracking_number', shipment.tracking_number), + invoice_number=data.get('invoice_number', shipment.invoice_number), + link=data.get('link', shipment.link), shipment_date=shipment_date, ) diff --git a/InvenTree/order/test_api.py b/InvenTree/order/test_api.py index dd17a033c9..6be694bb11 100644 --- a/InvenTree/order/test_api.py +++ b/InvenTree/order/test_api.py @@ -1324,6 +1324,8 @@ class SalesOrderAllocateTest(OrderTest): response = self.post( url, { + 'invoice_number': 'INV01234', + 'link': 'http://test.com/link.html', 'tracking_number': 'TRK12345', 'shipment_date': '2020-12-05', }, @@ -1334,6 +1336,8 @@ class SalesOrderAllocateTest(OrderTest): self.assertTrue(self.shipment.is_complete()) self.assertEqual(self.shipment.tracking_number, 'TRK12345') + self.assertEqual(self.shipment.invoice_number, 'INV01234') + self.assertEqual(self.shipment.link, 'http://test.com/link.html') def test_sales_order_shipment_list(self): diff --git a/InvenTree/templates/js/translated/order.js b/InvenTree/templates/js/translated/order.js index 5fa0d2f77a..03e967deee 100644 --- a/InvenTree/templates/js/translated/order.js +++ b/InvenTree/templates/js/translated/order.js @@ -55,6 +55,12 @@ function salesOrderShipmentFields(options={}) { tracking_number: { icon: 'fa-hashtag', }, + invoice_number: { + icon: 'fa-dollar-sign', + }, + link: { + icon: 'fa-link', + } }; // If order is specified, hide the order field @@ -129,11 +135,20 @@ function completeShipment(shipment_id, options={}) { method: 'POST', title: `{% trans "Complete Shipment" %} ${shipment.reference}`, fields: { - tracking_number: { - value: shipment.tracking_number, - }, shipment_date: { value: moment().format('YYYY-MM-DD'), + }, + tracking_number: { + value: shipment.tracking_number, + icon: 'fa-hashtag', + }, + invoice_number: { + value: shipment.invoice_number, + icon: 'fa-dollar-sign', + }, + link: { + value: shipment.link, + icon: 'fa-link', } }, preFormContent: html, @@ -2445,10 +2460,26 @@ function loadSalesOrderShipmentTable(table, options={}) { field: 'tracking_number', title: '{% trans "Tracking" %}', }, + { + field: 'invoice_number', + title: '{% trans "Invoice" %}', + }, + { + field: 'link', + title: '{% trans "Link" %}', + formatter: function(value) { + if (value) { + return renderLink(value, value); + } else { + return '-'; + } + } + }, { field: 'notes', title: '{% trans "Notes" %}', visible: false, + switchable: false, // TODO: Implement 'notes' field }, {