diff --git a/InvenTree/order/templates/order/order_base.html b/InvenTree/order/templates/order/order_base.html index 0d46207c33..6f01d0a172 100644 --- a/InvenTree/order/templates/order/order_base.html +++ b/InvenTree/order/templates/order/order_base.html @@ -49,7 +49,7 @@ src="{% static 'img/blank_image.png' %}" {% elif order.status == PurchaseOrderStatus.PLACED %} - + @@ -188,6 +188,27 @@ $("#edit-order").click(function() { }); $("#receive-order").click(function() { + + // Auto select items which have not been fully allocated + var items = $("#po-line-table").bootstrapTable('getData'); + + var items_to_receive = []; + + items.forEach(function(item) { + if (item.received < item.quantity) { + items_to_receive.push(item); + } + }); + + receivePurchaseOrderItems( + {{ order.id }}, + items_to_receive, + { + } + ); + + return; + launchModalForm("{% url 'po-receive' order.id %}", { reload: true, secondary: [ diff --git a/InvenTree/templates/js/translated/build.js b/InvenTree/templates/js/translated/build.js index 463c3c9ae2..aa68b26dd4 100644 --- a/InvenTree/templates/js/translated/build.js +++ b/InvenTree/templates/js/translated/build.js @@ -973,7 +973,6 @@ function allocateStockToBuild(build_id, part_id, bom_items, options={}) { `; - constructForm(`/api/build/${build_id}/allocate/`, { method: 'POST', fields: {}, diff --git a/InvenTree/templates/js/translated/order.js b/InvenTree/templates/js/translated/order.js index 532ab81655..613499344c 100644 --- a/InvenTree/templates/js/translated/order.js +++ b/InvenTree/templates/js/translated/order.js @@ -12,6 +12,7 @@ loadTableFilters, makeIconBadge, purchaseOrderStatusDisplay, + receivePurchaseOrderItems, renderLink, salesOrderStatusDisplay, setupFilterList, @@ -234,6 +235,145 @@ function newPurchaseOrderFromOrderWizard(e) { }); } + +/** + * Receive stock items against a PurchaseOrder + * Uses the POReceive API endpoint + * + * arguments: + * - order_id, ID / PK for the PurchaseOrder instance + * - line_items: A list of PurchaseOrderLineItems objects to be allocated + * + * options: + * - + */ +function receivePurchaseOrderItems(order_id, line_items, options={}) { + + function renderLineItem(line_item, opts={}) { + + var pk = line_item.pk; + + // Part thumbnail + description + var thumb = thumbnailImage(line_item.part_detail.thumbnail); + + // Quantity to Receive + var quantity_input = constructField( + `items_quantity_${pk}`, + { + type: 'decimal', + min_value: 0, + value: opts.quantity || 0, + title: '{% trans "Quantity to receive" %}', + required: true, + }, + { + hideLabels: true, + } + ); + + var destination_input = constructField( + `items_location_${pk}`, + { + type: 'related field', + label: '{% trans "Location" %}', + required: false, + }, + { + hideLabels: true, + } + ); + + // Button to remove the row + var delete_button = ``; + + delete_button += makeIconButton( + 'fa-times icon-red', + 'button-row-remove', + pk, + '{% trans "Remove row" %}', + ); + + delete_button += ''; + + var html = ` + + + ${thumb} ${line_item.part_detail.full_name} + + + ${line_item.supplier_part_detail.SKU} + + + ${line_item.quantity} + + + ${line_item.received} + + + ${quantity_input} + + + STATUS + + + ${destination_input} + + + ${delete_button} + + `; + + return html; + } + + var table_entries = ''; + + line_items.forEach(function(item) { + table_entries += renderLineItem(item); + }); + + var html = ``; + + // Add table + html += ` + + + + {% trans "Part" %} + {% trans "Order Code" %} + {% trans "On Order" %} + {% trans "Received" %} + {% trans "Receive" %} + {% trans "Status" %} + {% trans "Destination" %} + + + + + ${table_entries} + + + `; + + constructForm(`/api/order/po/${order_id}/receive/`, { + method: 'POST', + fields: { + location: {}, + }, + preFormContent: html, + confirm: true, + confirmMessage: '{% trans "Confirm receipt of items" %}', + title: '{% trans "Receive Purchase Order Items" %}', + afterRender: function(fields, opts) { + // TODO + }, + onSubmit: function(fields, opts) { + // TODO + } + }); +} + + function editPurchaseOrderLineItem(e) { /* Edit a purchase order line item in a modal form. @@ -618,7 +758,7 @@ function loadPurchaseOrderLineItemTable(table, options={}) { } if (options.allow_receive && row.received < row.quantity) { - html += makeIconButton('fa-clipboard-check', 'button-line-receive', pk, '{% trans "Receive line item" %}'); + html += makeIconButton('fa-sign-in-alt', 'button-line-receive', pk, '{% trans "Receive line item" %}'); } html += ``;