From 1a4c3c7bea30207f02b7c3a528f4511b1ae12e94 Mon Sep 17 00:00:00 2001
From: Renats <r.jursevskis@student.tudelft.nl>
Date: Thu, 28 Jul 2022 01:35:23 +0300
Subject: [PATCH] Add option to apply changes to instances of a recurrent
 edition

---
 .../concerns/params_concerns/projects.rb      |  1 +
 .../generic_projects_controller.rb            | 50 +++++++++++++------
 app/views/generic_projects/_form.html.erb     | 16 ++++++
 3 files changed, 52 insertions(+), 15 deletions(-)

diff --git a/app/controllers/concerns/params_concerns/projects.rb b/app/controllers/concerns/params_concerns/projects.rb
index 4a07dc01c..af2ac7f1b 100644
--- a/app/controllers/concerns/params_concerns/projects.rb
+++ b/app/controllers/concerns/params_concerns/projects.rb
@@ -10,6 +10,7 @@ module ParamsConcerns
             :offerer_id,
             :course_edition_id,
             :company_contact,
+            :projects_modify,
             { period_ids: [] },
             { tag_ids: [] }].freeze
 
diff --git a/app/controllers/generic_projects_controller.rb b/app/controllers/generic_projects_controller.rb
index dcf4128ae..54f21803f 100644
--- a/app/controllers/generic_projects_controller.rb
+++ b/app/controllers/generic_projects_controller.rb
@@ -151,23 +151,23 @@ class GenericProjectsController < ProjectsController
   end
 
   def update
-    @project = @specific_project.acting_as
-    edition = @project.course_edition
-    role_hash = create_role_hash(edition)
-
-    begin
-      fill_role_assignments(role_hash, params[:generic_project])
-    rescue ArgumentError => e
-      flash[:danger] = e.message
-      render 'edit'
-      return
+    main_specific_project = @specific_project
+    @role_creation_failed = false
+
+    # If recurrent course edition, also apply update to each selected project
+    if @specific_project.course_edition.recurrent
+      Project.where(id: params[:generic_project][:projects_modify]).each do |project|
+        unless apply_update project.specific
+          render 'edit'
+          return
+        end
+      end
     end
 
-    if update_project(project_update_params)
-      # assign course-specific roles
-      role_creation_failed = assign_course_specific_roles(role_hash)
-
-      if role_creation_failed
+    @specific_project = main_specific_project
+    @project = @specific_project.acting_as
+    if apply_update main_specific_project
+      if @role_creation_failed
         flash[:danger] = I18n.t 'activerecord.flashes.project.updated.role_failed'
       end
 
@@ -185,6 +185,26 @@ class GenericProjectsController < ProjectsController
 
   protected
 
+  def apply_update(specific_project)
+    @specific_project = specific_project
+    @project = @specific_project.acting_as
+    role_hash = create_role_hash(@project.course_edition)
+
+    begin
+      fill_role_assignments(role_hash, params[:generic_project])
+    rescue ArgumentError => e
+      flash[:danger] = e.message
+      return false
+    end
+
+    if update_project(project_update_params)
+      @role_creation_failed |= assign_course_specific_roles(role_hash)
+      true
+    else
+      false
+    end
+  end
+
   def page_title
     case action_name
     when 'show', 'edit'
diff --git a/app/views/generic_projects/_form.html.erb b/app/views/generic_projects/_form.html.erb
index d5d0db984..bfe107e43 100644
--- a/app/views/generic_projects/_form.html.erb
+++ b/app/views/generic_projects/_form.html.erb
@@ -1,4 +1,20 @@
 <%= bootstrap_form_with model: @specific_project do |f| %>
+
+  <% if !f.object.new_record? && @specific_project.course_edition.recurrent %>
+    <div class="alert alert-warning">
+      <strong><%= 'You are currently modifying the recurrent version of this project!' %></strong>
+      <br/>
+      <br/>
+      <%= 'If you want the changes to also apply to current instances of the project, you can select them here:' %>
+      <%= f.collection_select :projects_modify,
+                              Project.where(course_edition: CourseEdition.where(recurrent_edition_id: @specific_project.course_edition.id), original_project_id: @project.id),
+                              :id,
+                              ->(project) { "#{project.name} (#{project.course_edition.display_name})" },
+                              { required: false, hide_label: true },
+                              multiple: true, class: 'selectize' %>
+    </div>
+  <% end %>
+
   <% no_courses = @possible_course_editions.nil? || @possible_course_editions.none? %>
   <% disable_form = f.object.new_record? && no_courses %>
 
-- 
GitLab