Adding sample associations to basicsubmission

This commit is contained in:
lwark
2025-05-12 13:31:26 -05:00
parent 8a16738e93
commit 0dbb4ae77a
4 changed files with 50 additions and 38 deletions

View File

@@ -336,15 +336,15 @@ class BasicSubmission(BaseClass, LogMixin):
kittypes = relationship("KitType", back_populates="submissions", kittypes = relationship("KitType", back_populates="submissions",
secondary=kittypes_submissions) #: submissions this kit was used for secondary=kittypes_submissions) #: submissions this kit was used for
# submission_sample_associations = relationship( submission_sample_associations = relationship(
# "SubmissionSampleAssociation", "SubmissionSampleAssociation",
# back_populates="submission", back_populates="submission",
# cascade="all, delete-orphan", cascade="all, delete-orphan",
# ) #: Relation to SubmissionSampleAssociation ) #: Relation to SubmissionSampleAssociation
#
# samples = association_proxy("submission_sample_associations", samples = association_proxy("submission_sample_associations",
# "sample", creator=lambda sample: SubmissionSampleAssociation( "sample", creator=lambda sample: SubmissionSampleAssociation(
# sample=sample)) #: Association proxy to SubmissionSampleAssociation.samples sample=sample)) #: Association proxy to SubmissionSampleAssociation.samples
submission_reagent_associations = relationship( submission_reagent_associations = relationship(
"SubmissionReagentAssociation", "SubmissionReagentAssociation",
@@ -600,20 +600,20 @@ class BasicSubmission(BaseClass, LogMixin):
except Exception as e: except Exception as e:
logger.error(f"We got an error retrieving reagents: {e}") logger.error(f"We got an error retrieving reagents: {e}")
reagents = [] reagents = []
finally: # finally:
dicto, _ = self.extraction_kit.construct_xl_map_for_use(self.submission_type) # dicto, _ = self.extraction_kit.construct_xl_map_for_use(self.submission_type)
for k, v in dicto.items(): # for k, v in dicto.items():
if k == 'info': # if k == 'info':
continue # continue
if not any([item['role'] == k for item in reagents]): # if not any([item['role'] == k for item in reagents]):
expiry = "NA" # expiry = "NA"
reagents.append( # reagents.append(
dict(role=k, name="Not Applicable", lot="NA", expiry=expiry, # dict(role=k, name="Not Applicable", lot="NA", expiry=expiry,
missing=True)) # missing=True))
samples = self.generate_associations(name="submission_sample_associations") samples = self.generate_associations(name="submission_sample_associations")
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")
cost_centre = self.cost_centre # cost_centre = self.cost_centre
custom = self.custom custom = self.custom
controls = [item.to_sub_dict() for item in self.controls] controls = [item.to_sub_dict() for item in self.controls]
else: else:
@@ -648,7 +648,7 @@ class BasicSubmission(BaseClass, LogMixin):
output["comment"] = comments output["comment"] = comments
output["equipment"] = equipment output["equipment"] = equipment
output["tips"] = tips output["tips"] = tips
output["cost_centre"] = cost_centre # output["cost_centre"] = cost_centre
output["signed_by"] = self.signed_by output["signed_by"] = self.signed_by
output["contact"] = contact output["contact"] = contact
output["contact_phone"] = contact_phone output["contact_phone"] = contact_phone

View File

@@ -1343,7 +1343,7 @@ class PydClientSubmission(BaseModel, extra="allow", validate_assignment=True):
comment: dict | None = Field(default=dict(value="", missing=True), validate_default=True) comment: dict | None = Field(default=dict(value="", missing=True), validate_default=True)
cost_centre: dict | None = Field(default=dict(value=None, missing=True), validate_default=True) cost_centre: dict | None = Field(default=dict(value=None, missing=True), validate_default=True)
contact: dict | None = Field(default=dict(value=None, missing=True), validate_default=True) contact: dict | None = Field(default=dict(value=None, missing=True), validate_default=True)
submitter_plate_num: dict | None = Field(default=dict(value=None, missing=True), validate_default=True) submitter_plate_id: dict | None = Field(default=dict(value=None, missing=True), validate_default=True)
@field_validator("sample_count") @field_validator("sample_count")
@classmethod @classmethod
@@ -1354,7 +1354,7 @@ class PydClientSubmission(BaseModel, extra="allow", validate_assignment=True):
raise f"sample count value must be an integer" raise f"sample count value must be an integer"
return value return value
@field_validator("submitter_plate_num") @field_validator("submitter_plate_id")
@classmethod @classmethod
def create_submitter_plate_num(cls, value, values): def create_submitter_plate_num(cls, value, values):
if value['value'] in [None, "None"]: if value['value'] in [None, "None"]:
@@ -1373,6 +1373,13 @@ class PydClientSubmission(BaseModel, extra="allow", validate_assignment=True):
check = True check = True
if check: if check:
return dict(value=date.today(), missing=True) return dict(value=date.today(), missing=True)
else:
match value['value']:
case str():
value['value'] = datetime.strptime(value['value'], "%Y-%m-%d")
value['value'] = datetime.combine(value['value'], datetime.now().time())
case _:
pass
return value return value
def filter_field(self, key: str) -> Any: def filter_field(self, key: str) -> Any:
@@ -1437,11 +1444,5 @@ class PydClientSubmission(BaseModel, extra="allow", validate_assignment=True):
for key, value in self.improved_dict().items(): for key, value in self.improved_dict().items():
if isinstance(value, dict): if isinstance(value, dict):
value = value['value'] value = value['value']
# if hasattr(sql, key):
# try:
sql.set_attribute(key, value) sql.set_attribute(key, value)
# except AttributeError: return sql
# continue
# else:
# sql.misc_info[key] = value
print(sql.__dict__)

View File

@@ -5,7 +5,7 @@ import logging
import sys import sys
from pprint import pformat from pprint import pformat
from PyQt6.QtWidgets import QTableView, QMenu, QTreeView, QStyledItemDelegate, QStyle, QStyleOptionViewItem, \ from PyQt6.QtWidgets import QTableView, QMenu, QTreeView, QStyledItemDelegate, QStyle, QStyleOptionViewItem, \
QHeaderView, QAbstractItemView, QWidget QHeaderView, QAbstractItemView, QWidget, QTreeWidgetItemIterator
from PyQt6.QtCore import Qt, QAbstractTableModel, QSortFilterProxyModel, pyqtSlot, QModelIndex from PyQt6.QtCore import Qt, QAbstractTableModel, QSortFilterProxyModel, pyqtSlot, QModelIndex
from PyQt6.QtGui import QAction, QCursor, QStandardItemModel, QStandardItem, QIcon, QColor from PyQt6.QtGui import QAction, QCursor, QStandardItemModel, QStandardItem, QIcon, QColor
from backend.db.models import BasicSubmission, ClientSubmission from backend.db.models import BasicSubmission, ClientSubmission
@@ -250,7 +250,7 @@ class SubmissionsTree(QTreeView):
""" """
def __init__(self, model, parent=None): def __init__(self, model, parent=None):
super(SubmissionsTree, self).__init__(parent) super(SubmissionsTree, self).__init__(parent)
self.total_count = 1 self.total_count = ClientSubmission.__database_session__.query(ClientSubmission).count()
self.setIndentation(0) self.setIndentation(0)
self.setExpandsOnDoubleClick(False) self.setExpandsOnDoubleClick(False)
self.clicked.connect(self.on_clicked) self.clicked.connect(self.on_clicked)
@@ -277,6 +277,7 @@ class SubmissionsTree(QTreeView):
""" """
sets data in model sets data in model
""" """
self.clear()
# self.data = ClientSubmission.submissions_to_df(page=page, page_size=page_size) # self.data = ClientSubmission.submissions_to_df(page=page, page_size=page_size)
self.data = [item.to_dict(full_data=True) for item in ClientSubmission.query(chronologic=True, page=page, page_size=page_size)] self.data = [item.to_dict(full_data=True) for item in ClientSubmission.query(chronologic=True, page=page, page_size=page_size)]
logger.debug(pformat(self.data)) logger.debug(pformat(self.data))
@@ -287,6 +288,12 @@ class SubmissionsTree(QTreeView):
for run in submission['runs']: for run in submission['runs']:
self.model.append_element_to_group(group_item=group_item, element=run) self.model.append_element_to_group(group_item=group_item, element=run)
def clear(self):
if self.model != None:
# self.model.clear() # works
self.model.setRowCount(0) # works
def show_details(self, sel: QModelIndex): def show_details(self, sel: QModelIndex):
id = self.selectionModel().currentIndex() id = self.selectionModel().currentIndex()
# NOTE: Convert to data in id column (i.e. column 0) # NOTE: Convert to data in id column (i.e. column 0)
@@ -356,9 +363,7 @@ class ClientRunModel(QStandardItemModel):
continue continue
if not key: if not key:
continue continue
logger.debug(f"Looking for {key} in column {i}")
value = str(element[key]) value = str(element[key])
logger.debug(f"Got value: {value}")
item = QStandardItem(value) item = QStandardItem(value)
item.setBackground(QColor("#CFE2F3")) item.setBackground(QColor("#CFE2F3"))
item.setEditable(False) item.setEditable(False)

View File

@@ -785,12 +785,13 @@ class ClientSubmissionFormWidget(SubmissionFormWidget):
def __init__(self, parent: QWidget, submission: PydSubmission, disable: list | None = None) -> None: def __init__(self, parent: QWidget, submission: PydSubmission, disable: list | None = None) -> None:
super().__init__(parent, submission=submission, disable=disable) super().__init__(parent, submission=submission, disable=disable)
save_btn = QPushButton("Save") self.disabler.setHidden(True)
start_run_btn = QPushButton("Save && Add Run") # save_btn = QPushButton("Save")
self.layout.addWidget(save_btn) start_run_btn = QPushButton("Save")
# self.layout.addWidget(save_btn)
self.layout.addWidget(start_run_btn) self.layout.addWidget(start_run_btn)
start_run_btn.clicked.connect(self.create_new_submission) start_run_btn.clicked.connect(self.create_new_submission)
del self.disabler
def parse_form(self) -> Report: def parse_form(self) -> Report:
""" """
@@ -834,5 +835,10 @@ class ClientSubmissionFormWidget(SubmissionFormWidget):
def create_new_submission(self, *args) -> Report: def create_new_submission(self, *args) -> Report:
self.parse_form() self.parse_form()
sql = self.pyd.to_sql() sql = self.pyd.to_sql()
logger.debug(sql.__dict__)
sql.save()
self.app.table_widget.sub_wid.set_data()
self.setParent(None)