From 26b5e4cb24aa3fc11288ad2512876048d9d3317b Mon Sep 17 00:00:00 2001 From: Xavier J Date: Tue, 2 Aug 2016 16:13:15 +0200 Subject: [PATCH 1/6] 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 2/6] 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 3/6] 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 4/6] 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 5/6] 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 6/6] 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