This commit is contained in:
matteo porta 2022-10-25 15:38:18 +02:00
parent c81864df72
commit 47eb358a9b
8 changed files with 84 additions and 89 deletions

View File

@ -63,7 +63,7 @@ class Os_Label_Printer(Component):
os.makedirs("tmp", exist_ok=True) os.makedirs("tmp", exist_ok=True)
label_file = "tmp/label.prn" label_file = "tmp/label.prn"
with open(label_file, "w", errors="surrogateescape") as f: with open(label_file, "w", errors="surrogateescape") as f:
label = f.write(label_file_contents) f.write(label_file_contents)
if self.platform == "windows": if self.platform == "windows":
cmd = f'print /d:"{self.printer}" "{label_file}"' cmd = f'print /d:"{self.printer}" "{label_file}"'
elif self.platform == "cups": 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}" f"Non e stato possibile stampare l'etichetta.\n\nErrore:\nreturncode: {p.returncode}\noutput:\n{p.stdout}"
) )
return None return None
return label return label_file_contents
except Exception as e: except Exception as e:
self.log.exception(traceback.format_exc()) self.log.exception(traceback.format_exc())
QMessageBox.critical( QMessageBox.critical(

View File

@ -1,10 +1,10 @@
from datetime import datetime 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 playhouse.sqlite_ext import JSONField
from .base_model import BaseModel, db from .base_model import BaseModel, db
from .recipes import Recipes
from .users import Users from .users import Users
@ -21,40 +21,12 @@ class Archive(BaseModel):
@classmethod @classmethod
@db.atomic() @db.atomic()
def archive(cls, recipe, test_data, result, overridden): def archive(cls, 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
return cls.create( return cls.create(
user=Users.get_session().user, user=Users.get_session().user,
recipe=recipe,
test_data=test_data,
result=result, result=result,
overridden=overridden, overridden=overridden,
test_data=test_data,
) )
class Meta: class Meta:

View File

@ -27,11 +27,11 @@ class Recipes(BaseModel):
steps[step_name] = Steps.get_by_id(step_pk) steps[step_name] = Steps.get_by_id(step_pk)
return steps return steps
@classmethod # @classmethod
def delete(cls, *args, **kwargs): # def delete(cls, *args, **kwargs):
# OVERRIDE DELETION # # OVERRIDE DELETION
# so that deleting a user will only archive it # # so that deleting a user will only archive it
return cls.update(archived=True) # return cls.update(archived=True)
class Meta: class Meta:
table_name = "recipes" table_name = "recipes"

View File

@ -13,11 +13,11 @@ class Steps(BaseModel):
description = TextField(null=True) description = TextField(null=True)
archived = BooleanField(null=False, default=False) archived = BooleanField(null=False, default=False)
@classmethod # @classmethod
def delete(cls, *args, **kwargs): # def delete(cls, *args, **kwargs):
# OVERRIDE DELETION # # OVERRIDE DELETION
# so that deleting a user will only archive it # # so that deleting a user will only archive it
return cls.update(archived=True) # return cls.update(archived=True)
class Meta: class Meta:
table_name = "steps" table_name = "steps"

View File

@ -436,9 +436,15 @@ class Crud(Widget):
if fail: if fail:
QMessageBox.critical(None, "Errore Salvataggio DB", "\n".join(fails)) QMessageBox.critical(None, "Errore Salvataggio DB", "\n".join(fails))
return False return False
# reinsert primary key if not in selected fields
if self.db.table_pk.name not in self.select: if self.db.table_pk.name not in self.select:
for rn, r in enumerate(data): for rn, r in enumerate(data):
r[self.db.table_pk.name] = self.data_index[rn] 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 # INDEX DATA WITH PK
try: try:
self.db.commit(data, deleted_rows=self.deleted_rows) self.db.commit(data, deleted_rows=self.deleted_rows)
@ -518,15 +524,14 @@ class Crud(Widget):
selected = self.get_selected_rows() selected = self.get_selected_rows()
if len(selected) == 0: if len(selected) == 0:
return return
# ret = QMessageBox.warning( ret = QMessageBox.warning(
# None, None,
# "Conferma rimozione linee", "Conferma rimozione linee",
# "Si \u00E8 sicuri di voler eliminare le linee selezionate?", "Si vogliono davvero eliminare le linee selezionate?",
# buttons=QMessageBox.Ok | QMessageBox.Cancel, buttons=QMessageBox.Ok | QMessageBox.Cancel,
# defaultButton=QMessageBox.Cancel defaultButton=QMessageBox.Cancel
# ) )
# if ret == QMessageBox.Ok: if ret == QMessageBox.Ok:
if True:
for rn in reversed(selected): for rn in reversed(selected):
pk = self.data_index.pop(rn - 1) # - 1 because rn starts from 1 (filters line) pk = self.data_index.pop(rn - 1) # - 1 because rn starts from 1 (filters line)
if pk is not None: if pk is not None:

View File

@ -9,7 +9,7 @@ from glob import glob
from lib.db import Recipes, Steps, Users, db from lib.db import Recipes, Steps, Users, db
from PyQt5.QtCore import QTimer, pyqtSignal from PyQt5.QtCore import QTimer, pyqtSignal
from PyQt5.QtGui import QKeySequence 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.crud import Crud, Json_External_Dialog_Editor_Cell_Widget
from ui.helpers import replace_widget from ui.helpers import replace_widget
from ui.recipe_spec_and_step_editor import Recipe_Spec_And_Step_Editor from ui.recipe_spec_and_step_editor import Recipe_Spec_And_Step_Editor
@ -88,8 +88,6 @@ class Recipe_Selection(Widget):
), }, ), },
pagination=25, pagination=25,
) )
self.crud.delete_b.setEnabled(False)
self.crud.delete_b.setVisible(False)
replace_widget(self, "crud_w", self.crud) replace_widget(self, "crud_w", self.crud)
self.crud_modified = None self.crud_modified = None
self.selected = None self.selected = None
@ -109,9 +107,11 @@ class Recipe_Selection(Widget):
if session.is_admin: if session.is_admin:
self.import_b.clicked.connect(lambda checked, self=weakref.ref(self): self().import_recipes()) 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.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: else:
self.import_b.setVisible(False) self.import_b.setVisible(False)
self.export_b.setVisible(False) self.export_b.setVisible(False)
self.delete_all_b.setVisible(False)
# TESTING # TESTING
if "--auto-select" in sys.argv or "--test" in sys.argv: if "--auto-select" in sys.argv or "--test" in sys.argv:
recipe = "TEST" recipe = "TEST"
@ -420,3 +420,16 @@ class Recipe_Selection(Widget):
w.writeheader() w.writeheader()
w.writerows(data) w.writerows(data)
self.log.info(f"recipes: exported {len(data)} rows.") 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()

View File

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>347</width> <width>735</width>
<height>80</height> <height>80</height>
</rect> </rect>
</property> </property>
@ -26,24 +26,6 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item row="2" column="0">
<widget class="QPushButton" name="import_b">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string>Importa ricette da file CSV</string>
</property>
</widget>
</item>
<item row="2" column="1"> <item row="2" column="1">
<widget class="QPushButton" name="export_b"> <widget class="QPushButton" name="export_b">
<property name="sizePolicy"> <property name="sizePolicy">
@ -62,7 +44,37 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0" colspan="2"> <item row="2" column="0">
<widget class="QPushButton" name="import_b">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string>Importa ricette da file CSV</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="delete_all_b">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string>Cancella tutte le ricette</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QPushButton" name="select_b"> <widget class="QPushButton" name="select_b">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@ -82,7 +94,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0" colspan="2"> <item row="0" column="0" colspan="3">
<widget class="QWidget" name="crud_w" native="true"/> <widget class="QWidget" name="crud_w" native="true"/>
</item> </item>
</layout> </layout>

View File

@ -185,9 +185,6 @@ class Test(Widget):
self.set_recipe(recipe=None) self.set_recipe(recipe=None)
self.step = Steps(type="select_recipe") self.step = Steps(type="select_recipe")
self.cycle_index = -1 self.cycle_index = -1
# RESET TEST DATA
self.data = {"ok": True, "overridden": False}
self.archived = None
# COUNT RESET # COUNT RESET
self.pieces["ok"] = 0 self.pieces["ok"] = 0
self.pieces["ko"] = 0 self.pieces["ko"] = 0
@ -196,9 +193,6 @@ class Test(Widget):
# FAIL AND RESTART TEST # FAIL AND RESTART TEST
self.step = Steps(type="fail") self.step = Steps(type="fail")
self.cycle_index = -1 self.cycle_index = -1
# RESET TEST DATA
self.data = {"ok": True, "overridden": False}
self.archived = None
# COUNT FAIL # COUNT FAIL
self.pieces["ko"] += 1 self.pieces["ko"] += 1
elif action is not None: elif action is not None:
@ -222,7 +216,6 @@ class Test(Widget):
self.step = self.cycle_steps[self.cycle_index] self.step = self.cycle_steps[self.cycle_index]
else: else:
self.cycle_index = -1 self.cycle_index = -1
self.archived = None
self.step = Steps(type=None) self.step = Steps(type=None)
# enable/disable cycle controls # enable/disable cycle controls
self.change_recipe_b.setEnabled(self.recipe is not None) self.change_recipe_b.setEnabled(self.recipe is not None)
@ -233,12 +226,12 @@ class Test(Widget):
"wait", "wait",
}) })
self.log.info(f"cycle next: next cycle step: {model_to_dict(self.step)!r}") self.log.info(f"cycle next: next cycle step: {model_to_dict(self.step)!r}")
# INIT TEST DATA IF STARTING CYCLE LOOP # INIT TEST DATA IF STARTING CYCLE LOOP OR IF RESET IS NEEDED
if self.recipe is not None and "recipe" not in self.data: if self.cycle_index <= 0:
self.data["recipe"] = model_to_dict(self.recipe)
if self.cycle_index == 0:
self.data = {"ok": True, "overridden": False} self.data = {"ok": True, "overridden": False}
self.archived = None 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] w = self.cycle_available_steps[self.step.type]
show = None show = None
if hasattr(w, "start"): if hasattr(w, "start"):
@ -372,7 +365,7 @@ class Test(Widget):
for vision in self.data.get("vision", {}).values(): for vision in self.data.get("vision", {}).values():
vision.pop("frame", None) vision.pop("frame", None)
vision.pop("render", 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}") self.log.info(f"cycle archived locally: {archived!r}")
# COUNT OK # COUNT OK
self.pieces["ok"] += 1 self.pieces["ok"] += 1