From 0dbb4ae77ac0eb8327a0483788ed7667a0ae1a04 Mon Sep 17 00:00:00 2001 From: lwark Date: Mon, 12 May 2025 13:31:26 -0500 Subject: [PATCH] Adding sample associations to basicsubmission --- .../backend/db/models/submissions.py | 42 +++++++++---------- src/submissions/backend/validators/pydant.py | 19 +++++---- .../frontend/widgets/submission_table.py | 13 ++++-- .../frontend/widgets/submission_widget.py | 14 +++++-- 4 files changed, 50 insertions(+), 38 deletions(-) diff --git a/src/submissions/backend/db/models/submissions.py b/src/submissions/backend/db/models/submissions.py index f5542c4..f5ab539 100644 --- a/src/submissions/backend/db/models/submissions.py +++ b/src/submissions/backend/db/models/submissions.py @@ -336,15 +336,15 @@ class BasicSubmission(BaseClass, LogMixin): kittypes = relationship("KitType", back_populates="submissions", secondary=kittypes_submissions) #: submissions this kit was used for - # submission_sample_associations = relationship( - # "SubmissionSampleAssociation", - # back_populates="submission", - # cascade="all, delete-orphan", - # ) #: Relation to SubmissionSampleAssociation - # - # samples = association_proxy("submission_sample_associations", - # "sample", creator=lambda sample: SubmissionSampleAssociation( - # sample=sample)) #: Association proxy to SubmissionSampleAssociation.samples + submission_sample_associations = relationship( + "SubmissionSampleAssociation", + back_populates="submission", + cascade="all, delete-orphan", + ) #: Relation to SubmissionSampleAssociation + + samples = association_proxy("submission_sample_associations", + "sample", creator=lambda sample: SubmissionSampleAssociation( + sample=sample)) #: Association proxy to SubmissionSampleAssociation.samples submission_reagent_associations = relationship( "SubmissionReagentAssociation", @@ -600,20 +600,20 @@ class BasicSubmission(BaseClass, LogMixin): except Exception as e: logger.error(f"We got an error retrieving reagents: {e}") reagents = [] - finally: - dicto, _ = self.extraction_kit.construct_xl_map_for_use(self.submission_type) - for k, v in dicto.items(): - if k == 'info': - continue - if not any([item['role'] == k for item in reagents]): - expiry = "NA" - reagents.append( - dict(role=k, name="Not Applicable", lot="NA", expiry=expiry, - missing=True)) + # finally: + # dicto, _ = self.extraction_kit.construct_xl_map_for_use(self.submission_type) + # for k, v in dicto.items(): + # if k == 'info': + # continue + # if not any([item['role'] == k for item in reagents]): + # expiry = "NA" + # reagents.append( + # dict(role=k, name="Not Applicable", lot="NA", expiry=expiry, + # missing=True)) samples = self.generate_associations(name="submission_sample_associations") equipment = self.generate_associations(name="submission_equipment_associations") tips = self.generate_associations(name="submission_tips_associations") - cost_centre = self.cost_centre + # cost_centre = self.cost_centre custom = self.custom controls = [item.to_sub_dict() for item in self.controls] else: @@ -648,7 +648,7 @@ class BasicSubmission(BaseClass, LogMixin): output["comment"] = comments output["equipment"] = equipment output["tips"] = tips - output["cost_centre"] = cost_centre + # output["cost_centre"] = cost_centre output["signed_by"] = self.signed_by output["contact"] = contact output["contact_phone"] = contact_phone diff --git a/src/submissions/backend/validators/pydant.py b/src/submissions/backend/validators/pydant.py index 0456cc5..7913332 100644 --- a/src/submissions/backend/validators/pydant.py +++ b/src/submissions/backend/validators/pydant.py @@ -1343,7 +1343,7 @@ class PydClientSubmission(BaseModel, extra="allow", validate_assignment=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) 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") @classmethod @@ -1354,7 +1354,7 @@ class PydClientSubmission(BaseModel, extra="allow", validate_assignment=True): raise f"sample count value must be an integer" return value - @field_validator("submitter_plate_num") + @field_validator("submitter_plate_id") @classmethod def create_submitter_plate_num(cls, value, values): if value['value'] in [None, "None"]: @@ -1373,6 +1373,13 @@ class PydClientSubmission(BaseModel, extra="allow", validate_assignment=True): check = True if check: 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 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(): if isinstance(value, dict): value = value['value'] - # if hasattr(sql, key): - # try: sql.set_attribute(key, value) - # except AttributeError: - # continue - # else: - # sql.misc_info[key] = value - print(sql.__dict__) + return sql diff --git a/src/submissions/frontend/widgets/submission_table.py b/src/submissions/frontend/widgets/submission_table.py index 6e1a2f3..f635e20 100644 --- a/src/submissions/frontend/widgets/submission_table.py +++ b/src/submissions/frontend/widgets/submission_table.py @@ -5,7 +5,7 @@ import logging import sys from pprint import pformat 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.QtGui import QAction, QCursor, QStandardItemModel, QStandardItem, QIcon, QColor from backend.db.models import BasicSubmission, ClientSubmission @@ -250,7 +250,7 @@ class SubmissionsTree(QTreeView): """ def __init__(self, model, parent=None): super(SubmissionsTree, self).__init__(parent) - self.total_count = 1 + self.total_count = ClientSubmission.__database_session__.query(ClientSubmission).count() self.setIndentation(0) self.setExpandsOnDoubleClick(False) self.clicked.connect(self.on_clicked) @@ -277,6 +277,7 @@ class SubmissionsTree(QTreeView): """ sets data in model """ + self.clear() # 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)] logger.debug(pformat(self.data)) @@ -287,6 +288,12 @@ class SubmissionsTree(QTreeView): for run in submission['runs']: 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): id = self.selectionModel().currentIndex() # NOTE: Convert to data in id column (i.e. column 0) @@ -356,9 +363,7 @@ class ClientRunModel(QStandardItemModel): continue if not key: continue - logger.debug(f"Looking for {key} in column {i}") value = str(element[key]) - logger.debug(f"Got value: {value}") item = QStandardItem(value) item.setBackground(QColor("#CFE2F3")) item.setEditable(False) diff --git a/src/submissions/frontend/widgets/submission_widget.py b/src/submissions/frontend/widgets/submission_widget.py index fbadd4f..fabb023 100644 --- a/src/submissions/frontend/widgets/submission_widget.py +++ b/src/submissions/frontend/widgets/submission_widget.py @@ -785,12 +785,13 @@ class ClientSubmissionFormWidget(SubmissionFormWidget): def __init__(self, parent: QWidget, submission: PydSubmission, disable: list | None = None) -> None: super().__init__(parent, submission=submission, disable=disable) - save_btn = QPushButton("Save") - start_run_btn = QPushButton("Save && Add Run") - self.layout.addWidget(save_btn) + self.disabler.setHidden(True) + # save_btn = QPushButton("Save") + start_run_btn = QPushButton("Save") + # self.layout.addWidget(save_btn) self.layout.addWidget(start_run_btn) start_run_btn.clicked.connect(self.create_new_submission) - del self.disabler + def parse_form(self) -> Report: """ @@ -834,5 +835,10 @@ class ClientSubmissionFormWidget(SubmissionFormWidget): def create_new_submission(self, *args) -> Report: self.parse_form() sql = self.pyd.to_sql() + logger.debug(sql.__dict__) + sql.save() + self.app.table_widget.sub_wid.set_data() + self.setParent(None) +