From edbe67b999073716f5673edb5239ad6074b370e9 Mon Sep 17 00:00:00 2001 From: Arnaud Levy <contact@arnaudlevy.com> Date: Thu, 17 Mar 2022 09:16:41 +0100 Subject: [PATCH] alumnus wip --- .../admin/university/people_controller.rb | 3 +- .../university/person/alumni_controller.rb | 17 ++-- app/models/concerns/importable.rb | 36 +++++++++ .../university/person/alumnus/import.rb | 62 +++++++++++---- .../organization/imports/new.html.erb | 2 +- .../admin/university/people/_form.html.erb | 3 +- .../university/person/alumni/_list.html.erb | 18 ++++- .../university/person/alumni/show.html.erb | 1 + .../person/alumnus/imports/new.html.erb | 77 ++++++++++++++++++- .../person/alumnus/imports/show.html.erb | 17 ++-- config/locales/university/fr.yml | 4 +- 11 files changed, 194 insertions(+), 46 deletions(-) create mode 100644 app/models/concerns/importable.rb create mode 100644 app/views/admin/university/person/alumni/show.html.erb diff --git a/app/controllers/admin/university/people_controller.rb b/app/controllers/admin/university/people_controller.rb index 8babe56ea..febdd9829 100644 --- a/app/controllers/admin/university/people_controller.rb +++ b/app/controllers/admin/university/people_controller.rb @@ -64,7 +64,8 @@ class Admin::University::PeopleController < Admin::University::ApplicationContro :slug, :first_name, :last_name, :email, :phone, :description, :biography, :picture, :picture_delete, :picture_infos, :habilitation, :tenure, :url, :linkedin, :twitter, - :is_researcher, :is_teacher, :is_administration, :user_id + :is_researcher, :is_teacher, :is_administration, :is_alumnus, + :user_id ).merge(university_id: current_university.id) end end diff --git a/app/controllers/admin/university/person/alumni_controller.rb b/app/controllers/admin/university/person/alumni_controller.rb index 93d4438b7..f86a16f46 100644 --- a/app/controllers/admin/university/person/alumni_controller.rb +++ b/app/controllers/admin/university/person/alumni_controller.rb @@ -1,12 +1,12 @@ class Admin::University::Person::AlumniController < Admin::University::ApplicationController - before_action :load_alumnus, only: [:show, :edit, :update] - + load_and_authorize_resource class: University::Person::Alumnus, + through: :current_university, + through_association: :people def index - @alumni = current_university.people - .alumni - .accessible_by(current_ability) - .ordered - .page(params[:page]) + @alumni = @alumni.alumni + .accessible_by(current_ability) + .ordered + .page(params[:page]) breadcrumb end @@ -39,9 +39,6 @@ class Admin::University::Person::AlumniController < Admin::University::Applicati breadcrumb_for @alumnus end - def load_alumnus - end - def alumnus_params params.require(:university_person_alumnus) .permit() diff --git a/app/models/concerns/importable.rb b/app/models/concerns/importable.rb new file mode 100644 index 000000000..6bc569eef --- /dev/null +++ b/app/models/concerns/importable.rb @@ -0,0 +1,36 @@ +module Importable + extend ActiveSupport::Concern + + included do + belongs_to :user + + has_one_attached :file + + after_save :parse_async + end + + def lines + csv.count + rescue + 'NA' + end + + def to_s + "#{user}, #{I18n.l created_at}" + end + + protected + + def parse_async + parse + end + handle_asynchronously :parse_async, queue: 'default' + + def parse + raise NotImplementedError + end + + def csv + @csv ||= CSV.parse file.blob.download, headers: true + end +end diff --git a/app/models/university/person/alumnus/import.rb b/app/models/university/person/alumnus/import.rb index 94fcd55e8..6b31c5dfe 100644 --- a/app/models/university/person/alumnus/import.rb +++ b/app/models/university/person/alumnus/import.rb @@ -1,28 +1,58 @@ class University::Person::Alumnus::Import < ApplicationRecord include WithUniversity - - belongs_to :user - - has_one_attached :file - - after_save :parse + include Importable def self.table_name 'university_person_alumnus_imports' end - def lines - csv.count - rescue - 'NA' - end - - def to_s - "#{user}, #{I18n.l created_at}" - end - protected def parse + csv.each do |row| + # program + # year + # first_name + # last_name + # gender + # birth + # mail + # photo + # url + # phonepro + # phoneperso + # mobile + # address + # zipcode + # city + # country + # status + # socialtwitter + # sociallinkedin + row['program'] = '23279cab-8bc1-4c75-bcd8-1fccaa03ad55' #TMP local fix + program = university.education_programs + .find_by(id: row['program']) + next if program.nil? + year = university.academic_years + .where(year: row['year']) + .first_or_create + if row['mail'].blank? + person = university.people + .where(first_name: row['first_name'], last_name: row['last_name']) + .first_or_create + else + person = university.people + .where(email: row['mail']) + .first_or_create + person.first_name = row['first_name'] + person.last_name = row['last_name'] + end + # TODO all fields + person.is_alumnus = true + person.url = row['url'] + person.slug = person.to_s.parameterize + person.save + # byebug + end end end diff --git a/app/views/admin/university/organization/imports/new.html.erb b/app/views/admin/university/organization/imports/new.html.erb index d69bc7b28..fcf325f6f 100644 --- a/app/views/admin/university/organization/imports/new.html.erb +++ b/app/views/admin/university/organization/imports/new.html.erb @@ -5,8 +5,8 @@ <p> Les données doivent être au format csv, comme l'exemple suivant.<br> La première ligne doit être dédiée aux entêtes.<br> + Les noms des entêtes sont obligatoires et doivent être respectés strictement.<br> Le champ name est obligatoire.<br> - Les noms des entêtes sont indicatifs, l'import est basé sur la position des champs.<br> Les caractères doivent être encodés en UTF-8.<br> Les valeurs possibles pour kind sont : company, non_profit, government. </p> diff --git a/app/views/admin/university/people/_form.html.erb b/app/views/admin/university/people/_form.html.erb index 21eb1486a..f2a1bd72a 100644 --- a/app/views/admin/university/people/_form.html.erb +++ b/app/views/admin/university/people/_form.html.erb @@ -51,9 +51,10 @@ <div class="col-md-6"> <%= f.input :is_teacher %> <%= f.input :is_administration %> - <%= f.input :tenure %> + <%= f.input :is_alumnus %> </div> <div class="col-md-6"> + <%= f.input :tenure %> <%= f.input :is_researcher %> <%= f.input :habilitation %> </div> diff --git a/app/views/admin/university/person/alumni/_list.html.erb b/app/views/admin/university/person/alumni/_list.html.erb index 8af5512e6..0d3945bd5 100644 --- a/app/views/admin/university/person/alumni/_list.html.erb +++ b/app/views/admin/university/person/alumni/_list.html.erb @@ -3,13 +3,27 @@ <tr> <th><%= University::Person.human_attribute_name('last_name') %></th> <th><%= University::Person.human_attribute_name('first_name') %></th> + <th></th> </tr> </thead> <tbody> <% alumni.each do |alumnus| %> + <% path = admin_university_person_alumnus_path(alumnus) %> <tr> - <td><%= link_to alumnus.last_name, admin_university_alumnus_path(alumnus) %></td> - <td><%= link_to alumnus.first_name, admin_university_alumnus_path(alumnus) %></td> + <td><%= link_to alumnus.last_name, path %></td> + <td><%= link_to alumnus.first_name, path %></td> + <td class="text-end"> + <div class="btn-group" role="group"> + <%= link_to t('edit'), + edit_admin_university_person_alumnus_path(alumnus), + class: button_classes if can?(:update, alumnus) %> + <%= link_to t('delete'), + path, + method: :delete, + data: { confirm: t('please_confirm') }, + class: button_classes_danger if can?(:destroy, alumnus) %> + </div> + </td> </tr> <% end %> </tbody> diff --git a/app/views/admin/university/person/alumni/show.html.erb b/app/views/admin/university/person/alumni/show.html.erb new file mode 100644 index 000000000..a82ea88ff --- /dev/null +++ b/app/views/admin/university/person/alumni/show.html.erb @@ -0,0 +1 @@ +<% content_for :title, @alumnus %> diff --git a/app/views/admin/university/person/alumnus/imports/new.html.erb b/app/views/admin/university/person/alumnus/imports/new.html.erb index 89b51d4e8..e63db9d06 100644 --- a/app/views/admin/university/person/alumnus/imports/new.html.erb +++ b/app/views/admin/university/person/alumnus/imports/new.html.erb @@ -5,9 +5,10 @@ <p> Les données doivent être au format csv, comme l'exemple suivant.<br> La première ligne doit être dédiée aux entêtes.<br> - Le champ name est obligatoire.<br> - Les noms des entêtes sont indicatifs, l'import est basé sur la position des champs.<br> + Les noms des entêtes sont obligatoires et doivent être respectés strictement.<br> + Les champs marqués d'une astérisque sont obligatoires.<br> Les caractères doivent être encodés en UTF-8. + Les valeurs pour gender peuvent être m (masculin), m (féminin) et n (non binaire). </p> <%= simple_form_for [:admin, @import] do |f| %> <%= f.input :file %> @@ -24,6 +25,78 @@ <th>program*</th> <td>c6b78fac-0a5f-4c44-ad22-4ee68ed382bb</td> </tr> + <tr> + <th>year*</th> + <td>2022</td> + </tr> + <tr> + <th>first_name*</th> + <td>Stéphane</td> + </tr> + <tr> + <th>last_name*</th> + <td>Dupond</td> + </tr> + <tr> + <th>gender</th> + <td>m</td> + </tr> + <tr> + <th>birth</th> + <td>2006-05-26</td> + </tr> + <tr> + <th>mail</th> + <td>jean.dupont@gmail.com</td> + </tr> + <tr> + <th>photo</th> + <td>https://www.example.com/photo.jpg</td> + </tr> + <tr> + <th>url</th> + <td>https://www.stephanedupond.fr</td> + </tr> + <tr> + <th>phonepro</th> + <td>+33 1 01 01 01 01</td> + </tr> + <tr> + <th>phoneperso</th> + <td>+33 1 01 01 01 01</td> + </tr> + <tr> + <th>mobile</th> + <td>+33 6 01 01 01 01</td> + </tr> + <tr> + <th>address</th> + <td>1 rue Jacques Ellul</td> + </tr> + <tr> + <th>zipcode</th> + <td>33000</td> + </tr> + <tr> + <th>city</th> + <td>Bordeaux</td> + </tr> + <tr> + <th>country</th> + <td>FR</td> + </tr> + <tr> + <th>status</th> + <td>Product Designer</td> + </tr> + <tr> + <th>socialtwitter</th> + <td>stephanedupond</td> + </tr> + <tr> + <th>sociallinkedin</th> + <td>https://www.linkedin.com/in/stephanedupond</td> + </tr> </tbody> </table> </div> diff --git a/app/views/admin/university/person/alumnus/imports/show.html.erb b/app/views/admin/university/person/alumnus/imports/show.html.erb index a5c23fddc..d3fec028c 100644 --- a/app/views/admin/university/person/alumnus/imports/show.html.erb +++ b/app/views/admin/university/person/alumnus/imports/show.html.erb @@ -1,14 +1,7 @@ -<p id="notice"><%= notice %></p> +<% content_for :title, @import %> -<p> - <strong>University:</strong> - <%= @university_person_alumnus_import.university_id %> -</p> +<p><%= @import.lines %> lines</p> -<p> - <strong>User:</strong> - <%= @university_person_alumnus_import.user_id %> -</p> - -<%= link_to 'Edit', edit_university_person_alumnus_import_path(@university_person_alumnus_import) %> | -<%= link_to 'Back', university_person_alumnus_imports_path %> +<%= link_to "#{@import.file.filename} (#{number_to_human_size @import.file.byte_size})", + url_for(@import.file), + class: button_classes %> diff --git a/config/locales/university/fr.yml b/config/locales/university/fr.yml index aa0fb6657..43b7cb906 100644 --- a/config/locales/university/fr.yml +++ b/config/locales/university/fr.yml @@ -29,6 +29,7 @@ fr: is_author: Auteur·rice is_researcher: Chercheur·se is_teacher: Enseignant·e + is_alumnus: Alumnus last_name: Nom de famille linkedin: LinkedIn (URL) name: Nom @@ -86,8 +87,9 @@ fr: is_author: "Écrit des articles pour les sites." is_researcher: "Écrit des articles dans des revues scientifiques." is_teacher: "Enseigne dans des formations." + is_alumnus: "Étudie ou a étudié dans l'établissement." linkedin: "Exemple : https://www.linkedin.com/in/osuny" - tenure: "A différencier d'une personne vacataire." + tenure: "À différencier d'une personne vacataire." twitter: "Exemple : osuny" university: invoice_informations: Données de facturation -- GitLab