From 67966eba133c3a3ca33744765521d9c3b3cf99c6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 10 May 2022 23:56:02 +0200 Subject: [PATCH 1/9] Add code128 template --- .../label/part/part_label_code128.html | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 InvenTree/label/templates/label/part/part_label_code128.html diff --git a/InvenTree/label/templates/label/part/part_label_code128.html b/InvenTree/label/templates/label/part/part_label_code128.html new file mode 100644 index 0000000000..7f8ef144ec --- /dev/null +++ b/InvenTree/label/templates/label/part/part_label_code128.html @@ -0,0 +1,33 @@ +{% extends "label/label_base.html" %} + +{% load barcode %} + +{% block style %} + +.qr { + position: fixed; + left: 0mm; + top: 0mm; + height: {{ height }}mm; + width: {{ height }}mm; +} + +.part { + font-family: Arial, Helvetica, sans-serif; + display: inline; + position: absolute; + left: {{ height }}mm; + top: 2mm; +} + +{% endblock %} + +{% block content %} + + + +
+ {{ part.full_name }} +
+ +{% endblock %} \ No newline at end of file From a65d747501ddd6c1c134336cd04c10322f850410 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 11 May 2022 03:05:40 +0200 Subject: [PATCH 2/9] add additional template --- InvenTree/label/apps.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/InvenTree/label/apps.py b/InvenTree/label/apps.py index 318f4af984..633907f330 100644 --- a/InvenTree/label/apps.py +++ b/InvenTree/label/apps.py @@ -265,6 +265,13 @@ class LabelConfig(AppConfig): 'width': 70, 'height': 24, }, + { + 'file': 'part_label_code128.html', + 'name': 'Barcode Part Label', + 'description': 'Simple part label with Code128 barcode', + 'width': 70, + 'height': 24, + }, ] for label in labels: From f62049151777b6b88338b77ccfd6a0ded0ff0f05 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 11 May 2022 03:15:20 +0200 Subject: [PATCH 3/9] add test for rendering label --- InvenTree/label/tests.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/InvenTree/label/tests.py b/InvenTree/label/tests.py index 1e7e7994ae..0adc81abd4 100644 --- a/InvenTree/label/tests.py +++ b/InvenTree/label/tests.py @@ -8,17 +8,27 @@ import os from django.test import TestCase from django.conf import settings from django.apps import apps +from django.urls import reverse from django.core.exceptions import ValidationError from InvenTree.helpers import validateFilterString +from InvenTree.api_tester import InvenTreeAPITestCase -from .models import StockItemLabel, StockLocationLabel +from .models import StockItemLabel, StockLocationLabel, PartLabel from stock.models import StockItem -class LabelTest(TestCase): +class LabelTest(InvenTreeAPITestCase): + + fixtures = [ + 'category', + 'part', + 'location', + 'stock' + ] def setUp(self) -> None: + super().setUp() # ensure the labels were created apps.get_app_config('label').create_labels() @@ -77,3 +87,13 @@ class LabelTest(TestCase): with self.assertRaises(ValidationError): validateFilterString(bad_filter_string, model=StockItem) + + def test_label_rendering(self): + """Test label rendering""" + + labels = [PartLabel.objects.first(), ] + part = PartLabel.objects.first() + + for label in labels: + url = reverse('api-part-label-print', kwargs={'pk': label.pk}) + self.get(f'{url}?parts={part.pk}', expected_code=200) From 352e718e682fd20bba41ef47e16f31d6b6aafc6c Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 11 May 2022 04:03:30 +0200 Subject: [PATCH 4/9] remove digikey barcode plugin --- InvenTree/barcodes/plugins/digikey_barcode.py | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 InvenTree/barcodes/plugins/digikey_barcode.py diff --git a/InvenTree/barcodes/plugins/digikey_barcode.py b/InvenTree/barcodes/plugins/digikey_barcode.py deleted file mode 100644 index 656cdfa6f4..0000000000 --- a/InvenTree/barcodes/plugins/digikey_barcode.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -DigiKey barcode decoding -""" - -from barcodes.barcode import BarcodePlugin - - -class DigikeyBarcodePlugin(BarcodePlugin): - - PLUGIN_NAME = "DigikeyBarcode" - - def validate(self): - """ - TODO: Validation of Digikey barcodes. - """ - - return False From 9a69f125a9e178f9f94c33d3ce4dc82ccd75dfaa Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 11 May 2022 04:08:13 +0200 Subject: [PATCH 5/9] move barcodes to plugin --- InvenTree/InvenTree/settings.py | 2 +- InvenTree/InvenTree/urls.py | 4 +- InvenTree/barcodes/barcode.py | 20 ------ .../{barcodes/api.py => plugin/barcode.py} | 8 +-- InvenTree/plugin/builtin/barcode/__init__.py | 0 .../{ => plugin/builtin}/barcodes/__init__.py | 0 .../builtin/barcodes}/inventree_barcode.py | 5 +- .../builtin/{barcode => barcodes}/mixins.py | 0 .../barcodes/test_inventree_barcode.py | 62 +++++++++++++++++++ InvenTree/plugin/mixins/__init__.py | 2 +- .../tests.py => plugin/tests_barcode.py} | 54 ---------------- 11 files changed, 72 insertions(+), 85 deletions(-) delete mode 100644 InvenTree/barcodes/barcode.py rename InvenTree/{barcodes/api.py => plugin/barcode.py} (97%) delete mode 100644 InvenTree/plugin/builtin/barcode/__init__.py rename InvenTree/{ => plugin/builtin}/barcodes/__init__.py (100%) rename InvenTree/{barcodes/plugins => plugin/builtin/barcodes}/inventree_barcode.py (96%) rename InvenTree/plugin/builtin/{barcode => barcodes}/mixins.py (100%) create mode 100644 InvenTree/plugin/builtin/barcodes/test_inventree_barcode.py rename InvenTree/{barcodes/tests.py => plugin/tests_barcode.py} (79%) diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 3012cdc61f..2817664908 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -900,7 +900,7 @@ PLUGINS_ENABLED = _is_true(get_setting( PLUGIN_FILE = get_plugin_file() # Plugin Directories (local plugins will be loaded from these directories) -PLUGIN_DIRS = ['plugin.builtin', 'barcodes.plugins', ] +PLUGIN_DIRS = ['plugin.builtin', ] if not TESTING: # load local deploy directory in prod diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index 2b31d7c3b5..d408bd7346 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -18,7 +18,6 @@ from build.urls import build_urls from order.urls import order_urls from plugin.urls import get_plugin_urls -from barcodes.api import barcode_api_urls from common.api import common_api_urls, settings_api_urls from part.api import part_api_urls, bom_api_urls from company.api import company_api_urls @@ -28,6 +27,7 @@ from order.api import order_api_urls from label.api import label_api_urls from report.api import report_api_urls from plugin.api import plugin_api_urls +from plugin.barcode import barcode_api_urls from django.conf import settings from django.conf.urls.static import static @@ -59,7 +59,6 @@ if settings.PLUGINS_ENABLED: ) apipatterns += [ - re_path(r'^barcode/', include(barcode_api_urls)), re_path(r'^settings/', include(settings_api_urls)), re_path(r'^part/', include(part_api_urls)), re_path(r'^bom/', include(bom_api_urls)), @@ -75,6 +74,7 @@ apipatterns += [ # Plugin endpoints re_path(r'^action/', ActionPluginView.as_view(), name='api-action-plugin'), + re_path(r'^barcode/', include(barcode_api_urls)), # Webhook enpoint path('', include(common_api_urls)), diff --git a/InvenTree/barcodes/barcode.py b/InvenTree/barcodes/barcode.py deleted file mode 100644 index 030552c866..0000000000 --- a/InvenTree/barcodes/barcode.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -import warnings - -import plugin.builtin.barcode.mixins as mixin -import plugin.integration - - -hash_barcode = mixin.hash_barcode - - -class BarcodePlugin(mixin.BarcodeMixin, plugin.integration.IntegrationPluginBase): - """ - Legacy barcode plugin definition - will be replaced - Please use the new Integration Plugin API and the BarcodeMixin - """ - # TODO @matmair remove this with InvenTree 0.7.0 - def __init__(self, barcode_data=None): - warnings.warn("using the BarcodePlugin is depreceated", DeprecationWarning) - super().__init__() - self.init(barcode_data) diff --git a/InvenTree/barcodes/api.py b/InvenTree/plugin/barcode.py similarity index 97% rename from InvenTree/barcodes/api.py rename to InvenTree/plugin/barcode.py index f36e4b1703..98b111f073 100644 --- a/InvenTree/barcodes/api.py +++ b/InvenTree/plugin/barcode.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- - -from django.urls import reverse -from django.urls import path, re_path +from django.urls import reverse, path, re_path from django.utils.translation import gettext_lazy as _ from rest_framework.exceptions import ValidationError @@ -12,8 +10,8 @@ from rest_framework.views import APIView from stock.models import StockItem from stock.serializers import StockItemSerializer -from barcodes.plugins.inventree_barcode import InvenTreeBarcodePlugin -from barcodes.barcode import hash_barcode +from plugin.builtin.barcodes.inventree_barcode import InvenTreeBarcodePlugin +from plugin.builtin.barcodes.mixins import hash_barcode from plugin import registry diff --git a/InvenTree/plugin/builtin/barcode/__init__.py b/InvenTree/plugin/builtin/barcode/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/InvenTree/barcodes/__init__.py b/InvenTree/plugin/builtin/barcodes/__init__.py similarity index 100% rename from InvenTree/barcodes/__init__.py rename to InvenTree/plugin/builtin/barcodes/__init__.py diff --git a/InvenTree/barcodes/plugins/inventree_barcode.py b/InvenTree/plugin/builtin/barcodes/inventree_barcode.py similarity index 96% rename from InvenTree/barcodes/plugins/inventree_barcode.py rename to InvenTree/plugin/builtin/barcodes/inventree_barcode.py index 5df71cb776..a8d7252f49 100644 --- a/InvenTree/barcodes/plugins/inventree_barcode.py +++ b/InvenTree/plugin/builtin/barcodes/inventree_barcode.py @@ -13,7 +13,8 @@ references model objects actually exist in the database. import json -from barcodes.barcode import BarcodePlugin +import plugin.integration +from .mixins import BarcodeMixin from stock.models import StockItem, StockLocation from part.models import Part @@ -21,7 +22,7 @@ from part.models import Part from rest_framework.exceptions import ValidationError -class InvenTreeBarcodePlugin(BarcodePlugin): +class InvenTreeBarcodePlugin(BarcodeMixin, plugin.integration.IntegrationPluginBase): PLUGIN_NAME = "InvenTreeBarcode" diff --git a/InvenTree/plugin/builtin/barcode/mixins.py b/InvenTree/plugin/builtin/barcodes/mixins.py similarity index 100% rename from InvenTree/plugin/builtin/barcode/mixins.py rename to InvenTree/plugin/builtin/barcodes/mixins.py diff --git a/InvenTree/plugin/builtin/barcodes/test_inventree_barcode.py b/InvenTree/plugin/builtin/barcodes/test_inventree_barcode.py new file mode 100644 index 0000000000..1424d89ff2 --- /dev/null +++ b/InvenTree/plugin/builtin/barcodes/test_inventree_barcode.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +"""Unit tests for InvenTreeBarcodePlugin""" + +from django.contrib.auth import get_user_model +from django.urls import reverse + +from rest_framework.test import APITestCase +from rest_framework import status + + +class TestInvenTreeBarcode(APITestCase): + + fixtures = [ + 'category', + 'part', + 'location', + 'stock' + ] + + def setUp(self): + # Create a user for auth + user = get_user_model() + user.objects.create_user('testuser', 'test@testing.com', 'password') + + self.client.login(username='testuser', password='password') + + def test_errors(self): + """ + Test all possible error cases for assigment action + """ + + def test_assert_error(barcode_data): + response = self.client.post( + reverse('api-barcode-link'), format='json', + data={ + 'barcode': barcode_data, + 'stockitem': 521 + } + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertIn('error', response.data) + + # test with already existing stock + test_assert_error('{"stockitem": 521}') + + # test with already existing stock location + test_assert_error('{"stocklocation": 7}') + + # test with already existing part location + test_assert_error('{"part": 10004}') + + # test with hash + test_assert_error('{"blbla": 10004}') + + def test_scan(self): + """ + Test that a barcode can be scanned + """ + + response = self.client.post(reverse('api-barcode-scan'), format='json', data={'barcode': 'blbla=10004'}) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertIn('success', response.data) diff --git a/InvenTree/plugin/mixins/__init__.py b/InvenTree/plugin/mixins/__init__.py index fdbe863e19..97d27b48fc 100644 --- a/InvenTree/plugin/mixins/__init__.py +++ b/InvenTree/plugin/mixins/__init__.py @@ -7,7 +7,7 @@ from ..builtin.integration.mixins import APICallMixin, AppMixin, LabelPrintingMi from common.notifications import SingleNotificationMethod, BulkNotificationMethod from ..builtin.action.mixins import ActionMixin -from ..builtin.barcode.mixins import BarcodeMixin +from ..builtin.barcodes.mixins import BarcodeMixin __all__ = [ 'APICallMixin', diff --git a/InvenTree/barcodes/tests.py b/InvenTree/plugin/tests_barcode.py similarity index 79% rename from InvenTree/barcodes/tests.py rename to InvenTree/plugin/tests_barcode.py index 18d4e77d20..33b171d666 100644 --- a/InvenTree/barcodes/tests.py +++ b/InvenTree/plugin/tests_barcode.py @@ -214,57 +214,3 @@ class BarcodeAPITest(APITestCase): self.assertIn('error', data) self.assertNotIn('success', data) - - -class TestInvenTreeBarcode(APITestCase): - - fixtures = [ - 'category', - 'part', - 'location', - 'stock' - ] - - def setUp(self): - # Create a user for auth - user = get_user_model() - user.objects.create_user('testuser', 'test@testing.com', 'password') - - self.client.login(username='testuser', password='password') - - def test_errors(self): - """ - Test all possible error cases for assigment action - """ - - def test_assert_error(barcode_data): - response = self.client.post( - reverse('api-barcode-link'), format='json', - data={ - 'barcode': barcode_data, - 'stockitem': 521 - } - ) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertIn('error', response.data) - - # test with already existing stock - test_assert_error('{"stockitem": 521}') - - # test with already existing stock location - test_assert_error('{"stocklocation": 7}') - - # test with already existing part location - test_assert_error('{"part": 10004}') - - # test with hash - test_assert_error('{"blbla": 10004}') - - def test_scan(self): - """ - Test that a barcode can be scanned - """ - - response = self.client.post(reverse('api-barcode-scan'), format='json', data={'barcode': 'blbla=10004'}) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertIn('success', response.data) From fa8a72639990c78c088360d9cc2be3f2964f18cf Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 11 May 2022 04:08:26 +0200 Subject: [PATCH 6/9] activate barcode tests --- InvenTree/label/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/label/tests.py b/InvenTree/label/tests.py index 0adc81abd4..d8c3b6013f 100644 --- a/InvenTree/label/tests.py +++ b/InvenTree/label/tests.py @@ -91,7 +91,7 @@ class LabelTest(InvenTreeAPITestCase): def test_label_rendering(self): """Test label rendering""" - labels = [PartLabel.objects.first(), ] + labels = PartLabel.objects.all() part = PartLabel.objects.first() for label in labels: From 462713ca61ae8f74df7d21f324b1419289357605 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 11 May 2022 04:22:42 +0200 Subject: [PATCH 7/9] pep fix --- InvenTree/label/tests.py | 1 - 1 file changed, 1 deletion(-) diff --git a/InvenTree/label/tests.py b/InvenTree/label/tests.py index d8c3b6013f..53724a36fc 100644 --- a/InvenTree/label/tests.py +++ b/InvenTree/label/tests.py @@ -5,7 +5,6 @@ from __future__ import unicode_literals import os -from django.test import TestCase from django.conf import settings from django.apps import apps from django.urls import reverse From f0d2730ae6abfe119317aecb5621d4e654ca430a Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 11 May 2022 12:16:06 +0200 Subject: [PATCH 8/9] rename file to fit structure --- InvenTree/plugin/{tests_barcode.py => test_barcode.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename InvenTree/plugin/{tests_barcode.py => test_barcode.py} (100%) diff --git a/InvenTree/plugin/tests_barcode.py b/InvenTree/plugin/test_barcode.py similarity index 100% rename from InvenTree/plugin/tests_barcode.py rename to InvenTree/plugin/test_barcode.py From 3c9e4e7eabe7f9c594b92d7804ed337b49c5d560 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 11 May 2022 12:17:46 +0200 Subject: [PATCH 9/9] make imports easier --- InvenTree/plugin/builtin/barcodes/inventree_barcode.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/InvenTree/plugin/builtin/barcodes/inventree_barcode.py b/InvenTree/plugin/builtin/barcodes/inventree_barcode.py index 4cfbf1cb85..939bf12c08 100644 --- a/InvenTree/plugin/builtin/barcodes/inventree_barcode.py +++ b/InvenTree/plugin/builtin/barcodes/inventree_barcode.py @@ -13,8 +13,8 @@ references model objects actually exist in the database. import json -import plugin.integration -from .mixins import BarcodeMixin +from plugin import IntegrationPluginBase +from plugin.mixins import BarcodeMixin from stock.models import StockItem, StockLocation from part.models import Part @@ -22,7 +22,7 @@ from part.models import Part from rest_framework.exceptions import ValidationError -class InvenTreeBarcodePlugin(BarcodeMixin, plugin.integration.IntegrationPluginBase): +class InvenTreeBarcodePlugin(BarcodeMixin, IntegrationPluginBase): PLUGIN_NAME = "InvenTreeBarcode"