Generic info fields input into 'custom'.
This commit is contained in:
@@ -932,6 +932,9 @@ class SubmissionType(BaseClass):
|
||||
new_process.submission_types.append(submission_type)
|
||||
new_process.kit_types.append(new_kit)
|
||||
new_process.equipment_roles.append(new_role)
|
||||
if 'orgs' in import_dict.keys():
|
||||
logger.info("Found Organizations to be imported.")
|
||||
Organization.import_from_json(filepath=filepath)
|
||||
return submission_type
|
||||
|
||||
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
All client organization related models.
|
||||
'''
|
||||
from __future__ import annotations
|
||||
|
||||
import json, yaml, logging
|
||||
from pathlib import Path
|
||||
from pprint import pformat
|
||||
from sqlalchemy import Column, String, INTEGER, ForeignKey, Table
|
||||
from sqlalchemy.orm import relationship, Query
|
||||
from . import Base, BaseClass
|
||||
from tools import check_authorization, setup_lookup
|
||||
from typing import List
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
@@ -74,6 +77,42 @@ class Organization(BaseClass):
|
||||
def save(self):
|
||||
super().save()
|
||||
|
||||
@classmethod
|
||||
@check_authorization
|
||||
def import_from_json(cls, filepath: Path|str):
|
||||
if isinstance(filepath, str):
|
||||
filepath = Path(filepath)
|
||||
if not filepath.exists():
|
||||
logging.critical(f"Given file could not be found.")
|
||||
return None
|
||||
with open(filepath, "r") as f:
|
||||
if filepath.suffix == ".json":
|
||||
import_dict = json.load(fp=f)
|
||||
elif filepath.suffix == ".yml":
|
||||
import_dict = yaml.safe_load(stream=f)
|
||||
else:
|
||||
raise Exception(f"Filetype {filepath.suffix} not supported.")
|
||||
data = import_dict['orgs']
|
||||
logger.debug(pformat(import_dict))
|
||||
for org in data:
|
||||
organ = Organization.query(name=org['name'])
|
||||
if organ is None:
|
||||
organ = Organization(name=org['name'])
|
||||
try:
|
||||
organ.cost_centre = org['cost_centre']
|
||||
except KeyError:
|
||||
organ.cost_centre = "xxx"
|
||||
for contact in org['contacts']:
|
||||
cont = Contact.query(name=contact['name'])
|
||||
if cont is None:
|
||||
cont = Contact()
|
||||
for k, v in contact.items():
|
||||
cont.__setattr__(k, v)
|
||||
organ.contacts.append(cont)
|
||||
organ.save()
|
||||
# logger.debug(pformat(organ.__dict__))
|
||||
|
||||
|
||||
|
||||
class Contact(BaseClass):
|
||||
"""
|
||||
@@ -119,7 +158,7 @@ class Contact(BaseClass):
|
||||
match name:
|
||||
case str():
|
||||
# logger.debug(f"Looking up contact with name: {name}")
|
||||
query = query.filter(cls.name == name)
|
||||
query = query.filter(cls.name == name.title())
|
||||
limit = 1
|
||||
case _:
|
||||
pass
|
||||
|
||||
@@ -72,6 +72,7 @@ class BasicSubmission(BaseClass):
|
||||
contact = relationship("Contact", back_populates="submissions") #: client org
|
||||
contact_id = Column(INTEGER, ForeignKey("_contact.id", ondelete="SET NULL",
|
||||
name="fk_BS_contact_id")) #: client lab id from _organizations
|
||||
custom = Column(JSON)
|
||||
|
||||
submission_sample_associations = relationship(
|
||||
"SubmissionSampleAssociation",
|
||||
@@ -563,7 +564,11 @@ class BasicSubmission(BaseClass):
|
||||
existing += value
|
||||
else:
|
||||
if value is not None:
|
||||
existing.append(value)
|
||||
if key == "custom":
|
||||
existing = value
|
||||
else:
|
||||
existing.append(value)
|
||||
|
||||
self.__setattr__(key, existing)
|
||||
flag_modified(self, key)
|
||||
return
|
||||
@@ -741,6 +746,28 @@ class BasicSubmission(BaseClass):
|
||||
dict: Updated sample dictionary
|
||||
"""
|
||||
logger.info(f"Calling {cls.__mapper_args__['polymorphic_identity']} info parser.")
|
||||
# logger.debug(f"Input dict: {input_dict}")
|
||||
# logger.debug(f"Custom fields: {custom_fields}")
|
||||
input_dict['custom'] = {}
|
||||
for k,v in custom_fields.items():
|
||||
logger.debug(f"Attempting custom parse of {k}: {v}")
|
||||
|
||||
match v['type']:
|
||||
case "exempt":
|
||||
continue
|
||||
case "cell":
|
||||
ws = xl[v['read']['sheet']]
|
||||
input_dict['custom'][k] = ws.cell(row=v['read']['row'], column=v['read']['column']).value
|
||||
case "range":
|
||||
ws = xl[v['sheet']]
|
||||
input_dict['custom'][k] = []
|
||||
if v['start_row'] != v['end_row']:
|
||||
v['end_row'] = v['end_row'] + 1
|
||||
if v['start_column'] != v['end_column']:
|
||||
v['end_column'] = v['end_column'] + 1
|
||||
for ii in range(v['start_row'], v['end_row']):
|
||||
for jj in range(v['start_column'], v['end_column']+1):
|
||||
input_dict['custom'][k].append(dict(value=ws.cell(row=ii, column=jj).value, row=ii, column=jj))
|
||||
return input_dict
|
||||
|
||||
@classmethod
|
||||
@@ -790,6 +817,29 @@ class BasicSubmission(BaseClass):
|
||||
Workbook: Updated workbook
|
||||
"""
|
||||
logger.info(f"Hello from {cls.__mapper_args__['polymorphic_identity']} autofill")
|
||||
logger.debug(f"Input dict: {info}")
|
||||
logger.debug(f"Custom fields: {custom_fields}")
|
||||
for k,v in custom_fields.items():
|
||||
try:
|
||||
assert v['type'] in ['exempt', 'range', 'cell']
|
||||
except (AssertionError, KeyError):
|
||||
continue
|
||||
match v['type']:
|
||||
case "exempt":
|
||||
continue
|
||||
case "cell":
|
||||
v['write'].append(v['read'])
|
||||
for cell in v['write']:
|
||||
ws = input_excel[cell['sheet']]
|
||||
ws.cell(row=cell['row'], column=cell['column'], value=info['custom'][k])
|
||||
case "range":
|
||||
ws = input_excel[v['sheet']]
|
||||
if v['start_row'] != v['end_row']:
|
||||
v['end_row'] = v['end_row'] + 1
|
||||
if v['start_column'] != v['end_column']:
|
||||
v['end_column'] = v['end_column'] + 1
|
||||
for item in info['custom'][k]:
|
||||
ws.cell(row=item['row'], column=item['column'], value=item['value'])
|
||||
return input_excel
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -65,20 +65,28 @@ class SheetParser(object):
|
||||
"""
|
||||
parser = InfoParser(xl=self.xl, submission_type=self.submission_type, sub_object=self.sub_object)
|
||||
info = parser.parse_info()
|
||||
logger.debug(f"Checking old submission type: {self.submission_type.name} against new: {info['submission_type']['value']}")
|
||||
if self.submission_type.name != info['submission_type']['value']:
|
||||
if info['submission_type']['value'] not in [None, "None", "", " "]:
|
||||
self.submission_type = SubmissionType.query(name=info['submission_type']['value'])
|
||||
logger.debug(f"Updated self.submission_type to {self.submission_type}. Rerunning parse.")
|
||||
self.parse_info()
|
||||
return
|
||||
self.info_map = parser.map
|
||||
for k, v in info.items():
|
||||
match k:
|
||||
# NOTE: exclude samples.
|
||||
case "sample":
|
||||
continue
|
||||
case "submission_type":
|
||||
self.sub[k] = v
|
||||
# NOTE: Rescue submission type using scraped values to be used in Sample, Reagents, etc.
|
||||
if v not in [None, "None", "", " "]:
|
||||
self.submission_type = SubmissionType.query(name=v)
|
||||
logger.debug(f"Updated self.submission_type to {self.submission_type}")
|
||||
# case "submission_type":
|
||||
# self.sub[k] = v
|
||||
# # NOTE: Rescue submission type using scraped values to be used in Sample, Reagents, etc.
|
||||
# if v not in [None, "None", "", " "]:
|
||||
# self.submission_type = SubmissionType.query(name=v)
|
||||
# logger.debug(f"Updated self.submission_type to {self.submission_type}")
|
||||
case _:
|
||||
self.sub[k] = v
|
||||
print(f"\n\n {self.sub} \n\n")
|
||||
|
||||
|
||||
def parse_reagents(self, extraction_kit: str | None = None):
|
||||
|
||||
@@ -175,6 +175,8 @@ class InfoWriter(object):
|
||||
"""
|
||||
final_info = {}
|
||||
for k, v in self.info:
|
||||
if k == "custom":
|
||||
continue
|
||||
# NOTE: merge all comments to fit in single cell.
|
||||
if k == "comment" and isinstance(v['value'], list):
|
||||
json_join = [item['text'] for item in v['value'] if 'text' in item.keys()]
|
||||
|
||||
@@ -734,11 +734,19 @@ class PydSubmission(BaseModel, extra='allow'):
|
||||
# logger.debug(f"Here's our list of duplicate removed samples: {self.samples}")
|
||||
for key, value in dicto.items():
|
||||
if isinstance(value, dict):
|
||||
value = value['value']
|
||||
try:
|
||||
value = value['value']
|
||||
except KeyError:
|
||||
if key == "custom":
|
||||
pass
|
||||
else:
|
||||
continue
|
||||
if value is None:
|
||||
continue
|
||||
# logger.debug(f"Setting {key} to {value}")
|
||||
match key:
|
||||
# case "custom":
|
||||
# instance.custom = value
|
||||
case "reagents":
|
||||
if report.results[0].code == 1:
|
||||
instance.submission_reagent_associations = []
|
||||
@@ -782,9 +790,13 @@ class PydSubmission(BaseModel, extra='allow'):
|
||||
ii = value.items()
|
||||
except AttributeError:
|
||||
ii = {}
|
||||
logger.debug(f"ii is {ii}, value is {value}")
|
||||
for k, v in ii:
|
||||
logger.debug(f"k is {k}, v is {v}")
|
||||
if isinstance(v, datetime):
|
||||
value[k] = v.strftime("%Y-%m-%d %H:%M:%S")
|
||||
else:
|
||||
value[k] = v
|
||||
instance.set_attribute(key=key, value=value)
|
||||
case _:
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user