fix for printer not saved in the recipe import/export

This commit is contained in:
edo-neo 2025-11-10 11:06:56 +01:00
parent 847ee11ca9
commit adb487dffd
4 changed files with 153 additions and 32 deletions

View File

@ -44,6 +44,36 @@ def read_steps(row, config, defaults=None, unsupported_steps=None):
except ValueError:
return 0 # Default to 0 if parsing fails
# Normalize printer_selection to resolution string ("203"/"300")
lp1 = (config.get("label_printer", {}) or {})
lp2 = (config.get("label_printer_2", {}) or {})
def normalize_printer_sel(val):
try:
s = str(val).strip()
except Exception:
s = ""
if s == "":
# default to primary printer resolution
try:
return str(int(lp1.get("risoluzione", 300)))
except Exception:
return "300"
if s.isdigit():
return s
# legacy OS printer name: match lp1 or lp2 names
if s == str(lp1.get("printer", "")):
try:
return str(int(lp1.get("risoluzione", 300)))
except Exception:
return "300"
if s == str(lp2.get("printer", "")):
try:
return str(int(lp2.get("risoluzione", 300)))
except Exception:
return "300"
# unknown string; keep as-is
return s
# Define the steps dictionary
steps = {
"count": {
@ -158,7 +188,8 @@ def read_steps(row, config, defaults=None, unsupported_steps=None):
"labeltxt_5": row.get("barcode_input_finelinea", ""),
"extra_label": row.get("etichette_supplementari", ""),
"barcode": row.get("barcode_stampato",defaults["barcode_format"]),
"printer_selection": row.get("printer_selection", (config.get("label_printer", {}) or {}).get("printer", "")),
# Store resolution instead of printer name; map legacy names to their resolution
"printer_selection": normalize_printer_sel(row.get("printer_selection", lp1.get("risoluzione", 300))),
},
}
@ -436,7 +467,11 @@ def export_recipes(config, csv_path=None, logger=None):
exportable.update({
"stampa_etichetta_abilitata": "x",
print_template_field: steps["print"].spec["template"],
"printer_selection": steps["print"].spec.get("printer_selection", (config.get("label_printer", {}) or {}).get("printer", "")),
# Export resolution string; fallback to primary printer resolution from config
"printer_selection": steps["print"].spec.get(
"printer_selection",
str((config.get("label_printer", {}) or {}).get("risoluzione", 300)),
),
})
fieldnames.update(["stampa_etichetta_abilitata", print_template_field, "printer_selection"])

View File

@ -36,20 +36,40 @@ class Print_Step_Editor(Editor):
self._on_printer_changed(self.printer_selection.currentText())
def render(self, data, field_name=None, row_number=None, crud=None):
# Preserve current template choice from data then adjust list for selected printer
# Preserve current template choice from data then adjust list for selected printer/resolution
current_template = data.get("template", None)
super().render(data, field_name=field_name, row_number=row_number, crud=crud)
# Re-apply templates list based on printer and restore selection
# If stored value is a legacy printer name, convert to its resolution for the combo
try:
stored = str(data.get("printer_selection", "")).strip()
except Exception:
stored = ""
if stored and not stored.isdigit() and stored in self._printers_resolution:
try:
self.printer_selection.setCurrentText(str(int(self._printers_resolution.get(stored, 300))))
except Exception:
pass
# Re-apply templates list based on current selection and restore previous template if possible
self._on_printer_changed(self.printer_selection.currentText(), initial_template=current_template)
def _on_printer_changed(self, printer_name, initial_template=None):
# If no mapping for this printer, keep current list (use machine's default)
if not printer_name or printer_name not in self._printers_resolution:
def _on_printer_changed(self, value, initial_template=None):
# Determine resolution from current selection: it can be a resolution string ("203"/"300") or a legacy printer name
if not value:
return
# Decide resolution from mapping provided by recipe_selection
try:
res = int(self._printers_resolution.get(printer_name, 300))
except Exception:
res = None
v = str(value).strip()
if v.isdigit():
try:
res = int(v)
except Exception:
res = None
if res is None:
# Try legacy printer name mapping
try:
res = int(self._printers_resolution.get(v, 300)) if v in self._printers_resolution else None
except Exception:
res = None
if res is None:
res = 300
# Build the list accordingly
new_items = self._templates_300 if res == 300 else self._templates_203

View File

@ -100,17 +100,11 @@ class Recipe_Selection(Widget):
templates_203 = sorted(map(os.path.basename, glob(f"{label_folder_203}*.prn")))
templates_300 = sorted(map(os.path.basename, glob(f"{label_folder_300}*.prn")))
# Available printers from both sections (only 'printer' key) and mapping to resolution
# Available printers from both sections: build mapping name->resolution and a list of unique resolution strings
lp1 = self.config.get("label_printer", {}) or {}
lp2 = self.config.get("label_printer_2", {}) or {}
lp1_p = lp1.get("printer", "")
lp2_p = lp2.get("printer", "")
printers_list = []
seen = set()
for p in [lp1_p, lp2_p]:
if p and p not in seen:
seen.add(p)
printers_list.append(p)
printers_resolution = {}
if lp1_p:
try:
@ -122,6 +116,14 @@ class Recipe_Selection(Widget):
printers_resolution[lp2_p] = int(str(lp2.get("risoluzione", "300")).strip())
except Exception:
printers_resolution[lp2_p] = 300
# Build unique list of resolutions (as strings) to use in editor selector
res_set = []
for r in [printers_resolution.get(lp1_p), printers_resolution.get(lp2_p)]:
if r is None:
continue
s = str(int(r))
if s not in res_set:
res_set.append(s)
step_defaults.update({
"vision": {
@ -133,7 +135,7 @@ class Recipe_Selection(Widget):
"template": sorted(map(os.path.basename, glob(f"{label_folder}*.prn"))),
"templates_203": templates_203,
"templates_300": templates_300,
"printer_selection": printers_list,
"printer_selection": res_set,
"printers_resolution": printers_resolution,
},
}),
@ -327,6 +329,32 @@ class Recipe_Selection(Widget):
if rcsv == "":
rcsv = "999"
print_template_field = self.config.get("recipe", {}).get("label_template_field", "modello_etichetta").strip()
# Normalize printer_selection to resolution string ("203"/"300")
lp1 = (self.config.get("label_printer", {}) or {})
lp2 = (self.config.get("label_printer_2", {}) or {})
def normalize_printer_sel(val):
try:
s = str(val).strip()
except Exception:
s = ""
if s == "":
try:
return str(int(lp1.get("risoluzione", 300)))
except Exception:
return "300"
if s.isdigit():
return s
if s == str(lp1.get("printer", "")):
try:
return str(int(lp1.get("risoluzione", 300)))
except Exception:
return "300"
if s == str(lp2.get("printer", "")):
try:
return str(int(lp2.get("risoluzione", 300)))
except Exception:
return "300"
return s
return {
"count": {
"amount": row.get("dimensione_lotto", defaults["dimensione_lotto"]),
@ -410,7 +438,8 @@ class Recipe_Selection(Widget):
"labeltxt_4": row.get("testo_etich_4", ""),
"labeltxt_5": row.get("barcode_input_finelinea", ""),
"extra_label": row.get("etichette_supplementari", ""),
"printer_selection": row.get("printer_selection", self.config.get("label_printer", {}).get("printer", "")),
# Store resolution instead of printer name; map legacy names to their resolution
"printer_selection": normalize_printer_sel(row.get("printer_selection", (self.config.get("label_printer", {}) or {}).get("risoluzione", 300))),
},
}

View File

@ -1038,24 +1038,61 @@ class Test(Widget):
self.archived.barcode = self.printed_barcode
# PRINT MAIN PRODUCT LABEL
# Determine which OS label printer to use based on per-recipe selection
selected_printer = printer_fields.get("printer_selection", "")
lp2_cfg = self.config.get("label_printer_2", {})
lp2_printer = lp2_cfg.get("printer", "")
use_comp_name = "label_printer_2" if selected_printer and lp2_printer and selected_printer == lp2_printer else "label_printer"
# Determine which label printer component to use based on per-recipe selection.
# The recipe now stores the printer by resolution string ("203"/"300").
sel_val = str(printer_fields.get("printer_selection", "")).strip()
lp1_cfg = self.config.get("label_printer", {}) or {}
lp2_cfg = self.config.get("label_printer_2", {}) or {}
# Parse selected resolution; also support legacy OS printer names for backward compatibility
def parse_resolution(val: str):
if not val:
return None
if val.isdigit():
try:
return int(val)
except Exception:
return None
# Legacy: match configured printer names
if val == str(lp1_cfg.get("printer", "")):
try:
return int(lp1_cfg.get("risoluzione", 300))
except Exception:
return 300
if val == str(lp2_cfg.get("printer", "")):
try:
return int(lp2_cfg.get("risoluzione", 300))
except Exception:
return 300
return None
sel_res = parse_resolution(sel_val)
# Read configured resolutions
try:
lp1_res = int(str(lp1_cfg.get("risoluzione", 300)).strip())
except Exception:
lp1_res = 300
try:
lp2_res = int(str(lp2_cfg.get("risoluzione", 0)).strip()) if lp2_cfg else 0
except Exception:
lp2_res = 0
# Choose component by resolution match; default to primary
use_comp_name = "label_printer"
if sel_res is not None:
if lp2_cfg and lp2_res and sel_res == lp2_res:
use_comp_name = "label_printer_2"
elif sel_res == lp1_res:
use_comp_name = "label_printer"
comp = self.components.get(use_comp_name) or self.components.get("label_printer") or self.components.get("label_printer_2")
if comp is None:
# No printer component available; log and skip printing safely
self.log.warning("No label printer component available; skipping label print.")
return context
# Set the target device name to selected printer if provided
if selected_printer:
try:
comp.printer = selected_printer
except Exception:
pass
# Set the target device name to the configured OS printer for the chosen component
try:
comp.printer = (lp2_cfg.get("printer") if use_comp_name == "label_printer_2" else lp1_cfg.get("printer")) or comp.printer
except Exception:
pass
compiled_label = comp.print_label(label, context=context)
self.log.info(f"Main label printed: {context!r}")
self.log.info(f"Main label printed via {use_comp_name}: {context!r}")
# return fields used to print label for saving into test archive
return context