Pydantic switchover for omni is largely complete. Will need some debugging.
This commit is contained in:
@@ -333,6 +333,7 @@ class BaseClass(Base):
|
||||
|
||||
def check_all_attributes(self, attributes: dict) -> bool:
|
||||
"""
|
||||
Checks this instance against a dictionary of attributes to determine if they are a match.
|
||||
|
||||
Args:
|
||||
attributes (dict): A dictionary of attributes to be check for equivalence
|
||||
@@ -345,9 +346,16 @@ class BaseClass(Base):
|
||||
# print(getattr(self.__class__, key).property)
|
||||
if value.lower() == "none":
|
||||
value = None
|
||||
logger.debug(f"Attempting to grab attribute: {key}")
|
||||
self_value = getattr(self, key)
|
||||
class_attr = getattr(self.__class__, key)
|
||||
match class_attr.property:
|
||||
logger.debug(f"Self value: {self_value}, class attr: {class_attr} of type: {type(class_attr)}")
|
||||
if isinstance(class_attr, property):
|
||||
filter = "property"
|
||||
else:
|
||||
filter = class_attr.property
|
||||
match filter:
|
||||
# match class_attr:
|
||||
case ColumnProperty():
|
||||
match class_attr.type:
|
||||
case INTEGER():
|
||||
@@ -359,13 +367,25 @@ class BaseClass(Base):
|
||||
value = int(value)
|
||||
case FLOAT():
|
||||
value = float(value)
|
||||
case "property":
|
||||
pass
|
||||
case _RelationshipDeclared():
|
||||
logger.debug(f"Checking {self_value}")
|
||||
try:
|
||||
self_value = self_value.name
|
||||
except AttributeError:
|
||||
pass
|
||||
if class_attr.property.uselist:
|
||||
self_value = self_value.__str__()
|
||||
try:
|
||||
logger.debug(f"Check if {self_value.__class__} is subclass of {self.__class__}")
|
||||
check = issubclass(self_value.__class__, self.__class__)
|
||||
except TypeError as e:
|
||||
logger.error(f"Couldn't check if {self_value.__class__} is subclass of {self.__class__} due to {e}")
|
||||
check = False
|
||||
if check:
|
||||
logger.debug(f"Checking for subclass name.")
|
||||
self_value = self_value.name
|
||||
logger.debug(f"Checking self_value {self_value} of type {type(self_value)} against attribute {value} of type {type(value)}")
|
||||
if self_value != value:
|
||||
output = False
|
||||
@@ -393,13 +413,15 @@ class BaseClass(Base):
|
||||
logger.debug(f"Setting _RelationshipDeclared to {value}")
|
||||
if field_type.property.uselist:
|
||||
logger.debug(f"Setting with uselist")
|
||||
if self.__getattribute__(key) is not None:
|
||||
existing = self.__getattribute__(key)
|
||||
if existing is not None:
|
||||
if isinstance(value, list):
|
||||
value = self.__getattribute__(key) + value
|
||||
value = existing + value
|
||||
else:
|
||||
value = self.__getattribute__(key) + [value]
|
||||
value = existing + [value]
|
||||
else:
|
||||
value = [value]
|
||||
value = list(set(value))
|
||||
return super().__setattr__(key, value)
|
||||
else:
|
||||
if isinstance(value, list):
|
||||
|
||||
@@ -15,6 +15,7 @@ from pandas import ExcelFile
|
||||
from pathlib import Path
|
||||
from . import Base, BaseClass, Organization, LogMixin
|
||||
from io import BytesIO
|
||||
from inspect import getouterframes, currentframe
|
||||
|
||||
logger = logging.getLogger(f'submissions.{__name__}')
|
||||
|
||||
@@ -227,6 +228,20 @@ class KitType(BaseClass):
|
||||
# logger.debug(f"Output: {output}")
|
||||
return output, new_kit
|
||||
|
||||
@classmethod
|
||||
def query_or_create(cls, **kwargs) -> Tuple[KitType, bool]:
|
||||
from backend.validators.pydant import PydKitType
|
||||
new = False
|
||||
disallowed = ['expiry']
|
||||
sanitized_kwargs = {k: v for k, v in kwargs.items() if k not in disallowed}
|
||||
instance = cls.query(**sanitized_kwargs)
|
||||
if not instance or isinstance(instance, list):
|
||||
instance = PydKitType(**kwargs)
|
||||
new = True
|
||||
instance = instance.to_sql()
|
||||
logger.info(f"Instance from query or create: {instance}")
|
||||
return instance, new
|
||||
|
||||
@classmethod
|
||||
@setup_lookup
|
||||
def query(cls,
|
||||
@@ -380,8 +395,27 @@ class KitType(BaseClass):
|
||||
new_process.equipment_roles.append(new_role)
|
||||
return new_kit
|
||||
|
||||
def to_pydantic(self):
|
||||
pass
|
||||
def to_omni(self, expand: bool = False) -> "OmniKitType":
|
||||
from backend.validators.omni_gui_objects import OmniKitType
|
||||
# logger.debug(f"self.name: {self.name}")
|
||||
# level = len(getouterframes(currentframe()))
|
||||
# logger.warning(f"Function level is {level}")
|
||||
if expand:
|
||||
processes = [item.to_omni() for item in self.processes]
|
||||
kit_reagentrole_associations = [item.to_omni() for item in self.kit_reagentrole_associations]
|
||||
kit_submissiontype_associations = [item.to_omni() for item in self.kit_submissiontype_associations]
|
||||
else:
|
||||
processes = [item.name for item in self.processes]
|
||||
kit_reagentrole_associations = [item.name for item in self.kit_reagentrole_associations]
|
||||
kit_submissiontype_associations = [item.name for item in self.kit_submissiontype_associations]
|
||||
data = dict(
|
||||
name=self.name,
|
||||
processes=processes,
|
||||
kit_reagentrole_associations=kit_reagentrole_associations,
|
||||
kit_submissiontype_associations=kit_submissiontype_associations
|
||||
)
|
||||
logger.debug(f"Creating omni for {pformat(data)}")
|
||||
return OmniKitType(instance_object=self, **data)
|
||||
|
||||
|
||||
class ReagentRole(BaseClass):
|
||||
@@ -413,6 +447,20 @@ class ReagentRole(BaseClass):
|
||||
"""
|
||||
return f"<ReagentRole({self.name})>"
|
||||
|
||||
@classmethod
|
||||
def query_or_create(cls, **kwargs) -> Tuple[ReagentRole, bool]:
|
||||
new = False
|
||||
disallowed = ['expiry']
|
||||
sanitized_kwargs = {k: v for k, v in kwargs.items() if k not in disallowed}
|
||||
instance = cls.query(**sanitized_kwargs)
|
||||
if not instance or isinstance(instance, list):
|
||||
instance = cls()
|
||||
new = True
|
||||
for k, v in sanitized_kwargs.items():
|
||||
setattr(instance, k, v)
|
||||
logger.info(f"Instance from query or create: {instance}")
|
||||
return instance, new
|
||||
|
||||
@classmethod
|
||||
@setup_lookup
|
||||
def query(cls,
|
||||
@@ -496,6 +544,11 @@ class ReagentRole(BaseClass):
|
||||
def save(self):
|
||||
super().save()
|
||||
|
||||
def to_omni(self, expand: bool=False):
|
||||
from backend.validators.omni_gui_objects import OmniReagentRole
|
||||
logger.debug(f"Constructing OmniReagentRole with name {self.name}")
|
||||
return OmniReagentRole(instance_object=self, name=self.name, eol_ext=self.eol_ext)
|
||||
|
||||
|
||||
class Reagent(BaseClass, LogMixin):
|
||||
"""
|
||||
@@ -1010,6 +1063,20 @@ class SubmissionType(BaseClass):
|
||||
from .submissions import BasicSubmission
|
||||
return BasicSubmission.find_polymorphic_subclass(polymorphic_identity=self.name)
|
||||
|
||||
@classmethod
|
||||
def query_or_create(cls, **kwargs) -> Tuple[SubmissionType, bool]:
|
||||
new = False
|
||||
disallowed = ['expiry']
|
||||
sanitized_kwargs = {k: v for k, v in kwargs.items() if k not in disallowed}
|
||||
instance = cls.query(**sanitized_kwargs)
|
||||
if not instance or isinstance(instance, list):
|
||||
instance = cls()
|
||||
new = True
|
||||
for k, v in sanitized_kwargs.items():
|
||||
setattr(instance, k, v)
|
||||
logger.info(f"Instance from query or create: {instance}")
|
||||
return instance, new
|
||||
|
||||
@classmethod
|
||||
@setup_lookup
|
||||
def query(cls,
|
||||
@@ -1112,6 +1179,43 @@ class SubmissionType(BaseClass):
|
||||
Organization.import_from_yml(filepath=filepath)
|
||||
return submission_type
|
||||
|
||||
def to_omni(self, expand: bool = False):
|
||||
from backend.validators.omni_gui_objects import OmniSubmissionType
|
||||
# level = len(getouterframes(currentframe()))
|
||||
# logger.warning(f"Function level is {level}")
|
||||
# try:
|
||||
# info_map = self.submission_type.info_map
|
||||
# except AttributeError:
|
||||
# info_map = {}
|
||||
# try:
|
||||
# defaults = self.submission_type.defaults
|
||||
# except AttributeError:
|
||||
# defaults = {}
|
||||
# try:
|
||||
# sample_map = self.submission_type.sample_map
|
||||
# except AttributeError:
|
||||
# sample_map = {}
|
||||
try:
|
||||
template_file = self.template_file
|
||||
except AttributeError:
|
||||
template_file = bytes()
|
||||
if expand:
|
||||
try:
|
||||
processes = [item.to_omni() for item in self.processes]
|
||||
except AttributeError:
|
||||
processes = []
|
||||
else:
|
||||
processes = [item.name for item in self.processes]
|
||||
return OmniSubmissionType(
|
||||
instance_object=self,
|
||||
name=self.name,
|
||||
info_map=self.info_map,
|
||||
defaults=self.defaults,
|
||||
template_file=template_file,
|
||||
processes=processes,
|
||||
sample_map=self.sample_map
|
||||
)
|
||||
|
||||
|
||||
class SubmissionTypeKitTypeAssociation(BaseClass):
|
||||
"""
|
||||
@@ -1164,10 +1268,18 @@ class SubmissionTypeKitTypeAssociation(BaseClass):
|
||||
def kittype(self):
|
||||
return self.kit_type
|
||||
|
||||
@kittype.setter
|
||||
def kittype(self, value):
|
||||
self.kit_type = value
|
||||
|
||||
@hybrid_property
|
||||
def submissiontype(self):
|
||||
return self.submission_type
|
||||
|
||||
@submissiontype.setter
|
||||
def submissiontype(self, value):
|
||||
self.submission_type = value
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
try:
|
||||
@@ -1175,6 +1287,20 @@ class SubmissionTypeKitTypeAssociation(BaseClass):
|
||||
except AttributeError:
|
||||
return "Blank SubmissionTypeKitTypeAssociation"
|
||||
|
||||
@classmethod
|
||||
def query_or_create(cls, **kwargs) -> Tuple[SubmissionTypeKitTypeAssociation, bool]:
|
||||
new = False
|
||||
disallowed = ['expiry']
|
||||
sanitized_kwargs = {k: v for k, v in kwargs.items() if k not in disallowed}
|
||||
instance = cls.query(**sanitized_kwargs)
|
||||
if not instance or isinstance(instance, list):
|
||||
instance = cls()
|
||||
new = True
|
||||
for k, v in sanitized_kwargs.items():
|
||||
setattr(instance, k, v)
|
||||
logger.info(f"Instance from query or create: {instance}")
|
||||
return instance, new
|
||||
|
||||
@classmethod
|
||||
@setup_lookup
|
||||
def query(cls,
|
||||
@@ -1226,6 +1352,36 @@ class SubmissionTypeKitTypeAssociation(BaseClass):
|
||||
base_dict['kit_type'] = self.kit_type.to_export_dict(submission_type=self.submission_type)
|
||||
return base_dict
|
||||
|
||||
def to_omni(self, expand: bool = False):
|
||||
from backend.validators.omni_gui_objects import OmniSubmissionTypeKitTypeAssociation
|
||||
# level = len(getouterframes(currentframe()))
|
||||
# logger.warning(f"Function level is {level}")
|
||||
if expand:
|
||||
try:
|
||||
submissiontype = self.submission_type.to_omni()
|
||||
except AttributeError:
|
||||
submissiontype = ""
|
||||
try:
|
||||
kittype = self.kit_type.to_omni()
|
||||
except AttributeError:
|
||||
kittype = ""
|
||||
else:
|
||||
submissiontype = self.submission_type.name
|
||||
kittype = self.kit_type.name
|
||||
# try:
|
||||
# processes = [item.to_omni() for item in self.submission_type.processes]
|
||||
# except AttributeError:
|
||||
# processes = []
|
||||
return OmniSubmissionTypeKitTypeAssociation(
|
||||
instance_object=self,
|
||||
submissiontype=submissiontype,
|
||||
kittype=kittype,
|
||||
mutable_cost_column=self.mutable_cost_column,
|
||||
mutable_cost_sample=self.mutable_cost_sample,
|
||||
constant_cost=self.constant_cost
|
||||
# processes=processes,
|
||||
)
|
||||
|
||||
|
||||
class KitTypeReagentRoleAssociation(BaseClass):
|
||||
"""
|
||||
@@ -1312,11 +1468,26 @@ class KitTypeReagentRoleAssociation(BaseClass):
|
||||
raise ValueError(f'{value} is not a reagentrole')
|
||||
return value
|
||||
|
||||
@classmethod
|
||||
def query_or_create(cls, **kwargs) -> Tuple[KitTypeReagentRoleAssociation, bool]:
|
||||
new = False
|
||||
disallowed = ['expiry']
|
||||
sanitized_kwargs = {k: v for k, v in kwargs.items() if k not in disallowed}
|
||||
instance = cls.query(**sanitized_kwargs)
|
||||
if not instance or isinstance(instance, list):
|
||||
instance = cls()
|
||||
new = True
|
||||
for k, v in sanitized_kwargs.items():
|
||||
setattr(instance, k, v)
|
||||
logger.info(f"Instance from query or create: {instance}")
|
||||
return instance, new
|
||||
|
||||
@classmethod
|
||||
@setup_lookup
|
||||
def query(cls,
|
||||
kittype: KitType | str | None = None,
|
||||
reagentrole: ReagentRole | str | None = None,
|
||||
submissiontype: SubmissionType | str | None = None,
|
||||
limit: int = 0,
|
||||
**kwargs
|
||||
) -> KitTypeReagentRoleAssociation | List[KitTypeReagentRoleAssociation]:
|
||||
@@ -1346,6 +1517,14 @@ class KitTypeReagentRoleAssociation(BaseClass):
|
||||
query = query.join(ReagentRole).filter(ReagentRole.name == reagentrole)
|
||||
case _:
|
||||
pass
|
||||
match submissiontype:
|
||||
case SubmissionType():
|
||||
query = query.filter(cls.submission_type == submissiontype)
|
||||
case str():
|
||||
query = query.join(SubmissionType).filter(SubmissionType.name == submissiontype)
|
||||
case _:
|
||||
pass
|
||||
pass
|
||||
if kittype is not None and reagentrole is not None:
|
||||
limit = 1
|
||||
return cls.execute_query(query=query, limit=limit)
|
||||
@@ -1388,13 +1567,46 @@ class KitTypeReagentRoleAssociation(BaseClass):
|
||||
@classproperty
|
||||
def json_edit_fields(cls) -> dict:
|
||||
dicto = dict(
|
||||
sheet="str",
|
||||
expiry=dict(column="int", row="int"),
|
||||
lot=dict(column="int", row="int"),
|
||||
name=dict(column="int", row="int")
|
||||
)
|
||||
sheet="str",
|
||||
expiry=dict(column="int", row="int"),
|
||||
lot=dict(column="int", row="int"),
|
||||
name=dict(column="int", row="int")
|
||||
)
|
||||
return dicto
|
||||
|
||||
def to_omni(self, expand: bool = False) -> "OmniReagentRole":
|
||||
from backend.validators.omni_gui_objects import OmniKitTypeReagentRoleAssociation
|
||||
try:
|
||||
eol_ext = self.reagent_role.eol_ext
|
||||
except AttributeError:
|
||||
eol_ext = timedelta(days=0)
|
||||
if expand:
|
||||
try:
|
||||
submission_type = self.submission_type.to_omni()
|
||||
except AttributeError:
|
||||
submission_type = ""
|
||||
try:
|
||||
kit_type = self.kit_type.to_omni()
|
||||
except AttributeError:
|
||||
kit_type = ""
|
||||
try:
|
||||
reagent_role = self.reagent_role.to_omni()
|
||||
except AttributeError:
|
||||
reagent_role = ""
|
||||
else:
|
||||
submission_type = self.submission_type.name
|
||||
kit_type = self.kit_type.name
|
||||
reagent_role = self.reagent_role.name
|
||||
return OmniKitTypeReagentRoleAssociation(
|
||||
instance_object=self,
|
||||
reagent_role=reagent_role,
|
||||
eol_ext=eol_ext,
|
||||
required=self.required,
|
||||
submission_type=submission_type,
|
||||
kit_type=kit_type,
|
||||
uses=self.uses
|
||||
)
|
||||
|
||||
|
||||
class SubmissionReagentAssociation(BaseClass):
|
||||
"""
|
||||
@@ -1716,9 +1928,28 @@ class EquipmentRole(BaseClass):
|
||||
pyd_dict['processes'] = self.get_processes(submission_type=submission_type, extraction_kit=extraction_kit)
|
||||
return PydEquipmentRole(equipment=equipment, **pyd_dict)
|
||||
|
||||
@classmethod
|
||||
def query_or_create(cls, **kwargs) -> Tuple[EquipmentRole, bool]:
|
||||
new = False
|
||||
disallowed = ['expiry']
|
||||
sanitized_kwargs = {k: v for k, v in kwargs.items() if k not in disallowed}
|
||||
instance = cls.query(**sanitized_kwargs)
|
||||
if not instance or isinstance(instance, list):
|
||||
instance = cls()
|
||||
new = True
|
||||
for k, v in sanitized_kwargs.items():
|
||||
setattr(instance, k, v)
|
||||
logger.info(f"Instance from query or create: {instance}")
|
||||
return instance, new
|
||||
|
||||
@classmethod
|
||||
@setup_lookup
|
||||
def query(cls, name: str | None = None, id: int | None = None, limit: int = 0) -> EquipmentRole | List[
|
||||
def query(cls,
|
||||
name: str | None = None,
|
||||
id: int | None = None,
|
||||
limit: int = 0,
|
||||
**kwargs
|
||||
) -> EquipmentRole | List[
|
||||
EquipmentRole]:
|
||||
"""
|
||||
Lookup Equipment roles.
|
||||
@@ -1779,6 +2010,10 @@ class EquipmentRole(BaseClass):
|
||||
processes = self.get_processes(submission_type=submission_type, extraction_kit=kit_type)
|
||||
return dict(role=self.name, processes=[item for item in processes])
|
||||
|
||||
def to_omni(self, expand: bool = False) -> "OmniEquipmentRole":
|
||||
from backend.validators.omni_gui_objects import OmniEquipmentRole
|
||||
return OmniEquipmentRole(instance_object=self, name=self.name)
|
||||
|
||||
|
||||
class SubmissionEquipmentAssociation(BaseClass):
|
||||
"""
|
||||
@@ -1949,6 +2184,20 @@ class Process(BaseClass):
|
||||
if value not in field:
|
||||
field.append(value)
|
||||
|
||||
@classmethod
|
||||
def query_or_create(cls, **kwargs) -> Tuple[Process, bool]:
|
||||
new = False
|
||||
disallowed = ['expiry']
|
||||
sanitized_kwargs = {k: v for k, v in kwargs.items() if k not in disallowed}
|
||||
instance = cls.query(**sanitized_kwargs)
|
||||
if not instance or isinstance(instance, list):
|
||||
instance = cls()
|
||||
new = True
|
||||
for k, v in sanitized_kwargs.items():
|
||||
setattr(instance, k, v)
|
||||
logger.info(f"Instance from query or create: {instance}")
|
||||
return instance, new
|
||||
|
||||
@classmethod
|
||||
@setup_lookup
|
||||
def query(cls,
|
||||
@@ -2013,7 +2262,15 @@ class Process(BaseClass):
|
||||
def save(self):
|
||||
super().save()
|
||||
|
||||
# @classmethod
|
||||
def to_omni(self, expand: bool = False):
|
||||
from backend.validators.omni_gui_objects import OmniProcess
|
||||
return OmniProcess(
|
||||
instance_object=self,
|
||||
name=self.name,
|
||||
submission_types=[item.to_omni() for item in self.submission_types],
|
||||
equipment_roles=[item.to_omni() for item in self.equipment_roles],
|
||||
tip_roles=[item.to_omni() for item in self.tip_roles]
|
||||
)
|
||||
|
||||
|
||||
class TipRole(BaseClass):
|
||||
@@ -2034,13 +2291,51 @@ class TipRole(BaseClass):
|
||||
|
||||
submission_types = association_proxy("tiprole_submissiontype_associations", "submission_type")
|
||||
|
||||
@hybrid_property
|
||||
def tips(self):
|
||||
return self.instances
|
||||
|
||||
def __repr__(self):
|
||||
return f"<TipRole({self.name})>"
|
||||
|
||||
@classmethod
|
||||
def query_or_create(cls, **kwargs) -> Tuple[TipRole, bool]:
|
||||
new = False
|
||||
disallowed = ['expiry']
|
||||
sanitized_kwargs = {k: v for k, v in kwargs.items() if k not in disallowed}
|
||||
instance = cls.query(**sanitized_kwargs)
|
||||
if not instance or isinstance(instance, list):
|
||||
instance = cls()
|
||||
new = True
|
||||
for k, v in sanitized_kwargs.items():
|
||||
setattr(instance, k, v)
|
||||
logger.info(f"Instance from query or create: {instance}")
|
||||
return instance, new
|
||||
|
||||
@classmethod
|
||||
@setup_lookup
|
||||
def query(cls, name: str | None = None, limit: int = 0, **kwargs) -> TipRole | List[TipRole]:
|
||||
query = cls.__database_session__.query(cls)
|
||||
match name:
|
||||
case str():
|
||||
query = query.filter(cls.name == name)
|
||||
limit = 1
|
||||
case _:
|
||||
pass
|
||||
return cls.execute_query(query=query, limit=limit)
|
||||
|
||||
@check_authorization
|
||||
def save(self):
|
||||
super().save()
|
||||
|
||||
def to_omni(self, expand: bool = False):
|
||||
from backend.validators.omni_gui_objects import OmniTipRole
|
||||
return OmniTipRole(
|
||||
instance_object=self,
|
||||
name=self.name,
|
||||
tips=[item.to_omni() for item in self.tips]
|
||||
)
|
||||
|
||||
|
||||
class Tips(BaseClass, LogMixin):
|
||||
"""
|
||||
@@ -2070,6 +2365,20 @@ class Tips(BaseClass, LogMixin):
|
||||
def __repr__(self):
|
||||
return f"<Tips({self.name})>"
|
||||
|
||||
@classmethod
|
||||
def query_or_create(cls, **kwargs) -> Tuple[Tips, bool]:
|
||||
new = False
|
||||
disallowed = ['expiry']
|
||||
sanitized_kwargs = {k: v for k, v in kwargs.items() if k not in disallowed}
|
||||
instance = cls.query(**sanitized_kwargs)
|
||||
if not instance or isinstance(instance, list):
|
||||
instance = cls()
|
||||
new = True
|
||||
for k, v in sanitized_kwargs.items():
|
||||
setattr(instance, k, v)
|
||||
logger.info(f"Instance from query or create: {instance}")
|
||||
return instance, new
|
||||
|
||||
@classmethod
|
||||
def query(cls, name: str | None = None, lot: str | None = None, limit: int = 0, **kwargs) -> Tips | List[Tips]:
|
||||
"""
|
||||
@@ -2101,6 +2410,13 @@ class Tips(BaseClass, LogMixin):
|
||||
def save(self):
|
||||
super().save()
|
||||
|
||||
def to_omni(self, expand: bool = True):
|
||||
from backend.validators.omni_gui_objects import OmniTips
|
||||
return OmniTips(
|
||||
instance_object=self,
|
||||
name=self.name
|
||||
)
|
||||
|
||||
|
||||
class SubmissionTypeTipRoleAssociation(BaseClass):
|
||||
"""
|
||||
@@ -2129,6 +2445,9 @@ class SubmissionTypeTipRoleAssociation(BaseClass):
|
||||
def save(self):
|
||||
super().save()
|
||||
|
||||
def to_omni(self):
|
||||
pass
|
||||
|
||||
|
||||
class SubmissionTipsAssociation(BaseClass):
|
||||
"""
|
||||
|
||||
@@ -10,9 +10,7 @@ from zipfile import ZipFile, BadZipfile
|
||||
from tempfile import TemporaryDirectory, TemporaryFile
|
||||
from operator import itemgetter
|
||||
from pprint import pformat
|
||||
|
||||
from sqlalchemy.ext.hybrid import hybrid_property
|
||||
|
||||
from . import BaseClass, Reagent, SubmissionType, KitType, Organization, Contact, LogMixin, SubmissionReagentAssociation
|
||||
from sqlalchemy import Column, String, TIMESTAMP, INTEGER, ForeignKey, JSON, FLOAT, case, func
|
||||
from sqlalchemy.orm import relationship, validates, Query
|
||||
@@ -24,7 +22,7 @@ from sqlite3 import OperationalError as SQLOperationalError, IntegrityError as S
|
||||
from openpyxl import Workbook
|
||||
from openpyxl.drawing.image import Image as OpenpyxlImage
|
||||
from tools import row_map, setup_lookup, jinja_template_loading, rreplace, row_keys, check_key_or_attr, Result, Report, \
|
||||
report_result, create_holidays_for_year
|
||||
report_result, create_holidays_for_year, check_dictionary_inclusion_equality
|
||||
from datetime import datetime, date, timedelta
|
||||
from typing import List, Any, Tuple, Literal, Generator, Type
|
||||
from dateutil.parser import parse
|
||||
@@ -558,12 +556,14 @@ class BasicSubmission(BaseClass, LogMixin):
|
||||
existing = value
|
||||
case _:
|
||||
existing = self.__getattribute__(key)
|
||||
logger.debug(f"Existing value is {pformat(existing)}")
|
||||
if value in ['', 'null', None]:
|
||||
logger.error(f"No value given, not setting.")
|
||||
return
|
||||
if existing is None:
|
||||
existing = []
|
||||
if value in existing:
|
||||
# if value in existing:
|
||||
if check_dictionary_inclusion_equality(existing, value):
|
||||
logger.warning("Value already exists. Preventing duplicate addition.")
|
||||
return
|
||||
else:
|
||||
@@ -572,6 +572,7 @@ class BasicSubmission(BaseClass, LogMixin):
|
||||
else:
|
||||
if value:
|
||||
existing.append(value)
|
||||
|
||||
self.__setattr__(key, existing)
|
||||
# NOTE: Make sure this gets updated by telling SQLAlchemy it's been modified.
|
||||
flag_modified(self, key)
|
||||
@@ -1223,10 +1224,19 @@ class BasicSubmission(BaseClass, LogMixin):
|
||||
if "submitted_date" not in kwargs.keys():
|
||||
instance.submitted_date = date.today()
|
||||
else:
|
||||
from frontend.widgets.pop_ups import QuestionAsker
|
||||
logger.warning(f"Found existing instance: {instance}, asking to overwrite.")
|
||||
code = 1
|
||||
msg = "This submission already exists.\nWould you like to overwrite?"
|
||||
report.add_result(Result(msg=msg, code=code))
|
||||
# code = 1
|
||||
# msg = "This submission already exists.\nWould you like to overwrite?"
|
||||
# report.add_result(Result(msg=msg, code=code))
|
||||
dlg = QuestionAsker(title="Overwrite?", message="This submission already exists.\nWould you like to overwrite?")
|
||||
if dlg.exec():
|
||||
pass
|
||||
else:
|
||||
code = 1
|
||||
msg = "This submission already exists.\nWould you like to overwrite?"
|
||||
report.add_result(Result(msg=msg, code=code))
|
||||
return None, report
|
||||
return instance, report
|
||||
|
||||
# NOTE: Custom context events for the ui
|
||||
@@ -1528,6 +1538,7 @@ class Wastewater(BasicSubmission):
|
||||
dummy_samples.append(thing)
|
||||
output['origin_plate'] = self.__class__.make_plate_map(sample_list=dummy_samples, plate_rows=4,
|
||||
plate_columns=6)
|
||||
# logger.debug(f"PCR info: {output['pcr_info']}")
|
||||
return output
|
||||
|
||||
@classmethod
|
||||
|
||||
Reference in New Issue
Block a user