From 74ce91808f3fdc400564740087a71060d36eebf7 Mon Sep 17 00:00:00 2001 From: Florian Spreckelsen <f.spreckelsen@indiscale.com> Date: Mon, 27 Jan 2025 15:38:28 +0100 Subject: [PATCH] ENH: Make sample registration compatible --- .../sample-management-datamodel.yml | 4 +- .../ext/js/bis_custom_reference_resolver.js | 4 +- .../src/ext/js/ext_stockmanagement.js | 2 +- .../scripting/bin/register_new_samples.py | 48 ++++--------------- .../bin/sample_helpers/default_constants.yml | 2 + ...mple_registration_get_person_identifier.py | 44 +++++++++++++++++ 6 files changed, 60 insertions(+), 44 deletions(-) create mode 100644 sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_registration_get_person_identifier.py diff --git a/models_and_helper_scripts/sample-management-datamodel.yml b/models_and_helper_scripts/sample-management-datamodel.yml index d2cb68d..74828ea 100644 --- a/models_and_helper_scripts/sample-management-datamodel.yml +++ b/models_and_helper_scripts/sample-management-datamodel.yml @@ -33,9 +33,9 @@ Person: inherit_from_obligatory: - Responsible obligatory_properties: - First name: + first_name: datatype: TEXT - Last name: + last_name: datatype: TEXT Email: datatype: TEXT diff --git a/sample-management-custom/caosdb-server/caosdb-webui/src/ext/js/bis_custom_reference_resolver.js b/sample-management-custom/caosdb-server/caosdb-webui/src/ext/js/bis_custom_reference_resolver.js index 780a0c2..7059cb5 100644 --- a/sample-management-custom/caosdb-server/caosdb-webui/src/ext/js/bis_custom_reference_resolver.js +++ b/sample-management-custom/caosdb-server/caosdb-webui/src/ext/js/bis_custom_reference_resolver.js @@ -1,7 +1,7 @@ var bis_custom_reference_resolver = new function (getEntityID, getEntityName, getParents, getProperty, query) { - const lastname_prop_name = "Last name"; - const firstname_prop_name = "First name"; + const lastname_prop_name = "last_name"; + const firstname_prop_name = "first_name"; const person_rt_name = "Person"; const bis_label_prop_name = "BIS label"; const custom_label_prop_name = "Custom label" diff --git a/sample-management-custom/caosdb-server/caosdb-webui/src/ext/js/ext_stockmanagement.js b/sample-management-custom/caosdb-server/caosdb-webui/src/ext/js/ext_stockmanagement.js index 36e05ce..8afbebb 100644 --- a/sample-management-custom/caosdb-server/caosdb-webui/src/ext/js/ext_stockmanagement.js +++ b/sample-management-custom/caosdb-server/caosdb-webui/src/ext/js/ext_stockmanagement.js @@ -35,7 +35,7 @@ const ext_stockmanagement = function($, navbar, log, form_elements, form_panel, name: "responsible_entity", label: "Responsible entity", query: "FIND RECORD Responsible", - make_desc: getEntityName, + make_desc: bis_custom_reference_resolver.resolve_person_reference, required: true }, { diff --git a/sample-management-custom/caosdb-server/scripting/bin/register_new_samples.py b/sample-management-custom/caosdb-server/scripting/bin/register_new_samples.py index a93d78e..1b912ee 100755 --- a/sample-management-custom/caosdb-server/scripting/bin/register_new_samples.py +++ b/sample-management-custom/caosdb-server/scripting/bin/register_new_samples.py @@ -11,6 +11,7 @@ from caosadvancedtools.serverside.logging import configure_server_side_logging from bis_utils import (create_email_with_link_text, get_description_row, get_email_from_username, get_options_row, send_mail_with_defaults) +from sample_helpers.sample_registration_get_person_identifier import get_person_identifier from sample_helpers.sample_registration_post_processing import post_process_samples from sample_helpers.utils import CONSTANTS, get_column_header_name, get_entity_name @@ -25,53 +26,26 @@ def get_parser(): return par -def get_responsible_person_id(data): - return int(data["responsible_person"]) - - -def get_responsible_person_abbreviation(data): - person = db.execute_query("FIND {}".format(get_responsible_person_id(data)))[0] - return person.get_property("Abbreviation").value - - -def get_number_of_samples(data): - return int(data["number_of_samples"]) -# def is_samples_from_cruise(data): -# return ("samples_from_cruise" in data and data["samples_from_cruise"] == "on") -# def has_start_and_end_time(data): -# return ("start_and_end_time" in data and data["start_and_end_time"] == "on") -# def get_number_of_locations(data): -# number_of_locations = int(data["number_of_locations"]) -# if number_of_locations < 1: -# number_of_locations = 1 # At least one location is OBLIGATORY -# return number_of_locations - - -def get_reference_properties(data): - return data["reference_properties"] - - def get_column_names(data): # Make sure each header starts with BIS ID and Main User - starting_names = ["BIS ID", "Main User"] + starting_names = ["entity_id", "Main User"] # required_column_names is just a string of column names separated by # commas. other_names = data["required_column_names"].split(',') + data["column_names"] starting_names.extend([name.strip() for name in other_names if name.strip() not in starting_names]) - return starting_names + return [get_column_header_name(name) for name in starting_names] def create_sample_entities(data): - responsible_person_id = get_responsible_person_id(data) - number_of_samples = get_number_of_samples(data) + responsible_person_id = int(data["responsible_person"]) + number_of_samples = int(data["number_of_samples"]) batch = db.Container() for index in range(number_of_samples): sample = db.Record() - sample.add_parent(name="Sample") - sample.add_property(name="Main User", value=responsible_person_id) - sample.add_property("Container") + sample.add_parent(name=get_entity_name("Sample")) + sample.add_property(name=get_entity_name("Main User"), value=responsible_person_id) batch += [sample] batch = post_process_samples(batch) batch.insert() @@ -118,12 +92,8 @@ def read_input(args, log=False): def create_csv_template(template_name, samples, form_input): template_display_path, template_internal_path = helper.get_shared_filename(template_name) # Read form_input - responsible_person_abbreviation = get_responsible_person_abbreviation(form_input) - number_of_samples = get_number_of_samples(form_input) - # samples_from_cruise = is_samples_from_cruise(form_input) - # start_and_end_time = has_start_and_end_time(form_input) - # number_of_locations = get_number_of_locations(form_input) - # reference_properties = get_reference_properties(form_input) + responsible_person_abbreviation = get_person_identifier(form_input) + number_of_samples = int(form_input["number_of_samples"]) header = get_column_names(form_input) with open(template_internal_path, 'w') as csv_template: 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 c773685..2db07b9 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 @@ -56,6 +56,8 @@ entity_names: labelcounter_prop: Counter labelcounter_rt: LabelCounter responsible_rt: Responsible + first_name_prop: first_name + last_name_prop: last_name error_prefix: "Something went wrong:" error_suffix: "Please contact your administrator(s)." diff --git a/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_registration_get_person_identifier.py b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_registration_get_person_identifier.py new file mode 100644 index 0000000..329dc3d --- /dev/null +++ b/sample-management-custom/caosdb-server/scripting/bin/sample_helpers/sample_registration_get_person_identifier.py @@ -0,0 +1,44 @@ +# +# Copyright (C) 2025 Indiscale GmbH <info@indiscale.com> +# Copyright (C) 2025 Florian Spreckelsen <f.spreckelsen@indiscale.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +import linkahead as db + +from .utils import get_entity_name + + +def get_person_identifier(form_data: dict) -> str: + """Retrieve a person record from the given id, and replace by + abbreviation if present, else "last name, first name". + + """ + person_rec = db.cached.cached_get_entity_by(eid=form_data["responsible_person"]) + # Use abbreviation if present + if (person_rec.get_property(get_entity_name("abbreviation_prop")) is not None and + person_rec.get_property(get_entity_name("abbreviation_prop")).value): + return person_rec.get_property(get_entity_name("abbreviation_prop")).value + first_name = person_rec.get_property(get_entity_name("first_name_prop")).value if person_rec.get_property( + get_entity_name("first_name_prop")) is not None else "" + last_name = person_rec.get_property(get_entity_name("last_name_prop")).value if person_rec.get_property( + get_entity_name("last_name_prop")) is not None else "" + # Else use first and last name ... + if first_name and last_name: + return f"{last_name}, {first_name}" + # ... or just last name if no first name + if last_name: + return last_name + # Last fallback id + return person_rec.id -- GitLab