From 23012cd370777b60a25839788d131173d2abee91 Mon Sep 17 00:00:00 2001
From: Christian Heller <c.heller@plomlompom.de>
Date: Mon, 29 Apr 2024 00:32:24 +0200
Subject: [PATCH] Enable deletion of Conditions.

---
 plomtask/conditions.py   | 11 +++++++++++
 plomtask/http.py         |  4 ++++
 templates/condition.html |  7 ++++++-
 templates/process.html   | 13 -------------
 tests/conditions.py      | 19 ++++++++++++++++++-
 5 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/plomtask/conditions.py b/plomtask/conditions.py
index a452600..3379709 100644
--- a/plomtask/conditions.py
+++ b/plomtask/conditions.py
@@ -4,6 +4,7 @@ from typing import Any
 from sqlite3 import Row
 from plomtask.db import DatabaseConnection, BaseModel
 from plomtask.misc import VersionedAttribute
+from plomtask.exceptions import HandledException
 
 
 class Condition(BaseModel[int]):
@@ -35,6 +36,16 @@ class Condition(BaseModel[int]):
         self.title.save(db_conn)
         self.description.save(db_conn)
 
+    def remove(self, db_conn: DatabaseConnection) -> None:
+        """Remove from DB, with dependencies."""
+        assert isinstance(self.id_, int)
+        for item in ('process', 'todo'):
+            for attr in ('conditions', 'enables', 'disables'):
+                table_name = f'{item}_{attr}'
+                for _ in db_conn.row_where(table_name, 'condition', self.id_):
+                    raise HandledException('cannot remove Condition in use')
+        super().remove(db_conn)
+
 
 class ConditionsRelations:
     """Methods for handling relations to Conditions, for Todo and Process."""
diff --git a/plomtask/http.py b/plomtask/http.py
index 800193c..7e2b241 100644
--- a/plomtask/http.py
+++ b/plomtask/http.py
@@ -273,6 +273,10 @@ class TaskHandler(BaseHTTPRequestHandler):
     def do_POST_condition(self) -> str:
         """Update/insert Condition of ?id= and fields defined in postvars."""
         id_ = self.params.get_int_or_none('id')
+        for _ in self.form_data.get_all_str('delete'):
+            condition = Condition.by_id(self.conn, id_)
+            condition.remove(self.conn)
+            return '/conditions'
         condition = Condition.by_id(self.conn, id_, create=True)
         condition.title.set(self.form_data.get_str('title'))
         condition.description.set(self.form_data.get_str('description'))
diff --git a/templates/condition.html b/templates/condition.html
index dfdf6ef..a0a9f45 100644
--- a/templates/condition.html
+++ b/templates/condition.html
@@ -5,6 +5,11 @@
 <form action="condition?id={{condition.id_ or ''}}" method="POST">
 title: <input name="title" value="{{condition.title.newest|e}}" />
 description: <input name="description" value="{{condition.description.newest|e}}" />
-<input type="submit" value="OK" />
+
+<input class="btn-harmless" type="submit" name="update" value="update" />
+<div class="btn-to-right">
+<input class="btn-dangerous" type="submit" name="delete" value="delete" />
+</div>
+
 {% endblock %}
 
diff --git a/templates/process.html b/templates/process.html
index 8a50e15..2a57715 100644
--- a/templates/process.html
+++ b/templates/process.html
@@ -1,18 +1,5 @@
 {% extends 'base.html' %}
 
-{% block css %}
-input.btn-harmless {
-  color: green;
-}
-input.btn-dangerous {
-  color: red;
-}
-div.btn-to-right {
-  float: right;
-  text-align: right;
-}
-{% endblock %}
-
 
 
 {% macro step_with_steps(step_id, step_node, indent) %}
diff --git a/tests/conditions.py b/tests/conditions.py
index 3b95de1..6538e87 100644
--- a/tests/conditions.py
+++ b/tests/conditions.py
@@ -1,7 +1,8 @@
 """Test Conditions module."""
 from tests.utils import TestCaseWithDB, TestCaseWithServer
 from plomtask.conditions import Condition
-from plomtask.exceptions import NotFoundException
+from plomtask.processes import Process
+from plomtask.exceptions import NotFoundException, HandledException
 
 
 class TestsWithDB(TestCaseWithDB):
@@ -36,6 +37,22 @@ class TestsWithDB(TestCaseWithDB):
         condition_retrieved = Condition.by_id(self.db_conn, 1)
         self.assertEqual(True, condition_retrieved.is_active)
 
+    def test_Condition_removal(self) -> None:
+        """Test removal of Condition."""
+        cond = Condition(None, False)
+        cond.save(self.db_conn)
+        assert isinstance(cond.id_, int)
+        proc = Process(None)
+        proc.save(self.db_conn)
+        proc.set_conditions(self.db_conn, [cond.id_], 'conditions')
+        proc.save(self.db_conn)
+        with self.assertRaises(HandledException):
+            cond.remove(self.db_conn)
+        proc.set_conditions(self.db_conn, [], 'conditions')
+        proc.save(self.db_conn)
+        cond.remove(self.db_conn)
+        self.assertEqual(Condition.all(self.db_conn), [])
+
 
 class TestsWithServer(TestCaseWithServer):
     """Module tests against our HTTP server/handler (and database)."""
-- 
2.30.2