Coverage for src/backend/InvenTree/plugin/builtin/suppliers/tme.py: 32%
35 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
1"""The TMEBarcodePlugin is meant to integrate the TME API into InvenTree.
3This plugin can currently only match TME barcodes to supplier parts.
4"""
6import re
8from django.utils.translation import gettext_lazy as _
10from plugin import InvenTreePlugin
11from plugin.mixins import SettingsMixin, SupplierBarcodeMixin
14class TMEPlugin(SupplierBarcodeMixin, SettingsMixin, InvenTreePlugin):
15 """Plugin to integrate the TME API into InvenTree."""
17 NAME = 'TMEBarcodePlugin'
18 SLUG = 'tmeplugin'
19 TITLE = _('Supplier Integration - TME')
20 DESCRIPTION = _('Provides support for scanning TME barcodes')
21 VERSION = '1.0.1'
22 AUTHOR = _('InvenTree contributors')
24 DEFAULT_SUPPLIER_NAME = 'TME'
25 SETTINGS = {
26 'SUPPLIER_ID': {
27 'name': _('Supplier'),
28 'description': _("The Supplier which acts as 'TME'"),
29 'model': 'company.company',
30 'model_filters': {'is_supplier': True},
31 }
32 }
34 TME_IS_QRCODE_REGEX = re.compile(r'([^\s:]+:[^\s:]+\s+)+(\S+(\s|$)+)+')
35 TME_IS_OLD_BARCODE2D_REGEX = re.compile(r'(([^\s]+)(\s+|$))+')
37 # Custom field mapping
38 TME_QRCODE_FIELDS = {
39 'PN': SupplierBarcodeMixin.SUPPLIER_PART_NUMBER,
40 'CPO': SupplierBarcodeMixin.CUSTOMER_ORDER_NUMBER,
41 'PO': SupplierBarcodeMixin.SUPPLIER_ORDER_NUMBER,
42 'MPN': SupplierBarcodeMixin.MANUFACTURER_PART_NUMBER,
43 'QTY': SupplierBarcodeMixin.QUANTITY,
44 }
46 def extract_barcode_fields(self, barcode_data: str) -> dict[str, str]:
47 """Get supplier_part and barcode_fields from TME QR-Code or DataMatrix-Code."""
48 barcode_fields = {}
50 if self.TME_IS_QRCODE_REGEX.fullmatch(barcode_data):
51 # Custom QR Code format e.g. "QTY: 1 PN:12345"
52 for item in barcode_data.split(' '):
53 if ':' in item:
54 key, value = item.split(':')
55 if key in self.TME_QRCODE_FIELDS:
56 barcode_fields[self.TME_QRCODE_FIELDS[key]] = value
57 elif self.TME_IS_OLD_BARCODE2D_REGEX.fullmatch(barcode_data):
58 # Old 2D Barcode format e.g. "PWBP-302 1PMPNWBP-302 Q1 K19361337/1"
59 for item in barcode_data.split(' '):
60 for k, v in self.ecia_field_map().items():
61 if item.startswith(k):
62 barcode_fields[v] = item[len(k) :]
63 else:
64 barcode_fields = self.parse_ecia_barcode2d(barcode_data)
66 # Custom handling for order number
67 if SupplierBarcodeMixin.SUPPLIER_ORDER_NUMBER in barcode_fields:
68 order_number = barcode_fields[SupplierBarcodeMixin.SUPPLIER_ORDER_NUMBER]
69 order_number = order_number.split('/')[0]
70 barcode_fields[SupplierBarcodeMixin.SUPPLIER_ORDER_NUMBER] = order_number
72 return barcode_fields