From bca2f4a07b95c448a21e49ebfe66b600588d8d5d Mon Sep 17 00:00:00 2001 From: Nigel Date: Thu, 15 Apr 2021 15:21:13 -0600 Subject: [PATCH 1/2] feat(sales_order): Stock Items show the PO number Stock items show the PO number that they were purchased on when being viewed in the sales order allocation modal and when viewing the sales order details. --- InvenTree/order/models.py | 3 ++ InvenTree/order/serializers.py | 2 ++ .../templates/order/sales_order_detail.html | 29 +++++++++++++++++-- InvenTree/order/views.py | 2 +- InvenTree/stock/models.py | 6 ++++ 5 files changed, 39 insertions(+), 3 deletions(-) diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index 5305038b4f..fb169e0536 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -826,6 +826,9 @@ class SalesOrderAllocation(models.Model): else: return "" + def get_po(self): + return self.item.purchase_order + def complete_allocation(self, user): """ Complete this allocation (called when the parent SalesOrder is marked as "shipped"): diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py index 062e8986b2..6091140313 100644 --- a/InvenTree/order/serializers.py +++ b/InvenTree/order/serializers.py @@ -235,6 +235,7 @@ class SalesOrderAllocationSerializer(InvenTreeModelSerializer): location_path = serializers.CharField(source='get_location_path') location_id = serializers.IntegerField(source='get_location') serial = serializers.CharField(source='get_serial') + po = serializers.CharField(source='get_po') quantity = serializers.FloatField() class Meta: @@ -247,6 +248,7 @@ class SalesOrderAllocationSerializer(InvenTreeModelSerializer): 'quantity', 'location_id', 'location_path', + 'po', 'item', ] diff --git a/InvenTree/order/templates/order/sales_order_detail.html b/InvenTree/order/templates/order/sales_order_detail.html index 72b7d63911..a90e61bff9 100644 --- a/InvenTree/order/templates/order/sales_order_detail.html +++ b/InvenTree/order/templates/order/sales_order_detail.html @@ -87,6 +87,9 @@ function showAllocationSubTable(index, row, element) { return renderLink(row.location_path, `/stock/location/${row.location_id}/`); }, }, + { + field: 'po' + }, { field: 'buttons', title: '{% trans "Actions" %}', @@ -159,9 +162,12 @@ function showFulfilledSubTable(index, row, element) { text = `{% trans "Quantity" %}: ${row.quantity}`; } - return renderLink(text, `/stock/item/${row.pk}/`); + return renderLink(text, `/stock/item/${row.pk}/`); }, - } + }, + { + field: 'po' + }, ], }); } @@ -271,6 +277,25 @@ $("#so-lines-table").inventreeTable({ field: 'notes', title: '{% trans "Notes" %}', }, + { + field: 'po', + title: '{% trans "PO" %}', + formatter: function(value, row, index, field) { + var po_name = ""; + if (row.allocated) { + row.allocations.forEach(function(allocation) { + if (allocation.po != po_name) { + if (po_name) { + po_name = "-"; + } else { + po_name = allocation.po + } + } + }) + } + return `
` + po_name + `
`; + } + }, {% if order.status == SalesOrderStatus.PENDING %} { field: 'buttons', diff --git a/InvenTree/order/views.py b/InvenTree/order/views.py index cf79746f0d..c8ec42d3e7 100644 --- a/InvenTree/order/views.py +++ b/InvenTree/order/views.py @@ -90,7 +90,7 @@ class SalesOrderDetail(InvenTreeRoleMixin, DetailView): """ Detail view for a SalesOrder object """ context_object_name = 'order' - queryset = SalesOrder.objects.all().prefetch_related('lines') + queryset = SalesOrder.objects.all().prefetch_related('lines__allocations__item__purchase_order') template_name = 'order/sales_order_detail.html' diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index 28123ebc41..88f8dd081c 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -1370,6 +1370,12 @@ class StockItem(MPTTModel): if self.location: s += ' @ {loc}'.format(loc=self.location.name) + if self.purchase_order: + s += " ({pre}{po})".format( + pre=helpers.getSetting("PURCHASEORDER_REFERENCE_PREFIX"), + po=self.purchase_order, + ) + return s @transaction.atomic From 30a2194fe1b121c5f64345a8c245a31614d424ba Mon Sep 17 00:00:00 2001 From: Nigel Date: Fri, 14 May 2021 13:24:13 -0600 Subject: [PATCH 2/2] feat(admin): Show the line items on the PO on the Admin Site --- InvenTree/order/admin.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/InvenTree/order/admin.py b/InvenTree/order/admin.py index 4519f8a2a9..1e7b20e5a1 100644 --- a/InvenTree/order/admin.py +++ b/InvenTree/order/admin.py @@ -13,6 +13,10 @@ from .models import SalesOrder, SalesOrderLineItem from .models import SalesOrderAllocation +class PurchaseOrderLineItemInlineAdmin(admin.StackedInline): + model = PurchaseOrderLineItem + + class PurchaseOrderAdmin(ImportExportModelAdmin): list_display = ( @@ -29,6 +33,10 @@ class PurchaseOrderAdmin(ImportExportModelAdmin): 'description', ] + inlines = [ + PurchaseOrderLineItemInlineAdmin + ] + class SalesOrderAdmin(ImportExportModelAdmin):