Before merging enforce names.
This commit is contained in:
@@ -1,3 +1,7 @@
|
|||||||
|
## 202403.03
|
||||||
|
|
||||||
|
- Automated version construction.
|
||||||
|
|
||||||
## 202403.02
|
## 202403.02
|
||||||
|
|
||||||
- Moved functions out of submission container to submission form
|
- Moved functions out of submission container to submission form
|
||||||
|
|||||||
1
TODO.md
1
TODO.md
@@ -1,3 +1,4 @@
|
|||||||
|
- [ ] Merge BasicSubmission.find_subclasses and BasicSubmission.find_polymorphic_subclass
|
||||||
- [ ] Fix updating of Extraction Kit in submission form widget.
|
- [ ] Fix updating of Extraction Kit in submission form widget.
|
||||||
- [x] Fix cropping of gel image.
|
- [x] Fix cropping of gel image.
|
||||||
- [ ] Create Tips ... *sigh*.
|
- [ ] Create Tips ... *sigh*.
|
||||||
|
|||||||
@@ -1,12 +1,24 @@
|
|||||||
# __init__.py
|
# __init__.py
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from datetime import date
|
||||||
|
import calendar
|
||||||
|
|
||||||
# Version of the realpython-reader package
|
# Version of the realpython-reader package
|
||||||
|
|
||||||
|
year = date.today().year
|
||||||
|
month = date.today().month
|
||||||
|
day = date.today().day
|
||||||
|
|
||||||
|
def get_week_of_month() -> int:
|
||||||
|
for ii, week in enumerate(calendar.monthcalendar(date.today().year, date.today().month)):
|
||||||
|
if day in week:
|
||||||
|
return ii + 1
|
||||||
|
|
||||||
__project__ = "submissions"
|
__project__ = "submissions"
|
||||||
__version__ = "202403.2b"
|
__version__ = f"{year}{str(month).zfill(2)}.{get_week_of_month()}b"
|
||||||
__author__ = {"name":"Landon Wark", "email":"Landon.Wark@phac-aspc.gc.ca"}
|
__author__ = {"name":"Landon Wark", "email":"Landon.Wark@phac-aspc.gc.ca"}
|
||||||
__copyright__ = "2022-2024, Government of Canada"
|
__copyright__ = f"2022-{date.today().year}, Government of Canada"
|
||||||
|
|
||||||
project_path = Path(__file__).parents[2].absolute()
|
project_path = Path(__file__).parents[2].absolute()
|
||||||
|
|
||||||
|
|||||||
@@ -1252,9 +1252,13 @@ class SubmissionEquipmentAssociation(BaseClass):
|
|||||||
|
|
||||||
equipment = relationship(Equipment, back_populates="equipment_submission_associations") #: associated equipment
|
equipment = relationship(Equipment, back_populates="equipment_submission_associations") #: associated equipment
|
||||||
|
|
||||||
def __init__(self, submission, equipment):
|
def __repr__(self):
|
||||||
|
return f"<SubmissionEquipmentAssociation({self.submission.rsl_plate_num}&{self.equipment.name})>"
|
||||||
|
|
||||||
|
def __init__(self, submission, equipment, role:str="None"):
|
||||||
self.submission = submission
|
self.submission = submission
|
||||||
self.equipment = equipment
|
self.equipment = equipment
|
||||||
|
self.role = role
|
||||||
|
|
||||||
def to_sub_dict(self) -> dict:
|
def to_sub_dict(self) -> dict:
|
||||||
"""
|
"""
|
||||||
@@ -1263,7 +1267,11 @@ class SubmissionEquipmentAssociation(BaseClass):
|
|||||||
Returns:
|
Returns:
|
||||||
dict: This SubmissionEquipmentAssociation as a dictionary
|
dict: This SubmissionEquipmentAssociation as a dictionary
|
||||||
"""
|
"""
|
||||||
output = dict(name=self.equipment.name, asset_number=self.equipment.asset_number, comment=self.comments, processes=[self.process.name], role=self.role, nickname=self.equipment.nickname)
|
try:
|
||||||
|
process = self.process.name
|
||||||
|
except AttributeError:
|
||||||
|
process = "No process found"
|
||||||
|
output = dict(name=self.equipment.name, asset_number=self.equipment.asset_number, comment=self.comments, processes=[process], role=self.role, nickname=self.equipment.nickname)
|
||||||
return output
|
return output
|
||||||
|
|
||||||
class SubmissionTypeEquipmentRoleAssociation(BaseClass):
|
class SubmissionTypeEquipmentRoleAssociation(BaseClass):
|
||||||
@@ -1344,7 +1352,7 @@ class Process(BaseClass):
|
|||||||
Returns:
|
Returns:
|
||||||
str: Representation of this Process
|
str: Representation of this Process
|
||||||
"""
|
"""
|
||||||
return f"<Process({self.name})"
|
return f"<Process({self.name})>"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@setup_lookup
|
@setup_lookup
|
||||||
|
|||||||
@@ -96,9 +96,10 @@ class BasicSubmission(BaseClass):
|
|||||||
Returns:
|
Returns:
|
||||||
str: Representation of this BasicSubmission
|
str: Representation of this BasicSubmission
|
||||||
"""
|
"""
|
||||||
return f"{self.submission_type}Submission({self.rsl_plate_num})"
|
submission_type = self.submission_type or "Basic"
|
||||||
|
return f"{submission_type}Submission({self.rsl_plate_num})"
|
||||||
|
|
||||||
def to_dict(self, full_data:bool=False, backup:bool=False) -> dict:
|
def to_dict(self, full_data:bool=False, backup:bool=False, report:bool=False) -> dict:
|
||||||
"""
|
"""
|
||||||
Constructs dictionary used in submissions summary
|
Constructs dictionary used in submissions summary
|
||||||
|
|
||||||
@@ -126,13 +127,33 @@ class BasicSubmission(BaseClass):
|
|||||||
ext_kit = None
|
ext_kit = None
|
||||||
# load scraped extraction info
|
# load scraped extraction info
|
||||||
try:
|
try:
|
||||||
ext_info = json.loads(self.extraction_info)
|
# ext_info = json.loads(self.extraction_info)
|
||||||
|
ext_info = self.extraction_info
|
||||||
except TypeError:
|
except TypeError:
|
||||||
ext_info = None
|
ext_info = None
|
||||||
except JSONDecodeError as e:
|
# except JSONDecodeError as e:
|
||||||
ext_info = None
|
# ext_info = None
|
||||||
logger.error(f"Json error in {self.rsl_plate_num}: {e}")
|
# logger.error(f"Json error in {self.rsl_plate_num}: {e}")
|
||||||
# Updated 2023-09 to use the extraction kit to pull reagents.
|
output = {
|
||||||
|
"id": self.id,
|
||||||
|
"Plate Number": self.rsl_plate_num,
|
||||||
|
"Submission Type": self.submission_type_name,
|
||||||
|
# "Submission Category": self.submission_category,
|
||||||
|
"Submitter Plate Number": self.submitter_plate_num,
|
||||||
|
"Submitted Date": self.submitted_date.strftime("%Y-%m-%d"),
|
||||||
|
"Submitting Lab": sub_lab,
|
||||||
|
"Sample Count": self.sample_count,
|
||||||
|
"Extraction Kit": ext_kit,
|
||||||
|
# "Technician": self.technician,
|
||||||
|
"Cost": self.run_cost,
|
||||||
|
# "reagents": reagents,
|
||||||
|
# "samples": samples,
|
||||||
|
# "extraction_info": ext_info,
|
||||||
|
# "comment": comments,
|
||||||
|
# "equipment": equipment
|
||||||
|
}
|
||||||
|
if report:
|
||||||
|
return output
|
||||||
if full_data:
|
if full_data:
|
||||||
logger.debug(f"Attempting reagents.")
|
logger.debug(f"Attempting reagents.")
|
||||||
try:
|
try:
|
||||||
@@ -160,60 +181,27 @@ class BasicSubmission(BaseClass):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error setting comment: {self.comment}")
|
logger.error(f"Error setting comment: {self.comment}")
|
||||||
comments = None
|
comments = None
|
||||||
output = {
|
output["Submission Category"] = self.submission_category
|
||||||
"id": self.id,
|
output["Technician"] = self.technician
|
||||||
"Plate Number": self.rsl_plate_num,
|
output["reagents"] = reagents
|
||||||
"Submission Type": self.submission_type_name,
|
output["samples"] = samples
|
||||||
"Submission Category": self.submission_category,
|
output["extraction_info"] = ext_info
|
||||||
"Submitter Plate Number": self.submitter_plate_num,
|
output["comment"] = comments
|
||||||
"Submitted Date": self.submitted_date.strftime("%Y-%m-%d"),
|
output["equipment"] = equipment
|
||||||
"Submitting Lab": sub_lab,
|
|
||||||
"Sample Count": self.sample_count,
|
|
||||||
"Extraction Kit": ext_kit,
|
|
||||||
"Technician": self.technician,
|
|
||||||
"Cost": self.run_cost,
|
|
||||||
"reagents": reagents,
|
|
||||||
"samples": samples,
|
|
||||||
"extraction_info": ext_info,
|
|
||||||
"comment": comments,
|
|
||||||
"equipment": equipment
|
|
||||||
}
|
|
||||||
return output
|
|
||||||
|
|
||||||
def report_dict(self) -> dict:
|
|
||||||
"""
|
|
||||||
dictionary used in creating reports
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: dictionary used in creating reports
|
|
||||||
"""
|
|
||||||
# get lab name from nested organization object
|
|
||||||
try:
|
|
||||||
sub_lab = self.submitting_lab.name
|
|
||||||
except AttributeError:
|
|
||||||
sub_lab = None
|
|
||||||
try:
|
|
||||||
sub_lab = sub_lab.replace("_", " ").title()
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
# get extraction kit name from nested kittype object
|
|
||||||
try:
|
|
||||||
ext_kit = self.extraction_kit.name
|
|
||||||
except AttributeError:
|
|
||||||
ext_kit = None
|
|
||||||
output = {
|
|
||||||
"id": self.id,
|
|
||||||
"Plate Number": self.rsl_plate_num,
|
|
||||||
"Submission Type": self.submission_type_name.replace("_", " ").title(),
|
|
||||||
"Submitter Plate Number": self.submitter_plate_num,
|
|
||||||
"Submitted Date": self.submitted_date.strftime("%Y-%m-%d"),
|
|
||||||
"Submitting Lab": sub_lab,
|
|
||||||
"Sample Count": self.sample_count,
|
|
||||||
"Extraction Kit": ext_kit,
|
|
||||||
"Cost": self.run_cost
|
|
||||||
}
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
def calculate_column_count(self) -> int:
|
||||||
|
"""
|
||||||
|
Calculate the number of columns in this submission
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: Number of unique columns.
|
||||||
|
"""
|
||||||
|
# logger.debug(f"Here's the samples: {self.samples}")
|
||||||
|
columns = set([assoc.column for assoc in self.submission_sample_associations])
|
||||||
|
# logger.debug(f"Here are the columns for {self.rsl_plate_num}: {columns}")
|
||||||
|
return len(columns)
|
||||||
|
|
||||||
def calculate_base_cost(self):
|
def calculate_base_cost(self):
|
||||||
"""
|
"""
|
||||||
Calculates cost of the plate
|
Calculates cost of the plate
|
||||||
@@ -225,7 +213,7 @@ class BasicSubmission(BaseClass):
|
|||||||
logger.error(f"Column count error: {e}")
|
logger.error(f"Column count error: {e}")
|
||||||
# Get kit associated with this submission
|
# Get kit associated with this submission
|
||||||
assoc = [item for item in self.extraction_kit.kit_submissiontype_associations if item.submission_type == self.submission_type][0]
|
assoc = [item for item in self.extraction_kit.kit_submissiontype_associations if item.submission_type == self.submission_type][0]
|
||||||
# logger.debug(f"Came up with association: {assoc}")
|
logger.debug(f"Came up with association: {assoc}")
|
||||||
# If every individual cost is 0 this is probably an old plate.
|
# If every individual cost is 0 this is probably an old plate.
|
||||||
if all(item == 0.0 for item in [assoc.constant_cost, assoc.mutable_cost_column, assoc.mutable_cost_sample]):
|
if all(item == 0.0 for item in [assoc.constant_cost, assoc.mutable_cost_column, assoc.mutable_cost_sample]):
|
||||||
try:
|
try:
|
||||||
@@ -238,18 +226,6 @@ class BasicSubmission(BaseClass):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Calculation error: {e}")
|
logger.error(f"Calculation error: {e}")
|
||||||
self.run_cost = round(self.run_cost, 2)
|
self.run_cost = round(self.run_cost, 2)
|
||||||
|
|
||||||
def calculate_column_count(self) -> int:
|
|
||||||
"""
|
|
||||||
Calculate the number of columns in this submission
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
int: Number of unique columns.
|
|
||||||
"""
|
|
||||||
# logger.debug(f"Here's the samples: {self.samples}")
|
|
||||||
columns = set([assoc.column for assoc in self.submission_sample_associations])
|
|
||||||
# logger.debug(f"Here are the columns for {self.rsl_plate_num}: {columns}")
|
|
||||||
return len(columns)
|
|
||||||
|
|
||||||
def hitpick_plate(self) -> list:
|
def hitpick_plate(self) -> list:
|
||||||
"""
|
"""
|
||||||
@@ -363,9 +339,9 @@ class BasicSubmission(BaseClass):
|
|||||||
# logger.debug(f"Looking up organization: {value}")
|
# logger.debug(f"Looking up organization: {value}")
|
||||||
field_value = Organization.query(name=value)
|
field_value = Organization.query(name=value)
|
||||||
# logger.debug(f"Got {field_value} for organization {value}")
|
# logger.debug(f"Got {field_value} for organization {value}")
|
||||||
case "submitter_plate_num":
|
# case "submitter_plate_num":
|
||||||
# logger.debug(f"Submitter plate id: {value}")
|
# # logger.debug(f"Submitter plate id: {value}")
|
||||||
field_value = value
|
# field_value = value
|
||||||
case "samples":
|
case "samples":
|
||||||
for sample in value:
|
for sample in value:
|
||||||
# logger.debug(f"Parsing {sample} to sql.")
|
# logger.debug(f"Parsing {sample} to sql.")
|
||||||
@@ -388,7 +364,12 @@ class BasicSubmission(BaseClass):
|
|||||||
if value == "" or value == None or value == 'null':
|
if value == "" or value == None or value == 'null':
|
||||||
field_value = None
|
field_value = None
|
||||||
else:
|
else:
|
||||||
field_value = dict(name="submitter", text=value, time=datetime.now())
|
field_value = dict(name=getuser(), text=value, time=datetime.now())
|
||||||
|
if self.comment is None:
|
||||||
|
self.comment = [field_value]
|
||||||
|
else:
|
||||||
|
self.comment.append(field_value)
|
||||||
|
return
|
||||||
case _:
|
case _:
|
||||||
field_value = value
|
field_value = value
|
||||||
# insert into field
|
# insert into field
|
||||||
@@ -1010,21 +991,23 @@ class BacterialCulture(BasicSubmission):
|
|||||||
polymorphic_load="inline",
|
polymorphic_load="inline",
|
||||||
inherit_condition=(id == BasicSubmission.id))
|
inherit_condition=(id == BasicSubmission.id))
|
||||||
|
|
||||||
def to_dict(self, full_data:bool=False, backup:bool=False) -> dict:
|
def to_dict(self, full_data:bool=False, backup:bool=False, report:bool=False) -> dict:
|
||||||
"""
|
"""
|
||||||
Extends parent class method to add controls to dict
|
Extends parent class method to add controls to dict
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: dictionary used in submissions summary
|
dict: dictionary used in submissions summary
|
||||||
"""
|
"""
|
||||||
output = super().to_dict(full_data=full_data, backup=backup)
|
output = super().to_dict(full_data=full_data, backup=backup, report=report)
|
||||||
|
if report:
|
||||||
|
return output
|
||||||
if full_data:
|
if full_data:
|
||||||
output['controls'] = [item.to_sub_dict() for item in self.controls]
|
output['controls'] = [item.to_sub_dict() for item in self.controls]
|
||||||
return output
|
return output
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_abbreviation(cls) -> str:
|
def get_default_info(cls) -> dict:
|
||||||
return "BC"
|
return dict(abbreviation="BC", submission_type="Bacterial Culture")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def custom_platemap(cls, xl: pd.ExcelFile, plate_map: pd.DataFrame) -> pd.DataFrame:
|
def custom_platemap(cls, xl: pd.ExcelFile, plate_map: pd.DataFrame) -> pd.DataFrame:
|
||||||
@@ -1066,20 +1049,27 @@ class BacterialCulture(BasicSubmission):
|
|||||||
sheet.cell(row=12, column=2, value="=IF(ISBLANK('Sample List'!$B42),\"\",'Sample List'!$B42)")
|
sheet.cell(row=12, column=2, value="=IF(ISBLANK('Sample List'!$B42),\"\",'Sample List'!$B42)")
|
||||||
if sheet.cell(13,2).value == None:
|
if sheet.cell(13,2).value == None:
|
||||||
sheet.cell(row=13, column=2, value="=IF(ISBLANK('Sample List'!$B43),\"\",'Sample List'!$B43)")
|
sheet.cell(row=13, column=2, value="=IF(ISBLANK('Sample List'!$B43),\"\",'Sample List'!$B43)")
|
||||||
input_excel["Sample List"].cell(row=15, column=2, value=getuser()[0:2].upper())
|
input_excel["Sample List"].cell(row=15, column=2, value=getuser())
|
||||||
return input_excel
|
return input_excel
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def enforce_name(cls, instr:str, data:dict|None=None) -> str:
|
def enforce_name(cls, instr:str, data:dict|None={}) -> str:
|
||||||
"""
|
"""
|
||||||
Extends parent
|
Extends parent
|
||||||
"""
|
"""
|
||||||
from backend.validators import RSLNamer
|
from backend.validators import RSLNamer
|
||||||
data['abbreviation'] = cls.get_abbreviation()
|
defaults = cls.get_default_info()
|
||||||
|
data['abbreviation'] = defaults['abbreviation']
|
||||||
|
if 'submission_type' not in data.keys() or data['submission_type'] in [None, ""]:
|
||||||
|
data['submission_type'] = defaults['submission_type']
|
||||||
outstr = super().enforce_name(instr=instr, data=data)
|
outstr = super().enforce_name(instr=instr, data=data)
|
||||||
|
if outstr in [None, ""]:
|
||||||
|
outstr = RSLNamer.construct_new_plate_name(data=data)
|
||||||
|
if re.search(rf"{data['abbreviation']}", outstr, flags=re.IGNORECASE) is None:
|
||||||
|
outstr = re.sub(rf"RSL-?", rf"RSL-{data['abbreviation']}-", outstr, flags=re.IGNORECASE)
|
||||||
try:
|
try:
|
||||||
outstr = re.sub(r"(\d{4})-(\d{2})-(\d{2})", r"\1\2\3", outstr)
|
outstr = re.sub(r"(\d{4})-(\d{2})-(\d{2})", r"\1\2\3", outstr)
|
||||||
outstr = re.sub(r"BC(\d{6})", r"BC-\1", outstr, flags=re.IGNORECASE)
|
outstr = re.sub(rf"{data['abbreviation']}(\d{6})", rf"{data['abbreviation']}-\1", outstr, flags=re.IGNORECASE).upper()
|
||||||
except (AttributeError, TypeError) as e:
|
except (AttributeError, TypeError) as e:
|
||||||
outstr = RSLNamer.construct_new_plate_name(data=data)
|
outstr = RSLNamer.construct_new_plate_name(data=data)
|
||||||
try:
|
try:
|
||||||
@@ -1117,14 +1107,14 @@ class BacterialCulture(BasicSubmission):
|
|||||||
template += "_{{ submitting_lab }}_{{ submitter_plate_num }}"
|
template += "_{{ submitting_lab }}_{{ submitter_plate_num }}"
|
||||||
return template
|
return template
|
||||||
|
|
||||||
@classmethod
|
# @classmethod
|
||||||
def parse_info(cls, input_dict: dict, xl: pd.ExcelFile | None = None) -> dict:
|
# def parse_info(cls, input_dict: dict, xl: pd.ExcelFile | None = None) -> dict:
|
||||||
"""
|
# """
|
||||||
Extends parent
|
# Extends parent
|
||||||
"""
|
# """
|
||||||
input_dict = super().parse_info(input_dict, xl)
|
# input_dict = super().parse_info(input_dict, xl)
|
||||||
input_dict['submitted_date']['missing'] = True
|
# input_dict['submitted_date']['missing'] = True
|
||||||
return input_dict
|
# return input_dict
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def custom_sample_autofill_row(cls, sample, worksheet: Worksheet) -> int:
|
def custom_sample_autofill_row(cls, sample, worksheet: Worksheet) -> int:
|
||||||
@@ -1158,25 +1148,29 @@ class Wastewater(BasicSubmission):
|
|||||||
polymorphic_load="inline",
|
polymorphic_load="inline",
|
||||||
inherit_condition=(id == BasicSubmission.id))
|
inherit_condition=(id == BasicSubmission.id))
|
||||||
|
|
||||||
def to_dict(self, full_data:bool=False, backup:bool=False) -> dict:
|
def to_dict(self, full_data:bool=False, backup:bool=False, report:bool=False) -> dict:
|
||||||
"""
|
"""
|
||||||
Extends parent class method to add controls to dict
|
Extends parent class method to add controls to dict
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: dictionary used in submissions summary
|
dict: dictionary used in submissions summary
|
||||||
"""
|
"""
|
||||||
output = super().to_dict(full_data=full_data)
|
output = super().to_dict(full_data=full_data, backup=backup, report=report)
|
||||||
|
if report:
|
||||||
|
return output
|
||||||
try:
|
try:
|
||||||
output['pcr_info'] = json.loads(self.pcr_info)
|
# output['pcr_info'] = json.loads(self.pcr_info)
|
||||||
|
output['pcr_info'] = self.pcr_info
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
pass
|
pass
|
||||||
output['Technician'] = f"Enr: {self.technician}, Ext: {self.ext_technician}, PCR: {self.pcr_technician}"
|
ext_tech = self.ext_technician or self.technician
|
||||||
|
pcr_tech = self.pcr_technician or self.technician
|
||||||
|
output['Technician'] = f"Enr: {self.technician}, Ext: {ext_tech}, PCR: {pcr_tech}"
|
||||||
return output
|
return output
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_abbreviation(cls) -> str:
|
def get_default_info(cls) -> dict:
|
||||||
return "WW"
|
return dict(abbreviation="WW", submission_type="Wastewater")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def parse_info(cls, input_dict:dict, xl:pd.ExcelFile|None=None) -> dict:
|
def parse_info(cls, input_dict:dict, xl:pd.ExcelFile|None=None) -> dict:
|
||||||
@@ -1212,7 +1206,7 @@ class Wastewater(BasicSubmission):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
logger.error("Well call number doesn't match sample number")
|
logger.error("Well call number doesn't match sample number")
|
||||||
logger.debug(f"Well call df: {well_call_df}")
|
logger.debug(f"Well call df: {well_call_df}")
|
||||||
for ii, row in samples_df.iterrows():
|
for _, row in samples_df.iterrows():
|
||||||
try:
|
try:
|
||||||
sample_obj = [sample for sample in samples if sample['sample'] == row[3]][0]
|
sample_obj = [sample for sample in samples if sample['sample'] == row[3]][0]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
@@ -1238,7 +1232,8 @@ class Wastewater(BasicSubmission):
|
|||||||
Extends parent
|
Extends parent
|
||||||
"""
|
"""
|
||||||
from backend.validators import RSLNamer
|
from backend.validators import RSLNamer
|
||||||
data['abbreviation'] = cls.get_abbreviation()
|
defaults = cls.get_default_info()
|
||||||
|
data['abbreviation'] = defaults['abbreviation']
|
||||||
outstr = super().enforce_name(instr=instr, data=data)
|
outstr = super().enforce_name(instr=instr, data=data)
|
||||||
try:
|
try:
|
||||||
outstr = re.sub(r"PCR(-|_)", "", outstr)
|
outstr = re.sub(r"PCR(-|_)", "", outstr)
|
||||||
@@ -1313,14 +1308,16 @@ class WastewaterArtic(BasicSubmission):
|
|||||||
polymorphic_load="inline",
|
polymorphic_load="inline",
|
||||||
inherit_condition=(id == BasicSubmission.id))
|
inherit_condition=(id == BasicSubmission.id))
|
||||||
|
|
||||||
def to_dict(self, full_data:bool=False, backup:bool=False) -> dict:
|
def to_dict(self, full_data:bool=False, backup:bool=False, report:bool=False) -> dict:
|
||||||
"""
|
"""
|
||||||
Extends parent class method to add controls to dict
|
Extends parent class method to add controls to dict
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: dictionary used in submissions summary
|
dict: dictionary used in submissions summary
|
||||||
"""
|
"""
|
||||||
output = super().to_dict(full_data=full_data)
|
output = super().to_dict(full_data=full_data, backup=backup, report=report)
|
||||||
|
if report:
|
||||||
|
return output
|
||||||
output['gel_info'] = self.gel_info
|
output['gel_info'] = self.gel_info
|
||||||
output['gel_image'] = self.gel_image
|
output['gel_image'] = self.gel_image
|
||||||
output['dna_core_submission_number'] = self.dna_core_submission_number
|
output['dna_core_submission_number'] = self.dna_core_submission_number
|
||||||
@@ -2140,7 +2137,7 @@ class SubmissionSampleAssociation(BaseClass):
|
|||||||
tooltip_text += sample['tooltip']
|
tooltip_text += sample['tooltip']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
sample.update(dict(name=self.sample.submitter_id[:10], tooltip=tooltip_text))
|
sample.update(dict(Name=self.sample.submitter_id[:10], tooltip=tooltip_text))
|
||||||
return sample
|
return sample
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ class App(QMainWindow):
|
|||||||
Show the 'about' message
|
Show the 'about' message
|
||||||
"""
|
"""
|
||||||
output = f"Version: {self.ctx.package.__version__}\n\nAuthor: {self.ctx.package.__author__['name']} - {self.ctx.package.__author__['email']}\n\nCopyright: {self.ctx.package.__copyright__}"
|
output = f"Version: {self.ctx.package.__version__}\n\nAuthor: {self.ctx.package.__author__['name']} - {self.ctx.package.__author__['email']}\n\nCopyright: {self.ctx.package.__copyright__}"
|
||||||
about = AlertPop(message=output, status="information")
|
about = AlertPop(message=output, status="Information")
|
||||||
about.exec()
|
about.exec()
|
||||||
|
|
||||||
def openDocs(self):
|
def openDocs(self):
|
||||||
|
|||||||
@@ -178,12 +178,14 @@ class SubmissionsSheet(QTableView):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
continue
|
continue
|
||||||
if sub.extraction_info != None:
|
if sub.extraction_info != None:
|
||||||
existing = json.loads(sub.extraction_info)
|
# existing = json.loads(sub.extraction_info)
|
||||||
|
existing = sub.extraction_info
|
||||||
else:
|
else:
|
||||||
existing = None
|
existing = None
|
||||||
# Check if the new info already exists in the imported submission
|
# Check if the new info already exists in the imported submission
|
||||||
try:
|
try:
|
||||||
if json.dumps(new_run) in sub.extraction_info:
|
# if json.dumps(new_run) in sub.extraction_info:
|
||||||
|
if new_run in sub.extraction_info:
|
||||||
logger.debug(f"Looks like we already have that info.")
|
logger.debug(f"Looks like we already have that info.")
|
||||||
continue
|
continue
|
||||||
except TypeError:
|
except TypeError:
|
||||||
@@ -194,13 +196,16 @@ class SubmissionsSheet(QTableView):
|
|||||||
logger.debug(f"Updating {type(existing)}: {existing} with {type(new_run)}: {new_run}")
|
logger.debug(f"Updating {type(existing)}: {existing} with {type(new_run)}: {new_run}")
|
||||||
existing.append(new_run)
|
existing.append(new_run)
|
||||||
logger.debug(f"Setting: {existing}")
|
logger.debug(f"Setting: {existing}")
|
||||||
sub.extraction_info = json.dumps(existing)
|
# sub.extraction_info = json.dumps(existing)
|
||||||
|
sub.extraction_info = existing
|
||||||
except TypeError:
|
except TypeError:
|
||||||
logger.error(f"Error updating!")
|
logger.error(f"Error updating!")
|
||||||
sub.extraction_info = json.dumps([new_run])
|
# sub.extraction_info = json.dumps([new_run])
|
||||||
|
sub.extraction_info = [new_run]
|
||||||
logger.debug(f"Final ext info for {sub.rsl_plate_num}: {sub.extraction_info}")
|
logger.debug(f"Final ext info for {sub.rsl_plate_num}: {sub.extraction_info}")
|
||||||
else:
|
else:
|
||||||
sub.extraction_info = json.dumps([new_run])
|
# sub.extraction_info = json.dumps([new_run])
|
||||||
|
sub.extraction_info = [new_run]
|
||||||
sub.save()
|
sub.save()
|
||||||
self.report.add_result(Result(msg=f"We added {count} logs to the database.", status='Information'))
|
self.report.add_result(Result(msg=f"We added {count} logs to the database.", status='Information'))
|
||||||
|
|
||||||
@@ -250,30 +255,35 @@ class SubmissionsSheet(QTableView):
|
|||||||
continue
|
continue
|
||||||
# check if pcr_info already exists
|
# check if pcr_info already exists
|
||||||
if hasattr(sub, 'pcr_info') and sub.pcr_info != None:
|
if hasattr(sub, 'pcr_info') and sub.pcr_info != None:
|
||||||
existing = json.loads(sub.pcr_info)
|
# existing = json.loads(sub.pcr_info)
|
||||||
|
existing = sub.pcr_info
|
||||||
else:
|
else:
|
||||||
existing = None
|
existing = None
|
||||||
# check if this entry already exists in imported submission
|
# check if this entry already exists in imported submission
|
||||||
try:
|
try:
|
||||||
if json.dumps(new_run) in sub.pcr_info:
|
# if json.dumps(new_run) in sub.pcr_info:
|
||||||
|
if new_run in sub.pcr_info:
|
||||||
logger.debug(f"Looks like we already have that info.")
|
logger.debug(f"Looks like we already have that info.")
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
count += 1
|
count += 1
|
||||||
except TypeError:
|
except TypeError:
|
||||||
logger.error(f"No json to dump")
|
logger.error(f"No json to dump")
|
||||||
if existing != None:
|
if existing is not None:
|
||||||
try:
|
try:
|
||||||
logger.debug(f"Updating {type(existing)}: {existing} with {type(new_run)}: {new_run}")
|
logger.debug(f"Updating {type(existing)}: {existing} with {type(new_run)}: {new_run}")
|
||||||
existing.append(new_run)
|
existing.append(new_run)
|
||||||
logger.debug(f"Setting: {existing}")
|
logger.debug(f"Setting: {existing}")
|
||||||
|
# sub.pcr_info = json.dumps(existing)
|
||||||
sub.pcr_info = json.dumps(existing)
|
sub.pcr_info = json.dumps(existing)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
logger.error(f"Error updating!")
|
logger.error(f"Error updating!")
|
||||||
sub.pcr_info = json.dumps([new_run])
|
# sub.pcr_info = json.dumps([new_run])
|
||||||
|
sub.pcr_info = [new_run]
|
||||||
logger.debug(f"Final ext info for {sub.rsl_plate_num}: {sub.pcr_info}")
|
logger.debug(f"Final ext info for {sub.rsl_plate_num}: {sub.pcr_info}")
|
||||||
else:
|
else:
|
||||||
sub.pcr_info = json.dumps([new_run])
|
# sub.pcr_info = json.dumps([new_run])
|
||||||
|
sub.pcr_info = [new_run]
|
||||||
sub.save()
|
sub.save()
|
||||||
self.report.add_result(Result(msg=f"We added {count} logs to the database.", status='Information'))
|
self.report.add_result(Result(msg=f"We added {count} logs to the database.", status='Information'))
|
||||||
|
|
||||||
@@ -305,7 +315,7 @@ class SubmissionsSheet(QTableView):
|
|||||||
# find submissions based on date range
|
# find submissions based on date range
|
||||||
subs = BasicSubmission.query(start_date=info['start_date'], end_date=info['end_date'])
|
subs = BasicSubmission.query(start_date=info['start_date'], end_date=info['end_date'])
|
||||||
# convert each object to dict
|
# convert each object to dict
|
||||||
records = [item.report_dict() for item in subs]
|
records = [item.to_dict(report=True) for item in subs]
|
||||||
logger.debug(f"Records: {pformat(records)}")
|
logger.debug(f"Records: {pformat(records)}")
|
||||||
# make dataframe from record dictionaries
|
# make dataframe from record dictionaries
|
||||||
detailed_df, summary_df = make_report_xlsx(records=records)
|
detailed_df, summary_df = make_report_xlsx(records=records)
|
||||||
|
|||||||
@@ -151,23 +151,28 @@ class SubmissionFormContainer(QWidget):
|
|||||||
return
|
return
|
||||||
# Check if PCR info already exists
|
# Check if PCR info already exists
|
||||||
if hasattr(sub, 'pcr_info') and sub.pcr_info != None:
|
if hasattr(sub, 'pcr_info') and sub.pcr_info != None:
|
||||||
existing = json.loads(sub.pcr_info)
|
# existing = json.loads(sub.pcr_info)
|
||||||
|
existing = sub.pcr_info
|
||||||
else:
|
else:
|
||||||
existing = None
|
existing = None
|
||||||
if existing != None:
|
if existing != None:
|
||||||
# update pcr_info
|
# update pcr_info
|
||||||
try:
|
try:
|
||||||
logger.debug(f"Updating {type(existing)}: {existing} with {type(parser.pcr)}: {parser.pcr}")
|
logger.debug(f"Updating {type(existing)}: {existing} with {type(parser.pcr)}: {parser.pcr}")
|
||||||
if json.dumps(parser.pcr) not in sub.pcr_info:
|
# if json.dumps(parser.pcr) not in sub.pcr_info:
|
||||||
|
if parser.pcr not in sub.pcr_info:
|
||||||
existing.append(parser.pcr)
|
existing.append(parser.pcr)
|
||||||
logger.debug(f"Setting: {existing}")
|
logger.debug(f"Setting: {existing}")
|
||||||
sub.pcr_info = json.dumps(existing)
|
# sub.pcr_info = json.dumps(existing)
|
||||||
|
sub.pcr_info = existing
|
||||||
except TypeError:
|
except TypeError:
|
||||||
logger.error(f"Error updating!")
|
logger.error(f"Error updating!")
|
||||||
sub.pcr_info = json.dumps([parser.pcr])
|
# sub.pcr_info = json.dumps([parser.pcr])
|
||||||
|
sub.pcr_info = [parser.pcr]
|
||||||
logger.debug(f"Final pcr info for {sub.rsl_plate_num}: {sub.pcr_info}")
|
logger.debug(f"Final pcr info for {sub.rsl_plate_num}: {sub.pcr_info}")
|
||||||
else:
|
else:
|
||||||
sub.pcr_info = json.dumps([parser.pcr])
|
# sub.pcr_info = json.dumps([parser.pcr])
|
||||||
|
sub.pcr_info = [parser.pcr]
|
||||||
logger.debug(f"Existing {type(sub.pcr_info)}: {sub.pcr_info}")
|
logger.debug(f"Existing {type(sub.pcr_info)}: {sub.pcr_info}")
|
||||||
logger.debug(f"Inserting {type(json.dumps(parser.pcr))}: {json.dumps(parser.pcr)}")
|
logger.debug(f"Inserting {type(json.dumps(parser.pcr))}: {json.dumps(parser.pcr)}")
|
||||||
sub.save(original=False)
|
sub.save(original=False)
|
||||||
|
|||||||
Reference in New Issue
Block a user