home · contact · privacy
Fix broken ProcessStep processing.
authorChristian Heller <c.heller@plomlompom.de>
Tue, 24 Dec 2024 07:25:14 +0000 (08:25 +0100)
committerChristian Heller <c.heller@plomlompom.de>
Tue, 24 Dec 2024 07:25:14 +0000 (08:25 +0100)
plomtask/http.py
plomtask/processes.py

index e86d314510bfbdeae570577e45a0afdcb3df871f..754e36e8d02aad02fae3fe32e5c97248782be2a1 100644 (file)
@@ -751,10 +751,9 @@ class TaskHandler(BaseHTTPRequestHandler):
         suppressions = self._form.get_all_int('suppressed_steps')
         kept_steps = self._form.get_all_int('kept_steps')
         new_top_step_procs = self._form.get_all_str('new_top_step')
-        new_steps_to = {}
-        for step_id in kept_steps:
-            name = f'new_step_to_{step_id}'
-            new_steps_to[step_id] = self._form.get_all_int(name)
+        new_steps_to = {
+                int(k):[int(n) for n in v] for (k, v)
+                in self._form.get_all_of_key_prefixed('new_step_to_').items()}
         new_owner_title, owners_to_set = id_or_title(step_of)
         new_step_title, new_top_step_proc_ids = id_or_title(new_top_step_procs)
         #
@@ -765,15 +764,14 @@ class TaskHandler(BaseHTTPRequestHandler):
         assert isinstance(process.id_, int)
         # set relations to Conditions and ProcessSteps / other Processes
         process.set_condition_relations(self._conn, *cond_rels)
-        owned_steps = []
-        for step_id in kept_steps:
-            owned_steps += [ProcessStep.by_id(self._conn, step_id)]
-            owned_steps += [  # new sub-steps
-                    ProcessStep(None, process.id_, step_process_id, step_id)
-                    for step_process_id in new_steps_to[step_id]]
-        for step_process_id in new_top_step_proc_ids:
+        owned_steps = [ProcessStep.by_id(self._conn, step_id)
+                       for step_id in kept_steps]
+        for parent_step_id, step_process_ids in new_steps_to.items():
             owned_steps += [ProcessStep(None, process.id_, step_process_id,
-                                        None)]
+                                        parent_step_id)
+                            for step_process_id in step_process_ids]
+        owned_steps += [ProcessStep(None, process.id_, step_process_id, None)
+                        for step_process_id in new_top_step_proc_ids]
         process.set_step_relations(self._conn, owners_to_set, suppressions,
                                    owned_steps)
         # encode titles for potential newly-to-create Processes up or down
index d2e84109770e0f00d24b4e6f547e6ca38261b76f..3c8eebe2d4560825ec86bdaafa00ccf87131ddfe 100644 (file)
@@ -194,8 +194,14 @@ class Process(BaseModel[int], ConditionsRelations):
                 walk_steps(step)
 
         assert isinstance(self.id_, int)
+        # NB: separate the collection of steps to save/remove from the action
+        # because the latter may modify the collection / self.explicit_steps
+        to_remove = []
         for step in [s for s in self.explicit_steps if s not in steps]:
+            to_remove += [step]
+        for step in to_remove:
             step.remove(db_conn)
+        to_save = []
         for step in [s for s in steps if s not in self.explicit_steps]:
             if step.parent_step_id is not None:
                 try:
@@ -206,6 +212,8 @@ class Process(BaseModel[int], ConditionsRelations):
                 except NotFoundException:
                     step.parent_step_id = None
             walk_steps(step)
+            to_save += [step]
+        for step in to_save:
             step.save(db_conn)
 
     def save(self, db_conn: DatabaseConnection) -> None:
@@ -213,7 +221,12 @@ class Process(BaseModel[int], ConditionsRelations):
         super().save(db_conn)
         assert isinstance(self.id_, int)
         db_conn.delete_where('process_steps', 'owner', self.id_)
+        # NB: we separate the collection of steps to save from step.save()
+        # because the latter may modify the collection / self.explicit_steps
+        to_save = []
         for step in self.explicit_steps:
+            to_save += [step]
+        for step in to_save:
             step.save(db_conn)
 
     def remove(self, db_conn: DatabaseConnection) -> None: