2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-28 11:36:44 +00:00
InvenTree/InvenTree/plugin/builtin/barcodes/inventree_barcode.py
Oliver 7af2bb4e8c
Order barcodes (#4575)
* Add barcode support to external orders

- ReturnOrder
- PurchaseOrder
- SalesOrder

* Support scanning for new model types

* Integrate UI elements for ReturnOrder

* Update PurchaseOrder page

* SalesOrder implementation
2023-04-04 11:30:49 +10:00

114 lines
3.7 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 django.utils.translation import gettext_lazy as _
import company.models
import order.models
import part.models
import stock.models
from InvenTree.helpers import hash_barcode
from plugin import InvenTreePlugin
from plugin.mixins import BarcodeMixin
class InvenTreeInternalBarcodePlugin(BarcodeMixin, InvenTreePlugin):
"""Builtin BarcodePlugin for matching and generating internal barcodes."""
NAME = "InvenTreeBarcode"
TITLE = _("InvenTree Barcodes")
DESCRIPTION = _("Provides native support for barcodes")
VERSION = "2.0.0"
AUTHOR = _("InvenTree contributors")
@staticmethod
def get_supported_barcode_models():
"""Returns a list of database models which support barcode functionality"""
return [
company.models.SupplierPart,
order.models.PurchaseOrder,
order.models.ReturnOrder,
order.models.SalesOrder,
part.models.Part,
stock.models.StockItem,
stock.models.StockLocation,
]
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 # pragma: no cover
response = {
label: data
}
if url is not None:
response['url'] = url
return response
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
"""
# Create hash from raw barcode data
barcode_hash = hash_barcode(barcode_data)
# Attempt to coerce the barcode data into a dict object
# This is the internal barcode representation that InvenTree uses
barcode_dict = None
if type(barcode_data) is dict:
barcode_dict = barcode_data
elif type(barcode_data) is str:
try:
barcode_dict = json.loads(barcode_data)
except json.JSONDecodeError:
pass
if barcode_dict is not None and type(barcode_dict) is dict:
# 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_dict:
try:
instance = model.objects.get(pk=barcode_dict[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.barcode_model_type()
instance = model.lookup_barcode(barcode_hash)
if instance is not None:
return self.format_matched_response(label, model, instance)