From 4119967e77c75257eed8ab1e7101861ea125c204 Mon Sep 17 00:00:00 2001
From: Nathan Hertz <nhertz@nrao.edu>
Date: Thu, 18 Nov 2021 17:27:34 -0500
Subject: [PATCH] WS-797: Execution/version state is correctly updated after QA
 operation

---
 ...add_actions_for_qa_pass_and_qa_fail_to_.py | 58 +++++++++++++++++++
 .../workspaces/capability/schema.py           | 32 +++++-----
 2 files changed, 74 insertions(+), 16 deletions(-)
 create mode 100644 schema/versions/e0bbf2bf093f_add_actions_for_qa_pass_and_qa_fail_to_.py

diff --git a/schema/versions/e0bbf2bf093f_add_actions_for_qa_pass_and_qa_fail_to_.py b/schema/versions/e0bbf2bf093f_add_actions_for_qa_pass_and_qa_fail_to_.py
new file mode 100644
index 000000000..c324495a2
--- /dev/null
+++ b/schema/versions/e0bbf2bf093f_add_actions_for_qa_pass_and_qa_fail_to_.py
@@ -0,0 +1,58 @@
+"""add actions for qa-pass and qa-fail to complete versions
+
+Revision ID: e0bbf2bf093f
+Revises: 9507363ddab7
+Create Date: 2021-11-18 12:58:08.894885
+
+"""
+from alembic import op
+
+# revision identifiers, used by Alembic.
+revision = "e0bbf2bf093f"
+down_revision = "9507363ddab7"
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    complete_version_sql = """
+    INSERT INTO capability_state_actions (transition_id, action_type, arguments)
+    SELECT transition_id, 'SendMessage', 'execution_complete'
+    FROM capability_state_transitions
+    WHERE pattern = 'type == qa-pass'
+        AND capability_name = 'std_calibration'
+    """
+    fail_version_sql = """
+    INSERT INTO capability_state_actions (transition_id, action_type, arguments)
+    SELECT transition_id, 'SendMessage', 'execution_failed'
+    FROM capability_state_transitions
+    WHERE pattern = 'type == qa-fail'
+        AND capability_name = 'std_calibration'
+    """
+    op.execute(complete_version_sql)
+    op.execute(fail_version_sql)
+
+
+def downgrade():
+    delete_complete_sql = """
+    DELETE FROM capability_state_actions
+    WHERE action_type = 'SendMessage'
+        AND arguments = 'execution_complete'
+        AND transition_id = (SELECT transition_id
+            FROM capability_state_transitions
+            WHERE pattern = 'type == qa-pass'
+                AND capability_name = 'std_calibration'
+    )
+    """
+    delete_failed_sql = """
+    DELETE FROM capability_state_actions
+    WHERE action_type = 'SendMessage'
+        AND arguments = 'execution_failed'
+        AND transition_id = (SELECT transition_id
+            FROM capability_state_transitions
+            WHERE pattern = 'type == qa-fail'
+                AND capability_name = 'std_calibration'
+    )
+    """
+    op.execute(delete_complete_sql)
+    op.execute(delete_failed_sql)
diff --git a/shared/workspaces/workspaces/capability/schema.py b/shared/workspaces/workspaces/capability/schema.py
index f845d161c..6ea49c30b 100644
--- a/shared/workspaces/workspaces/capability/schema.py
+++ b/shared/workspaces/workspaces/capability/schema.py
@@ -480,24 +480,21 @@ class CapabilityRequest(Base, JSONSerializable):
         - If all versions are created, the request is created
         - Otherwise, it is submitted
         """
-        logger.info("Determine request state...")
         version_states = [version.state for version in self.versions]
 
-        if self.current_version.state == CapabilityVersionState.Complete.name:
-            # The current version is complete, so the request is complete
-            logger.info("Current version is complete. Setting request to Complete.")
-            self.state = CapabilityRequestState.Complete.name
-        elif all(state == CapabilityRequestState.Failed.name for state in version_states):
-            # Request has all failed versions, so it is failed
-            logger.info("All versions are failed. Setting request to Failed.")
-            self.state = CapabilityRequestState.Failed.name
-        elif all(state == CapabilityRequestState.Created.name for state in version_states):
-            # Request has no submitted versions, so it is still in the created state
-            logger.info("All versions are created. Setting request to Created.")
-            self.state = CapabilityRequestState.Created.name
-        else:
-            logger.info("Versions are in a mixture of states. Setting request to Submitted.")
-            self.state = CapabilityRequestState.Submitted.name
+        # Check that the request has versions to base state off of
+        if len(version_states):
+            if self.current_version.state == CapabilityVersionState.Complete.name:
+                # The current version is complete, so the request is complete
+                self.state = CapabilityRequestState.Complete.name
+            elif all(state == CapabilityRequestState.Failed.name for state in version_states):
+                # Request has all failed versions, so it is failed
+                self.state = CapabilityRequestState.Failed.name
+            elif all(state == CapabilityRequestState.Created.name for state in version_states):
+                # Request has no submitted versions, so it is still in the created state
+                self.state = CapabilityRequestState.Created.name
+            else:
+                self.state = CapabilityRequestState.Submitted.name
 
     def __str__(self):
         return f"CapabilityRequest object: {self.__dict__}"
@@ -520,6 +517,9 @@ class CapabilityRequest(Base, JSONSerializable):
 
     # Pyramid support method: must accept a "request" argument that is unused by us
     def __json__(self, request=None) -> dict:
+        # Calculate state to ensure it's up to date
+        self.determine_state()
+
         return {
             "type": self.__class__.__name__,
             "id": self.id,
-- 
GitLab