diff --git a/InvenTree/InvenTree/static/script/inventree/sidenav.js b/InvenTree/InvenTree/static/script/inventree/sidenav.js index 6b5d190538..eca19076f2 100644 --- a/InvenTree/InvenTree/static/script/inventree/sidenav.js +++ b/InvenTree/InvenTree/static/script/inventree/sidenav.js @@ -209,8 +209,6 @@ function enableNavbar(options) { var state = localStorage.getItem(stateLabel); - console.log(stateLabel, '->', state); - var width = localStorage.getItem(widthLabel) || '250px'; if (state && state == 'open') { diff --git a/InvenTree/part/bom.py b/InvenTree/part/bom.py index f52b295235..81a0a4eb00 100644 --- a/InvenTree/part/bom.py +++ b/InvenTree/part/bom.py @@ -5,7 +5,7 @@ Primarily BOM upload tools. from collections import OrderedDict -from django.utils.translation import gettext_lazy as _ +from django.utils.translation import gettext as _ from InvenTree.helpers import DownloadFile, GetExportFormats @@ -140,11 +140,16 @@ def ExportBom(part, fmt='csv', cascade=False, max_levels=None, parameter_data=Fa stock_data = [] # Get part default location try: - stock_data.append(bom_item.sub_part.get_default_location().name) + loc = bom_item.sub_part.get_default_location() + + if loc is not None: + stock_data.append(str(loc.name)) + else: + stock_data.append('') except AttributeError: stock_data.append('') # Get part current stock - stock_data.append(bom_item.sub_part.available_stock) + stock_data.append(str(bom_item.sub_part.available_stock)) for s_idx, header in enumerate(stock_headers): try: @@ -318,6 +323,6 @@ def ExportBom(part, fmt='csv', cascade=False, max_levels=None, parameter_data=Fa data = dataset.export(fmt) - filename = '{n}_BOM.{fmt}'.format(n=part.full_name, fmt=fmt) + filename = f"{part.full_name}_BOM.{fmt}" return DownloadFile(data, filename) diff --git a/InvenTree/part/test_bom_export.py b/InvenTree/part/test_bom_export.py new file mode 100644 index 0000000000..13ec3a179e --- /dev/null +++ b/InvenTree/part/test_bom_export.py @@ -0,0 +1,131 @@ +""" +Unit testing for BOM export functionality +""" + +from django.test import TestCase + +from django.urls import reverse +from django.contrib.auth import get_user_model +from django.contrib.auth.models import Group + + +class BomExportTest(TestCase): + + fixtures = [ + 'category', + 'part', + 'location', + 'bom', + ] + + def setUp(self): + super().setUp() + + # Create a user + user = get_user_model() + + self.user = user.objects.create_user( + username='username', + email='user@email.com', + password='password' + ) + + # Put the user into a group with the correct permissions + group = Group.objects.create(name='mygroup') + self.user.groups.add(group) + + # Give the group *all* the permissions! + for rule in group.rule_sets.all(): + rule.can_view = True + rule.can_change = True + rule.can_add = True + rule.can_delete = True + + rule.save() + + self.client.login(username='username', password='password') + + self.url = reverse('bom-download', kwargs={'pk': 100}) + + def test_export_csv(self): + """ + Test BOM download in CSV format + """ + + print("URL", self.url) + + params = { + 'file_format': 'csv', + 'cascade': True, + 'parameter_data': True, + 'stock_data': True, + 'supplier_data': True, + 'manufacturer_data': True, + } + + response = self.client.get(self.url, data=params) + + self.assertEqual(response.status_code, 200) + + content = response.headers['Content-Disposition'] + self.assertEqual(content, 'attachment; filename="BOB | Bob | A2_BOM.csv"') + + def test_export_xls(self): + """ + Test BOM download in XLS format + """ + + params = { + 'file_format': 'xls', + 'cascade': True, + 'parameter_data': True, + 'stock_data': True, + 'supplier_data': True, + 'manufacturer_data': True, + } + + response = self.client.get(self.url, data=params) + + self.assertEqual(response.status_code, 200) + + content = response.headers['Content-Disposition'] + self.assertEqual(content, 'attachment; filename="BOB | Bob | A2_BOM.xls"') + + def test_export_xlsx(self): + """ + Test BOM download in XLSX format + """ + + params = { + 'file_format': 'xlsx', + 'cascade': True, + 'parameter_data': True, + 'stock_data': True, + 'supplier_data': True, + 'manufacturer_data': True, + } + + response = self.client.get(self.url, data=params) + + self.assertEqual(response.status_code, 200) + + def test_export_json(self): + """ + Test BOM download in JSON format + """ + + params = { + 'file_format': 'json', + 'cascade': True, + 'parameter_data': True, + 'stock_data': True, + 'supplier_data': True, + 'manufacturer_data': True, + } + + response = self.client.get(self.url, data=params) + + self.assertEqual(response.status_code, 200) + + content = response.headers['Content-Disposition'] + self.assertEqual(content, 'attachment; filename="BOB | Bob | A2_BOM.json"')