Bug fixes for omni gui objects.
This commit is contained in:
@@ -457,12 +457,12 @@ class BaseClass(Base):
|
|||||||
"""
|
"""
|
||||||
match input_date:
|
match input_date:
|
||||||
case datetime() | date():
|
case datetime() | date():
|
||||||
output_date = input_date#.strftime("%Y-%m-%d %H:%M:%S")
|
output_date = input_date
|
||||||
case int():
|
case int():
|
||||||
output_date = datetime.fromordinal(
|
output_date = datetime.fromordinal(
|
||||||
datetime(1900, 1, 1).toordinal() + input_date - 2)#.date().strftime("%Y-%m-%d %H:%M:%S")
|
datetime(1900, 1, 1).toordinal() + input_date - 2)
|
||||||
case _:
|
case _:
|
||||||
output_date = parse(input_date)#.strftime("%Y-%m-%d %H:%M:%S")
|
output_date = parse(input_date)
|
||||||
if eod:
|
if eod:
|
||||||
addition_time = datetime.max.time()
|
addition_time = datetime.max.time()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -126,7 +126,13 @@ class KitType(BaseClass):
|
|||||||
submission_type=ST)) #: Association proxy to SubmissionTypeKitTypeAssociation
|
submission_type=ST)) #: Association proxy to SubmissionTypeKitTypeAssociation
|
||||||
|
|
||||||
@classproperty
|
@classproperty
|
||||||
def aliases(cls):
|
def aliases(cls) -> List[str]:
|
||||||
|
"""
|
||||||
|
Gets other names the sql object of this class might go by.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[str]: List of names
|
||||||
|
"""
|
||||||
return super().aliases + [cls.query_alias, "kit_types", "kit_type"]
|
return super().aliases + [cls.query_alias, "kit_types", "kit_type"]
|
||||||
|
|
||||||
@hybrid_property
|
@hybrid_property
|
||||||
@@ -1077,7 +1083,13 @@ class SubmissionType(BaseClass):
|
|||||||
return self.processes
|
return self.processes
|
||||||
|
|
||||||
@classproperty
|
@classproperty
|
||||||
def aliases(cls):
|
def aliases(cls) -> List[str]:
|
||||||
|
"""
|
||||||
|
Gets other names the sql object of this class might go by.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[str]: List of names
|
||||||
|
"""
|
||||||
return super().aliases + ["submission_types", "submission_type"]
|
return super().aliases + ["submission_types", "submission_type"]
|
||||||
|
|
||||||
@classproperty
|
@classproperty
|
||||||
|
|||||||
@@ -1540,12 +1540,15 @@ class BacterialCulture(BasicSubmission):
|
|||||||
return report
|
return report
|
||||||
parser = ConcentrationParser(filepath=fname, submission=self)
|
parser = ConcentrationParser(filepath=fname, submission=self)
|
||||||
conc_samples = [sample for sample in parser.samples]
|
conc_samples = [sample for sample in parser.samples]
|
||||||
|
# logger.debug(f"Concentration samples: {pformat(conc_samples)}")
|
||||||
for sample in self.samples:
|
for sample in self.samples:
|
||||||
logger.debug(f"Sample {sample.submitter_id}")
|
# logger.debug(f"Sample {sample.submitter_id}")
|
||||||
|
# logger.debug(f"Match {item['submitter_id']}")
|
||||||
try:
|
try:
|
||||||
# NOTE: Fix for ENs which have no rsl_number...
|
# NOTE: Fix for ENs which have no rsl_number...
|
||||||
sample_dict = next(item for item in conc_samples if item['submitter_id'] == sample.submitter_id)
|
sample_dict = next(item for item in conc_samples if str(item['submitter_id']).upper() == sample.submitter_id)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
|
logger.error(f"Couldn't find sample dict for {sample.submitter_id}")
|
||||||
continue
|
continue
|
||||||
logger.debug(f"Sample {sample.submitter_id} conc. = {sample_dict['concentration']}")
|
logger.debug(f"Sample {sample.submitter_id} conc. = {sample_dict['concentration']}")
|
||||||
if sample_dict['concentration']:
|
if sample_dict['concentration']:
|
||||||
@@ -1734,12 +1737,10 @@ class Wastewater(BasicSubmission):
|
|||||||
sample[f"ct_{sample['target'].lower()}"] = sample['ct'] if isinstance(sample['ct'], float) else 0.0
|
sample[f"ct_{sample['target'].lower()}"] = sample['ct'] if isinstance(sample['ct'], float) else 0.0
|
||||||
# NOTE: Set assessment
|
# NOTE: Set assessment
|
||||||
# logger.debug(f"Sample assessemnt: {sample['assessment']}")
|
# logger.debug(f"Sample assessemnt: {sample['assessment']}")
|
||||||
# sample[f"{sample['target'].lower()}_status"] = sample['assessment']
|
|
||||||
# NOTE: Get sample having other target
|
# NOTE: Get sample having other target
|
||||||
other_targets = [s for s in samples if re.sub('-N\\d*$', '', s['sample']) == sample['sample']]
|
other_targets = [s for s in samples if re.sub('-N\\d*$', '', s['sample']) == sample['sample']]
|
||||||
for s in other_targets:
|
for s in other_targets:
|
||||||
sample[f"ct_{s['target'].lower()}"] = s['ct'] if isinstance(s['ct'], float) else 0.0
|
sample[f"ct_{s['target'].lower()}"] = s['ct'] if isinstance(s['ct'], float) else 0.0
|
||||||
# sample[f"{s['target'].lower()}_status"] = s['assessment']
|
|
||||||
try:
|
try:
|
||||||
del sample['ct']
|
del sample['ct']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@@ -2177,7 +2178,6 @@ class WastewaterArtic(BasicSubmission):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
plate_num = "1"
|
plate_num = "1"
|
||||||
plate_num = plate_num.strip("-")
|
plate_num = plate_num.strip("-")
|
||||||
# repeat_num = re.search(r"R(?P<repeat>\d)?$", "PBS20240426-2R").groups()[0]
|
|
||||||
try:
|
try:
|
||||||
repeat_num = re.search(r"R(?P<repeat>\d)?$", processed).groups()[0]
|
repeat_num = re.search(r"R(?P<repeat>\d)?$", processed).groups()[0]
|
||||||
except:
|
except:
|
||||||
@@ -2663,16 +2663,6 @@ class BasicSample(BaseClass, LogMixin):
|
|||||||
def delete(self):
|
def delete(self):
|
||||||
raise AttributeError(f"Delete not implemented for {self.__class__}")
|
raise AttributeError(f"Delete not implemented for {self.__class__}")
|
||||||
|
|
||||||
# @classmethod
|
|
||||||
# def get_searchables(cls) -> List[dict]:
|
|
||||||
# """
|
|
||||||
# Delivers a list of fields that can be used in fuzzy search.
|
|
||||||
#
|
|
||||||
# Returns:
|
|
||||||
# List[str]: List of fields.
|
|
||||||
# """
|
|
||||||
# return [dict(label="Submitter ID", field="submitter_id")]
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def samples_to_df(cls, sample_list: List[BasicSample], **kwargs) -> pd.DataFrame:
|
def samples_to_df(cls, sample_list: List[BasicSample], **kwargs) -> pd.DataFrame:
|
||||||
"""
|
"""
|
||||||
@@ -2729,8 +2719,6 @@ class WastewaterSample(BasicSample):
|
|||||||
Derivative wastewater sample
|
Derivative wastewater sample
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# searchables = BasicSample.searchables + ['ww_processing_num', 'ww_full_sample_id', 'rsl_number']
|
|
||||||
|
|
||||||
id = Column(INTEGER, ForeignKey('_basicsample.id'), primary_key=True)
|
id = Column(INTEGER, ForeignKey('_basicsample.id'), primary_key=True)
|
||||||
ww_processing_num = Column(String(64)) #: wastewater processing number
|
ww_processing_num = Column(String(64)) #: wastewater processing number
|
||||||
ww_full_sample_id = Column(String(64)) #: full id given by entrics
|
ww_full_sample_id = Column(String(64)) #: full id given by entrics
|
||||||
|
|||||||
@@ -24,10 +24,25 @@ class BaseOmni(BaseModel):
|
|||||||
return f"<{self.__class__.__name__}({self.__repr_name__})>"
|
return f"<{self.__class__.__name__}({self.__repr_name__})>"
|
||||||
|
|
||||||
@classproperty
|
@classproperty
|
||||||
def aliases(cls):
|
def aliases(cls) -> List[str]:
|
||||||
|
"""
|
||||||
|
Gets other names the sql object of this class might go by.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[str]: List of names
|
||||||
|
"""
|
||||||
return cls.class_object.aliases
|
return cls.class_object.aliases
|
||||||
|
|
||||||
def check_all_attributes(self, attributes: dict) -> bool:
|
def check_all_attributes(self, attributes: dict) -> bool:
|
||||||
|
"""
|
||||||
|
Compares this pobject to dictionary of attributes to determine equality.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
attributes (dict):
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: result
|
||||||
|
"""
|
||||||
# logger.debug(f"Incoming attributes: {attributes}")
|
# logger.debug(f"Incoming attributes: {attributes}")
|
||||||
attributes = {k : v for k, v in attributes.items() if k in self.list_searchables.keys()}
|
attributes = {k : v for k, v in attributes.items() if k in self.list_searchables.keys()}
|
||||||
for key, value in attributes.items():
|
for key, value in attributes.items():
|
||||||
@@ -47,7 +62,14 @@ class BaseOmni(BaseModel):
|
|||||||
# logger.debug("Everything checks out, these are the same object.")
|
# logger.debug("Everything checks out, these are the same object.")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def __setattr__(self, key, value):
|
def __setattr__(self, key: str, value: Any):
|
||||||
|
"""
|
||||||
|
Overrides built in dunder method
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key (str):
|
||||||
|
value (Any):
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
class_value = getattr(self.class_object, key)
|
class_value = getattr(self.class_object, key)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
@@ -151,12 +173,22 @@ class OmniSubmissionType(BaseOmni):
|
|||||||
super().__init__(**data)
|
super().__init__(**data)
|
||||||
self.instance_object = instance_object
|
self.instance_object = instance_object
|
||||||
|
|
||||||
def to_dataframe_dict(self):
|
@property
|
||||||
|
def dataframe_dict(self) -> dict:
|
||||||
|
"""
|
||||||
|
Dictionary of gui relevant values.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: result
|
||||||
|
"""
|
||||||
return dict(
|
return dict(
|
||||||
name=self.name
|
name=self.name
|
||||||
)
|
)
|
||||||
|
|
||||||
def to_sql(self):
|
def to_sql(self):
|
||||||
|
"""
|
||||||
|
Convert this object to an instance of its class object.
|
||||||
|
"""
|
||||||
instance, new = self.class_object.query_or_create(name=self.name)
|
instance, new = self.class_object.query_or_create(name=self.name)
|
||||||
instance.info_map = self.info_map
|
instance.info_map = self.info_map
|
||||||
instance.defaults = self.defaults
|
instance.defaults = self.defaults
|
||||||
@@ -191,12 +223,23 @@ class OmniReagentRole(BaseOmni):
|
|||||||
super().__init__(**data)
|
super().__init__(**data)
|
||||||
self.instance_object = instance_object
|
self.instance_object = instance_object
|
||||||
|
|
||||||
def to_dataframe_dict(self):
|
@property
|
||||||
|
def dataframe_dict(self) -> dict:
|
||||||
|
"""
|
||||||
|
Dictionary of gui relevant values.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: result
|
||||||
|
"""
|
||||||
return dict(
|
return dict(
|
||||||
name=self.name
|
name=self.name
|
||||||
)
|
)
|
||||||
|
|
||||||
def to_sql(self):
|
def to_sql(self):
|
||||||
|
"""
|
||||||
|
Convert this object to an instance of its class object.
|
||||||
|
"""
|
||||||
|
|
||||||
instance, new = self.class_object.query_or_create(name=self.name)
|
instance, new = self.class_object.query_or_create(name=self.name)
|
||||||
if new:
|
if new:
|
||||||
instance.eol_ext = self.eol_ext
|
instance.eol_ext = self.eol_ext
|
||||||
@@ -252,7 +295,14 @@ class OmniSubmissionTypeKitTypeAssociation(BaseOmni):
|
|||||||
super().__init__(**data)
|
super().__init__(**data)
|
||||||
self.instance_object = instance_object
|
self.instance_object = instance_object
|
||||||
|
|
||||||
def to_dataframe_dict(self):
|
@property
|
||||||
|
def dataframe_dict(self) -> dict:
|
||||||
|
"""
|
||||||
|
Dictionary of gui relevant values.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: result
|
||||||
|
"""
|
||||||
if isinstance(self.submissiontype, OmniSubmissionType):
|
if isinstance(self.submissiontype, OmniSubmissionType):
|
||||||
submissiontype = self.submissiontype.name
|
submissiontype = self.submissiontype.name
|
||||||
else:
|
else:
|
||||||
@@ -270,6 +320,10 @@ class OmniSubmissionTypeKitTypeAssociation(BaseOmni):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def to_sql(self):
|
def to_sql(self):
|
||||||
|
"""
|
||||||
|
Convert this object to an instance of its class object.
|
||||||
|
"""
|
||||||
|
|
||||||
# logger.debug(f"Self kittype: {self.submissiontype}")
|
# logger.debug(f"Self kittype: {self.submissiontype}")
|
||||||
if issubclass(self.submissiontype.__class__, BaseOmni):
|
if issubclass(self.submissiontype.__class__, BaseOmni):
|
||||||
submissiontype = SubmissionType.query(name=self.submissiontype.name)
|
submissiontype = SubmissionType.query(name=self.submissiontype.name)
|
||||||
@@ -288,7 +342,13 @@ class OmniSubmissionTypeKitTypeAssociation(BaseOmni):
|
|||||||
return instance
|
return instance
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def list_searchables(self):
|
def list_searchables(self) -> dict:
|
||||||
|
"""
|
||||||
|
Provides attributes for checking this object against a dictionary.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: result
|
||||||
|
"""
|
||||||
if isinstance(self.kittype, OmniKitType):
|
if isinstance(self.kittype, OmniKitType):
|
||||||
kit = self.kittype.name
|
kit = self.kittype.name
|
||||||
else:
|
else:
|
||||||
@@ -334,7 +394,14 @@ class OmniKitTypeReagentRoleAssociation(BaseOmni):
|
|||||||
super().__init__(**data)
|
super().__init__(**data)
|
||||||
self.instance_object = instance_object
|
self.instance_object = instance_object
|
||||||
|
|
||||||
def to_dataframe_dict(self):
|
@property
|
||||||
|
def dataframe_dict(self) -> dict:
|
||||||
|
"""
|
||||||
|
Dictionary of gui relevant values.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: result
|
||||||
|
"""
|
||||||
if isinstance(self.submission_type, OmniSubmissionType):
|
if isinstance(self.submission_type, OmniSubmissionType):
|
||||||
submission_type = self.submission_type.name
|
submission_type = self.submission_type.name
|
||||||
else:
|
else:
|
||||||
@@ -349,12 +416,16 @@ class OmniKitTypeReagentRoleAssociation(BaseOmni):
|
|||||||
else:
|
else:
|
||||||
reagent_role = self.reagent_role
|
reagent_role = self.reagent_role
|
||||||
return dict(
|
return dict(
|
||||||
reagent_role=reagent_role,
|
reagentrole=reagent_role,
|
||||||
submission_type=submission_type,
|
submissiontype=submission_type,
|
||||||
kit_type=kit_type
|
kittype=kit_type
|
||||||
)
|
)
|
||||||
|
|
||||||
def to_sql(self):
|
def to_sql(self):
|
||||||
|
"""
|
||||||
|
Convert this object to an instance of its class object.
|
||||||
|
"""
|
||||||
|
|
||||||
if isinstance(self.reagent_role, OmniReagentRole):
|
if isinstance(self.reagent_role, OmniReagentRole):
|
||||||
reagent_role = self.reagent_role.name
|
reagent_role = self.reagent_role.name
|
||||||
else:
|
else:
|
||||||
@@ -387,7 +458,13 @@ class OmniKitTypeReagentRoleAssociation(BaseOmni):
|
|||||||
return instance
|
return instance
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def list_searchables(self):
|
def list_searchables(self) -> dict:
|
||||||
|
"""
|
||||||
|
Provides attributes for checking this object against a dictionary.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: result
|
||||||
|
"""
|
||||||
if isinstance(self.kit_type, OmniKitType):
|
if isinstance(self.kit_type, OmniKitType):
|
||||||
kit = self.kit_type.name
|
kit = self.kit_type.name
|
||||||
else:
|
else:
|
||||||
@@ -420,12 +497,23 @@ class OmniEquipmentRole(BaseOmni):
|
|||||||
super().__init__(**data)
|
super().__init__(**data)
|
||||||
self.instance_object = instance_object
|
self.instance_object = instance_object
|
||||||
|
|
||||||
def to_dataframe_dict(self):
|
@property
|
||||||
|
def dataframe_dict(self) -> dict:
|
||||||
|
"""
|
||||||
|
Dictionary of gui relevant values.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: result
|
||||||
|
"""
|
||||||
return dict(
|
return dict(
|
||||||
name=self.name
|
name=self.name
|
||||||
)
|
)
|
||||||
|
|
||||||
def to_sql(self):
|
def to_sql(self):
|
||||||
|
"""
|
||||||
|
Convert this object to an instance of its class object.
|
||||||
|
"""
|
||||||
|
|
||||||
instance, new = self.class_object.query_or_create(name=self.name)
|
instance, new = self.class_object.query_or_create(name=self.name)
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
@@ -447,12 +535,23 @@ class OmniTips(BaseOmni):
|
|||||||
super().__init__(**data)
|
super().__init__(**data)
|
||||||
self.instance_object = instance_object
|
self.instance_object = instance_object
|
||||||
|
|
||||||
def to_dataframe_dict(self):
|
@property
|
||||||
|
def dataframe_dict(self) -> dict:
|
||||||
|
"""
|
||||||
|
Dictionary of gui relevant values.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: result
|
||||||
|
"""
|
||||||
return dict(
|
return dict(
|
||||||
name=self.name
|
name=self.name
|
||||||
)
|
)
|
||||||
|
|
||||||
def to_sql(self):
|
def to_sql(self):
|
||||||
|
"""
|
||||||
|
Convert this object to an instance of its class object.
|
||||||
|
"""
|
||||||
|
|
||||||
instance, new = self.class_object.query_or_create(name=self.name)
|
instance, new = self.class_object.query_or_create(name=self.name)
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
@@ -475,13 +574,24 @@ class OmniTipRole(BaseOmni):
|
|||||||
super().__init__(**data)
|
super().__init__(**data)
|
||||||
self.instance_object = instance_object
|
self.instance_object = instance_object
|
||||||
|
|
||||||
def to_dataframe_dict(self):
|
@property
|
||||||
|
def dataframe_dict(self) -> dict:
|
||||||
|
"""
|
||||||
|
Dictionary of gui relevant values.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: result
|
||||||
|
"""
|
||||||
return dict(
|
return dict(
|
||||||
name=self.name,
|
name=self.name,
|
||||||
tips=[item.name for item in self.tips]
|
tips=[item.name for item in self.tips]
|
||||||
)
|
)
|
||||||
|
|
||||||
def to_sql(self):
|
def to_sql(self):
|
||||||
|
"""
|
||||||
|
Convert this object to an instance of its class object.
|
||||||
|
"""
|
||||||
|
|
||||||
instance, new = self.class_object.query_or_create(name=self.name)
|
instance, new = self.class_object.query_or_create(name=self.name)
|
||||||
for tips in self.tips:
|
for tips in self.tips:
|
||||||
tips.to_sql()
|
tips.to_sql()
|
||||||
@@ -504,10 +614,17 @@ class OmniProcess(BaseOmni):
|
|||||||
super().__init__(**data)
|
super().__init__(**data)
|
||||||
self.instance_object = instance_object
|
self.instance_object = instance_object
|
||||||
|
|
||||||
def to_dataframe_dict(self):
|
@property
|
||||||
submissiontypes = [item.name for item in self.submission_types]
|
def dataframe_dict(self) -> dict:
|
||||||
|
"""
|
||||||
|
Dictionary of gui relevant values.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: result
|
||||||
|
"""
|
||||||
|
submissiontypes = [item if isinstance(item, str) else item.name for item in self.submission_types]
|
||||||
logger.debug(f"Submission Types: {submissiontypes}")
|
logger.debug(f"Submission Types: {submissiontypes}")
|
||||||
equipmentroles = [item.name for item in self.equipment_roles]
|
equipmentroles = [item if isinstance(item, str) else item.name for item in self.equipment_roles]
|
||||||
logger.debug(f"Equipment Roles: {equipmentroles}")
|
logger.debug(f"Equipment Roles: {equipmentroles}")
|
||||||
return dict(
|
return dict(
|
||||||
name=self.name,
|
name=self.name,
|
||||||
@@ -523,6 +640,10 @@ class OmniProcess(BaseOmni):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
def to_sql(self):
|
def to_sql(self):
|
||||||
|
"""
|
||||||
|
Convert this object to an instance of its class object.
|
||||||
|
"""
|
||||||
|
|
||||||
instance, new = self.class_object.query_or_create(name=self.name)
|
instance, new = self.class_object.query_or_create(name=self.name)
|
||||||
for st in self.submission_types:
|
for st in self.submission_types:
|
||||||
try:
|
try:
|
||||||
@@ -548,7 +669,13 @@ class OmniProcess(BaseOmni):
|
|||||||
return instance
|
return instance
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def list_searchables(self):
|
def list_searchables(self) -> dict:
|
||||||
|
"""
|
||||||
|
Provides attributes for checking this object against a dictionary.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: result
|
||||||
|
"""
|
||||||
return dict(name=self.name)
|
return dict(name=self.name)
|
||||||
|
|
||||||
|
|
||||||
@@ -572,17 +699,24 @@ class OmniKitType(BaseOmni):
|
|||||||
super().__init__(**data)
|
super().__init__(**data)
|
||||||
self.instance_object = instance_object
|
self.instance_object = instance_object
|
||||||
|
|
||||||
def to_dataframe_dict(self):
|
@property
|
||||||
|
def dataframe_dict(self) -> dict:
|
||||||
|
"""
|
||||||
|
Dictionary of gui relevant values.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: result
|
||||||
|
"""
|
||||||
return dict(
|
return dict(
|
||||||
name=self.name
|
name=self.name
|
||||||
)
|
)
|
||||||
|
|
||||||
def to_sql(self) -> KitType:
|
def to_sql(self) -> KitType:
|
||||||
|
"""
|
||||||
|
Convert this object to an instance of its class object.
|
||||||
|
"""
|
||||||
|
|
||||||
kit, is_new = KitType.query_or_create(name=self.name)
|
kit, is_new = KitType.query_or_create(name=self.name)
|
||||||
# if is_new:
|
|
||||||
# logger.debug(f"New kit made: {kit}")
|
|
||||||
# else:
|
|
||||||
# logger.debug(f"Kit retrieved: {kit}")
|
|
||||||
new_rr = []
|
new_rr = []
|
||||||
for rr_assoc in self.kit_reagentrole_associations:
|
for rr_assoc in self.kit_reagentrole_associations:
|
||||||
new_assoc = rr_assoc.to_sql()
|
new_assoc = rr_assoc.to_sql()
|
||||||
@@ -603,9 +737,6 @@ class OmniKitType(BaseOmni):
|
|||||||
if new_process not in new_processes:
|
if new_process not in new_processes:
|
||||||
new_processes.append(new_process)
|
new_processes.append(new_process)
|
||||||
kit.processes = new_processes
|
kit.processes = new_processes
|
||||||
# logger.debug(f"Kit: {pformat(kit.__dict__)}")
|
|
||||||
# for item in kit.kit_reagentrole_associations:
|
|
||||||
# logger.debug(f"KTRRassoc: {item.__dict__}")
|
|
||||||
return kit
|
return kit
|
||||||
|
|
||||||
|
|
||||||
@@ -622,7 +753,14 @@ class OmniOrganization(BaseOmni):
|
|||||||
super().__init__(**data)
|
super().__init__(**data)
|
||||||
self.instance_object = instance_object
|
self.instance_object = instance_object
|
||||||
|
|
||||||
def to_dataframe_dict(self):
|
@property
|
||||||
|
def dataframe_dict(self) -> dict:
|
||||||
|
"""
|
||||||
|
Dictionary of gui relevant values.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: result
|
||||||
|
"""
|
||||||
return dict(
|
return dict(
|
||||||
name=self.name,
|
name=self.name,
|
||||||
cost_centre=self.cost_centre,
|
cost_centre=self.cost_centre,
|
||||||
@@ -639,14 +777,27 @@ class OmniContact(BaseOmni):
|
|||||||
phone: str = Field(default="", description="property")
|
phone: str = Field(default="", description="property")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def list_searchables(self):
|
def list_searchables(self) -> dict:
|
||||||
|
"""
|
||||||
|
Provides attributes for checking this object against a dictionary.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: result
|
||||||
|
"""
|
||||||
return dict(name=self.name, email=self.email)
|
return dict(name=self.name, email=self.email)
|
||||||
|
|
||||||
def __init__(self, instance_object: Any, **data):
|
def __init__(self, instance_object: Any, **data):
|
||||||
super().__init__(**data)
|
super().__init__(**data)
|
||||||
self.instance_object = instance_object
|
self.instance_object = instance_object
|
||||||
|
|
||||||
def to_dataframe_dict(self):
|
@property
|
||||||
|
def dataframe_dict(self) -> dict:
|
||||||
|
"""
|
||||||
|
Dictionary of gui relevant values.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: result
|
||||||
|
"""
|
||||||
return dict(
|
return dict(
|
||||||
name=self.name,
|
name=self.name,
|
||||||
email=self.email,
|
email=self.email,
|
||||||
@@ -654,9 +805,9 @@ class OmniContact(BaseOmni):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def to_sql(self):
|
def to_sql(self):
|
||||||
|
"""
|
||||||
|
Convert this object to an instance of its class object.
|
||||||
|
"""
|
||||||
|
|
||||||
contact, is_new = Contact.query_or_create(name=self.name, email=self.email, phone=self.phone)
|
contact, is_new = Contact.query_or_create(name=self.name, email=self.email, phone=self.phone)
|
||||||
# if is_new:
|
|
||||||
# logger.debug(f"New contact made: {contact}")
|
|
||||||
# else:
|
|
||||||
# logger.debug(f"Contact retrieved: {contact}")
|
|
||||||
return contact
|
return contact
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ Contains all operations for creating charts, graphs and visual effects.
|
|||||||
from datetime import timedelta, date
|
from datetime import timedelta, date
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Generator
|
from typing import Generator
|
||||||
|
|
||||||
|
import plotly
|
||||||
from PyQt6.QtWidgets import QWidget
|
from PyQt6.QtWidgets import QWidget
|
||||||
import pandas as pd, logging
|
import pandas as pd, logging
|
||||||
from plotly.graph_objects import Figure
|
from plotly.graph_objects import Figure
|
||||||
@@ -126,8 +128,8 @@ class CustomFigure(Figure):
|
|||||||
html = f'<html><body>'
|
html = f'<html><body>'
|
||||||
if self is not None:
|
if self is not None:
|
||||||
# NOTE: Just cannot get this load from string to freaking work.
|
# NOTE: Just cannot get this load from string to freaking work.
|
||||||
html += self.to_html(include_plotlyjs='cdn', full_html=False)
|
# html += self.to_html(include_plotlyjs='cdn', full_html=False)
|
||||||
# html += plotly.offline.plot(self, output_type='div', include_plotlyjs=True)
|
html += plotly.offline.plot(self, output_type='div', include_plotlyjs="cdn")
|
||||||
else:
|
else:
|
||||||
html += "<h1>No data was retrieved for the given parameters.</h1>"
|
html += "<h1>No data was retrieved for the given parameters.</h1>"
|
||||||
html += '</body></html>'
|
html += '</body></html>'
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from json.decoder import JSONDecodeError
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
from typing import Any, List, Literal
|
from typing import Any, List, Literal
|
||||||
from PyQt6.QtCore import QSortFilterProxyModel, Qt
|
from PyQt6.QtCore import QSortFilterProxyModel, Qt, QModelIndex
|
||||||
from PyQt6.QtGui import QAction, QCursor
|
from PyQt6.QtGui import QAction, QCursor
|
||||||
from PyQt6.QtWidgets import (
|
from PyQt6.QtWidgets import (
|
||||||
QLabel, QDialog,
|
QLabel, QDialog,
|
||||||
@@ -114,7 +114,16 @@ class ManagerWindow(QDialog):
|
|||||||
# logger.debug(f"Instance: {self.instance}")
|
# logger.debug(f"Instance: {self.instance}")
|
||||||
self.update_data()
|
self.update_data()
|
||||||
|
|
||||||
def update_instance(self, initial: bool = False):
|
def update_instance(self, initial: bool = False) -> None:
|
||||||
|
"""
|
||||||
|
Gets the proper instance of this object's class object.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
initial (bool): Whether this is the initial creation of this object.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
if self.add_edit == "edit" or initial:
|
if self.add_edit == "edit" or initial:
|
||||||
try:
|
try:
|
||||||
# logger.debug(f"Querying with {self.options.currentText()}")
|
# logger.debug(f"Querying with {self.options.currentText()}")
|
||||||
@@ -146,6 +155,7 @@ class ManagerWindow(QDialog):
|
|||||||
[item for item in self.findChildren(QDialogButtonBox)]
|
[item for item in self.findChildren(QDialogButtonBox)]
|
||||||
for item in deletes:
|
for item in deletes:
|
||||||
item.setParent(None)
|
item.setParent(None)
|
||||||
|
logger.debug(f"Self.omni_object: {self.omni_object}")
|
||||||
fields = self.omni_object.__class__.model_fields
|
fields = self.omni_object.__class__.model_fields
|
||||||
for key, info in fields.items():
|
for key, info in fields.items():
|
||||||
# logger.debug(f"Attempting to set {key}, {info} widget")
|
# logger.debug(f"Attempting to set {key}, {info} widget")
|
||||||
@@ -193,14 +203,22 @@ class ManagerWindow(QDialog):
|
|||||||
# logger.debug(f"Instance coming from parsed form: {self.omni_object.__dict__}")
|
# logger.debug(f"Instance coming from parsed form: {self.omni_object.__dict__}")
|
||||||
return self.omni_object
|
return self.omni_object
|
||||||
|
|
||||||
def add_new(self):
|
def add_new(self) -> None:
|
||||||
|
"""
|
||||||
|
Creates a new instance of this object's class object.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
new_instance = self.class_object()
|
new_instance = self.class_object()
|
||||||
self.instance = new_instance
|
self.instance = new_instance
|
||||||
self.update_options()
|
self.update_options()
|
||||||
|
|
||||||
|
|
||||||
class EditProperty(QWidget):
|
class EditProperty(QWidget):
|
||||||
|
"""
|
||||||
|
Class to manage info items of SQL objects.
|
||||||
|
"""
|
||||||
def __init__(self, parent: ManagerWindow, key: str, column_type: Any, value):
|
def __init__(self, parent: ManagerWindow, key: str, column_type: Any, value):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.label = QLabel(key.title().replace("_", " "))
|
self.label = QLabel(key.title().replace("_", " "))
|
||||||
@@ -245,7 +263,13 @@ class EditProperty(QWidget):
|
|||||||
self.layout.addWidget(self.widget, 0, 1, 1, 3)
|
self.layout.addWidget(self.widget, 0, 1, 1, 3)
|
||||||
self.setLayout(self.layout)
|
self.setLayout(self.layout)
|
||||||
|
|
||||||
def parse_form(self):
|
def parse_form(self) -> dict:
|
||||||
|
"""
|
||||||
|
Gets values from this EditProperty form.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: Dictionary of values.
|
||||||
|
"""
|
||||||
# logger.debug(f"Parsing widget {self.objectName()}: {type(self.widget)}")
|
# logger.debug(f"Parsing widget {self.objectName()}: {type(self.widget)}")
|
||||||
match self.widget:
|
match self.widget:
|
||||||
case QLineEdit():
|
case QLineEdit():
|
||||||
@@ -269,7 +293,7 @@ class EditRelationship(QWidget):
|
|||||||
from backend.db import models
|
from backend.db import models
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.class_object = getattr(models, class_object)
|
self.class_object = getattr(models, class_object)
|
||||||
logger.debug(f"Attempt value: {value}")
|
# logger.debug(f"Attempt value: {value}")
|
||||||
# logger.debug(f"Class object: {self.class_object}")
|
# logger.debug(f"Class object: {self.class_object}")
|
||||||
self.setParent(parent)
|
self.setParent(parent)
|
||||||
# logger.debug(f"Edit relationship class_object: {self.class_object}")
|
# logger.debug(f"Edit relationship class_object: {self.class_object}")
|
||||||
@@ -317,7 +341,13 @@ class EditRelationship(QWidget):
|
|||||||
self.setLayout(self.layout)
|
self.setLayout(self.layout)
|
||||||
self.set_data()
|
self.set_data()
|
||||||
|
|
||||||
def update_buttons(self):
|
def update_buttons(self) -> None:
|
||||||
|
"""
|
||||||
|
Enables/disables buttons based on whether property is a list and has data.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
if not self.relationship.property.uselist and len(self.data) >= 1:
|
if not self.relationship.property.uselist and len(self.data) >= 1:
|
||||||
# logger.debug(f"Property {self.relationship} doesn't use list and data is of length: {len(self.data)}")
|
# logger.debug(f"Property {self.relationship} doesn't use list and data is of length: {len(self.data)}")
|
||||||
self.add_button.setEnabled(False)
|
self.add_button.setEnabled(False)
|
||||||
@@ -326,14 +356,23 @@ class EditRelationship(QWidget):
|
|||||||
self.add_button.setEnabled(True)
|
self.add_button.setEnabled(True)
|
||||||
self.existing_button.setEnabled(True)
|
self.existing_button.setEnabled(True)
|
||||||
|
|
||||||
def parse_row(self, x):
|
def parse_row(self, x: QModelIndex) -> None:
|
||||||
|
"""
|
||||||
|
|
||||||
|
Args:
|
||||||
|
x ():
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
"""
|
||||||
context = {item: x.sibling(x.row(), self.df.columns.get_loc(item)).data() for item in self.df.columns}
|
context = {item: x.sibling(x.row(), self.df.columns.get_loc(item)).data() for item in self.df.columns}
|
||||||
|
# logger.debug(f"Context: {pformat(context)}")
|
||||||
try:
|
try:
|
||||||
object = self.class_object.query(**context)
|
object = self.class_object.query(**context)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
object = None
|
object = None
|
||||||
self.widget.doubleClicked.disconnect()
|
self.widget.doubleClicked.disconnect()
|
||||||
self.add_edit(instance=object)
|
self.add_new(instance=object)
|
||||||
|
|
||||||
def add_new(self, instance: Any = None, add_edit: Literal["add", "edit"] = "add", index: int | None = None):
|
def add_new(self, instance: Any = None, add_edit: Literal["add", "edit"] = "add", index: int | None = None):
|
||||||
if add_edit == "edit":
|
if add_edit == "edit":
|
||||||
@@ -388,12 +427,13 @@ class EditRelationship(QWidget):
|
|||||||
"""
|
"""
|
||||||
sets data in model
|
sets data in model
|
||||||
"""
|
"""
|
||||||
# logger.debug(f"Self.data: {self.data}")
|
logger.debug(f"Self.data: {self.data}")
|
||||||
try:
|
try:
|
||||||
records = [item.to_dataframe_dict() for item in self.data]
|
records = [item.dataframe_dict for item in self.data]
|
||||||
except AttributeError:
|
except AttributeError as e:
|
||||||
|
logger.error(e)
|
||||||
records = []
|
records = []
|
||||||
# logger.debug(f"Records: {records}")
|
logger.debug(f"Records: {records}")
|
||||||
self.df = DataFrame.from_records(records)
|
self.df = DataFrame.from_records(records)
|
||||||
try:
|
try:
|
||||||
self.columns_of_interest = [dict(name=item, column=self.df.columns.get_loc(item)) for item in self.extras]
|
self.columns_of_interest = [dict(name=item, column=self.df.columns.get_loc(item)) for item in self.extras]
|
||||||
|
|||||||
Reference in New Issue
Block a user