diff --git a/src/components/os_label_printer.py b/src/components/os_label_printer.py index efda98f..39d94f0 100644 --- a/src/components/os_label_printer.py +++ b/src/components/os_label_printer.py @@ -63,7 +63,7 @@ class Os_Label_Printer(Component): os.makedirs("tmp", exist_ok=True) label_file = "tmp/label.prn" with open(label_file, "w", errors="surrogateescape") as f: - label = f.write(label_file_contents) + f.write(label_file_contents) if self.platform == "windows": cmd = f'print /d:"{self.printer}" "{label_file}"' elif self.platform == "cups": @@ -80,7 +80,7 @@ class Os_Label_Printer(Component): f"Non e stato possibile stampare l'etichetta.\n\nErrore:\nreturncode: {p.returncode}\noutput:\n{p.stdout}" ) return None - return label + return label_file_contents except Exception as e: self.log.exception(traceback.format_exc()) QMessageBox.critical( diff --git a/src/lib/db/models/archive.py b/src/lib/db/models/archive.py index 85ceba7..32e1e7d 100644 --- a/src/lib/db/models/archive.py +++ b/src/lib/db/models/archive.py @@ -1,10 +1,10 @@ from datetime import datetime -from peewee import AutoField, BooleanField, DateTimeField, ForeignKeyField, TextField +from peewee import (AutoField, BooleanField, DateTimeField, ForeignKeyField, + TextField) from playhouse.sqlite_ext import JSONField from .base_model import BaseModel, db -from .recipes import Recipes from .users import Users @@ -21,40 +21,12 @@ class Archive(BaseModel): @classmethod @db.atomic() - def archive(cls, recipe, test_data, result, overridden): - # parsed_test_data = { - # "ESITO GLOBALE COLLAUDO": "OK" if test_data.get("ok", None) else "KO", - # "recipe": test_data.get("recipe", None), - # } - # total_duration = 0 - # for step_name in [ - # "autotest", - # "barcodes", - # "connector", - # "leak", - # "print", - # "resistance", - # "vision", - # ]: - # for k, v in test_data.get(step_name, {}).items(): - # if step_name not in parsed_test_data: - # parsed_test_data[step_name] = {} - # parsed_test_data[step_name][k] = { - # f"ESITO {step_name}": "OK" if v.get("ok", None) else "KO", - # "result": v.get("results", {}).get("result", None), - # "data": v.get("results", {}).get("data", None), - # "step": v.get("step", None), - # "duration": v.get("duration", None), - # } - # if parsed_test_data[step_name][k]["duration"] is not None: - # total_duration += parsed_test_data[step_name][k]["duration"] - # parsed_test_data["DURATA TOTALE COLLAUDO"] = total_duration + def archive(cls, test_data, result, overridden): return cls.create( user=Users.get_session().user, - recipe=recipe, - test_data=test_data, result=result, overridden=overridden, + test_data=test_data, ) class Meta: diff --git a/src/lib/db/models/recipes.py b/src/lib/db/models/recipes.py index 2e0c60b..7cbc601 100644 --- a/src/lib/db/models/recipes.py +++ b/src/lib/db/models/recipes.py @@ -27,11 +27,11 @@ class Recipes(BaseModel): steps[step_name] = Steps.get_by_id(step_pk) return steps - @classmethod - def delete(cls, *args, **kwargs): - # OVERRIDE DELETION - # so that deleting a user will only archive it - return cls.update(archived=True) + # @classmethod + # def delete(cls, *args, **kwargs): + # # OVERRIDE DELETION + # # so that deleting a user will only archive it + # return cls.update(archived=True) class Meta: table_name = "recipes" diff --git a/src/lib/db/models/steps.py b/src/lib/db/models/steps.py index 9368a6f..4baa839 100644 --- a/src/lib/db/models/steps.py +++ b/src/lib/db/models/steps.py @@ -13,11 +13,11 @@ class Steps(BaseModel): description = TextField(null=True) archived = BooleanField(null=False, default=False) - @classmethod - def delete(cls, *args, **kwargs): - # OVERRIDE DELETION - # so that deleting a user will only archive it - return cls.update(archived=True) + # @classmethod + # def delete(cls, *args, **kwargs): + # # OVERRIDE DELETION + # # so that deleting a user will only archive it + # return cls.update(archived=True) class Meta: table_name = "steps" diff --git a/src/ui/crud/crud.py b/src/ui/crud/crud.py index acfef1c..658af92 100755 --- a/src/ui/crud/crud.py +++ b/src/ui/crud/crud.py @@ -436,9 +436,15 @@ class Crud(Widget): if fail: QMessageBox.critical(None, "Errore Salvataggio DB", "\n".join(fails)) return False + # reinsert primary key if not in selected fields if self.db.table_pk.name not in self.select: for rn, r in enumerate(data): r[self.db.table_pk.name] = self.data_index[rn] + # delete rows with primary key changed to avoid duplication if primary key in selected fields and editable + if self.db.table_pk.name in self.select and not (self.readonly is None or self.readonly is True or (self.readonly is not False and self.db.table_pk.name in self.readonly)): + for rn, r in enumerate(data): + if r[self.db.table_pk.name] != self.data_index[rn]: + self.deleted_rows.add(self.data_index[rn]) # INDEX DATA WITH PK try: self.db.commit(data, deleted_rows=self.deleted_rows) @@ -518,15 +524,14 @@ class Crud(Widget): selected = self.get_selected_rows() if len(selected) == 0: return - # ret = QMessageBox.warning( - # None, - # "Conferma rimozione linee", - # "Si \u00E8 sicuri di voler eliminare le linee selezionate?", - # buttons=QMessageBox.Ok | QMessageBox.Cancel, - # defaultButton=QMessageBox.Cancel - # ) - # if ret == QMessageBox.Ok: - if True: + ret = QMessageBox.warning( + None, + "Conferma rimozione linee", + "Si vogliono davvero eliminare le linee selezionate?", + buttons=QMessageBox.Ok | QMessageBox.Cancel, + defaultButton=QMessageBox.Cancel + ) + if ret == QMessageBox.Ok: for rn in reversed(selected): pk = self.data_index.pop(rn - 1) # - 1 because rn starts from 1 (filters line) if pk is not None: diff --git a/src/ui/recipe_selection/recipe_selection.py b/src/ui/recipe_selection/recipe_selection.py index 4b60fc9..10efd38 100755 --- a/src/ui/recipe_selection/recipe_selection.py +++ b/src/ui/recipe_selection/recipe_selection.py @@ -9,7 +9,7 @@ from glob import glob from lib.db import Recipes, Steps, Users, db from PyQt5.QtCore import QTimer, pyqtSignal from PyQt5.QtGui import QKeySequence -from PyQt5.QtWidgets import QFileDialog, QShortcut +from PyQt5.QtWidgets import QFileDialog, QMessageBox, QShortcut from ui.crud import Crud, Json_External_Dialog_Editor_Cell_Widget from ui.helpers import replace_widget from ui.recipe_spec_and_step_editor import Recipe_Spec_And_Step_Editor @@ -88,8 +88,6 @@ class Recipe_Selection(Widget): ), }, pagination=25, ) - self.crud.delete_b.setEnabled(False) - self.crud.delete_b.setVisible(False) replace_widget(self, "crud_w", self.crud) self.crud_modified = None self.selected = None @@ -109,9 +107,11 @@ class Recipe_Selection(Widget): if session.is_admin: self.import_b.clicked.connect(lambda checked, self=weakref.ref(self): self().import_recipes()) self.export_b.clicked.connect(lambda checked, self=weakref.ref(self): self().export_recipes()) + self.delete_all_b.clicked.connect(lambda checked, self=weakref.ref(self): self().delete_recipes()) else: self.import_b.setVisible(False) self.export_b.setVisible(False) + self.delete_all_b.setVisible(False) # TESTING if "--auto-select" in sys.argv or "--test" in sys.argv: recipe = "TEST" @@ -420,3 +420,16 @@ class Recipe_Selection(Widget): w.writeheader() w.writerows(data) self.log.info(f"recipes: exported {len(data)} rows.") + + def delete_recipes(self): + ret = QMessageBox.warning( + None, + "Attenzione si sta cercando di cancellare tutte le ricette!", + "Si è sicuri di voler eliminare tutte le ricette?\nQuesta operazione non può essere annullata!", + buttons=QMessageBox.Ok | QMessageBox.Cancel, + defaultButton=QMessageBox.Cancel + ) + if ret == QMessageBox.Ok: + Recipes.delete().execute() + Steps.delete().execute() + self.crud.refresh() diff --git a/src/ui/recipe_selection/recipe_selection.ui b/src/ui/recipe_selection/recipe_selection.ui index 924a277..a37a490 100644 --- a/src/ui/recipe_selection/recipe_selection.ui +++ b/src/ui/recipe_selection/recipe_selection.ui @@ -6,7 +6,7 @@ 0 0 - 347 + 735 80 @@ -26,24 +26,6 @@ 0 - - - - - 0 - 0 - - - - - 16 - - - - Importa ricette da file CSV - - - @@ -62,7 +44,37 @@ - + + + + + 0 + 0 + + + + + 16 + + + + Importa ricette da file CSV + + + + + + + + 16 + + + + Cancella tutte le ricette + + + + @@ -82,7 +94,7 @@ - + diff --git a/src/ui/test/test.py b/src/ui/test/test.py index 914ee41..a591e37 100755 --- a/src/ui/test/test.py +++ b/src/ui/test/test.py @@ -185,9 +185,6 @@ class Test(Widget): self.set_recipe(recipe=None) self.step = Steps(type="select_recipe") self.cycle_index = -1 - # RESET TEST DATA - self.data = {"ok": True, "overridden": False} - self.archived = None # COUNT RESET self.pieces["ok"] = 0 self.pieces["ko"] = 0 @@ -196,9 +193,6 @@ class Test(Widget): # FAIL AND RESTART TEST self.step = Steps(type="fail") self.cycle_index = -1 - # RESET TEST DATA - self.data = {"ok": True, "overridden": False} - self.archived = None # COUNT FAIL self.pieces["ko"] += 1 elif action is not None: @@ -222,7 +216,6 @@ class Test(Widget): self.step = self.cycle_steps[self.cycle_index] else: self.cycle_index = -1 - self.archived = None self.step = Steps(type=None) # enable/disable cycle controls self.change_recipe_b.setEnabled(self.recipe is not None) @@ -233,12 +226,12 @@ class Test(Widget): "wait", }) self.log.info(f"cycle next: next cycle step: {model_to_dict(self.step)!r}") - # INIT TEST DATA IF STARTING CYCLE LOOP - if self.recipe is not None and "recipe" not in self.data: - self.data["recipe"] = model_to_dict(self.recipe) - if self.cycle_index == 0: + # INIT TEST DATA IF STARTING CYCLE LOOP OR IF RESET IS NEEDED + if self.cycle_index <= 0: self.data = {"ok": True, "overridden": False} self.archived = None + if self.recipe is not None and "recipe" not in self.data: + self.data["recipe"] = model_to_dict(self.recipe) w = self.cycle_available_steps[self.step.type] show = None if hasattr(w, "start"): @@ -372,7 +365,7 @@ class Test(Widget): for vision in self.data.get("vision", {}).values(): vision.pop("frame", None) vision.pop("render", None) - archived = Archive.archive(self.recipe, self.data, ok and self.data["ok"], overridden=self.data["overridden"]) + archived = Archive.archive(self.data, ok and self.data["ok"], overridden=self.data["overridden"]) self.log.info(f"cycle archived locally: {archived!r}") # COUNT OK self.pieces["ok"] += 1