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

1"""The TMEBarcodePlugin is meant to integrate the TME API into InvenTree. 

2 

3This plugin can currently only match TME barcodes to supplier parts. 

4""" 

5 

6import re 

7 

8from django.utils.translation import gettext_lazy as _ 

9 

10from plugin import InvenTreePlugin 

11from plugin.mixins import SettingsMixin, SupplierBarcodeMixin 

12 

13 

14class TMEPlugin(SupplierBarcodeMixin, SettingsMixin, InvenTreePlugin): 

15 """Plugin to integrate the TME API into InvenTree.""" 

16 

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') 

23 

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 } 

33 

34 TME_IS_QRCODE_REGEX = re.compile(r'([^\s:]+:[^\s:]+\s+)+(\S+(\s|$)+)+') 

35 TME_IS_OLD_BARCODE2D_REGEX = re.compile(r'(([^\s]+)(\s+|$))+') 

36 

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 } 

45 

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 = {} 

49 

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) 

65 

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 

71 

72 return barcode_fields