From cf66a386ea631ce798ceedd1333b151a26a44a72 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 10 Jul 2021 14:13:46 +1000 Subject: [PATCH 1/3] Bug fix --- InvenTree/part/bom.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) 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) From 73e03636a2267774019b56b523f0cdbede6bdda6 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 10 Jul 2021 23:04:20 +1000 Subject: [PATCH 2/3] Add unit tests --- .../static/script/inventree/sidenav.js | 2 - InvenTree/part/test_bom_export.py | 133 ++++++++++++++++++ 2 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 InvenTree/part/test_bom_export.py 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/test_bom_export.py b/InvenTree/part/test_bom_export.py new file mode 100644 index 0000000000..29ee588621 --- /dev/null +++ b/InvenTree/part/test_bom_export.py @@ -0,0 +1,133 @@ +""" +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 + +from .models import Part, BomItem + + +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"') From 7cc1063114f46d06b56a2847b804bda772497445 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 10 Jul 2021 23:04:34 +1000 Subject: [PATCH 3/3] PEP --- InvenTree/part/test_bom_export.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/InvenTree/part/test_bom_export.py b/InvenTree/part/test_bom_export.py index 29ee588621..13ec3a179e 100644 --- a/InvenTree/part/test_bom_export.py +++ b/InvenTree/part/test_bom_export.py @@ -8,8 +8,6 @@ from django.urls import reverse from django.contrib.auth import get_user_model from django.contrib.auth.models import Group -from .models import Part, BomItem - class BomExportTest(TestCase):