mirror of
https://github.com/inventree/InvenTree.git
synced 2026-09-03 11:28:49 +00:00
* extend barcode scans with user perm check * fix import * fix call * align error message * add missing permissions to test * remove erronous assign * ensure permission erros knock through
591 lines
23 KiB
Python
591 lines
23 KiB
Python
"""Tests barcode parsing for all suppliers."""
|
|
|
|
from django.urls import reverse
|
|
|
|
from company.models import Company, ManufacturerPart, SupplierPart
|
|
from InvenTree.unit_test import InvenTreeAPITestCase
|
|
from order.models import PurchaseOrder, PurchaseOrderLineItem
|
|
from part.models import Part
|
|
from plugin.registry import registry
|
|
from stock.models import StockItem, StockLocation
|
|
|
|
|
|
class SupplierBarcodeTests(InvenTreeAPITestCase):
|
|
"""Tests barcode parsing for all suppliers."""
|
|
|
|
SCAN_URL = reverse('api-barcode-scan')
|
|
roles = [
|
|
'stock.view',
|
|
'stock_location.view',
|
|
'part.view',
|
|
'company.view',
|
|
'order.view',
|
|
]
|
|
|
|
@classmethod
|
|
def setUpTestData(cls):
|
|
"""Create supplier parts for barcodes."""
|
|
super().setUpTestData()
|
|
|
|
# Enable the plugins
|
|
registry.set_plugin_state('digikeyplugin', True)
|
|
registry.set_plugin_state('mouserplugin', True)
|
|
registry.set_plugin_state('lcscplugin', True)
|
|
registry.set_plugin_state('tmeplugin', True)
|
|
|
|
part = Part.objects.create(name='Test Part', description='Test Part')
|
|
|
|
manufacturer = Company.objects.create(
|
|
name='Test Manufacturer', is_manufacturer=True
|
|
)
|
|
|
|
mpart1 = ManufacturerPart.objects.create(
|
|
part=part, manufacturer=manufacturer, MPN='MC34063ADR'
|
|
)
|
|
mpart2 = ManufacturerPart.objects.create(
|
|
part=part, manufacturer=manufacturer, MPN='LDK320ADU33R'
|
|
)
|
|
|
|
digikey_supplier = Company.objects.create(name='Supplier', is_supplier=True)
|
|
mouser_supplier = Company.objects.create(name='Mouser Test', is_supplier=True)
|
|
|
|
supplier_parts = [
|
|
SupplierPart(
|
|
SKU='296-LM358BIDDFRCT-ND', part=part, supplier=digikey_supplier
|
|
),
|
|
SupplierPart(SKU='C312270', part=part, supplier=digikey_supplier),
|
|
SupplierPart(SKU='WBP-302', part=part, supplier=digikey_supplier),
|
|
SupplierPart(
|
|
SKU='1', part=part, manufacturer_part=mpart1, supplier=mouser_supplier
|
|
),
|
|
SupplierPart(
|
|
SKU='2', part=part, manufacturer_part=mpart2, supplier=mouser_supplier
|
|
),
|
|
]
|
|
|
|
SupplierPart.objects.bulk_create(supplier_parts)
|
|
|
|
# Assign supplier information to the plugins
|
|
# Add supplier information to each custom plugin
|
|
registry.set_plugin_state('digikeyplugin', True)
|
|
digikey_plugin = registry.get_plugin('digikeyplugin')
|
|
digikey_plugin.set_setting('SUPPLIER_ID', digikey_supplier.pk)
|
|
|
|
registry.set_plugin_state('mouserplugin', True)
|
|
mouser_plugin = registry.get_plugin('mouserplugin')
|
|
mouser_plugin.set_setting('SUPPLIER_ID', mouser_supplier.pk)
|
|
|
|
def test_digikey_barcode(self):
|
|
"""Test digikey barcode."""
|
|
result = self.post(
|
|
self.SCAN_URL, data={'barcode': DIGIKEY_BARCODE}, expected_code=200
|
|
)
|
|
self.assertEqual(result.data['plugin'], 'DigiKeyBarcodePlugin')
|
|
|
|
supplier_part_data = result.data.get('supplierpart')
|
|
self.assertIn('pk', supplier_part_data)
|
|
|
|
supplier_part = SupplierPart.objects.get(pk=supplier_part_data['pk'])
|
|
self.assertEqual(supplier_part.SKU, '296-LM358BIDDFRCT-ND')
|
|
|
|
def test_digikey_2_barcode(self):
|
|
"""Test digikey barcode which uses 30P instead of P."""
|
|
result = self.post(
|
|
self.SCAN_URL, data={'barcode': DIGIKEY_BARCODE_2}, expected_code=200
|
|
)
|
|
|
|
self.assertEqual(result.data['plugin'], 'DigiKeyBarcodePlugin')
|
|
|
|
supplier_part_data = result.data.get('supplierpart')
|
|
self.assertIn('pk', supplier_part_data)
|
|
|
|
supplier_part = SupplierPart.objects.get(pk=supplier_part_data['pk'])
|
|
self.assertEqual(supplier_part.SKU, '296-LM358BIDDFRCT-ND')
|
|
|
|
def test_digikey_3_barcode(self):
|
|
"""Test digikey barcode which is invalid."""
|
|
self.post(self.SCAN_URL, data={'barcode': DIGIKEY_BARCODE_3}, expected_code=400)
|
|
|
|
def test_mouser_barcode(self):
|
|
"""Test mouser barcode with custom order number."""
|
|
result = self.post(
|
|
self.SCAN_URL, data={'barcode': MOUSER_BARCODE}, expected_code=200
|
|
)
|
|
|
|
supplier_part_data = result.data.get('supplierpart')
|
|
self.assertIn('pk', supplier_part_data)
|
|
|
|
supplier_part = SupplierPart.objects.get(pk=supplier_part_data['pk'])
|
|
self.assertEqual(supplier_part.SKU, '1')
|
|
|
|
def test_old_mouser_barcode(self):
|
|
"""Test old mouser barcode with messed up header."""
|
|
registry.set_plugin_state('mouserplugin', False)
|
|
|
|
# Initial scan should fail - plugin not enabled
|
|
self.post(
|
|
self.SCAN_URL, data={'barcode': MOUSER_BARCODE_OLD}, expected_code=400
|
|
)
|
|
|
|
registry.set_plugin_state('mouserplugin', True)
|
|
|
|
result = self.post(
|
|
self.SCAN_URL, data={'barcode': MOUSER_BARCODE_OLD}, expected_code=200
|
|
)
|
|
|
|
supplier_part_data = result.data.get('supplierpart')
|
|
self.assertIn('pk', supplier_part_data)
|
|
supplier_part = SupplierPart.objects.get(pk=supplier_part_data['pk'])
|
|
self.assertEqual(supplier_part.SKU, '2')
|
|
|
|
def test_lcsc_barcode(self):
|
|
"""Test LCSC barcode."""
|
|
result = self.post(
|
|
self.SCAN_URL, data={'barcode': LCSC_BARCODE}, expected_code=200
|
|
)
|
|
|
|
self.assertEqual(result.data['plugin'], 'LCSCBarcodePlugin')
|
|
|
|
supplier_part_data = result.data.get('supplierpart')
|
|
self.assertIn('pk', supplier_part_data)
|
|
|
|
supplier_part = SupplierPart.objects.get(pk=supplier_part_data['pk'])
|
|
self.assertEqual(supplier_part.SKU, 'C312270')
|
|
|
|
def test_tme_qrcode(self):
|
|
"""Test TME QR-Code."""
|
|
result = self.post(
|
|
self.SCAN_URL, data={'barcode': TME_QRCODE}, expected_code=200
|
|
)
|
|
|
|
self.assertEqual(result.data['plugin'], 'TMEBarcodePlugin')
|
|
|
|
supplier_part_data = result.data.get('supplierpart')
|
|
self.assertIn('pk', supplier_part_data)
|
|
supplier_part = SupplierPart.objects.get(pk=supplier_part_data['pk'])
|
|
self.assertEqual(supplier_part.SKU, 'WBP-302')
|
|
|
|
def test_tme_barcode2d(self):
|
|
"""Test TME DataMatrix-Code."""
|
|
result = self.post(
|
|
self.SCAN_URL, data={'barcode': TME_DATAMATRIX_CODE}, expected_code=200
|
|
)
|
|
|
|
self.assertEqual(result.data['plugin'], 'TMEBarcodePlugin')
|
|
|
|
supplier_part_data = result.data.get('supplierpart')
|
|
self.assertIn('pk', supplier_part_data)
|
|
|
|
supplier_part = SupplierPart.objects.get(pk=supplier_part_data['pk'])
|
|
self.assertEqual(supplier_part.SKU, 'WBP-302')
|
|
|
|
|
|
class SupplierBarcodePOReceiveTests(InvenTreeAPITestCase):
|
|
"""Tests barcode scanning to receive a purchase order item."""
|
|
|
|
roles = ['stock.view', 'stock_location.view']
|
|
|
|
def setUp(self):
|
|
"""Create supplier part and purchase_order."""
|
|
super().setUp()
|
|
|
|
registry.set_plugin_state('digikeyplugin', True)
|
|
registry.set_plugin_state('mouserplugin', True)
|
|
registry.set_plugin_state('lcscplugin', True)
|
|
registry.set_plugin_state('tmeplugin', True)
|
|
|
|
self.loc_1 = StockLocation.objects.create(name='Location 1')
|
|
self.loc_2 = StockLocation.objects.create(name='Location 2')
|
|
|
|
part = Part.objects.create(name='Test Part', description='Test Part')
|
|
digikey_supplier = Company.objects.create(name='Supplier', is_supplier=True)
|
|
manufacturer = Company.objects.create(
|
|
name='Test Manufacturer', is_manufacturer=True
|
|
)
|
|
|
|
mouser = Company.objects.create(name='Mouser Test', is_supplier=True)
|
|
mpart = ManufacturerPart.objects.create(
|
|
part=part, manufacturer=manufacturer, MPN='MC34063ADR'
|
|
)
|
|
|
|
self.purchase_order1 = PurchaseOrder.objects.create(
|
|
supplier_reference='72991337',
|
|
supplier=digikey_supplier,
|
|
destination=self.loc_1,
|
|
)
|
|
|
|
supplier_parts1 = [
|
|
SupplierPart(SKU=f'1_{i}', part=part, supplier=digikey_supplier)
|
|
for i in range(6)
|
|
]
|
|
|
|
supplier_parts1.insert(
|
|
2,
|
|
SupplierPart(
|
|
SKU='296-LM358BIDDFRCT-ND', part=part, supplier=digikey_supplier
|
|
),
|
|
)
|
|
|
|
for supplier_part in supplier_parts1:
|
|
supplier_part.save()
|
|
self.purchase_order1.add_line_item(supplier_part, 8, destination=self.loc_2)
|
|
|
|
self.purchase_order2 = PurchaseOrder.objects.create(
|
|
reference='P0-1337', supplier=mouser, destination=self.loc_1
|
|
)
|
|
|
|
self.purchase_order2.place_order()
|
|
supplier_parts2 = [
|
|
SupplierPart(SKU=f'2_{i}', part=part, supplier=mouser) for i in range(6)
|
|
]
|
|
|
|
supplier_parts2.insert(
|
|
3,
|
|
SupplierPart(SKU='42', part=part, manufacturer_part=mpart, supplier=mouser),
|
|
)
|
|
|
|
for supplier_part in supplier_parts2:
|
|
supplier_part.save()
|
|
self.purchase_order2.add_line_item(supplier_part, 5, destination=self.loc_2)
|
|
|
|
# Add supplier information to each custom plugin
|
|
registry.set_plugin_state('digikeyplugin', True)
|
|
digikey_plugin = registry.get_plugin('digikeyplugin')
|
|
digikey_plugin.set_setting('SUPPLIER_ID', digikey_supplier.pk)
|
|
|
|
registry.set_plugin_state('mouserplugin', True)
|
|
mouser_plugin = registry.get_plugin('mouserplugin')
|
|
mouser_plugin.set_setting('SUPPLIER_ID', mouser.pk)
|
|
|
|
def test_receive(self):
|
|
"""Test receiving an item from a barcode."""
|
|
url = reverse('api-barcode-po-receive')
|
|
|
|
# First attempt - PO is not yet "placed"
|
|
result1 = self.post(url, data={'barcode': DIGIKEY_BARCODE}, expected_code=400)
|
|
|
|
self.assertIn('received against an order marked as', result1.data['error'])
|
|
|
|
# Next, place the order - receipt should then work
|
|
self.purchase_order1.place_order()
|
|
|
|
result2 = self.post(url, data={'barcode': DIGIKEY_BARCODE}, expected_code=200)
|
|
self.assertIn('success', result2.data)
|
|
|
|
# Attempt to receive the same item again
|
|
# Already received - failure expected
|
|
result3 = self.post(url, data={'barcode': DIGIKEY_BARCODE}, expected_code=400)
|
|
self.assertEqual(result3.data['error'], 'Item has already been received')
|
|
|
|
result5 = self.post(
|
|
reverse('api-barcode-scan'),
|
|
data={'barcode': DIGIKEY_BARCODE},
|
|
expected_code=200,
|
|
)
|
|
|
|
stock_item = StockItem.objects.get(pk=result5.data['stockitem']['pk'])
|
|
self.assertEqual(stock_item.supplier_part.SKU, '296-LM358BIDDFRCT-ND')
|
|
self.assertEqual(stock_item.quantity, 10)
|
|
self.assertEqual(stock_item.location, self.loc_2)
|
|
|
|
def test_no_auto_allocate(self):
|
|
"""Test with auto_allocate explicitly disabled."""
|
|
url = reverse('api-barcode-po-receive')
|
|
self.purchase_order1.place_order()
|
|
|
|
response = self.post(
|
|
url,
|
|
data={'barcode': DIGIKEY_BARCODE, 'auto_allocate': False},
|
|
expected_code=200,
|
|
)
|
|
|
|
self.assertEqual(response.data['plugin'], 'DigiKeyBarcodePlugin')
|
|
self.assertIn('action_required', response.data)
|
|
item = response.data['lineitem']
|
|
self.assertEqual(item['quantity'], 10.0)
|
|
self.assertEqual(item['purchase_order'], self.purchase_order1.pk)
|
|
self.assertEqual(item['location'], self.loc_2.pk)
|
|
|
|
def test_receive_custom_order_number(self):
|
|
"""Test receiving an item from a barcode with a custom order number."""
|
|
url = reverse('api-barcode-po-receive')
|
|
result1 = self.post(url, data={'barcode': MOUSER_BARCODE}, expected_code=200)
|
|
self.assertIn('success', result1.data)
|
|
|
|
# Scan the same barcode again - should be resolved to the created item
|
|
result2 = self.post(
|
|
reverse('api-barcode-scan'),
|
|
data={'barcode': MOUSER_BARCODE},
|
|
expected_code=200,
|
|
)
|
|
stock_item = StockItem.objects.get(pk=result2.data['stockitem']['pk'])
|
|
|
|
self.assertEqual(stock_item.supplier_part.SKU, '42')
|
|
self.assertEqual(stock_item.supplier_part.manufacturer_part.MPN, 'MC34063ADR')
|
|
self.assertEqual(stock_item.quantity, 3)
|
|
self.assertEqual(stock_item.location, self.loc_2)
|
|
self.assertEqual(stock_item.barcode_data, MOUSER_BARCODE)
|
|
|
|
def test_receive_stock_location(self):
|
|
"""Test receiving an item when the location is provided."""
|
|
stock_location = StockLocation.objects.create(name='Test Location')
|
|
|
|
url = reverse('api-barcode-po-receive')
|
|
|
|
result1 = self.post(
|
|
url,
|
|
data={'barcode': MOUSER_BARCODE, 'location': stock_location.pk},
|
|
expected_code=200,
|
|
)
|
|
|
|
self.assertIn('success', result1.data)
|
|
|
|
result2 = self.post(
|
|
reverse('api-barcode-scan'),
|
|
data={'barcode': MOUSER_BARCODE},
|
|
expected_code=200,
|
|
)
|
|
|
|
stock_item = StockItem.objects.get(pk=result2.data['stockitem']['pk'])
|
|
self.assertEqual(stock_item.location, stock_location)
|
|
|
|
def test_receive_default_line_item_location(self):
|
|
"""Test receiving an item into the default line_item location."""
|
|
StockLocation.objects.create(name='Test Location 1')
|
|
stock_location2 = StockLocation.objects.create(name='Test Location 2')
|
|
|
|
line_item = PurchaseOrderLineItem.objects.filter(part__SKU='42')[0]
|
|
line_item.destination = stock_location2
|
|
line_item.save()
|
|
|
|
url = reverse('api-barcode-po-receive')
|
|
result1 = self.post(url, data={'barcode': MOUSER_BARCODE}, expected_code=200)
|
|
self.assertIn('success', result1.data)
|
|
|
|
result2 = self.post(
|
|
reverse('api-barcode-scan'),
|
|
data={'barcode': MOUSER_BARCODE},
|
|
expected_code=200,
|
|
)
|
|
stock_item = StockItem.objects.get(pk=result2.data['stockitem']['pk'])
|
|
self.assertEqual(stock_item.location, stock_location2)
|
|
|
|
def test_receive_default_part_location(self):
|
|
"""Test receiving an item into the default part location."""
|
|
StockLocation.objects.create(name='Test Location 1')
|
|
stock_location2 = StockLocation.objects.create(name='Test Location 2')
|
|
|
|
# Ensure no other fallback locations are set
|
|
# This is to ensure that the part location is used instead
|
|
self.purchase_order2.destination = None
|
|
self.purchase_order2.save()
|
|
|
|
for line in self.purchase_order2.lines.all():
|
|
line.destination = None
|
|
line.save()
|
|
|
|
part = Part.objects.all()[0]
|
|
part.default_location = stock_location2
|
|
part.save()
|
|
|
|
url = reverse('api-barcode-po-receive')
|
|
result1 = self.post(url, data={'barcode': MOUSER_BARCODE}, expected_code=200)
|
|
self.assertIn('success', result1.data)
|
|
|
|
result2 = self.post(
|
|
reverse('api-barcode-scan'),
|
|
data={'barcode': MOUSER_BARCODE},
|
|
expected_code=200,
|
|
)
|
|
stock_item = StockItem.objects.get(pk=result2.data['stockitem']['pk'])
|
|
self.assertEqual(stock_item.location, stock_location2)
|
|
|
|
def test_receive_specific_order_and_location(self):
|
|
"""Test receiving an item from a specific order into a specific location."""
|
|
StockLocation.objects.create(name='Test Location 1')
|
|
stock_location2 = StockLocation.objects.create(name='Test Location 2')
|
|
|
|
url = reverse('api-barcode-po-receive')
|
|
barcode = MOUSER_BARCODE.replace('\x1dKP0-1337', '')
|
|
result1 = self.post(
|
|
url,
|
|
data={
|
|
'barcode': barcode,
|
|
'purchase_order': self.purchase_order2.pk,
|
|
'location': stock_location2.pk,
|
|
},
|
|
expected_code=200,
|
|
)
|
|
self.assertIn('success', result1.data)
|
|
|
|
result2 = self.post(
|
|
reverse('api-barcode-scan'), data={'barcode': barcode}, expected_code=200
|
|
)
|
|
stock_item = StockItem.objects.get(pk=result2.data['stockitem']['pk'])
|
|
self.assertEqual(stock_item.location, stock_location2)
|
|
|
|
def test_receive_missing_quantity(self):
|
|
"""Test receiving an with missing quantity information."""
|
|
url = reverse('api-barcode-po-receive')
|
|
barcode = MOUSER_BARCODE.replace('\x1dQ3', '')
|
|
response = self.post(url, data={'barcode': barcode}, expected_code=200)
|
|
|
|
self.assertIn('action_required', response.data)
|
|
|
|
self.assertIn('lineitem', response.data)
|
|
|
|
# Quantity should be pre-filled with the remaining quantity
|
|
self.assertEqual(5, response.data['lineitem']['quantity'])
|
|
|
|
def test_receive_includes_no_match_false(self):
|
|
"""Successful receive merges no_match=False from the plugin response."""
|
|
self.purchase_order1.place_order()
|
|
url = reverse('api-barcode-po-receive')
|
|
|
|
result = self.post(url, data={'barcode': DIGIKEY_BARCODE}, expected_code=200)
|
|
|
|
self.assertIn('success', result.data)
|
|
self.assertIn('no_match', result.data)
|
|
self.assertFalse(result.data['no_match'])
|
|
|
|
def test_partial_match_po_found_no_supplier_part(self):
|
|
"""Barcode references a known PO but the SKU has no matching supplier part."""
|
|
url = reverse('api-barcode-po-receive')
|
|
|
|
# '1K72991337' matches purchase_order1 via supplier_reference; SKU is unknown
|
|
result = self.post(
|
|
url, data={'barcode': DIGIKEY_BARCODE_PO_NO_PART}, expected_code=400
|
|
)
|
|
|
|
self.assertIn('error', result.data)
|
|
self.assertIn('Purchase order Found', result.data['error'])
|
|
self.assertIn('No supplier Part Match', result.data['error'])
|
|
|
|
self.assertIn('supplier_matches', result.data)
|
|
matches = result.data['supplier_matches']
|
|
self.assertIsNotNone(matches['purchase_order'])
|
|
# DRF's ValidationError converts None leaves to ErrorDetail('None')
|
|
self.assertEqual(str(matches['supplier_part']), 'None')
|
|
self.assertIsNotNone(matches['supplier'])
|
|
self.assertTrue(matches['no_match'])
|
|
|
|
def test_partial_match_supplier_part_found_no_po(self):
|
|
"""Barcode references a known supplier part but the PO reference has no match."""
|
|
url = reverse('api-barcode-po-receive')
|
|
|
|
# 'P296-LM358BIDDFRCT-ND' matches the existing supplier part; PO ref is unknown
|
|
result = self.post(
|
|
url, data={'barcode': DIGIKEY_BARCODE_PART_NO_PO}, expected_code=400
|
|
)
|
|
|
|
self.assertIn('error', result.data)
|
|
self.assertIn('Supplier Part Found', result.data['error'])
|
|
self.assertIn('No Purchase Order Match', result.data['error'])
|
|
|
|
self.assertIn('supplier_matches', result.data)
|
|
matches = result.data['supplier_matches']
|
|
# DRF's ValidationError converts None leaves to ErrorDetail('None')
|
|
self.assertEqual(str(matches['purchase_order']), 'None')
|
|
self.assertIsNotNone(matches['supplier_part'])
|
|
self.assertIsNotNone(matches['supplier'])
|
|
self.assertTrue(matches['no_match'])
|
|
|
|
def test_no_supplier_plugin_error(self):
|
|
"""Plugins that cannot resolve a supplier are listed in no_supplier_plugin_error."""
|
|
url = reverse('api-barcode-po-receive')
|
|
|
|
digikey_plugin = registry.get_plugin('digikeyplugin')
|
|
original_supplier_id = digikey_plugin.get_setting('SUPPLIER_ID')
|
|
|
|
# Use a non-existent PK so get_supplier() returns None
|
|
digikey_plugin.set_setting('SUPPLIER_ID', 99999)
|
|
if hasattr(digikey_plugin, '_supplier'):
|
|
del digikey_plugin._supplier
|
|
|
|
try:
|
|
result = self.post(
|
|
url, data={'barcode': DIGIKEY_BARCODE}, expected_code=400
|
|
)
|
|
|
|
self.assertIn('no_supplier_plugin_error', result.data)
|
|
self.assertIn('digikeyplugin', result.data['no_supplier_plugin_error'])
|
|
finally:
|
|
digikey_plugin.set_setting('SUPPLIER_ID', original_supplier_id)
|
|
if hasattr(digikey_plugin, '_supplier'):
|
|
del digikey_plugin._supplier
|
|
|
|
def test_no_supplier_matches_when_both_missing(self):
|
|
"""When neither PO nor supplier part can be resolved, no supplier_matches is set."""
|
|
url = reverse('api-barcode-po-receive')
|
|
|
|
# Completely unknown barcode — no PO, no part, no supplier
|
|
result = self.post(
|
|
url, data={'barcode': 'COMPLETELY-UNKNOWN-BARCODE-XYZ'}, expected_code=400
|
|
)
|
|
|
|
self.assertIn('error', result.data)
|
|
self.assertNotIn('supplier_matches', result.data)
|
|
|
|
|
|
DIGIKEY_BARCODE = (
|
|
'[)>\x1e06\x1dP296-LM358BIDDFRCT-ND\x1d1PLM358BIDDFR\x1dK\x1d1K72991337\x1d'
|
|
'10K85781337\x1d11K1\x1d4LPH\x1dQ10\x1d11ZPICK\x1d12Z15221337\x1d13Z361337'
|
|
'\x1d20Z0000000000000000000000000000000000000000000000000000000000000000000'
|
|
'00000000000000000000000000000000000000000000000000000000000000000000000000'
|
|
'0000000000000000000000000000000000'
|
|
)
|
|
|
|
# Uses 30P instead of P
|
|
DIGIKEY_BARCODE_2 = (
|
|
'[)>\x1e06\x1d30P296-LM358BIDDFRCT-ND\x1dK\x1d1K72991337\x1d'
|
|
'10K85781337\x1d11K1\x1d4LPH\x1dQ10\x1d11ZPICK\x1d12Z15221337\x1d13Z361337'
|
|
'\x1d20Z0000000000000000000000000000000000000000000000000000000000000000000'
|
|
'00000000000000000000000000000000000000000000000000000000000000000000000000'
|
|
'0000000000000000000000000000000000'
|
|
)
|
|
|
|
# Invalid code
|
|
DIGIKEY_BARCODE_3 = (
|
|
'[)>\x1e06\x1dPnonsense\x1d30Pnonsense\x1d1Pnonsense\x1dK\x1d1K72991337\x1d'
|
|
'10K85781337\x1d11K1\x1d4LPH\x1dQ10\x1d11ZPICK\x1d12Z15221337\x1d13Z361337'
|
|
'\x1d20Z0000000000000000000000000000000000000000000000000000000000000000000'
|
|
'00000000000000000000000000000000000000000000000000000000000000000000000000'
|
|
'0000000000000000000000000000000000'
|
|
)
|
|
|
|
MOUSER_BARCODE = (
|
|
'[)>\x1e06\x1dKP0-1337\x1d14K011\x1d1PMC34063ADR\x1dQ3\x1d11K073121337\x1d4'
|
|
'LMX\x1d1VTI\x1e\x04'
|
|
)
|
|
|
|
MOUSER_BARCODE_OLD = (
|
|
'>[)>06\x1dK21421337\x1d14K033\x1d1PLDK320ADU33R\x1dQ32\x1d11K060931337\x1d'
|
|
'4LCN\x1d1VSTMicro'
|
|
)
|
|
|
|
LCSC_BARCODE = (
|
|
'{pbn:PICK2009291337,on:SO2009291337,pc:C312270,pm:ST-1-102-A01-T000-RS,qty'
|
|
':2,mc:,cc:1,pdi:34421807}'
|
|
)
|
|
|
|
TME_QRCODE = (
|
|
'QTY:1 PN:WBP-302 PO:19361337/1 CPO:PO-2023-06-08-001337 MFR:WISHERENTERPRI'
|
|
'SE MPN:WBP-302 RoHS https://www.tme.eu/details/WBP-302'
|
|
)
|
|
|
|
TME_DATAMATRIX_CODE = 'PWBP-302 1PMPNWBP-302 Q1 K19361337/1'
|
|
|
|
# DigiKey barcode: '1K72991337' matches purchase_order1 via supplier_reference,
|
|
# but 'PNONEXISTENT-SKU' has no matching supplier part in the test database.
|
|
DIGIKEY_BARCODE_PO_NO_PART = (
|
|
'[)>\x1e06\x1dPNONEXISTENT-SKU-XXXX\x1d1PNONEXISTENT-MPN\x1dK\x1d1K72991337\x1d'
|
|
'10K85781337\x1d11K1\x1d4LPH\x1dQ10\x1d11ZPICK'
|
|
)
|
|
|
|
# DigiKey barcode: 'P296-LM358BIDDFRCT-ND' matches the existing supplier part,
|
|
# but '1KBADORDER-XXXXX' matches no purchase order in the test database.
|
|
DIGIKEY_BARCODE_PART_NO_PO = (
|
|
'[)>\x1e06\x1dP296-LM358BIDDFRCT-ND\x1d1PLM358BIDDFR\x1dK\x1d1KBADORDER-XXXXX\x1d'
|
|
'10K85781337\x1d11K1\x1d4LPH\x1dQ10\x1d11ZPICK'
|
|
)
|