Pre- pydsubmission toForm method.
This commit is contained in:
@@ -138,7 +138,7 @@ def lookup_reagent_types(ctx:Settings,
|
||||
assert reagent.type != []
|
||||
logger.debug(f"Looking up reagent type for {type(kit_type)} {kit_type} and {type(reagent)} {reagent}")
|
||||
logger.debug(f"Kit reagent types: {kit_type.reagent_types}")
|
||||
logger.debug(f"Reagent reagent types: {reagent._sa_instance_state}")
|
||||
# logger.debug(f"Reagent reagent types: {reagent._sa_instance_state}")
|
||||
result = list(set(kit_type.reagent_types).intersection(reagent.type))
|
||||
logger.debug(f"Result: {result}")
|
||||
return result[0]
|
||||
|
||||
@@ -7,6 +7,7 @@ from sqlalchemy.orm import relationship, validates
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from datetime import date
|
||||
import logging
|
||||
from tools import Settings, check_authorization
|
||||
|
||||
logger = logging.getLogger(f'submissions.{__name__}')
|
||||
|
||||
@@ -100,6 +101,11 @@ class KitType(Base):
|
||||
map['info'] = {}
|
||||
return map
|
||||
|
||||
@check_authorization
|
||||
def save(self, ctx:Settings):
|
||||
ctx.database_session.add(self)
|
||||
ctx.database_session.commit()
|
||||
|
||||
class ReagentType(Base):
|
||||
"""
|
||||
Base of reagent type abstract
|
||||
@@ -265,12 +271,21 @@ class Reagent(Base):
|
||||
rtype = reagent_role.name
|
||||
except AttributeError:
|
||||
rtype = "Unknown"
|
||||
try:
|
||||
expiry = self.expiry.strftime("%Y-%m-%d")
|
||||
except:
|
||||
expiry = date.today()
|
||||
return {
|
||||
"name":self.name,
|
||||
"type": rtype,
|
||||
"lot": self.lot,
|
||||
"expiry": self.expiry.strftime("%Y-%m-%d")
|
||||
}
|
||||
|
||||
def save(self, ctx:Settings):
|
||||
ctx.database_session.add(self)
|
||||
ctx.database_session.commit()
|
||||
|
||||
|
||||
class Discount(Base):
|
||||
"""
|
||||
|
||||
@@ -853,7 +853,6 @@ class WastewaterSample(BasicSample):
|
||||
output_dict["submitter_id"] = output_dict['ww_full_sample_id']
|
||||
return output_dict
|
||||
|
||||
|
||||
class BacterialCultureSample(BasicSample):
|
||||
"""
|
||||
base of bacterial culture sample
|
||||
|
||||
@@ -112,7 +112,8 @@ class SheetParser(object):
|
||||
kit = lookup_kit_types(ctx=self.ctx, name=self.sub['extraction_kit']['value'])
|
||||
allowed_reagents = [item.name for item in kit.get_reagents()]
|
||||
logger.debug(f"List of reagents for comparison with allowed_reagents: {pprint.pformat(self.sub['reagents'])}")
|
||||
self.sub['reagents'] = [reagent for reagent in self.sub['reagents'] if reagent['value'].type in allowed_reagents]
|
||||
# self.sub['reagents'] = [reagent for reagent in self.sub['reagents'] if reagent['value'].type in allowed_reagents]
|
||||
self.sub['reagents'] = [reagent for reagent in self.sub['reagents'] if reagent.type in allowed_reagents]
|
||||
|
||||
def to_pydantic(self) -> PydSubmission:
|
||||
"""
|
||||
@@ -231,8 +232,9 @@ class ReagentParser(object):
|
||||
lot = df.iat[relevant[item]['lot']['row']-1, relevant[item]['lot']['column']-1]
|
||||
expiry = df.iat[relevant[item]['expiry']['row']-1, relevant[item]['expiry']['column']-1]
|
||||
except (KeyError, IndexError):
|
||||
listo.append(dict(value=PydReagent(ctx=self.ctx, type=item.strip(), lot=None, exp=None, name=None), parsed=False))
|
||||
listo.append(PydReagent(ctx=self.ctx, type=item.strip(), lot=None, exp=None, name=None, parsed=False))
|
||||
continue
|
||||
# If the cell is blank tell the PydReagent
|
||||
if check_not_nan(lot):
|
||||
parsed = True
|
||||
else:
|
||||
@@ -240,7 +242,7 @@ class ReagentParser(object):
|
||||
# logger.debug(f"Got lot for {item}-{name}: {lot} as {type(lot)}")
|
||||
lot = str(lot)
|
||||
logger.debug(f"Going into pydantic: name: {name}, lot: {lot}, expiry: {expiry}, type: {item.strip()}")
|
||||
listo.append(dict(value=PydReagent(ctx=self.ctx, type=item.strip(), lot=lot, exp=expiry, name=name), parsed=parsed))
|
||||
listo.append(PydReagent(ctx=self.ctx, type=item.strip(), lot=lot, expiry=expiry, name=name, parsed=parsed))
|
||||
logger.debug(f"Returning listo: {listo}")
|
||||
return listo
|
||||
|
||||
@@ -387,7 +389,11 @@ class SampleParser(object):
|
||||
# Set row in lookup table to blank values to prevent multipe lookups.
|
||||
try:
|
||||
self.lookup_table.loc[self.lookup_table['Sample #']==addition['Sample #']] = np.nan
|
||||
except ValueError:
|
||||
except (ValueError, KeyError):
|
||||
pass
|
||||
try:
|
||||
self.lookup_table.loc[self.lookup_table['Well']==addition['Well']] = np.nan
|
||||
except (ValueError, KeyError):
|
||||
pass
|
||||
logger.debug(f"Output sample dict: {sample}")
|
||||
logger.debug(f"Final lookup_table: \n\n {self.lookup_table}")
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
Contains pydantic models and accompanying validators
|
||||
'''
|
||||
import uuid
|
||||
from PyQt6 import QtCore
|
||||
from pydantic import BaseModel, field_validator, Field
|
||||
from datetime import date, datetime, timedelta
|
||||
from dateutil.parser import parse
|
||||
@@ -18,6 +19,7 @@ from backend.db.functions import (lookup_submissions, lookup_reagent_types, look
|
||||
)
|
||||
from backend.db.models import *
|
||||
from sqlalchemy.exc import InvalidRequestError, StatementError
|
||||
from PyQt6.QtWidgets import QComboBox, QWidget, QLabel, QVBoxLayout
|
||||
|
||||
logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
@@ -25,8 +27,9 @@ class PydReagent(BaseModel):
|
||||
ctx: Settings
|
||||
lot: str|None
|
||||
type: str|None
|
||||
exp: date|None
|
||||
expiry: date|None
|
||||
name: str|None
|
||||
parsed: bool = Field(default=False)
|
||||
|
||||
@field_validator("type", mode='before')
|
||||
@classmethod
|
||||
@@ -61,7 +64,7 @@ class PydReagent(BaseModel):
|
||||
return value.upper()
|
||||
return value
|
||||
|
||||
@field_validator("exp", mode="before")
|
||||
@field_validator("expiry", mode="before")
|
||||
@classmethod
|
||||
def enforce_date(cls, value):
|
||||
if value != None:
|
||||
@@ -86,7 +89,7 @@ class PydReagent(BaseModel):
|
||||
else:
|
||||
return values.data['type']
|
||||
|
||||
def toSQL(self):# -> Tuple[Reagent, dict]:
|
||||
def toSQL(self) -> Tuple[Reagent, dict]:
|
||||
result = None
|
||||
logger.debug(f"Reagent SQL constructor is looking up type: {self.type}, lot: {self.lot}")
|
||||
reagent = lookup_reagents(ctx=self.ctx, lot_number=self.lot)
|
||||
@@ -113,6 +116,10 @@ class PydReagent(BaseModel):
|
||||
# NOTE: this will now be done only in the reporting phase to account for potential changes in end-of-life extensions
|
||||
return reagent, result
|
||||
|
||||
def toForm(self, parent:QWidget, extraction_kit:str) -> QComboBox:
|
||||
from frontend.custom_widgets.misc import ReagentFormWidget
|
||||
return ReagentFormWidget(parent=parent, reagent=self, extraction_kit=extraction_kit)
|
||||
|
||||
class PydSample(BaseModel, extra='allow'):
|
||||
|
||||
submitter_id: str
|
||||
@@ -127,13 +134,6 @@ class PydSample(BaseModel, extra='allow'):
|
||||
return [value]
|
||||
return value
|
||||
|
||||
# @field_validator(column)
|
||||
# @classmethod
|
||||
# def column_int_to_list(cls, value):
|
||||
# if isinstance(value, int):
|
||||
# return [value]
|
||||
# return value
|
||||
|
||||
def toSQL(self, ctx:Settings, submission):
|
||||
result = None
|
||||
self.__dict__.update(self.model_extra)
|
||||
@@ -302,6 +302,22 @@ class PydSubmission(BaseModel, extra='allow'):
|
||||
value['value'] = values.data['submission_type']['value']
|
||||
return value
|
||||
|
||||
def handle_duplicate_samples(self):
|
||||
submitter_ids = list(set([sample.submitter_id for sample in self.samples]))
|
||||
output = []
|
||||
for id in submitter_ids:
|
||||
relevants = [item for item in self.samples if item.submitter_id==id]
|
||||
if len(relevants) <= 1:
|
||||
output += relevants
|
||||
else:
|
||||
rows = [item.row[0] for item in relevants]
|
||||
columns = [item.column[0] for item in relevants]
|
||||
dummy = relevants[0]
|
||||
dummy.row = rows
|
||||
dummy.column = columns
|
||||
output.append(dummy)
|
||||
self.samples = output
|
||||
|
||||
def toSQL(self):
|
||||
code = 0
|
||||
msg = None
|
||||
@@ -380,21 +396,7 @@ class PydSubmission(BaseModel, extra='allow'):
|
||||
logger.debug(f"Constructed submissions message: {msg}")
|
||||
return instance, {'code':code, 'message':msg}
|
||||
|
||||
def handle_duplicate_samples(self):
|
||||
submitter_ids = list(set([sample.submitter_id for sample in self.samples]))
|
||||
output = []
|
||||
for id in submitter_ids:
|
||||
relevants = [item for item in self.samples if item.submitter_id==id]
|
||||
if len(relevants) <= 1:
|
||||
output += relevants
|
||||
else:
|
||||
rows = [item.row[0] for item in relevants]
|
||||
columns = [item.column[0] for item in relevants]
|
||||
dummy = relevants[0]
|
||||
dummy.row = rows
|
||||
dummy.column = columns
|
||||
output.append(dummy)
|
||||
self.samples = output
|
||||
def toForm(self):
|
||||
|
||||
class PydContact(BaseModel):
|
||||
|
||||
@@ -447,19 +449,21 @@ class PydReagentType(BaseModel):
|
||||
assoc = None
|
||||
if assoc == None:
|
||||
assoc = KitTypeReagentTypeAssociation(kit_type=kit, reagent_type=instance, uses=self.uses, required=self.required)
|
||||
kit.kit_reagenttype_associations.append(assoc)
|
||||
# kit.kit_reagenttype_associations.append(assoc)
|
||||
return instance
|
||||
|
||||
class PydKit(BaseModel):
|
||||
|
||||
name: str
|
||||
reagent_types: List[PydReagentType]|None
|
||||
reagent_types: List[PydReagentType] = []
|
||||
|
||||
def toSQL(self, ctx):
|
||||
result = dict(message=None, status='Information')
|
||||
instance = lookup_kit_types(ctx=ctx, name=self.name)
|
||||
if instance == None:
|
||||
instance = KitType(name=self.name)
|
||||
instance.reagent_types = [item.toSQL(ctx, instance) for item in self.reagent_types]
|
||||
return instance
|
||||
# instance.reagent_types = [item.toSQL(ctx, instance) for item in self.reagent_types]
|
||||
[item.toSQL(ctx, instance) for item in self.reagent_types]
|
||||
return instance, result
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user