Bug fixes

This commit is contained in:
lwark
2025-08-13 09:45:51 -05:00
parent 6380f1e2a9
commit 6f58030e75
11 changed files with 110 additions and 50 deletions

View File

@@ -227,9 +227,11 @@ class BaseClass(Base):
""" """
if not objects: if not objects:
try: try:
records = [obj.to_sub_dict(**kwargs) for obj in cls.query()] # records = [obj.to_sub_dict(**kwargs) for obj in cls.query()]
records = [obj.details_dict(**kwargs) for obj in cls.query()]
except AttributeError: except AttributeError:
records = [obj.to_dict(**kwargs) for obj in cls.query(page_size=0)] # records = [obj.to_dict(**kwargs) for obj in cls.query(page_size=0)]
records = [obj.details_dict(**kwargs) for obj in cls.query(page_size=0)]
else: else:
try: try:
records = [obj.to_sub_dict(**kwargs) for obj in objects] records = [obj.to_sub_dict(**kwargs) for obj in objects]
@@ -244,7 +246,7 @@ class BaseClass(Base):
# and not isinstance(v.property, _RelationshipDeclared)] # and not isinstance(v.property, _RelationshipDeclared)]
sanitized_kwargs = {k: v for k, v in kwargs.items() if k in allowed} sanitized_kwargs = {k: v for k, v in kwargs.items() if k in allowed}
outside_kwargs = {k: v for k, v in kwargs.items() if k not in allowed} outside_kwargs = {k: v for k, v in kwargs.items() if k not in allowed}
logger.debug(f"Sanitized kwargs: {sanitized_kwargs}") # logger.debug(f"Sanitized kwargs: {sanitized_kwargs}")
instance = cls.query(**sanitized_kwargs) instance = cls.query(**sanitized_kwargs)
if not instance or isinstance(instance, list): if not instance or isinstance(instance, list):
instance = cls() instance = cls()
@@ -259,10 +261,10 @@ class BaseClass(Base):
from backend.validators.pydant import PydBaseClass from backend.validators.pydant import PydBaseClass
if issubclass(v.__class__, PydBaseClass): if issubclass(v.__class__, PydBaseClass):
setattr(instance, k, v.to_sql()) setattr(instance, k, v.to_sql())
else: # else:
logger.error(f"Could not set {k} due to {e}") # logger.error(f"Could not set {k} due to {e}")
instance._misc_info.update(outside_kwargs) instance._misc_info.update(outside_kwargs)
logger.info(f"Instance from query or create: {instance}, new: {new}") # logger.info(f"Instance from query or create: {instance}, new: {new}")
return instance, new return instance, new
@classmethod @classmethod
@@ -300,7 +302,7 @@ class BaseClass(Base):
# logger.debug(f"Incoming query: {query}") # logger.debug(f"Incoming query: {query}")
singles = cls.get_default_info('singles') singles = cls.get_default_info('singles')
for k, v in kwargs.items(): for k, v in kwargs.items():
logger.info(f"Using key: {k} with value: {v} against {cls}") # logger.info(f"Using key: {k} with value: {v} against {cls}")
try: try:
attr = getattr(cls, k) attr = getattr(cls, k)
except (ArgumentError, AttributeError) as e: except (ArgumentError, AttributeError) as e:
@@ -318,7 +320,7 @@ class BaseClass(Base):
except ArgumentError: except ArgumentError:
continue continue
else: else:
logger.debug("Single item.") # logger.debug("Single item.")
try: try:
query = query.filter(attr == v) query = query.filter(attr == v)
except ArgumentError: except ArgumentError:

View File

@@ -6,7 +6,7 @@ import zipfile, logging, re
from operator import itemgetter from operator import itemgetter
from pprint import pformat from pprint import pformat
import numpy as np import numpy as np
from sqlalchemy import Column, String, TIMESTAMP, JSON, INTEGER, ForeignKey, Interval, Table, FLOAT, BLOB from sqlalchemy import Column, String, TIMESTAMP, JSON, INTEGER, ForeignKey, Interval, Table, FLOAT, BLOB, func
from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import relationship, validates, Query from sqlalchemy.orm import relationship, validates, Query
from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.ext.associationproxy import association_proxy
@@ -1447,7 +1447,7 @@ class Procedure(BaseClass):
) #: Relation to ProcedureReagentAssociation ) #: Relation to ProcedureReagentAssociation
reagentlot = association_proxy("procedurereagentlotassociation", reagentlot = association_proxy("procedurereagentlotassociation",
"reagent", creator=lambda reg: ProcedureReagentLotAssociation( "reagentlot", creator=lambda reg: ProcedureReagentLotAssociation(
reagent=reg)) #: Association proxy to RunReagentAssociation.reagent reagent=reg)) #: Association proxy to RunReagentAssociation.reagent
procedureequipmentassociation = relationship( procedureequipmentassociation = relationship(
@@ -1477,9 +1477,22 @@ class Procedure(BaseClass):
@classmethod @classmethod
@setup_lookup @setup_lookup
def query(cls, id: int | None = None, name: str | None = None, limit: int = 0, **kwargs) -> Procedure | List[ def query(cls, id: int | None = None, name: str | None = None, start_date: date | datetime | str | int | None = None,
end_date: date | datetime | str | int | None = None, limit: int = 0, **kwargs) -> Procedure | List[
Procedure]: Procedure]:
query: Query = cls.__database_session__.query(cls) query: Query = cls.__database_session__.query(cls)
if start_date is not None and end_date is None:
logger.warning(f"Start date with no end date, using today.")
end_date = date.today()
if end_date is not None and start_date is None:
# NOTE: this query returns a tuple of (object, datetime), need to get only datetime.
start_date = cls.__database_session__.query(cls, func.min(cls.submitted_date)).first()[1]
logger.warning(f"End date with no start date, using first procedure date: {start_date}")
if start_date is not None:
start_date = cls.rectify_query_date(start_date)
end_date = cls.rectify_query_date(end_date, eod=True)
logger.debug(f"Start date: {start_date}, end date: {end_date}")
query = query.filter(cls.started_date.between(start_date, end_date))
match id: match id:
case int(): case int():
query = query.filter(cls.id == id) query = query.filter(cls.id == id)
@@ -1574,8 +1587,8 @@ class Procedure(BaseClass):
def details_dict(self, **kwargs): def details_dict(self, **kwargs):
output = super().details_dict() output = super().details_dict()
output['kittype'] = output['kittype'].details_dict() # output['kittype'] = output['kittype'].details_dict()
output['kit_type'] = self.kittype.name # output['kit_type'] = self.kittype.name
output['proceduretype'] = output['proceduretype'].details_dict()['name'] output['proceduretype'] = output['proceduretype'].details_dict()['name']
output['results'] = [result.details_dict() for result in output['results']] output['results'] = [result.details_dict() for result in output['results']]
run_samples = [sample for sample in self.run.sample] run_samples = [sample for sample in self.run.sample]
@@ -1601,6 +1614,9 @@ class Procedure(BaseClass):
"procedurereagentlotassociation", "procedurereagentlotassociation",
"procedureequipmentassociation", "proceduretipsassociation", "reagent", "equipment", "procedureequipmentassociation", "proceduretipsassociation", "reagent", "equipment",
"tips", "control", "kittype"] "tips", "control", "kittype"]
output['sample_count'] = len(active_samples)
output['clientlab'] = self.run.clientsubmission.clientlab.name
output['cost'] = 0.00
# output = self.clean_details_dict(output) # output = self.clean_details_dict(output)
return output return output
@@ -1650,6 +1666,27 @@ class Procedure(BaseClass):
from backend.db.models import ProcedureSampleAssociation from backend.db.models import ProcedureSampleAssociation
return ProcedureSampleAssociation(procedure=self, sample=sample) return ProcedureSampleAssociation(procedure=self, sample=sample)
@classmethod
def get_default_info(cls, *args) -> dict | list | str:
dicto = super().get_default_info()
recover = ['filepath', 'sample', 'csv', 'comment', 'equipment']
dicto.update(dict(
details_ignore=['excluded', 'reagents', 'sample',
'extraction_info', 'comment', 'barcode',
'platemap', 'export_map', 'equipment', 'tips', 'custom', 'reagentlot',
'procedurereagentassociation'],
# NOTE: Fields not placed in ui form
form_ignore=['reagents', 'ctx', 'id', 'cost', 'extraction_info', 'signed_by', 'comment', 'namer',
'submission_object', "tips", 'contact_phone', 'custom', 'cost_centre', 'completed_date',
'control', "origin_plate"] + recover,
# NOTE: Fields not placed in ui form to be moved to pydantic
form_recover=recover
))
if args:
output = {k: v for k, v in dicto.items() if k in args}
else:
output = {k: v for k, v in dicto.items()}
return output
# class ProcedureTypeKitTypeAssociation(BaseClass): # class ProcedureTypeKitTypeAssociation(BaseClass):
# """ # """
@@ -2118,8 +2155,8 @@ class ProcedureReagentLotAssociation(BaseClass):
output = super().details_dict() output = super().details_dict()
# NOTE: Figure out how to merge the misc_info if doing .update instead. # NOTE: Figure out how to merge the misc_info if doing .update instead.
relevant = {k: v for k, v in output.items() if k not in ['reagent']} relevant = {k: v for k, v in output.items() if k not in ['reagent']}
output = output['reagent'].details_dict() output = output['reagentlot'].details_dict()
output['reagent_name'] = self.reagentlot.reagent.name
misc = output['misc_info'] misc = output['misc_info']
output.update(relevant) output.update(relevant)
output['reagentrole'] = self.reagentrole output['reagentrole'] = self.reagentrole
@@ -2538,7 +2575,7 @@ class EquipmentRole(BaseClass):
# output['process'] = [item.details_dict() for item in output['process']] # output['process'] = [item.details_dict() for item in output['process']]
output['process'] = [version.details_dict() for version in output['process'] = [version.details_dict() for version in
flatten_list([process.processversion for process in self.process])] flatten_list([process.processversion for process in self.process])]
logger.debug(f"\n\nProcess: {pformat(output['process'])}") # logger.debug(f"\n\nProcess: {pformat(output['process'])}")
try: try:
output['tips'] = [item.details_dict() for item in output['tips']] output['tips'] = [item.details_dict() for item in output['tips']]
except KeyError: except KeyError:
@@ -2848,6 +2885,7 @@ class Process(BaseClass):
def details_dict(self, **kwargs): def details_dict(self, **kwargs):
output = super().details_dict(**kwargs) output = super().details_dict(**kwargs)
output['processversion'] = [item.details_dict() for item in self.processversion] output['processversion'] = [item.details_dict() for item in self.processversion]
logger.debug(f"Process output dict: {pformat(output)}")
return output return output
def to_pydantic(self): def to_pydantic(self):

View File

@@ -633,7 +633,7 @@ class Run(BaseClass, LogMixin):
samples = self.generate_associations(name="clientsubmissionsampleassociation") samples = self.generate_associations(name="clientsubmissionsampleassociation")
equipment = self.generate_associations(name="submission_equipment_associations") equipment = self.generate_associations(name="submission_equipment_associations")
tips = self.generate_associations(name="submission_tips_associations") tips = self.generate_associations(name="submission_tips_associations")
procedures = [item.to_dict(full_data=True) for item in self.procedure] procedures = [item.details_dict() for item in self.procedure]
custom = self.custom custom = self.custom
else: else:
samples = None samples = None
@@ -696,7 +696,8 @@ class Run(BaseClass, LogMixin):
output['excluded'] += ['procedure', "runsampleassociation", 'excluded', 'expanded', 'sample', 'id', 'custom', output['excluded'] += ['procedure', "runsampleassociation", 'excluded', 'expanded', 'sample', 'id', 'custom',
'permission', "clientsubmission"] 'permission', "clientsubmission"]
output['sample_count'] = self.sample_count output['sample_count'] = self.sample_count
output['client_submission'] = self.clientsubmission.name output['clientsubmission'] = self.clientsubmission.name
output['clientlab'] = self.clientsubmission.clientlab
output['started_date'] = self.started_date output['started_date'] = self.started_date
output['completed_date'] = self.completed_date output['completed_date'] = self.completed_date
return output return output
@@ -718,7 +719,8 @@ class Run(BaseClass, LogMixin):
query_out = cls.query(page_size=0, start_date=start_date, end_date=end_date) query_out = cls.query(page_size=0, start_date=start_date, end_date=end_date)
records = [] records = []
for sub in query_out: for sub in query_out:
output = sub.to_dict(full_data=True) # output = sub.to_dict(full_data=True)
output = sub.details_dict()
for k, v in output.items(): for k, v in output.items():
if isinstance(v, types.GeneratorType): if isinstance(v, types.GeneratorType):
output[k] = [item for item in v] output[k] = [item for item in v]
@@ -839,7 +841,8 @@ class Run(BaseClass, LogMixin):
pd.DataFrame: Pandas Dataframe of all relevant procedure pd.DataFrame: Pandas Dataframe of all relevant procedure
""" """
# NOTE: use lookup function to create list of dicts # NOTE: use lookup function to create list of dicts
subs = [item.to_dict() for item in # subs = [item.to_dict() for item in
subs = [item.details_dict() for item in
cls.query(submissiontype=submission_type, limit=limit, chronologic=chronologic, page=page, cls.query(submissiontype=submission_type, limit=limit, chronologic=chronologic, page=page,
page_size=page_size)] page_size=page_size)]
df = pd.DataFrame.from_records(subs) df = pd.DataFrame.from_records(subs)

View File

@@ -131,7 +131,8 @@ class DefaultTABLEParser(DefaultParser):
df = df.dropna(axis=1, how='all') df = df.dropna(axis=1, how='all')
for ii, row in enumerate(df.iterrows()): for ii, row in enumerate(df.iterrows()):
output = {} output = {}
for key, value in row[1].to_dict().items(): # for key, value in row[1].to_dict().items():
for key, value in row[1].details_dict().items():
if isinstance(key, str): if isinstance(key, str):
key = key.lower().replace(" ", "_") key = key.lower().replace(" ", "_")
key = re.sub(r"_(\(.*\)|#)", "", key) key = re.sub(r"_(\(.*\)|#)", "", key)

View File

@@ -7,7 +7,9 @@ from pandas import DataFrame, ExcelWriter
from pathlib import Path from pathlib import Path
from datetime import date from datetime import date
from typing import Tuple, List from typing import Tuple, List
from backend.db.models import Run
# from backend import Procedure
from backend.db.models import Procedure, Run
from tools import jinja_template_loading, get_first_blank_df_row, row_map, flatten_list from tools import jinja_template_loading, get_first_blank_df_row, row_map, flatten_list
from PyQt6.QtWidgets import QWidget from PyQt6.QtWidgets import QWidget
from openpyxl.worksheet.worksheet import Worksheet from openpyxl.worksheet.worksheet import Worksheet
@@ -45,9 +47,10 @@ class ReportMaker(object):
self.start_date = start_date self.start_date = start_date
self.end_date = end_date self.end_date = end_date
# NOTE: Set page size to zero to override limiting query size. # NOTE: Set page size to zero to override limiting query size.
self.runs = Run.query(start_date=start_date, end_date=end_date, page_size=0) # self.runs = Run.query(start_date=start_date, end_date=end_date, page_size=0)
self.procedures = Procedure.query(start_date=start_date, end_date=end_date, page_size=0)
if organizations is not None: if organizations is not None:
self.runs = [run for run in self.runs if run.clientsubmission.clientlab.name in organizations] self.procedures = [procedure for procedure in self.procedures if procedure.run.clientsubmission.clientlab.name in organizations]
self.detailed_df, self.summary_df = self.make_report_xlsx() self.detailed_df, self.summary_df = self.make_report_xlsx()
self.html = self.make_report_html(df=self.summary_df) self.html = self.make_report_html(df=self.summary_df)
@@ -58,15 +61,17 @@ class ReportMaker(object):
Returns: Returns:
DataFrame: output dataframe DataFrame: output dataframe
""" """
if not self.runs: if not self.procedures:
return DataFrame(), DataFrame() return DataFrame(), DataFrame()
df = DataFrame.from_records([item.to_dict(report=True) for item in self.runs]) # df = DataFrame.from_records([item.to_dict(report=True) for item in self.runs])
df = DataFrame.from_records([item.details_dict() for item in self.procedures])
logger.debug(df.columns)
# NOTE: put procedure with the same lab together # NOTE: put procedure with the same lab together
df = df.sort_values("clientlab") df = df.sort_values("clientlab")
# NOTE: aggregate cost and sample count columns # NOTE: aggregate cost and sample count columns
df2 = df.groupby(["clientlab", "kittype"]).agg( df2 = df.groupby(["clientlab", "proceduretype"]).agg(
{'kittype': 'count', 'cost': 'sum', 'sample_count': 'sum'}) {'proceduretype': 'count', 'cost': 'sum', 'sample_count': 'sum'})
df2 = df2.rename(columns={"kittype": 'run_count'}) df2 = df2.rename(columns={"proceduretype": 'run_count'})
df = df.drop('id', axis=1) df = df.drop('id', axis=1)
df = df.sort_values(['clientlab', "started_date"]) df = df.sort_values(['clientlab', "started_date"])
return df, df2 return df, df2

View File

@@ -25,9 +25,13 @@ logger = logging.getLogger(f"submission.{__name__}")
class PydBaseClass(BaseModel, extra='allow', validate_assignment=True): class PydBaseClass(BaseModel, extra='allow', validate_assignment=True):
_sql_object: ClassVar = None # _sql_object: ClassVar = None
key_value_order: ClassVar = [] key_value_order: ClassVar = []
@classproperty
def _sql_object(cls):
return getattr(models, cls.__name__.replace("Pyd", ""))
@model_validator(mode="before") @model_validator(mode="before")
@classmethod @classmethod
def prevalidate(cls, data): def prevalidate(cls, data):
@@ -36,7 +40,7 @@ class PydBaseClass(BaseModel, extra='allow', validate_assignment=True):
try: try:
items = data.items() items = data.items()
except AttributeError as e: except AttributeError as e:
logger.error(f"Could not prevalidate {cls.__name__} due to {e}") logger.error(f"Could not prevalidate {cls.__name__} due to {e} for {pformat(data)}")
return data return data
for key, value in items: for key, value in items:
new_key = key.replace("_", "") new_key = key.replace("_", "")
@@ -67,7 +71,8 @@ class PydBaseClass(BaseModel, extra='allow', validate_assignment=True):
def __init__(self, **data): def __init__(self, **data):
# NOTE: Grab the sql model for validation purposes. # NOTE: Grab the sql model for validation purposes.
self.__class__._sql_object = getattr(models, self.__class__.__name__.replace("Pyd", "")) # self.__class__._sql_object = getattr(models, self.__class__.__name__.replace("Pyd", ""))
logger.debug(f"Initial data: {data}")
super().__init__(**data) super().__init__(**data)
def filter_field(self, key: str) -> Any: def filter_field(self, key: str) -> Any:
@@ -398,14 +403,17 @@ class PydEquipment(PydBaseClass):
# if isinstance(value, dict): # if isinstance(value, dict):
# value = value['processes'] # value = value['processes']
if isinstance(value, GeneratorType): if isinstance(value, GeneratorType):
value = [item.name for item in value] value = [item for item in value]
value = convert_nans_to_nones(value) value = convert_nans_to_nones(value)
if not value: if not value:
value = [''] value = ['']
# logger.debug(value) # logger.debug(value)
try: try:
# value = [item.strip() for item in value] # value = [item.strip() for item in value]
value = next((PydProcess(**process.details_dict()) for process in value)) d = next((process for process in value), None)
logger.debug(f"Next process: {d.detail_dict()}")
value = PydProcess(d.details_dict())
# value = next((process.to_pydantic() for process in value))
except AttributeError: except AttributeError:
pass pass
return value return value
@@ -1461,7 +1469,7 @@ class PydProcedure(PydBaseClass, arbitrary_types_allowed=True):
idx = 0 idx = 0
insertable = PydReagent(reagentrole=reagentrole, name=name, lot=lot, expiry=expiry) insertable = PydReagent(reagentrole=reagentrole, name=name, lot=lot, expiry=expiry)
self.reagent.insert(idx, insertable) self.reagent.insert(idx, insertable)
# logger.debug(self.reagent) logger.debug(self.reagent)
@classmethod @classmethod
def update_new_reagents(cls, reagent: PydReagent): def update_new_reagents(cls, reagent: PydReagent):
@@ -1501,9 +1509,9 @@ class PydProcedure(PydBaseClass, arbitrary_types_allowed=True):
for reagent in self.reagent: for reagent in self.reagent:
if not reagent.lot or reagent.name == "--New--": if not reagent.lot or reagent.name == "--New--":
continue continue
self.update_new_reagents(reagent) # self.update_new_reagents(reagent)
# NOTE: reset reagent associations. # NOTE: reset reagent associations.
sql.procedurereagentassociation = [] # sql.procedurereagentassociation = []
for reagent in self.reagent: for reagent in self.reagent:
if isinstance(reagent, dict): if isinstance(reagent, dict):
reagent = PydReagent(**reagent) reagent = PydReagent(**reagent)
@@ -1542,12 +1550,13 @@ class PydProcedure(PydBaseClass, arbitrary_types_allowed=True):
logger.debug(f"sample {sample_sql} not found in {sql.run.sample}") logger.debug(f"sample {sample_sql} not found in {sql.run.sample}")
run_assoc = RunSampleAssociation(sample=sample_sql, run=self.run, row=sample.row, run_assoc = RunSampleAssociation(sample=sample_sql, run=self.run, row=sample.row,
column=sample.column) column=sample.column)
else: # else:
logger.debug(f"sample {sample_sql} found in {sql.run.sample}") # logger.debug(f"sample {sample_sql} found in {sql.run.sample}")
if sample_sql not in sql.sample: if sample_sql not in sql.sample:
proc_assoc = ProcedureSampleAssociation(new_id=assoc_id_range[iii], procedure=sql, sample=sample_sql, proc_assoc = ProcedureSampleAssociation(new_id=assoc_id_range[iii], procedure=sql, sample=sample_sql,
row=sample.row, column=sample.column, row=sample.row, column=sample.column,
procedure_rank=sample.procedure_rank) procedure_rank=sample.procedure_rank)
sys.exit(pformat(self.equipment))
for equipment in self.equipment: for equipment in self.equipment:
equip = Equipment.query(name=equipment.name) equip = Equipment.query(name=equipment.name)
if equip not in sql.equipment: if equip not in sql.equipment:
@@ -1555,8 +1564,6 @@ class PydProcedure(PydBaseClass, arbitrary_types_allowed=True):
equipmentrole=equip.equipmentrole[0]) equipmentrole=equip.equipmentrole[0])
process = equipment.process.to_sql() process = equipment.process.to_sql()
equip_assoc.process = process equip_assoc.process = process
# logger.debug(f"Output sql: {[pformat(item.__dict__) for item in sql.procedureequipmentassociation]}")
logger.debug(pformat(sql.__dict__))
return sql, None return sql, None

View File

@@ -73,8 +73,8 @@ class ProcedureCreation(QDialog):
from .equipment_usage_2 import EquipmentUsage from .equipment_usage_2 import EquipmentUsage
# logger.debug(f"Edit: {self.edit}") # logger.debug(f"Edit: {self.edit}")
proceduretype_dict = self.proceduretype.details_dict() proceduretype_dict = self.proceduretype.details_dict()
logger.debug(f"Reagent roles: {self.procedure.reagentrole}") # logger.debug(f"Reagent roles: {self.procedure.reagentrole}")
logger.debug(f"Equipment roles: {pformat(proceduretype_dict['equipment'])}") # logger.debug(f"Equipment roles: {pformat(proceduretype_dict['equipment'])}")
# NOTE: Add --New-- as an option for reagents. # NOTE: Add --New-- as an option for reagents.
for key, value in self.procedure.reagentrole.items(): for key, value in self.procedure.reagentrole.items():
value.append(dict(name="--New--")) value.append(dict(name="--New--"))
@@ -124,7 +124,7 @@ class ProcedureCreation(QDialog):
if equipment_of_interest: if equipment_of_interest:
eoi = self.procedure.equipment.pop(self.procedure.equipment.index(equipment_of_interest)) eoi = self.procedure.equipment.pop(self.procedure.equipment.index(equipment_of_interest))
else: else:
eoi = equipment.to_pydantic(proceduretype=self.procedure.proceduretype) eoi = equipment.to_pydantic(equipmentrole=equipmentrole, proceduretype=self.procedure.proceduretype)
eoi.name = equipment.name eoi.name = equipment.name
eoi.asset_number = equipment.asset_number eoi.asset_number = equipment.asset_number
eoi.nickname = equipment.nickname eoi.nickname = equipment.nickname
@@ -185,6 +185,7 @@ class ProcedureCreation(QDialog):
@pyqtSlot(str, str) @pyqtSlot(str, str)
def update_reagent(self, reagentrole: str, name_lot_expiry: str): def update_reagent(self, reagentrole: str, name_lot_expiry: str):
logger.debug(f"{reagentrole}: {name_lot_expiry}")
try: try:
name, lot, expiry = name_lot_expiry.split(" - ") name, lot, expiry = name_lot_expiry.split(" - ")
except ValueError as e: except ValueError as e:

View File

@@ -175,6 +175,7 @@ class SubmissionDetails(QDialog):
if isinstance(proceduretype, str): if isinstance(proceduretype, str):
self.proceduretype = ProcedureType.query(name=proceduretype) self.proceduretype = ProcedureType.query(name=proceduretype)
base_dict = reagent.to_sub_dict(proceduretype=self.proceduretype, full_data=True) base_dict = reagent.to_sub_dict(proceduretype=self.proceduretype, full_data=True)
# base_dict = reagent.details_dict(proceduretype=self.proceduretype, full_data=True)
env = jinja_template_loading() env = jinja_template_loading()
temp_name = "reagent_details.html" temp_name = "reagent_details.html"
try: try:
@@ -224,7 +225,8 @@ class SubmissionDetails(QDialog):
if isinstance(run, str): if isinstance(run, str):
run = Run.query(name=run) run = Run.query(name=run)
self.rsl_plate_number = run.rsl_plate_number self.rsl_plate_number = run.rsl_plate_number
self.base_dict = run.to_dict(full_data=True) # self.base_dict = run.to_dict(full_data=True)
self.base_dict = run.details_dict()
# NOTE: don't want id # NOTE: don't want id
self.base_dict['platemap'] = run.make_plate_map(sample_list=run.hitpicked) self.base_dict['platemap'] = run.make_plate_map(sample_list=run.hitpicked)
self.base_dict['excluded'] = run.get_default_info("details_ignore") self.base_dict['excluded'] = run.get_default_info("details_ignore")

View File

@@ -43,7 +43,7 @@ class Summary(InfoPane):
orgs = self.org_select.get_checked() orgs = self.org_select.get_checked()
self.report_obj = ReportMaker(start_date=self.start_date, end_date=self.end_date, organizations=orgs) self.report_obj = ReportMaker(start_date=self.start_date, end_date=self.end_date, organizations=orgs)
self.webview.setHtml(self.report_obj.html) self.webview.setHtml(self.report_obj.html)
if self.report_obj.runs: if self.report_obj.procedures:
self.save_pdf_button.setEnabled(True) self.save_pdf_button.setEnabled(True)
self.save_excel_button.setEnabled(True) self.save_excel_button.setEnabled(True)
else: else:

View File

@@ -94,6 +94,7 @@ for(let i = 0; i < reagentRoles.length; i++) {
} }
new_reg.appendChild(new_form); new_reg.appendChild(new_form);
} else { } else {
backend.update_reagent(reagentRoles[i].id, reagentRoles[i].value);
newregform = document.getElementById(reagentRoles[i].id + "_addition"); newregform = document.getElementById(reagentRoles[i].id + "_addition");
try { try {
newregform.remove(); newregform.remove();
@@ -101,16 +102,16 @@ for(let i = 0; i < reagentRoles.length; i++) {
catch(err) { catch(err) {
console.log("Missed it."); console.log("Missed it.");
} }
backend.update_reagent(reagentRoles[i].id, reagentRoles[i].value);
} }
}); });
}; };
var equipmentroles = document.getElementsByClassName("equipmentrole");
window.onload = function() { window.onload = function() {
for(let i = 0; i < reagentRoles.length; i++) { for(let i = 0; i < reagentRoles.length; i++) {
backend.update_reagent(reagentRoles[i].id, reagentRoles[i].value); backend.update_reagent(reagentRoles[i].id, reagentRoles[i].value);
} }
} }

View File

@@ -1,6 +1,6 @@
<tr> <tr>
<td style="border: 1px solid black;">{{ reagent['reagentrole'] }}</td> <td style="border: 1px solid black;">{{ reagent['reagentrole'] }}</td>
<td style="border: 1px solid black;">{{ reagent['name'] }}</td> <td style="border: 1px solid black;">{{ reagent['reagent_name'] }}</td>
<td style="border: 1px solid black;">{{ reagent['lot'] }}</td> <td style="border: 1px solid black;">{{ reagent['lot'] }}</td>
<td style="border: 1px solid black;">{{ reagent['expiry'].strftime('%Y-%m-%d') }}</td> <td style="border: 1px solid black;">{{ reagent['expiry'].strftime('%Y-%m-%d') }}</td>
</tr> </tr>