wip
This commit is contained in:
parent
c81864df72
commit
47eb358a9b
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user