From b3ff25deb388919c9a205ceb1997ff3c42e93bc8 Mon Sep 17 00:00:00 2001
From: Christian Heller <c.heller@plomlompom.de>
Date: Wed, 10 Apr 2024 07:10:05 +0200
Subject: [PATCH] Display what Processes use focused Process as ProcessStep.

---
 plomtask/http.py       |  3 ++-
 plomtask/processes.py  |  8 ++++++++
 templates/process.html | 10 +++++++++-
 tests/processes.py     |  3 +++
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/plomtask/http.py b/plomtask/http.py
index 54450e4..1743b90 100644
--- a/plomtask/http.py
+++ b/plomtask/http.py
@@ -144,9 +144,10 @@ class TaskHandler(BaseHTTPRequestHandler):
         """Show process of ?id=."""
         id_ = params.get_int_or_none('id')
         process = Process.by_id(conn, id_, create=True)
+        owners = process.used_as_step_by(conn)
         return self.server.jinja.get_template('process.html').render(
                 process=process, steps=process.get_steps(conn),
-                candidates=Process.all(conn))
+                owners=owners, candidates=Process.all(conn))
 
     def do_GET_processes(self, conn: DatabaseConnection,
                          _: ParamsParser) -> str:
diff --git a/plomtask/processes.py b/plomtask/processes.py
index 0a7d5b5..03fecb2 100644
--- a/plomtask/processes.py
+++ b/plomtask/processes.py
@@ -70,6 +70,14 @@ class Process:
                 process.explicit_steps += [ProcessStep.from_table_row(row)]
         return process
 
+    def used_as_step_by(self, db_conn: DatabaseConnection) -> list[Process]:
+        """Return Processes using self for a ProcessStep."""
+        owner_ids = set()
+        for owner_id in db_conn.exec('SELECT owner_id FROM process_steps WHERE'
+                                     ' step_process_id = ?', (self.id_,)):
+            owner_ids.add(owner_id[0])
+        return [self.__class__.by_id(db_conn, id_) for id_ in owner_ids]
+
     def get_steps(self, db_conn: DatabaseConnection, external_owner:
                   Process | None = None) -> dict[int, dict[str, object]]:
         """Return tree of depended-on explicit and implicit ProcessSteps."""
diff --git a/templates/process.html b/templates/process.html
index 1dcfff6..8731f4b 100644
--- a/templates/process.html
+++ b/templates/process.html
@@ -31,11 +31,12 @@ add step: <input name="new_step_to_{{step_id}}" list="candidates" autocomplete="
 {% endmacro %}
 
 {% block content %}
-<h3>Process</h3>
+<h3>process</h3>
 <form action="process?id={{process.id_ or ''}}" method="POST">
 title: <input name="title" value="{{process.title.newest|e}}" />
 description: <input name="description" value="{{process.description.newest|e}}" />
 default effort: <input name="effort" type="number" step=0.1 value={{process.effort.newest}} />
+<h4>steps</h4>
 <table>
 {% for step_id, step_node in steps.items() %}
 {{ process_with_steps(step_id, step_node, 0) }}
@@ -47,8 +48,15 @@ add step: <input name="new_top_step" list="candidates" autocomplete="off" />
 <option value="{{candidate.id_}}">{{candidate.title.newest|e}}</option>
 {% endfor %}
 </datalist>
+<h4>save</h4>
 <input type="submit" value="OK" />
 </form>
+<h4>step of</h4>
+<ul>
+{% for owner in owners %}
+<li><a href="process?id={{owner.id_}}">{{owner.title.newest|e}}</a>
+{% endfor %}
+</ul>
 {% endblock %}
 
 
diff --git a/tests/processes.py b/tests/processes.py
index d6a9899..87b0b09 100644
--- a/tests/processes.py
+++ b/tests/processes.py
@@ -100,6 +100,9 @@ class TestsWithDB(TestCaseWithDB):
             'is_explicit': True, 'steps': {}, 'seen': False
         }
         self.assertEqual(p_1.get_steps(self.db_conn, None), p_1_dict)
+        self.assertEqual(p_1.used_as_step_by(self.db_conn), [])
+        self.assertEqual(p_2.used_as_step_by(self.db_conn), [p_1])
+        self.assertEqual(p_3.used_as_step_by(self.db_conn), [p_1, p_2])
 
     def test_Process_by_id(self) -> None:
         """Test Process.by_id()."""
-- 
2.30.2