Moments before disaster

This commit is contained in:
Landon Wark
2024-03-11 08:21:48 -05:00
parent d0418ebc9e
commit 17572b4a55
5 changed files with 43 additions and 48 deletions

View File

@@ -4,6 +4,7 @@ Contains all models for sqlalchemy
import sys
from sqlalchemy.orm import DeclarativeMeta, declarative_base, Query
from sqlalchemy.ext.declarative import declared_attr
# Load testing environment
if 'pytest' in sys.modules:
from pathlib import Path
sys.path.append(Path(__file__).parents[4].absolute().joinpath("tests").__str__())

View File

@@ -3,7 +3,7 @@ Models for the main submission types.
'''
from __future__ import annotations
from getpass import getuser
import math, json, logging, uuid, tempfile, re, yaml, base64
import json, logging, uuid, tempfile, re, yaml, base64
from zipfile import ZipFile
from tempfile import TemporaryDirectory
from reportlab.graphics.barcode import createBarcodeImageInMemory
@@ -237,6 +237,7 @@ class BasicSubmission(BaseClass):
self.run_cost = assoc.constant_cost + (assoc.mutable_cost_column * cols_count_96) + (assoc.mutable_cost_sample * int(self.sample_count))
except Exception as e:
logger.error(f"Calculation error: {e}")
self.run_cost = round(self.run_cost, 2)
def calculate_column_count(self) -> int:
"""
@@ -338,7 +339,7 @@ class BasicSubmission(BaseClass):
logger.debug(f"Got {len(subs)} submissions.")
df = pd.DataFrame.from_records(subs)
# Exclude sub information
for item in ['controls', 'extraction_info', 'pcr_info', 'comment', 'comments', 'samples', 'reagents', 'equipment', 'gel_info', 'gel_image', 'dna_core_submission_number']:
for item in ['controls', 'extraction_info', 'pcr_info', 'comment', 'comments', 'samples', 'reagents', 'equipment', 'gel_info', 'gel_image', 'dna_core_submission_number', 'source_plates']:
try:
df = df.drop(item, axis=1)
except:
@@ -873,8 +874,8 @@ class BasicSubmission(BaseClass):
Returns:
dict: dictionary of functions
"""
names = ["Delete", "Details", "Add Comment", "Add Equipment", "Export"]
funcs = [self.delete, self.show_details, self.add_comment, self.add_equipment, self.backup]
names = ["Delete", "Details", "Edit", "Add Comment", "Add Equipment", "Export"]
funcs = [self.delete, self.show_details, self.edit, self.add_comment, self.add_equipment, self.backup]
dicto = {item[0]:item[1] for item in zip(names, funcs)}
return dicto
@@ -915,6 +916,15 @@ class BasicSubmission(BaseClass):
if dlg.exec():
pass
def edit(self, obj):
from frontend.widgets.submission_widget import SubmissionFormWidget
for widg in obj.app.table_widget.formwidget.findChildren(SubmissionFormWidget):
logger.debug(widg)
widg.setParent(None)
pyd = self.to_pydantic(backup=True)
form = pyd.toForm(parent=obj)
obj.app.table_widget.formwidget.layout().addWidget(form)
def add_comment(self, obj):
"""
Creates widget for adding comments to submissions
@@ -1300,25 +1310,6 @@ class WastewaterArtic(BasicSubmission):
polymorphic_load="inline",
inherit_condition=(id == BasicSubmission.id))
def calculate_base_cost(self):
"""
This method overrides parent method due to multiple output plates from a single submission
"""
logger.debug(f"Hello from calculate base cost in WWArtic")
try:
cols_count_96 = math.ceil(int(self.sample_count) / 8)
except Exception as e:
logger.error(f"Column count error: {e}")
assoc = [item for item in self.extraction_kit.kit_submissiontype_associations if item.submission_type == self.submission_type][0]
# Since we have multiple output plates per submission form, the constant cost will have to reflect this.
output_plate_count = math.ceil(int(self.sample_count) / 16)
logger.debug(f"Looks like we have {output_plate_count} output plates.")
const_cost = assoc.constant_cost * output_plate_count
try:
self.run_cost = const_cost + (assoc.mutable_cost_column * cols_count_96) + (assoc.mutable_cost_sample * int(self.sample_count))
except Exception as e:
logger.error(f"Calculation error: {e}")
def to_dict(self, full_data:bool=False, backup:bool=False) -> dict:
"""
Extends parent class method to add controls to dict
@@ -1859,7 +1850,7 @@ class BasicSample(BaseClass):
Returns:
Tuple(dict, Template): (Updated dictionary, Template to be rendered)
"""
base_dict['excluded'] = ['submissions', 'excluded']
base_dict['excluded'] = ['submissions', 'excluded', 'colour', 'tooltip']
env = jinja_template_loading()
temp_name = f"{cls.__name__.lower()}_details.html"
logger.debug(f"Returning template: {temp_name}")

View File

@@ -33,21 +33,10 @@ class SubmissionDetails(QDialog):
self.app = parent.parent().parent().parent().parent().parent().parent()
except AttributeError:
self.app = None
self.setWindowTitle(f"Submission Details - {sub.rsl_plate_num}")
# self.setWindowTitle(f"Submission Details - {sub.rsl_plate_num}")
# create scrollable interior
interior = QScrollArea()
interior.setParent(self)
# self.base_dict = sub.to_dict(full_data=True)
# logger.debug(f"Submission details data:\n{pformat({k:v for k,v in self.base_dict.items() if k != 'samples'})}")
# # don't want id
# del self.base_dict['id']
# logger.debug(f"Creating barcode.")
# if not check_if_app():
# self.base_dict['barcode'] = base64.b64encode(sub.make_plate_barcode(width=120, height=30)).decode('utf-8')
# logger.debug(f"Making platemap...")
# self.base_dict['platemap'] = sub.make_plate_map()
# self.base_dict, self.template = sub.get_details_template(base_dict=self.base_dict)
# self.html = self.template.render(sub=self.base_dict)
self.webview = QWebEngineView(parent=self)
self.webview.setMinimumSize(900, 500)
self.webview.setMaximumSize(900, 500)
@@ -80,6 +69,7 @@ class SubmissionDetails(QDialog):
base_dict, template = sample.get_details_template(base_dict=base_dict)
html = template.render(sample=base_dict)
self.webview.setHtml(html)
self.setWindowTitle(f"Sample Details - {sample.submitter_id}")
@pyqtSlot(str)
def submission_details(self, submission:str|BasicSubmission):
@@ -104,6 +94,7 @@ class SubmissionDetails(QDialog):
self.base_dict, self.template = submission.get_details_template(base_dict=self.base_dict)
self.html = self.template.render(sub=self.base_dict)
self.webview.setHtml(self.html)
self.setWindowTitle(f"Submission Details - {submission.rsl_plate_num}")
def export(self):
"""
@@ -124,8 +115,6 @@ class SubmissionDetails(QDialog):
self.base_dict['export_map'] = base64.b64encode(image_io.getvalue()).decode('utf-8')
del self.base_dict['platemap']
self.html2 = self.template.render(sub=self.base_dict)
with open("test.html", "w") as fw:
fw.write(self.html2)
try:
with open(fname, "w+b") as f:
pisa.CreatePDF(self.html2, dest=f)

View File

@@ -148,11 +148,11 @@ class SubmissionFormContainer(QWidget):
logger.debug(f"Pydantic result: \n\n{pformat(self.pyd)}\n\n")
self.form = self.pyd.toForm(parent=self)
self.layout().addWidget(self.form)
kit_widget = self.form.find_widgets(object_name="extraction_kit")[0].input
logger.debug(f"Kitwidget {kit_widget}")
self.scrape_reagents(kit_widget.currentText())
kit_widget.currentTextChanged.connect(self.scrape_reagents)
# compare obj.reagents with expected reagents in kit
# kit_widget = self.form.find_widgets(object_name="extraction_kit")[0].input
# logger.debug(f"Kitwidget {kit_widget}")
# self.scrape_reagents(kit_widget.currentText())
# kit_widget.currentTextChanged.connect(self.scrape_reagents)
# # compare obj.reagents with expected reagents in kit
if self.prsr.sample_result != None:
report.add_result(msg=self.prsr.sample_result, status="Warning")
self.report.add_result(report)
@@ -220,7 +220,8 @@ class SubmissionFormContainer(QWidget):
for reagent in self.form.reagents:
logger.debug(f"Creating widget for {reagent}")
add_widget = ReagentFormWidget(parent=self, reagent=reagent, extraction_kit=self.ext_kit)
self.form.layout().addWidget(add_widget)
# self.form.layout().addWidget(add_widget)
self.form.layout.addWidget(add_widget)
if reagent.missing:
missing_reagents.append(reagent)
logger.debug(f"Checking integrity of {self.ext_kit}")
@@ -397,15 +398,15 @@ class SubmissionFormWidget(QWidget):
super().__init__(parent)
self.ignore = ['filepath', 'samples', 'reagents', 'csv', 'ctx', 'comment', 'equipment', 'source_plates']
self.recover = ['filepath', 'samples', 'csv', 'comment', 'equipment']
layout = QVBoxLayout()
self.layout = QVBoxLayout()
for k, v in kwargs.items():
if k not in self.ignore:
add_widget = self.create_widget(key=k, value=v, submission_type=kwargs['submission_type'])
if add_widget != None:
layout.addWidget(add_widget)
self.layout.addWidget(add_widget)
else:
setattr(self, k, v)
self.setLayout(layout)
self.setLayout(self.layout)
def create_widget(self, key:str, value:dict, submission_type:str|None=None) -> "self.InfoItem":
"""
@@ -420,7 +421,15 @@ class SubmissionFormWidget(QWidget):
self.InfoItem: Form widget to hold name:value
"""
if key not in self.ignore:
return self.InfoItem(self, key=key, value=value, submission_type=submission_type)
widget = self.InfoItem(self, key=key, value=value, submission_type=submission_type)
# match key:
# case "extraction_kit":
# # compare obj.reagents with expected reagents in kit
# self.scrape_reagents(widget.currentText())
# widget.currentTextChanged.connect(self.scrape_reagents)
# case _:
# pass
return widget
return None
def clear_form(self):