2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-18 13:05:42 +00:00
Files
InvenTree/InvenTree/plugin/builtin/barcodes/inventree_barcode.py

107 lines
3.3 KiB
Python

"""The InvenTreeBarcodePlugin validates barcodes generated by InvenTree itself. It can be used as a template for developing third-party barcode plugins.
The data format is very simple, and maps directly to database objects,
via the "id" parameter.
Parsing an InvenTree barcode simply involves validating that the
references model objects actually exist in the database.
"""
import json
from company.models import SupplierPart
from InvenTree.helpers import hash_barcode
from part.models import Part
from plugin import InvenTreePlugin
from plugin.mixins import BarcodeMixin
from stock.models import StockItem, StockLocation
class InvenTreeBarcodePlugin(BarcodeMixin, InvenTreePlugin):
"""Generic base class for handling InvenTree barcodes"""
@staticmethod
def get_supported_barcode_models():
"""Returns a list of database models which support barcode functionality"""
return [
Part,
StockItem,
StockLocation,
SupplierPart,
]
def format_matched_response(self, label, model, instance):
"""Format a response for the scanned data"""
data = {
'pk': instance.pk
}
# Add in the API URL if available
if hasattr(model, 'get_api_url'):
data['api_url'] = f"{model.get_api_url()}{instance.pk}/"
# Add in the web URL if available
if hasattr(instance, 'get_absolute_url'):
url = instance.get_absolute_url()
data['web_url'] = url
else:
url = None
response = {
label: data
}
if url is not None:
response['url'] = url
return response
class InvenTreeInternalBarcodePlugin(InvenTreeBarcodePlugin):
"""Builtin BarcodePlugin for matching and generating internal barcodes."""
NAME = "InvenTreeInternalBarcode"
TITLE = "Inventree Barcodes"
def scan(self, barcode_data):
"""Scan a barcode against this plugin.
Here we are looking for a dict object which contains a reference to a particular InvenTree database object
"""
if type(barcode_data) is dict:
pass
elif type(barcode_data) is str:
try:
barcode_data = json.loads(barcode_data)
except json.JSONDecodeError:
return None
else:
return None
if type(barcode_data) is not dict:
return None
barcode_hash = hash_barcode(barcode_data)
# Look for various matches. First good match will be returned
for model in self.get_supported_barcode_models():
label = model.barcode_model_type()
if label in barcode_data:
try:
instance = model.objects.get(pk=barcode_data[label])
return self.format_matched_response(label, model, instance)
except (ValueError, model.DoesNotExist):
pass
# If no "direct" hits are found, look for assigned third-party barcodes
for model in self.get_supported_barcode_models():
label = model.get_barcode_model_type()
instance = model.lookup_barcode(barcode_hash)
if instance is not None:
return self.format_matched_response(label, model, instance)