From 153b9c0abe9af1cef1486659d80781d89fc86e65 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 16 Mar 2023 16:09:18 +1100 Subject: [PATCH] Render extra line table for return order - Refactor existing functions into a single generic function - Reduces repeated JS code a lot --- .../order/purchase_order_detail.html | 28 +-- .../templates/order/return_order_detail.html | 52 ++++- .../templates/order/sales_order_detail.html | 24 ++- InvenTree/templates/js/translated/order.js | 195 +++++++++++++++++ .../templates/js/translated/purchase_order.js | 196 ------------------ .../templates/js/translated/sales_order.js | 194 ----------------- 6 files changed, 273 insertions(+), 416 deletions(-) diff --git a/InvenTree/order/templates/order/purchase_order_detail.html b/InvenTree/order/templates/order/purchase_order_detail.html index a7cceb0d8a..7743e6c630 100644 --- a/InvenTree/order/templates/order/purchase_order_detail.html +++ b/InvenTree/order/templates/order/purchase_order_detail.html @@ -259,19 +259,21 @@ $("#new-po-extra-line").click(function() { }); }); -loadPurchaseOrderExtraLineTable( - '#po-extra-lines-table', - { - order: {{ order.pk }}, - status: {{ order.status }}, - {% if order.is_pending %} - pending: true, - {% endif %} - {% if roles.purchase_order.change %} - allow_edit: true, - {% endif %} - } -); +loadExtraLineTable({ + table: '#po-extra-lines-table', + order: {{ order.pk }}, + url: '{% url "api-po-extra-line-list" %}', + name: 'purchaseorderextraline', + filtertarget: '#filter-list-purchase-order-extra-lines', + {% settings_value "PURCHASEORDER_EDIT_COMPLETED_ORDERS" as allow_edit %} + {% if order.is_pending or allow_edit %} + allow_edit: {% js_bool roles.purchase_order.change %}, + allow_delete: {% js_bool roles.purchase_order.delete %}, + {% else %} + allow_edit: false, + allow_delete: false, + {% endif %} +}); loadOrderTotal( '#poTotalPrice', diff --git a/InvenTree/order/templates/order/return_order_detail.html b/InvenTree/order/templates/order/return_order_detail.html index 8cff9bbf9a..54107d6cf2 100644 --- a/InvenTree/order/templates/order/return_order_detail.html +++ b/InvenTree/order/templates/order/return_order_detail.html @@ -13,11 +13,42 @@
-

{% trans "Order Details" %}

- {% include "spacer.html" %} +
+

{% trans "Line Items" %}

+ {% include "spacer.html" %} + +
- +
+
+ {% include "filter_list.html" with id="return-order-lines" %} +
+
+ +
+
+
+
+

{% trans "Extra Lines" %}

+ {% include "spacer.html" %} +
+ {% if roles.return_order.change %} + + {% endif %} +
+
+
+
+
+
+ {% include "filter_list.html" with id="return-order-extra-lines" %} +
+
+ +
@@ -59,7 +90,20 @@ // Callback function when the 'details' panel is loaded onPanelLoad('order-details', function() { - // TODO + + loadExtraLineTable({ + order: {{ order.pk }}, + url: '{% url "api-return-order-extra-line-list" %}', + table: "#return-order-extra-lines-table", + name: 'returnorderextralines', + filtertarget: '#filter-list-return-order-extra-lines', + allow_edit: {% js_bool roles.return_order.change %}, + allow_delete: {% js_bool roles.return_order.delete %}, + }); + + $('#new-return-order-extra-line').click(function() { + // TODO: Create new return order extra line item + }); }); // Callback function when the 'notes' panel is loaded diff --git a/InvenTree/order/templates/order/sales_order_detail.html b/InvenTree/order/templates/order/sales_order_detail.html index 269a1f1397..864c112c3f 100644 --- a/InvenTree/order/templates/order/sales_order_detail.html +++ b/InvenTree/order/templates/order/sales_order_detail.html @@ -289,15 +289,21 @@ }); }); - loadSalesOrderExtraLineTable( - '#so-extra-lines-table', - { - order: {{ order.pk }}, - status: {{ order.status }}, - {% if roles.sales_order.change %}allow_edit: true,{% endif %} - {% if order.is_pending %}pending: true,{% endif %} - } - ); + loadExtraLineTable({ + order: {{ order.pk }}, + table: '#so-extra-lines-table', + url: '{% url "api-so-extra-line-list" %}', + name: 'salesorderextraline', + filtertarget: '#filter-list-sales-order-extra-lines', + {% settings_value "SALESORDER_EDIT_COMPLETED_ORDERS" as allow_edit %} + {% if order.is_pending or allow_edit %} + allow_edit: {% js_bool roles.sales_order.change %}, + allow_delete: {% js_bool roles.sales_order.delete %}, + {% else %} + allow_edit: false, + allow_delete: false, + {% endif %} + }); loadOrderTotal( '#soTotalPrice', diff --git a/InvenTree/templates/js/translated/order.js b/InvenTree/templates/js/translated/order.js index b1fc49639d..d255f45c25 100644 --- a/InvenTree/templates/js/translated/order.js +++ b/InvenTree/templates/js/translated/order.js @@ -14,6 +14,7 @@ removeOrderRowFromOrderWizard, removePurchaseOrderLineItem, loadOrderTotal, + loadExtraLineTable, extraLineFields, reloadTotal, */ @@ -122,3 +123,197 @@ function reloadTotal() { } ); }; + + +/* + * Load a table displaying "extra" line items for a given order. + * Used for all external order types (e.g. PurchaseOrder / SalesOrder / ReturnOrder) + * + * options: + * - table: The DOM ID of the table element + * - order: The ID of the related order (required) + * - name: The unique 'name' for this table + * - url: The API URL for the extra line item model (required) + * - filtertarget: The DOM ID for the filter list element + */ +function loadExtraLineTable(options={}) { + + const table = options.table; + + options.params = options.params || {}; + + // Filtering + options.params.order = options.order; + + var filters = {}; + + if (options.name) { + filters = loadTableFilters(options.name); + } + + for (var key in options.params) { + filters[key] = options.params[key]; + } + + setupFilterList( + options.name, + $(table), + options.filtertarget, + { + download: true + } + ); + + // Helper function to reload table + function reloadExtraLineTable() { + $(table).bootstrapTable('refresh'); + reloadTotal(); + } + + // Configure callback functions once the table is loaded + function setupCallbacks() { + + if (options.allow_edit) { + + // Callback to duplicate line item + $(table).find('.button-duplicate').click(function() { + var pk = $(this).attr('pk'); + + inventreeGet(`${options.url}${pk}/`, {}, { + success: function(data) { + + var fields = extraLineFields(); + + constructForm(options.url, { + method: 'POST', + fields: fields, + data: data, + title: '{% trans "Duplicate Line" %}', + onSuccess: reloadExtraLineTable, + }); + } + }); + }); + + // Callback to edit line item + // Callback for editing lines + $(table).find('.button-edit').click(function() { + var pk = $(this).attr('pk'); + + constructForm(`${options.url}${pk}/`, { + fields: extraLineFields(), + title: '{% trans "Edit Line" %}', + onSuccess: reloadExtraLineTable, + }); + }); + } + + if (options.allow_delete) { + // Callback for deleting lines + $(table).find('.button-delete').click(function() { + var pk = $(this).attr('pk'); + + constructForm(`${options.url}${pk}/`, { + method: 'DELETE', + title: '{% trans "Delete Line" %}', + onSuccess: reloadExtraLineTable, + }); + }); + } + } + + $(table).inventreeTable({ + url: options.url, + name: options.name, + sidePagination: 'server', + onPostBody: setupCallbacks, + formatNoMatches: function() { + return '{% trans "No line items found" %}'; + }, + queryParams: filters, + original: options.params, + showFooter: true, + uniqueId: 'pk', + columns: [ + { + sortable: true, + field: 'reference', + title: '{% trans "Reference" %}', + switchable: false, + }, + { + sortable: true, + switchable: false, + field: 'quantity', + title: '{% trans "Quantity" %}', + footerFormatter: function(data) { + return data.map(function(row) { + return +row['quantity']; + }).reduce(function(sum, i) { + return sum + i; + }, 0); + }, + }, + { + sortable: true, + field: 'price', + title: '{% trans "Unit Price" %}', + formatter: function(value, row) { + return formatCurrency(row.price, { + currency: row.price_currency, + }); + } + }, + { + field: 'total_price', + sortable: true, + switchable: true, + title: '{% trans "Total Price" %}', + formatter: function(value, row) { + return formatCurrency(row.price * row.quantity, { + currency: row.price_currency, + }); + }, + footerFormatter: function(data) { + return calculateTotalPrice( + data, + function(row) { + return row.price ? row.price * row.quantity : null; + }, + function(row) { + return row.price_currency; + } + ); + } + }, + { + field: 'notes', + title: '{% trans "Notes" %}', + }, + { + field: 'buttons', + switchable: false, + formatter: function(value, row, index, field) { + + var html = `
`; + + if (options.allow_edit || options.allow_delete) { + var pk = row.pk; + + if (options.allow_edit) { + html += makeIconButton('fa-clone', 'button-duplicate', pk, '{% trans "Duplicate line" %}'); + html += makeIconButton('fa-edit icon-blue', 'button-edit', pk, '{% trans "Edit line" %}'); + } + + if (options.allow_delete) { + html += makeIconButton('fa-trash-alt icon-red', 'button-delete', pk, '{% trans "Delete line" %}', ); + } + } + + html += `
`; + return html; + } + }, + ] + }) +} diff --git a/InvenTree/templates/js/translated/purchase_order.js b/InvenTree/templates/js/translated/purchase_order.js index 85df6c4a76..f3586cfb96 100644 --- a/InvenTree/templates/js/translated/purchase_order.js +++ b/InvenTree/templates/js/translated/purchase_order.js @@ -28,7 +28,6 @@ editPurchaseOrderLineItem, issuePurchaseOrder, loadPurchaseOrderLineItemTable, - loadPurchaseOrderExtraLineTable loadPurchaseOrderTable, newPurchaseOrderFromOrderWizard, newSupplierPartFromOrderWizard, @@ -2085,198 +2084,3 @@ function loadPurchaseOrderLineItemTable(table, options={}) { ); } - - -/** - * Load a table displaying lines for a particular PurchaseOrder - * - * @param {String} table : HTML ID tag e.g. '#table' - * @param {Object} options : object which contains: - * - order {integer} : pk of the PurchaseOrder - * - status: {integer} : status code for the order - */ -function loadPurchaseOrderExtraLineTable(table, options={}) { - - options.table = table; - - if (!options.pending && !global_settings.PURCHASEORDER_EDIT_COMPLETED_ORDERS) { - options.allow_edit = false; - } - - options.params = options.params || {}; - - if (!options.order) { - console.error('function called without order ID'); - return; - } - - if (!options.status) { - console.error('function called without order status'); - return; - } - - options.params.order = options.order; - options.params.part_detail = true; - options.params.allocations = true; - - var filters = loadTableFilters('purchaseorderextraline'); - - for (var key in options.params) { - filters[key] = options.params[key]; - } - - options.url = options.url || '{% url "api-po-extra-line-list" %}'; - - var filter_target = options.filter_target || '#filter-list-purchase-order-extra-lines'; - - setupFilterList('purchaseorderextraline', $(table), filter_target, {download: true}); - - // Table columns to display - var columns = [ - { - sortable: true, - field: 'reference', - title: '{% trans "Reference" %}', - switchable: true, - }, - { - sortable: true, - field: 'quantity', - title: '{% trans "Quantity" %}', - footerFormatter: function(data) { - return data.map(function(row) { - return +row['quantity']; - }).reduce(function(sum, i) { - return sum + i; - }, 0); - }, - switchable: false, - }, - { - sortable: true, - field: 'price', - title: '{% trans "Unit Price" %}', - formatter: function(value, row) { - return formatCurrency(row.price, { - currency: row.price_currency, - }); - } - }, - { - field: 'total_price', - sortable: true, - title: '{% trans "Total Price" %}', - formatter: function(value, row) { - return formatCurrency(row.price * row.quantity, { - currency: row.price_currency, - }); - }, - footerFormatter: function(data) { - return calculateTotalPrice( - data, - function(row) { - return row.price ? row.price * row.quantity : null; - }, - function(row) { - return row.price_currency; - } - ); - } - } - ]; - - columns.push({ - field: 'notes', - title: '{% trans "Notes" %}', - }); - - columns.push({ - field: 'buttons', - switchable: false, - formatter: function(value, row, index, field) { - - var html = `
`; - - var pk = row.pk; - - if (options.allow_edit) { - html += makeIconButton('fa-clone', 'button-duplicate', pk, '{% trans "Duplicate line" %}'); - html += makeIconButton('fa-edit icon-blue', 'button-edit', pk, '{% trans "Edit line" %}'); - html += makeIconButton('fa-trash-alt icon-red', 'button-delete', pk, '{% trans "Delete line" %}', ); - } - - html += `
`; - - return html; - } - }); - - function reloadTable() { - $(table).bootstrapTable('refresh'); - reloadTotal(); - } - - // Configure callback functions once the table is loaded - function setupCallbacks() { - - // Callback for duplicating lines - $(table).find('.button-duplicate').click(function() { - var pk = $(this).attr('pk'); - - inventreeGet(`/api/order/po-extra-line/${pk}/`, {}, { - success: function(data) { - - var fields = extraLineFields(); - - constructForm('{% url "api-po-extra-line-list" %}', { - method: 'POST', - fields: fields, - data: data, - title: '{% trans "Duplicate Line" %}', - onSuccess: function(response) { - $(table).bootstrapTable('refresh'); - } - }); - } - }); - }); - - // Callback for editing lines - $(table).find('.button-edit').click(function() { - var pk = $(this).attr('pk'); - - constructForm(`/api/order/po-extra-line/${pk}/`, { - fields: extraLineFields(), - title: '{% trans "Edit Line" %}', - onSuccess: reloadTable, - }); - }); - - // Callback for deleting lines - $(table).find('.button-delete').click(function() { - var pk = $(this).attr('pk'); - - constructForm(`/api/order/po-extra-line/${pk}/`, { - method: 'DELETE', - title: '{% trans "Delete Line" %}', - onSuccess: reloadTable, - }); - }); - } - - $(table).inventreeTable({ - onPostBody: setupCallbacks, - name: 'purchaseorderextraline', - sidePagination: 'client', - formatNoMatches: function() { - return '{% trans "No matching line" %}'; - }, - queryParams: filters, - original: options.params, - url: options.url, - showFooter: true, - uniqueId: 'pk', - detailViewByClick: false, - columns: columns, - }); -} diff --git a/InvenTree/templates/js/translated/sales_order.js b/InvenTree/templates/js/translated/sales_order.js index 27a39fd7a8..8bb9ba9a84 100644 --- a/InvenTree/templates/js/translated/sales_order.js +++ b/InvenTree/templates/js/translated/sales_order.js @@ -29,7 +29,6 @@ exportOrder, loadSalesOrderAllocationTable, loadSalesOrderLineItemTable, - loadSalesOrderExtraLineTable loadSalesOrderShipmentTable, loadSalesOrderTable, orderParts, @@ -2143,196 +2142,3 @@ function loadSalesOrderLineItemTable(table, options={}) { columns: columns, }); } - - -/** - * Load a table displaying lines for a particular SalesOrder - * - * @param {String} table : HTML ID tag e.g. '#table' - * @param {Object} options : object which contains: - * - order {integer} : pk of the SalesOrder - * - status: {integer} : status code for the order - */ -function loadSalesOrderExtraLineTable(table, options={}) { - - options.table = table; - - if (!options.pending && !global_settings.SALESORDER_EDIT_COMPLETED_ORDERS) { - options.allow_edit = false; - } - - options.params = options.params || {}; - - if (!options.order) { - console.error('function called without order ID'); - return; - } - - if (!options.status) { - console.error('function called without order status'); - return; - } - - options.params.order = options.order; - options.params.part_detail = true; - options.params.allocations = true; - - var filters = loadTableFilters('salesorderextraline'); - - for (var key in options.params) { - filters[key] = options.params[key]; - } - - options.url = options.url || '{% url "api-so-extra-line-list" %}'; - - var filter_target = options.filter_target || '#filter-list-sales-order-extra-lines'; - - setupFilterList('salesorderextraline', $(table), filter_target, {download: true}); - - // Table columns to display - var columns = [ - { - sortable: true, - field: 'reference', - title: '{% trans "Reference" %}', - switchable: true, - }, - { - sortable: true, - field: 'quantity', - title: '{% trans "Quantity" %}', - footerFormatter: function(data) { - return data.map(function(row) { - return +row['quantity']; - }).reduce(function(sum, i) { - return sum + i; - }, 0); - }, - switchable: false, - }, - { - sortable: true, - field: 'price', - title: '{% trans "Unit Price" %}', - formatter: function(value, row) { - return formatCurrency(row.price, { - currency: row.price_currency, - }); - } - }, - { - field: 'total_price', - sortable: true, - title: '{% trans "Total Price" %}', - formatter: function(value, row) { - return formatCurrency(row.price * row.quantity, { - currency: row.price_currency, - }); - }, - footerFormatter: function(data) { - return calculateTotalPrice( - data, - function(row) { - return row.price ? row.price * row.quantity : null; - }, - function(row) { - return row.price_currency; - } - ); - } - } - ]; - - columns.push({ - field: 'notes', - title: '{% trans "Notes" %}', - }); - - columns.push({ - field: 'buttons', - switchable: false, - formatter: function(value, row, index, field) { - - var html = `
`; - - if (options.allow_edit) { - var pk = row.pk; - html += makeIconButton('fa-clone', 'button-duplicate', pk, '{% trans "Duplicate line" %}'); - html += makeIconButton('fa-edit icon-blue', 'button-edit', pk, '{% trans "Edit line" %}'); - html += makeIconButton('fa-trash-alt icon-red', 'button-delete', pk, '{% trans "Delete line" %}', ); - } - - html += `
`; - return html; - } - }); - - function reloadTable() { - $(table).bootstrapTable('refresh'); - reloadTotal(); - } - - // Configure callback functions once the table is loaded - function setupCallbacks() { - - // Callback for duplicating lines - $(table).find('.button-duplicate').click(function() { - var pk = $(this).attr('pk'); - - inventreeGet(`/api/order/so-extra-line/${pk}/`, {}, { - success: function(data) { - - var fields = extraLineFields(); - - constructForm('{% url "api-so-extra-line-list" %}', { - method: 'POST', - fields: fields, - data: data, - title: '{% trans "Duplicate Line" %}', - onSuccess: function(response) { - $(table).bootstrapTable('refresh'); - } - }); - } - }); - }); - - // Callback for editing lines - $(table).find('.button-edit').click(function() { - var pk = $(this).attr('pk'); - - constructForm(`/api/order/so-extra-line/${pk}/`, { - fields: extraLineFields(), - title: '{% trans "Edit Line" %}', - onSuccess: reloadTable, - }); - }); - - // Callback for deleting lines - $(table).find('.button-delete').click(function() { - var pk = $(this).attr('pk'); - - constructForm(`/api/order/so-extra-line/${pk}/`, { - method: 'DELETE', - title: '{% trans "Delete Line" %}', - onSuccess: reloadTable, - }); - }); - } - - $(table).inventreeTable({ - onPostBody: setupCallbacks, - name: 'salesorderextraline', - sidePagination: 'client', - formatNoMatches: function() { - return '{% trans "No matching lines" %}'; - }, - queryParams: filters, - original: options.params, - url: options.url, - showFooter: true, - uniqueId: 'pk', - detailViewByClick: false, - columns: columns, - }); -}