From 5e1b2bac82b6940f4f8449112652e47900fdb738 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Gaya?= <sebastien.gaya@gmail.com>
Date: Thu, 27 Jan 2022 01:33:40 +0100
Subject: [PATCH] program role

---
 .../program/role/people_controller.rb         | 49 ++++++++++++-------
 .../education/program/roles_controller.rb     | 16 +++---
 .../school/role/people_controller.rb          | 12 +++--
 .../education/school/roles_controller.rb      |  2 +-
 app/models/education/program.rb               | 12 +++++
 .../program/role/people/_form.html.erb        | 23 +++++++++
 .../program/role/people/_list.html.erb        | 25 +++++-----
 .../program/role/people/edit.html.erb         |  3 ++
 .../program/role/people/new.html.erb          | 20 +-------
 .../education/program/roles/_form.html.erb    | 20 ++++----
 .../education/program/roles/_list.html.erb    |  6 +--
 .../education/program/roles/new.html.erb      |  2 +-
 .../education/program/roles/show.html.erb     | 32 +-----------
 .../admin/education/programs/show.html.erb    |  2 +-
 .../school/role/people/_form.html.erb         |  2 +-
 .../education/school/roles/_form.html.erb     |  4 +-
 config/locales/university/en.yml              |  3 ++
 config/locales/university/fr.yml              |  3 ++
 config/routes/admin/education.rb              |  2 +-
 19 files changed, 129 insertions(+), 109 deletions(-)
 create mode 100644 app/views/admin/education/program/role/people/_form.html.erb
 create mode 100644 app/views/admin/education/program/role/people/edit.html.erb

diff --git a/app/controllers/admin/education/program/role/people_controller.rb b/app/controllers/admin/education/program/role/people_controller.rb
index 0369f528d..8a606f4dc 100644
--- a/app/controllers/admin/education/program/role/people_controller.rb
+++ b/app/controllers/admin/education/program/role/people_controller.rb
@@ -1,51 +1,62 @@
 class Admin::Education::Program::Role::PeopleController < Admin::Education::Program::ApplicationController
-  load_and_authorize_resource :role, class: Education::Program::Role, through: :program
-  load_and_authorize_resource class: Education::Program::Role::Person, through: :role
+  load_and_authorize_resource :role, class: University::Role, through: :program, param: :role_id, through_association: :university_roles
+  load_and_authorize_resource :involvement, class: University::Person::Involvement, through: :role, parent: false
 
   before_action :get_available_people, except: :destroy
 
-  include Admin::Reorderable
-
-  def reorder
-    super { |first_person| first_person.sync_program }
+  def new
+    breadcrumb
   end
 
-  def new
+  def edit
     breadcrumb
+    add_breadcrumb t('edit')
   end
 
   def create
-    if @person.save
-      redirect_to admin_education_program_role_path(@role), notice: t('admin.successfully_created_html', model: @person.to_s)
+    if @involvement.save
+      redirect_to admin_education_program_role_path(@role, { program_id: @program.id }), notice: t('admin.successfully_created_html', model: @person.to_s)
     else
       breadcrumb
       render :new, status: :unprocessable_entity
     end
   end
 
+  def update
+    if @involvement.update(involvement_params)
+      redirect_to admin_education_program_role_path(@role, { program_id: @program.id }), notice: t('admin.successfully_updated_html', model: @involvement.to_s)
+    else
+      breadcrumb
+      render :edit, status: :unprocessable_entity
+      add_breadcrumb t('edit')
+    end
+  end
+
   def destroy
-    @person.destroy
-    redirect_to admin_education_program_role_path(@role), notice: t('admin.successfully_destroyed_html', model: @person.to_s)
+    @involvement.destroy
+    redirect_to admin_education_program_role_path(@role, { program_id: @program.id }), notice: t('admin.successfully_destroyed_html', model: @person.to_s)
   end
 
   protected
 
   def get_available_people
-    used_person_ids = @role.people.where.not(id: @person.id).pluck(:person_id)
+    used_person_ids = @role.involvements.where.not(id: @involvement.id).pluck(:person_id)
     @available_people = current_university.people.where.not(id: used_person_ids).accessible_by(current_ability).ordered
   end
 
   def breadcrumb
     super
     add_breadcrumb Education::Program::Role.model_name.human(count: 2)
-    breadcrumb_for @role
-    add_breadcrumb Education::Program::Role::Person.model_name.human(count: 2)
-    breadcrumb_for @person
+    add_breadcrumb(@role, admin_education_program_role_path(@role, { program_id: @program.id }))
+    if @involvement
+      @involvement.persisted?  ? add_breadcrumb(@involvement, admin_education_program_role_person_path(@involvement, { program_id: @program.id, role_id: @role.id }))
+                               : add_breadcrumb(t('create'))
+    end
   end
 
-  def person_params
-    params.require(:education_program_role_person)
-          .permit(:person_id)
-          .merge(role_id: @role.id)
+  def involvement_params
+    params.require(:university_person_involvement)
+          .permit(:description, :position, :person_id)
+          .merge(university_id: @program.university_id, kind: :administrator)
   end
 end
diff --git a/app/controllers/admin/education/program/roles_controller.rb b/app/controllers/admin/education/program/roles_controller.rb
index edf300d53..48b07bba4 100644
--- a/app/controllers/admin/education/program/roles_controller.rb
+++ b/app/controllers/admin/education/program/roles_controller.rb
@@ -1,5 +1,5 @@
 class Admin::Education::Program::RolesController < Admin::Education::Program::ApplicationController
-  load_and_authorize_resource class: Education::Program::Role, through: :program
+  load_and_authorize_resource class: University::Role, through: :program, through_association: :university_roles
 
   include Admin::Reorderable
 
@@ -8,6 +8,7 @@ class Admin::Education::Program::RolesController < Admin::Education::Program::Ap
   end
 
   def show
+    @involvements = @role.involvements.ordered
     breadcrumb
   end
 
@@ -48,13 +49,16 @@ class Admin::Education::Program::RolesController < Admin::Education::Program::Ap
 
   def breadcrumb
     super
-    add_breadcrumb Education::Program::Role.model_name.human(count: 2)
-    breadcrumb_for @role
+    add_breadcrumb University::Role.model_name.human(count: 2)
+    if @role
+      @role.persisted?  ? add_breadcrumb(@role, admin_education_program_role_path(@role, { program_id: @program.id }))
+                        : add_breadcrumb(t('create'))
+    end
   end
 
   def role_params
-    params.require(:education_program_role)
-          .permit(:title)
-          .merge(program_id: @program.id, university_id: current_university.id)
+    params.require(:university_role)
+          .permit(:description, :position)
+          .merge(target: @program, university_id: current_university.id)
   end
 end
diff --git a/app/controllers/admin/education/school/role/people_controller.rb b/app/controllers/admin/education/school/role/people_controller.rb
index d1929ee37..c1747a9dc 100644
--- a/app/controllers/admin/education/school/role/people_controller.rb
+++ b/app/controllers/admin/education/school/role/people_controller.rb
@@ -2,6 +2,8 @@ class Admin::Education::School::Role::PeopleController < Admin::Education::Schoo
   load_and_authorize_resource :role, class: University::Role, through: :school, param: :role_id, through_association: :university_roles
   load_and_authorize_resource :involvement, class: University::Person::Involvement, through: :role, parent: false
 
+  before_action :get_available_people, except: :destroy
+
   def new
     breadcrumb
   end
@@ -37,11 +39,15 @@ class Admin::Education::School::Role::PeopleController < Admin::Education::Schoo
 
   protected
 
+  def get_available_people
+    used_person_ids = @role.involvements.where.not(id: @involvement.id).pluck(:person_id)
+    @available_people = current_university.people.administrator.where.not(id: used_person_ids).accessible_by(current_ability).ordered
+  end
+
   def breadcrumb
     super
     add_breadcrumb University::Role.model_name.human(count: 2), admin_education_school_roles_path(@school)
-    @role.persisted?  ? add_breadcrumb(@role, admin_education_school_role_path(@role, { school_id: @school.id }))
-                      : add_breadcrumb(t('create'))
+    add_breadcrumb(@role, admin_education_school_role_path(@role, { school_id: @school.id }))
     if @involvement
       @involvement.persisted?  ? add_breadcrumb(@involvement, admin_education_school_role_person_path(@involvement, { school_id: @school.id, role_id: @role.id }))
                                : add_breadcrumb(t('create'))
@@ -51,6 +57,6 @@ class Admin::Education::School::Role::PeopleController < Admin::Education::Schoo
   def involvement_params
     params.require(:university_person_involvement)
           .permit(:description, :position, :person_id)
-          .merge(university_id: @school.university_id)
+          .merge(university_id: @school.university_id, kind: :administrator)
   end
 end
diff --git a/app/controllers/admin/education/school/roles_controller.rb b/app/controllers/admin/education/school/roles_controller.rb
index f795f26cc..6e0633b1b 100644
--- a/app/controllers/admin/education/school/roles_controller.rb
+++ b/app/controllers/admin/education/school/roles_controller.rb
@@ -40,7 +40,7 @@ class Admin::Education::School::RolesController < Admin::Education::School::Appl
 
   def destroy
     @role.destroy
-    redirect_to admin_education_school_role_path(@role), notice: t('admin.successfully_destroyed_html', model: @role.to_s)
+    redirect_to admin_education_school_roles_path(@school), notice: t('admin.successfully_destroyed_html', model: @role.to_s)
   end
 
   protected
diff --git a/app/models/education/program.rb b/app/models/education/program.rb
index c4c75482b..735de5888 100644
--- a/app/models/education/program.rb
+++ b/app/models/education/program.rb
@@ -78,6 +78,18 @@ class Education::Program < ApplicationRecord
   has_many   :university_people_through_roles,
              through: :role_people,
              source: :person
+  has_many   :university_roles,
+             class_name: 'University::Role',
+             as: :target,
+             dependent: :destroy
+  has_many   :involvements_through_roles,
+             class_name: 'University::Person::Involvement',
+             through: :university_roles,
+             source: :involvements
+  has_many   :university_person_involvements,
+             class_name: 'University::Person::Involvement',
+             as: :target,
+             dependent: :destroy
   has_many   :website_categories,
              class_name: 'Communication::Website::Category',
              dependent: :destroy
diff --git a/app/views/admin/education/program/role/people/_form.html.erb b/app/views/admin/education/program/role/people/_form.html.erb
new file mode 100644
index 000000000..182e8e207
--- /dev/null
+++ b/app/views/admin/education/program/role/people/_form.html.erb
@@ -0,0 +1,23 @@
+<%= simple_form_for [:admin, involvement],
+                    url: involvement.new_record? ? admin_education_program_role_people_path(@role, { program_id: @program.id })
+                                                 : admin_education_program_role_person_path(involvement, { program_id: @program.id, role_id: @role.id }) do |f| %>
+  <div class="card flex-fill w-100">
+    <div class="card-header">
+      <h5 class="card-title mb-0"><%= t('admin.infos') %></h5>
+    </div>
+    <div class="card-body">
+      <div class="row">
+        <div class="col-md-6">
+          <% used_person_ids = @role.involvements.where.not(id: involvement.id).pluck(:person_id) %>
+          <%= f.association :person, collection: @available_people %>
+        </div>
+        <div class="col-md-6">
+          <%= f.input :description %>
+        </div>
+      </div>
+    </div>
+  </div>
+  <% content_for :action_bar_right do %>
+    <%= submit f %>
+  <% end %>
+<% end %>
diff --git a/app/views/admin/education/program/role/people/_list.html.erb b/app/views/admin/education/program/role/people/_list.html.erb
index fc31ddd11..e9995a524 100644
--- a/app/views/admin/education/program/role/people/_list.html.erb
+++ b/app/views/admin/education/program/role/people/_list.html.erb
@@ -1,26 +1,29 @@
-<% if people.any? %>
+<% if involvements.any? %>
   <table class="table table-sortable">
     <thead>
       <tr>
-        <th><%= Education::Program::Role::Person.model_name.human %></th>
+        <th class="ps-0"><%= University::Person.model_name.human %></th>
+        <th><%= University::Person::Involvement.human_attribute_name("description") %></th>
         <th></th>
       </tr>
     </thead>
-    <tbody data-reorder-url="<%= reorder_admin_education_program_role_people_path(program_id: @program.id, role_id: @role.id) %>">
-      <% people.each do |person| %>
-        <tr class="handle" data-id="<%= person.id %>">
-          <td>
-            <%= link_to_if  can?(:read, person.person),
-                            person.person,
-                            admin_university_person_path(person.person) %>
+    <tbody data-reorder-url="<%= reorder_admin_education_program_role_people_path(@role, { program_id: @program.id }) %>">
+      <% involvements.each do |involvement| %>
+        <tr class="handle" data-id="<%= involvement.id %>">
+          <td class="ps-0">
+            <%= involvement %>
           </td>
+          <td><%= involvement.description %></td>
           <td class="text-end pe-0">
             <div class="btn-group" role="group">
+              <%= link_to t('edit'),
+                          edit_admin_education_program_role_person_path(involvement, { program_id: @program.id, role_id: @role.id }),
+                          class: button_classes if can?(:edit, involvement) %>
               <%= link_to t('delete'),
-                          admin_education_program_role_person_path(person, { role_id: @role.id }),
+                          admin_education_program_role_person_path(involvement, { program_id: @program.id, role_id: @role.id }),
                           method: :delete,
                           data: { confirm: t('please_confirm') },
-                          class: button_classes_danger %>
+                          class: button_classes_danger if can?(:destroy, involvement) %>
             </div>
           </td>
         </tr>
diff --git a/app/views/admin/education/program/role/people/edit.html.erb b/app/views/admin/education/program/role/people/edit.html.erb
new file mode 100644
index 000000000..da924cd05
--- /dev/null
+++ b/app/views/admin/education/program/role/people/edit.html.erb
@@ -0,0 +1,3 @@
+<% content_for :title, @involvement %>
+
+<%= render 'form', involvement: @involvement %>
diff --git a/app/views/admin/education/program/role/people/new.html.erb b/app/views/admin/education/program/role/people/new.html.erb
index d2a7ac697..f07ff39c1 100644
--- a/app/views/admin/education/program/role/people/new.html.erb
+++ b/app/views/admin/education/program/role/people/new.html.erb
@@ -1,19 +1,3 @@
-<% content_for :title, Education::Program::Role::Person.model_name.human %>
+<% content_for :title, University::Person.model_name.human %>
 
-<%= simple_form_for [:admin, @person] do |f| %>
-  <div class="row">
-    <div class="col-md-8">
-      <div class="card flex-fill w-100">
-        <div class="card-header">
-          <h5 class="card-title mb-0"><%= t('admin.infos') %></h5>
-        </div>
-        <div class="card-body">
-          <%= f.association :person, collection: @available_people %>
-        </div>
-      </div>
-    </div>
-  </div>
-  <% content_for :action_bar_right do %>
-    <%= submit f %>
-  <% end %>
-<% end %>
+<%= render 'form', involvement: @involvement %>
diff --git a/app/views/admin/education/program/roles/_form.html.erb b/app/views/admin/education/program/roles/_form.html.erb
index 26ccb783e..0515ed3c5 100644
--- a/app/views/admin/education/program/roles/_form.html.erb
+++ b/app/views/admin/education/program/roles/_form.html.erb
@@ -1,14 +1,12 @@
-<%= simple_form_for [:admin, role] do |f| %>
-  <div class="row">
-    <div class="col-md-8">
-      <div class="card flex-fill w-100">
-        <div class="card-header">
-          <h5 class="card-title mb-0"><%= t('admin.infos') %></h5>
-        </div>
-        <div class="card-body">
-          <%= f.input :title %>
-        </div>
-      </div>
+<%= simple_form_for [:admin, role],
+                    url: role.new_record? ? admin_education_program_roles_path(@program)
+                                          : admin_education_program_role_path(role, { program_id: @program.id }) do |f| %>
+  <div class="card flex-fill w-100">
+    <div class="card-header">
+      <h5 class="card-title mb-0"><%= t('admin.infos') %></h5>
+    </div>
+    <div class="card-body">
+      <%= f.input :description %>
     </div>
   </div>
   <% content_for :action_bar_right do %>
diff --git a/app/views/admin/education/program/roles/_list.html.erb b/app/views/admin/education/program/roles/_list.html.erb
index c4465b657..ad85ad92c 100644
--- a/app/views/admin/education/program/roles/_list.html.erb
+++ b/app/views/admin/education/program/roles/_list.html.erb
@@ -2,8 +2,8 @@
   <table class="table table-sortable">
     <thead>
       <tr>
-        <th class="ps-0"><%= Education::Program::Role.model_name.human %></th>
-        <th><%= Education::Program::Role.human_attribute_name('people') %></th>
+        <th class="ps-0"><%= University::Role.model_name.human %></th>
+        <th><%= University::Role.human_attribute_name('people') %></th>
         <th></th>
       </tr>
     </thead>
@@ -15,7 +15,7 @@
                             role,
                             admin_education_program_role_path(role, { program_id: @program.id }) %>
           </td>
-          <td><%= role.people.includes(:person).ordered.map { |person| person.person.to_s }.to_sentence %></td>
+          <td><%= role.involvements.includes(:person).ordered.map { |involvement| involvement.person.to_s }.to_sentence %></td>
           <td class="text-end pe-0">
             <div class="btn-group" role="group">
               <%= link_to t('edit'),
diff --git a/app/views/admin/education/program/roles/new.html.erb b/app/views/admin/education/program/roles/new.html.erb
index 1bad6fa6b..1e11d9157 100644
--- a/app/views/admin/education/program/roles/new.html.erb
+++ b/app/views/admin/education/program/roles/new.html.erb
@@ -1,3 +1,3 @@
-<% content_for :title, Education::Program::Role.model_name.human %>
+<% content_for :title, University::Role.model_name.human %>
 
 <%= render 'form', role: @role %>
diff --git a/app/views/admin/education/program/roles/show.html.erb b/app/views/admin/education/program/roles/show.html.erb
index 09d1438ba..f68d81188 100644
--- a/app/views/admin/education/program/roles/show.html.erb
+++ b/app/views/admin/education/program/roles/show.html.erb
@@ -1,32 +1,4 @@
 <% content_for :title, @role %>
 
-<div class="row">
-  <div class="col-md-4">
-    <div class="card flex-fill w-100">
-      <div class="card-header">
-        <h2 class="card-title mb-0 h5"><%= t('admin.infos') %></h2>
-      </div>
-      <div class="card-body">
-        <h3 class="h5"><%= Education::Program::Role.human_attribute_name('title') %></h3>
-        <%= @role.title %>
-      </div>
-    </div>
-  </div>
-  <div class="col-md-8">
-    <div class="card flex-fill w-100">
-      <div class="card-header">
-        <h2 class="card-title mb-0 h5"><%= Education::Program::Role.human_attribute_name('people') %></h2>
-      </div>
-      <div class="card-body">
-        <%= render 'admin/education/program/role/people/list', people: @role.people.includes(:person).ordered %>
-        <% if can? :create, Education::Program::Role::Person %>
-          <p><%= link_to t('create'), new_admin_education_program_role_person_path(role_id: @role.id), class: 'btn btn-primary' %></p>
-        <% end %>
-      </div>
-    </div>
-  </div>
-</div>
-
-<% content_for :action_bar_right do %>
-  <%= edit_link @role %>
-<% end %>
+<%= link_to t('create'), new_admin_education_program_role_person_path(program_id: @program.id, role_id: @role.id), class: button_classes %>
+<%= render 'admin/education/program/role/people/list', involvements: @involvements %>
diff --git a/app/views/admin/education/programs/show.html.erb b/app/views/admin/education/programs/show.html.erb
index 4ebd03b90..5ce85ad22 100644
--- a/app/views/admin/education/programs/show.html.erb
+++ b/app/views/admin/education/programs/show.html.erb
@@ -122,7 +122,7 @@
     <div class="row">
       <div class="col-md-6">
         <h3 class="h5"><%= Education::Program.human_attribute_name('roles') %></h3>
-        <%= render 'admin/education/program/roles/list', roles: @program.roles.ordered %>
+        <%= render 'admin/education/program/roles/list', roles: @program.university_roles.ordered %>
         <%= link_to t('create'), new_admin_education_program_role_path(program_id: @program.id), class: button_classes if can?(:create, Education::Program::Role) %>
       </div>
       <div class="col-md-6">
diff --git a/app/views/admin/education/school/role/people/_form.html.erb b/app/views/admin/education/school/role/people/_form.html.erb
index 81fb739c7..2f982edeb 100644
--- a/app/views/admin/education/school/role/people/_form.html.erb
+++ b/app/views/admin/education/school/role/people/_form.html.erb
@@ -9,7 +9,7 @@
       <div class="row">
         <div class="col-md-6">
           <% used_person_ids = @role.involvements.where.not(id: involvement.id).pluck(:person_id) %>
-          <%= f.association :person, collection: current_university.people.administration.where.not(id: used_person_ids).ordered %>
+          <%= f.association :person, collection: @available_people %>
         </div>
         <div class="col-md-6">
           <%= f.input :description %>
diff --git a/app/views/admin/education/school/roles/_form.html.erb b/app/views/admin/education/school/roles/_form.html.erb
index f09aa1ee3..24b66befe 100644
--- a/app/views/admin/education/school/roles/_form.html.erb
+++ b/app/views/admin/education/school/roles/_form.html.erb
@@ -6,9 +6,7 @@
       <h5 class="card-title mb-0"><%= t('admin.infos') %></h5>
     </div>
     <div class="card-body">
-      <div class="row">
-        <%= f.input :description %>
-      </div>
+      <%= f.input :description %>
     </div>
   </div>
   <% content_for :action_bar_right do %>
diff --git a/config/locales/university/en.yml b/config/locales/university/en.yml
index 6d8df213d..7a266ed3c 100644
--- a/config/locales/university/en.yml
+++ b/config/locales/university/en.yml
@@ -35,6 +35,9 @@ en:
         slug: Slug
         tenure: Have tenure?
         user: User
+      university/role:
+        description: Description
+        people: People
     models:
       university:
         one: University
diff --git a/config/locales/university/fr.yml b/config/locales/university/fr.yml
index a47bf3c9b..bee1ae6c4 100644
--- a/config/locales/university/fr.yml
+++ b/config/locales/university/fr.yml
@@ -35,6 +35,9 @@ fr:
         slug: Slug
         tenure: Titulaire ?
         user: Utilisateur
+      university/role:
+        description: Description
+        people: Personnes
     models:
       university:
         one: Université
diff --git a/config/routes/admin/education.rb b/config/routes/admin/education.rb
index 125c44a9e..59bfe5170 100644
--- a/config/routes/admin/education.rb
+++ b/config/routes/admin/education.rb
@@ -15,7 +15,7 @@ namespace :education do
   end
   resources :programs do
     resources :roles, controller: 'program/roles', except: :index do
-      resources :people, controller: 'program/role/people', except: [:index, :show, :edit, :update] do
+      resources :people, controller: 'program/role/people', except: [:index, :show] do
         collection do
           post :reorder
         end
-- 
GitLab