Compare commits
2 Commits
e9ff0a2774
...
dba4ca0130
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dba4ca0130 | ||
|
|
7f40e091fa |
2
TODO.md
2
TODO.md
@@ -1,3 +1,5 @@
|
|||||||
|
- [ ] Do results writing.
|
||||||
|
- [ ] Allow use of multiple tips per process.
|
||||||
- [x] Add in database objects for rsl_run (submission -> run), procedure (run -> procedure), many more things will likely be associated with procedure.
|
- [x] Add in database objects for rsl_run (submission -> run), procedure (run -> procedure), many more things will likely be associated with procedure.
|
||||||
- [x] Add in database object for client submission.
|
- [x] Add in database object for client submission.
|
||||||
- [ ] Add arbitrary pipette addition to equipment UI.
|
- [ ] Add arbitrary pipette addition to equipment UI.
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
All kittype and reagent related models
|
All kittype and reagent related models
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import sys
|
||||||
import zipfile, logging, re, numpy as np
|
import zipfile, logging, re, numpy as np
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -593,7 +595,7 @@ class SubmissionType(BaseClass):
|
|||||||
query: Query = cls.__database_session__.query(cls)
|
query: Query = cls.__database_session__.query(cls)
|
||||||
match name:
|
match name:
|
||||||
case str():
|
case str():
|
||||||
logger.debug(f"querying with {name}")
|
# logger.debug(f"querying with {name}")
|
||||||
query = query.filter(cls.name == name)
|
query = query.filter(cls.name == name)
|
||||||
limit = 1
|
limit = 1
|
||||||
case _:
|
case _:
|
||||||
@@ -927,7 +929,7 @@ class Procedure(BaseClass):
|
|||||||
logger.info(f"Add Results! {resultstype_name}")
|
logger.info(f"Add Results! {resultstype_name}")
|
||||||
from backend.managers import results
|
from backend.managers import results
|
||||||
results_manager = getattr(results, f"{resultstype_name}Manager")
|
results_manager = getattr(results, f"{resultstype_name}Manager")
|
||||||
rs = results_manager(procedure=self, parent=obj, fname=Path("C:\\Users\lwark\Documents\Submission_Forms\QubitData_18-09-2025_13-43-53.csv"))
|
rs = results_manager(procedure=self, parent=obj)#, fname=Path("C:\\Users\lwark\Documents\Submission_Forms\QubitData_18-09-2025_13-43-53.csv"))
|
||||||
procedure = rs.procedure_to_pydantic()
|
procedure = rs.procedure_to_pydantic()
|
||||||
samples = rs.samples_to_pydantic()
|
samples = rs.samples_to_pydantic()
|
||||||
if procedure:
|
if procedure:
|
||||||
@@ -982,7 +984,6 @@ class Procedure(BaseClass):
|
|||||||
output['sample'] = active_samples + inactive_samples
|
output['sample'] = active_samples + inactive_samples
|
||||||
output['reagent'] = [reagent.details_dict() for reagent in output['procedurereagentlotassociation']]
|
output['reagent'] = [reagent.details_dict() for reagent in output['procedurereagentlotassociation']]
|
||||||
output['equipment'] = [equipment.details_dict() for equipment in output['procedureequipmentassociation']]
|
output['equipment'] = [equipment.details_dict() for equipment in output['procedureequipmentassociation']]
|
||||||
# logger.debug(f"equipment: {pformat([item for item in output['equipment']])}")
|
|
||||||
output['repeat'] = self.repeat
|
output['repeat'] = self.repeat
|
||||||
output['run'] = self.run.name
|
output['run'] = self.run.name
|
||||||
output['excluded'] += self.get_default_info("details_ignore")
|
output['excluded'] += self.get_default_info("details_ignore")
|
||||||
@@ -995,7 +996,6 @@ class Procedure(BaseClass):
|
|||||||
def to_pydantic(self, **kwargs):
|
def to_pydantic(self, **kwargs):
|
||||||
from backend.validators.pydant import PydReagent
|
from backend.validators.pydant import PydReagent
|
||||||
output = super().to_pydantic()
|
output = super().to_pydantic()
|
||||||
print(f"Super to_pydantic: {output.equipment}")
|
|
||||||
output.sample = [item.to_pydantic() for item in output.proceduresampleassociation]
|
output.sample = [item.to_pydantic() for item in output.proceduresampleassociation]
|
||||||
reagents = []
|
reagents = []
|
||||||
for reagent in output.reagent:
|
for reagent in output.reagent:
|
||||||
|
|||||||
@@ -646,7 +646,6 @@ class Run(BaseClass, LogMixin):
|
|||||||
'permission', "clientsubmission"]
|
'permission', "clientsubmission"]
|
||||||
output['sample_count'] = self.sample_count
|
output['sample_count'] = self.sample_count
|
||||||
output['clientsubmission'] = 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
|
||||||
@@ -1852,6 +1851,9 @@ class RunSampleAssociation(BaseClass):
|
|||||||
|
|
||||||
|
|
||||||
class ProcedureSampleAssociation(BaseClass):
|
class ProcedureSampleAssociation(BaseClass):
|
||||||
|
|
||||||
|
pyd_model_name = "PydSample"
|
||||||
|
|
||||||
id = Column(INTEGER, unique=True, nullable=False)
|
id = Column(INTEGER, unique=True, nullable=False)
|
||||||
procedure_id = Column(INTEGER, ForeignKey("_procedure.id"), primary_key=True) #: id of associated procedure
|
procedure_id = Column(INTEGER, ForeignKey("_procedure.id"), primary_key=True) #: id of associated procedure
|
||||||
sample_id = Column(INTEGER, ForeignKey("_sample.id"), primary_key=True) #: id of associated equipment
|
sample_id = Column(INTEGER, ForeignKey("_sample.id"), primary_key=True) #: id of associated equipment
|
||||||
@@ -1924,12 +1926,13 @@ class ProcedureSampleAssociation(BaseClass):
|
|||||||
# 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 ['sample']}
|
relevant = {k: v for k, v in output.items() if k not in ['sample']}
|
||||||
output = output['sample'].details_dict()
|
output = output['sample'].details_dict()
|
||||||
|
# logger.debug(output)
|
||||||
misc = output['misc_info']
|
misc = output['misc_info']
|
||||||
output.update(relevant)
|
output.update(relevant)
|
||||||
output['misc_info'] = misc
|
output['misc_info'] = misc
|
||||||
output['row'] = self.row
|
output['row'] = self.row
|
||||||
output['column'] = self.column
|
output['column'] = self.column
|
||||||
output['results'] = [result.details_dict() for result in output['results']]
|
output['results'] = [item.details_dict() for item in self.results]
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def to_pydantic(self, **kwargs):
|
def to_pydantic(self, **kwargs):
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class DefaultParser(object):
|
|||||||
self.sheet = sheet
|
self.sheet = sheet
|
||||||
if not start_row:
|
if not start_row:
|
||||||
start_row = self.__class__.start_row
|
start_row = self.__class__.start_row
|
||||||
if self.filepath.suffix == ".xslx":
|
if self.filepath.suffix == ".xlsx":
|
||||||
self.workbook = load_workbook(self.filepath, data_only=True)
|
self.workbook = load_workbook(self.filepath, data_only=True)
|
||||||
self.worksheet = self.workbook[self.sheet]
|
self.worksheet = self.workbook[self.sheet]
|
||||||
elif self.filepath.suffix == ".csv":
|
elif self.filepath.suffix == ".csv":
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ class DefaultWriter(object):
|
|||||||
case x if issubclass(value.__class__, BaseClass):
|
case x if issubclass(value.__class__, BaseClass):
|
||||||
value = value.name
|
value = value.name
|
||||||
case x if issubclass(value.__class__, PydBaseClass):
|
case x if issubclass(value.__class__, PydBaseClass):
|
||||||
logger.warning(f"PydBaseClass: {value}")
|
|
||||||
value = value.name
|
value = value.name
|
||||||
case bytes() | list():
|
case bytes() | list():
|
||||||
value = None
|
value = None
|
||||||
@@ -241,6 +240,7 @@ class DefaultTABLEWriter(DefaultWriter):
|
|||||||
|
|
||||||
from .procedure_writers import ProcedureInfoWriter, ProcedureSampleWriter, ProcedureReagentWriter, ProcedureEquipmentWriter
|
from .procedure_writers import ProcedureInfoWriter, ProcedureSampleWriter, ProcedureReagentWriter, ProcedureEquipmentWriter
|
||||||
from .results_writers import (
|
from .results_writers import (
|
||||||
PCRInfoWriter, PCRSampleWriter
|
PCRInfoWriter, PCRSampleWriter,
|
||||||
|
QubitInfoWriter, QubitSampleWriter
|
||||||
)
|
)
|
||||||
from .clientsubmission_writer import ClientSubmissionInfoWriter, ClientSubmissionSampleWriter
|
from .clientsubmission_writer import ClientSubmissionInfoWriter, ClientSubmissionSampleWriter
|
||||||
|
|||||||
@@ -1 +1,32 @@
|
|||||||
|
"""
|
||||||
|
|
||||||
|
"""
|
||||||
|
from openpyxl import Workbook
|
||||||
|
|
||||||
|
from backend.excel.writers import DefaultKEYVALUEWriter, DefaultTABLEWriter
|
||||||
|
from backend.db.models import ProcedureType
|
||||||
|
from tools import flatten_list
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultResultsInfoWriter(DefaultKEYVALUEWriter):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
class DefaultResultsSampleWriter(DefaultTABLEWriter):
|
||||||
|
|
||||||
|
def __init__(self, pydant_obj, proceduretype: ProcedureType | None = None, *args, **kwargs):
|
||||||
|
super().__init__(pydant_obj=pydant_obj, proceduretype=proceduretype, *args, **kwargs)
|
||||||
|
self.pydant_obj = flatten_list([sample.results for sample in pydant_obj.sample])
|
||||||
|
|
||||||
|
def write_to_workbook(self, workbook: Workbook, sheet: str | None = None,
|
||||||
|
start_row: int | None = None, *args, **kwargs) -> Workbook:
|
||||||
|
try:
|
||||||
|
self.worksheet = workbook[f"{self.proceduretype.name[:15]} Results"]
|
||||||
|
except KeyError:
|
||||||
|
self.worksheet = workbook.create_sheet(f"{self.proceduretype.name[:15]} Results")
|
||||||
|
# worksheet = workbook[f"{self.proceduretype.name[:15]} Results"]
|
||||||
|
return workbook
|
||||||
|
|
||||||
|
|
||||||
|
from .qubit_results_writer import QubitInfoWriter, QubitSampleWriter
|
||||||
from .pcr_results_writer import PCRInfoWriter, PCRSampleWriter
|
from .pcr_results_writer import PCRInfoWriter, PCRSampleWriter
|
||||||
@@ -7,14 +7,15 @@ from pprint import pformat
|
|||||||
from typing import Generator, TYPE_CHECKING
|
from typing import Generator, TYPE_CHECKING
|
||||||
from openpyxl import Workbook
|
from openpyxl import Workbook
|
||||||
from openpyxl.styles import Alignment
|
from openpyxl.styles import Alignment
|
||||||
from backend.excel.writers import DefaultKEYVALUEWriter, DefaultTABLEWriter
|
# from backend.excel.writers import DefaultKEYVALUEWriter, DefaultTABLEWriter
|
||||||
|
from . import DefaultResultsInfoWriter, DefaultResultsSampleWriter
|
||||||
from tools import flatten_list
|
from tools import flatten_list
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from backend.db.models import ProcedureType
|
from backend.db.models import ProcedureType
|
||||||
|
|
||||||
logger = logging.getLogger(f"submissions.{__name__}")
|
logger = logging.getLogger(f"submissions.{__name__}")
|
||||||
|
|
||||||
class PCRInfoWriter(DefaultKEYVALUEWriter):
|
class PCRInfoWriter(DefaultResultsInfoWriter):
|
||||||
|
|
||||||
start_row = 1
|
start_row = 1
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ class PCRInfoWriter(DefaultKEYVALUEWriter):
|
|||||||
return workbook
|
return workbook
|
||||||
|
|
||||||
|
|
||||||
class PCRSampleWriter(DefaultTABLEWriter):
|
class PCRSampleWriter(DefaultResultsSampleWriter):
|
||||||
|
|
||||||
def write_to_workbook(self, workbook: Workbook) -> Workbook:
|
def write_to_workbook(self, workbook: Workbook) -> Workbook:
|
||||||
worksheet = workbook[f"{self.proceduretype.name} Results"]
|
worksheet = workbook[f"{self.proceduretype.name} Results"]
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
"""
|
||||||
|
Writers for PCR results from Qubit device
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
import logging
|
||||||
|
from pprint import pformat
|
||||||
|
from openpyxl import Workbook
|
||||||
|
from openpyxl.styles import Alignment
|
||||||
|
from . import DefaultResultsInfoWriter, DefaultResultsSampleWriter
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(f"submissions.{__name__}")
|
||||||
|
|
||||||
|
class QubitInfoWriter(DefaultResultsInfoWriter):
|
||||||
|
|
||||||
|
def write_to_workbook(self, workbook: Workbook, sheet: str | None = None,
|
||||||
|
start_row: int = 1, *args, **kwargs) -> Workbook:
|
||||||
|
return workbook
|
||||||
|
|
||||||
|
|
||||||
|
class QubitSampleWriter(DefaultResultsSampleWriter):
|
||||||
|
|
||||||
|
def write_to_workbook(self, workbook: Workbook, *args, **kwargs) -> Workbook:
|
||||||
|
workbook = super().write_to_workbook(workbook=workbook, *args, **kwargs)
|
||||||
|
header_row = self.proceduretype.allowed_result_methods['Qubit']['sample']['start_row']
|
||||||
|
for iii, header in enumerate(self.column_headers, start=1):
|
||||||
|
# logger.debug(f"Row: {header_row}, column: {iii}")
|
||||||
|
self.worksheet.cell(row=header_row, column=iii, value=header.replace("_", " ").title())
|
||||||
|
# logger.debug(f"Column headers: {self.column_headers}")
|
||||||
|
for iii, result in enumerate(self.pydant_obj, start = 1):
|
||||||
|
row = header_row + iii
|
||||||
|
for k, v in result.result.items():
|
||||||
|
try:
|
||||||
|
column = next((col[0].column for col in self.worksheet.iter_cols() if col[0].value == k.replace("_", " ").title()))
|
||||||
|
except StopIteration:
|
||||||
|
print(f"fail for {k.replace('_', ' ').title()}")
|
||||||
|
continue
|
||||||
|
# logger.debug(f"Writing to row: {row}, column {column}")
|
||||||
|
cell = self.worksheet.cell(row=row, column=column)
|
||||||
|
cell.value = v
|
||||||
|
cell.alignment = Alignment(horizontal='left')
|
||||||
|
self.worksheet = self.postwrite(self.worksheet)
|
||||||
|
return workbook
|
||||||
|
|
||||||
|
@property
|
||||||
|
def column_headers(self):
|
||||||
|
output = []
|
||||||
|
for result in self.pydant_obj:
|
||||||
|
for k, value in result.result.items():
|
||||||
|
output.append(k)
|
||||||
|
return sorted(list(set(output)))
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
Module for manager defaults.
|
Module for manager defaults.
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
|
from pprint import pformat
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from frontend.widgets.functions import select_open_file
|
from frontend.widgets.functions import select_open_file
|
||||||
from tools import get_application_from_parent
|
from tools import get_application_from_parent
|
||||||
@@ -14,6 +15,7 @@ class DefaultManager(object):
|
|||||||
|
|
||||||
def __init__(self, parent, input_object: Path | str | None = None):
|
def __init__(self, parent, input_object: Path | str | None = None):
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
|
||||||
match input_object:
|
match input_object:
|
||||||
case str():
|
case str():
|
||||||
self.input_object = Path(input_object)
|
self.input_object = Path(input_object)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class DefaultProcedureManager(DefaultManager):
|
|||||||
if isinstance(proceduretype, str):
|
if isinstance(proceduretype, str):
|
||||||
proceduretype = ProcedureType.query(name=proceduretype)
|
proceduretype = ProcedureType.query(name=proceduretype)
|
||||||
self.proceduretype = proceduretype
|
self.proceduretype = proceduretype
|
||||||
|
self.procedure = input_object
|
||||||
super().__init__(parent=parent, input_object=input_object)
|
super().__init__(parent=parent, input_object=input_object)
|
||||||
|
|
||||||
|
|
||||||
@@ -84,4 +85,8 @@ class DefaultProcedureManager(DefaultManager):
|
|||||||
Writer = getattr(results_writers, f"{result.result_type}InfoWriter")
|
Writer = getattr(results_writers, f"{result.result_type}InfoWriter")
|
||||||
res_info_writer = Writer(pydant_obj=result, proceduretype=self.proceduretype)
|
res_info_writer = Writer(pydant_obj=result, proceduretype=self.proceduretype)
|
||||||
workbook = res_info_writer.write_to_workbook(workbook=workbook)
|
workbook = res_info_writer.write_to_workbook(workbook=workbook)
|
||||||
|
for result in self.pyd.sample_results:
|
||||||
|
Writer = getattr(results_writers, f"{result.result_type}SampleWriter")
|
||||||
|
res_sample_writer = Writer(pydant_obj=self.procedure, proceduretype=self.proceduretype)
|
||||||
|
workbook = res_sample_writer.write_to_workbook(workbook=workbook)
|
||||||
return workbook
|
return workbook
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from typing import TYPE_CHECKING
|
|||||||
from openpyxl.reader.excel import load_workbook
|
from openpyxl.reader.excel import load_workbook
|
||||||
from backend.db.models import Procedure
|
from backend.db.models import Procedure
|
||||||
from backend.excel.parsers.results_parsers.qubit_results_parser import QubitSampleParser, QubitInfoParser
|
from backend.excel.parsers.results_parsers.qubit_results_parser import QubitSampleParser, QubitInfoParser
|
||||||
# from backend.excel.writers.results_writers.pcr_results_writer import QubitInfoWriter, QubitSampleWriter
|
from backend.excel.writers.results_writers.qubit_results_writer import QubitInfoWriter, QubitSampleWriter
|
||||||
from . import DefaultResultsManager
|
from . import DefaultResultsManager
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from backend.validators.pydant import PydResults
|
from backend.validators.pydant import PydResults
|
||||||
@@ -28,6 +28,6 @@ class QubitManager(DefaultResultsManager):
|
|||||||
|
|
||||||
def write(self):
|
def write(self):
|
||||||
workbook = load_workbook(BytesIO(self.procedure.proceduretype.template_file))
|
workbook = load_workbook(BytesIO(self.procedure.proceduretype.template_file))
|
||||||
self.info_writer = PCRInfoWriter(pydant_obj=self.procedure.to_pydantic(), proceduretype=self.procedure.proceduretype)
|
self.sample_writer = QubitSampleWriter(pydant_obj=self.procedure.to_pydantic(), proceduretype=self.procedure.proceduretype)
|
||||||
workbook = self.info_writer.write_to_workbook(workbook)
|
workbook = self.sample_writer.write_to_workbook(workbook)
|
||||||
self.sample_writer = PCRSampleWriter(pydant_obj=self.procedure.to_pydantic(), proceduretype=self.procedure.proceduretype)
|
return workbook
|
||||||
|
|||||||
@@ -254,12 +254,12 @@ class PydReagent(PydBaseClass):
|
|||||||
report = Report()
|
report = Report()
|
||||||
if self.model_extra is not None:
|
if self.model_extra is not None:
|
||||||
self.__dict__.update(self.model_extra)
|
self.__dict__.update(self.model_extra)
|
||||||
reagent, new = ReagentLot.query_or_create(lot=self.lot, name=self.name)
|
reagentlot, new = ReagentLot.query_or_create(lot=self.lot, name=self.name)
|
||||||
if new:
|
if new:
|
||||||
reagentrole = ReagentRole.query(name=self.reagentrole)
|
reagent = Reagent.query(name=self.name)
|
||||||
reagent.reagentrole = reagentrole
|
reagentlot.reagent = reagent
|
||||||
reagent.expiry = self.expiry
|
reagentlot.expiry = self.expiry
|
||||||
return reagent, report
|
return reagentlot, report
|
||||||
|
|
||||||
|
|
||||||
class PydSample(PydBaseClass):
|
class PydSample(PydBaseClass):
|
||||||
@@ -268,6 +268,7 @@ class PydSample(PydBaseClass):
|
|||||||
enabled: bool = Field(default=True)
|
enabled: bool = Field(default=True)
|
||||||
row: int = Field(default=0)
|
row: int = Field(default=0)
|
||||||
column: int = Field(default=0)
|
column: int = Field(default=0)
|
||||||
|
results: List[PydResults] | PydResults = Field(default=[])
|
||||||
|
|
||||||
@field_validator("sample_id", mode="before")
|
@field_validator("sample_id", mode="before")
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -389,7 +390,6 @@ class PydEquipment(PydBaseClass):
|
|||||||
@field_validator('tips', mode='before')
|
@field_validator('tips', mode='before')
|
||||||
@classmethod
|
@classmethod
|
||||||
def tips_to_pydantic(cls, value, values):
|
def tips_to_pydantic(cls, value, values):
|
||||||
print(f"Value coming into tips: {value}")
|
|
||||||
if isinstance(value, GeneratorType):
|
if isinstance(value, GeneratorType):
|
||||||
value = [item for item in value]
|
value = [item for item in value]
|
||||||
value = convert_nans_to_nones(value)
|
value = convert_nans_to_nones(value)
|
||||||
|
|||||||
@@ -56,7 +56,15 @@ class ProcedureCreation(QDialog):
|
|||||||
proceduretype_dict = self.proceduretype.details_dict()
|
proceduretype_dict = self.proceduretype.details_dict()
|
||||||
# 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--"))
|
try:
|
||||||
|
check = "--New--" in [v['name'] for v in value]
|
||||||
|
except TypeError:
|
||||||
|
try:
|
||||||
|
check = "--New--" in [v.name for v in value]
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
check = True
|
||||||
|
if not check:
|
||||||
|
value.append(dict(name="--New--"))
|
||||||
if self.procedure.equipment:
|
if self.procedure.equipment:
|
||||||
for equipmentrole in proceduretype_dict['equipment']:
|
for equipmentrole in proceduretype_dict['equipment']:
|
||||||
# NOTE: Check if procedure equipment is present and move to head of the list if so.
|
# NOTE: Check if procedure equipment is present and move to head of the list if so.
|
||||||
@@ -150,6 +158,7 @@ class ProcedureCreation(QDialog):
|
|||||||
def add_new_reagent(self, reagentrole: str, name: str, lot: str, expiry: str):
|
def add_new_reagent(self, reagentrole: str, name: str, lot: str, expiry: str):
|
||||||
from backend.validators.pydant import PydReagent
|
from backend.validators.pydant import PydReagent
|
||||||
expiry = datetime.datetime.strptime(expiry, "%Y-%m-%d")
|
expiry = datetime.datetime.strptime(expiry, "%Y-%m-%d")
|
||||||
|
logger.debug(f"{reagentrole}, {name}, {lot}, {expiry}")
|
||||||
pyd = PydReagent(reagentrole=reagentrole, name=name, lot=lot, expiry=expiry)
|
pyd = PydReagent(reagentrole=reagentrole, name=name, lot=lot, expiry=expiry)
|
||||||
self.procedure.reagentrole[reagentrole].insert(0, pyd)
|
self.procedure.reagentrole[reagentrole].insert(0, pyd)
|
||||||
self.set_html()
|
self.set_html()
|
||||||
|
|||||||
Reference in New Issue
Block a user