diff --git a/InvenTree/order/templates/order/sales_order_detail.html b/InvenTree/order/templates/order/sales_order_detail.html index 30799e2296..bd853702c4 100644 --- a/InvenTree/order/templates/order/sales_order_detail.html +++ b/InvenTree/order/templates/order/sales_order_detail.html @@ -158,467 +158,38 @@ $("#so-lines-table").bootstrapTable("refresh"); } -$("#new-so-line").click(function() { + $("#new-so-line").click(function() { - constructForm('{% url "api-so-line-list" %}', { - fields: { - order: { - value: {{ order.pk }}, - hidden: true, - }, - part: {}, - quantity: {}, - reference: {}, - sale_price: {}, - sale_price_currency: {}, - notes: {}, - }, - method: 'POST', - title: '{% trans "Add Line Item" %}', - onSuccess: reloadTable, - }); -}); - -{% if order.status == SalesOrderStatus.PENDING %} -function showAllocationSubTable(index, row, element) { - // Construct a table showing stock items which have been allocated against this line item - - var html = `
`; - - element.html(html); - - var lineItem = row; - - var table = $(`#allocation-table-${row.pk}`); - - table.bootstrapTable({ - data: row.allocations, - showHeader: false, - columns: [ - { - width: '50%', - field: 'allocated', - title: '{% trans "Quantity" %}', - formatter: function(value, row, index, field) { - var text = ''; - - if (row.serial != null && row.quantity == 1) { - text = `{% trans "Serial Number" %}: ${row.serial}`; - } else { - text = `{% trans "Quantity" %}: ${row.quantity}`; - } - - return renderLink(text, `/stock/item/${row.item}/`); - }, - }, - { - field: 'location', - title: 'Location', - formatter: function(value, row, index, field) { - return renderLink(row.location_path, `/stock/location/${row.location}/`); - }, - }, - { - field: 'po' - }, - { - field: 'buttons', - title: '{% trans "Actions" %}', - formatter: function(value, row, index, field) { - - var html = "
"; - var pk = row.pk; - - {% if order.status == SalesOrderStatus.PENDING %} - html += makeIconButton('fa-edit icon-blue', 'button-allocation-edit', pk, '{% trans "Edit stock allocation" %}'); - html += makeIconButton('fa-trash-alt icon-red', 'button-allocation-delete', pk, '{% trans "Delete stock allocation" %}'); - {% endif %} - - html += "
"; - - return html; - }, - }, - ], - }); - - table.find(".button-allocation-edit").click(function() { - - var pk = $(this).attr('pk'); - - launchModalForm(`/order/sales-order/allocation/${pk}/edit/`, { - success: reloadTable, - }); - }); - - table.find(".button-allocation-delete").click(function() { - var pk = $(this).attr('pk'); - - launchModalForm(`/order/sales-order/allocation/${pk}/delete/`, { - success: reloadTable, - }); - }); -} -{% endif %} - -function showFulfilledSubTable(index, row, element) { - // Construct a table showing stock items which have been fulfilled against this line item - - var id = `fulfilled-table-${row.pk}`; - var html = `
`; - - element.html(html); - - var lineItem = row; - - $(`#${id}`).bootstrapTable({ - url: "{% url 'api-stock-list' %}", - queryParams: { - part: row.part, - sales_order: {{ order.id }}, - }, - showHeader: false, - columns: [ - { - field: 'pk', - visible: false, - }, - { - field: 'stock', - formatter: function(value, row) { - var text = ''; - if (row.serial && row.quantity == 1) { - text = `{% trans "Serial Number" %}: ${row.serial}`; - } else { - text = `{% trans "Quantity" %}: ${row.quantity}`; - } - - return renderLink(text, `/stock/item/${row.pk}/`); - }, - }, - { - field: 'po' - }, - ], - }); -} - -$("#so-lines-table").inventreeTable({ - formatNoMatches: function() { return "{% trans 'No matching line items' %}"; }, - queryParams: { - order: {{ order.id }}, - part_detail: true, - allocations: true, - }, - sidePagination: 'server', - uniqueId: 'pk', - url: "{% url 'api-so-line-list' %}", - onPostBody: setupCallbacks, - {% if order.status == SalesOrderStatus.PENDING or order.status == SalesOrderStatus.SHIPPED %} - detailViewByClick: true, - detailView: true, - detailFilter: function(index, row) { - {% if order.status == SalesOrderStatus.PENDING %} - return row.allocated > 0; - {% else %} - return row.fulfilled > 0; - {% endif %} - }, - {% if order.status == SalesOrderStatus.PENDING %} - detailFormatter: showAllocationSubTable, - {% else %} - detailFormatter: showFulfilledSubTable, - {% endif %} - {% endif %} - showFooter: true, - columns: [ - { - field: 'pk', - title: '{% trans "ID" %}', - visible: false, - switchable: false, - }, - { - sortable: true, - sortName: 'part__name', - field: 'part', - title: '{% trans "Part" %}', - formatter: function(value, row, index, field) { - if (row.part) { - return imageHoverIcon(row.part_detail.thumbnail) + renderLink(row.part_detail.full_name, `/part/${value}/`); - } else { - return '-'; - } - }, - footerFormatter: function() { - return '{% trans "Total" %}' - }, - }, - { - 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: 'sale_price', - title: '{% trans "Unit Price" %}', - formatter: function(value, row) { - return row.sale_price_string || row.sale_price; - } - }, - { - sortable: true, - title: '{% trans "Total price" %}', - formatter: function(value, row) { - var total = row.sale_price * row.quantity; - var formatter = new Intl.NumberFormat('en-US', {style: 'currency', currency: row.sale_price_currency}); - return formatter.format(total) - }, - footerFormatter: function(data) { - var total = data.map(function (row) { - return +row['sale_price']*row['quantity'] - }).reduce(function (sum, i) { - return sum + i - }, 0) - var currency = (data.slice(-1)[0] && data.slice(-1)[0].sale_price_currency) || 'USD'; - var formatter = new Intl.NumberFormat('en-US', {style: 'currency', currency: currency}); - return formatter.format(total) - } - }, - - { - field: 'allocated', - {% if order.status == SalesOrderStatus.PENDING %} - title: '{% trans "Allocated" %}', - {% else %} - title: '{% trans "Fulfilled" %}', - {% endif %} - formatter: function(value, row, index, field) { - {% if order.status == SalesOrderStatus.PENDING %} - var quantity = row.allocated; - {% else %} - var quantity = row.fulfilled; - {% endif %} - return makeProgressBar(quantity, row.quantity, { - id: `order-line-progress-${row.pk}`, - }); - }, - sorter: function(valA, valB, rowA, rowB) { - {% if order.status == SalesOrderStatus.PENDING %} - var A = rowA.allocated; - var B = rowB.allocated; - {% else %} - var A = rowA.fulfilled; - var B = rowB.fulfilled; - {% endif %} - - if (A == 0 && B == 0) { - return (rowA.quantity > rowB.quantity) ? 1 : -1; - } - - var progressA = parseFloat(A) / rowA.quantity; - var progressB = parseFloat(B) / rowB.quantity; - - return (progressA < progressB) ? 1 : -1; - } - }, - { - field: 'notes', - title: '{% trans "Notes" %}', - }, - { - field: 'po', - title: '{% trans "PO" %}', - formatter: function(value, row, index, field) { - var po_name = ""; - if (row.allocated) { - row.allocations.forEach(function(allocation) { - if (allocation.po != po_name) { - if (po_name) { - po_name = "-"; - } else { - po_name = allocation.po - } - } - }) - } - return `
` + po_name + `
`; - } - }, - {% if order.status == SalesOrderStatus.PENDING %} - { - field: 'buttons', - formatter: function(value, row, index, field) { - - var html = `
`; - - var pk = row.pk; - - if (row.part) { - var part = row.part_detail; - - if (part.trackable) { - html += makeIconButton('fa-hashtag icon-green', 'button-add-by-sn', pk, '{% trans "Allocate serial numbers" %}'); - } - - html += makeIconButton('fa-sign-in-alt icon-green', 'button-add', pk, '{% trans "Allocate stock" %}'); - - if (part.purchaseable) { - html += makeIconButton('fa-shopping-cart', 'button-buy', row.part, '{% trans "Purchase stock" %}'); - } - - if (part.assembly) { - html += makeIconButton('fa-tools', 'button-build', row.part, '{% trans "Build stock" %}'); - } - - html += makeIconButton('fa-dollar-sign icon-green', 'button-price', pk, '{% trans "Calculate price" %}'); - } - - html += makeIconButton('fa-edit icon-blue', 'button-edit', pk, '{% trans "Edit line item" %}'); - html += makeIconButton('fa-trash-alt icon-red', 'button-delete', pk, '{% trans "Delete line item " %}'); - - html += `
`; - - return html; - } - }, - {% endif %} - ], -}); - -function setupCallbacks() { - - var table = $("#so-lines-table"); - - // Set up callbacks for the row buttons - table.find(".button-edit").click(function() { - - var pk = $(this).attr('pk'); - - constructForm(`/api/order/so-line/${pk}/`, { + constructForm('{% url "api-so-line-list" %}', { fields: { + order: { + value: {{ order.pk }}, + hidden: true, + }, + part: {}, quantity: {}, reference: {}, sale_price: {}, sale_price_currency: {}, notes: {}, }, - title: '{% trans "Edit Line Item" %}', + method: 'POST', + title: '{% trans "Add Line Item" %}', onSuccess: reloadTable, }); }); - table.find(".button-delete").click(function() { - var pk = $(this).attr('pk'); - - constructForm(`/api/order/so-line/${pk}/`, { - method: 'DELETE', - title: '{% trans "Delete Line Item" %}', - onSuccess: reloadTable, - }); - }); - - table.find(".button-add-by-sn").click(function() { - var pk = $(this).attr('pk'); - - inventreeGet(`/api/order/so-line/${pk}/`, {}, - { - success: function(response) { - launchModalForm('{% url "so-assign-serials" %}', { - success: reloadTable, - data: { - line: pk, - part: response.part, - } - }); - } - } - ); - }); - - table.find(".button-add").click(function() { - var pk = $(this).attr('pk'); - - launchModalForm(`/order/sales-order/allocation/new/`, { - success: reloadTable, - data: { - line: pk, - }, - }); - }); - - table.find(".button-build").click(function() { - - var pk = $(this).attr('pk'); - - // Extract the row data from the table! - var idx = $(this).closest('tr').attr('data-index'); - - var row = table.bootstrapTable('getData')[idx]; - - var quantity = 1; - - if (row.allocated < row.quantity) { - quantity = row.quantity - row.allocated; + loadSalesOrderLineItemTable( + '#so-lines-table', + { + order: {{ order.pk }}, + status: {{ order.status }}, } - - launchModalForm(`/build/new/`, { - follow: true, - data: { - part: pk, - sales_order: {{ order.id }}, - quantity: quantity, - }, - }); - }); - - table.find(".button-buy").click(function() { - var pk = $(this).attr('pk'); - - launchModalForm("{% url 'order-parts' %}", { - data: { - parts: [pk], - }, - }); - }); - - $(".button-price").click(function() { - var pk = $(this).attr('pk'); - var idx = $(this).closest('tr').attr('data-index'); - var row = table.bootstrapTable('getData')[idx]; - - launchModalForm( - "{% url 'line-pricing' %}", - { - submit_text: '{% trans "Calculate price" %}', - data: { - line_item: pk, - quantity: row.quantity, - }, - buttons: [{name: 'update_price', - title: '{% trans "Update Unit Price" %}'},], - success: reloadTable, - } - ); - }); + ); attachNavCallbacks({ name: 'sales-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 43d4b56936..c9a5d92b5b 100644 --- a/InvenTree/templates/js/translated/order.js +++ b/InvenTree/templates/js/translated/order.js @@ -24,6 +24,7 @@ loadPurchaseOrderLineItemTable, loadPurchaseOrderTable, loadSalesOrderAllocationTable, + loadSalesOrderLineItemTable, loadSalesOrderTable, newPurchaseOrderFromOrderWizard, newSupplierPartFromOrderWizard, @@ -1126,3 +1127,529 @@ function loadSalesOrderAllocationTable(table, options={}) { ] }); } + + +/** + * Display an "allocations" sub table, showing stock items allocated againt a sales order + * @param {*} index + * @param {*} row + * @param {*} element + */ +function showAllocationSubTable(index, row, element, options) { + + // Construct a sub-table element + var html = ` +
+ +
+
`; + + element.html(html); + + var lineItem = row; + + var table = $(`#allocation-table-${row.pk}`); + + // Is the parent SalesOrder pending? + var pending = options.status == {{ SalesOrderStatus.PENDING }}; + + table.bootstrapTable({ + data: row.allocations, + showHeader: false, + columns: [ + { + width: '50%', + field: 'allocated', + title: '{% trans "Quantity" %}', + formatter: function(value, row, index, field) { + var text = ''; + + if (row.serial != null && row.quantity == 1) { + text = `{% trans "Serial Number" %}: ${row.serial}`; + } else { + text = `{% trans "Quantity" %}: ${row.quantity}`; + } + + return renderLink(text, `/stock/item/${row.item}/`); + }, + }, + { + field: 'location', + title: '{% trans "Location" %}', + formatter: function(value, row, index, field) { + return renderLink(row.location_path, `/stock/location/${row.location}/`); + }, + }, + { + field: 'po' + }, + { + field: 'buttons', + title: '{% trans "Actions" %}', + formatter: function(value, row, index, field) { + + var html = `
`; + var pk = row.pk; + + if (pending) { + html += makeIconButton('fa-edit icon-blue', 'button-allocation-edit', pk, '{% trans "Edit stock allocation" %}'); + html += makeIconButton('fa-trash-alt icon-red', 'button-allocation-delete', pk, '{% trans "Delete stock allocation" %}'); + } + + html += "
"; + + return html; + }, + }, + ], + }); + + // Add callbacks for 'edit' buttons + table.find(".button-allocation-edit").click(function() { + + var pk = $(this).attr('pk'); + + // TODO: Migrate to API forms + launchModalForm(`/order/sales-order/allocation/${pk}/edit/`, { + success: reloadTable, + }); + }); + + // Add callbacks for 'delete' buttons + table.find(".button-allocation-delete").click(function() { + var pk = $(this).attr('pk'); + + // TODO: Migrate to API forms + launchModalForm(`/order/sales-order/allocation/${pk}/delete/`, { + success: reloadTable, + }); + }); +} + +/** + * Display a "fulfilled" sub table, showing stock items fulfilled against a purchase order + */ +function showFulfilledSubTable(index, row, element, options) { + // Construct a table showing stock items which have been fulfilled against this line item + + if (!options.order) { + return 'ERROR: Order ID not supplied'; + } + + var id = `fulfilled-table-${row.pk}`; + + var html = ` +
+ +
+
`; + + element.html(html); + + var lineItem = row; + + $(`#${id}`).bootstrapTable({ + url: "{% url 'api-stock-list' %}", + queryParams: { + part: row.part, + sales_order: options.order, + }, + showHeader: false, + columns: [ + { + field: 'pk', + visible: false, + }, + { + field: 'stock', + formatter: function(value, row) { + var text = ''; + if (row.serial && row.quantity == 1) { + text = `{% trans "Serial Number" %}: ${row.serial}`; + } else { + text = `{% trans "Quantity" %}: ${row.quantity}`; + } + + return renderLink(text, `/stock/item/${row.pk}/`); + }, + }, + { + field: 'po' + }, + ], + }); +} + + +/** + * Load a table displaying line items 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 loadSalesOrderLineItemTable(table, options={}) { + + options.params = options.params || {}; + + if (!options.order) { + console.log("ERROR: function called without order ID"); + return; + } + + if (!options.status) { + console.log("ERROR: function called without order status"); + return; + } + + options.params.order = options.order; + options.params.part_detail = true; + options.params.allocations = true; + + var filters = loadTableFilters('salesorderlineitem'); + + for (var key in options.params) { + filters[key] = options.params[key]; + } + + options.url = options.url || '{% url "api-so-line-list" %}'; + + var filter_target = options.filter_target || '#filter-list-sales-order-lines'; + + setupFilterList('salesorderlineitems', $(table), filter_target); + + // Is the order pending? + var pending = options.status == {{ SalesOrderStatus.PENDING }}; + + // Has the order shipped? + var shipped = options.status == {{ SalesOrderStatus.SHIPPED }}; + + // Show detail view if the PurchaseOrder is PENDING or SHIPPED + var show_detail = pending || shipped; + + // Table columns to display + var columns = [ + { + checkbox: true, + visible: true, + switchable: false, + }, + { + sortable: true, + sortName: 'part__name', + field: 'part', + title: '{% trans "Part" %}', + formatter: function(value, row, index, field) { + if (row.part) { + return imageHoverIcon(row.part_detail.thumbnail) + renderLink(row.part_detail.full_name, `/part/${value}/`); + } else { + return '-'; + } + }, + footerFormatter: function() { + return '{% trans "Total" %}' + }, + }, + { + 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: 'sale_price', + title: '{% trans "Unit Price" %}', + formatter: function(value, row) { + return row.sale_price_string || row.sale_price; + } + }, + { + sortable: true, + title: '{% trans "Total price" %}', + formatter: function(value, row) { + var total = row.sale_price * row.quantity; + var formatter = new Intl.NumberFormat('en-US', {style: 'currency', currency: row.sale_price_currency}); + return formatter.format(total) + }, + footerFormatter: function(data) { + var total = data.map(function (row) { + return +row['sale_price']*row['quantity'] + }).reduce(function (sum, i) { + return sum + i + }, 0) + var currency = (data.slice(-1)[0] && data.slice(-1)[0].sale_price_currency) || 'USD'; + var formatter = new Intl.NumberFormat('en-US', {style: 'currency', currency: currency}); + return formatter.format(total) + } + }, + { + field: 'stock', + title: '{% trans "In Stock" %}', + formatter: function(value, row) { + return row.part_detail.stock; + } + }, + { + field: 'allocated', + title: pending ? '{% trans "Allocated" %}' : '{% trans "Fulfilled" %}', + formatter: function(value, row, index, field) { + + var quantity = pending ? row.allocated : row.fulfilled; + return makeProgressBar(quantity, row.quantity, { + id: `order-line-progress-${row.pk}`, + }); + }, + sorter: function(valA, valB, rowA, rowB) { + + var A = pending ? rowA.allocated : rowA.fulfilled; + var B = pending ? rowB.allocated : rowB.fulfilled; + + if (A == 0 && B == 0) { + return (rowA.quantity > rowB.quantity) ? 1 : -1; + } + + var progressA = parseFloat(A) / rowA.quantity; + var progressB = parseFloat(B) / rowB.quantity; + + return (progressA < progressB) ? 1 : -1; + } + }, + { + field: 'notes', + title: '{% trans "Notes" %}', + }, + { + field: 'po', + title: '{% trans "PO" %}', + formatter: function(value, row, index, field) { + var po_name = ""; + if (row.allocated) { + row.allocations.forEach(function(allocation) { + if (allocation.po != po_name) { + if (po_name) { + po_name = "-"; + } else { + po_name = allocation.po + } + } + }) + } + return `
` + po_name + `
`; + } + }, + ]; + + if (pending) { + columns.push({ + field: 'buttons', + formatter: function(value, row, index, field) { + + var html = `
`; + + var pk = row.pk; + + if (row.part) { + var part = row.part_detail; + + if (part.trackable) { + html += makeIconButton('fa-hashtag icon-green', 'button-add-by-sn', pk, '{% trans "Allocate serial numbers" %}'); + } + + html += makeIconButton('fa-sign-in-alt icon-green', 'button-add', pk, '{% trans "Allocate stock" %}'); + + if (part.purchaseable) { + html += makeIconButton('fa-shopping-cart', 'button-buy', row.part, '{% trans "Purchase stock" %}'); + } + + if (part.assembly) { + html += makeIconButton('fa-tools', 'button-build', row.part, '{% trans "Build stock" %}'); + } + + html += makeIconButton('fa-dollar-sign icon-green', 'button-price', pk, '{% trans "Calculate price" %}'); + } + + html += makeIconButton('fa-edit icon-blue', 'button-edit', pk, '{% trans "Edit line item" %}'); + html += makeIconButton('fa-trash-alt icon-red', 'button-delete', pk, '{% trans "Delete line item " %}'); + + html += `
`; + + return html; + } + }); + } else { + // Remove the "in stock" column + delete columns['stock']; + } + + function reloadTable() { + $(table).bootstrapTable('refresh'); + } + + // Configure callback functions once the table is loaded + function setupCallbacks() { + + // Callback for editing line items + $(table).find('.button-edit').click(function() { + var pk = $(this).attr('pk'); + + constructForm(`/api/order/so-line/${pk}/`, { + fields: { + quantity: {}, + reference: {}, + sale_price: {}, + sale_price_currency: {}, + notes: {}, + }, + title: '{% trans "Edit Line Item" %}', + onSuccess: reloadTable, + }); + }); + + // Callback for deleting line items + $(table).find('.button-delete').click(function() { + var pk = $(this).attr('pk'); + + constructForm(`/api/order/so-line/${pk}/`, { + method: 'DELETE', + title: '{% trans "Delete Line Item" %}', + onSuccess: reloadTable, + }); + }); + + // Callback for allocating stock items by serial number + $(table).find('.button-add-by-sn').click(function() { + var pk = $(this).attr('pk'); + + // TODO: Migrate this form to the API forms + inventreeGet(`/api/order/so-line/${pk}/`, {}, + { + success: function(response) { + launchModalForm('{% url "so-assign-serials" %}', { + success: reloadTable, + data: { + line: pk, + part: response.part, + } + }); + } + } + ); + }); + + // Callback for allocation stock items to the order + $(table).find('.button-add').click(function() { + var pk = $(this).attr('pk'); + + // TODO: Migrate this form to the API forms + launchModalForm(`/order/sales-order/allocation/new/`, { + success: reloadTable, + data: { + line: pk, + }, + }); + }); + + // Callback for creating a new build + $(table).find('.button-build').click(function() { + var pk = $(this).attr('pk'); + + // Extract the row data from the table! + var idx = $(this).closest('tr').attr('data-index'); + + var row = $(table).bootstrapTable('getData')[idx]; + + var quantity = 1; + + if (row.allocated < row.quantity) { + quantity = row.quantity - row.allocated; + } + + // TODO: Migrate this to the API forms + launchModalForm(`/build/new/`, { + follow: true, + data: { + part: pk, + sales_order: options.order, + quantity: quantity, + }, + }); + }); + + // Callback for purchasing parts + $(table).find('.button-buy').click(function() { + var pk = $(this).attr('pk'); + + launchModalForm("{% url 'order-parts' %}", { + data: { + parts: [pk], + }, + }); + }); + + // Callback for displaying price + $(table).find('.button-price').click(function() { + var pk = $(this).attr('pk'); + var idx = $(this).closest('tr').attr('data-index'); + var row = $(table).bootstrapTable('getData')[idx]; + + launchModalForm( + "{% url 'line-pricing' %}", + { + submit_text: '{% trans "Calculate price" %}', + data: { + line_item: pk, + quantity: row.quantity, + }, + buttons: [{name: 'update_price', + title: '{% trans "Update Unit Price" %}'},], + success: reloadTable, + } + ); + }); + } + + $(table).inventreeTable({ + onPostBody: setupCallbacks, + name: 'salesorderlineitems', + sidePagination: 'server', + formatNoMatches: function() { + return '{% trans "No matching line items" %}'; + }, + queryParams: filters, + original: options.params, + url: options.url, + showFooter: true, + uniqueId: 'pk', + // detailView: show_detail, + // detailViewByClick: show_detail, + // detailFilter: function(index, row) { + // if (pending) { + // // Order is pending + // return row.allocated > 0; + // } else { + // return row.fulfilled > 0; + // } + // }, + // detailFormatter: function(index, row, element) { + // if (pending) { + // return showAllocationSubTable(index, row, element, options); + // } else { + // return showFulfilledSubTable(index, row, element, options); + // } + // }, + columns: columns, + }); +}