From 889834b6930ca40a84e8d1de7a1a08e44252e50b Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 3 Jul 2021 21:43:22 +1000 Subject: [PATCH] Refactor POLineItemCreate form --- InvenTree/order/forms.py | 20 +---- InvenTree/order/serializers.py | 2 +- .../order/purchase_order_detail.html | 43 ++++++---- InvenTree/order/test_views.py | 51 ----------- InvenTree/order/views.py | 84 ------------------- InvenTree/templates/js/model_renderers.js | 2 + 6 files changed, 30 insertions(+), 172 deletions(-) diff --git a/InvenTree/order/forms.py b/InvenTree/order/forms.py index 60837b6cf6..f0cc8b6535 100644 --- a/InvenTree/order/forms.py +++ b/InvenTree/order/forms.py @@ -20,7 +20,7 @@ from common.forms import MatchItemForm import part.models from stock.models import StockLocation -from .models import PurchaseOrder, PurchaseOrderLineItem +from .models import PurchaseOrder from .models import SalesOrder, SalesOrderLineItem from .models import SalesOrderAllocation @@ -96,24 +96,6 @@ class ReceivePurchaseOrderForm(HelperForm): ] -class EditPurchaseOrderLineItemForm(HelperForm): - """ Form for editing a PurchaseOrderLineItem object """ - - quantity = RoundingDecimalFormField(max_digits=10, decimal_places=5, label=_('Quantity')) - - class Meta: - model = PurchaseOrderLineItem - fields = [ - 'order', - 'part', - 'quantity', - 'reference', - 'purchase_price', - 'destination', - 'notes', - ] - - class EditSalesOrderLineItemForm(HelperForm): """ Form for editing a SalesOrderLineItem object """ diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py index 220b6dee11..809dd0e8fb 100644 --- a/InvenTree/order/serializers.py +++ b/InvenTree/order/serializers.py @@ -350,7 +350,7 @@ class SOLineItemSerializer(InvenTreeModelSerializer): max_digits=19, decimal_places=4, allow_null=True - ) + ) sale_price_string = serializers.CharField(source='sale_price', read_only=True) diff --git a/InvenTree/order/templates/order/purchase_order_detail.html b/InvenTree/order/templates/order/purchase_order_detail.html index 6a42d0d0cc..9746103c89 100644 --- a/InvenTree/order/templates/order/purchase_order_detail.html +++ b/InvenTree/order/templates/order/purchase_order_detail.html @@ -38,26 +38,34 @@ {% if order.status == PurchaseOrderStatus.PENDING %} $('#new-po-line').click(function() { - launchModalForm("{% url 'po-line-item-create' %}", - { - reload: true, - data: { - order: {{ order.id }}, + + + constructForm('{% url "api-po-line-list" %}', { + fields: { + order: { + value: {{ order.pk }}, + hidden: true, }, - secondary: [ - { - field: 'part', - label: '{% trans "New Supplier Part" %}', - title: '{% trans "Create new supplier part" %}', - url: "{% url 'supplier-part-create' %}", - data: { - supplier: {{ order.supplier.id }}, - }, + part: { + filters: { + part_detail: true, + supplier_detail: true, + supplier: {{ order.supplier.pk }}, }, - ], - } - ); + }, + quantity: {}, + reference: {}, + purchase_price: {}, + purchase_price_currency: {}, + destination: {}, + notes: {}, + }, + method: 'POST', + title: '{% trans "Add Line Item" %}', + onSuccess: reloadTable, + }); }); + {% endif %} function reloadTable() { @@ -77,6 +85,7 @@ function setupCallbacks() { fields: { part: { filters: { + part_detail: true, supplier_detail: true, supplier: {{ order.supplier.pk }}, } diff --git a/InvenTree/order/test_views.py b/InvenTree/order/test_views.py index 934e1346f8..4b49b6c94e 100644 --- a/InvenTree/order/test_views.py +++ b/InvenTree/order/test_views.py @@ -104,57 +104,6 @@ class POTests(OrderViewTestCase): order = PurchaseOrder.objects.get(pk=1) self.assertEqual(order.status, PurchaseOrderStatus.PLACED) - def test_line_item_create(self): - """ Test the form for adding a new LineItem to a PurchaseOrder """ - - # Record the number of line items in the PurchaseOrder - po = PurchaseOrder.objects.get(pk=1) - n = po.lines.count() - self.assertEqual(po.status, PurchaseOrderStatus.PENDING) - - url = reverse('po-line-item-create') - - # GET the form (pass the correct info) - response = self.client.get(url, {'order': 1}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - - post_data = { - 'part': 100, - 'quantity': 45, - 'reference': 'Test reference field', - 'notes': 'Test notes field' - } - - # POST with an invalid purchase order - post_data['order'] = 99 - response = self.client.post(url, post_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - data = json.loads(response.content) - self.assertFalse(data['form_valid']) - - # POST with a part that does not match the purchase order - post_data['order'] = 1 - post_data['part'] = 7 - response = self.client.post(url, post_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - data = json.loads(response.content) - self.assertFalse(data['form_valid']) - - # POST with an invalid part - post_data['part'] = 12345 - response = self.client.post(url, post_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - data = json.loads(response.content) - self.assertFalse(data['form_valid']) - - # POST the form with valid data - post_data['part'] = 100 - response = self.client.post(url, post_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - self.assertEqual(response.status_code, 200) - data = json.loads(response.content) - self.assertTrue(data['form_valid']) - - self.assertEqual(n + 1, PurchaseOrder.objects.get(pk=1).lines.count()) - - line = PurchaseOrderLineItem.objects.get(order=1, part=100) - self.assertEqual(line.quantity, 45) - class TestPOReceive(OrderViewTestCase): """ Tests for receiving a purchase order """ diff --git a/InvenTree/order/views.py b/InvenTree/order/views.py index a8048a0cf8..a8fbcf23f1 100644 --- a/InvenTree/order/views.py +++ b/InvenTree/order/views.py @@ -1049,90 +1049,6 @@ class OrderParts(AjaxView): order.add_line_item(supplier_part, quantity, purchase_price=purchase_price) -class POLineItemCreate(AjaxCreateView): - """ AJAX view for creating a new PurchaseOrderLineItem object - """ - - model = PurchaseOrderLineItem - context_object_name = 'line' - form_class = order_forms.EditPurchaseOrderLineItemForm - ajax_form_title = _('Add Line Item') - - def validate(self, item, form, **kwargs): - - order = form.cleaned_data.get('order', None) - - part = form.cleaned_data.get('part', None) - - if not part: - form.add_error('part', _('Supplier part must be specified')) - - if part and order: - if not part.supplier == order.supplier: - form.add_error( - 'part', - _('Supplier must match for Part and Order') - ) - - def get_form(self): - """ Limit choice options based on the selected order, etc - """ - - form = super().get_form() - - # Limit the available to orders to ones that are PENDING - query = form.fields['order'].queryset - query = query.filter(status=PurchaseOrderStatus.PENDING) - form.fields['order'].queryset = query - - order_id = form['order'].value() - - try: - order = PurchaseOrder.objects.get(id=order_id) - - query = form.fields['part'].queryset - - # Only allow parts from the selected supplier - query = query.filter(supplier=order.supplier.id) - - exclude = [] - - for line in order.lines.all(): - if line.part and line.part.id not in exclude: - exclude.append(line.part.id) - - # Remove parts that are already in the order - query = query.exclude(id__in=exclude) - - form.fields['part'].queryset = query - form.fields['order'].widget = HiddenInput() - except (ValueError, PurchaseOrder.DoesNotExist): - pass - - return form - - def get_initial(self): - """ Extract initial data for the line item. - - - The 'order' will be passed as a query parameter - - Use this to set the 'order' field and limit the options for 'part' - """ - - initials = super().get_initial().copy() - - order_id = self.request.GET.get('order', None) - - if order_id: - try: - order = PurchaseOrder.objects.get(id=order_id) - initials['order'] = order - - except (PurchaseOrder.DoesNotExist, ValueError): - pass - - return initials - - class SOLineItemCreate(AjaxCreateView): """ Ajax view for creating a new SalesOrderLineItem object """ diff --git a/InvenTree/templates/js/model_renderers.js b/InvenTree/templates/js/model_renderers.js index 3ad9e44782..5b838f184b 100644 --- a/InvenTree/templates/js/model_renderers.js +++ b/InvenTree/templates/js/model_renderers.js @@ -145,9 +145,11 @@ function renderSupplierPart(name, data, parameters, options) { var html = ``; html += ` ${data.supplier_detail.name} - ${data.SKU}`; + html += ` - ${data.part_detail.full_name}`; html += `{% trans "Supplier Part ID" %}: ${data.pk}`; + return html; } \ No newline at end of file