{% extends "part/part_base.html" %} {% load static %} {% load i18n %} {% load inventree_extras %} {% load crispy_forms_tags %} {% load markdownify %} {% block menubar %} {% include 'part/navbar.html' %} {% endblock %} {% block page_content %}

{% trans "Part Stock" %}

{% if part.is_template %}
{% blocktrans with full_name=part.full_name%}Showing stock for all variants of {{full_name}}{% endblocktrans %}
{% endif %} {% include "stock_table.html" %}

{% trans "Part Test Templates" %}

{% trans "Purchase Orders" %}

{% trans "Sales Orders" %}

{% if 0 %} {% endif %}

{% trans "Sales Order Allocations" %}

{% include "part/prices.html" %}

{% trans "Notes" %}

{% if part.notes %} {{ part.notes | markdownify }} {% endif %}

{% trans "Part Variants" %}

{% if part.is_template and part.active %} {% endif %}

{% trans "Parameters" %}

{% if roles.part.add %} {% endif %}

{% trans "Attachments" %}

{% include "attachment_table.html" %}

{% trans "Bill of Materials" %}

{% include "part/bom.html" with part=part %}

{% trans "Assemblies" %}

{% trans "Part Builds" %}

{% if part.active %} {% if roles.build.add %} {% endif %} {% endif %}

{% trans "Build Order Allocations" %}

{% trans "Part Suppliers" %}

{% trans "Part Manufacturers" %}

{% endblock %} {% block js_load %} {{ block.super }} {% endblock %} {% block js_ready %} {{ block.super }} // Load the "suppliers" tab onPanelLoad('suppliers', function() { function reloadSupplierPartTable() { $('#supplier-part-table').bootstrapTable('refresh'); } $('#supplier-create').click(function () { createSupplierPart({ part: {{ part.pk }}, onSuccess: reloadSupplierPartTable, }); }); $("#supplier-part-delete").click(function() { var selections = $("#supplier-part-table").bootstrapTable("getSelections"); var requests = []; showQuestionDialog( '{% trans "Delete Supplier Parts?" %}', '{% trans "All selected supplier parts will be deleted" %}', { accept: function() { selections.forEach(function(part) { var url = `/api/company/part/${part.pk}/`; requests.push(inventreeDelete(url)); }); $.when.apply($, requests).done(function() { reloadSupplierPartTable(); }); } } ); }); loadSupplierPartTable( "#supplier-part-table", "{% url 'api-supplier-part-list' %}", { params: { part: {{ part.id }}, part_detail: false, supplier_detail: true, manufacturer_detail: true, }, } ); linkButtonsToSelection($("#supplier-part-table"), ['#supplier-part-options']); loadManufacturerPartTable( '#manufacturer-part-table', "{% url 'api-manufacturer-part-list' %}", { params: { part: {{ part.id }}, part_detail: true, manufacturer_detail: true, }, } ); linkButtonsToSelection($("#manufacturer-part-table"), ['#manufacturer-part-options']); $("#manufacturer-part-delete").click(function() { var selections = $("#manufacturer-part-table").bootstrapTable("getSelections"); deleteManufacturerParts(selections, { onSuccess: function() { $("#manufacturer-part-table").bootstrapTable("refresh"); } }); }); $('#manufacturer-create').click(function () { createManufacturerPart({ part: {{ part.pk }}, onSuccess: function() { $("#manufacturer-part-table").bootstrapTable("refresh"); } }); }); }); // Load the "builds" tab onPanelLoad("build-orders", function() { $("#start-build").click(function() { newBuildOrder({ part: {{ part.pk }}, }); }); loadBuildTable($("#build-table"), { url: "{% url 'api-build-list' %}", params: { part: {{ part.id }}, } }); loadBuildOrderAllocationTable("#build-order-allocation-table", { params: { part: {{ part.id }}, } }); }); // Load the "sales orders" tab onPanelLoad("sales-orders", function() { loadSalesOrderAllocationTable("#sales-order-allocation-table", { params: { part: {{ part.id }}, } }); }); // Load the "used in" tab onPanelLoad("used-in", function() { loadPartTable('#used-table', '{% url "api-part-list" %}', { params: { uses: {{ part.pk }}, }, filterTarget: '#filter-list-usedin', } ); }); // Load the "BOM" tab onPanelLoad("bom", function() { // Load the BOM table data loadBomTable($("#bom-table"), { editable: {{ editing_enabled }}, bom_url: "{% url 'api-bom-list' %}", part_url: "{% url 'api-part-list' %}", parent_id: {{ part.id }} , sub_part_detail: true, }); linkButtonsToSelection($("#bom-table"), [ "#bom-item-delete", ] ); {% if editing_enabled %} $("#editing-finished").click(function() { location.href = "{% url 'part-detail' part.id %}?display=bom"; }); $('#bom-item-delete').click(function() { // Get a list of the selected BOM items var rows = $("#bom-table").bootstrapTable('getSelections'); // TODO - In the future, display (in the dialog) which items are going to be deleted showQuestionDialog( '{% trans "Delete selected BOM items?" %}', '{% trans "All selected BOM items will be deleted" %}', { accept: function() { // Keep track of each DELETE request var requests = []; rows.forEach(function(row) { requests.push( inventreeDelete( `/api/bom/${row.pk}/`, ) ); }); // Wait for *all* the requests to complete $.when.apply($, requests).done(function() { location.reload(); }); } } ); }); $('#bom-upload').click(function() { location.href = "{% url 'upload-bom' part.id %}"; }); $('#bom-duplicate').click(function() { launchModalForm( "{% url 'duplicate-bom' part.id %}", { success: function() { $('#bom-table').bootstrapTable('refresh'); } } ); }); $("#bom-item-new").click(function () { var fields = bomItemFields(); fields.part.value = {{ part.pk }}; fields.sub_part.filters = { active: true, }; constructForm('{% url "api-bom-list" %}', { fields: fields, method: 'POST', title: '{% trans "Create BOM Item" %}', focus: 'sub_part', onSuccess: function() { $('#bom-table').bootstrapTable('refresh'); } }); }); {% else %} $("#validate-bom").click(function() { launchModalForm( "{% url 'bom-validate' part.id %}", { reload: true, } ); }); $("#edit-bom").click(function () { location.href = "{% url 'part-detail' part.id %}?display=bom&edit=1"; }); $("#download-bom").click(function () { launchModalForm("{% url 'bom-export' part.id %}", { success: function(response) { location.href = response.url; }, } ); }); {% endif %} $("#print-bom-report").click(function() { printBomReports([{{ part.pk }}]); }); }); // Load the "related parts" tab onPanelLoad("related-parts", function() { $('#table-related-part').inventreeTable({ }); $("#add-related-part").click(function() { launchModalForm("{% url 'part-related-create' %}", { data: { part: {{ part.id }}, }, reload: true, }); }); $('.delete-related-part').click(function() { var button = $(this); launchModalForm(button.attr('url'), { reload: true, }); }); }); // Load the "variants" tab onPanelLoad("variants", function() { loadPartVariantTable($('#variants-table'), {{ part.pk }}); $('#new-variant').click(function() { duplicatePart( {{ part.pk}}, { variant: true, } ); }); }); // Load the BOM table data in the pricing view loadBomTable($("#bom-pricing-table"), { editable: {{ editing_enabled }}, bom_url: "{% url 'api-bom-list' %}", part_url: "{% url 'api-part-list' %}", parent_id: {{ part.id }} , sub_part_detail: true, }); onPanelLoad("purchase-orders", function() { loadPurchaseOrderTable($("#purchase-order-table"), { url: "{% url 'api-po-list' %}", params: { part: {{ part.id }}, }, }); }); onPanelLoad("sales-orders", function() { loadSalesOrderTable($("#sales-order-table"), { url: "{% url 'api-so-list' %}", params: { part: {{ part.id }}, }, }); }); $("#part-order2").click(function() { launchModalForm("{% url 'order-parts' %}", { data: { part: {{ part.id }}, }, reload: true, }); }); onPanelLoad("test-templates", function() { // Load test template table loadPartTestTemplateTable( $("#test-template-table"), { part: {{ part.pk }}, params: { part: {{ part.pk }}, } } ); // Callback for "add test template" button $("#add-test-template").click(function() { constructForm('{% url "api-part-test-template-list" %}', { method: 'POST', fields: { test_name: {}, description: {}, required: {}, requires_value: {}, requires_attachment: {}, part: { value: {{ part.pk }}, hidden: true, } }, title: '{% trans "Add Test Result Template" %}', onSuccess: function() { $("#test-template-table").bootstrapTable("refresh"); } }); }); }); onPanelLoad("part-stock", function() { $('#add-stock-item').click(function () { createNewStockItem({ reload: true, data: { part: {{ part.id }}, } }); }); loadStockTable($("#stock-table"), { params: { part: {{ part.id }}, location_detail: true, part_detail: true, supplier_part_detail: true, }, groupByField: 'location', buttons: [ '#stock-options', ], url: "{% url 'api-stock-list' %}", }); $("#stock-export").click(function() { exportStock({ part: {{ part.pk }} }); }); $('#item-create').click(function () { createNewStockItem({ reload: true, data: { part: {{ part.id }}, } }); }); }); $('#edit-notes').click(function() { constructForm('{% url "api-part-detail" part.pk %}', { fields: { notes: { multiline: true, } }, title: '{% trans "Edit Part Notes" %}', reload: true, }); }); $(".slidey").change(function() { var field = $(this).attr('fieldname'); var checked = $(this).prop('checked'); var data = {}; data[field] = checked; // Update the particular field inventreePut("{% url 'api-part-detail' part.id %}", data, { method: 'PATCH', reloadOnSuccess: true, }, ); }); onPanelLoad("part-parameters", function() { loadPartParameterTable( '#parameter-table', '{% url "api-part-parameter-list" %}', { params: { part: {{ part.pk }}, } } ); $('#param-table').inventreeTable({ }); {% if roles.part.add %} $('#param-create').click(function() { constructForm('{% url "api-part-parameter-list" %}', { method: 'POST', fields: { part: { value: {{ part.pk }}, hidden: true, }, template: {}, data: {}, }, title: '{% trans "Add Parameter" %}', onSuccess: function() { $('#parameter-table').bootstrapTable('refresh'); } }); }); {% endif %} $('.param-edit').click(function() { var button = $(this); launchModalForm(button.attr('url'), { reload: true, }); }); $('.param-delete').click(function() { var button = $(this); launchModalForm(button.attr('url'), { reload: true, }); }); }); onPanelLoad("part-attachments", function() { loadAttachmentTable( '{% url "api-part-attachment-list" %}', { filters: { part: {{ part.pk }}, }, onEdit: function(pk) { var url = `/api/part/attachment/${pk}/`; constructForm(url, { fields: { filename: {}, comment: {}, }, title: '{% trans "Edit Attachment" %}', onSuccess: reloadAttachmentTable, }); }, onDelete: function(pk) { var url = `/api/part/attachment/${pk}/`; constructForm(url, { method: 'DELETE', confirmMessage: '{% trans "Confirm Delete Operation" %}', title: '{% trans "Delete Attachment" %}', onSuccess: reloadAttachmentTable, }); } } ); enableDragAndDrop( '#attachment-dropzone', '{% url "api-part-attachment-list" %}', { data: { part: {{ part.id }}, }, label: 'attachment', success: function(data, status, xhr) { reloadAttachmentTable(); } } ); $("#new-attachment").click(function() { constructForm( '{% url "api-part-attachment-list" %}', { method: 'POST', fields: { attachment: {}, comment: {}, part: { value: {{ part.pk }}, hidden: true, } }, onSuccess: reloadAttachmentTable, title: '{% trans "Add Attachment" %}', } ) }); }); {% default_currency as currency %} // history graphs {% if price_history %} var purchasepricedata = { labels: [ {% for line in price_history %}'{{ line.date }}',{% endfor %} ], datasets: [{ label: '{% blocktrans %}Purchase Unit Price - {{currency}}{% endblocktrans %}', backgroundColor: 'rgba(255, 99, 132, 0.2)', borderColor: 'rgb(255, 99, 132)', yAxisID: 'y', data: [ {% for line in price_history %}{{ line.price|stringformat:".2f" }},{% endfor %} ], borderWidth: 1, type: 'line' }, {% if 'price_diff' in price_history.0 %} { label: '{% blocktrans %}Unit Price-Cost Difference - {{currency}}{% endblocktrans %}', backgroundColor: 'rgba(68, 157, 68, 0.2)', borderColor: 'rgb(68, 157, 68)', yAxisID: 'y2', data: [ {% for line in price_history %}{{ line.price_diff|stringformat:".2f" }},{% endfor %} ], borderWidth: 1, type: 'line', hidden: true, }, { label: '{% blocktrans %}Supplier Unit Cost - {{currency}}{% endblocktrans %}', backgroundColor: 'rgba(70, 127, 155, 0.2)', borderColor: 'rgb(70, 127, 155)', yAxisID: 'y', data: [ {% for line in price_history %}{{ line.price_part|stringformat:".2f" }},{% endfor %} ], borderWidth: 1, type: 'line', hidden: true, }, {% endif %} { label: '{% trans "Quantity" %}', backgroundColor: 'rgba(255, 206, 86, 0.2)', borderColor: 'rgb(255, 206, 86)', yAxisID: 'y1', data: [ {% for line in price_history %}{{ line.qty|stringformat:"f" }},{% endfor %} ], borderWidth: 1 }] } var StockPriceChart = loadStockPricingChart($('#StockPriceChart'), purchasepricedata) {% endif %} {% if bom_parts %} var bom_colors = randomColor({hue: 'green', count: {{ bom_parts|length }} }) var bomdata = { labels: [{% for line in bom_parts %}'{{ line.name }}',{% endfor %}], datasets: [ { label: 'Price', data: [{% for line in bom_parts %}{{ line.min_price }},{% endfor %}], backgroundColor: bom_colors, }, {% if bom_pie_max %} { label: 'Max Price', data: [{% for line in bom_parts %}{{ line.max_price }},{% endfor %}], backgroundColor: bom_colors, }, {% endif %} ] }; var BomChart = loadBomChart(document.getElementById('BomChart'), bomdata) {% endif %} // Internal pricebreaks {% settings_value "PART_INTERNAL_PRICE" as show_internal_price %} {% if show_internal_price and roles.sales_order.view %} initPriceBreakSet( $('#internal-price-break-table'), { part_id: {{part.id}}, pb_human_name: 'internal price break', pb_url_slug: 'internal-price', pb_url: '{% url 'api-part-internal-price-list' %}', pb_new_btn: $('#new-internal-price-break'), pb_new_url: '{% url 'internal-price-break-create' %}', linkedGraph: $('#InternalPriceBreakChart'), }, ); {% endif %} // Sales pricebreaks {% if part.salable and roles.sales_order.view %} initPriceBreakSet( $('#price-break-table'), { part_id: {{part.id}}, pb_human_name: 'sale price break', pb_url_slug: 'sale-price', pb_url: "{% url 'api-part-sale-price-list' %}", pb_new_btn: $('#new-price-break'), pb_new_url: '{% url 'sale-price-break-create' %}', linkedGraph: $('#SalePriceBreakChart'), }, ); {% endif %} // Sale price history {% if sale_history %} var salepricedata = { labels: [ {% for line in sale_history %}'{{ line.date }}',{% endfor %} ], datasets: [{ label: '{% blocktrans %}Unit Price - {{currency}}{% endblocktrans %}', backgroundColor: 'rgba(255, 99, 132, 0.2)', borderColor: 'rgb(255, 99, 132)', yAxisID: 'y', data: [ {% for line in sale_history %}{{ line.price|stringformat:".2f" }},{% endfor %} ], borderWidth: 1, }, { label: '{% trans "Quantity" %}', backgroundColor: 'rgba(255, 206, 86, 0.2)', borderColor: 'rgb(255, 206, 86)', yAxisID: 'y1', data: [ {% for line in sale_history %}{{ line.qty|stringformat:"f" }},{% endfor %} ], borderWidth: 1, type: 'bar', }] } var SalePriceChart = loadSellPricingChart($('#SalePriceChart'), salepricedata) {% endif %} attachNavCallbacks({ name: 'part', default: 'part-stock' }); {% endblock %}