{% load i18n %} {% load inventree_extras %} /* globals Chart, constructForm, global_settings, imageHoverIcon, inventreeGet, inventreePut, linkButtonsToSelection, loadTableFilters, makeIconBadge, makeIconButton, printPartLabels, renderLink, setFormGroupVisibility, setupFilterList, yesNoLabel, */ /* exported deletePart, deletePartCategory, duplicateBom, duplicatePart, editCategory, editPart, initPriceBreakSet, loadBomChart, loadParametricPartTable, loadPartCategoryTable, loadPartParameterTable, loadPartPurchaseOrderTable, loadPartTable, loadPartTestTemplateTable, loadPartSchedulingChart, loadPartVariantTable, loadRelatedPartsTable, loadSellPricingChart, loadSimplePartTable, loadStockPricingChart, partStockLabel, toggleStar, validateBom, */ /* Part API functions * Requires api.js to be loaded first */ function partGroups() { return { attributes: { title: '{% trans "Part Attributes" %}', collapsible: true, }, create: { title: '{% trans "Part Creation Options" %}', collapsible: true, }, duplicate: { title: '{% trans "Part Duplication Options" %}', collapsible: true, }, supplier: { title: '{% trans "Supplier Options" %}', collapsible: true, hidden: !global_settings.PART_PURCHASEABLE, } }; } // Construct fieldset for part forms function partFields(options={}) { var fields = { category: { secondary: { title: '{% trans "Add Part Category" %}', fields: function() { var fields = categoryFields(); return fields; } } }, name: {}, IPN: {}, revision: {}, description: {}, variant_of: {}, keywords: { icon: 'fa-key', }, units: {}, link: { icon: 'fa-link', }, default_location: { }, default_supplier: { filters: { part_detail: true, supplier_detail: true, } }, default_expiry: { icon: 'fa-calendar-alt', }, minimum_stock: { icon: 'fa-boxes', }, component: { default: global_settings.PART_COMPONENT, group: 'attributes', }, assembly: { default: global_settings.PART_ASSEMBLY, group: 'attributes', }, is_template: { default: global_settings.PART_TEMPLATE, group: 'attributes', }, trackable: { default: global_settings.PART_TRACKABLE, group: 'attributes', }, purchaseable: { default: global_settings.PART_PURCHASEABLE, group: 'attributes', onEdit: function(value, name, field, options) { setFormGroupVisibility('supplier', value, options); } }, salable: { default: global_settings.PART_SALABLE, group: 'attributes', }, virtual: { default: global_settings.PART_VIRTUAL, group: 'attributes', }, }; // If editing a part, we can set the "active" status if (options.edit) { fields.active = { group: 'attributes' }; } // Pop expiry field if (!global_settings.STOCK_ENABLE_EXPIRY) { delete fields['default_expiry']; } if (options.create || options.duplicate) { if (global_settings.PART_CREATE_INITIAL) { fields.initial_stock = { type: 'boolean', label: '{% trans "Create Initial Stock" %}', help_text: '{% trans "Create an initial stock item for this part" %}', group: 'create', }; fields.initial_stock_quantity = { type: 'decimal', value: 1, label: '{% trans "Initial Stock Quantity" %}', help_text: '{% trans "Specify initial stock quantity for this part" %}', group: 'create', }; // TODO - Allow initial location of stock to be specified fields.initial_stock_location = { label: '{% trans "Location" %}', help_text: '{% trans "Select destination stock location" %}', type: 'related field', required: true, api_url: `/api/stock/location/`, model: 'stocklocation', group: 'create', }; } } // Additional fields when "creating" a new part if (options.create) { // No supplier parts available yet delete fields['default_supplier']; fields.copy_category_parameters = { type: 'boolean', label: '{% trans "Copy Category Parameters" %}', help_text: '{% trans "Copy parameter templates from selected part category" %}', value: global_settings.PART_CATEGORY_PARAMETERS, group: 'create', }; // Supplier options fields.add_supplier_info = { type: 'boolean', label: '{% trans "Add Supplier Data" %}', help_text: '{% trans "Create initial supplier data for this part" %}', group: 'supplier', }; fields.supplier = { type: 'related field', model: 'company', label: '{% trans "Supplier" %}', help_text: '{% trans "Select supplier" %}', filters: { 'is_supplier': true, }, api_url: '{% url "api-company-list" %}', group: 'supplier', }; fields.SKU = { type: 'string', label: '{% trans "SKU" %}', help_text: '{% trans "Supplier stock keeping unit" %}', group: 'supplier', }; fields.manufacturer = { type: 'related field', model: 'company', label: '{% trans "Manufacturer" %}', help_text: '{% trans "Select manufacturer" %}', filters: { 'is_manufacturer': true, }, api_url: '{% url "api-company-list" %}', group: 'supplier', }; fields.MPN = { type: 'string', label: '{% trans "MPN" %}', help_text: '{% trans "Manufacturer Part Number" %}', group: 'supplier', }; } // Additional fields when "duplicating" a part if (options.duplicate) { fields.copy_from = { type: 'integer', hidden: true, value: options.duplicate, group: 'duplicate', }, fields.copy_image = { type: 'boolean', label: '{% trans "Copy Image" %}', help_text: '{% trans "Copy image from original part" %}', value: true, group: 'duplicate', }, fields.copy_bom = { type: 'boolean', label: '{% trans "Copy BOM" %}', help_text: '{% trans "Copy bill of materials from original part" %}', value: global_settings.PART_COPY_BOM, group: 'duplicate', }; fields.copy_parameters = { type: 'boolean', label: '{% trans "Copy Parameters" %}', help_text: '{% trans "Copy parameter data from original part" %}', value: global_settings.PART_COPY_PARAMETERS, group: 'duplicate', }; } return fields; } function categoryFields() { return { parent: { help_text: '{% trans "Parent part category" %}', required: false, }, name: {}, description: {}, default_location: {}, default_keywords: { icon: 'fa-key', }, icon: { help_text: `{% trans "Icon (optional) - Explore all available icons on" %} Font Awesome.`, placeholder: 'fas fa-tag', }, }; } // Edit a PartCategory via the API function editCategory(pk) { var url = `/api/part/category/${pk}/`; var fields = categoryFields(); constructForm(url, { fields: fields, title: '{% trans "Edit Part Category" %}', reload: true, }); } /* * Delete a PartCategory via the API */ function deletePartCategory(pk, options={}) { var url = `/api/part/category/${pk}/`; var html = `
${thumb} ${part.full_name} - ${part.description}
{% trans "Deleting this part cannot be reversed" %}