diff --git a/.github/workflows/qc_checks.yaml b/.github/workflows/qc_checks.yaml index 929a299e93..598f518f27 100644 --- a/.github/workflows/qc_checks.yaml +++ b/.github/workflows/qc_checks.yaml @@ -12,7 +12,7 @@ on: - l10* env: - python_version: 3.7 + python_version: 3.8 node_version: 16 server_start_sleep: 60 @@ -229,6 +229,7 @@ jobs: cache: 'pip' - name: Install Dependencies run: | + sudo apt-get update sudo apt-get install libpq-dev pip3 install invoke pip3 install psycopg2 @@ -282,7 +283,8 @@ jobs: cache: 'pip' - name: Install Dependencies run: | - sudo apt-get install mysql-server libmysqlclient-dev + sudo apt-get update + sudo apt-get install libmysqlclient-dev pip3 install invoke pip3 install mysqlclient invoke install diff --git a/InvenTree/part/forms.py b/InvenTree/part/forms.py index 609acec917..2d9ae4dc30 100644 --- a/InvenTree/part/forms.py +++ b/InvenTree/part/forms.py @@ -11,7 +11,7 @@ from django.utils.translation import ugettext_lazy as _ from mptt.fields import TreeNodeChoiceField from InvenTree.forms import HelperForm -from InvenTree.helpers import GetExportFormats, clean_decimal +from InvenTree.helpers import clean_decimal from InvenTree.fields import RoundingDecimalFormField import common.models @@ -55,36 +55,6 @@ class PartImageDownloadForm(HelperForm): ] -class BomExportForm(forms.Form): - """ Simple form to let user set BOM export options, - before exporting a BOM (bill of materials) file. - """ - - file_format = forms.ChoiceField(label=_("File Format"), help_text=_("Select output file format")) - - cascading = forms.BooleanField(label=_("Cascading"), required=False, initial=True, help_text=_("Download cascading / multi-level BOM")) - - levels = forms.IntegerField(label=_("Levels"), required=True, initial=0, help_text=_("Select maximum number of BOM levels to export (0 = all levels)")) - - parameter_data = forms.BooleanField(label=_("Include Parameter Data"), required=False, initial=False, help_text=_("Include part parameters data in exported BOM")) - - stock_data = forms.BooleanField(label=_("Include Stock Data"), required=False, initial=False, help_text=_("Include part stock data in exported BOM")) - - manufacturer_data = forms.BooleanField(label=_("Include Manufacturer Data"), required=False, initial=True, help_text=_("Include part manufacturer data in exported BOM")) - - supplier_data = forms.BooleanField(label=_("Include Supplier Data"), required=False, initial=True, help_text=_("Include part supplier data in exported BOM")) - - def get_choices(self): - """ BOM export format choices """ - - return [(x, x.upper()) for x in GetExportFormats()] - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - self.fields['file_format'].choices = self.get_choices() - - class BomDuplicateForm(HelperForm): """ Simple confirmation form for BOM duplication. diff --git a/InvenTree/part/templates/part/bom_upload/upload_file.html b/InvenTree/part/templates/part/bom_upload/upload_file.html index 6775176ede..40411f074a 100644 --- a/InvenTree/part/templates/part/bom_upload/upload_file.html +++ b/InvenTree/part/templates/part/bom_upload/upload_file.html @@ -32,7 +32,7 @@
{% trans "Requirements for BOM upload" %}:
@@ -60,4 +60,8 @@ enableSidebar('bom-upload'); -{% endblock js_ready %} +$('#bom-template-download').click(function() { + downloadBomTemplate(); +}); + +{% endblock js_ready %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/detail.html b/InvenTree/part/templates/part/detail.html index f1b47bc4e2..d16de22e1b 100644 --- a/InvenTree/part/templates/part/detail.html +++ b/InvenTree/part/templates/part/detail.html @@ -620,13 +620,7 @@ }); $("#download-bom").click(function () { - launchModalForm("{% url 'bom-export' part.id %}", - { - success: function(response) { - location.href = response.url; - }, - } - ); + exportBom({{ part.id }}); }); {% if report_enabled %} diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 6e742dc571..af35cf9c1f 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -1192,14 +1192,10 @@ class BomExport(AjaxView): """ model = Part - form_class = part_forms.BomExportForm ajax_form_title = _("Export Bill of Materials") role_required = 'part.view' - def get(self, request, *args, **kwargs): - return self.renderJsonResponse(request, self.form_class()) - def post(self, request, *args, **kwargs): # Extract POSTed form data diff --git a/InvenTree/templates/js/translated/bom.js b/InvenTree/templates/js/translated/bom.js index 3cde5bca61..ffd8195e07 100644 --- a/InvenTree/templates/js/translated/bom.js +++ b/InvenTree/templates/js/translated/bom.js @@ -2,6 +2,7 @@ /* globals constructForm, + exportFormatOptions, imageHoverIcon, inventreeGet, inventreePut, @@ -14,6 +15,8 @@ */ /* exported + downloadBomTemplate, + exportBom, newPartFromBomWizard, loadBomTable, loadUsedInTable, @@ -21,12 +24,121 @@ removeColFromBomWizard, */ -/* BOM management functions. - * Requires follwing files to be loaded first: - * - api.js - * - part.js - * - modals.js +function downloadBomTemplate(options={}) { + + var format = options.format; + + if (!format) { + format = inventreeLoad('bom-export-format', 'csv'); + } + + constructFormBody({}, { + title: '{% trans "Download BOM Template" %}', + fields: { + format: { + label: '{% trans "Format" %}', + help_text: '{% trans "Select file format" %}', + required: true, + type: 'choice', + value: format, + choices: exportFormatOptions(), + } + }, + onSubmit: function(fields, opts) { + var format = getFormFieldValue('format', fields['format'], opts); + + // Save the format for next time + inventreeSave('bom-export-format', format); + + // Hide the modal + $(opts.modal).modal('hide'); + + // Download the file + location.href = `{% url "bom-upload-template" %}?format=${format}`; + + } + }); +} + + +/** + * Export BOM (Bill of Materials) for the specified Part instance */ +function exportBom(part_id, options={}) { + + constructFormBody({}, { + title: '{% trans "Export BOM" %}', + fields: { + format: { + label: '{% trans "Format" %}', + help_text: '{% trans "Select file format" %}', + required: true, + type: 'choice', + value: inventreeLoad('bom-export-format', 'csv'), + choices: exportFormatOptions(), + }, + cascading: { + label: '{% trans "Cascading" %}', + help_text: '{% trans "Download cascading / multi-level BOM" %}', + type: 'boolean', + value: inventreeLoad('bom-export-cascading', true), + }, + levels: { + label: '{% trans "Levels" %}', + help_text: '{% trans "Select maximum number of BOM levels to export (0 = all levels)" %}', + type: 'integer', + value: 0, + min_value: 0, + }, + parameter_data: { + label: '{% trans "Include Parameter Data" %}', + help_text: '{% trans "Include part parameter data in exported BOM" %}', + type: 'boolean', + value: inventreeLoad('bom-export-parameter_data', false), + }, + stock_data: { + label: '{% trans "Include Stock Data" %}', + help_text: '{% trans "Include part stock data in exported BOM" %}', + type: 'boolean', + value: inventreeLoad('bom-export-stock_data', false), + }, + manufacturer_data: { + label: '{% trans "Include Manufacturer Data" %}', + help_text: '{% trans "Include part manufacturer data in exported BOM" %}', + type: 'boolean', + value: inventreeLoad('bom-export-manufacturer_data', false), + }, + supplier_data: { + label: '{% trans "Include Supplier Data" %}', + help_text: '{% trans "Include part supplier data in exported BOM" %}', + type: 'boolean', + value: inventreeLoad('bom-export-supplier_data', false), + } + }, + onSubmit: function(fields, opts) { + + // Extract values from the form + var field_names = ['format', 'cascading', 'levels', 'parameter_data', 'stock_data', 'manufacturer_data', 'supplier_data']; + + var url = `/part/${part_id}/bom-download/?`; + + field_names.forEach(function(fn) { + var val = getFormFieldValue(fn, fields[fn], opts); + + // Update user preferences + inventreeSave(`bom-export-${fn}`, val); + + url += `${fn}=${val}&`; + }); + + $(opts.modal).modal('hide'); + + // Redirect to the BOM file download + location.href = url; + } + }); + +} function bomItemFields() { diff --git a/InvenTree/templates/js/translated/forms.js b/InvenTree/templates/js/translated/forms.js index def7e41358..43e8d5ce62 100644 --- a/InvenTree/templates/js/translated/forms.js +++ b/InvenTree/templates/js/translated/forms.js @@ -811,7 +811,9 @@ function updateFieldValue(name, value, field, options) { switch (field.type) { case 'boolean': - el.prop('checked', value); + if (value == true || value.toString().toLowerCase() == 'true') { + el.prop('checked'); + } break; case 'related field': // Clear? @@ -2034,8 +2036,15 @@ function constructInputOptions(name, classes, type, parameters) { } if (parameters.value != null) { - // Existing value? - opts.push(`value='${parameters.value}'`); + if (parameters.type == 'boolean') { + // Special consideration of a boolean (checkbox) value + if (parameters.value == true || parameters.value.toString().toLowerCase() == 'true') { + opts.push('checked'); + } + } else { + // Existing value? + opts.push(`value='${parameters.value}'`); + } } else if (parameters.default != null) { // Otherwise, a defualt value? opts.push(`value='${parameters.default}'`);