From e5f870fac196cdd4c65933d9e10bf68ce28b9735 Mon Sep 17 00:00:00 2001 From: Andrej Date: Wed, 30 Jul 2025 09:48:35 +0200 Subject: [PATCH] Add automation for steps completed on task [SCI-12076] --- app/models/concerns/observable_model.rb | 15 ++++++++++ app/models/step.rb | 5 ++++ .../all_checked_steps_automation_observer.rb | 30 +++++++++++++++++++ config/initializers/extends.rb | 8 +++-- config/locales/en.yml | 2 ++ config/locales/global_activities/en.yml | 2 ++ 6 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 app/models/concerns/observable_model.rb create mode 100644 app/services/automation_observers/all_checked_steps_automation_observer.rb diff --git a/app/models/concerns/observable_model.rb b/app/models/concerns/observable_model.rb new file mode 100644 index 000000000..2243f4518 --- /dev/null +++ b/app/models/concerns/observable_model.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module ObservableModel + extend ActiveSupport::Concern + + included do + after_update :run_observers + end + + private + + def run_observers + raise NotImplemented + end +end diff --git a/app/models/step.rb b/app/models/step.rb index 16fbcff72..7c66f94e2 100644 --- a/app/models/step.rb +++ b/app/models/step.rb @@ -3,6 +3,7 @@ class Step < ApplicationRecord include SearchableByNameModel include TinyMceImages include ViewableModel + include ObservableModel attr_accessor :skip_position_adjust # to be used in bulk deletion @@ -185,6 +186,10 @@ class Step < ApplicationRecord private + def run_observers + AutomationObservers::AllCheckedStepsAutomationObserver.new(my_module, last_modified_by).call if saved_change_to_completed? && completed + end + def duplicate_table(new_step, user, table) table.duplicate(new_step, user, table.step_table.step_orderable_element.position) end diff --git a/app/services/automation_observers/all_checked_steps_automation_observer.rb b/app/services/automation_observers/all_checked_steps_automation_observer.rb new file mode 100644 index 000000000..ce2b0cd47 --- /dev/null +++ b/app/services/automation_observers/all_checked_steps_automation_observer.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module AutomationObservers + class AllCheckedStepsAutomationObserver + def initialize(my_module, user) + @my_module = my_module + @user = user + end + + def call + return unless @my_module.team.settings.dig('team_automation_settings', 'all_my_module_steps_marked_as_completed') + return unless @my_module.my_module_status.previous_status == @my_module.my_module_status_flow.initial_status && @my_module.steps.where(completed: false).none? + + previous_status_id = @my_module.my_module_status.id + @my_module.update!(my_module_status: @my_module.my_module_status.next_status) + + Activities::CreateActivityService + .call(activity_type: :automation_task_status_changed, + owner: @user, + team: @my_module.team, + project: @my_module.project, + subject: @my_module, + message_items: { + my_module: @my_module.id, + my_module_status_old: previous_status_id, + my_module_status_new: @my_module.my_module_status.id + }) + end + end +end diff --git a/config/initializers/extends.rb b/config/initializers/extends.rb index c8ac58f51..ac5171a7d 100644 --- a/config/initializers/extends.rb +++ b/config/initializers/extends.rb @@ -617,14 +617,15 @@ class Extends repository_access_revoked_all_team_members: 402, repository_access_granted_user_group: 403, repository_access_changed_user_group: 404, - repository_access_revoked_user_group: 405 + repository_access_revoked_user_group: 405, + automation_task_status_changed: 406 } ACTIVITY_GROUPS = { projects: [*0..7, 32, 33, 34, 95, 108, 65, 109, *158..162, 241, 242, 243, *370..378, *390..392], task_results: [23, 26, 25, 42, 24, 40, 41, 99, 110, 122, 116, 128, *246..248, *257..273, *284..291, 301, 303, 306, 328], task: [8, 58, 9, 59, *10..14, 35, 36, 37, 53, 54, *60..63, 138, 139, 140, 64, 66, 106, 126, 120, 132, - 148, 166, 394, 395, 396], + 148, 166, 394, 395, 396, 406], task_protocol: [15, 22, 16, 18, 19, 20, 21, 17, 38, 39, 100, 111, 45, 46, 47, 121, 124, 115, 118, 127, 130, 137, 184, 185, 188, 189, *192..203, 221, 222, 224, 225, 226, 236, *249..252, *274..278, 299, 302, 305, 327, *347..352, 359], task_inventory: [55, 56, 146, 147, 183], @@ -805,6 +806,9 @@ class Extends protocol_content_added step_marked_as_completed task_result_added + ], + task_status_completed: %I[ + all_my_module_steps_marked_as_completed ] }, experiment_automation: { diff --git a/config/locales/en.yml b/config/locales/en.yml index 24892704d..ef14a172f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -4340,6 +4340,7 @@ en: project_automation: 'Project automations' sub_groups: task_status_in_progress: 'Automatically update task status to "In progress" when:' + task_status_completed: 'Automatically update task status to “Completed” when:' task_status_done: 'Automatically update task status to "Done" when:' experiment_status_in_progress: 'Automatically update experiment status to "In progress" when:' experiment_status_done: 'Automatically update experiment status to "Done" when:' @@ -4353,6 +4354,7 @@ en: all_tasks_done: 'All tasks inside reach their final status.' experiment_moves_from_not_started_to_in_progress: 'At least one experiment moves to "In progress" or "Done"' all_experiments_done: 'All experiments inside are marked as "Done"' + all_my_module_steps_marked_as_completed: 'All steps are marked as done' notifications: title: "Notifications" diff --git a/config/locales/global_activities/en.yml b/config/locales/global_activities/en.yml index 2303640b3..d64b981a0 100644 --- a/config/locales/global_activities/en.yml +++ b/config/locales/global_activities/en.yml @@ -421,6 +421,7 @@ en: repository_access_granted_user_group_html: "%{user} granted access to %{user_group} with user role %{role} to inventory template %{repository}." repository_access_changed_user_group_html: "%{user} changed %{user_group}'s role on inventory template %{repository} to %{role}." repository_access_revoked_user_group_html: "%{user} removed group %{user_group} with user role %{role} from inventory template %{repository}." + automation_task_status_changed_html: "%{user} triggered automatic status change from %{my_module_status_old} to %{my_module_status_new} for task %{my_module}." activity_name: create_project: "Project created" edit_project: "Project edited" @@ -797,6 +798,7 @@ en: repository_access_granted_user_group: "Grant access to group" repository_access_changed_user_group: "Change role of group" repository_access_revoked_user_group: "Remove access to group" + automation_task_status_changed: "Task status changed automatically" activity_group: projects: "Projects" task_results: "Task results"