diff --git a/README.md b/README.md index 724f51953a94fc1ab5093350d03bba9f0665a7b5..71abb5a53d47f565f816196d238ed9b207ed3dd2 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,19 @@ stored in LinkAhead You can create a filled CSV template with the information about Containers as it is currently stored in LinkAhead. +### Extensibility +The registration, update and export does not only work with RecordTypes and +Properties that are defined within this module, but the data model can be +extended by users of the system: Any Property that is added to the Sample +RecordType can also be used within the workflow. Once an additional Property +was added to the RecordType (say "width"), you can select a corresponding +column during registration with the same name and also upload CSV templates +that have this column. The Sample records will be created or updated to also +have this ("width") column. + +If the Property that is added is a RecordType, it must be kind of an enum, i.e. +it should be uniquely identified either by its name or by a sole property. + ## Usage **TODO**: Add explanations, screenshots, ec. to explain the sample @@ -132,7 +145,7 @@ allow to change those. This is the central RecordType for the sample management and used to represent samples of various types -#### `Parent_Sample` (`$parent_sample_prop`) +#### `Parent_sample` (`$parent_sample_prop`) references the sample from which the sample at hand originated (for example by cutting the parent sample into multiple pieces0 diff --git a/models_and_helper_scripts/sample-management-datamodel.yml b/models_and_helper_scripts/sample-management-datamodel.yml index 4d12dc6999feb0e3f5272912349392f7b699ed84..aef3b68183e47b862b3189622822247dcb8c3ee3 100644 --- a/models_and_helper_scripts/sample-management-datamodel.yml +++ b/models_and_helper_scripts/sample-management-datamodel.yml @@ -83,7 +83,7 @@ Sample: recommended_properties: Container: SampleType: - Parent_Sample: + Parent_sample: datatype: Sample Main User: datatype: Person diff --git a/sample-management-custom/caosdb-server/caosdb-webui/src/ext/js/ext_samplemanagement.js b/sample-management-custom/caosdb-server/caosdb-webui/src/ext/js/ext_samplemanagement.js index ba4dcb4809afc498c8ab49baaeed2ebdda7ff130..e8e46e0d88ac2cc40b4fe89fe5032ecbbdd3cb82 100644 --- a/sample-management-custom/caosdb-server/caosdb-webui/src/ext/js/ext_samplemanagement.js +++ b/sample-management-custom/caosdb-server/caosdb-webui/src/ext/js/ext_samplemanagement.js @@ -42,6 +42,7 @@ const ext_samplemanagement = function($, navbar, log, form_elements, form_panel, "Latitude start", "Longitude start", "Elevation start", + "Start date", "Storage ID", "Device" ]; @@ -73,8 +74,10 @@ const ext_samplemanagement = function($, navbar, log, form_elements, form_panel, const unused_property_names = [ "Main User", + "Event", + "Container", 'NagoyaCase', - "Parent_Sample", + "Parent_sample", ] const upload_sample_template_form_config = { diff --git a/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/default_constants.yml b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/default_constants.yml index f7521803ad3ec7696e2b71d83241a31d2bdebf38..c575cb61f4cbd50676d8b944f7af7631963907bf 100644 --- a/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/default_constants.yml +++ b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/default_constants.yml @@ -68,7 +68,7 @@ entity_names: labelcounter_prop: counter labelcounter_rt: LabelCounter last_name_prop: last_name - parent_sample_prop: Parent_Sample + parent_sample_prop: Parent_sample responsible_rt: Responsible start_date_prop: start_date locality_description_prop: locality_description diff --git a/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_add_special_properties.py b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_add_special_properties.py index 5c559d42f9e926303f2c2d94d0bb26e2c42d5d38..9ec2fffef113f842440b1907f153b0e01cbe5050 100644 --- a/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_add_special_properties.py +++ b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_add_special_properties.py @@ -33,10 +33,16 @@ def add_special_properties(sample: db.Record, data: pd.Series) -> db.Record: """ main_user_prop = db.get_entity_by_name(get_entity_name("Main User")) + pi_prop = db.get_entity_by_name(get_entity_name("PI")) container_rt = db.get_entity_by_name(get_entity_name("container_rt")) device_rt = db.get_entity_by_name(get_entity_name("Device")) parent_sample_prop = db.get_entity_by_name(get_entity_name("parent_sample_prop")) + if (get_column_header_name("PI") in data and + return_value_if_not_none(data[get_column_header_name("PI")]) is not None): + pi_user = get_person(return_value_if_not_none(data[get_column_header_name("PI")])) + sample = update_property(sample, pi_prop.id, pi_user, property_name=pi_prop.name) + if (get_column_header_name("Main User") in data and return_value_if_not_none(data[get_column_header_name("Main User")]) is not None): main_user = get_person(return_value_if_not_none(data[get_column_header_name("Main User")])) diff --git a/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_column_definitions.py b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_column_definitions.py index 5535863a33ce7ddc46ad1b5d613c29bccc0a9e45..058452266722257db5023f076031d2cc570a54dd 100644 --- a/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_column_definitions.py +++ b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_column_definitions.py @@ -79,6 +79,7 @@ DATATYPE_DEFINITIONS = use_custom_names({ # Must exist OBLIGATORY_COLUMNS = use_custom_names([ "entity_id", + "Start date", ]) OBLIGATORY_COLUMNS_CHILD = use_custom_names([ @@ -114,6 +115,7 @@ SPECIAL_TREATMENT_SAMPLE = use_custom_names([ "Longitude start", "Longitude stop", "Main User", + "PI", "PDFReport", "parent_sample_prop", "Sphere", @@ -124,6 +126,6 @@ SPECIAL_TREATMENT_SAMPLE = use_custom_names([ IGNORED_COLUMN_NAMES_SAMPLE = use_custom_names([ "LinkAhead URL", - "Parent Sample", + "Parent_sample", "Storage chain", ]) diff --git a/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_get_person.py b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_get_person.py index 1872f6224dfa9282ebcc772f1bea2c93d355dcfa..3e947804d60d10e20a6cd05219c02861b0c067a0 100644 --- a/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_get_person.py +++ b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_upload_get_person.py @@ -21,6 +21,7 @@ from caosadvancedtools.datainconsistency import DataInconsistencyError from .utils import get_entity_name +from linkahead.cached import cached_get_entity_by, cached_query as cquery def get_person(text: str) -> db.Record: """Return the Person Record that is specifed as 'Main User' or @@ -60,11 +61,19 @@ def _get_person_by_fullname(first_name: str, last_name: str) -> db.Record: return res[0] -def _get_person_by_id(eid: str) -> db.Record: - - try: - return db.get_entity_by_id(eid, role=get_entity_name("Person")) - except db.EmptyUniqueQueryError: +def _get_person_by_id(ident: str) -> db.Record: + options = cquery(f"FIND '{get_entity_name('Person')}' WITH ID='{ident}' ") + if len(options)==1: + return options[0] + options = cquery(f"FIND '{get_entity_name('Person')}' WITH " + f"'{get_entity_name('abbreviation_prop')}'='{ident}' ") + if len(options) == 1: + return options[0] + elif len(options) == 0: + raise DataInconsistencyError( + f"Could not find a {get_entity_name('Person')} with ID {ident}." + ) + else: raise DataInconsistencyError( - f"Could not find a {get_entity_name('Person')} with ID {eid}." + f"Found multiple {get_entity_name('Person')} with {get_entity_name('abbreviation_prop')}={ident}." )