# django from django.utils.translation import gettext_lazy as _ from django.core.validators import MinValueValidator from django.core.validators import MaxValueValidator from django.http import JsonResponse # printer support import socket import json # barcode helpers from InvenTree.helpers_model import getModelsWithMixin from InvenTree.models import InvenTreeBarcodeMixin # InvenTree plugin libs from plugin import InvenTreePlugin from plugin.mixins import LabelPrintingMixin, SettingsMixin, BarcodeMixin from label.models import LabelTemplate from inventree_phomemo.version import PHOMEMO_PLUGIN_VERSION class PhomemoLabelPlugin(LabelPrintingMixin, BarcodeMixin, SettingsMixin, InvenTreePlugin): AUTHOR = "Sergal.engineering" DESCRIPTION = "Label printing plugin for Phomemo printers" VERSION = PHOMEMO_PLUGIN_VERSION NAME = "Phomemo" SLUG = "phomemo" TITLE = "Phomemo Label Printer" SETTINGS = { 'IP_ADDRESS': { 'name': _('IP Address'), 'description': _('IP address of phomemo print server'), 'default': '', }, 'PORT': { 'name': _('Port'), 'description': _('Port of phomemo print server'), 'default': '9100', }, } def get_fields(self, label_instance): object_to_print = label_instance.object_to_print match label_instance.SUBDIR: case 'part': tpart = object_to_print barcode = '1' + str(object_to_print.pk) case 'stockitem': tpart = object_to_print.part barcode = '2' + str(object_to_print.pk) case 'stocklocation': tpart = object_to_print barcode = '3' + str(object_to_print.pk) case 'build': tpart = object_to_print barcode = '4' + str(object_to_print.pk) case _: tpart = object_to_print barcode = '0' + str(object_to_print.pk) print(f"!! Unsupported item type: {label_instance.SUBDIR}") fields = { 'name': tpart.name, 'description': tpart.description, 'pk': tpart.pk, 'params': tpart.parameters_map() if hasattr(tpart, 'parameters_map') else None, 'category': tpart.category.name if hasattr(tpart, 'category') else None, 'category_path': tpart.category.pathstring if hasattr(tpart, 'category') else None, 'barcode': barcode, 'type': label_instance.SUBDIR, 'width': label_instance.width, 'height': label_instance.height } return fields def print_labels(self, label: LabelTemplate, items: list, request, **kwargs): outputs = [] # Get label content for every label for item in items: label.object_to_print = item outputs.append(self.get_fields(label)) # Read settings ip_address = self.get_setting('IP_ADDRESS') port = int(self.get_setting('PORT')) # Dump to json data = json.dumps(outputs) # Send the label to the printer try: print_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print_socket.settimeout(5) print_socket.connect((ip_address, port)) print_socket.sendall(bytes(data,encoding="utf-8")) print_socket.close() except Exception as error: raise ConnectionError('Error connecting to printer server: ' + str(error)) return JsonResponse({ 'success': True, 'message': f'{len(items)} labels printed', }) @staticmethod def get_supported_barcode_models(): """Returns a list of database models which support barcode functionality.""" return getModelsWithMixin(InvenTreeBarcodeMixin) def format_matched_response(self, label, model, instance): """Format a response for the scanned data.""" return {label: instance.format_matched_response()} def scan(self, barcode_data): # Our barcode should be a string if type(barcode_data) is not str: barcode_data = str(barcode_data) # Our barcodes are at least two symbols long if len(barcode_data) < 2: return match barcode_data[0]: case '1': model_type = 'part' case '2': model_type = 'stockitem' case '3': model_type = 'stocklocation' case '4': model_type = 'build' supported_models = self.get_supported_barcode_models() for model in supported_models: label = model.barcode_model_type() if label == model_type: try: pk = int(barcode_data[1:]) instance = model.objects.get(pk=pk) return self.format_matched_response(label, model, instance) except (ValueError, model.DoesNotExist): pass