{% extends "order/order_base.html" %} {% load inventree_extras %} {% load status_codes %} {% load i18n %} {% load static %} {% block menubar %} {% include 'order/po_navbar.html' with tab='details' %} {% endblock %} {% block heading %} {% trans "Purchase Order Items" %} {% endblock %} {% block details %}
{% if order.status == PurchaseOrderStatus.PENDING and roles.purchase_order.change %} {% endif %}
{% endblock %} {% block js_ready %} {{ block.super }} {% if order.status == PurchaseOrderStatus.PENDING %} $('#new-po-line').click(function() { constructForm('{% url "api-po-line-list" %}', { fields: { order: { value: {{ order.pk }}, hidden: true, }, part: { filters: { part_detail: true, supplier_detail: true, supplier: {{ order.supplier.pk }}, }, }, quantity: {}, reference: {}, purchase_price: {}, purchase_price_currency: {}, destination: {}, notes: {}, }, method: 'POST', title: '{% trans "Add Line Item" %}', onSuccess: reloadTable, }); }); {% endif %} function reloadTable() { $("#po-table").bootstrapTable("refresh"); } function setupCallbacks() { // Setup callbacks for the line buttons var table = $("#po-table"); {% 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, }); }); {% 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-table").inventreeTable({ onPostBody: setupCallbacks, name: 'purchaseorder', 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__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: 'part__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: 'part__MPN', field: 'supplier_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.pk}/`); } 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; } }, { sortable: true, 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: true, 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.pathstring', title: '{% trans "Destination" %}', }, { 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; }, } ] }); {% endblock %}