From a37320bae93d1faefe943ff627125c126f54cfb2 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Mon, 1 Aug 2016 18:10:32 +0200 Subject: [PATCH 01/10] Add lateral panel to configure dossier list in back office --- app/assets/javascripts/pref_list_dossier.js | 33 +++ app/assets/stylesheets/backoffice.scss | 12 + app/assets/stylesheets/pref_list_menu.scss | 20 ++ .../backoffice/dossiers_controller.rb | 23 +- .../preference_list_dossier_controller.rb | 31 +++ app/decorators/dossier_decorator.rb | 4 + app/decorators/etablissement_decorator.rb | 4 + .../france_connect_information_decorator.rb | 4 + app/mailers/new_admin_mailer.rb | 2 +- app/models/dossier.rb | 1 + app/models/gestionnaire.rb | 1 + app/models/preference_list_dossier.rb | 94 +++++++ app/views/backoffice/dossiers/_list.html.haml | 31 ++- .../backoffice/dossiers/_onglets.html.haml | 24 +- .../backoffice/dossiers/_pref_list.html.haml | 43 +++ .../backoffice/dossiers/_pref_list.js.erb | 14 + app/views/backoffice/dossiers/index.html.haml | 2 + app/views/layouts/application.html.haml | 6 + config/routes.rb | 8 + ...35927_add_preference_list_dossier_table.rb | 15 ++ db/schema.rb | 13 +- ...preference_list_dossier_controller_spec.rb | 51 ++++ spec/factories/preference_list_dossier.rb | 11 + ..._page_pref_list_dossier_backoffice_spec.rb | 86 ++++++ .../backoffice/navigate_to_dossier_spec.rb | 9 + spec/models/dossier_spec.rb | 1 + spec/models/gestionnaire_spec.rb | 1 + spec/models/preference_list_dossier_spec.rb | 253 ++++++++++++++++++ .../dossiers/index_html.haml_spec.rb | 24 ++ 29 files changed, 794 insertions(+), 27 deletions(-) create mode 100644 app/assets/javascripts/pref_list_dossier.js create mode 100644 app/assets/stylesheets/pref_list_menu.scss create mode 100644 app/controllers/backoffice/preference_list_dossier_controller.rb create mode 100644 app/decorators/etablissement_decorator.rb create mode 100644 app/decorators/france_connect_information_decorator.rb create mode 100644 app/models/preference_list_dossier.rb create mode 100644 app/views/backoffice/dossiers/_pref_list.html.haml create mode 100644 app/views/backoffice/dossiers/_pref_list.js.erb create mode 100644 db/migrate/20160722135927_add_preference_list_dossier_table.rb create mode 100644 spec/controllers/backoffice/preference_list_dossier_controller_spec.rb create mode 100644 spec/factories/preference_list_dossier.rb create mode 100644 spec/features/backoffice/lateral_page_pref_list_dossier_backoffice_spec.rb create mode 100644 spec/models/preference_list_dossier_spec.rb diff --git a/app/assets/javascripts/pref_list_dossier.js b/app/assets/javascripts/pref_list_dossier.js new file mode 100644 index 000000000..70bf1a4dd --- /dev/null +++ b/app/assets/javascripts/pref_list_dossier.js @@ -0,0 +1,33 @@ +$(document).on('page:load', pref_list_dossier_actions); +$(document).ready(pref_list_dossier_actions); + +function pref_list_dossier_actions() { + pref_list_dossier_open_action(); + pref_list_dossier_close_action(); +} + +function pref_list_dossier_open_action() { + $("#pref_list_dossier_open_action").on('click', function () { + $("#pref_list_menu").css('display', 'block'); + $("#pref_list_menu").css('visibility', 'visible'); + + $("#pref_list_menu").animate({ + right: 0 + }, 250); + }); +} + +function pref_list_dossier_close_action() { + $("#pref_list_dossier_close_action").on('click', function () { + $("#pref_list_menu").animate({ + right: parseInt($("#pref_list_menu").css('width'), 10)*(-1)+'px' + },{ + duration: 250, + complete: function () { + $("#pref_list_menu").css('display', 'none'); + $("#pref_list_menu").css('visibility', 'hidden'); + } + } + ) + }); +} \ No newline at end of file diff --git a/app/assets/stylesheets/backoffice.scss b/app/assets/stylesheets/backoffice.scss index f0054f56c..b447e2a5e 100644 --- a/app/assets/stylesheets/backoffice.scss +++ b/app/assets/stylesheets/backoffice.scss @@ -6,6 +6,18 @@ } } +#backoffice_index, #backoffice_search { + margin-left: -7rem; + margin-right: -7rem; +} + +#pref_list{ + .dropdown-menu { + padding: 10px; + width: 500px; + } +} + #onglets { ul { li, li.active { diff --git a/app/assets/stylesheets/pref_list_menu.scss b/app/assets/stylesheets/pref_list_menu.scss new file mode 100644 index 000000000..0ab24a30d --- /dev/null +++ b/app/assets/stylesheets/pref_list_menu.scss @@ -0,0 +1,20 @@ +#pref_list_menu{ + z-index: 100; + display: none; + position: fixed; + visibility: hidden; + top: 10px; + right: -470px; + background-color: rgba(255, 255, 255, 0.95); + border-left: solid 1px lightgrey; + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2); + width: 470px; + height: calc(100% - 25px); + padding: 15px; + overflow: scroll; +} + +.open_pref_list { + right: 0 !important; + display: block !important; +} \ No newline at end of file diff --git a/app/controllers/backoffice/dossiers_controller.rb b/app/controllers/backoffice/dossiers_controller.rb index edf67db28..82d41b543 100644 --- a/app/controllers/backoffice/dossiers_controller.rb +++ b/app/controllers/backoffice/dossiers_controller.rb @@ -7,10 +7,7 @@ class Backoffice::DossiersController < ApplicationController def index @liste = params[:liste] || 'a_traiter' - @dossiers = smart_listing_create :dossiers, - dossiers_to_display, - partial: "backoffice/dossiers/list", - array: true + smartlisting_dossier total_dossiers_per_state end @@ -61,8 +58,26 @@ class Backoffice::DossiersController < ApplicationController redirect_to request.referer end + def reload_smartlisting + begin + @liste = URI(request.referer).query.split('=').second + rescue NoMethodError + @liste = 'a_traiter' + end + smartlisting_dossier + + render 'backoffice/dossiers/index', formats: :js + end + private + def smartlisting_dossier + @dossiers = smart_listing_create :dossiers, + dossiers_to_display, + partial: "backoffice/dossiers/list", + array: true + end + def dossiers_to_display {'a_traiter' => waiting_for_gestionnaire, 'en_attente' => waiting_for_user, diff --git a/app/controllers/backoffice/preference_list_dossier_controller.rb b/app/controllers/backoffice/preference_list_dossier_controller.rb new file mode 100644 index 000000000..034ff1fb1 --- /dev/null +++ b/app/controllers/backoffice/preference_list_dossier_controller.rb @@ -0,0 +1,31 @@ +class Backoffice::PreferenceListDossierController < ApplicationController + include SmartListing::Helper::ControllerExtensions + helper SmartListing::Helper + + before_action :authenticate_gestionnaire! + + def add + PreferenceListDossier.create( + libelle: params[:libelle], + table: params[:table], + attr: params[:attr], + attr_decorate: params[:attr_decorate], + bootstrap_lg: params[:bootstrap_lg], + order: nil, + filter: nil, + gestionnaire: current_gestionnaire + ) + + render partial: 'backoffice/dossiers/pref_list', formats: :js + end + + def reload_pref_list + render partial: 'backoffice/dossiers/pref_list' + end + + def delete + PreferenceListDossier.delete(params[:pref_id]) + + render partial: 'backoffice/dossiers/pref_list', formats: :js + end +end diff --git a/app/decorators/dossier_decorator.rb b/app/decorators/dossier_decorator.rb index a1b76c80d..109b95bf7 100644 --- a/app/decorators/dossier_decorator.rb +++ b/app/decorators/dossier_decorator.rb @@ -8,6 +8,10 @@ class DossierDecorator < Draper::Decorator 'dd/mm/YYYY' end + def first_creation + created_at.localtime.strftime('%d/%m/%Y %H:%M') + end + def last_update updated_at.localtime.strftime('%d/%m/%Y %H:%M') end diff --git a/app/decorators/etablissement_decorator.rb b/app/decorators/etablissement_decorator.rb new file mode 100644 index 000000000..23f809c79 --- /dev/null +++ b/app/decorators/etablissement_decorator.rb @@ -0,0 +1,4 @@ +class EtablissementDecorator < Draper::Decorator + delegate_all + +end diff --git a/app/decorators/france_connect_information_decorator.rb b/app/decorators/france_connect_information_decorator.rb new file mode 100644 index 000000000..206361fe8 --- /dev/null +++ b/app/decorators/france_connect_information_decorator.rb @@ -0,0 +1,4 @@ +class FranceConnectInformationDecorator < Draper::Decorator + delegate_all + +end diff --git a/app/mailers/new_admin_mailer.rb b/app/mailers/new_admin_mailer.rb index 22c0428fb..f7acb8e7e 100644 --- a/app/mailers/new_admin_mailer.rb +++ b/app/mailers/new_admin_mailer.rb @@ -4,7 +4,7 @@ class NewAdminMailer < ApplicationMailer @admin = admin @password = password - mail(from: "tech@apientreprise.fr", to: 'tech@apientreprise.fr', + mail(from: "tps@apientreprise.fr", to: 'tech@apientreprise.fr', subject: "Création d'un compte Admin TPS") end end diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 4e0f13f8c..f387d28d5 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -27,6 +27,7 @@ class Dossier < ActiveRecord::Base delegate :siret, to: :etablissement, allow_nil: true delegate :types_de_piece_justificative, to: :procedure delegate :types_de_champ, to: :procedure + delegate :france_connect_information, to: :user after_save :build_default_champs, if: Proc.new { procedure_id_changed? } diff --git a/app/models/gestionnaire.rb b/app/models/gestionnaire.rb index 128783937..2faf97c47 100644 --- a/app/models/gestionnaire.rb +++ b/app/models/gestionnaire.rb @@ -8,6 +8,7 @@ class Gestionnaire < ActiveRecord::Base has_many :procedures, through: :assign_to has_many :dossiers, through: :procedures has_many :follows + has_many :preference_list_dossiers def dossiers_filter dossiers.where(procedure_id: procedure_filter_list) diff --git a/app/models/preference_list_dossier.rb b/app/models/preference_list_dossier.rb new file mode 100644 index 000000000..93befa9d0 --- /dev/null +++ b/app/models/preference_list_dossier.rb @@ -0,0 +1,94 @@ +class PreferenceListDossier < ActiveRecord::Base + belongs_to :gestionnaire + + def table_attr + return self.attr if table.empty? + table + '.' + attr + end + + def self.available_columns + { + dossier: columns_dossier, + procedure: columns_procedure, + entreprise: columns_entreprise, + etablissement: columns_etablissement, + user: columns_user + } + end + + private + + def self.columns_dossier + table = nil + + { + dossier_id: create_column('ID', table, 'id', 'id', 1), + created_at: create_column('Créé le', table, 'created_at', 'first_creation', 2), + updated_at: create_column('Mise à jour le', table, 'updated_at', 'last_update', 2), + state: create_column('Statut', table, 'state', 'display_state', 1) + } + end + + def self.columns_procedure + table = 'procedure' + + { + libelle: create_column('Libellé procédure', table, 'libelle', 'libelle', 4), + organisation: create_column('Organisation', table, 'organisation', 'organisation', 3), + direction: create_column('Direction', table, 'direction', 'direction', 3) + } + end + + def self.columns_entreprise + table = 'entreprise' + + { + siren: create_column('SIREN', table, 'siren', 'siren', 2), + forme_juridique: create_column('Forme juridique', table, 'forme_juridique', 'forme_juridique', 3), + nom_commercial: create_column('Nom commercial', table, 'nom_commercial', 'nom_commercial', 3), + raison_sociale: create_column('Raison sociale', table, 'raison_sociale', 'raison_sociale', 3), + siret_siege_social: create_column('SIRET siège social', table, 'siret_siege_social', 'siret_siege_social', 2), + date_creation: create_column('Date de création', table, 'date_creation', 'date_creation', 2), + } + end + + def self.columns_etablissement + table = 'etablissement' + + { + siret: create_column('SIRET', table, 'siret', 'siret', 2), + libelle: create_column('Nom établissement', table, 'libelle_naf', 'libelle_naf', 3), + code_postal: create_column('Code postal', table, 'code_postal', 'code_postal', 1) + } + end + + def self.columns_user + table = 'user' + + { + email: create_column('Email', table, 'email', 'email', 2) + } + end + + def self.columns_france_connect + table = 'france_connect_information' + + { + gender: create_column('Civilité', table, 'gender', 'gender', 1), + given_name: create_column('Prénom', table, 'given_name', 'given_name', 2), + family_name: create_column('Nom', table, 'family_name', 'family_name', 2) + } + end + + def self.create_column libelle, table, attr, attr_decorate, bootstrap_lg + { + libelle: libelle, + table: table, + attr: attr, + attr_decorate: attr_decorate, + bootstrap_lg: bootstrap_lg, + order: nil, + filter: nil + } + end +end \ No newline at end of file diff --git a/app/views/backoffice/dossiers/_list.html.haml b/app/views/backoffice/dossiers/_list.html.haml index 6307fff8c..3afa85d7a 100644 --- a/app/views/backoffice/dossiers/_list.html.haml +++ b/app/views/backoffice/dossiers/_list.html.haml @@ -1,21 +1,25 @@ - unless smart_listing.empty? %table.table %thead - %th= smart_listing.sortable 'Procédure', 'procedure.libelle' - %th= smart_listing.sortable 'Raison sociale', 'entreprise.raison_sociale' - %th= smart_listing.sortable 'État', 'state' - %th= smart_listing.sortable 'Date de mise à jour', 'updated_at' - %th.center Actions - %th.center Abonnés + - current_gestionnaire.preference_list_dossiers.order(:id).each do |preference| + %th{class: "col-md-#{preference.bootstrap_lg} col-lg-#{preference.bootstrap_lg}"}= smart_listing.sortable preference.libelle, preference.table_attr + %th.col-md-1.col-lg-1.center Actions + %th.col-md-1.col-lg-1.center Abonnés - @dossiers.each do |dossier| - - dossier = dossier.decorate %tr - %td.col-md-4.col-lg-4= dossier.procedure.libelle - %td.col-md-4.col-lg-4 - = link_to(dossier.entreprise.raison_sociale, "/backoffice/dossiers/#{dossier.id}") - %td= dossier.display_state - %td= dossier.last_update + - current_gestionnaire.preference_list_dossiers.order(:id).each_with_index do |preference, index| + %td + - if preference.table.empty? + - value = dossier.decorate.public_send(preference.attr_decorate) + - else + - value = dossier.public_send(preference.table).decorate.public_send(preference.attr_decorate) + + - if index == 0 + = link_to value, backoffice_dossier_path(id: dossier.id) + - else + = value + %td.center - if current_gestionnaire.follow?(dossier.id) = link_to('Quitter'.html_safe, backoffice_dossier_follow_path(dossier_id: dossier.id), 'data-method' => :put, class: 'btn-sm btn-danger', id: "suivre_dossier_#{dossier.id}") @@ -26,6 +30,7 @@ = smart_listing.paginate = smart_listing.pagination_per_page_links + - else %h4.center - Aucun dossier + Aucun dossier \ No newline at end of file diff --git a/app/views/backoffice/dossiers/_onglets.html.haml b/app/views/backoffice/dossiers/_onglets.html.haml index 589b12fce..29ff955e7 100644 --- a/app/views/backoffice/dossiers/_onglets.html.haml +++ b/app/views/backoffice/dossiers/_onglets.html.haml @@ -31,12 +31,20 @@ .badge.progress-bar-success =@dossiers_termine_total - %li#search{class: "#{'active' unless @dossiers_search.nil?}", style:'float:right'} - %a - = form_tag(backoffice_dossiers_search_url, method: :get) do - .input-group{style:'width: 300px'} - = text_field_tag('q', "#{@search_terms unless @search_terms.nil? }", id: 'q', placeholder: "Rechercher un dossier ...", class:'form-control') - %span.input-group-btn - %button.btn.btn-default{ id:'search_button' } - %i.fa.fa-search + %ul.nav.nav-tabs.navbar-right{style:'border-bottom: none;'} + %li#search{class: "#{'active' unless @dossiers_search.nil?}"} + %a + = form_tag(backoffice_dossiers_search_url, method: :get) do + .input-group{style:'width: 300px'} + = text_field_tag('q', "#{@search_terms unless @search_terms.nil? }", id: 'q', placeholder: "Rechercher un dossier ...", class:'form-control') + %span.input-group-btn + %button.btn.btn-default{ id:'search_button' } + %i.fa.fa-search + + - if @dossiers_search.nil? + %li#pref_list + %a.btn#pref_list_dossier_open_action{href: '#'} + %i.fa.fa-columns + + %br \ No newline at end of file diff --git a/app/views/backoffice/dossiers/_pref_list.html.haml b/app/views/backoffice/dossiers/_pref_list.html.haml new file mode 100644 index 000000000..e802bb638 --- /dev/null +++ b/app/views/backoffice/dossiers/_pref_list.html.haml @@ -0,0 +1,43 @@ +%button#pref_list_dossier_close_action.btn.btn-danger.btn-xs{style:'float:right'} + %i.fa.fa-close +%h3 Gestion de colonnes affichées + +%p{style:'margin-top: 15px; margin-bottom: 20px'} + Ce menu vous permet de choisir les différentes colonnes que vous souhaitez voir apparaitrent dans votre interface de suivi des dossiers. + +%h4.text-primary + Actuelles + +%ul + - current_gestionnaire.preference_list_dossiers.order(:id).each_with_index do |preference, index| + %li + = form_tag backoffice_preference_list_dossier_delete_path, method: :delete, remote: true do + = hidden_field_tag :pref_id, preference.id + = preference.libelle + %button.btn.btn-default.btn-xs{type: :submit, id: "delete_pref_list_#{preference[:table]}_#{preference[:attr]}"} + %i.fa.fa-minus + +%h4.text-success{style:'margin-top: 15px'} + Disponibles + +%table + - PreferenceListDossier.available_columns.each_with_index do |tables, index| + - if index%2 == 0 + %tr + + %td.col-sm-5.col-md-5.col-lg-5{style: 'vertical-align: top'} + %h5= tables.first.to_s.gsub('_', ' ').capitalize + %ul + - tables.second.each do |columns| + %li + = form_tag backoffice_preference_list_dossier_add_path, method: :post, remote: true do + = hidden_field_tag :libelle, columns.second[:libelle] + = hidden_field_tag :table, columns.second[:table] + = hidden_field_tag :attr, columns.second[:attr] + = hidden_field_tag :attr_decorate, columns.second[:attr_decorate] + = hidden_field_tag :bootstrap_lg, columns.second[:bootstrap_lg] + + = columns.second[:libelle] + %button.btn.btn-default.btn-xs{type: :submit, id: "add_pref_list_#{columns.second[:table]}_#{columns.second[:attr]}"} + %i.fa.fa-plus + diff --git a/app/views/backoffice/dossiers/_pref_list.js.erb b/app/views/backoffice/dossiers/_pref_list.js.erb new file mode 100644 index 000000000..2d421e10f --- /dev/null +++ b/app/views/backoffice/dossiers/_pref_list.js.erb @@ -0,0 +1,14 @@ +$.ajax({ + method: 'get', + url: '/backoffice/preference_list_dossier/reload_smartlisting', + async: true +}); + +$.ajax({ + methd: 'get', + url: '/backoffice/preference_list_dossier/reload_pref_list', + async: true +}).done(function (data) { + $("#pref_list_menu").html(data); + pref_list_dossier_actions(); +}); diff --git a/app/views/backoffice/dossiers/index.html.haml b/app/views/backoffice/dossiers/index.html.haml index d6095bffd..f6156379e 100644 --- a/app/views/backoffice/dossiers/index.html.haml +++ b/app/views/backoffice/dossiers/index.html.haml @@ -1,4 +1,6 @@ #backoffice_index + #pref_list_menu + = render partial: 'pref_list' = render partial: 'onglets' = smart_listing_render :dossiers diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 440c59544..7fb7c8008 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -7,9 +7,15 @@ = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true = stylesheet_link_tag 'application_split2', media: 'all', 'data-turbolinks-track' => true + + = javascript_include_tag 'application', 'data-turbolinks-track' => true = csrf_meta_tags %body + - if Rails.env == 'test' + %script{type: 'text/javascript'} + (typeof jQuery !== 'undefined') && (jQuery.fx.off = true); + %div#wrap %div#header.navbar =render partial: "layouts/navbar" diff --git a/config/routes.rb b/config/routes.rb index cc657c43d..cb11c81c3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -139,6 +139,14 @@ Rails.application.routes.draw do patch 'filtres/update' => 'procedure_filter#update' + namespace :preference_list_dossier do + post 'add' + delete 'delete' + + get 'reload_smartlisting' => '/backoffice/dossiers#reload_smartlisting' + get 'reload_pref_list' + end + resources :dossiers do post 'valid' => 'dossiers#valid' post 'close' => 'dossiers#close' diff --git a/db/migrate/20160722135927_add_preference_list_dossier_table.rb b/db/migrate/20160722135927_add_preference_list_dossier_table.rb new file mode 100644 index 000000000..d638ee92f --- /dev/null +++ b/db/migrate/20160722135927_add_preference_list_dossier_table.rb @@ -0,0 +1,15 @@ +class AddPreferenceListDossierTable < ActiveRecord::Migration + def change + create_table :preference_list_dossiers do |t| + t.string :libelle + t.string :table + t.string :attr + t.string :attr_decorate + t.string :bootstrap_lg + t.string :order + t.string :filter + end + + add_belongs_to :preference_list_dossiers, :gestionnaire + end +end diff --git a/db/schema.rb b/db/schema.rb index 1dacf946f..0a0f042e0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160718124741) do +ActiveRecord::Schema.define(version: 20160722135927) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -234,6 +234,17 @@ ActiveRecord::Schema.define(version: 20160718124741) do add_index "pieces_justificatives", ["type_de_piece_justificative_id"], name: "index_pieces_justificatives_on_type_de_piece_justificative_id", using: :btree + create_table "preference_list_dossiers", force: :cascade do |t| + t.string "libelle" + t.string "table" + t.string "attr" + t.string "attr_decorate" + t.string "bootstrap_lg" + t.string "order" + t.string "filter" + t.integer "gestionnaire_id" + end + create_table "procedure_paths", force: :cascade do |t| t.string "path", limit: 30 t.integer "procedure_id" diff --git a/spec/controllers/backoffice/preference_list_dossier_controller_spec.rb b/spec/controllers/backoffice/preference_list_dossier_controller_spec.rb new file mode 100644 index 000000000..ecf6c25f0 --- /dev/null +++ b/spec/controllers/backoffice/preference_list_dossier_controller_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' + +describe Backoffice::PreferenceListDossierController, type: :controller do + let(:gestionnaire) { create :gestionnaire } + let(:libelle) { 'Plop' } + let(:table) { 'plip' } + let(:attr) { 'plap' } + let(:attr_decorate) { 'plup' } + let(:bootstrap_lg) { 'plyp' } + + before do + sign_in gestionnaire + end + + describe '#POST add' do + subject { post :add, libelle: libelle, + table: table, + attr: attr, + attr_decorate: attr_decorate, + bootstrap_lg: bootstrap_lg } + + it { expect(subject.status).to eq 200 } + it { expect { subject }.to change(PreferenceListDossier, :count).by(1) } + + describe 'attributs' do + let(:last) { PreferenceListDossier.last } + + before do + subject + end + + it { expect(last.libelle).to eq libelle } + it { expect(last.table).to eq table } + it { expect(last.attr).to eq attr } + it { expect(last.attr_decorate).to eq attr_decorate } + it { expect(last.bootstrap_lg).to eq bootstrap_lg } + it { expect(last.order).to be_nil } + it { expect(last.filter).to be_nil } + it { expect(last.gestionnaire).to eq gestionnaire } + end + end + + describe '#DELETE delete' do + let!(:pref) { create :preference_list_dossier } + + subject { delete :delete, pref_id: pref.id } + + it { expect(subject.status).to eq 200 } + it { expect { subject }.to change(PreferenceListDossier, :count).by(-1) } + end +end diff --git a/spec/factories/preference_list_dossier.rb b/spec/factories/preference_list_dossier.rb new file mode 100644 index 000000000..cda3b8c11 --- /dev/null +++ b/spec/factories/preference_list_dossier.rb @@ -0,0 +1,11 @@ +FactoryGirl.define do + factory :preference_list_dossier do + libelle 'Procedure' + table 'procedure' + attr 'libelle' + attr_decorate 'libelle' + order nil + filter nil + bootstrap_lg 1 + end +end diff --git a/spec/features/backoffice/lateral_page_pref_list_dossier_backoffice_spec.rb b/spec/features/backoffice/lateral_page_pref_list_dossier_backoffice_spec.rb new file mode 100644 index 000000000..e2fe77a4d --- /dev/null +++ b/spec/features/backoffice/lateral_page_pref_list_dossier_backoffice_spec.rb @@ -0,0 +1,86 @@ +require 'spec_helper' + +feature 'usage of pref list dossier lateral panel', js: true do + + let(:administrateur) { create(:administrateur) } + let(:gestionnaire) { create(:gestionnaire, administrateurs: [administrateur]) } + let(:procedure) { create(:procedure, administrateur: administrateur) } + + before do + create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated') + create :assign_to, procedure: procedure, gestionnaire: gestionnaire + visit backoffice_path + end + + scenario 'he is redirected to /gestionnaires/sign_id' do + expect(page).to have_css('#gestionnaire_login') + end + + context 'when user enter good credentials' do + before do + page.find_by_id(:gestionnaire_email).set gestionnaire.email + page.find_by_id(:gestionnaire_password).set gestionnaire.password + page.click_on 'Se connecter' + end + + scenario 'he is redirected to /backoffice' do + expect(page).to have_css('#backoffice_index') + end + + scenario 'lateral panel is masked' do + expect(page).to have_css('#pref_list_menu', visible: false) + end + + context 'when on click on pref list button' do + before do + page.click_on 'pref_list_dossier_open_action' + end + + scenario 'lateral panel is appeared' do + expect(page).to have_css('#pref_list_menu') + end + + context 'when on click on add attribut button' do + before do + page.click_on 'add_pref_list_entreprise_siren' + end + + scenario 'preference list panel is brought up to date' do + wait_for_ajax + expect(page).to have_css('#delete_pref_list_entreprise_siren') + end + + scenario 'dossier is brought up to date' do + wait_for_ajax + expect(page).to have_selector("a.sortable[data-attr='entreprise.siren']") + end + + context 'when on click on delete attribut button' do + before do + page.click_on 'delete_pref_list_entreprise_siren' + end + + scenario 'preference list panel is brought up to date' do + wait_for_ajax + expect(page).not_to have_css('#delete_pref_list_entreprise_siren') + end + + scenario 'dossier is brought up to date' do + wait_for_ajax + expect(page).not_to have_selector("a.sortable[data-attr='entreprise.siren']") + end + + context 'when on click on close pref list button' do + before do + page.click_on 'pref_list_dossier_close_action' + end + + scenario 'lateral panel is masked' do + expect(page).to have_css('#pref_list_menu', visible: false) + end + end + end + end + end + end +end \ No newline at end of file diff --git a/spec/features/backoffice/navigate_to_dossier_spec.rb b/spec/features/backoffice/navigate_to_dossier_spec.rb index 4a3664a99..05114df6e 100644 --- a/spec/features/backoffice/navigate_to_dossier_spec.rb +++ b/spec/features/backoffice/navigate_to_dossier_spec.rb @@ -9,6 +9,13 @@ feature 'on backoffice page' do before do create :assign_to, gestionnaire: gestionnaire, procedure: procedure + + create :preference_list_dossier, + gestionnaire: gestionnaire, + table: 'entreprise', + attr: 'raison_sociale', + attr_decorate: 'raison_sociale' + visit backoffice_path end @@ -17,6 +24,8 @@ feature 'on backoffice page' do page.find_by_id(:gestionnaire_email).set gestionnaire.email page.find_by_id(:gestionnaire_password).set gestionnaire.password page.click_on 'Se connecter' + + end context 'when he click on first dossier' do before do diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index b26b8243e..3a789effc 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -33,6 +33,7 @@ describe Dossier do it { is_expected.to delegate_method(:siret).to(:etablissement) } it { is_expected.to delegate_method(:types_de_piece_justificative).to(:procedure) } it { is_expected.to delegate_method(:types_de_champ).to(:procedure) } + it { is_expected.to delegate_method(:france_connect_information).to(:user) } end describe 'methods' do diff --git a/spec/models/gestionnaire_spec.rb b/spec/models/gestionnaire_spec.rb index 17a8b55a2..e485b028f 100644 --- a/spec/models/gestionnaire_spec.rb +++ b/spec/models/gestionnaire_spec.rb @@ -32,6 +32,7 @@ describe Gestionnaire, type: :model do it { is_expected.to have_many(:procedures) } it { is_expected.to have_many(:dossiers) } it { is_expected.to have_many(:follows) } + it { is_expected.to have_many(:preference_list_dossiers) } end describe '#dossiers_filter' do diff --git a/spec/models/preference_list_dossier_spec.rb b/spec/models/preference_list_dossier_spec.rb new file mode 100644 index 000000000..e65b377fb --- /dev/null +++ b/spec/models/preference_list_dossier_spec.rb @@ -0,0 +1,253 @@ +require 'spec_helper' + +describe PreferenceListDossier do + it { is_expected.to have_db_column(:libelle) } + it { is_expected.to have_db_column(:table) } + it { is_expected.to have_db_column(:attr) } + it { is_expected.to have_db_column(:attr_decorate) } + it { is_expected.to have_db_column(:bootstrap_lg) } + it { is_expected.to have_db_column(:order) } + it { is_expected.to have_db_column(:filter) } + it { is_expected.to have_db_column(:gestionnaire_id) } + + it { is_expected.to belong_to(:gestionnaire) } + + describe '.available_columns' do + subject { PreferenceListDossier.available_columns } + + describe 'dossier' do + subject { super()[:dossier] } + + it { expect(subject.size).to eq 4 } + + describe 'dossier_id' do + subject { super()[:dossier_id] } + + it { expect(subject[:libelle]).to eq 'ID' } + it { expect(subject[:table]).to be_nil } + it { expect(subject[:attr]).to eq 'id' } + it { expect(subject[:attr_decorate]).to eq 'id' } + it { expect(subject[:bootstrap_lg]).to eq 1 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + + describe 'created_at' do + subject { super()[:created_at] } + + it { expect(subject[:libelle]).to eq 'Créé le' } + it { expect(subject[:table]).to be_nil } + it { expect(subject[:attr]).to eq 'created_at' } + it { expect(subject[:attr_decorate]).to eq 'first_creation' } + it { expect(subject[:bootstrap_lg]).to eq 2 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + + describe 'updated_at' do + subject { super()[:updated_at] } + + it { expect(subject[:libelle]).to eq 'Mise à jour le' } + it { expect(subject[:table]).to be_nil } + it { expect(subject[:attr]).to eq 'updated_at' } + it { expect(subject[:attr_decorate]).to eq 'last_update' } + it { expect(subject[:bootstrap_lg]).to eq 2 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + + describe 'state' do + subject { super()[:state] } + + it { expect(subject[:libelle]).to eq 'Statut' } + it { expect(subject[:table]).to be_nil } + it { expect(subject[:attr]).to eq 'state' } + it { expect(subject[:attr_decorate]).to eq 'display_state' } + it { expect(subject[:bootstrap_lg]).to eq 1 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + end + + describe 'procedure' do + subject { super()[:procedure] } + + it { expect(subject.size).to eq 3 } + + describe 'libelle' do + subject { super()[:libelle] } + + it { expect(subject[:libelle]).to eq 'Libellé procédure' } + it { expect(subject[:table]).to eq 'procedure' } + it { expect(subject[:attr]).to eq 'libelle' } + it { expect(subject[:attr_decorate]).to eq 'libelle' } + it { expect(subject[:bootstrap_lg]).to eq 4 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + + describe 'organisation' do + subject { super()[:organisation] } + + it { expect(subject[:libelle]).to eq 'Organisation' } + it { expect(subject[:table]).to eq 'procedure' } + it { expect(subject[:attr]).to eq 'organisation' } + it { expect(subject[:attr_decorate]).to eq 'organisation' } + it { expect(subject[:bootstrap_lg]).to eq 3 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + + describe 'direction' do + subject { super()[:direction] } + + it { expect(subject[:libelle]).to eq 'Direction' } + it { expect(subject[:table]).to eq 'procedure' } + it { expect(subject[:attr]).to eq 'direction' } + it { expect(subject[:attr_decorate]).to eq 'direction' } + it { expect(subject[:bootstrap_lg]).to eq 3 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + end + + describe 'entreprise' do + subject { super()[:entreprise] } + + it { expect(subject.size).to eq 6 } + + describe 'siren' do + subject { super()[:siren] } + + it { expect(subject[:libelle]).to eq 'SIREN' } + it { expect(subject[:table]).to eq 'entreprise' } + it { expect(subject[:attr]).to eq 'siren' } + it { expect(subject[:attr_decorate]).to eq 'siren' } + it { expect(subject[:bootstrap_lg]).to eq 2 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + + describe 'forme_juridique' do + subject { super()[:forme_juridique] } + + it { expect(subject[:libelle]).to eq 'Forme juridique' } + it { expect(subject[:table]).to eq 'entreprise' } + it { expect(subject[:attr]).to eq 'forme_juridique' } + it { expect(subject[:attr_decorate]).to eq 'forme_juridique' } + it { expect(subject[:bootstrap_lg]).to eq 3 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + + describe 'nom_commercial' do + subject { super()[:nom_commercial] } + + it { expect(subject[:libelle]).to eq 'Nom commercial' } + it { expect(subject[:table]).to eq 'entreprise' } + it { expect(subject[:attr]).to eq 'nom_commercial' } + it { expect(subject[:attr_decorate]).to eq 'nom_commercial' } + it { expect(subject[:bootstrap_lg]).to eq 3 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + + describe 'raison_sociale' do + subject { super()[:raison_sociale] } + + it { expect(subject[:libelle]).to eq 'Raison sociale' } + it { expect(subject[:table]).to eq 'entreprise' } + it { expect(subject[:attr]).to eq 'raison_sociale' } + it { expect(subject[:attr_decorate]).to eq 'raison_sociale' } + it { expect(subject[:bootstrap_lg]).to eq 3 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + + describe 'siret_siege_social' do + subject { super()[:siret_siege_social] } + + it { expect(subject[:libelle]).to eq 'SIRET siège social' } + it { expect(subject[:table]).to eq 'entreprise' } + it { expect(subject[:attr]).to eq 'siret_siege_social' } + it { expect(subject[:attr_decorate]).to eq 'siret_siege_social' } + it { expect(subject[:bootstrap_lg]).to eq 2 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + + describe 'date_creation' do + subject { super()[:date_creation] } + + it { expect(subject[:libelle]).to eq 'Date de création' } + it { expect(subject[:table]).to eq 'entreprise' } + it { expect(subject[:attr]).to eq 'date_creation' } + it { expect(subject[:attr_decorate]).to eq 'date_creation' } + it { expect(subject[:bootstrap_lg]).to eq 2 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + + end + + describe 'etablissement' do + subject { super()[:etablissement] } + + it { expect(subject.size).to eq 3 } + + describe 'siret' do + subject { super()[:siret] } + + it { expect(subject[:libelle]).to eq 'SIRET' } + it { expect(subject[:table]).to eq 'etablissement' } + it { expect(subject[:attr]).to eq 'siret' } + it { expect(subject[:attr_decorate]).to eq 'siret' } + it { expect(subject[:bootstrap_lg]).to eq 2 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + + describe 'libelle' do + subject { super()[:libelle] } + + it { expect(subject[:libelle]).to eq 'Nom établissement' } + it { expect(subject[:table]).to eq 'etablissement' } + it { expect(subject[:attr]).to eq 'libelle_naf' } + it { expect(subject[:attr_decorate]).to eq 'libelle_naf' } + it { expect(subject[:bootstrap_lg]).to eq 3 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + + describe 'code_postal' do + subject { super()[:code_postal] } + + it { expect(subject[:libelle]).to eq 'Code postal' } + it { expect(subject[:table]).to eq 'etablissement' } + it { expect(subject[:attr]).to eq 'code_postal' } + it { expect(subject[:attr_decorate]).to eq 'code_postal' } + it { expect(subject[:bootstrap_lg]).to eq 1 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + end + + describe 'user' do + subject { super()[:user] } + + it { expect(subject.size).to eq 1 } + + describe 'email' do + subject { super()[:email] } + + it { expect(subject[:libelle]).to eq 'Email' } + it { expect(subject[:table]).to eq 'user' } + it { expect(subject[:attr]).to eq 'email' } + it { expect(subject[:attr_decorate]).to eq 'email' } + it { expect(subject[:bootstrap_lg]).to eq 2 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + end + end +end diff --git a/spec/views/backoffice/dossiers/index_html.haml_spec.rb b/spec/views/backoffice/dossiers/index_html.haml_spec.rb index a8d59f286..382caf9a6 100644 --- a/spec/views/backoffice/dossiers/index_html.haml_spec.rb +++ b/spec/views/backoffice/dossiers/index_html.haml_spec.rb @@ -15,6 +15,30 @@ describe 'backoffice/dossiers/index.html.haml', type: :view do decorate_dossier_closed.entreprise.update_column(:raison_sociale, 'plip') decorate_dossier_replied.entreprise.update_column(:raison_sociale, 'plop') + create :preference_list_dossier, + gestionnaire: gestionnaire, + table: '', + attr: 'state', + attr_decorate: 'display_state' + + create :preference_list_dossier, + gestionnaire: gestionnaire, + table: 'procedure', + attr: 'libelle', + attr_decorate: 'libelle' + + create :preference_list_dossier, + gestionnaire: gestionnaire, + table: 'entreprise', + attr: 'raison_sociale', + attr_decorate: 'raison_sociale' + + create :preference_list_dossier, + gestionnaire: gestionnaire, + table: '', + attr: 'last_update', + attr_decorate: 'last_update' + create :assign_to, gestionnaire: gestionnaire, procedure: procedure sign_in gestionnaire end From 9bf80056585141f0e57e91dc24274133ada805a0 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Tue, 2 Aug 2016 14:45:09 +0200 Subject: [PATCH 02/10] Fix get entreprise 404 not found --- app/models/entreprise.rb | 2 ++ app/services/dossier_service.rb | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/app/models/entreprise.rb b/app/models/entreprise.rb index 382a64c28..ad3a8ee9b 100644 --- a/app/models/entreprise.rb +++ b/app/models/entreprise.rb @@ -2,4 +2,6 @@ class Entreprise < ActiveRecord::Base belongs_to :dossier has_one :etablissement, dependent: :destroy has_one :rna_information, dependent: :destroy + + validates_presence_of :siren end diff --git a/app/services/dossier_service.rb b/app/services/dossier_service.rb index d6ee9b4ae..e086c3657 100644 --- a/app/services/dossier_service.rb +++ b/app/services/dossier_service.rb @@ -9,6 +9,10 @@ class DossierService def dossier_informations! @entreprise_adapter = SIADE::EntrepriseAdapter.new(DossierService.siren @siret) + if @entreprise_adapter.to_params.nil? + raise RestClient::ResourceNotFound + end + @dossier.create_entreprise(@entreprise_adapter.to_params) @etablissement_adapter = SIADE::EtablissementAdapter.new(@siret) From bce1b96fee17bf883063170f1d332b7bee9fba9a Mon Sep 17 00:00:00 2001 From: Xavier J Date: Tue, 2 Aug 2016 14:49:41 +0200 Subject: [PATCH 03/10] Build default pref list dossier for new gestionnaire --- app/models/gestionnaire.rb | 46 ++++++ app/models/preference_list_dossier.rb | 2 +- app/views/backoffice/dossiers/_list.html.haml | 2 +- ...2_build_default_preference_list_dossier.rb | 133 ++++++++++++++++++ db/schema.rb | 2 +- .../backoffice/navigate_to_dossier_spec.rb | 10 +- spec/models/gestionnaire_spec.rb | 35 +++++ 7 files changed, 218 insertions(+), 12 deletions(-) create mode 100644 db/migrate/20160802113112_build_default_preference_list_dossier.rb diff --git a/app/models/gestionnaire.rb b/app/models/gestionnaire.rb index 2faf97c47..5f9d2baff 100644 --- a/app/models/gestionnaire.rb +++ b/app/models/gestionnaire.rb @@ -10,6 +10,8 @@ class Gestionnaire < ActiveRecord::Base has_many :follows has_many :preference_list_dossiers + after_create :build_default_preferences_list_dossier + def dossiers_filter dossiers.where(procedure_id: procedure_filter_list) end @@ -38,4 +40,48 @@ class Gestionnaire < ActiveRecord::Base Follow.where(gestionnaire_id: id, dossier_id: dossier_id).any? end + + def build_default_preferences_list_dossier + + PreferenceListDossier.available_columns.each do |table| + table.second.each do |column| + + if valid_couple_table_attr? table.first, column.first + PreferenceListDossier.create( + libelle: column.second[:libelle], + table: column.second[:table], + attr: column.second[:attr], + attr_decorate: column.second[:attr_decorate], + bootstrap_lg: column.second[:bootstrap_lg], + order: nil, + filter: nil, + gestionnaire: self + ) + end + end + end + end + + private + + def valid_couple_table_attr? table, column + couples = [{ + table: :dossier, + column: :dossier_id + }, { + table: :procedure, + column: :libelle + }, { + table: :etablissement, + column: :siret + }, { + table: :entreprise, + column: :raison_sociale + }, { + table: :dossier, + column: :state + }] + + couples.include?({table: table, column: column}) + end end diff --git a/app/models/preference_list_dossier.rb b/app/models/preference_list_dossier.rb index 93befa9d0..a6a57f985 100644 --- a/app/models/preference_list_dossier.rb +++ b/app/models/preference_list_dossier.rb @@ -2,7 +2,7 @@ class PreferenceListDossier < ActiveRecord::Base belongs_to :gestionnaire def table_attr - return self.attr if table.empty? + return self.attr if table.nil? || table.empty? table + '.' + attr end diff --git a/app/views/backoffice/dossiers/_list.html.haml b/app/views/backoffice/dossiers/_list.html.haml index 3afa85d7a..8add886a6 100644 --- a/app/views/backoffice/dossiers/_list.html.haml +++ b/app/views/backoffice/dossiers/_list.html.haml @@ -10,7 +10,7 @@ %tr - current_gestionnaire.preference_list_dossiers.order(:id).each_with_index do |preference, index| %td - - if preference.table.empty? + - if preference.table.nil? || preference.table.empty? - value = dossier.decorate.public_send(preference.attr_decorate) - else - value = dossier.public_send(preference.table).decorate.public_send(preference.attr_decorate) diff --git a/db/migrate/20160802113112_build_default_preference_list_dossier.rb b/db/migrate/20160802113112_build_default_preference_list_dossier.rb new file mode 100644 index 000000000..d5fad79a4 --- /dev/null +++ b/db/migrate/20160802113112_build_default_preference_list_dossier.rb @@ -0,0 +1,133 @@ +class BuildDefaultPreferenceListDossier < ActiveRecord::Migration + class Gestionnaire < ActiveRecord::Base + def build_default_preferences_list_dossier + + PreferenceListDossier.available_columns.each do |table| + table.second.each do |column| + + if valid_couple_table_attr? table.first, column.first + PreferenceListDossier.create( + libelle: column.second[:libelle], + table: column.second[:table], + attr: column.second[:attr], + attr_decorate: column.second[:attr_decorate], + bootstrap_lg: column.second[:bootstrap_lg], + order: nil, + filter: nil, + gestionnaire_id: self.id + ) + end + end + end + end + + def valid_couple_table_attr? table, column + couples = [{ + table: :dossier, + column: :dossier_id + }, { + table: :procedure, + column: :libelle + }, { + table: :etablissement, + column: :siret + }, { + table: :entreprise, + column: :raison_sociale + }, { + table: :dossier, + column: :state + }] + + couples.include?({table: table, column: column}) + end + end + + class PreferenceListDossier < ActiveRecord::Base + def self.available_columns + { + dossier: columns_dossier, + procedure: columns_procedure, + entreprise: columns_entreprise, + etablissement: columns_etablissement, + user: columns_user + } + end + + def self.columns_dossier + table = nil + + { + dossier_id: create_column('ID', table, 'id', 'id', 1), + created_at: create_column('Créé le', table, 'created_at', 'first_creation', 2), + updated_at: create_column('Mise à jour le', table, 'updated_at', 'last_update', 2), + state: create_column('Statut', table, 'state', 'display_state', 1) + } + end + + def self.columns_procedure + table = 'procedure' + + { + libelle: create_column('Libellé procédure', table, 'libelle', 'libelle', 4), + organisation: create_column('Organisation', table, 'organisation', 'organisation', 3), + direction: create_column('Direction', table, 'direction', 'direction', 3) + } + end + + def self.columns_entreprise + table = 'entreprise' + + { + siren: create_column('SIREN', table, 'siren', 'siren', 2), + forme_juridique: create_column('Forme juridique', table, 'forme_juridique', 'forme_juridique', 3), + nom_commercial: create_column('Nom commercial', table, 'nom_commercial', 'nom_commercial', 3), + raison_sociale: create_column('Raison sociale', table, 'raison_sociale', 'raison_sociale', 3), + siret_siege_social: create_column('SIRET siège social', table, 'siret_siege_social', 'siret_siege_social', 2), + date_creation: create_column('Date de création', table, 'date_creation', 'date_creation', 2), + } + end + + def self.columns_etablissement + table = 'etablissement' + + { + siret: create_column('SIRET', table, 'siret', 'siret', 2), + libelle: create_column('Nom établissement', table, 'libelle_naf', 'libelle_naf', 3), + code_postal: create_column('Code postal', table, 'code_postal', 'code_postal', 1) + } + end + + def self.columns_user + table = 'user' + + { + email: create_column('Email', table, 'email', 'email', 2) + } + end + + def self.create_column libelle, table, attr, attr_decorate, bootstrap_lg + { + libelle: libelle, + table: table, + attr: attr, + attr_decorate: attr_decorate, + bootstrap_lg: bootstrap_lg, + order: nil, + filter: nil + } + end + end + + def up + Gestionnaire.all.each do |gestionnaire| + gestionnaire.build_default_preferences_list_dossier + end + end + + def down + Gestionnaire.all.each do |gestionnaire| + PreferenceListDossier.where(gestionnaire_id: gestionnaire.id).delete_all + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 0a0f042e0..5eed35e00 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160722135927) do +ActiveRecord::Schema.define(version: 20160802113112) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" diff --git a/spec/features/backoffice/navigate_to_dossier_spec.rb b/spec/features/backoffice/navigate_to_dossier_spec.rb index 05114df6e..56d046347 100644 --- a/spec/features/backoffice/navigate_to_dossier_spec.rb +++ b/spec/features/backoffice/navigate_to_dossier_spec.rb @@ -10,12 +10,6 @@ feature 'on backoffice page' do before do create :assign_to, gestionnaire: gestionnaire, procedure: procedure - create :preference_list_dossier, - gestionnaire: gestionnaire, - table: 'entreprise', - attr: 'raison_sociale', - attr_decorate: 'raison_sociale' - visit backoffice_path end @@ -24,12 +18,10 @@ feature 'on backoffice page' do page.find_by_id(:gestionnaire_email).set gestionnaire.email page.find_by_id(:gestionnaire_password).set gestionnaire.password page.click_on 'Se connecter' - - end context 'when he click on first dossier' do before do - page.click_on dossier.entreprise.raison_sociale + page.click_on dossier.id end scenario 'it redirect to dossier page' do expect(page).to have_css('#backoffice_dossier_show') diff --git a/spec/models/gestionnaire_spec.rb b/spec/models/gestionnaire_spec.rb index e485b028f..ff8762702 100644 --- a/spec/models/gestionnaire_spec.rb +++ b/spec/models/gestionnaire_spec.rb @@ -156,4 +156,39 @@ describe Gestionnaire, type: :model do it { expect(Follow.all.size).to eq 1 } it { expect(subject.first).to eq dossier } end + + describe '#build_default_preferences_list_dossier' do + subject { gestionnaire.preference_list_dossiers } + + context 'when gestionnaire is created' do + it 'build default 5 pref list dossier object' do + expect(subject.size).to eq 5 + end + + it 'build dossier_id column' do + expect(subject.first.table).to be_nil + expect(subject.first.attr).to eq 'id' + end + + it 'build dossier state column' do + expect(subject[1].table).to be_nil + expect(subject[1].attr).to eq 'state' + end + + it 'build procedure libelle column' do + expect(subject[2].table).to eq 'procedure' + expect(subject[2].attr).to eq 'libelle' + end + + it 'build entreprise raison_sociale column' do + expect(subject[3].table).to eq 'entreprise' + expect(subject[3].attr).to eq 'raison_sociale' + end + + it 'build entreprise raison_sociale column' do + expect(subject.last.table).to eq 'etablissement' + expect(subject.last.attr).to eq 'siret' + end + end + end end From 26b5e4cb24aa3fc11288ad2512876048d9d3317b Mon Sep 17 00:00:00 2001 From: Xavier J Date: Tue, 2 Aug 2016 16:13:15 +0200 Subject: [PATCH 04/10] Add model TypeDeChampPrivate --- app/models/procedure.rb | 1 + app/models/type_de_champ.rb | 2 ++ app/models/type_de_champ_private.rb | 9 +++++++++ app/serializers/procedure_serializer.rb | 5 +++-- app/serializers/type_de_champ_serializer.rb | 3 ++- .../20160802131031_add_public_attr_on_type_de_champ.rb | 5 +++++ db/schema.rb | 3 ++- 7 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 app/models/type_de_champ_private.rb create mode 100644 db/migrate/20160802131031_add_public_attr_on_type_de_champ.rb diff --git a/app/models/procedure.rb b/app/models/procedure.rb index cd90371f7..c09adbe39 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -1,6 +1,7 @@ class Procedure < ActiveRecord::Base has_many :types_de_piece_justificative, dependent: :destroy has_many :types_de_champ, dependent: :destroy + has_many :types_de_champ_private, class_name: 'TypeDeChampPrivate', dependent: :destroy has_many :dossiers has_one :procedure_path, dependent: :destroy diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index e4df31ea0..6a738957f 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -18,6 +18,8 @@ class TypeDeChamp < ActiveRecord::Base has_many :champ, dependent: :destroy + default_scope { where(private: false) } + validates :libelle, presence: true, allow_blank: false, allow_nil: false validates :type_champ, presence: true, allow_blank: false, allow_nil: false # validates :order_place, presence: true, allow_blank: false, allow_nil: false diff --git a/app/models/type_de_champ_private.rb b/app/models/type_de_champ_private.rb new file mode 100644 index 000000000..c9acf24e2 --- /dev/null +++ b/app/models/type_de_champ_private.rb @@ -0,0 +1,9 @@ +class TypeDeChampPrivate < TypeDeChamp + after_initialize :force_private_value + + default_scope { where(private: true) } + + def force_private_value + self.private = true + end +end \ No newline at end of file diff --git a/app/serializers/procedure_serializer.rb b/app/serializers/procedure_serializer.rb index 69d3bf307..c85ed7ff4 100644 --- a/app/serializers/procedure_serializer.rb +++ b/app/serializers/procedure_serializer.rb @@ -12,6 +12,7 @@ class ProcedureSerializer < ActiveModel::Serializer has_one :geographic_information, serializer: ModuleApiCartoSerializer - has_many :types_de_champ, serializer: TypeDeChampSerializer - has_many :types_de_piece_justificative, serializer: TypeDePieceJustificativeSerializer + has_many :types_de_champ, serializer: TypeDeChampSerializer + has_many :types_de_champ_private, serializer: TypeDeChampSerializer + has_many :types_de_piece_justificative, serializer: TypeDePieceJustificativeSerializer end diff --git a/app/serializers/type_de_champ_serializer.rb b/app/serializers/type_de_champ_serializer.rb index bbe2cb7dc..ebf66c0b8 100644 --- a/app/serializers/type_de_champ_serializer.rb +++ b/app/serializers/type_de_champ_serializer.rb @@ -3,5 +3,6 @@ class TypeDeChampSerializer < ActiveModel::Serializer :libelle, {:type_champ => :type}, :order_place, - :description + :description, + :private end \ No newline at end of file diff --git a/db/migrate/20160802131031_add_public_attr_on_type_de_champ.rb b/db/migrate/20160802131031_add_public_attr_on_type_de_champ.rb new file mode 100644 index 000000000..05491de73 --- /dev/null +++ b/db/migrate/20160802131031_add_public_attr_on_type_de_champ.rb @@ -0,0 +1,5 @@ +class AddPublicAttrOnTypeDeChamp < ActiveRecord::Migration + def change + add_column :types_de_champ, :private, :boolean, default: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 5eed35e00..65a008f87 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160802113112) do +ActiveRecord::Schema.define(version: 20160802131031) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -296,6 +296,7 @@ ActiveRecord::Schema.define(version: 20160802113112) do t.integer "procedure_id" t.text "description" t.boolean "mandatory", default: false + t.boolean "private", default: false end create_table "types_de_piece_justificative", force: :cascade do |t| From 116dd0d94fada647c66bc2b55b366ee04d229145 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Wed, 3 Aug 2016 18:19:56 +0200 Subject: [PATCH 05/10] Administrateur can be define private champs => same as typical champs --- .../admin/types_de_champ_controller.rb | 2 +- .../types_de_champ_private_controller.rb | 44 ++++ app/decorators/type_de_champ_decorator.rb | 23 +- .../type_de_champ_private_decorator.rb | 3 + app/models/procedure.rb | 13 +- app/models/type_de_champ.rb | 2 - app/models/type_de_champ_private.rb | 6 - app/models/type_de_champ_public.rb | 3 + app/serializers/type_de_champ_serializer.rb | 3 +- app/views/admin/procedures/_navbar.html.haml | 4 + .../admin/types_de_champ/_fields.html.haml | 4 +- .../admin/types_de_champ/_form.html.haml | 2 +- .../types_de_champ_private/_fields.html.haml | 38 ++++ .../types_de_champ_private/_form.html.haml | 6 + .../types_de_champ_private/show.html.haml | 4 + .../admin/types_de_champ_private/show.js.erb | 5 + config/initializers/inflections.rb | 1 + config/routes.rb | 13 +- ...02161734_add_type_attr_on_type_de_champ.rb | 5 + ...fix_default_type_on_type_de_champ_table.rb | 17 ++ db/schema.rb | 4 +- .../admin/types_de_champ_controller_spec.rb | 18 +- .../types_de_champ_private_controller_spec.rb | 202 ++++++++++++++++++ .../api/v1/dossiers_controller_spec.rb | 2 +- .../type_de_champ_decorator_spec.rb | 6 +- spec/factories/procedure.rb | 14 +- spec/factories/type_de_champ_private.rb | 9 + ...pe_de_champ.rb => type_de_champ_public.rb} | 2 +- .../move_down_type_de_champ_private_spec.rb | 29 +++ .../admin/move_down_type_de_champ_spec.rb | 8 +- .../move_up_type_de_champ_private_spec.rb | 29 +++ .../admin/move_up_type_de_champ_spec.rb | 8 +- spec/models/champ_spec.rb | 4 +- spec/models/dossier_spec.rb | 10 +- spec/models/procedure_spec.rb | 12 +- spec/models/type_de_champ_private_spec.rb | 7 + spec/models/type_de_champ_public_spec.rb | 7 + spec/models/type_de_champ_shared_example.rb | 44 ++++ spec/models/type_de_champ_spec.rb | 43 +--- .../types_de_champ/show.html.haml_spec.rb | 10 +- .../show.html.haml_spec.rb | 48 +++++ 41 files changed, 601 insertions(+), 113 deletions(-) create mode 100644 app/controllers/admin/types_de_champ_private_controller.rb create mode 100644 app/decorators/type_de_champ_private_decorator.rb create mode 100644 app/models/type_de_champ_public.rb create mode 100644 app/views/admin/types_de_champ_private/_fields.html.haml create mode 100644 app/views/admin/types_de_champ_private/_form.html.haml create mode 100644 app/views/admin/types_de_champ_private/show.html.haml create mode 100644 app/views/admin/types_de_champ_private/show.js.erb create mode 100644 db/migrate/20160802161734_add_type_attr_on_type_de_champ.rb create mode 100644 db/migrate/20160803081304_fix_default_type_on_type_de_champ_table.rb create mode 100644 spec/controllers/admin/types_de_champ_private_controller_spec.rb create mode 100644 spec/factories/type_de_champ_private.rb rename spec/factories/{type_de_champ.rb => type_de_champ_public.rb} (82%) create mode 100644 spec/features/admin/move_down_type_de_champ_private_spec.rb create mode 100644 spec/features/admin/move_up_type_de_champ_private_spec.rb create mode 100644 spec/models/type_de_champ_private_spec.rb create mode 100644 spec/models/type_de_champ_public_spec.rb create mode 100644 spec/models/type_de_champ_shared_example.rb create mode 100644 spec/views/admin/types_de_champ_private/show.html.haml_spec.rb diff --git a/app/controllers/admin/types_de_champ_controller.rb b/app/controllers/admin/types_de_champ_controller.rb index 6aa974d74..8eab26c02 100644 --- a/app/controllers/admin/types_de_champ_controller.rb +++ b/app/controllers/admin/types_de_champ_controller.rb @@ -21,7 +21,7 @@ class Admin::TypesDeChampController < AdminController def update_params params .require(:procedure) - .permit(types_de_champ_attributes: [:libelle, :description, :order_place, :type_champ, :id, :mandatory]) + .permit(types_de_champ_attributes: [:libelle, :description, :order_place, :type_champ, :id, :mandatory, :type]) end def move_up diff --git a/app/controllers/admin/types_de_champ_private_controller.rb b/app/controllers/admin/types_de_champ_private_controller.rb new file mode 100644 index 000000000..d8f1af66c --- /dev/null +++ b/app/controllers/admin/types_de_champ_private_controller.rb @@ -0,0 +1,44 @@ +class Admin::TypesDeChampPrivateController < AdminController + before_action :retrieve_procedure + before_action :procedure_locked? + + def destroy + @procedure.types_de_champ_private.destroy(params[:id]) + render 'show', format: :js + rescue ActiveRecord::RecordNotFound + render json: { message: 'Champ not found' }, status: 404 + end + + def show + + end + + def update + @procedure.update_attributes(update_params) + flash.now.notice = 'Modifications sauvegardées' + render 'show', format: :js + end + + def update_params + params + .require(:procedure) + .permit(types_de_champ_private_attributes: [:libelle, :description, :order_place, :type_champ, :id, :mandatory, :type]) + end + + def move_up + index = params[:index].to_i - 1 + if @procedure.switch_types_de_champ_private index + render 'show', format: :js + else + render json: {}, status: 400 + end + end + + def move_down + if @procedure.switch_types_de_champ_private params[:index].to_i + render 'show', format: :js + else + render json: {}, status: 400 + end + end +end \ No newline at end of file diff --git a/app/decorators/type_de_champ_decorator.rb b/app/decorators/type_de_champ_decorator.rb index 6e92f6647..d149996a7 100644 --- a/app/decorators/type_de_champ_decorator.rb +++ b/app/decorators/type_de_champ_decorator.rb @@ -1,12 +1,13 @@ - class TypeDeChampDecorator < Draper::Decorator + delegate_all + def button_up params - h.link_to '', params[:url], class: up_classes, id: "btn_up_#{params[:index]}", remote: true, method: :post if display_up_button?(params[:index]) + h.link_to '', params[:url], class: up_classes, id: "btn_up_#{params[:index]}", remote: true, method: :post if display_up_button?(params[:index], params[:private]) end def button_down params - h.link_to '', params[:url], class: down_classes, id: "btn_down_#{params[:index]}", remote: true, method: :post if display_down_button?(params[:index]) + h.link_to '', params[:url], class: down_classes, id: "btn_down_#{params[:index]}", remote: true, method: :post if display_down_button?(params[:index], params[:private]) end private @@ -23,15 +24,19 @@ class TypeDeChampDecorator < Draper::Decorator %w(btn btn-default form-control fa) end - def display_up_button?(index) - !(index == 0 || count_type_de_champ < 2) + def display_up_button?(index, private) + !(index == 0 || count_type_de_champ(private) < 2) end - def display_down_button?(index) - (index + 1) < count_type_de_champ + def display_down_button?(index, private) + (index + 1) < count_type_de_champ(private) end - def count_type_de_champ - @count_type_de_champ ||= procedure.types_de_champ.count + def count_type_de_champ private + if private + @count_type_de_champ ||= procedure.types_de_champ_private.count + else + @count_type_de_champ ||= procedure.types_de_champ.count + end end end \ No newline at end of file diff --git a/app/decorators/type_de_champ_private_decorator.rb b/app/decorators/type_de_champ_private_decorator.rb new file mode 100644 index 000000000..1adcaca84 --- /dev/null +++ b/app/decorators/type_de_champ_private_decorator.rb @@ -0,0 +1,3 @@ +class TypeDeChampPrivateDecorator < TypeDeChampDecorator + +end \ No newline at end of file diff --git a/app/models/procedure.rb b/app/models/procedure.rb index c09adbe39..73f950cef 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -1,7 +1,7 @@ class Procedure < ActiveRecord::Base has_many :types_de_piece_justificative, dependent: :destroy - has_many :types_de_champ, dependent: :destroy - has_many :types_de_champ_private, class_name: 'TypeDeChampPrivate', dependent: :destroy + has_many :types_de_champ, class_name: 'TypeDeChampPublic', dependent: :destroy + has_many :types_de_champ_private, dependent: :destroy has_many :dossiers has_one :procedure_path, dependent: :destroy @@ -18,6 +18,7 @@ class Procedure < ActiveRecord::Base accepts_nested_attributes_for :types_de_champ,:reject_if => proc { |attributes| attributes['libelle'].blank? }, :allow_destroy => true accepts_nested_attributes_for :types_de_piece_justificative, :reject_if => proc { |attributes| attributes['libelle'].blank? }, :allow_destroy => true accepts_nested_attributes_for :module_api_carto + accepts_nested_attributes_for :types_de_champ_private mount_uploader :logo, ProcedureLogoUploader @@ -36,6 +37,10 @@ class Procedure < ActiveRecord::Base types_de_champ.order(:order_place) end + def types_de_champ_private_ordered + types_de_champ_private.order(:order_place) + end + def types_de_piece_justificative_ordered types_de_piece_justificative.order(:order_place) end @@ -52,6 +57,10 @@ class Procedure < ActiveRecord::Base switch_list_order(types_de_champ_ordered, index_of_first_element) end + def switch_types_de_champ_private index_of_first_element + switch_list_order(types_de_champ_private_ordered, index_of_first_element) + end + def switch_types_de_piece_justificative index_of_first_element switch_list_order(types_de_piece_justificative_ordered, index_of_first_element) end diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index 6a738957f..e4df31ea0 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -18,8 +18,6 @@ class TypeDeChamp < ActiveRecord::Base has_many :champ, dependent: :destroy - default_scope { where(private: false) } - validates :libelle, presence: true, allow_blank: false, allow_nil: false validates :type_champ, presence: true, allow_blank: false, allow_nil: false # validates :order_place, presence: true, allow_blank: false, allow_nil: false diff --git a/app/models/type_de_champ_private.rb b/app/models/type_de_champ_private.rb index c9acf24e2..804bb2e99 100644 --- a/app/models/type_de_champ_private.rb +++ b/app/models/type_de_champ_private.rb @@ -1,9 +1,3 @@ class TypeDeChampPrivate < TypeDeChamp - after_initialize :force_private_value - default_scope { where(private: true) } - - def force_private_value - self.private = true - end end \ No newline at end of file diff --git a/app/models/type_de_champ_public.rb b/app/models/type_de_champ_public.rb new file mode 100644 index 000000000..90052b762 --- /dev/null +++ b/app/models/type_de_champ_public.rb @@ -0,0 +1,3 @@ +class TypeDeChampPublic < TypeDeChamp + +end \ No newline at end of file diff --git a/app/serializers/type_de_champ_serializer.rb b/app/serializers/type_de_champ_serializer.rb index ebf66c0b8..bbe2cb7dc 100644 --- a/app/serializers/type_de_champ_serializer.rb +++ b/app/serializers/type_de_champ_serializer.rb @@ -3,6 +3,5 @@ class TypeDeChampSerializer < ActiveModel::Serializer :libelle, {:type_champ => :type}, :order_place, - :description, - :private + :description end \ No newline at end of file diff --git a/app/views/admin/procedures/_navbar.html.haml b/app/views/admin/procedures/_navbar.html.haml index 25198c9b0..6a382894a 100644 --- a/app/views/admin/procedures/_navbar.html.haml +++ b/app/views/admin/procedures/_navbar.html.haml @@ -16,5 +16,9 @@ = link_to_unless(@procedure.locked?, 'Pièces justificatives', admin_procedure_pieces_justificatives_path(@procedure)) do = link_to('Pièces justificatives', '#') +%li{ class: ('disabled' if @procedure.locked?) || ('active' if active == 'Champs privés') } + = link_to_unless(@procedure.locked?, 'Champs privés', admin_procedure_types_de_champ_private_path(@procedure)) do + = link_to('Champs privés', '#') + %li{ class: ('active' if active == 'Prévisualisation'), style: 'float:right' } = link_to('Prévisualisation', admin_procedure_previsualisation_path(@procedure), {style: 'font-style: italic;'}) \ No newline at end of file diff --git a/app/views/admin/types_de_champ/_fields.html.haml b/app/views/admin/types_de_champ/_fields.html.haml index 4103a2329..dd0250fbd 100644 --- a/app/views/admin/types_de_champ/_fields.html.haml +++ b/app/views/admin/types_de_champ/_fields.html.haml @@ -6,7 +6,7 @@ .form-group.type %h4 Type - = ff.select :type_champ, TypeDeChamp.type_champs, {}, {class: 'form-control type_champ'} + = ff.select :type_champ, TypeDeChampPublic.type_champs, {}, {class: 'form-control type_champ'} .form-group.description %h4 Description @@ -19,6 +19,7 @@ .form-group = ff.hidden_field :order_place, value: ff.index + = ff.hidden_field :type = ff.hidden_field :id - unless ff.object.id.nil? .form-group @@ -26,7 +27,6 @@ = ff.object.button_up(index: ff.index, url: move_up_admin_procedure_types_de_champ_path(@procedure, ff.index)) = ff.object.button_down(index: ff.index, url: move_down_admin_procedure_types_de_champ_path(@procedure, ff.index)) - .form-group %br   - if ff.object.id.nil? diff --git a/app/views/admin/types_de_champ/_form.html.haml b/app/views/admin/types_de_champ/_form.html.haml index 2b2ce0b37..d92771855 100644 --- a/app/views/admin/types_de_champ/_form.html.haml +++ b/app/views/admin/types_de_champ/_form.html.haml @@ -3,4 +3,4 @@ = f.submit "Enregistrer", class: 'btn btn-success', id: :save %hr #new_type_de_champ - = render partial: 'fields', locals: { types_de_champ: TypeDeChamp.new.decorate, f: f } + = render partial: 'fields', locals: { types_de_champ: TypeDeChampPublic.new.decorate, f: f } diff --git a/app/views/admin/types_de_champ_private/_fields.html.haml b/app/views/admin/types_de_champ_private/_fields.html.haml new file mode 100644 index 000000000..6da37a941 --- /dev/null +++ b/app/views/admin/types_de_champ_private/_fields.html.haml @@ -0,0 +1,38 @@ += f.fields_for :types_de_champ_private, types_de_champ_private, remote: true do |ff| + .form-inline{class:"#{ff.object.object.type_champ == 'header_section' ? 'header_section' : ''}"} + .form-group.libelle + %h4 Libellé + = ff.text_field :libelle, class: 'form-control libelle', placeholder: 'Libellé' + + .form-group.type + %h4 Type + = ff.select :type_champ, TypeDeChampPrivate.type_champs, {}, {class: 'form-control type_champ'} + + .form-group.description + %h4 Description + = ff.text_area :description, class: 'form-control description', placeholder: 'Description' + + .form-group.mandatory + %h4 Obligatoire ? + .center + = ff.check_box :mandatory, placeholder: 'Obligatoire ?' + + .form-group + = ff.hidden_field :order_place, value: ff.index + = ff.hidden_field :type + = ff.hidden_field :id + + - unless ff.object.id.nil? + .form-group + %br   + = ff.object.button_up(index: ff.index, url: move_up_admin_procedure_types_de_champ_private_path(@procedure, ff.index), private: true) + = ff.object.button_down(index: ff.index, url: move_down_admin_procedure_types_de_champ_private_path(@procedure, ff.index), private: true) + + .form-group + %br   + - if ff.object.id.nil? + = f.submit "Ajouter le champ", class: 'btn btn-success', id: :add_type_de_champ_private + - else + = link_to("", admin_procedure_type_de_champ_private_path(@procedure, ff.object.id), method: :delete, remote: true, id: "delete_type_de_champ_private_#{ff.object.id}", class: %w(form-control btn btn-danger fa fa-trash-o) ) + + diff --git a/app/views/admin/types_de_champ_private/_form.html.haml b/app/views/admin/types_de_champ_private/_form.html.haml new file mode 100644 index 000000000..a098de1f8 --- /dev/null +++ b/app/views/admin/types_de_champ_private/_form.html.haml @@ -0,0 +1,6 @@ += form_for [:admin, @procedure], url: admin_procedure_types_de_champ_private_path(@procedure) , remote: true do |f| + = render partial: 'fields', locals: { types_de_champ_private: @procedure.types_de_champ_private_ordered.decorate, f: f } + = f.submit "Enregistrer", class: 'btn btn-success', id: :save + %hr + #new_type_de_champ + = render partial: 'fields', locals: { types_de_champ_private: TypeDeChampPrivate.new.decorate, f: f } diff --git a/app/views/admin/types_de_champ_private/show.html.haml b/app/views/admin/types_de_champ_private/show.html.haml new file mode 100644 index 000000000..464f9083d --- /dev/null +++ b/app/views/admin/types_de_champ_private/show.html.haml @@ -0,0 +1,4 @@ +=render partial: 'admin/procedures/head', locals: {active: 'Champs privés'} + +#liste_champ + = render partial: 'form' \ No newline at end of file diff --git a/app/views/admin/types_de_champ_private/show.js.erb b/app/views/admin/types_de_champ_private/show.js.erb new file mode 100644 index 000000000..259d609e3 --- /dev/null +++ b/app/views/admin/types_de_champ_private/show.js.erb @@ -0,0 +1,5 @@ +<% flash.each do |type, message| %> +$("#flash_message").html("
<%= message.html_safe %>
").children().fadeOut(5000) +<% end %> +$('#liste_champ').html("<%= escape_javascript(render partial: 'form', locals: { procedure: @procedure, types_de_champ: @types_de_champ } ) %>"); +on_change_type_de_champ_select (); \ No newline at end of file diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index 1e5e84144..940e78aad 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -13,6 +13,7 @@ ActiveSupport::Inflector.inflections(:en) do |inflect| inflect.irregular 'piece_justificative', 'pieces_justificatives' inflect.irregular 'type_de_piece_justificative', 'types_de_piece_justificative' inflect.irregular 'type_de_champ', 'types_de_champ' + inflect.irregular 'type_de_champ_private', 'types_de_champ_private' inflect.irregular 'assign_to', 'assign_tos' end diff --git a/config/routes.rb b/config/routes.rb index cb11c81c3..a60906714 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -93,10 +93,20 @@ Rails.application.routes.draw do get 'profile' => 'profile#show', as: :profile resources :procedures do + resources :types_de_champ, only: [:destroy] resource :types_de_champ, only: [:show, :update] do post '/:index/move_up' => 'types_de_champ#move_up', as: :move_up post '/:index/move_down' => 'types_de_champ#move_down', as: :move_down end + + resources :types_de_champ_private, only: [:destroy] + resource :types_de_champ_private, only: [:show, :update] do + post '/:index/move_up' => 'types_de_champ_private#move_up', as: :move_up + post '/:index/move_down' => 'types_de_champ_private#move_down', as: :move_down + end + + resource :pieces_justificatives, only: [:show, :update] + resources :pieces_justificatives, only: :destroy resource :pieces_justificatives, only: [:show, :update] do post '/:index/move_up' => 'pieces_justificatives#move_up', as: :move_up post '/:index/move_down' => 'pieces_justificatives#move_down', as: :move_down @@ -111,9 +121,6 @@ Rails.application.routes.draw do resource :previsualisation, only: [:show] - resources :types_de_champ, only: [:destroy] - resource :pieces_justificatives, only: [:show, :update] - resources :pieces_justificatives, only: :destroy end namespace :accompagnateurs do diff --git a/db/migrate/20160802161734_add_type_attr_on_type_de_champ.rb b/db/migrate/20160802161734_add_type_attr_on_type_de_champ.rb new file mode 100644 index 000000000..d1ab25589 --- /dev/null +++ b/db/migrate/20160802161734_add_type_attr_on_type_de_champ.rb @@ -0,0 +1,5 @@ +class AddTypeAttrOnTypeDeChamp < ActiveRecord::Migration + def change + add_column :types_de_champ, :type, :string + end +end diff --git a/db/migrate/20160803081304_fix_default_type_on_type_de_champ_table.rb b/db/migrate/20160803081304_fix_default_type_on_type_de_champ_table.rb new file mode 100644 index 000000000..b5aec3a3a --- /dev/null +++ b/db/migrate/20160803081304_fix_default_type_on_type_de_champ_table.rb @@ -0,0 +1,17 @@ +class FixDefaultTypeOnTypeDeChampTable < ActiveRecord::Migration + class TypeDeChamp < ActiveRecord::Base + + end + + def up + TypeDeChamp.where("private = false").update_all("type = 'TypeDeChampPublic'") + TypeDeChamp.where("private = true").update_all("type = 'TypeDeChampPrivate'") + remove_column :types_de_champ, :private + end + + def down + add_column :types_de_champ, :private, :boolean, default: true + TypeDeChamp.where("type = 'TypeDeChampPublic'").update_all("private = false") + TypeDeChamp.where("type = 'TypeDeChampPrivate'").update_all("private = true") + end +end diff --git a/db/schema.rb b/db/schema.rb index 65a008f87..d022e46cd 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160802131031) do +ActiveRecord::Schema.define(version: 20160803081304) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -296,7 +296,7 @@ ActiveRecord::Schema.define(version: 20160802131031) do t.integer "procedure_id" t.text "description" t.boolean "mandatory", default: false - t.boolean "private", default: false + t.string "type" end create_table "types_de_piece_justificative", force: :cascade do |t| diff --git a/spec/controllers/admin/types_de_champ_controller_spec.rb b/spec/controllers/admin/types_de_champ_controller_spec.rb index c334ccb0c..68203e16f 100644 --- a/spec/controllers/admin/types_de_champ_controller_spec.rb +++ b/spec/controllers/admin/types_de_champ_controller_spec.rb @@ -121,7 +121,7 @@ describe Admin::TypesDeChampController, type: :controller do end end context 'when procedure and type de champs are not linked' do - let(:type_de_champ) { create(:type_de_champ) } + let(:type_de_champ) { create(:type_de_champ_public) } let(:type_de_champ_id) { type_de_champ.id } it { expect(subject.status).to eq(404) } end @@ -136,20 +136,20 @@ describe Admin::TypesDeChampController, type: :controller do end context 'when procedure have only one type de champ' do let(:index) { 1 } - let!(:type_de_champ) { create(:type_de_champ, procedure: procedure) } + let!(:type_de_champ) { create(:type_de_champ_public, procedure: procedure) } it { expect(subject.status).to eq(400) } end context 'when procedure have tow type de champs' do context 'when index == 0' do let(:index) { 0 } - let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure) } - let!(:type_de_champ_2) { create(:type_de_champ, procedure: procedure) } + let!(:type_de_champ_1) { create(:type_de_champ_public, procedure: procedure) } + let!(:type_de_champ_2) { create(:type_de_champ_public, procedure: procedure) } it { expect(subject.status).to eq(400) } end context 'when index > 0' do let(:index) { 1 } - let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) } - let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) } + let!(:type_de_champ_0) { create(:type_de_champ_public, procedure: procedure, order_place: 0) } + let!(:type_de_champ_1) { create(:type_de_champ_public, procedure: procedure, order_place: 1) } it { expect(subject.status).to eq(200) } it { expect(subject).to render_template('show') } @@ -174,12 +174,12 @@ describe Admin::TypesDeChampController, type: :controller do it { expect(subject.status).to eq(400) } end context 'when procedure have only one type de champ' do - let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure) } + let!(:type_de_champ_0) { create(:type_de_champ_public, procedure: procedure) } it { expect(subject.status).to eq(400) } end context 'when procedure have 2 type de champ' do - let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) } - let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) } + let!(:type_de_champ_0) { create(:type_de_champ_public, procedure: procedure, order_place: 0) } + let!(:type_de_champ_1) { create(:type_de_champ_public, procedure: procedure, order_place: 1) } context 'when index represent last type_de_champ' do let(:index) { 1 } it { expect(subject.status).to eq(400) } diff --git a/spec/controllers/admin/types_de_champ_private_controller_spec.rb b/spec/controllers/admin/types_de_champ_private_controller_spec.rb new file mode 100644 index 000000000..2db709955 --- /dev/null +++ b/spec/controllers/admin/types_de_champ_private_controller_spec.rb @@ -0,0 +1,202 @@ +require 'spec_helper' + +describe Admin::TypesDeChampPrivateController, type: :controller do + let(:admin) { create(:administrateur) } + let(:procedure) { create(:procedure, administrateur: admin) } + + before do + sign_in admin + end + + describe 'GET #show' do + let(:published) { false } + let(:procedure) { create(:procedure, administrateur: admin, published: published) } + let(:procedure_id) { procedure.id } + + subject { get :show, procedure_id: procedure_id } + + context 'when procedure is not found' do + let(:procedure_id) { 9_999_999 } + it { expect(subject.status).to eq(404) } + end + + context 'when procedure is published' do + let(:published) { true } + it { is_expected.to redirect_to admin_procedure_path id: procedure_id } + end + + context 'when procedure does not belong to admin' do + let(:admin_2) { create(:administrateur) } + let(:procedure) { create(:procedure, administrateur: admin_2) } + it { expect(subject.status).to eq(404) } + end + end + + describe '#update' do + let(:libelle) { 'mon libelle' } + let(:type_champ) { 'text' } + let(:description) { 'titi' } + let(:order_place) { '' } + let(:types_de_champ_id) { '' } + let(:mandatory) { 'on' } + + let(:procedure_params) do + { types_de_champ_private_attributes: + { '0' => + { + libelle: libelle, + type_champ: type_champ, + description: description, + order_place: order_place, + id: types_de_champ_id, + mandatory: mandatory, + type: 'TypeDeChampPrivate' + } + } + } + end + + let(:request) { put :update, format: :js, procedure_id: procedure.id, procedure: procedure_params } + + context 'when procedure is found' do + it { expect{ request }.to change(TypeDeChamp, :count).by(1) } + + describe 'created type de champ' do + before do + request + procedure.reload + end + subject { procedure.types_de_champ_private.first } + + it { expect(subject.libelle).to eq('mon libelle') } + it { expect(subject.type_champ).to eq('text') } + it { expect(subject.description).to eq('titi') } + it { expect(subject.mandatory).to be_truthy } + end + + context 'when type_de_champ already exist' do + let(:procedure) { create(:procedure, :with_type_de_champ_private, administrateur: admin) } + let(:type_de_champ) { procedure.types_de_champ_private.first } + let(:types_de_champ_id) { type_de_champ.id } + let(:libelle) { 'toto' } + let(:type_champ) { 'text' } + let(:description) { 'citrouille' } + let(:order_place) { '0' } + let(:mandatory) { 'on' } + before do + request + procedure.reload + end + subject { procedure.types_de_champ_private.first } + it { expect(subject.libelle).to eq('toto') } + it { expect(subject.type_champ).to eq('text') } + it { expect(subject.description).to eq('citrouille') } + it { expect(subject.order_place).to eq(0) } + it { expect(subject.order_place).to be_truthy } + end + end + context 'when procedure is not found' do + subject { put :update, format: :js, procedure_id: 9_999_999, procedure: procedure_params } + it 'creates type de champ' do + expect(subject.status).to eq(404) + end + end + end + + describe '#destroy' do + before do + delete :destroy, procedure_id: procedure.id, id: type_de_champ_id, format: :js + end + + context 'when type de champs does not exist' do + let(:type_de_champ_id) { 99999999 } + it { expect(subject.status).to eq(404) } + end + context 'when types_de_champ exists' do + let(:procedure) { create(:procedure, :with_type_de_champ_private, administrateur: admin) } + let(:type_de_champ_id) { procedure.types_de_champ_private.first.id } + it { expect(subject.status).to eq(200) } + it 'destroy type de champ' do + procedure.reload + expect(procedure.types_de_champ.count).to eq(0) + end + end + context 'when procedure and type de champs are not linked' do + let(:type_de_champ) { create(:type_de_champ_public) } + let(:type_de_champ_id) { type_de_champ.id } + it { expect(subject.status).to eq(404) } + end + end + + describe 'POST #move_up' do + subject { post :move_up, procedure_id: procedure.id, index: index, format: :js } + + context 'when procedure have no type de champ' do + let(:index) { 0 } + it { expect(subject.status).to eq(400) } + end + context 'when procedure have only one type de champ' do + let(:index) { 1 } + let!(:type_de_champ) { create(:type_de_champ_private, procedure: procedure) } + it { expect(subject.status).to eq(400) } + end + context 'when procedure have tow type de champs' do + context 'when index == 0' do + let(:index) { 0 } + let!(:type_de_champ_1) { create(:type_de_champ_private, procedure: procedure) } + let!(:type_de_champ_2) { create(:type_de_champ_private, procedure: procedure) } + it { expect(subject.status).to eq(400) } + end + context 'when index > 0' do + let(:index) { 1 } + let!(:type_de_champ_0) { create(:type_de_champ_private, procedure: procedure, order_place: 0) } + let!(:type_de_champ_1) { create(:type_de_champ_private, procedure: procedure, order_place: 1) } + + it { expect(subject.status).to eq(200) } + it { expect(subject).to render_template('show') } + it 'changes order places' do + post :move_up, procedure_id: procedure.id, index: index, format: :js + type_de_champ_0.reload + type_de_champ_1.reload + expect(type_de_champ_0.order_place).to eq(1) + expect(type_de_champ_1.order_place).to eq(0) + end + end + end + end + + describe 'POST #move_down' do + let(:request) { post :move_down, procedure_id: procedure.id, index: index, format: :js } + let(:index) { 0 } + + subject { request } + + context 'when procedure have no type de champ' do + it { expect(subject.status).to eq(400) } + end + context 'when procedure have only one type de champ' do + let!(:type_de_champ_0) { create(:type_de_champ_private, procedure: procedure) } + it { expect(subject.status).to eq(400) } + end + context 'when procedure have 2 type de champ' do + let!(:type_de_champ_0) { create(:type_de_champ_private, procedure: procedure, order_place: 0) } + let!(:type_de_champ_1) { create(:type_de_champ_private, procedure: procedure, order_place: 1) } + context 'when index represent last type_de_champ' do + let(:index) { 1 } + it { expect(subject.status).to eq(400) } + end + context 'when index does not represent last type_de_champ' do + let(:index) { 0 } + it { expect(subject.status).to eq(200) } + it { expect(subject).to render_template('show') } + it 'changes order place' do + request + type_de_champ_0.reload + type_de_champ_1.reload + expect(type_de_champ_0.order_place).to eq(1) + expect(type_de_champ_1.order_place).to eq(0) + end + end + end + end +end diff --git a/spec/controllers/api/v1/dossiers_controller_spec.rb b/spec/controllers/api/v1/dossiers_controller_spec.rb index 6ff404ec4..a2eeaeeca 100644 --- a/spec/controllers/api/v1/dossiers_controller_spec.rb +++ b/spec/controllers/api/v1/dossiers_controller_spec.rb @@ -230,7 +230,7 @@ describe API::V1::DossiersController do it { expect(subject[:libelle]).to eq('Description') } it { expect(subject[:description]).to eq('description de votre projet') } it { expect(subject.keys.include?(:order_place)).to be_truthy } - it { expect(subject[:type]).to eq('text') } + it { expect(subject[:type_champ]).to eq('text') } end end end diff --git a/spec/decorators/type_de_champ_decorator_spec.rb b/spec/decorators/type_de_champ_decorator_spec.rb index 61a2bc73f..7ab455e00 100644 --- a/spec/decorators/type_de_champ_decorator_spec.rb +++ b/spec/decorators/type_de_champ_decorator_spec.rb @@ -5,9 +5,9 @@ describe TypeDeChampDecorator do let(:procedure) { create(:procedure) } let(:url) { 'http://localhost' } let(:params) { { url: url, index: index } } - let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) } - let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) } - let!(:type_de_champ_2) { create(:type_de_champ, procedure: procedure, order_place: 2) } + let!(:type_de_champ_0) { create(:type_de_champ_public, procedure: procedure, order_place: 0) } + let!(:type_de_champ_1) { create(:type_de_champ_public, procedure: procedure, order_place: 1) } + let!(:type_de_champ_2) { create(:type_de_champ_public, procedure: procedure, order_place: 2) } describe '#button_up' do diff --git a/spec/factories/procedure.rb b/spec/factories/procedure.rb index d8d5dc8c1..11cd238b1 100644 --- a/spec/factories/procedure.rb +++ b/spec/factories/procedure.rb @@ -24,15 +24,23 @@ FactoryGirl.define do trait :with_type_de_champ do after(:build) do |procedure, _evaluator| - type_de_champ = create(:type_de_champ) + type_de_champ = create(:type_de_champ_public) procedure.types_de_champ << type_de_champ end end + trait :with_type_de_champ_private do + after(:build) do |procedure, _evaluator| + type_de_champ = create(:type_de_champ_private) + + procedure.types_de_champ_private << type_de_champ + end + end + trait :with_type_de_champ_mandatory do after(:build) do |procedure, _evaluator| - type_de_champ = create(:type_de_champ, mandatory: true) + type_de_champ = create(:type_de_champ_public, mandatory: true) procedure.types_de_champ << type_de_champ end @@ -40,7 +48,7 @@ FactoryGirl.define do trait :with_datetime do after(:build) do |procedure, _evaluator| - type_de_champ = create(:type_de_champ, mandatory: true, type_champ: :datetime) + type_de_champ = create(:type_de_champ_public, mandatory: true, type_champ: :datetime) procedure.types_de_champ << type_de_champ end diff --git a/spec/factories/type_de_champ_private.rb b/spec/factories/type_de_champ_private.rb new file mode 100644 index 000000000..408279d05 --- /dev/null +++ b/spec/factories/type_de_champ_private.rb @@ -0,0 +1,9 @@ +FactoryGirl.define do + factory :type_de_champ_private do + libelle 'Description' + description 'description de votre projet' + type_champ 'text' + order_place 1 + mandatory false + end +end diff --git a/spec/factories/type_de_champ.rb b/spec/factories/type_de_champ_public.rb similarity index 82% rename from spec/factories/type_de_champ.rb rename to spec/factories/type_de_champ_public.rb index 8e348a254..937921d0d 100644 --- a/spec/factories/type_de_champ.rb +++ b/spec/factories/type_de_champ_public.rb @@ -1,5 +1,5 @@ FactoryGirl.define do - factory :type_de_champ do + factory :type_de_champ_public do libelle 'Description' description 'description de votre projet' type_champ 'text' diff --git a/spec/features/admin/move_down_type_de_champ_private_spec.rb b/spec/features/admin/move_down_type_de_champ_private_spec.rb new file mode 100644 index 000000000..b811617a0 --- /dev/null +++ b/spec/features/admin/move_down_type_de_champ_private_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +feature 'move down button type de champs', js: true do + let(:administrateur) { create(:administrateur) } + + before do + login_as administrateur, scope: :administrateur + end + + let(:procedure) { create(:procedure, administrateur: administrateur) } + let!(:type_de_champ_0) { create(:type_de_champ_private, procedure: procedure, order_place: 0) } + let!(:type_de_champ_1) { create(:type_de_champ_private, procedure: procedure, order_place: 1) } + let!(:type_de_champ_2) { create(:type_de_champ_private, procedure: procedure, order_place: 2) } + let!(:type_de_champ_3) { create(:type_de_champ_private, procedure: procedure, order_place: 3) } + + context 'when clicking on move down for type de champ 1' do + before do + visit admin_procedure_types_de_champ_private_path procedure.id + page.find_by_id('btn_down_1').click + wait_for_ajax + type_de_champ_1.reload + type_de_champ_2.reload + end + scenario 'it switches type_de_champ 1 and 2 place ' do + expect(type_de_champ_1.order_place).to eq(2) + expect(type_de_champ_2.order_place).to eq(1) + end + end +end diff --git a/spec/features/admin/move_down_type_de_champ_spec.rb b/spec/features/admin/move_down_type_de_champ_spec.rb index 84f291caf..0e9243cf9 100644 --- a/spec/features/admin/move_down_type_de_champ_spec.rb +++ b/spec/features/admin/move_down_type_de_champ_spec.rb @@ -8,10 +8,10 @@ feature 'move down button type de champs', js: true do end let(:procedure) { create(:procedure, administrateur: administrateur) } - let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) } - let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) } - let!(:type_de_champ_2) { create(:type_de_champ, procedure: procedure, order_place: 2) } - let!(:type_de_champ_3) { create(:type_de_champ, procedure: procedure, order_place: 3) } + let!(:type_de_champ_0) { create(:type_de_champ_public, procedure: procedure, order_place: 0) } + let!(:type_de_champ_1) { create(:type_de_champ_public, procedure: procedure, order_place: 1) } + let!(:type_de_champ_2) { create(:type_de_champ_public, procedure: procedure, order_place: 2) } + let!(:type_de_champ_3) { create(:type_de_champ_public, procedure: procedure, order_place: 3) } context 'when clicking on move down for type de champ 1' do before do diff --git a/spec/features/admin/move_up_type_de_champ_private_spec.rb b/spec/features/admin/move_up_type_de_champ_private_spec.rb new file mode 100644 index 000000000..377fcea61 --- /dev/null +++ b/spec/features/admin/move_up_type_de_champ_private_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +feature 'move up button type de champs', js: true do + let(:administrateur) { create(:administrateur) } + + before do + login_as administrateur, scope: :administrateur + end + + let(:procedure) { create(:procedure, administrateur: administrateur) } + let!(:type_de_champ_0) { create(:type_de_champ_private, procedure: procedure, order_place: 0) } + let!(:type_de_champ_1) { create(:type_de_champ_private, procedure: procedure, order_place: 1) } + let!(:type_de_champ_2) { create(:type_de_champ_private, procedure: procedure, order_place: 2) } + let!(:type_de_champ_3) { create(:type_de_champ_private, procedure: procedure, order_place: 3) } + + context 'when clicking on move down for type de champ 1' do + before do + visit admin_procedure_types_de_champ_private_path procedure.id + page.find_by_id('btn_up_1').click + wait_for_ajax + type_de_champ_0.reload + type_de_champ_1.reload + end + scenario 'it switches type_de_champ 1 and 2 place ' do + expect(type_de_champ_0.order_place).to eq(1) + expect(type_de_champ_1.order_place).to eq(0) + end + end +end diff --git a/spec/features/admin/move_up_type_de_champ_spec.rb b/spec/features/admin/move_up_type_de_champ_spec.rb index 4f0679509..28c0ab9f5 100644 --- a/spec/features/admin/move_up_type_de_champ_spec.rb +++ b/spec/features/admin/move_up_type_de_champ_spec.rb @@ -8,10 +8,10 @@ feature 'move up button type de champs', js: true do end let(:procedure) { create(:procedure, administrateur: administrateur) } - let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) } - let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) } - let!(:type_de_champ_2) { create(:type_de_champ, procedure: procedure, order_place: 2) } - let!(:type_de_champ_3) { create(:type_de_champ, procedure: procedure, order_place: 3) } + let!(:type_de_champ_0) { create(:type_de_champ_public, procedure: procedure, order_place: 0) } + let!(:type_de_champ_1) { create(:type_de_champ_public, procedure: procedure, order_place: 1) } + let!(:type_de_champ_2) { create(:type_de_champ_public, procedure: procedure, order_place: 2) } + let!(:type_de_champ_3) { create(:type_de_champ_public, procedure: procedure, order_place: 3) } context 'when clicking on move down for type de champ 1' do before do diff --git a/spec/models/champ_spec.rb b/spec/models/champ_spec.rb index 0e2cd61a8..edd9bfa2e 100644 --- a/spec/models/champ_spec.rb +++ b/spec/models/champ_spec.rb @@ -23,7 +23,7 @@ describe Champ do context 'when type_champ is datetime' do before do - champ.type_de_champ = create :type_de_champ, type_champ: 'datetime' + champ.type_de_champ = create :type_de_champ_public, type_champ: 'datetime' end it { is_expected.to eq 'datepicker' } @@ -31,7 +31,7 @@ describe Champ do context 'when type_champ is address' do before do - champ.type_de_champ = create :type_de_champ, type_champ: 'address' + champ.type_de_champ = create :type_de_champ_public, type_champ: 'address' end it { is_expected.to eq 'typeahead' } diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index 3a789effc..ebf8b2c9c 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -591,12 +591,12 @@ describe Dossier do let(:dossier_2) { Dossier.new(id: 0, procedure: procedure_2) } before do - create :type_de_champ, libelle: 'type_1_1', order_place: 1, procedure: dossier_1.procedure - create :type_de_champ, libelle: 'type_1_2', order_place: 2, procedure: dossier_1.procedure + create :type_de_champ_public, libelle: 'type_1_1', order_place: 1, procedure: dossier_1.procedure + create :type_de_champ_public, libelle: 'type_1_2', order_place: 2, procedure: dossier_1.procedure - create :type_de_champ, libelle: 'type_2_1', order_place: 1, procedure: dossier_2.procedure - create :type_de_champ, libelle: 'type_2_2', order_place: 2, procedure: dossier_2.procedure - create :type_de_champ, libelle: 'type_2_3', order_place: 3, procedure: dossier_2.procedure + create :type_de_champ_public, libelle: 'type_2_1', order_place: 1, procedure: dossier_2.procedure + create :type_de_champ_public, libelle: 'type_2_2', order_place: 2, procedure: dossier_2.procedure + create :type_de_champ_public, libelle: 'type_2_3', order_place: 3, procedure: dossier_2.procedure dossier_1.build_default_champs dossier_2.build_default_champs diff --git a/spec/models/procedure_spec.rb b/spec/models/procedure_spec.rb index 1724ed8d2..6e4f6fdbb 100644 --- a/spec/models/procedure_spec.rb +++ b/spec/models/procedure_spec.rb @@ -44,8 +44,8 @@ describe Procedure do describe '#types_de_champ_ordered' do let(:procedure) { create(:procedure) } - let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 1) } - let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 0) } + let!(:type_de_champ_0) { create(:type_de_champ_public, procedure: procedure, order_place: 1) } + let!(:type_de_champ_1) { create(:type_de_champ_public, procedure: procedure, order_place: 0) } subject { procedure.types_de_champ_ordered } it { expect(subject.first).to eq(type_de_champ_1) } it { expect(subject.last).to eq(type_de_champ_0) } @@ -60,8 +60,8 @@ describe Procedure do it { expect(subject).to eq(false) } end context 'when procedure have 2 types de champ' do - let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) } - let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) } + let!(:type_de_champ_0) { create(:type_de_champ_public, procedure: procedure, order_place: 0) } + let!(:type_de_champ_1) { create(:type_de_champ_public, procedure: procedure, order_place: 1) } context 'when index is not the last element' do it { expect(subject).to eq(true) } it 'switch order place' do @@ -128,8 +128,8 @@ describe Procedure do let(:archived) { false } let(:published) { false } let(:procedure) { create(:procedure, archived: archived, published: published) } - let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) } - let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) } + let!(:type_de_champ_0) { create(:type_de_champ_public, procedure: procedure, order_place: 0) } + let!(:type_de_champ_1) { create(:type_de_champ_public, procedure: procedure, order_place: 1) } let!(:piece_justificative_0) { create(:type_de_piece_justificative, procedure: procedure, order_place: 0) } let!(:piece_justificative_1) { create(:type_de_piece_justificative, procedure: procedure, order_place: 1) } subject { procedure.clone } diff --git a/spec/models/type_de_champ_private_spec.rb b/spec/models/type_de_champ_private_spec.rb new file mode 100644 index 000000000..6f0b1ce8a --- /dev/null +++ b/spec/models/type_de_champ_private_spec.rb @@ -0,0 +1,7 @@ +require 'spec_helper' + +describe TypeDeChampPrivate do + require 'models/type_de_champ_shared_example' + + it_should_behave_like "type_de_champ_spec" +end diff --git a/spec/models/type_de_champ_public_spec.rb b/spec/models/type_de_champ_public_spec.rb new file mode 100644 index 000000000..fc855566f --- /dev/null +++ b/spec/models/type_de_champ_public_spec.rb @@ -0,0 +1,7 @@ +require 'spec_helper' + +describe TypeDeChampPublic do + require 'models/type_de_champ_shared_example' + + it_should_behave_like "type_de_champ_spec" +end diff --git a/spec/models/type_de_champ_shared_example.rb b/spec/models/type_de_champ_shared_example.rb new file mode 100644 index 000000000..5ce94d7d3 --- /dev/null +++ b/spec/models/type_de_champ_shared_example.rb @@ -0,0 +1,44 @@ +shared_examples 'type_de_champ_spec' do + describe 'database columns' do + it { is_expected.to have_db_column(:libelle) } + it { is_expected.to have_db_column(:type_champ) } + it { is_expected.to have_db_column(:order_place) } + it { is_expected.to have_db_column(:description) } + end + + describe 'associations' do + it { is_expected.to belong_to(:procedure) } + it { is_expected.to have_many(:champ) } + end + + describe 'validation' do + context 'libelle' do + it { is_expected.not_to allow_value(nil).for(:libelle) } + it { is_expected.not_to allow_value('').for(:libelle) } + it { is_expected.to allow_value('Montant projet').for(:libelle) } + end + + context 'type' do + it { is_expected.not_to allow_value(nil).for(:type_champ) } + it { is_expected.not_to allow_value('').for(:type_champ) } + + it { is_expected.to allow_value('text').for(:type_champ) } + it { is_expected.to allow_value('textarea').for(:type_champ) } + it { is_expected.to allow_value('datetime').for(:type_champ) } + it { is_expected.to allow_value('number').for(:type_champ) } + it { is_expected.to allow_value('checkbox').for(:type_champ) } + end + + context 'order_place' do + # it { is_expected.not_to allow_value(nil).for(:order_place) } + # it { is_expected.not_to allow_value('').for(:order_place) } + it { is_expected.to allow_value(1).for(:order_place) } + end + + context 'description' do + it { is_expected.to allow_value(nil).for(:description) } + it { is_expected.to allow_value('').for(:description) } + it { is_expected.to allow_value('blabla').for(:description) } + end + end +end \ No newline at end of file diff --git a/spec/models/type_de_champ_spec.rb b/spec/models/type_de_champ_spec.rb index 101b2be02..9649c4078 100644 --- a/spec/models/type_de_champ_spec.rb +++ b/spec/models/type_de_champ_spec.rb @@ -1,46 +1,9 @@ require 'spec_helper' describe TypeDeChamp do - describe 'database columns' do - it { is_expected.to have_db_column(:libelle) } - it { is_expected.to have_db_column(:type_champ) } - it { is_expected.to have_db_column(:order_place) } - it { is_expected.to have_db_column(:description) } - end - describe 'associations' do - it { is_expected.to belong_to(:procedure) } - it { is_expected.to have_many(:champ) } - end + require 'models/type_de_champ_shared_example' - describe 'validation' do - context 'libelle' do - it { is_expected.not_to allow_value(nil).for(:libelle) } - it { is_expected.not_to allow_value('').for(:libelle) } - it { is_expected.to allow_value('Montant projet').for(:libelle) } - end - - context 'type' do - it { is_expected.not_to allow_value(nil).for(:type_champ) } - it { is_expected.not_to allow_value('').for(:type_champ) } - - it { is_expected.to allow_value('text').for(:type_champ) } - it { is_expected.to allow_value('textarea').for(:type_champ) } - it { is_expected.to allow_value('datetime').for(:type_champ) } - it { is_expected.to allow_value('number').for(:type_champ) } - it { is_expected.to allow_value('checkbox').for(:type_champ) } - end - - context 'order_place' do - # it { is_expected.not_to allow_value(nil).for(:order_place) } - # it { is_expected.not_to allow_value('').for(:order_place) } - it { is_expected.to allow_value(1).for(:order_place) } - end - - context 'description' do - it { is_expected.to allow_value(nil).for(:description) } - it { is_expected.to allow_value('').for(:description) } - it { is_expected.to allow_value('blabla').for(:description) } - end - end + it_should_behave_like "type_de_champ_spec" end + diff --git a/spec/views/admin/types_de_champ/show.html.haml_spec.rb b/spec/views/admin/types_de_champ/show.html.haml_spec.rb index d6b7d1355..4029d7e98 100644 --- a/spec/views/admin/types_de_champ/show.html.haml_spec.rb +++ b/spec/views/admin/types_de_champ/show.html.haml_spec.rb @@ -6,8 +6,8 @@ describe 'admin/types_de_champ/show.html.haml', type: :view do describe 'fields sorted' do let(:first_libelle) { 'salut la compagnie' } let(:last_libelle) { 'je suis bien sur la page' } - let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1, libelle: last_libelle) } - let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0, libelle: first_libelle) } + let!(:type_de_champ_1) { create(:type_de_champ_public, procedure: procedure, order_place: 1, libelle: last_libelle) } + let!(:type_de_champ_0) { create(:type_de_champ_public, procedure: procedure, order_place: 0, libelle: first_libelle) } before do procedure.reload assign(:procedure, procedure) @@ -30,15 +30,15 @@ describe 'admin/types_de_champ/show.html.haml', type: :view do it { expect(subject).not_to have_css('.fa-chevron-up') } end context 'when there is only one field in database' do - let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) } + let!(:type_de_champ_0) { create(:type_de_champ_public, procedure: procedure, order_place: 0) } it { expect(subject).not_to have_css('#btn_down_0') } it { expect(subject).not_to have_css('#btn_up_0') } it { expect(subject).not_to have_css('#btn_up_1') } it { expect(subject).not_to have_css('#btn_down_1') } end context 'when there are 2 fields in database' do - let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) } - let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) } + let!(:type_de_champ_0) { create(:type_de_champ_public, procedure: procedure, order_place: 0) } + let!(:type_de_champ_1) { create(:type_de_champ_public, procedure: procedure, order_place: 1) } it { expect(subject).to have_css('#btn_down_0') } it { expect(subject).not_to have_css('#btn_up_0') } it { expect(subject).to have_css('#btn_up_1') } diff --git a/spec/views/admin/types_de_champ_private/show.html.haml_spec.rb b/spec/views/admin/types_de_champ_private/show.html.haml_spec.rb new file mode 100644 index 000000000..e3515a0df --- /dev/null +++ b/spec/views/admin/types_de_champ_private/show.html.haml_spec.rb @@ -0,0 +1,48 @@ +require 'spec_helper' + +describe 'admin/types_de_champ_private/show.html.haml', type: :view do + let(:procedure) { create(:procedure) } + + describe 'fields sorted' do + let(:first_libelle) { 'salut la compagnie' } + let(:last_libelle) { 'je suis bien sur la page' } + let!(:type_de_champ_1) { create(:type_de_champ_private, procedure: procedure, order_place: 1, libelle: last_libelle) } + let!(:type_de_champ_0) { create(:type_de_champ_private, procedure: procedure, order_place: 0, libelle: first_libelle) } + before do + procedure.reload + assign(:procedure, procedure) + render + end + it 'sorts by order place' do + expect(rendered).to match(/#{first_libelle}.*#{last_libelle}/m) + end + end + + describe 'arrow button' do + subject do + procedure.reload + assign(:procedure, procedure) + render + rendered + end + context 'when there is no field in database' do + it { expect(subject).not_to have_css('.fa-chevron-down') } + it { expect(subject).not_to have_css('.fa-chevron-up') } + end + context 'when there is only one field in database' do + let!(:type_de_champ_0) { create(:type_de_champ_private, procedure: procedure, order_place: 0) } + it { expect(subject).not_to have_css('#btn_down_0') } + it { expect(subject).not_to have_css('#btn_up_0') } + it { expect(subject).not_to have_css('#btn_up_1') } + it { expect(subject).not_to have_css('#btn_down_1') } + end + context 'when there are 2 fields in database' do + let!(:type_de_champ_0) { create(:type_de_champ_private, procedure: procedure, order_place: 0) } + let!(:type_de_champ_1) { create(:type_de_champ_private, procedure: procedure, order_place: 1) } + it { expect(subject).to have_css('#btn_down_0') } + it { expect(subject).not_to have_css('#btn_up_0') } + it { expect(subject).to have_css('#btn_up_1') } + it { expect(subject).not_to have_css('#btn_down_1') } + end + end +end \ No newline at end of file From ddb64878c8bb8f07fdc56bc089604dd0419bf8e0 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Thu, 4 Aug 2016 12:06:46 +0200 Subject: [PATCH 06/10] Refactor code for private type de champ --- .../admin/types_de_champ_controller.rb | 11 +++++ .../types_de_champ_private_controller.rb | 21 ++++++-- app/facades/admin_types_de_champ_facades.rb | 48 +++++++++++++++++++ .../admin/types_de_champ/_fields.html.haml | 13 ++--- .../admin/types_de_champ/_form.html.haml | 6 +-- app/views/admin/types_de_champ/show.html.haml | 4 +- app/views/admin/types_de_champ/show.js.erb | 2 +- .../types_de_champ_private/_fields.html.haml | 38 --------------- .../types_de_champ_private/_form.html.haml | 6 --- .../types_de_champ_private/show.html.haml | 4 -- .../admin/types_de_champ_private/show.js.erb | 5 -- .../types_de_champ/show.html.haml_spec.rb | 2 + .../show.html.haml_spec.rb | 4 +- 13 files changed, 93 insertions(+), 71 deletions(-) create mode 100644 app/facades/admin_types_de_champ_facades.rb delete mode 100644 app/views/admin/types_de_champ_private/_fields.html.haml delete mode 100644 app/views/admin/types_de_champ_private/_form.html.haml delete mode 100644 app/views/admin/types_de_champ_private/show.html.haml delete mode 100644 app/views/admin/types_de_champ_private/show.js.erb diff --git a/app/controllers/admin/types_de_champ_controller.rb b/app/controllers/admin/types_de_champ_controller.rb index 8eab26c02..d28fccc87 100644 --- a/app/controllers/admin/types_de_champ_controller.rb +++ b/app/controllers/admin/types_de_champ_controller.rb @@ -4,16 +4,19 @@ class Admin::TypesDeChampController < AdminController def destroy @procedure.types_de_champ.destroy(params[:id]) + create_facade render 'show', format: :js rescue ActiveRecord::RecordNotFound render json: { message: 'Champ not found' }, status: 404 end def show + create_facade end def update @procedure.update_attributes(update_params) + create_facade flash.now.notice = 'Modifications sauvegardées' render 'show', format: :js end @@ -27,6 +30,7 @@ class Admin::TypesDeChampController < AdminController def move_up index = params[:index].to_i - 1 if @procedure.switch_types_de_champ index + create_facade render 'show', format: :js else render json: {}, status: 400 @@ -35,9 +39,16 @@ class Admin::TypesDeChampController < AdminController def move_down if @procedure.switch_types_de_champ params[:index].to_i + create_facade render 'show', format: :js else render json: {}, status: 400 end end + + private + + def create_facade + @types_de_champ_facade = AdminTypesDeChampFacades.new false, @procedure + end end \ No newline at end of file diff --git a/app/controllers/admin/types_de_champ_private_controller.rb b/app/controllers/admin/types_de_champ_private_controller.rb index d8f1af66c..fce48700a 100644 --- a/app/controllers/admin/types_de_champ_private_controller.rb +++ b/app/controllers/admin/types_de_champ_private_controller.rb @@ -4,19 +4,22 @@ class Admin::TypesDeChampPrivateController < AdminController def destroy @procedure.types_de_champ_private.destroy(params[:id]) - render 'show', format: :js + create_facade + render 'admin/types_de_champ/show', format: :js rescue ActiveRecord::RecordNotFound render json: { message: 'Champ not found' }, status: 404 end def show - + create_facade + render 'admin/types_de_champ/show' end def update @procedure.update_attributes(update_params) + create_facade flash.now.notice = 'Modifications sauvegardées' - render 'show', format: :js + render 'admin/types_de_champ/show', format: :js end def update_params @@ -28,7 +31,8 @@ class Admin::TypesDeChampPrivateController < AdminController def move_up index = params[:index].to_i - 1 if @procedure.switch_types_de_champ_private index - render 'show', format: :js + create_facade + render 'admin/types_de_champ/show', format: :js else render json: {}, status: 400 end @@ -36,9 +40,16 @@ class Admin::TypesDeChampPrivateController < AdminController def move_down if @procedure.switch_types_de_champ_private params[:index].to_i - render 'show', format: :js + create_facade + render 'admin/types_de_champ/show', format: :js else render json: {}, status: 400 end end + + private + + def create_facade + @types_de_champ_facade = AdminTypesDeChampFacades.new true, @procedure + end end \ No newline at end of file diff --git a/app/facades/admin_types_de_champ_facades.rb b/app/facades/admin_types_de_champ_facades.rb new file mode 100644 index 000000000..9ee482dff --- /dev/null +++ b/app/facades/admin_types_de_champ_facades.rb @@ -0,0 +1,48 @@ +class AdminTypesDeChampFacades + include Rails.application.routes.url_helpers + + def initialize private, procedure + @private = private + @procedure = procedure + end + + def private + @private + end + + def active + @private ? 'Champs privés' : 'Champs' + end + + def url + @private ? admin_procedure_types_de_champ_private_path(@procedure) : admin_procedure_types_de_champ_path(@procedure) + end + + def types_de_champ + @private ? @procedure.types_de_champ_private_ordered.decorate : @procedure.types_de_champ_ordered.decorate + end + + def new_type_de_champ + @private ? TypeDeChampPrivate.new.decorate : TypeDeChampPublic.new.decorate + end + + def fields_for_var + @private ? :types_de_champ_private : :types_de_champ + end + + def move_up_url ff + @private ? move_up_admin_procedure_types_de_champ_private_path(@procedure, ff.index) : move_up_admin_procedure_types_de_champ_path(@procedure, ff.index) + end + + def move_down_url ff + @private ? move_down_admin_procedure_types_de_champ_private_path(@procedure, ff.index) : move_down_admin_procedure_types_de_champ_path(@procedure, ff.index) + end + + def delete_url ff + @private ? admin_procedure_type_de_champ_private_path(@procedure, ff.object.id) : admin_procedure_type_de_champ_path(@procedure, ff.object.id) + end + + def add_button_id + @private ? :add_type_de_champ_private : :add_type_de_champ + end +end \ No newline at end of file diff --git a/app/views/admin/types_de_champ/_fields.html.haml b/app/views/admin/types_de_champ/_fields.html.haml index dd0250fbd..35046c4c1 100644 --- a/app/views/admin/types_de_champ/_fields.html.haml +++ b/app/views/admin/types_de_champ/_fields.html.haml @@ -1,4 +1,4 @@ -= f.fields_for :types_de_champ, types_de_champ, remote: true do |ff| += f.fields_for @types_de_champ_facade.fields_for_var, types_de_champ, remote: true do |ff| .form-inline{class:"#{ff.object.object.type_champ == 'header_section' ? 'header_section' : ''}"} .form-group.libelle %h4 Libellé @@ -6,7 +6,7 @@ .form-group.type %h4 Type - = ff.select :type_champ, TypeDeChampPublic.type_champs, {}, {class: 'form-control type_champ'} + = ff.select :type_champ, TypeDeChamp.type_champs, {}, {class: 'form-control type_champ'} .form-group.description %h4 Description @@ -21,17 +21,18 @@ = ff.hidden_field :order_place, value: ff.index = ff.hidden_field :type = ff.hidden_field :id + - unless ff.object.id.nil? .form-group %br   - = ff.object.button_up(index: ff.index, url: move_up_admin_procedure_types_de_champ_path(@procedure, ff.index)) - = ff.object.button_down(index: ff.index, url: move_down_admin_procedure_types_de_champ_path(@procedure, ff.index)) + = ff.object.button_up(index: ff.index, url: @types_de_champ_facade.move_up_url(ff), private: @types_de_champ_facade.private) + = ff.object.button_down(index: ff.index, url: @types_de_champ_facade.move_down_url(ff), private: @types_de_champ_facade.private) .form-group %br   - if ff.object.id.nil? - = f.submit "Ajouter le champ", class: 'btn btn-success', id: :add_type_de_champ + = f.submit "Ajouter le champ", class: 'btn btn-success', id: @types_de_champ_facade.add_button_id - else - = link_to("", admin_procedure_type_de_champ_path(@procedure, ff.object.id), method: :delete, remote: true, id: "delete_type_de_champ_#{ff.object.id}", class: %w(form-control btn btn-danger fa fa-trash-o) ) + = link_to("", @types_de_champ_facade.delete_url(ff), method: :delete, remote: true, id: "delete_type_de_champ_#{ff.object.id}", class: %w(form-control btn btn-danger fa fa-trash-o) ) diff --git a/app/views/admin/types_de_champ/_form.html.haml b/app/views/admin/types_de_champ/_form.html.haml index d92771855..2c5aaa880 100644 --- a/app/views/admin/types_de_champ/_form.html.haml +++ b/app/views/admin/types_de_champ/_form.html.haml @@ -1,6 +1,6 @@ -= form_for [:admin, @procedure], url: admin_procedure_types_de_champ_path(@procedure) , remote: true do |f| - = render partial: 'fields', locals: { types_de_champ: @procedure.types_de_champ_ordered.decorate, f: f } += form_for [:admin, @procedure], url: @types_de_champ_facade.url , remote: true do |f| + = render partial: 'admin/types_de_champ/fields', locals: { types_de_champ: @types_de_champ_facade.types_de_champ, f: f } = f.submit "Enregistrer", class: 'btn btn-success', id: :save %hr #new_type_de_champ - = render partial: 'fields', locals: { types_de_champ: TypeDeChampPublic.new.decorate, f: f } + = render partial: 'admin/types_de_champ/fields', locals: { types_de_champ: @types_de_champ_facade.new_type_de_champ, f: f } diff --git a/app/views/admin/types_de_champ/show.html.haml b/app/views/admin/types_de_champ/show.html.haml index 2dbac0970..bed676c74 100644 --- a/app/views/admin/types_de_champ/show.html.haml +++ b/app/views/admin/types_de_champ/show.html.haml @@ -1,4 +1,4 @@ -=render partial: 'admin/procedures/head', locals: {active: 'Champs'} +=render partial: 'admin/procedures/head', locals: {active: @types_de_champ_facade.active} #liste_champ - = render partial: 'form' \ No newline at end of file + = render partial: 'admin/types_de_champ/form' \ No newline at end of file diff --git a/app/views/admin/types_de_champ/show.js.erb b/app/views/admin/types_de_champ/show.js.erb index 259d609e3..1406b46c8 100644 --- a/app/views/admin/types_de_champ/show.js.erb +++ b/app/views/admin/types_de_champ/show.js.erb @@ -1,5 +1,5 @@ <% flash.each do |type, message| %> $("#flash_message").html("
<%= message.html_safe %>
").children().fadeOut(5000) <% end %> -$('#liste_champ').html("<%= escape_javascript(render partial: 'form', locals: { procedure: @procedure, types_de_champ: @types_de_champ } ) %>"); +$('#liste_champ').html("<%= escape_javascript(render partial: 'admin/types_de_champ/form', locals: { procedure: @procedure, types_de_champ: @types_de_champ } ) %>"); on_change_type_de_champ_select (); \ No newline at end of file diff --git a/app/views/admin/types_de_champ_private/_fields.html.haml b/app/views/admin/types_de_champ_private/_fields.html.haml deleted file mode 100644 index 6da37a941..000000000 --- a/app/views/admin/types_de_champ_private/_fields.html.haml +++ /dev/null @@ -1,38 +0,0 @@ -= f.fields_for :types_de_champ_private, types_de_champ_private, remote: true do |ff| - .form-inline{class:"#{ff.object.object.type_champ == 'header_section' ? 'header_section' : ''}"} - .form-group.libelle - %h4 Libellé - = ff.text_field :libelle, class: 'form-control libelle', placeholder: 'Libellé' - - .form-group.type - %h4 Type - = ff.select :type_champ, TypeDeChampPrivate.type_champs, {}, {class: 'form-control type_champ'} - - .form-group.description - %h4 Description - = ff.text_area :description, class: 'form-control description', placeholder: 'Description' - - .form-group.mandatory - %h4 Obligatoire ? - .center - = ff.check_box :mandatory, placeholder: 'Obligatoire ?' - - .form-group - = ff.hidden_field :order_place, value: ff.index - = ff.hidden_field :type - = ff.hidden_field :id - - - unless ff.object.id.nil? - .form-group - %br   - = ff.object.button_up(index: ff.index, url: move_up_admin_procedure_types_de_champ_private_path(@procedure, ff.index), private: true) - = ff.object.button_down(index: ff.index, url: move_down_admin_procedure_types_de_champ_private_path(@procedure, ff.index), private: true) - - .form-group - %br   - - if ff.object.id.nil? - = f.submit "Ajouter le champ", class: 'btn btn-success', id: :add_type_de_champ_private - - else - = link_to("", admin_procedure_type_de_champ_private_path(@procedure, ff.object.id), method: :delete, remote: true, id: "delete_type_de_champ_private_#{ff.object.id}", class: %w(form-control btn btn-danger fa fa-trash-o) ) - - diff --git a/app/views/admin/types_de_champ_private/_form.html.haml b/app/views/admin/types_de_champ_private/_form.html.haml deleted file mode 100644 index a098de1f8..000000000 --- a/app/views/admin/types_de_champ_private/_form.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -= form_for [:admin, @procedure], url: admin_procedure_types_de_champ_private_path(@procedure) , remote: true do |f| - = render partial: 'fields', locals: { types_de_champ_private: @procedure.types_de_champ_private_ordered.decorate, f: f } - = f.submit "Enregistrer", class: 'btn btn-success', id: :save - %hr - #new_type_de_champ - = render partial: 'fields', locals: { types_de_champ_private: TypeDeChampPrivate.new.decorate, f: f } diff --git a/app/views/admin/types_de_champ_private/show.html.haml b/app/views/admin/types_de_champ_private/show.html.haml deleted file mode 100644 index 464f9083d..000000000 --- a/app/views/admin/types_de_champ_private/show.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -=render partial: 'admin/procedures/head', locals: {active: 'Champs privés'} - -#liste_champ - = render partial: 'form' \ No newline at end of file diff --git a/app/views/admin/types_de_champ_private/show.js.erb b/app/views/admin/types_de_champ_private/show.js.erb deleted file mode 100644 index 259d609e3..000000000 --- a/app/views/admin/types_de_champ_private/show.js.erb +++ /dev/null @@ -1,5 +0,0 @@ -<% flash.each do |type, message| %> -$("#flash_message").html("
<%= message.html_safe %>
").children().fadeOut(5000) -<% end %> -$('#liste_champ').html("<%= escape_javascript(render partial: 'form', locals: { procedure: @procedure, types_de_champ: @types_de_champ } ) %>"); -on_change_type_de_champ_select (); \ No newline at end of file diff --git a/spec/views/admin/types_de_champ/show.html.haml_spec.rb b/spec/views/admin/types_de_champ/show.html.haml_spec.rb index 4029d7e98..bed11f3d4 100644 --- a/spec/views/admin/types_de_champ/show.html.haml_spec.rb +++ b/spec/views/admin/types_de_champ/show.html.haml_spec.rb @@ -11,6 +11,7 @@ describe 'admin/types_de_champ/show.html.haml', type: :view do before do procedure.reload assign(:procedure, procedure) + assign(:types_de_champ_facade, AdminTypesDeChampFacades.new(false, procedure)) render end it 'sorts by order place' do @@ -22,6 +23,7 @@ describe 'admin/types_de_champ/show.html.haml', type: :view do subject do procedure.reload assign(:procedure, procedure) + assign(:types_de_champ_facade, AdminTypesDeChampFacades.new(false, procedure)) render rendered end diff --git a/spec/views/admin/types_de_champ_private/show.html.haml_spec.rb b/spec/views/admin/types_de_champ_private/show.html.haml_spec.rb index e3515a0df..319e9c30a 100644 --- a/spec/views/admin/types_de_champ_private/show.html.haml_spec.rb +++ b/spec/views/admin/types_de_champ_private/show.html.haml_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'admin/types_de_champ_private/show.html.haml', type: :view do +describe 'admin/types_de_champ/show.html.haml', type: :view do let(:procedure) { create(:procedure) } describe 'fields sorted' do @@ -11,6 +11,7 @@ describe 'admin/types_de_champ_private/show.html.haml', type: :view do before do procedure.reload assign(:procedure, procedure) + assign(:types_de_champ_facade, AdminTypesDeChampFacades.new(true, procedure)) render end it 'sorts by order place' do @@ -22,6 +23,7 @@ describe 'admin/types_de_champ_private/show.html.haml', type: :view do subject do procedure.reload assign(:procedure, procedure) + assign(:types_de_champ_facade, AdminTypesDeChampFacades.new(true, procedure)) render rendered end From 480431ea013cd28d86de8cecdc23e0492c23d90e Mon Sep 17 00:00:00 2001 From: Xavier J Date: Mon, 8 Aug 2016 12:52:30 +0200 Subject: [PATCH 07/10] Add on gestionnaire dossier view the private form --- app/assets/stylesheets/application.scss | 2 +- .../backoffice/dossiers_controller.rb | 1 + .../private_formulaires_controller.rb | 19 +++++++ .../users/description_controller.rb | 20 ++------ app/facades/dossier_facades.rb | 4 ++ app/models/champ_private.rb | 3 ++ app/models/champ_public.rb | 3 ++ app/models/dossier.rb | 13 ++++- app/serializers/champ_private_serializer.rb | 5 ++ app/serializers/champ_public_serializer.rb | 5 ++ app/serializers/champ_serializer.rb | 5 -- app/serializers/dossier_serializer.rb | 1 + app/services/champs_service.rb | 25 ++++++++++ .../admin/types_de_champ/_fields.html.haml | 9 ++-- .../dossiers/formulaire_private.js.erb | 4 ++ app/views/backoffice/dossiers/show.html.haml | 11 +++- config/routes.rb | 1 + ...0804130638_add_type_attr_in_champ_table.rb | 25 ++++++++++ db/schema.rb | 3 +- .../api/v1/dossiers_controller_spec.rb | 35 ++++++++++++- .../private_formulaires_controller_spec.rb | 28 +++++++++++ spec/factories/dossier.rb | 2 +- spec/models/champ_private_spec.rb | 7 +++ spec/models/champ_public_spec.rb | 7 +++ spec/models/champ_shared_example.rb | 38 ++++++++++++++ spec/models/champ_spec.rb | 37 +------------- spec/models/dossier_spec.rb | 50 ++++++++++++++++++- .../show.html.haml_spec.rb | 45 ++++++++++------- 28 files changed, 320 insertions(+), 88 deletions(-) create mode 100644 app/controllers/backoffice/private_formulaires_controller.rb create mode 100644 app/models/champ_private.rb create mode 100644 app/models/champ_public.rb create mode 100644 app/serializers/champ_private_serializer.rb create mode 100644 app/serializers/champ_public_serializer.rb delete mode 100644 app/serializers/champ_serializer.rb create mode 100644 app/services/champs_service.rb create mode 100644 app/views/backoffice/dossiers/formulaire_private.js.erb create mode 100644 db/migrate/20160804130638_add_type_attr_in_champ_table.rb create mode 100644 spec/controllers/backoffice/private_formulaires_controller_spec.rb create mode 100644 spec/models/champ_private_spec.rb create mode 100644 spec/models/champ_public_spec.rb create mode 100644 spec/models/champ_shared_example.rb diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index dedae8dcd..dd36af17e 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -184,7 +184,7 @@ div.pagination { .alert.alert-success.move_up, .alert.alert-danger.siret{ - position: absolute; + position: fixed; top: 0px; left: 0; height: 52px; diff --git a/app/controllers/backoffice/dossiers_controller.rb b/app/controllers/backoffice/dossiers_controller.rb index 82d41b543..a927d94d1 100644 --- a/app/controllers/backoffice/dossiers_controller.rb +++ b/app/controllers/backoffice/dossiers_controller.rb @@ -14,6 +14,7 @@ class Backoffice::DossiersController < ApplicationController def show create_dossier_facade params[:id] + @champs = @facade.champs_private unless @facade.nil? end def search diff --git a/app/controllers/backoffice/private_formulaires_controller.rb b/app/controllers/backoffice/private_formulaires_controller.rb new file mode 100644 index 000000000..4ad2ff671 --- /dev/null +++ b/app/controllers/backoffice/private_formulaires_controller.rb @@ -0,0 +1,19 @@ +class Backoffice::PrivateFormulairesController < ApplicationController + before_action :authenticate_gestionnaire! + + def update + dossier = current_gestionnaire.dossiers.find(params[:dossier_id]) + + unless params[:champs].nil? + champs_service_errors = ChampsService.save_formulaire dossier.champs_private, params + + if champs_service_errors.empty? + flash[:notice] = "Formulaire enregistré" + else + flash[:alert] = (champs_service_errors.inject('') { |acc, error| acc+= error[:message]+'
' }).html_safe + end + end + + render 'backoffice/dossiers/formulaire_private', formats: :js + end +end \ No newline at end of file diff --git a/app/controllers/users/description_controller.rb b/app/controllers/users/description_controller.rb index b3956eaa6..080b96275 100644 --- a/app/controllers/users/description_controller.rb +++ b/app/controllers/users/description_controller.rb @@ -43,23 +43,11 @@ class Users::DescriptionController < UsersController end unless params[:champs].nil? - @dossier.champs.each do |champ| - champ.value = params[:champs]["'#{champ.id}'"] + champs_service_errors = ChampsService.save_formulaire @dossier.champs, params - if champ.type_champ == 'datetime' - champ.value = params[:champs]["'#{champ.id}'"]+ - ' ' + - params[:time_hour]["'#{champ.id}'"] + - ':' + - params[:time_minute]["'#{champ.id}'"] - end - - if champ.mandatory? && (champ.value.nil? || champ.value.blank?) - flash.now.alert = "Le champ #{champ.libelle} doit être rempli." - return render 'show' - end - - champ.save + unless champs_service_errors.empty? + flash.now.alert = (champs_service_errors.inject('') {|acc, error| acc+= error[:message]+'
' }).html_safe + return render 'show' end end diff --git a/app/facades/dossier_facades.rb b/app/facades/dossier_facades.rb index 2291d608f..059462848 100644 --- a/app/facades/dossier_facades.rb +++ b/app/facades/dossier_facades.rb @@ -46,6 +46,10 @@ class DossierFacades @dossier.invites end + def champs_private + @dossier.ordered_champs_private + end + def commentaires_files PieceJustificative.where(dossier_id: @dossier.id, type_de_piece_justificative_id: nil) end diff --git a/app/models/champ_private.rb b/app/models/champ_private.rb new file mode 100644 index 000000000..6f7068148 --- /dev/null +++ b/app/models/champ_private.rb @@ -0,0 +1,3 @@ +class ChampPrivate < Champ + +end diff --git a/app/models/champ_public.rb b/app/models/champ_public.rb new file mode 100644 index 000000000..7b0efcb3d --- /dev/null +++ b/app/models/champ_public.rb @@ -0,0 +1,3 @@ +class ChampPublic < Champ + +end diff --git a/app/models/dossier.rb b/app/models/dossier.rb index f387d28d5..f5ab282d7 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -13,7 +13,8 @@ class Dossier < ActiveRecord::Base has_many :cerfa, dependent: :destroy has_many :pieces_justificatives, dependent: :destroy - has_many :champs, dependent: :destroy + has_many :champs, class_name: 'ChampPublic', dependent: :destroy + has_many :champs_private, class_name: 'ChampPrivate', dependent: :destroy has_many :quartier_prioritaires, dependent: :destroy has_many :cadastres, dependent: :destroy has_many :commentaires, dependent: :destroy @@ -47,7 +48,11 @@ class Dossier < ActiveRecord::Base def build_default_champs procedure.types_de_champ.each do |type_de_champ| - Champ.create(type_de_champ_id: type_de_champ.id, dossier_id: id) + ChampPublic.create(type_de_champ_id: type_de_champ.id, dossier_id: id) + end + + procedure.types_de_champ_private.each do |type_de_champ| + ChampPrivate.create(type_de_champ_id: type_de_champ.id, dossier_id: id) end end @@ -55,6 +60,10 @@ class Dossier < ActiveRecord::Base champs.joins(', types_de_champ').where("champs.type_de_champ_id = types_de_champ.id AND types_de_champ.procedure_id = #{procedure.id}").order('order_place') end + def ordered_champs_private + champs_private.joins(', types_de_champ').where("champs.type_de_champ_id = types_de_champ.id AND types_de_champ.procedure_id = #{procedure.id}").order('order_place') + end + def ordered_commentaires commentaires.order(created_at: :desc) end diff --git a/app/serializers/champ_private_serializer.rb b/app/serializers/champ_private_serializer.rb new file mode 100644 index 000000000..be0320f55 --- /dev/null +++ b/app/serializers/champ_private_serializer.rb @@ -0,0 +1,5 @@ +class ChampPrivateSerializer < ActiveModel::Serializer + attributes :value + + has_one :type_de_champ +end \ No newline at end of file diff --git a/app/serializers/champ_public_serializer.rb b/app/serializers/champ_public_serializer.rb new file mode 100644 index 000000000..528a4f850 --- /dev/null +++ b/app/serializers/champ_public_serializer.rb @@ -0,0 +1,5 @@ +class ChampPublicSerializer < ActiveModel::Serializer + attributes :value + + has_one :type_de_champ +end \ No newline at end of file diff --git a/app/serializers/champ_serializer.rb b/app/serializers/champ_serializer.rb deleted file mode 100644 index 5a0ba0bf3..000000000 --- a/app/serializers/champ_serializer.rb +++ /dev/null @@ -1,5 +0,0 @@ -class ChampSerializer < ActiveModel::Serializer - attributes :value - - has_one :type_de_champ -end \ No newline at end of file diff --git a/app/serializers/dossier_serializer.rb b/app/serializers/dossier_serializer.rb index 3364c8928..5060598ab 100644 --- a/app/serializers/dossier_serializer.rb +++ b/app/serializers/dossier_serializer.rb @@ -12,6 +12,7 @@ class DossierSerializer < ActiveModel::Serializer has_many :cerfa has_many :commentaires has_many :champs + has_many :champs_private has_many :pieces_justificatives has_many :types_de_piece_justificative end \ No newline at end of file diff --git a/app/services/champs_service.rb b/app/services/champs_service.rb new file mode 100644 index 000000000..7ae8817a7 --- /dev/null +++ b/app/services/champs_service.rb @@ -0,0 +1,25 @@ +class ChampsService + def self.save_formulaire champs, params + errors = Array.new + + champs.each do |champ| + champ.value = params[:champs]["'#{champ.id}'"] + + if champ.type_champ == 'datetime' + champ.value = params[:champs]["'#{champ.id}'"]+ + ' ' + + params[:time_hour]["'#{champ.id}'"] + + ':' + + params[:time_minute]["'#{champ.id}'"] + end + + if champ.mandatory? && (champ.value.nil? || champ.value.blank?) + errors.push({message: "Le champ #{champ.libelle} doit être rempli."}) + end + + champ.save + end + + errors + end +end \ No newline at end of file diff --git a/app/views/admin/types_de_champ/_fields.html.haml b/app/views/admin/types_de_champ/_fields.html.haml index 35046c4c1..8ef85b152 100644 --- a/app/views/admin/types_de_champ/_fields.html.haml +++ b/app/views/admin/types_de_champ/_fields.html.haml @@ -12,10 +12,11 @@ %h4 Description = ff.text_area :description, class: 'form-control description', placeholder: 'Description' - .form-group.mandatory - %h4 Obligatoire ? - .center - = ff.check_box :mandatory, placeholder: 'Obligatoire ?' + - unless ff.object.object.class == TypeDeChampPrivate + .form-group.mandatory + %h4 Obligatoire ? + .center + = ff.check_box :mandatory, placeholder: 'Obligatoire ?' .form-group = ff.hidden_field :order_place, value: ff.index diff --git a/app/views/backoffice/dossiers/formulaire_private.js.erb b/app/views/backoffice/dossiers/formulaire_private.js.erb new file mode 100644 index 000000000..a4a9f595b --- /dev/null +++ b/app/views/backoffice/dossiers/formulaire_private.js.erb @@ -0,0 +1,4 @@ +<% flash.each do |type, message| %> +$("#flash_message").html("
<%= message.html_safe %>
").children().fadeOut(5000) +<% end %> +<% flash.clear %> diff --git a/app/views/backoffice/dossiers/show.html.haml b/app/views/backoffice/dossiers/show.html.haml index caba91adb..ca83b7225 100644 --- a/app/views/backoffice/dossiers/show.html.haml +++ b/app/views/backoffice/dossiers/show.html.haml @@ -27,6 +27,9 @@ %li{role: "presentation"} %a{href: "#followers", 'aria-controls' => "followers", role: "tab", 'data-toggle' => "tab"} Abonnés + %li{role: "presentation"} + %a{href: "#champs_private", 'aria-controls' => "champs_private", role: "tab", 'data-toggle' => "tab"} + Formulaire %div{class: "tab-content"} %div{role: "tabpanel", class: "tab-pane fade in active", id:"commentaires"} @@ -39,6 +42,12 @@ = render partial: '/dossiers/invites' %div{role: "tabpanel", class: "tab-pane fade", id:"followers"} = render partial: 'followers' - + %div{role: "tabpanel", class: "tab-pane fade", id:"champs_private"} + %h3 Formulaire privé + - unless @champs.nil? + = form_for @facade.dossier, url: {controller: 'backoffice/private_formulaires', action: :update, dossier_id: @facade.dossier.id}, remote: true do + = render partial: '/users/description/champs' + %br + = submit_tag :Enregistrer, {class: 'btn btn-success', style: 'float: right'} %br %br \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index a60906714..66e600ab1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -145,6 +145,7 @@ Rails.application.routes.draw do get 'filtres' => 'procedure_filter#index' patch 'filtres/update' => 'procedure_filter#update' + resource :private_formulaire namespace :preference_list_dossier do post 'add' diff --git a/db/migrate/20160804130638_add_type_attr_in_champ_table.rb b/db/migrate/20160804130638_add_type_attr_in_champ_table.rb new file mode 100644 index 000000000..465d9ce63 --- /dev/null +++ b/db/migrate/20160804130638_add_type_attr_in_champ_table.rb @@ -0,0 +1,25 @@ +class AddTypeAttrInChampTable < ActiveRecord::Migration + + class TypeDeChamp < ActiveRecord::Base + has_many :champs + end + + class Champ < ActiveRecord::Base + belongs_to :type_de_champ + end + + def up + add_column :champs, :type, :string + + Champ.all.each do |champ| + type = 'ChampPublic' if champ.type_de_champ.class == TypeDeChampPublic + type = 'ChampPrivate' if champ.type_de_champ.class == TypeDeChampPrivate + + champ.update_attribute(:type, type) + end + end + + def down + remove_column :champs, :type + end +end diff --git a/db/schema.rb b/db/schema.rb index d022e46cd..b737a1d69 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160803081304) do +ActiveRecord::Schema.define(version: 20160804130638) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -99,6 +99,7 @@ ActiveRecord::Schema.define(version: 20160803081304) do t.string "value" t.integer "type_de_champ_id" t.integer "dossier_id" + t.string "type" end create_table "commentaires", force: :cascade do |t| diff --git a/spec/controllers/api/v1/dossiers_controller_spec.rb b/spec/controllers/api/v1/dossiers_controller_spec.rb index a2eeaeeca..5295b7d49 100644 --- a/spec/controllers/api/v1/dossiers_controller_spec.rb +++ b/spec/controllers/api/v1/dossiers_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe API::V1::DossiersController do let(:admin) { create(:administrateur) } - let(:procedure) { create(:procedure, :with_two_type_de_piece_justificative, :with_type_de_champ, administrateur: admin, cerfa_flag: true) } + let(:procedure) { create(:procedure, :with_two_type_de_piece_justificative, :with_type_de_champ, :with_type_de_champ_private, administrateur: admin, cerfa_flag: true) } let(:wrong_procedure) { create(:procedure) } it { expect(described_class).to be < APIController } @@ -115,7 +115,7 @@ describe API::V1::DossiersController do let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, procedure: procedure) } } let(:dossier_id) { dossier.id } let(:body) { JSON.parse(retour.body, symbolize_names: true) } - let(:field_list) { [:id, :created_at, :updated_at, :archived, :mandataire_social, :total_commentaire, :entreprise, :etablissement, :cerfa, :types_de_piece_justificative, :pieces_justificatives, :champs, :commentaires, :state] } + let(:field_list) { [:id, :created_at, :updated_at, :archived, :mandataire_social, :total_commentaire, :entreprise, :etablissement, :cerfa, :types_de_piece_justificative, :pieces_justificatives, :champs, :champs_private, :commentaires, :state] } subject { body[:dossier] } it 'return REST code 200', :show_in_doc do @@ -235,6 +235,37 @@ describe API::V1::DossiersController do end end + describe 'champs_private' do + let(:field_list) { [ + :url] } + subject { super()[:champs_private] } + + it { expect(subject.length).to eq 1 } + + describe 'first champs' do + subject { super().first } + + it { expect(subject.keys.include?(:value)).to be_truthy } + it { expect(subject.keys.include?(:type_de_champ)).to be_truthy } + + describe 'type de champ' do + let(:field_list) { [ + :id, + :libelle, + :description, + :order_place, + :type] } + subject { super()[:type_de_champ] } + + it { expect(subject.keys.include?(:id)).to be_truthy } + it { expect(subject[:libelle]).to eq('Description') } + it { expect(subject[:description]).to eq('description de votre projet') } + it { expect(subject.keys.include?(:order_place)).to be_truthy } + it { expect(subject[:type_champ]).to eq('text') } + end + end + end + describe 'commentaires' do let!(:commentaire) { create :commentaire, body: 'plop', created_at: '2016-03-14 14:00:00', email: 'plop@plip.com', dossier: dossier } let!(:commentaire_2) { create :commentaire, body: 'plip', created_at: '2016-03-14 15:00:00', email: 'plip@plap.com', dossier: dossier } diff --git a/spec/controllers/backoffice/private_formulaires_controller_spec.rb b/spec/controllers/backoffice/private_formulaires_controller_spec.rb new file mode 100644 index 000000000..80b5bb345 --- /dev/null +++ b/spec/controllers/backoffice/private_formulaires_controller_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' + +describe Backoffice::PrivateFormulairesController, type: :controller do + let(:gestionnaire) { create :gestionnaire } + let(:dossier) { create :dossier } + let(:dossier_champs_first) { 'plop' } + + before do + create :assign_to, procedure_id: dossier.procedure.id, gestionnaire_id: gestionnaire.id + + sign_in gestionnaire + end + + describe '#PATCH update' do + subject { patch :update, dossier_id: dossier.id, + champs: { + "'#{dossier.champs_private.first.id}'" => dossier_champs_first + } } + + before do + subject + end + + it { expect(response.status).to eq 200 } + it { expect(Dossier.find(dossier.id).champs_private.first.value).to eq dossier_champs_first } + it { expect(flash[:notice]).to be_present } + end +end diff --git a/spec/factories/dossier.rb b/spec/factories/dossier.rb index e3f1e3490..2a98f2a0b 100644 --- a/spec/factories/dossier.rb +++ b/spec/factories/dossier.rb @@ -5,7 +5,7 @@ FactoryGirl.define do before(:create) do |dossier, _evaluator| unless dossier.procedure - procedure = create(:procedure, :with_two_type_de_piece_justificative, :with_type_de_champ) + procedure = create(:procedure, :with_two_type_de_piece_justificative, :with_type_de_champ, :with_type_de_champ_private) dossier.procedure = procedure end end diff --git a/spec/models/champ_private_spec.rb b/spec/models/champ_private_spec.rb new file mode 100644 index 000000000..635cf4fbf --- /dev/null +++ b/spec/models/champ_private_spec.rb @@ -0,0 +1,7 @@ +require 'spec_helper' + +describe ChampPrivate do + require 'models/champ_shared_example.rb' + + it_should_behave_like "champ_spec" +end \ No newline at end of file diff --git a/spec/models/champ_public_spec.rb b/spec/models/champ_public_spec.rb new file mode 100644 index 000000000..b52c3e1f6 --- /dev/null +++ b/spec/models/champ_public_spec.rb @@ -0,0 +1,7 @@ +require 'spec_helper' + +describe ChampPublic do + require 'models/champ_shared_example.rb' + + it_should_behave_like "champ_spec" +end \ No newline at end of file diff --git a/spec/models/champ_shared_example.rb b/spec/models/champ_shared_example.rb new file mode 100644 index 000000000..bf70d0012 --- /dev/null +++ b/spec/models/champ_shared_example.rb @@ -0,0 +1,38 @@ +shared_examples 'champ_spec' do + describe 'database columns' do + it { is_expected.to have_db_column(:value) } + end + + describe 'associations' do + it { is_expected.to belong_to(:dossier) } + it { is_expected.to belong_to(:type_de_champ) } + end + + describe 'delegation' do + it { is_expected.to delegate_method(:libelle).to(:type_de_champ) } + it { is_expected.to delegate_method(:type_champ).to(:type_de_champ) } + it { is_expected.to delegate_method(:order_place).to(:type_de_champ) } + end + + describe 'data_provide' do + let(:champ) { create :champ } + + subject { champ.data_provide } + + context 'when type_champ is datetime' do + before do + champ.type_de_champ = create :type_de_champ_public, type_champ: 'datetime' + end + + it { is_expected.to eq 'datepicker' } + end + + context 'when type_champ is address' do + before do + champ.type_de_champ = create :type_de_champ_public, type_champ: 'address' + end + + it { is_expected.to eq 'typeahead' } + end + end +end \ No newline at end of file diff --git a/spec/models/champ_spec.rb b/spec/models/champ_spec.rb index edd9bfa2e..66114be2d 100644 --- a/spec/models/champ_spec.rb +++ b/spec/models/champ_spec.rb @@ -1,40 +1,7 @@ require 'spec_helper' describe Champ do - describe 'database columns' do - it { is_expected.to have_db_column(:value) } - end + require 'models/champ_shared_example.rb' - describe 'associations' do - it { is_expected.to belong_to(:dossier) } - it { is_expected.to belong_to(:type_de_champ) } - end - - describe 'delegation' do - it { is_expected.to delegate_method(:libelle).to(:type_de_champ) } - it { is_expected.to delegate_method(:type_champ).to(:type_de_champ) } - it { is_expected.to delegate_method(:order_place).to(:type_de_champ) } - end - - describe 'data_provide' do - let(:champ) { create :champ } - - subject { champ.data_provide } - - context 'when type_champ is datetime' do - before do - champ.type_de_champ = create :type_de_champ_public, type_champ: 'datetime' - end - - it { is_expected.to eq 'datepicker' } - end - - context 'when type_champ is address' do - before do - champ.type_de_champ = create :type_de_champ_public, type_champ: 'address' - end - - it { is_expected.to eq 'typeahead' } - end - end + it_should_behave_like "champ_spec" end \ No newline at end of file diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index ebf8b2c9c..393968cd1 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -92,12 +92,16 @@ describe Dossier do end describe '#build_default_champs' do - context 'when dossier is linked to a procedure' do + context 'when dossier is linked to a procedure with type_de_champ_public and private' do let(:dossier) { create(:dossier, user: user) } it 'build all champs needed' do expect(dossier.champs.count).to eq(1) end + + it 'build all champs_private needed' do + expect(dossier.champs_private.count).to eq(1) + end end end @@ -604,7 +608,7 @@ describe Dossier do subject { dossier.ordered_champs } - it { expect(Champ.where(dossier_id: 0).size).to eq 5 } + it { expect(ChampPublic.where(dossier_id: 0).size).to eq 5 } describe 'for dossier 1' do let(:dossier) { dossier_1 } @@ -626,6 +630,48 @@ describe Dossier do end + describe '#ordered_champs_private' do + let!(:procedure_1) { create :procedure } + let!(:procedure_2) { create :procedure } + + let(:dossier_1) { Dossier.new(id: 0, procedure: procedure_1) } + let(:dossier_2) { Dossier.new(id: 0, procedure: procedure_2) } + + before do + create :type_de_champ_private, libelle: 'type_1_1', order_place: 1, procedure: dossier_1.procedure + create :type_de_champ_private, libelle: 'type_1_2', order_place: 2, procedure: dossier_1.procedure + + create :type_de_champ_private, libelle: 'type_2_1', order_place: 1, procedure: dossier_2.procedure + create :type_de_champ_private, libelle: 'type_2_2', order_place: 2, procedure: dossier_2.procedure + create :type_de_champ_private, libelle: 'type_2_3', order_place: 3, procedure: dossier_2.procedure + + dossier_1.build_default_champs + dossier_2.build_default_champs + end + + subject { dossier.ordered_champs_private } + + it { expect(ChampPrivate.where(dossier_id: 0).size).to eq 5 } + + describe 'for dossier 1' do + let(:dossier) { dossier_1 } + + it { expect(subject.size).to eq 2 } + it { expect(subject.first.type_de_champ.libelle).to eq 'type_1_1' } + it { expect(subject.last.type_de_champ.libelle).to eq 'type_1_2' } + end + + describe 'for dossier 2' do + let(:dossier) { dossier_2 } + + it { expect(subject.size).to eq 3 } + + it { expect(subject.first.type_de_champ.libelle).to eq 'type_2_1' } + it { expect(subject.second.type_de_champ.libelle).to eq 'type_2_2' } + it { expect(subject.last.type_de_champ.libelle).to eq 'type_2_3' } + end + end + describe '#total_follow' do let(:dossier) { create(:dossier, :with_entreprise, user: user) } let(:dossier2) { create(:dossier, :with_entreprise, user: user) } diff --git a/spec/views/admin/types_de_champ_private/show.html.haml_spec.rb b/spec/views/admin/types_de_champ_private/show.html.haml_spec.rb index 319e9c30a..829050748 100644 --- a/spec/views/admin/types_de_champ_private/show.html.haml_spec.rb +++ b/spec/views/admin/types_de_champ_private/show.html.haml_spec.rb @@ -19,7 +19,7 @@ describe 'admin/types_de_champ/show.html.haml', type: :view do end end - describe 'arrow button' do + describe 'elements presents or not' do subject do procedure.reload assign(:procedure, procedure) @@ -27,24 +27,33 @@ describe 'admin/types_de_champ/show.html.haml', type: :view do render rendered end - context 'when there is no field in database' do - it { expect(subject).not_to have_css('.fa-chevron-down') } - it { expect(subject).not_to have_css('.fa-chevron-up') } + + describe 'mandatory checkbox' do + it 'no mandatory checkbox are present' do + expect(subject).not_to have_css('.form-group.mandatory') + end end - context 'when there is only one field in database' do - let!(:type_de_champ_0) { create(:type_de_champ_private, procedure: procedure, order_place: 0) } - it { expect(subject).not_to have_css('#btn_down_0') } - it { expect(subject).not_to have_css('#btn_up_0') } - it { expect(subject).not_to have_css('#btn_up_1') } - it { expect(subject).not_to have_css('#btn_down_1') } - end - context 'when there are 2 fields in database' do - let!(:type_de_champ_0) { create(:type_de_champ_private, procedure: procedure, order_place: 0) } - let!(:type_de_champ_1) { create(:type_de_champ_private, procedure: procedure, order_place: 1) } - it { expect(subject).to have_css('#btn_down_0') } - it { expect(subject).not_to have_css('#btn_up_0') } - it { expect(subject).to have_css('#btn_up_1') } - it { expect(subject).not_to have_css('#btn_down_1') } + + describe 'arrow button' do + context 'when there is no field in database' do + it { expect(subject).not_to have_css('.fa-chevron-down') } + it { expect(subject).not_to have_css('.fa-chevron-up') } + end + context 'when there is only one field in database' do + let!(:type_de_champ_0) { create(:type_de_champ_private, procedure: procedure, order_place: 0) } + it { expect(subject).not_to have_css('#btn_down_0') } + it { expect(subject).not_to have_css('#btn_up_0') } + it { expect(subject).not_to have_css('#btn_up_1') } + it { expect(subject).not_to have_css('#btn_down_1') } + end + context 'when there are 2 fields in database' do + let!(:type_de_champ_0) { create(:type_de_champ_private, procedure: procedure, order_place: 0) } + let!(:type_de_champ_1) { create(:type_de_champ_private, procedure: procedure, order_place: 1) } + it { expect(subject).to have_css('#btn_down_0') } + it { expect(subject).not_to have_css('#btn_up_0') } + it { expect(subject).to have_css('#btn_up_1') } + it { expect(subject).not_to have_css('#btn_down_1') } + end end end end \ No newline at end of file From d6b9ebde9ad4aea58a533a74d13dbdfd282d1594 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Mon, 8 Aug 2016 13:34:26 +0200 Subject: [PATCH 08/10] User can access at the summary tab of comments files --- app/views/backoffice/dossiers/show.html.haml | 37 +--------------- .../dossiers/_tab_objects_dossier.html.haml | 43 +++++++++++++++++++ app/views/users/recapitulatif/show.html.haml | 5 ++- 3 files changed, 47 insertions(+), 38 deletions(-) create mode 100644 app/views/dossiers/_tab_objects_dossier.html.haml diff --git a/app/views/backoffice/dossiers/show.html.haml b/app/views/backoffice/dossiers/show.html.haml index ca83b7225..6a99e2f16 100644 --- a/app/views/backoffice/dossiers/show.html.haml +++ b/app/views/backoffice/dossiers/show.html.haml @@ -14,40 +14,5 @@ %br %div - %ul{class: "nav nav-tabs", role: "tablist"} - %li{role: "presentation", class: "active"} - %a{href: "#commentaires", 'aria-controls' => "commentaires", role: "tab", 'data-toggle' => "tab"} - Commentaires - %li{role: "presentation"} - %a{href: "#commentaires_files", 'aria-controls' => "commentaires_files", role: "tab", 'data-toggle' => "tab"} - Fichiers - %li{role: "presentation"} - %a{href: "#invites", 'aria-controls' => "invites", role: "tab", 'data-toggle' => "tab"} - Invités - %li{role: "presentation"} - %a{href: "#followers", 'aria-controls' => "followers", role: "tab", 'data-toggle' => "tab"} - Abonnés - %li{role: "presentation"} - %a{href: "#champs_private", 'aria-controls' => "champs_private", role: "tab", 'data-toggle' => "tab"} - Formulaire - - %div{class: "tab-content"} - %div{role: "tabpanel", class: "tab-pane fade in active", id:"commentaires"} - %h3 Flux de commentaires - %br - = render partial: '/users/recapitulatif/commentaires_flux' - %div{role: "tabpanel", class: "tab-pane fade", id:"commentaires_files"} - = render partial: '/dossiers/commentaires_files' - %div{role: "tabpanel", class: "tab-pane fade", id:"invites"} - = render partial: '/dossiers/invites' - %div{role: "tabpanel", class: "tab-pane fade", id:"followers"} - = render partial: 'followers' - %div{role: "tabpanel", class: "tab-pane fade", id:"champs_private"} - %h3 Formulaire privé - - unless @champs.nil? - = form_for @facade.dossier, url: {controller: 'backoffice/private_formulaires', action: :update, dossier_id: @facade.dossier.id}, remote: true do - = render partial: '/users/description/champs' - %br - = submit_tag :Enregistrer, {class: 'btn btn-success', style: 'float: right'} - %br + = render partial: 'dossiers/tab_objects_dossier' %br \ No newline at end of file diff --git a/app/views/dossiers/_tab_objects_dossier.html.haml b/app/views/dossiers/_tab_objects_dossier.html.haml new file mode 100644 index 000000000..a478f0dbe --- /dev/null +++ b/app/views/dossiers/_tab_objects_dossier.html.haml @@ -0,0 +1,43 @@ +%ul{class: "nav nav-tabs", role: "tablist"} + %li{role: "presentation", class: "active"} + %a{href: "#commentaires", 'aria-controls' => "commentaires", role: "tab", 'data-toggle' => "tab"} + Commentaires + %li{role: "presentation"} + %a{href: "#commentaires_files", 'aria-controls' => "commentaires_files", role: "tab", 'data-toggle' => "tab"} + Fichiers + + - if gestionnaire_signed_in? + %li{role: "presentation"} + %a{href: "#invites", 'aria-controls' => "invites", role: "tab", 'data-toggle' => "tab"} + Invités + %li{role: "presentation"} + %a{href: "#followers", 'aria-controls' => "followers", role: "tab", 'data-toggle' => "tab"} + Abonnés + %li{role: "presentation"} + %a{href: "#champs_private", 'aria-controls' => "champs_private", role: "tab", 'data-toggle' => "tab"} + Formulaire + +%div{class: "tab-content"} + %div{role: "tabpanel", class: "tab-pane fade in active", id:"commentaires"} + %h3 Flux de commentaires + %br + = render partial: '/users/recapitulatif/commentaires_flux' + %div{role: "tabpanel", class: "tab-pane fade", id:"commentaires_files"} + = render partial: '/dossiers/commentaires_files' + + - if gestionnaire_signed_in? + %div{role: "tabpanel", class: "tab-pane fade", id:"invites"} + = render partial: '/dossiers/invites' + %div{role: "tabpanel", class: "tab-pane fade", id:"followers"} + = render partial: 'followers' + %div{role: "tabpanel", class: "tab-pane fade", id:"champs_private"} + %h3 Formulaire privé + - if @champs.nil? || @champs.empty? + %br + %h4.text-primary + Pas de formulaire privé pour ce dossier + - else + = form_for @facade.dossier, url: {controller: 'backoffice/private_formulaires', action: :update, dossier_id: @facade.dossier.id}, remote: true do + = render partial: '/users/description/champs' + %br + = submit_tag :Enregistrer, {class: 'btn btn-success', style: 'float: right'} \ No newline at end of file diff --git a/app/views/users/recapitulatif/show.html.haml b/app/views/users/recapitulatif/show.html.haml index 6a998be36..4373c2abb 100644 --- a/app/views/users/recapitulatif/show.html.haml +++ b/app/views/users/recapitulatif/show.html.haml @@ -24,5 +24,6 @@ = render partial: '/dossiers/infos_dossier' -%br -= render partial: '/users/recapitulatif/commentaires_flux' \ No newline at end of file +%div + %br + = render partial: 'dossiers/tab_objects_dossier' \ No newline at end of file From 9487d47ef88f9f59ea4dde7e0c04367e1d27dfa4 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Mon, 8 Aug 2016 14:12:16 +0200 Subject: [PATCH 09/10] Add deposit date time on dossier table --- app/controllers/users/recapitulatif_controller.rb | 4 +--- app/models/dossier.rb | 7 +++++++ ...160808115924_add_deposit_attr_in_dossier_table.rb | 5 +++++ db/schema.rb | 3 ++- .../users/recapitulatif_controller_spec.rb | 12 +++++++++--- 5 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 db/migrate/20160808115924_add_deposit_attr_in_dossier_table.rb diff --git a/app/controllers/users/recapitulatif_controller.rb b/app/controllers/users/recapitulatif_controller.rb index 594f30e3d..214e8e594 100644 --- a/app/controllers/users/recapitulatif_controller.rb +++ b/app/controllers/users/recapitulatif_controller.rb @@ -19,11 +19,9 @@ class Users::RecapitulatifController < UsersController def submit create_dossier_facade - @facade.dossier.next_step! 'user', 'submit' + @facade.dossier.submit! flash.notice = 'Dossier déposé avec succès.' - NotificationMailer.dossier_submitted(@facade.dossier).deliver_now! - render 'show' end diff --git a/app/models/dossier.rb b/app/models/dossier.rb index f5ab282d7..eeb9df03d 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -216,4 +216,11 @@ class Dossier < ActiveRecord::Base def total_commentaire self.commentaires.size end + + def submit! + self.deposit_datetime= DateTime.now + + next_step! 'user', 'submit' + NotificationMailer.dossier_submitted(self).deliver_now! + end end diff --git a/db/migrate/20160808115924_add_deposit_attr_in_dossier_table.rb b/db/migrate/20160808115924_add_deposit_attr_in_dossier_table.rb new file mode 100644 index 000000000..a3794eebe --- /dev/null +++ b/db/migrate/20160808115924_add_deposit_attr_in_dossier_table.rb @@ -0,0 +1,5 @@ +class AddDepositAttrInDossierTable < ActiveRecord::Migration + def change + add_column :dossiers, :deposit_datetime, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index b737a1d69..c2ca0cd47 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160804130638) do +ActiveRecord::Schema.define(version: 20160808115924) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -124,6 +124,7 @@ ActiveRecord::Schema.define(version: 20160804130638) do t.text "json_latlngs" t.boolean "archived", default: false t.boolean "mandataire_social", default: false + t.datetime "deposit_datetime" end add_index "dossiers", ["procedure_id"], name: "index_dossiers_on_procedure_id", using: :btree diff --git a/spec/controllers/users/recapitulatif_controller_spec.rb b/spec/controllers/users/recapitulatif_controller_spec.rb index 32146b5c1..79402c694 100644 --- a/spec/controllers/users/recapitulatif_controller_spec.rb +++ b/spec/controllers/users/recapitulatif_controller_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Users::RecapitulatifController, type: :controller do - let(:dossier) { create(:dossier, state:'initiated') } + let(:dossier) { create(:dossier, state: 'initiated') } let(:bad_dossier_id) { Dossier.count + 100000 } before do @@ -55,16 +55,22 @@ describe Users::RecapitulatifController, type: :controller do describe 'POST #submit' do context 'when an user depose his dossier' do + let(:deposit_datetime) { Time.local(2016, 8, 1, 10, 5, 0) } + before do dossier.validated! - post :submit, dossier_id: dossier.id + Timecop.freeze(deposit_datetime) { post :submit, dossier_id: dossier.id } + dossier.reload end it 'dossier change his state for submitted' do - dossier.reload expect(dossier.state).to eq('submitted') end + it 'dossier deposit datetime is filled' do + expect(dossier.deposit_datetime).to eq deposit_datetime + end + it 'a message informe user what his dossier is initiated' do expect(flash[:notice]).to include('Dossier déposé avec succès.') end From 85e7af840a2fbc7bfaf4bafc06662c0e9451ed85 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Tue, 9 Aug 2016 16:21:39 +0200 Subject: [PATCH 10/10] Add drop down list on type champ list --- app/assets/javascripts/admin.js | 18 ++++++---- app/assets/javascripts/application.js | 2 -- .../stylesheets/admin_type_de_champ.scss | 9 +++++ app/assets/stylesheets/description.scss | 6 ++++ .../admin/types_de_champ_controller.rb | 10 ++---- .../types_de_champ_private_controller.rb | 12 ++----- app/models/champ.rb | 2 +- app/models/drop_down_list.rb | 7 ++++ app/models/type_de_champ.rb | 5 +++ app/services/types_de_champ_service.rb | 18 ++++++++++ .../admin/types_de_champ/_fields.html.haml | 7 +++- app/views/users/description/_champs.html.haml | 3 ++ .../champs/_drop_down_list.html.haml | 13 +++++++ ...60809083606_create_drop_down_list_table.rb | 8 +++++ db/schema.rb | 7 +++- .../admin/types_de_champ_controller_spec.rb | 34 ++++++++++++------- .../types_de_champ_private_controller_spec.rb | 12 ++++++- 17 files changed, 132 insertions(+), 41 deletions(-) create mode 100644 app/models/drop_down_list.rb create mode 100644 app/services/types_de_champ_service.rb create mode 100644 app/views/users/description/champs/_drop_down_list.html.haml create mode 100644 db/migrate/20160809083606_create_drop_down_list_table.rb diff --git a/app/assets/javascripts/admin.js b/app/assets/javascripts/admin.js index 8cf2e6467..571e93b65 100644 --- a/app/assets/javascripts/admin.js +++ b/app/assets/javascripts/admin.js @@ -26,13 +26,19 @@ function on_change_type_de_champ_select (){ $("select.form-control.type_champ").on('change', function(e){ - parent = $(this).parent().parent() + parent = $(this).parent().parent(); + + parent.removeClass('header_section'); + parent.children(".drop_down_list").removeClass('show_inline'); + + switch(this.value){ + case 'header_section': + parent.addClass('header_section'); + break; + case 'drop_down_list': + parent.children(".drop_down_list").addClass('show_inline'); + break; - if (this.value === 'header_section') { - parent.addClass('header_section') - } - else { - parent.removeClass('header_section') } }) } \ No newline at end of file diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 288d060c0..79ba48052 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -44,5 +44,3 @@ function scroll_to() { }); } - - diff --git a/app/assets/stylesheets/admin_type_de_champ.scss b/app/assets/stylesheets/admin_type_de_champ.scss index d8b9d1a7b..71747f829 100644 --- a/app/assets/stylesheets/admin_type_de_champ.scss +++ b/app/assets/stylesheets/admin_type_de_champ.scss @@ -14,5 +14,14 @@ .form-group.mandatory { display: none; } +} +#liste_champ{ + .show_inline { + display: inline-block !important; + } + + .form-group.drop_down_list{ + display: none; + } } \ No newline at end of file diff --git a/app/assets/stylesheets/description.scss b/app/assets/stylesheets/description.scss index 6c0845c46..1c6129833 100644 --- a/app/assets/stylesheets/description.scss +++ b/app/assets/stylesheets/description.scss @@ -57,6 +57,12 @@ } } +.type_champ-drop_down_list { + @extend .col-md-4; + @extend .col-lg-4; + +} + .type_champ-civilite { @extend .col-md-3; @extend .col-lg-3; diff --git a/app/controllers/admin/types_de_champ_controller.rb b/app/controllers/admin/types_de_champ_controller.rb index d28fccc87..ee3205901 100644 --- a/app/controllers/admin/types_de_champ_controller.rb +++ b/app/controllers/admin/types_de_champ_controller.rb @@ -7,7 +7,7 @@ class Admin::TypesDeChampController < AdminController create_facade render 'show', format: :js rescue ActiveRecord::RecordNotFound - render json: { message: 'Champ not found' }, status: 404 + render json: {message: 'Champ not found'}, status: 404 end def show @@ -15,18 +15,12 @@ class Admin::TypesDeChampController < AdminController end def update - @procedure.update_attributes(update_params) + @procedure.update_attributes(TypesDeChampService.create_update_procedure_params params) create_facade flash.now.notice = 'Modifications sauvegardées' render 'show', format: :js end - def update_params - params - .require(:procedure) - .permit(types_de_champ_attributes: [:libelle, :description, :order_place, :type_champ, :id, :mandatory, :type]) - end - def move_up index = params[:index].to_i - 1 if @procedure.switch_types_de_champ index diff --git a/app/controllers/admin/types_de_champ_private_controller.rb b/app/controllers/admin/types_de_champ_private_controller.rb index fce48700a..25252b88c 100644 --- a/app/controllers/admin/types_de_champ_private_controller.rb +++ b/app/controllers/admin/types_de_champ_private_controller.rb @@ -7,27 +7,21 @@ class Admin::TypesDeChampPrivateController < AdminController create_facade render 'admin/types_de_champ/show', format: :js rescue ActiveRecord::RecordNotFound - render json: { message: 'Champ not found' }, status: 404 + render json: {message: 'Champ not found'}, status: 404 end def show - create_facade + create_facade render 'admin/types_de_champ/show' end def update - @procedure.update_attributes(update_params) + @procedure.update_attributes(TypesDeChampService.create_update_procedure_params params, true) create_facade flash.now.notice = 'Modifications sauvegardées' render 'admin/types_de_champ/show', format: :js end - def update_params - params - .require(:procedure) - .permit(types_de_champ_private_attributes: [:libelle, :description, :order_place, :type_champ, :id, :mandatory, :type]) - end - def move_up index = params[:index].to_i - 1 if @procedure.switch_types_de_champ_private index diff --git a/app/models/champ.rb b/app/models/champ.rb index 7b6c357b9..ca8e1b531 100644 --- a/app/models/champ.rb +++ b/app/models/champ.rb @@ -2,7 +2,7 @@ class Champ < ActiveRecord::Base belongs_to :dossier belongs_to :type_de_champ - delegate :libelle, :type_champ, :order_place, :mandatory, :description, to: :type_de_champ + delegate :libelle, :type_champ, :order_place, :mandatory, :description, :drop_down_list, to: :type_de_champ def mandatory? mandatory diff --git a/app/models/drop_down_list.rb b/app/models/drop_down_list.rb new file mode 100644 index 000000000..d6e2d3d02 --- /dev/null +++ b/app/models/drop_down_list.rb @@ -0,0 +1,7 @@ +class DropDownList < ActiveRecord::Base + belongs_to :type_de_champ + + def options + value.split(/[\r\n]|[\r]|[\n]|[\n\r]/).reject(&:empty?) + end +end diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index e4df31ea0..4292aa8c7 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -11,12 +11,17 @@ class TypeDeChamp < ActiveRecord::Base phone: 'phone', address: 'address', yes_no: 'yes_no', + drop_down_list: 'drop_down_list', header_section: 'header_section' } belongs_to :procedure has_many :champ, dependent: :destroy + has_one :drop_down_list + + accepts_nested_attributes_for :drop_down_list + validates :libelle, presence: true, allow_blank: false, allow_nil: false validates :type_champ, presence: true, allow_blank: false, allow_nil: false diff --git a/app/services/types_de_champ_service.rb b/app/services/types_de_champ_service.rb new file mode 100644 index 000000000..8a6c7a066 --- /dev/null +++ b/app/services/types_de_champ_service.rb @@ -0,0 +1,18 @@ +class TypesDeChampService + def self.create_update_procedure_params(params, private=false) + attributes = (private ? 'types_de_champ_private_attributes' : 'types_de_champ_attributes') + + parameters = params + .require(:procedure) + .permit("#{attributes}" => [:libelle, :description, :order_place, :type_champ, :id, :mandatory, :type, + drop_down_list_attributes: [:value, :id]]) + + parameters[attributes].each do |param| + if param.second[:libelle].empty? + parameters[attributes].delete(param.first.to_s) + end + end + + parameters + end +end \ No newline at end of file diff --git a/app/views/admin/types_de_champ/_fields.html.haml b/app/views/admin/types_de_champ/_fields.html.haml index 8ef85b152..3b9c5c6f9 100644 --- a/app/views/admin/types_de_champ/_fields.html.haml +++ b/app/views/admin/types_de_champ/_fields.html.haml @@ -10,8 +10,13 @@ .form-group.description %h4 Description - = ff.text_area :description, class: 'form-control description', placeholder: 'Description' + = ff.text_area :description, class: 'form-control description', placeholder: 'Description', rows: 2 + .form-group.drop_down_list{class:"#{ff.object.object.type_champ == 'drop_down_list' ? 'show_inline' : ''}",style:'margin-right: 5px'} + %h4 Liste déroulante + = ff.fields_for :drop_down_list_attributes, ff.object.object.drop_down_list do |fff| + = fff.text_area :value, class: 'form-control drop_down_list', placeholder: "Ecrire une valeur par ligne.\nEcrire --valeur-- pour un séparateur.", rows: 3, cols: 30 + = fff.hidden_field :id - unless ff.object.object.class == TypeDeChampPrivate .form-group.mandatory %h4 Obligatoire ? diff --git a/app/views/users/description/_champs.html.haml b/app/views/users/description/_champs.html.haml index 3d6d5387f..cb78dbd3b 100644 --- a/app/views/users/description/_champs.html.haml +++ b/app/views/users/description/_champs.html.haml @@ -30,6 +30,9 @@ - elsif champ.type_champ == 'yes_no' =render partial: 'users/description/champs/yes_no', locals: {champ: champ} + - elsif champ.type_champ == 'drop_down_list' + =render partial: 'users/description/champs/drop_down_list', locals: {champ: champ} + -else %input.form-control{name:"champs['#{champ.id}']", placeholder: champ.libelle, diff --git a/app/views/users/description/champs/_drop_down_list.html.haml b/app/views/users/description/champs/_drop_down_list.html.haml new file mode 100644 index 000000000..bee4e6609 --- /dev/null +++ b/app/views/users/description/champs/_drop_down_list.html.haml @@ -0,0 +1,13 @@ +%select{ name:"champs['#{champ.id}']", + id: "champs_#{champ.id}" } + - champ.drop_down_list.options.each do |option| + - if (option=~ /^--.*--$/).nil? + - if champ.value == option + %option{selected:''} + = option + - else + %option + = option + -else + %option{disabled:''} + = option diff --git a/db/migrate/20160809083606_create_drop_down_list_table.rb b/db/migrate/20160809083606_create_drop_down_list_table.rb new file mode 100644 index 000000000..505d65067 --- /dev/null +++ b/db/migrate/20160809083606_create_drop_down_list_table.rb @@ -0,0 +1,8 @@ +class CreateDropDownListTable < ActiveRecord::Migration + def change + create_table :drop_down_lists do |t| + t.string :value + t.belongs_to :type_de_champ + end + end +end diff --git a/db/schema.rb b/db/schema.rb index c2ca0cd47..86f0bac18 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160808115924) do +ActiveRecord::Schema.define(version: 20160809083606) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -130,6 +130,11 @@ ActiveRecord::Schema.define(version: 20160808115924) do add_index "dossiers", ["procedure_id"], name: "index_dossiers_on_procedure_id", using: :btree add_index "dossiers", ["user_id"], name: "index_dossiers_on_user_id", using: :btree + create_table "drop_down_lists", force: :cascade do |t| + t.string "value" + t.integer "type_de_champ_id" + end + create_table "entreprises", force: :cascade do |t| t.string "siren" t.integer "capital_social" diff --git a/spec/controllers/admin/types_de_champ_controller_spec.rb b/spec/controllers/admin/types_de_champ_controller_spec.rb index 68203e16f..493dd64a4 100644 --- a/spec/controllers/admin/types_de_champ_controller_spec.rb +++ b/spec/controllers/admin/types_de_champ_controller_spec.rb @@ -41,24 +41,34 @@ describe Admin::TypesDeChampController, type: :controller do let(:mandatory) { 'on' } let(:procedure_params) do - { types_de_champ_attributes: - { '0' => - { - libelle: libelle, - type_champ: type_champ, - description: description, - order_place: order_place, - id: types_de_champ_id, - mandatory: mandatory - } - } + {types_de_champ_attributes: + {'0' => + { + libelle: libelle, + type_champ: type_champ, + description: description, + order_place: order_place, + id: types_de_champ_id, + mandatory: mandatory + }, + '1' => + { + libelle: '', + type_champ: 'text', + description: '', + order_place: '1', + id: '', + mandatory: false, + type: 'TypeDeChampPublic' + } + } } end let(:request) { put :update, format: :js, procedure_id: procedure.id, procedure: procedure_params } context 'when procedure is found' do - it { expect{ request }.to change(TypeDeChamp, :count).by(1) } + it { expect { request }.to change(TypeDeChamp, :count).by(1) } describe 'created type de champ' do before do diff --git a/spec/controllers/admin/types_de_champ_private_controller_spec.rb b/spec/controllers/admin/types_de_champ_private_controller_spec.rb index 2db709955..635fca004 100644 --- a/spec/controllers/admin/types_de_champ_private_controller_spec.rb +++ b/spec/controllers/admin/types_de_champ_private_controller_spec.rb @@ -51,7 +51,17 @@ describe Admin::TypesDeChampPrivateController, type: :controller do id: types_de_champ_id, mandatory: mandatory, type: 'TypeDeChampPrivate' - } + }, + '1' => + { + libelle: '', + type_champ: 'text', + description: '', + order_place: '1', + id: '', + mandatory: false, + type: 'TypeDeChampPrivate' + } } } end