From 836879828038baf5583cf64d7b19703c2e77f47f Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 8 Sep 2021 12:51:49 +1000 Subject: [PATCH] Move po-line-item-table into javascript file - for better linting --- .../order/purchase_order_detail.html | 257 +----------------- InvenTree/templates/js/translated/order.js | 257 +++++++++++++++++- 2 files changed, 271 insertions(+), 243 deletions(-) diff --git a/InvenTree/order/templates/order/purchase_order_detail.html b/InvenTree/order/templates/order/purchase_order_detail.html index 8e7f77bad1..02a4cd35f1 100644 --- a/InvenTree/order/templates/order/purchase_order_detail.html +++ b/InvenTree/order/templates/order/purchase_order_detail.html @@ -207,251 +207,24 @@ $('#new-po-line').click(function() { {% endif %} -function reloadTable() { - $("#po-line-table").bootstrapTable("refresh"); -} - -function setupCallbacks() { - // Setup callbacks for the line buttons - - var table = $("#po-line-table"); - +loadPurchaseOrderLineItemTable('#po-line-table', { + order: {{ order.pk }}, + supplier: {{ order.supplier.pk }}, {% if order.status == PurchaseOrderStatus.PENDING %} - table.find(".button-line-edit").click(function() { - var pk = $(this).attr('pk'); - - constructForm(`/api/order/po-line/${pk}/`, { - fields: { - part: { - filters: { - part_detail: true, - supplier_detail: true, - supplier: {{ order.supplier.pk }}, - } - }, - quantity: {}, - reference: {}, - purchase_price: {}, - purchase_price_currency: {}, - destination: {}, - notes: {}, - }, - title: '{% trans "Edit Line Item" %}', - onSuccess: reloadTable, - }); - }); - - table.find(".button-line-delete").click(function() { - var pk = $(this).attr('pk'); - - constructForm(`/api/order/po-line/${pk}/`, { - method: 'DELETE', - title: '{% trans "Delete Line Item" %}', - onSuccess: reloadTable, - }); - }); + allow_edit: true, + {% else %} + allow_edit: false, + {% endif %} + {% if order.status == PurchaseOrderStatus.PLACED and roles.purchase_order.change %} + allow_receive: true, + {% else %} + allow_receive: false, {% endif %} - - table.find(".button-line-receive").click(function() { - var pk = $(this).attr('pk'); - - launchModalForm("{% url 'po-receive' order.id %}", { - success: reloadTable, - data: { - line: pk, - }, - secondary: [ - { - field: 'location', - label: '{% trans "New Location" %}', - title: '{% trans "Create new stock location" %}', - url: "{% url 'stock-location-create' %}", - }, - ] - }); - }); - -} - -$("#po-line-table").inventreeTable({ - onPostBody: setupCallbacks, - name: 'purchaseorderlines', - sidePagination: 'server', - formatNoMatches: function() { return "{% trans 'No line items found' %}"; }, - queryParams: { - order: {{ order.id }}, - part_detail: true, - }, - url: "{% url 'api-po-line-list' %}", - showFooter: true, - columns: [ - { - field: 'pk', - title: 'ID', - visible: false, - switchable: false, - }, - { - field: 'part', - sortable: true, - sortName: 'part_name', - title: '{% trans "Part" %}', - switchable: false, - formatter: function(value, row, index, field) { - if (row.part) { - return imageHoverIcon(row.part_detail.thumbnail) + renderLink(row.part_detail.full_name, `/part/${row.part_detail.pk}/`); - } else { - return '-'; - } - }, - footerFormatter: function() { - return '{% trans "Total" %}' - } - }, - { - field: 'part_detail.description', - title: '{% trans "Description" %}', - }, - { - sortable: true, - sortName: 'SKU', - field: 'supplier_part_detail.SKU', - title: '{% trans "SKU" %}', - formatter: function(value, row, index, field) { - if (value) { - return renderLink(value, `/supplier-part/${row.part}/`); - } else { - return '-'; - } - }, - }, - { - sortable: true, - sortName: 'MPN', - field: 'supplier_part_detail.manufacturer_part_detail.MPN', - title: '{% trans "MPN" %}', - formatter: function(value, row, index, field) { - if (row.supplier_part_detail && row.supplier_part_detail.manufacturer_part) { - return renderLink(value, `/manufacturer-part/${row.supplier_part_detail.manufacturer_part}/`); - } else { - return "-"; - } - }, - }, - { - sortable: true, - field: 'reference', - title: '{% trans "Reference" %}', - }, - { - 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) - } - }, - { - sortable: true, - field: 'purchase_price', - title: '{% trans "Unit Price" %}', - formatter: function(value, row) { - return row.purchase_price_string || row.purchase_price; - } - }, - { - field: 'total_price', - sortable: true, - field: 'total_price', - title: '{% trans "Total price" %}', - formatter: function(value, row) { - var total = row.purchase_price * row.quantity; - var formatter = new Intl.NumberFormat('en-US', {style: 'currency', currency: row.purchase_price_currency}); - return formatter.format(total) - }, - footerFormatter: function(data) { - var total = data.map(function (row) { - return +row['purchase_price']*row['quantity'] - }).reduce(function (sum, i) { - return sum + i - }, 0) - var currency = (data.slice(-1)[0] && data.slice(-1)[0].purchase_price_currency) || 'USD'; - var formatter = new Intl.NumberFormat('en-US', {style: 'currency', currency: currency}); - return formatter.format(total) - } - }, - { - sortable: false, - field: 'received', - switchable: false, - title: '{% trans "Received" %}', - formatter: function(value, row, index, field) { - return makeProgressBar(row.received, row.quantity, { - id: `order-line-progress-${row.pk}`, - }); - }, - sorter: function(valA, valB, rowA, rowB) { - - if (rowA.received == 0 && rowB.received == 0) { - return (rowA.quantity > rowB.quantity) ? 1 : -1; - } - - var progressA = parseFloat(rowA.received) / rowA.quantity; - var progressB = parseFloat(rowB.received) / rowB.quantity; - - return (progressA < progressB) ? 1 : -1; - } - }, - { - field: 'destination', - title: '{% trans "Destination" %}', - formatter: function(value, row) { - if (value) { - return renderLink(row.destination_detail.pathstring, `/stock/location/${value}/`); - } else { - return '-'; - } - } - }, - { - field: 'notes', - title: '{% trans "Notes" %}', - }, - { - switchable: false, - field: 'buttons', - title: '', - formatter: function(value, row, index, field) { - var html = `
`; - - var pk = row.pk; - - {% if order.status == PurchaseOrderStatus.PENDING and roles.purchase_order.delete %} - html += makeIconButton('fa-edit icon-blue', 'button-line-edit', pk, '{% trans "Edit line item" %}'); - html += makeIconButton('fa-trash-alt icon-red', 'button-line-delete', pk, '{% trans "Delete line item" %}'); - {% endif %} - - {% if order.status == PurchaseOrderStatus.PLACED and roles.purchase_order.change %} - if (row.received < row.quantity) { - html += makeIconButton('fa-clipboard-check', 'button-line-receive', pk, '{% trans "Receive line item" %}'); - } - {% endif %} - - html += `
`; - - return html; - }, - } - ] }); - attachNavCallbacks({ - name: 'purchase-order', - default: 'order-items' - }); +attachNavCallbacks({ + name: 'purchase-order', + default: 'order-items' +}); {% endblock %} \ No newline at end of file diff --git a/InvenTree/templates/js/translated/order.js b/InvenTree/templates/js/translated/order.js index 7ebe000f64..4ab6d5b815 100644 --- a/InvenTree/templates/js/translated/order.js +++ b/InvenTree/templates/js/translated/order.js @@ -144,7 +144,6 @@ function newSupplierPartFromOrderWizard(e) { if (!part) { part = $(src).closest('button').attr('part'); - console.log('parent: ' + part); } createSupplierPart({ @@ -367,6 +366,262 @@ function loadPurchaseOrderTable(table, options) { }); } + +/** + * Load a table displaying line items for a particular PurchasesOrder + * @param {String} table - HTML ID tag e.g. '#table' + * @param {Object} options - options which must provide: + * - order (integer PK) + * - supplier (integer PK) + * - allow_edit (boolean) + * - allow_receive (boolean) + */ +function loadPurchaseOrderLineItemTable(table, options={}) { + + function setupCallbacks() { + if (options.allow_edit) { + $(table).find('.button-line-edit').click(function() { + var pk = $(this).attr('pk'); + + constructForm(`/api/order/po-line/${pk}/`, { + fields: { + part: { + filters: { + part_detail: true, + supplier_detail: true, + supplier: options.supplier, + } + }, + quantity: {}, + reference: {}, + purchase_price: {}, + purchase_price_currency: {}, + destination: {}, + notes: {}, + }, + title: '{% trans "Edit Line Item" %}', + onSuccess: function() { + $(table).bootstrapTable('refresh'); + } + }); + }); + + $(table).find('.button-line-delete').click(function() { + var pk = $(this).attr('pk'); + + constructForm(`/api/order/po-line/${pk}/`, { + method: 'DELETE', + title: '{% trans "Delete Line Item" %}', + onSuccess: function() { + $(table).bootstrapTable('refresh'); + } + }); + }); + } + + if (options.allow_receive) { + $(table).find('.button-line-receive').click(function() { + var pk = $(this).attr('pk'); + + launchModalForm(`/order/purchase-order/${options.order}/receive/`, { + success: function() { + $(table).bootstrapTable('refresh'); + }, + data: { + line: pk, + }, + secondary: [ + { + field: 'location', + label: '{% trans "New Location" %}', + title: '{% trans "Create new stock location" %}', + url: "{% url 'stock-location-create' %}", + }, + ] + }); + }); + } + } + + $(table).inventreeTable({ + onPostBody: setupCallbacks, + name: 'purchaseorderlines', + sidePagination: 'server', + formatNoMatches: function() { + return '{% trans "No line items found" %}'; + }, + queryParams: { + order: options.order, + part_detail: true + }, + url: "{% url 'api-po-line-list' %}", + showFooter: true, + columns: [ + { + field: 'pk', + title: 'ID', + visible: false, + switchable: false, + }, + { + field: 'part', + sortable: true, + sortName: 'part_name', + title: '{% trans "Part" %}', + switchable: false, + formatter: function(value, row, index, field) { + if (row.part) { + return imageHoverIcon(row.part_detail.thumbnail) + renderLink(row.part_detail.full_name, `/part/${row.part_detail.pk}/`); + } else { + return '-'; + } + }, + footerFormatter: function() { + return '{% trans "Total" %}' + } + }, + { + field: 'part_detail.description', + title: '{% trans "Description" %}', + }, + { + sortable: true, + sortName: 'SKU', + field: 'supplier_part_detail.SKU', + title: '{% trans "SKU" %}', + formatter: function(value, row, index, field) { + if (value) { + return renderLink(value, `/supplier-part/${row.part}/`); + } else { + return '-'; + } + }, + }, + { + sortable: true, + sortName: 'MPN', + field: 'supplier_part_detail.manufacturer_part_detail.MPN', + title: '{% trans "MPN" %}', + formatter: function(value, row, index, field) { + if (row.supplier_part_detail && row.supplier_part_detail.manufacturer_part) { + return renderLink(value, `/manufacturer-part/${row.supplier_part_detail.manufacturer_part}/`); + } else { + return "-"; + } + }, + }, + { + sortable: true, + field: 'reference', + title: '{% trans "Reference" %}', + }, + { + 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) + } + }, + { + sortable: true, + field: 'purchase_price', + title: '{% trans "Unit Price" %}', + formatter: function(value, row) { + return row.purchase_price_string || row.purchase_price; + } + }, + { + field: 'total_price', + sortable: true, + field: 'total_price', + title: '{% trans "Total price" %}', + formatter: function(value, row) { + var total = row.purchase_price * row.quantity; + var formatter = new Intl.NumberFormat('en-US', {style: 'currency', currency: row.purchase_price_currency}); + return formatter.format(total) + }, + footerFormatter: function(data) { + var total = data.map(function (row) { + return +row['purchase_price']*row['quantity'] + }).reduce(function (sum, i) { + return sum + i + }, 0) + var currency = (data.slice(-1)[0] && data.slice(-1)[0].purchase_price_currency) || 'USD'; + var formatter = new Intl.NumberFormat('en-US', {style: 'currency', currency: currency}); + return formatter.format(total) + } + }, + { + sortable: false, + field: 'received', + switchable: false, + title: '{% trans "Received" %}', + formatter: function(value, row, index, field) { + return makeProgressBar(row.received, row.quantity, { + id: `order-line-progress-${row.pk}`, + }); + }, + sorter: function(valA, valB, rowA, rowB) { + + if (rowA.received == 0 && rowB.received == 0) { + return (rowA.quantity > rowB.quantity) ? 1 : -1; + } + + var progressA = parseFloat(rowA.received) / rowA.quantity; + var progressB = parseFloat(rowB.received) / rowB.quantity; + + return (progressA < progressB) ? 1 : -1; + } + }, + { + field: 'destination', + title: '{% trans "Destination" %}', + formatter: function(value, row) { + if (value) { + return renderLink(row.destination_detail.pathstring, `/stock/location/${value}/`); + } else { + return '-'; + } + } + }, + { + field: 'notes', + title: '{% trans "Notes" %}', + }, + { + switchable: false, + field: 'buttons', + title: '', + formatter: function(value, row, index, field) { + var html = `
`; + + var pk = row.pk; + + if (options.allow_edit) { + html += makeIconButton('fa-edit icon-blue', 'button-line-edit', pk, '{% trans "Edit line item" %}'); + html += makeIconButton('fa-trash-alt icon-red', 'button-line-delete', pk, '{% trans "Delete line item" %}'); + } + + if (options.allow_receive && row.received < row.quantity) { + html += makeIconButton('fa-clipboard-check', 'button-line-receive', pk, '{% trans "Receive line item" %}'); + } + + html += `
`; + + return html; + }, + } + ] + }); + +} + + function loadSalesOrderTable(table, options) { options.params = options.params || {};