mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-28 11:36:44 +00:00
* 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
114 lines
3.7 KiB
Python
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)
|