Render extra line table for return order

- Refactor existing functions into a single generic function
- Reduces repeated JS code a lot
This commit is contained in:
Oliver 2023-03-16 16:09:18 +11:00
parent 3803d30be6
commit 153b9c0abe
6 changed files with 273 additions and 416 deletions

View File

@ -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',

View File

@ -13,11 +13,42 @@
<div class='panel panel-hidden' id='panel-order-details'>
<div class='panel-heading'>
<h4>{% trans "Order Details" %}</h4>
{% include "spacer.html" %}
<div class='d-flex flex-wrap'>
<h4>{% trans "Line Items" %}</h4>
{% include "spacer.html" %}
<!-- TODO: Actions -->
</div>
</div>
<div class='panel-content'>
<!-- TODO: Order details here -->
<div id='order-toolbar-buttons' class='btn-group' style='float: right;'>
<div class='btn-group'>
{% include "filter_list.html" with id="return-order-lines" %}
</div>
</div>
<table class='table table-striped table-condensed' id='return-order-lines-table' data-toolbar='#order-toolbar-buttons'>
</table>
</div>
<div class='panel-heading'>
<div class='d-flex flex-wrap'>
<h4>{% trans "Extra Lines" %}</h4>
{% include "spacer.html" %}
<div class='btn-group' role='group'>
{% if roles.return_order.change %}
<button type='button' class='btn btn-success' id='new-return-order-extra-line'>
<span class='fas fa-plus-circle'></span> {% trans "Add Extra Line" %}
</button>
{% endif %}
</div>
</div>
</div>
<div class='panel-content'>
<div id='order-extra-toolbar-buttons' class='btn-group' style='float: right;'>
<div class='btn-group'>
{% include "filter_list.html" with id="return-order-extra-lines" %}
</div>
</div>
<table class='table table-striped table-condensed' id='return-order-extra-lines-table' data-toolbar='#order-extra-toolbar-buttons'>
</table>
</div>
</div>
@ -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

View File

@ -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',

View File

@ -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 = `<div class='btn-group float-right' role='group'>`;
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 += `</div>`;
return html;
}
},
]
})
}

View File

@ -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 = `<div class='btn-group float-right' role='group'>`;
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 += `</div>`;
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,
});
}

View File

@ -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 = `<div class='btn-group float-right' role='group'>`;
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 += `</div>`;
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,
});
}