Allow for grabbing of single kit if only one exists for submission type.

This commit is contained in:
lwark
2024-11-13 13:36:03 -06:00
parent 816a0a45f8
commit 514781fd29
9 changed files with 59 additions and 28 deletions

View File

@@ -683,6 +683,11 @@ class SubmissionType(BaseClass):
"""
return f"<SubmissionType({self.name})>"
@classmethod
def retrieve_template_file(cls):
submission_type = cls.query(name="Bacterial Culture")
return submission_type.template_file
def get_template_file_sheets(self) -> List[str]:
logger.debug(f"Submission type to get sheets for: {self.name}")
"""
@@ -779,6 +784,12 @@ class SubmissionType(BaseClass):
tmap = {}
yield item.tip_role.name, tmap
def get_default_kit(self) -> KitType | None:
if len(self.kit_types) == 1:
return self.kit_types[0]
else:
return None
def get_equipment(self, extraction_kit: str | KitType | None = None) -> Generator['PydEquipmentRole', None, None]:
"""
Returns PydEquipmentRole of all equipment associated with this SubmissionType

View File

@@ -8,7 +8,7 @@ from pprint import pformat
from sqlalchemy import Column, String, INTEGER, ForeignKey, Table
from sqlalchemy.orm import relationship, Query
from . import Base, BaseClass
from tools import check_authorization, setup_lookup
from tools import check_authorization, setup_lookup, yaml_regex_creator
from typing import List
logger = logging.getLogger(f"submissions.{__name__}")
@@ -88,6 +88,7 @@ class Organization(BaseClass):
Returns:
"""
yaml.add_constructor("!regex", yaml_regex_creator)
if isinstance(filepath, str):
filepath = Path(filepath)
if not filepath.exists():
@@ -97,7 +98,7 @@ class Organization(BaseClass):
if filepath.suffix == ".json":
import_dict = json.load(fp=f)
elif filepath.suffix == ".yml":
import_dict = yaml.safe_load(stream=f)
import_dict = yaml.load(stream=f, Loader=yaml.Loader)
else:
raise Exception(f"Filetype {filepath.suffix} not supported.")
data = import_dict['orgs']

View File

@@ -1038,7 +1038,7 @@ class BasicSubmission(BaseClass):
chronologic: bool = False,
limit: int = 0,
page: int = 1,
page_size: int = 250,
page_size: None | int = 250,
**kwargs
) -> BasicSubmission | List[BasicSubmission]:
"""
@@ -1059,6 +1059,7 @@ class BasicSubmission(BaseClass):
"""
# logger.debug(f"Incoming kwargs: {kwargs}")
# NOTE: if you go back to using 'model' change the appropriate cls to model in the query filters
# logger.debug(f"Page size: {page_size}")
if submission_type is not None:
model = cls.find_polymorphic_subclass(polymorphic_identity=submission_type)
elif len(kwargs) > 0:
@@ -1139,7 +1140,7 @@ class BasicSubmission(BaseClass):
# if chronologic:
# logger.debug("Attempting sort by date descending")
query = query.order_by(cls.submitted_date.desc())
if page_size is not None:
if page_size > 0:
query = query.limit(page_size)
page = page - 1
if page is not None:

View File

@@ -96,7 +96,7 @@ class SheetParser(object):
parser = ReagentParser(xl=self.xl, submission_type=self.submission_type,
extraction_kit=extraction_kit)
self.sub['reagents'] = parser.parse_reagents()
logger.debug(f"Reagents out of parser: {pformat(self.sub['reagents'])}")
# logger.debug(f"Reagents out of parser: {pformat(self.sub['reagents'])}")
def parse_samples(self):
"""
@@ -273,11 +273,11 @@ class ReagentParser(object):
self.kit_object = KitType.query(name=extraction_kit)
logger.debug(f"Got extraction kit object: {self.kit_object}")
self.map = self.fetch_kit_info_map(submission_type=submission_type)
# logger.debug(f"Reagent Parser map: {self.map}")
logger.debug(f"Reagent Parser map: {self.map}")
self.xl = xl
@report_result
def fetch_kit_info_map(self, submission_type: str|SubmissionType) -> Tuple[Report, dict]:
def fetch_kit_info_map(self, submission_type: str | SubmissionType) -> Tuple[Report, dict]:
"""
Gets location of kit reagents from database
@@ -296,15 +296,24 @@ class ReagentParser(object):
except KeyError:
pass
# logger.debug(f"Reagent map: {pformat(reagent_map)}")
# NOTE: If reagent map is empty, maybe the wrong kit was given, check if there's only one kit for that submission type and use it if so.
if not reagent_map.keys():
try:
ext_kit_loc = self.submission_type_obj.info_map['extraction_kit']['read'][0]
location_string = f"Sheet: {ext_kit_loc['sheet']}, Row: {ext_kit_loc['row']}, Column: {ext_kit_loc['column']}?"
except:
location_string = ""
report.add_result(Result(owner=__name__, code=0, msg=f"No kit map found for {self.kit_object.name}.\n\n"
f"Are you sure you put the right kit in:\n\n{location_string}?",
status="Critical"))
temp_kit_object = self.submission_type_obj.get_default_kit()
if temp_kit_object:
self.kit_object = temp_kit_object
reagent_map = {k: v for k, v in self.kit_object.construct_xl_map_for_use(submission_type)}
logger.warning(f"Attempting to salvage {self.kit_object} with default kit map: {reagent_map}")
if not reagent_map.keys():
logger.error(f"Still no reagent map, displaying error.")
try:
ext_kit_loc = self.submission_type_obj.info_map['extraction_kit']['read'][0]
location_string = f"Sheet: {ext_kit_loc['sheet']}, Row: {ext_kit_loc['row']}, Column: {ext_kit_loc['column']}?"
except (IndexError, KeyError):
location_string = ""
report.add_result(Result(owner=__name__, code=0,
msg=f"No kit map found for {self.kit_object.name}.\n\n"
f"Are you sure you put the right kit in:\n\n{location_string}?",
status="Critical"))
return report, reagent_map
def parse_reagents(self) -> Generator[dict, None, None]:
@@ -317,7 +326,7 @@ class ReagentParser(object):
for sheet in self.xl.sheetnames:
ws = self.xl[sheet]
relevant = {k.strip(): v for k, v in self.map.items() if sheet in self.map[k]['sheet']}
# logger.debug(f"relevant map for {sheet}: {pformat(relevant)}")
logger.debug(f"relevant map for {sheet}: {pformat(relevant)}")
if relevant == {}:
continue
for item in relevant:

View File

@@ -18,10 +18,12 @@ env = jinja_template_loading()
class ReportMaker(object):
def __init__(self, start_date: date, end_date: date, organizations:list|None=None):
def __init__(self, start_date: date, end_date: date, organizations: list | None = None):
self.start_date = start_date
self.end_date = end_date
self.subs = BasicSubmission.query(start_date=start_date, end_date=end_date)
# NOTE: Set page size to zero to override limiting query size.
self.subs = BasicSubmission.query(start_date=start_date, end_date=end_date, page_size=0)
# logger.debug(f"Number of subs returned: {len(self.subs)}")
if organizations is not None:
self.subs = [sub for sub in self.subs if sub.submitting_lab.name in organizations]
self.detailed_df, self.summary_df = self.make_report_xlsx()
@@ -46,6 +48,7 @@ class ReportMaker(object):
# logger.debug(f"Output daftaframe for xlsx: {df2.columns}")
df = df.drop('id', axis=1)
df = df.sort_values(['submitting_lab', "submitted_date"])
logger.debug(f"Details dataframe:\n{df2}")
return df, df2
def make_report_html(self, df: DataFrame) -> str:
@@ -97,7 +100,7 @@ class ReportMaker(object):
Args:
filename (Path | str): Basename of output file
obj (QWidget | None, optional): Parent object. Defaults to None.
"""
"""
if isinstance(filename, str):
filename = Path(filename)
filename = filename.absolute()
@@ -111,7 +114,7 @@ class ReportMaker(object):
def fix_up_xl(self):
"""
Handles formatting of xl file, mediocrely.
"""
"""
# logger.debug(f"Updating worksheet")
worksheet: Worksheet = self.writer.sheets['Report']
for idx, col in enumerate(self.summary_df, start=1): # NOTE: loop through all columns
@@ -134,5 +137,3 @@ class ReportMaker(object):
for cell in worksheet['D']:
if cell.row > 1:
cell.style = 'Currency'

View File

@@ -51,6 +51,9 @@ class SheetWriter(object):
# except Exception as e:
# logger.error(f"Couldn't open workbook due to {e}")
template = self.submission_type.template_file
if not template:
logger.error(f"No template file found, falling back to Bacterial Culture")
template = SubmissionType.retrieve_template_file()
workbook = load_workbook(BytesIO(template))
# self.workbook = workbook
self.xl = workbook