Pre-code cleanup.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
# 202503.05
|
||||
|
||||
- Added concentrations chart tab.
|
||||
- Saving report xlsx/pdf now inserts report class name in file name.
|
||||
|
||||
# 202503.04
|
||||
|
||||
|
||||
@@ -56,23 +56,23 @@ class BaseClass(Base):
|
||||
omni_inheritable = []
|
||||
searchables = []
|
||||
|
||||
@classproperty
|
||||
def skip_on_edit(cls):
|
||||
if "association" in cls.__name__.lower() or cls.__name__.lower() == "discount":
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
# @classproperty
|
||||
# def skip_on_edit(cls):
|
||||
# if "association" in cls.__name__.lower() or cls.__name__.lower() == "discount":
|
||||
# return True
|
||||
# else:
|
||||
# return False
|
||||
|
||||
@classproperty
|
||||
def aliases(cls):
|
||||
return [cls.query_alias]
|
||||
|
||||
@classproperty
|
||||
def level(cls):
|
||||
if "association" in cls.__name__.lower() or cls.__name__.lower() == "discount":
|
||||
return 2
|
||||
else:
|
||||
return 1
|
||||
# @classproperty
|
||||
# def level(cls):
|
||||
# if "association" in cls.__name__.lower() or cls.__name__.lower() == "discount":
|
||||
# return 2
|
||||
# else:
|
||||
# return 1
|
||||
|
||||
@classproperty
|
||||
def query_alias(cls):
|
||||
@@ -187,8 +187,9 @@ class BaseClass(Base):
|
||||
return query.limit(50).all()
|
||||
|
||||
@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:
|
||||
objects (list): Objects to be converted to dataframe.
|
||||
@@ -197,6 +198,12 @@ class BaseClass(Base):
|
||||
Returns:
|
||||
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:
|
||||
records = [obj.to_sub_dict(**kwargs) for obj in objects]
|
||||
except AttributeError:
|
||||
|
||||
@@ -262,7 +262,7 @@ class Control(BaseClass):
|
||||
try:
|
||||
model = next(subclass for subclass in cls.__subclasses__() if
|
||||
all([hasattr(subclass, attr) for attr in attrs.keys()]))
|
||||
except StopIteration as e:
|
||||
except StopIteration:
|
||||
raise AttributeError(
|
||||
f"Couldn't find existing class/subclass of {cls} with all attributes:\n{pformat(attrs.keys())}")
|
||||
return model
|
||||
@@ -286,6 +286,7 @@ class Control(BaseClass):
|
||||
Dummy operation to be overridden by child classes.
|
||||
|
||||
Args:
|
||||
parent (QWidget): widget to add chart to.
|
||||
chart_settings (dict): settings passed down from chart widget
|
||||
ctx (Settings): settings passed down from gui
|
||||
"""
|
||||
@@ -663,7 +664,7 @@ class IridaControl(Control):
|
||||
return df, previous_dates
|
||||
# NOTE: if date was changed, rerun with new date
|
||||
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)
|
||||
return df, previous_dates
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ from jinja2.exceptions import TemplateNotFound
|
||||
from jinja2 import Template
|
||||
from PIL import Image
|
||||
|
||||
|
||||
logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
|
||||
@@ -1584,7 +1583,7 @@ class Wastewater(BasicSubmission):
|
||||
continue
|
||||
thing['tooltip'] = f"Sample Name: {thing['name']}\nWell: {thing['sample_location']}"
|
||||
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,
|
||||
plate_columns=6)
|
||||
# logger.debug(f"PCR info: {output['pcr_info']}")
|
||||
@@ -2772,7 +2771,12 @@ class BacterialCultureSample(BasicSample):
|
||||
sample['concentration'] = self.concentration
|
||||
if self.control is not None:
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -134,3 +134,5 @@ class CustomFigure(Figure):
|
||||
|
||||
from .irida_charts import IridaFigure
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
def save_pdf(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")
|
||||
save_pdf(obj=self.webview, filename=fname)
|
||||
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
Contains miscellaneous widgets for frontend functions
|
||||
"""
|
||||
import math
|
||||
from datetime import date
|
||||
from PyQt6.QtGui import QStandardItem, QIcon
|
||||
from PyQt6.QtWidgets import (
|
||||
QLabel, QLineEdit, QComboBox, QDateEdit, QPushButton, QWidget,
|
||||
QHBoxLayout, QSizePolicy
|
||||
)
|
||||
from PyQt6.QtCore import Qt, QDate, QSize, QMarginsF
|
||||
from PyQt6.QtCore import Qt, QDate, QSize
|
||||
from tools import jinja_template_loading
|
||||
from backend.db.models import *
|
||||
import logging
|
||||
@@ -18,98 +17,6 @@ logger = logging.getLogger(f"submissions.{__name__}")
|
||||
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):
|
||||
"""
|
||||
custom widget to pick start and end dates for controls graphs
|
||||
@@ -135,16 +42,6 @@ class StartEndDatePicker(QWidget):
|
||||
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):
|
||||
# once there is a checkState set, it is rendered
|
||||
# here we assume default Unchecked
|
||||
|
||||
Reference in New Issue
Block a user