Bugs squashed.
This commit is contained in:
@@ -4,7 +4,7 @@ from pathlib import Path
|
||||
|
||||
# Version of the realpython-reader package
|
||||
__project__ = "submissions"
|
||||
__version__ = "202311.2b"
|
||||
__version__ = "202311.3b"
|
||||
__author__ = {"name":"Landon Wark", "email":"Landon.Wark@phac-aspc.gc.ca"}
|
||||
__copyright__ = "2022-2023, Government of Canada"
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import sys
|
||||
import os
|
||||
# environment variable must be set to enable qtwebengine in network path
|
||||
if getattr(sys, 'frozen', False):
|
||||
# if getattr(sys, 'frozen', False):
|
||||
# os.environ['QTWEBENGINE_DISABLE_SANDBOX'] = "1"
|
||||
from tools import get_config, setup_logger, check_if_app
|
||||
if check_if_app():
|
||||
os.environ['QTWEBENGINE_DISABLE_SANDBOX'] = "1"
|
||||
from tools import get_config, setup_logger
|
||||
# setup custom logger
|
||||
logger = setup_logger(verbosity=3)
|
||||
# create settings object
|
||||
|
||||
@@ -471,6 +471,21 @@ class Reagent(Base):
|
||||
pass
|
||||
return query_return(query=query, limit=limit)
|
||||
|
||||
def update_last_used(self, kit:KitType):
|
||||
report = Report()
|
||||
logger.debug(f"Attempting update of reagent type at intersection of ({self}), ({kit})")
|
||||
rt = ReagentType.query(kit_type=kit, reagent=self, limit=1)
|
||||
if rt != None:
|
||||
logger.debug(f"got reagenttype {rt}")
|
||||
assoc = KitTypeReagentTypeAssociation.query(kit_type=kit, reagent_type=rt)
|
||||
if assoc != None:
|
||||
if assoc.last_used != self.lot:
|
||||
logger.debug(f"Updating {assoc} last used to {self.lot}")
|
||||
assoc.last_used = self.lot
|
||||
result = assoc.save()
|
||||
return(report.add_result(result))
|
||||
return report.add_result(Result(msg=f"Updating last used {rt} was not performed.", status="Information"))
|
||||
|
||||
class Discount(Base):
|
||||
"""
|
||||
Relationship table for client labs for certain kits.
|
||||
|
||||
@@ -25,7 +25,6 @@ from dateutil.parser._parser import ParserError
|
||||
import yaml
|
||||
from sqlalchemy.exc import OperationalError as AlcOperationalError, IntegrityError as AlcIntegrityError, StatementError
|
||||
from sqlite3 import OperationalError as SQLOperationalError, IntegrityError as SQLIntegrityError
|
||||
import sys
|
||||
|
||||
logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
@@ -572,6 +571,17 @@ class BasicSubmission(Base):
|
||||
except AttributeError:
|
||||
logger.error(f"Could not set {self} attribute {key} to {value}")
|
||||
|
||||
def update_subsampassoc(self, sample:BasicSample, input_dict:dict):
|
||||
assoc = SubmissionSampleAssociation.query(submission=self, sample=sample, limit=1)
|
||||
for k,v in input_dict.items():
|
||||
try:
|
||||
setattr(assoc, k, v)
|
||||
except AttributeError:
|
||||
logger.error(f"Can't set {k} to {v}")
|
||||
# result = store_object(ctx=ctx, object=assoc)
|
||||
result = assoc.save()
|
||||
return result
|
||||
|
||||
# Below are the custom submission types
|
||||
|
||||
class BacterialCulture(BasicSubmission):
|
||||
@@ -925,6 +935,8 @@ class WastewaterArtic(BasicSubmission):
|
||||
input_dict['csv'] = df
|
||||
return input_dict
|
||||
|
||||
# Sample Classes
|
||||
|
||||
class BasicSample(Base):
|
||||
"""
|
||||
Base of basic sample which polymorphs into BCSample and WWSample
|
||||
@@ -1115,6 +1127,8 @@ class BasicSample(Base):
|
||||
instance.sample_type = sample_type
|
||||
return instance
|
||||
|
||||
#Below are the custom sample types
|
||||
|
||||
class WastewaterSample(BasicSample):
|
||||
"""
|
||||
Derivative wastewater sample
|
||||
@@ -1199,6 +1213,8 @@ class BacterialCultureSample(BasicSample):
|
||||
sample['name'] = f"{self.submitter_id} - ({self.organism})"
|
||||
return sample
|
||||
|
||||
# Submission to Sample Associations
|
||||
|
||||
class SubmissionSampleAssociation(Base):
|
||||
"""
|
||||
table containing submission/sample associations
|
||||
|
||||
@@ -13,7 +13,7 @@ import re
|
||||
import logging
|
||||
from tools import check_not_nan, convert_nans_to_nones, jinja_template_loading, Report, Result
|
||||
from backend.db.models import *
|
||||
from sqlalchemy.exc import StatementError
|
||||
from sqlalchemy.exc import StatementError, IntegrityError
|
||||
from PyQt6.QtWidgets import QComboBox, QWidget
|
||||
from pprint import pformat
|
||||
from openpyxl import load_workbook
|
||||
@@ -172,7 +172,10 @@ class PydSample(BaseModel, extra='allow'):
|
||||
submission=submission,
|
||||
sample=instance,
|
||||
row=row, column=column)
|
||||
instance.sample_submission_associations.append(association)
|
||||
try:
|
||||
instance.sample_submission_associations.append(association)
|
||||
except IntegrityError:
|
||||
instance.metadata.session.rollback()
|
||||
return instance, result
|
||||
|
||||
class PydSubmission(BaseModel, extra='allow'):
|
||||
@@ -408,9 +411,9 @@ class PydSubmission(BaseModel, extra='allow'):
|
||||
extraction_kit = KitType.query(name=self.extraction_kit['value'])
|
||||
logger.debug(f"We have the extraction kit: {extraction_kit.name}")
|
||||
excel_map = extraction_kit.construct_xl_map_for_use(self.submission_type['value'])
|
||||
logger.debug(f"Extraction kit map:\n\n{pformat(excel_map)}")
|
||||
logger.debug(f"Missing reagents going into autofile: {pformat(reagents)}")
|
||||
logger.debug(f"Missing info going into autofile: {pformat(info)}")
|
||||
# logger.debug(f"Extraction kit map:\n\n{pformat(excel_map)}")
|
||||
# logger.debug(f"Missing reagents going into autofile: {pformat(reagents)}")
|
||||
# logger.debug(f"Missing info going into autofile: {pformat(info)}")
|
||||
new_reagents = []
|
||||
for reagent in reagents:
|
||||
new_reagent = {}
|
||||
|
||||
@@ -145,7 +145,7 @@ class SubmissionsSheet(QTableView):
|
||||
index = (self.selectionModel().currentIndex())
|
||||
value = index.sibling(index.row(),1).data()
|
||||
logger.debug(f"Selected value: {value}")
|
||||
dlg = SubmissionComment(ctx=self.ctx, rsl=value)
|
||||
dlg = SubmissionComment(rsl=value)
|
||||
if dlg.exec():
|
||||
dlg.add_comment()
|
||||
|
||||
@@ -455,6 +455,8 @@ class SubmissionDetails(QDialog):
|
||||
|
||||
super().__init__(parent)
|
||||
# self.ctx = ctx
|
||||
self.app = parent.parent().parent().parent().parent().parent().parent
|
||||
print(f"App: {self.app}")
|
||||
self.setWindowTitle("Submission Details")
|
||||
# create scrollable interior
|
||||
interior = QScrollArea()
|
||||
@@ -603,10 +605,10 @@ class SubmissionComment(QDialog):
|
||||
"""
|
||||
a window for adding comment text to a submission
|
||||
"""
|
||||
def __init__(self, ctx:Settings, rsl:str) -> None:
|
||||
def __init__(self, rsl:str) -> None:
|
||||
|
||||
super().__init__()
|
||||
self.ctx = ctx
|
||||
# self.ctx = ctx
|
||||
self.rsl = rsl
|
||||
self.setWindowTitle(f"{self.rsl} Submission Comment")
|
||||
# create text field
|
||||
@@ -640,7 +642,6 @@ class SubmissionComment(QDialog):
|
||||
except AttributeError:
|
||||
sub.comment = [full_comment]
|
||||
logger.debug(sub.__dict__)
|
||||
self.ctx.database_session.add(sub)
|
||||
self.ctx.database_session.commit()
|
||||
sub.save()
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ from tools import Report, Result, check_not_nan
|
||||
from backend.excel.parser import SheetParser, PCRParser
|
||||
from backend.validators import PydSubmission, PydReagent
|
||||
from backend.db import (
|
||||
check_kit_integrity, update_last_used, KitType, Organization, SubmissionType, Reagent,
|
||||
check_kit_integrity, KitType, Organization, SubmissionType, Reagent,
|
||||
ReagentType, KitTypeReagentTypeAssociation, BasicSubmission, update_subsampassoc_with_pcr
|
||||
)
|
||||
from pprint import pformat
|
||||
@@ -22,7 +22,7 @@ import difflib
|
||||
from datetime import date
|
||||
import inspect
|
||||
import json
|
||||
|
||||
import sys
|
||||
|
||||
logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
@@ -80,27 +80,6 @@ class SubmissionFormContainer(QWidget):
|
||||
case _:
|
||||
self.app.result_reporter()
|
||||
|
||||
# def kit_reload_function(self):
|
||||
# """
|
||||
# Reload the fields in the form
|
||||
|
||||
# Args:
|
||||
# obj (QMainWindow): original app window
|
||||
|
||||
# Returns:
|
||||
# Tuple[QMainWindow, dict]: Collection of new main app window and result dict
|
||||
# """
|
||||
# report = Report()
|
||||
# # for item in obj.table_widget.formlayout.parentWidget().findChildren(QWidget):
|
||||
# logger.debug(f"Attempting to clear {obj.form.find_widgets()}")
|
||||
# for item in self.form.find_widgets():
|
||||
# if isinstance(item, ReagentFormWidget):
|
||||
# item.setParent(None)
|
||||
# self.kit_integrity_completion_function()
|
||||
# self.report.add_result(report)
|
||||
|
||||
|
||||
|
||||
def kit_integrity_completion(self):
|
||||
"""
|
||||
Performs check of imported reagents
|
||||
@@ -296,6 +275,8 @@ class SubmissionFormContainer(QWidget):
|
||||
self.report.add_result(report)
|
||||
return
|
||||
base_submission, result = self.pyd.toSQL()
|
||||
# logger.debug(f"Base submission: {base_submission.to_dict()}")
|
||||
# sys.exit()
|
||||
# check output message for issues
|
||||
match result.code:
|
||||
# code 0: everything is fine.
|
||||
@@ -303,7 +284,7 @@ class SubmissionFormContainer(QWidget):
|
||||
self.report.add_result(None)
|
||||
# code 1: ask for overwrite
|
||||
case 1:
|
||||
dlg = QuestionAsker(title=f"Review {base_submission.rsl_plate_num}?", message=result['message'])
|
||||
dlg = QuestionAsker(title=f"Review {base_submission.rsl_plate_num}?", message=result.msg)
|
||||
if dlg.exec():
|
||||
# Do not add duplicate reagents.
|
||||
# base_submission.reagents = []
|
||||
@@ -320,7 +301,10 @@ class SubmissionFormContainer(QWidget):
|
||||
pass
|
||||
# add reagents to submission object
|
||||
for reagent in base_submission.reagents:
|
||||
update_last_used(reagent=reagent, kit=base_submission.extraction_kit)
|
||||
# logger.debug(f"Updating: {reagent} with {reagent.lot}")
|
||||
# update_last_used(reagent=reagent, kit=base_submission.extraction_kit)
|
||||
reagent.update_last_used(kit=base_submission.extraction_kit)
|
||||
# sys.exit()
|
||||
logger.debug(f"Here is the final submission: {pformat(base_submission.__dict__)}")
|
||||
logger.debug(f"Parsed reagents: {pformat(base_submission.reagents)}")
|
||||
logger.debug(f"Sending submission: {base_submission.rsl_plate_num} to database.")
|
||||
@@ -329,7 +313,7 @@ class SubmissionFormContainer(QWidget):
|
||||
self.app.table_widget.sub_wid.setData()
|
||||
# reset form
|
||||
self.form.setParent(None)
|
||||
logger.debug(f"All attributes of obj: {pformat(self.__dict__)}")
|
||||
# logger.debug(f"All attributes of obj: {pformat(self.__dict__)}")
|
||||
wkb = self.pyd.autofill_excel()
|
||||
if wkb != None:
|
||||
fname = select_save_file(obj=self, default_name=self.pyd.construct_filename(), extension="xlsx")
|
||||
@@ -352,6 +336,7 @@ class SubmissionFormContainer(QWidget):
|
||||
fname = select_save_file(obj=self, default_name=self.pyd.construct_filename(), extension="csv")
|
||||
try:
|
||||
self.pyd.csv.to_csv(fname.__str__(), index=False)
|
||||
del self.pyd.csv
|
||||
except PermissionError:
|
||||
logger.debug(f"Could not get permissions to {fname}. Possibly the request was cancelled.")
|
||||
|
||||
@@ -424,7 +409,8 @@ class SubmissionFormContainer(QWidget):
|
||||
sample_dict = [item for item in parser.samples if item['sample']==sample.rsl_number][0]
|
||||
except IndexError:
|
||||
continue
|
||||
update_subsampassoc_with_pcr(submission=sub, sample=sample, input_dict=sample_dict)
|
||||
# update_subsampassoc_with_pcr(submission=sub, sample=sample, input_dict=sample_dict)
|
||||
sub.update_subsampassoc(sample=sample, input_dict=sample_dict)
|
||||
self.report.add_result(Result(msg=f"We added PCR info to {sub.rsl_plate_num}.", status='Information'))
|
||||
# return obj, result
|
||||
|
||||
@@ -481,6 +467,7 @@ class SubmissionFormWidget(QWidget):
|
||||
info[field] = value
|
||||
logger.debug(f"Info: {pformat(info)}")
|
||||
logger.debug(f"Reagents: {pformat(reagents)}")
|
||||
# sys.exit()
|
||||
# app = self.parent().parent().parent().parent().parent().parent().parent().parent
|
||||
submission = PydSubmission(filepath=self.filepath, reagents=reagents, samples=self.samples, **info)
|
||||
return submission
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
</style>
|
||||
<title>Submission Details for {{ sub['Plate Number'] }}</title>
|
||||
</head>
|
||||
{% set excluded = ['reagents', 'samples', 'controls', 'ext_info', 'pcr_info', 'comments', 'barcode', 'platemap'] %}
|
||||
{% set excluded = ['reagents', 'samples', 'controls', 'ext_info', 'pcr_info', 'comments', 'barcode', 'platemap', 'export_map'] %}
|
||||
<body>
|
||||
<h2><u>Submission Details for {{ sub['Plate Number'] }}</u></h2> {% if sub['barcode'] %}<img align='right' height="30px" width="120px" src="data:image/jpeg;base64,{{ sub['barcode'] | safe }}">{% endif %}
|
||||
<p>{% for key, value in sub.items() if key not in excluded %}
|
||||
|
||||
Reference in New Issue
Block a user