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