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}'`);