Pre-code cleanup.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
# 202503.05
|
# 202503.05
|
||||||
|
|
||||||
- Added concentrations chart tab.
|
- Added concentrations chart tab.
|
||||||
|
- Saving report xlsx/pdf now inserts report class name in file name.
|
||||||
|
|
||||||
# 202503.04
|
# 202503.04
|
||||||
|
|
||||||
|
|||||||
@@ -56,23 +56,23 @@ class BaseClass(Base):
|
|||||||
omni_inheritable = []
|
omni_inheritable = []
|
||||||
searchables = []
|
searchables = []
|
||||||
|
|
||||||
@classproperty
|
# @classproperty
|
||||||
def skip_on_edit(cls):
|
# def skip_on_edit(cls):
|
||||||
if "association" in cls.__name__.lower() or cls.__name__.lower() == "discount":
|
# if "association" in cls.__name__.lower() or cls.__name__.lower() == "discount":
|
||||||
return True
|
# return True
|
||||||
else:
|
# else:
|
||||||
return False
|
# return False
|
||||||
|
|
||||||
@classproperty
|
@classproperty
|
||||||
def aliases(cls):
|
def aliases(cls):
|
||||||
return [cls.query_alias]
|
return [cls.query_alias]
|
||||||
|
|
||||||
@classproperty
|
# @classproperty
|
||||||
def level(cls):
|
# def level(cls):
|
||||||
if "association" in cls.__name__.lower() or cls.__name__.lower() == "discount":
|
# if "association" in cls.__name__.lower() or cls.__name__.lower() == "discount":
|
||||||
return 2
|
# return 2
|
||||||
else:
|
# else:
|
||||||
return 1
|
# return 1
|
||||||
|
|
||||||
@classproperty
|
@classproperty
|
||||||
def query_alias(cls):
|
def query_alias(cls):
|
||||||
@@ -187,8 +187,9 @@ class BaseClass(Base):
|
|||||||
return query.limit(50).all()
|
return query.limit(50).all()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def results_to_df(cls, objects: list, **kwargs) -> DataFrame:
|
def results_to_df(cls, objects: list|None=None, **kwargs) -> DataFrame:
|
||||||
"""
|
"""
|
||||||
|
Converts class sub_dicts into a Dataframe for all instances of the class.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
objects (list): Objects to be converted to dataframe.
|
objects (list): Objects to be converted to dataframe.
|
||||||
@@ -197,6 +198,12 @@ class BaseClass(Base):
|
|||||||
Returns:
|
Returns:
|
||||||
Dataframe
|
Dataframe
|
||||||
"""
|
"""
|
||||||
|
if not objects:
|
||||||
|
try:
|
||||||
|
records = [obj.to_sub_dict(**kwargs) for obj in cls.query()]
|
||||||
|
except AttributeError:
|
||||||
|
records = [obj.to_dict(**kwargs) for obj in cls.query(page_size=0)]
|
||||||
|
else:
|
||||||
try:
|
try:
|
||||||
records = [obj.to_sub_dict(**kwargs) for obj in objects]
|
records = [obj.to_sub_dict(**kwargs) for obj in objects]
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ class Control(BaseClass):
|
|||||||
try:
|
try:
|
||||||
model = next(subclass for subclass in cls.__subclasses__() if
|
model = next(subclass for subclass in cls.__subclasses__() if
|
||||||
all([hasattr(subclass, attr) for attr in attrs.keys()]))
|
all([hasattr(subclass, attr) for attr in attrs.keys()]))
|
||||||
except StopIteration as e:
|
except StopIteration:
|
||||||
raise AttributeError(
|
raise AttributeError(
|
||||||
f"Couldn't find existing class/subclass of {cls} with all attributes:\n{pformat(attrs.keys())}")
|
f"Couldn't find existing class/subclass of {cls} with all attributes:\n{pformat(attrs.keys())}")
|
||||||
return model
|
return model
|
||||||
@@ -286,6 +286,7 @@ class Control(BaseClass):
|
|||||||
Dummy operation to be overridden by child classes.
|
Dummy operation to be overridden by child classes.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
parent (QWidget): widget to add chart to.
|
||||||
chart_settings (dict): settings passed down from chart widget
|
chart_settings (dict): settings passed down from chart widget
|
||||||
ctx (Settings): settings passed down from gui
|
ctx (Settings): settings passed down from gui
|
||||||
"""
|
"""
|
||||||
@@ -663,7 +664,7 @@ class IridaControl(Control):
|
|||||||
return df, previous_dates
|
return df, previous_dates
|
||||||
# NOTE: if date was changed, rerun with new date
|
# NOTE: if date was changed, rerun with new date
|
||||||
else:
|
else:
|
||||||
logger.warning(f"Date check failed, running recursion")
|
logger.warning(f"Date check failed, running recursion.")
|
||||||
df, previous_dates = cls.check_date(df, item, previous_dates)
|
df, previous_dates = cls.check_date(df, item, previous_dates)
|
||||||
return df, previous_dates
|
return df, previous_dates
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ from jinja2.exceptions import TemplateNotFound
|
|||||||
from jinja2 import Template
|
from jinja2 import Template
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(f"submissions.{__name__}")
|
logger = logging.getLogger(f"submissions.{__name__}")
|
||||||
|
|
||||||
|
|
||||||
@@ -1584,7 +1583,7 @@ class Wastewater(BasicSubmission):
|
|||||||
continue
|
continue
|
||||||
thing['tooltip'] = f"Sample Name: {thing['name']}\nWell: {thing['sample_location']}"
|
thing['tooltip'] = f"Sample Name: {thing['name']}\nWell: {thing['sample_location']}"
|
||||||
dummy_samples.append(thing)
|
dummy_samples.append(thing)
|
||||||
logger.debug(f"Dummy samples for 24 well: {pformat(dummy_samples)}")
|
# logger.debug(f"Dummy samples for 24 well: {pformat(dummy_samples)}")
|
||||||
output['origin_plate'] = self.__class__.make_plate_map(sample_list=dummy_samples, plate_rows=4,
|
output['origin_plate'] = self.__class__.make_plate_map(sample_list=dummy_samples, plate_rows=4,
|
||||||
plate_columns=6)
|
plate_columns=6)
|
||||||
# logger.debug(f"PCR info: {output['pcr_info']}")
|
# logger.debug(f"PCR info: {output['pcr_info']}")
|
||||||
@@ -2772,7 +2771,12 @@ class BacterialCultureSample(BasicSample):
|
|||||||
sample['concentration'] = self.concentration
|
sample['concentration'] = self.concentration
|
||||||
if self.control is not None:
|
if self.control is not None:
|
||||||
sample['colour'] = [0, 128, 0]
|
sample['colour'] = [0, 128, 0]
|
||||||
sample['tooltip'] = f"Control: {self.control.controltype.name} - {self.control.controltype.targets}"
|
target = next((v for k,v in self.control.controltype.targets.items() if k == self.control.subtype), "Not Available")
|
||||||
|
try:
|
||||||
|
target = ", ".join(target)
|
||||||
|
except:
|
||||||
|
target = "None"
|
||||||
|
sample['tooltip'] = f"\nControl: {self.control.controltype.name} - {target}"
|
||||||
return sample
|
return sample
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -134,3 +134,5 @@ class CustomFigure(Figure):
|
|||||||
|
|
||||||
from .irida_charts import IridaFigure
|
from .irida_charts import IridaFigure
|
||||||
from .pcr_charts import PCRFigure
|
from .pcr_charts import PCRFigure
|
||||||
|
from .concentrations_chart import ConcentrationsChart
|
||||||
|
from .turnaround_chart import TurnaroundChart
|
||||||
|
|||||||
@@ -60,12 +60,12 @@ class InfoPane(QWidget):
|
|||||||
return abs((d1.year - d2.year) * 12 + d1.month - d2.month)
|
return abs((d1.year - d2.year) * 12 + d1.month - d2.month)
|
||||||
|
|
||||||
def save_excel(self):
|
def save_excel(self):
|
||||||
fname = select_save_file(self, default_name=f"Report {self.start_date.strftime('%Y%m%d')} - {self.end_date.strftime('%Y%m%d')}", extension="xlsx")
|
fname = select_save_file(self, default_name=f"{self.__class__.__name__} Report {self.start_date.strftime('%Y%m%d')} - {self.end_date.strftime('%Y%m%d')}", extension="xlsx")
|
||||||
self.report_obj.write_report(fname, obj=self)
|
self.report_obj.write_report(fname, obj=self)
|
||||||
|
|
||||||
def save_pdf(self):
|
def save_pdf(self):
|
||||||
fname = select_save_file(obj=self,
|
fname = select_save_file(obj=self,
|
||||||
default_name=f"Report {self.start_date.strftime('%Y%m%d')} - {self.end_date.strftime('%Y%m%d')}",
|
default_name=f"{self.__class__.__name__} Report {self.start_date.strftime('%Y%m%d')} - {self.end_date.strftime('%Y%m%d')}",
|
||||||
extension="pdf")
|
extension="pdf")
|
||||||
save_pdf(obj=self.webview, filename=fname)
|
save_pdf(obj=self.webview, filename=fname)
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,12 @@
|
|||||||
Contains miscellaneous widgets for frontend functions
|
Contains miscellaneous widgets for frontend functions
|
||||||
"""
|
"""
|
||||||
import math
|
import math
|
||||||
from datetime import date
|
|
||||||
from PyQt6.QtGui import QStandardItem, QIcon
|
from PyQt6.QtGui import QStandardItem, QIcon
|
||||||
from PyQt6.QtWidgets import (
|
from PyQt6.QtWidgets import (
|
||||||
QLabel, QLineEdit, QComboBox, QDateEdit, QPushButton, QWidget,
|
QLabel, QLineEdit, QComboBox, QDateEdit, QPushButton, QWidget,
|
||||||
QHBoxLayout, QSizePolicy
|
QHBoxLayout, QSizePolicy
|
||||||
)
|
)
|
||||||
from PyQt6.QtCore import Qt, QDate, QSize, QMarginsF
|
from PyQt6.QtCore import Qt, QDate, QSize
|
||||||
from tools import jinja_template_loading
|
from tools import jinja_template_loading
|
||||||
from backend.db.models import *
|
from backend.db.models import *
|
||||||
import logging
|
import logging
|
||||||
@@ -18,98 +17,6 @@ logger = logging.getLogger(f"submissions.{__name__}")
|
|||||||
env = jinja_template_loading()
|
env = jinja_template_loading()
|
||||||
|
|
||||||
|
|
||||||
# class AddReagentForm(QDialog):
|
|
||||||
# """
|
|
||||||
# dialog to add gather info about new reagent (Defunct)
|
|
||||||
# """
|
|
||||||
#
|
|
||||||
# def __init__(self, reagent_lot: str | None = None, reagent_role: str | None = None, expiry: date | None = None,
|
|
||||||
# reagent_name: str | None = None, kit: str | KitType | None = None) -> None:
|
|
||||||
# super().__init__()
|
|
||||||
# if reagent_name is None:
|
|
||||||
# reagent_name = reagent_role
|
|
||||||
# self.setWindowTitle("Add Reagent")
|
|
||||||
# QBtn = QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
|
|
||||||
# self.buttonBox = QDialogButtonBox(QBtn)
|
|
||||||
# self.buttonBox.accepted.connect(self.accept)
|
|
||||||
# self.buttonBox.rejected.connect(self.reject)
|
|
||||||
# # NOTE: widget to get lot info
|
|
||||||
# self.name_input = QComboBox()
|
|
||||||
# self.name_input.setObjectName("name")
|
|
||||||
# self.name_input.setEditable(True)
|
|
||||||
# self.name_input.setCurrentText(reagent_name)
|
|
||||||
# self.lot_input = QLineEdit()
|
|
||||||
# self.lot_input.setObjectName("lot")
|
|
||||||
# self.lot_input.setText(reagent_lot)
|
|
||||||
# # NOTE: widget to get expiry info
|
|
||||||
# self.expiry_input = QDateEdit(calendarPopup=True)
|
|
||||||
# self.expiry_input.setObjectName('expiry')
|
|
||||||
# # NOTE: if expiry is not passed in from gui, use today
|
|
||||||
# if expiry is None:
|
|
||||||
# logger.warning(f"Did not receive expiry, setting to 1970, 1, 1")
|
|
||||||
# self.expiry_input.setDate(QDate(1970, 1, 1))
|
|
||||||
# else:
|
|
||||||
# try:
|
|
||||||
# self.expiry_input.setDate(expiry)
|
|
||||||
# except TypeError:
|
|
||||||
# self.expiry_input.setDate(QDate(1970, 1, 1))
|
|
||||||
# # NOTE: widget to get reagent type info
|
|
||||||
# self.role_input = QComboBox()
|
|
||||||
# self.role_input.setObjectName('role')
|
|
||||||
# if kit:
|
|
||||||
# match kit:
|
|
||||||
# case str():
|
|
||||||
# kit = KitType.query(name=kit)
|
|
||||||
# case _:
|
|
||||||
# pass
|
|
||||||
# self.role_input.addItems([item.name for item in ReagentRole.query() if kit in item.kit_types])
|
|
||||||
# else:
|
|
||||||
# self.role_input.addItems([item.name for item in ReagentRole.query()])
|
|
||||||
# # NOTE: convert input to user-friendly string?
|
|
||||||
# try:
|
|
||||||
# reagent_role = reagent_role.replace("_", " ").title()
|
|
||||||
# except AttributeError:
|
|
||||||
# reagent_role = None
|
|
||||||
# # NOTE: set parsed reagent type to top of list
|
|
||||||
# index = self.role_input.findText(reagent_role, Qt.MatchFlag.MatchEndsWith)
|
|
||||||
# if index >= 0:
|
|
||||||
# self.role_input.setCurrentIndex(index)
|
|
||||||
# self.layout = QVBoxLayout()
|
|
||||||
# self.layout.addWidget(QLabel("Name:"))
|
|
||||||
# self.layout.addWidget(self.name_input)
|
|
||||||
# self.layout.addWidget(QLabel("Lot:"))
|
|
||||||
# self.layout.addWidget(self.lot_input)
|
|
||||||
# self.layout.addWidget(
|
|
||||||
# QLabel("Expiry:\n(use exact date on reagent.\nEOL will be calculated from kit automatically)")
|
|
||||||
# )
|
|
||||||
# self.layout.addWidget(self.expiry_input)
|
|
||||||
# self.layout.addWidget(QLabel("Type:"))
|
|
||||||
# self.layout.addWidget(self.role_input)
|
|
||||||
# self.layout.addWidget(self.buttonBox)
|
|
||||||
# self.setLayout(self.layout)
|
|
||||||
# self.role_input.currentTextChanged.connect(self.update_names)
|
|
||||||
#
|
|
||||||
# def parse_form(self) -> dict:
|
|
||||||
# """
|
|
||||||
# Converts information in form to dict.
|
|
||||||
#
|
|
||||||
# Returns:
|
|
||||||
# dict: Output info
|
|
||||||
# """
|
|
||||||
# return dict(name=self.name_input.currentText().strip(),
|
|
||||||
# lot=self.lot_input.text().strip(),
|
|
||||||
# expiry=self.expiry_input.date().toPyDate(),
|
|
||||||
# role=self.role_input.currentText().strip())
|
|
||||||
#
|
|
||||||
# def update_names(self):
|
|
||||||
# """
|
|
||||||
# Updates reagent names form field with examples from reagent type
|
|
||||||
# """
|
|
||||||
# self.name_input.clear()
|
|
||||||
# lookup = Reagent.query(role=self.role_input.currentText())
|
|
||||||
# self.name_input.addItems(list(set([item.name for item in lookup])))
|
|
||||||
#
|
|
||||||
#
|
|
||||||
class StartEndDatePicker(QWidget):
|
class StartEndDatePicker(QWidget):
|
||||||
"""
|
"""
|
||||||
custom widget to pick start and end dates for controls graphs
|
custom widget to pick start and end dates for controls graphs
|
||||||
@@ -135,16 +42,6 @@ class StartEndDatePicker(QWidget):
|
|||||||
return QSize(80, 20)
|
return QSize(80, 20)
|
||||||
|
|
||||||
|
|
||||||
# def save_pdf(obj: QWebEngineView, filename: Path):
|
|
||||||
# page_layout = QPageLayout()
|
|
||||||
# page_layout.setPageSize(QPageSize(QPageSize.PageSizeId.A4))
|
|
||||||
# page_layout.setOrientation(QPageLayout.Orientation.Portrait)
|
|
||||||
# page_layout.setMargins(QMarginsF(25, 25, 25, 25))
|
|
||||||
# obj.page().printToPdf(filename.absolute().__str__(), page_layout)
|
|
||||||
|
|
||||||
|
|
||||||
# NOTE: subclass
|
|
||||||
|
|
||||||
class CheckableComboBox(QComboBox):
|
class CheckableComboBox(QComboBox):
|
||||||
# once there is a checkState set, it is rendered
|
# once there is a checkState set, it is rendered
|
||||||
# here we assume default Unchecked
|
# here we assume default Unchecked
|
||||||
|
|||||||
Reference in New Issue
Block a user