From baddfdb3d166f6d804d8e5381bc9655c04c905c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 20 Jul 2016 13:15:02 +0200 Subject: [PATCH 01/15] adds phase scopes to budget --- app/models/budget.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/models/budget.rb b/app/models/budget.rb index ea22a4615..d642e7d0c 100644 --- a/app/models/budget.rb +++ b/app/models/budget.rb @@ -10,6 +10,9 @@ class Budget < ActiveRecord::Base has_many :headings, through: :groups has_many :investments, through: :headings + scope :open, -> { where.not(phase: "finished") } + scope :finished, -> { where(phase: "finished") } + def on_hold? phase == "on_hold" end From 1ad78d599e0f30ab5e79f1cf7ffa712c65c96171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Thu, 28 Jul 2016 12:36:39 +0200 Subject: [PATCH 02/15] adds admin budgets index --- app/controllers/admin/budgets_controller.rb | 9 +++ app/views/admin/budgets/index.html.erb | 25 +++++++ config/locales/activerecord.en.yml | 3 + config/locales/activerecord.es.yml | 3 + config/locales/admin.en.yml | 8 +++ config/locales/admin.es.yml | 8 +++ config/locales/en.yml | 7 ++ config/locales/es.yml | 7 ++ config/routes.rb | 7 ++ db/schema.rb | 2 +- spec/features/admin/budgets_spec.rb | 79 +++++++++++++++++++++ 11 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 app/controllers/admin/budgets_controller.rb create mode 100644 app/views/admin/budgets/index.html.erb create mode 100644 spec/features/admin/budgets_spec.rb diff --git a/app/controllers/admin/budgets_controller.rb b/app/controllers/admin/budgets_controller.rb new file mode 100644 index 000000000..a2f92a39e --- /dev/null +++ b/app/controllers/admin/budgets_controller.rb @@ -0,0 +1,9 @@ +class Admin::BudgetsController < Admin::BaseController + + has_filters %w{open finished}, only: :index + + def index + @budgets = Budget.send(@current_filter).order(created_at: :desc).page(params[:page]) + end + +end diff --git a/app/views/admin/budgets/index.html.erb b/app/views/admin/budgets/index.html.erb new file mode 100644 index 000000000..193b6a7ef --- /dev/null +++ b/app/views/admin/budgets/index.html.erb @@ -0,0 +1,25 @@ +

<%= t("admin.budgets.index.title") %>

+ +<%= link_to t("admin.budgets.index.new_link"), + new_admin_budget_path, + class: "button float-right margin-right" %> + +<%= render 'shared/filter_subnav', i18n_namespace: "admin.budgets.index" %> + + +

<%= page_entries_info @budgets %>

+ + + <% @budgets.each do |budget| %> + + + + + <% end %> +
+ <%= link_to budget.name, admin_budget_path(budget) %> + + <%= t("budget.phase.#{budget.phase}") %> +
+ +<%= paginate @budgets %> \ No newline at end of file diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index 07791e53c..5a7a591bd 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -4,6 +4,9 @@ en: activity: one: "activity" other: "activities" + budget: + one: "Participatory budget" + other: "Participatory budgets" comment: one: "Comment" other: "Comments" diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index d5b7f0005..ccd0240e8 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -4,6 +4,9 @@ es: activity: one: "actividad" other: "actividades" + budget: + one: "Presupuesto participativo" + other: "Presupuestos participativos" comment: one: "Comentario" other: "Comentarios" diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 2f73f64d8..7d32e3291 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -60,6 +60,13 @@ en: on_users: Users title: Moderator activity type: Type + budgets: + index: + title: Participatory budgets + new_link: Create new + filters: + open: Open + finished: Finished comments: index: filter: Filter @@ -96,6 +103,7 @@ en: activity: Moderator activity admin: Admin menu banner: Manage banners + budgets: Participatory budgets debate_topics: Debate topics hidden_comments: Hidden comments hidden_debates: Hidden debates diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 5aada1ce1..c5f0df247 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -58,6 +58,13 @@ es: on_users: Usuarios title: Actividad de los Moderadores type: Tipo + budgets: + index: + title: Presupuestos participativos + new_link: Crear nuevo + filters: + open: Abiertos + finished: Terminados comments: index: filter: Filtro @@ -94,6 +101,7 @@ es: activity: Actividad de moderadores admin: Menú de administración banner: Gestionar banners + budgets: Presupuestos participativos debate_topics: Temas de debate hidden_comments: Comentarios ocultos hidden_debates: Debates ocultos diff --git a/config/locales/en.yml b/config/locales/en.yml index 05153d714..fae75307f 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -33,6 +33,13 @@ en: application: close: Close menu: Menu + budget: + phase: + on_hold: On hold + accepting: Accepting proposals + selecting: Selecting + balloting: Balloting + finished: Finished comments: comment: admin: Administrator diff --git a/config/locales/es.yml b/config/locales/es.yml index 9391da3bf..282340395 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -33,6 +33,13 @@ es: application: close: Cerrar menu: Menú + budget: + phase: + on_hold: Pausa + accepting: Aceptando propuestas + selecting: Fase de selección + balloting: Fase de Votación + finished: Terminado comments: comment: admin: Administrador diff --git a/config/routes.rb b/config/routes.rb index 22518f8c8..8cf94ea23 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -153,6 +153,13 @@ Rails.application.routes.draw do get :summary, on: :collection end + resources :budgets do + resources :budget_groups do + resources :budget_headings do + end + end + end + resources :banners, only: [:index, :new, :create, :edit, :update, :destroy] do collection { get :search} end diff --git a/db/schema.rb b/db/schema.rb index ee5b3ab6f..df58b15cb 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -210,10 +210,10 @@ ActiveRecord::Schema.define(version: 20160617172616) do t.string "visit_id" t.datetime "hidden_at" t.integer "flags_count", default: 0 - t.datetime "ignored_flag_at" t.integer "cached_votes_total", default: 0 t.integer "cached_votes_up", default: 0 t.integer "cached_votes_down", default: 0 + t.datetime "ignored_flag_at" t.integer "comments_count", default: 0 t.datetime "confirmed_hide_at" t.integer "cached_anonymous_votes_total", default: 0 diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb new file mode 100644 index 000000000..8326a5dac --- /dev/null +++ b/spec/features/admin/budgets_spec.rb @@ -0,0 +1,79 @@ +require 'rails_helper' + +feature 'Admin budgets' do + + background do + admin = create(:administrator) + login_as(admin.user) + end + + context "Feature flag" do + + xscenario 'Disabled with a feature flag' do + Setting['feature.budgets'] = nil + expect{ visit admin_budgets_path }.to raise_exception(FeatureFlags::FeatureDisabled) + end + + end + + context "Index" do + + scenario 'Displaying budgets' do + budget = create(:budget) + visit admin_budgets_path + + expect(page).to have_content(budget.name) + expect(page).to have_content(I18n.t("budget.phase.#{budget.phase}")) + end + + scenario 'Filters by phase' do + budget1 = create(:budget) + budget2 = create(:budget, :accepting) + budget3 = create(:budget, :selecting) + budget4 = create(:budget, :balloting) + budget5 = create(:budget, :finished) + + visit admin_budgets_path + expect(page).to have_content(budget1.name) + expect(page).to have_content(budget2.name) + expect(page).to have_content(budget3.name) + expect(page).to have_content(budget4.name) + expect(page).to_not have_content(budget5.name) + + click_link "Finished" + expect(page).to_not have_content(budget1.name) + expect(page).to_not have_content(budget2.name) + expect(page).to_not have_content(budget3.name) + expect(page).to_not have_content(budget4.name) + expect(page).to have_content(budget5.name) + + click_link "Open" + expect(page).to have_content(budget1.name) + expect(page).to have_content(budget2.name) + expect(page).to have_content(budget3.name) + expect(page).to have_content(budget4.name) + expect(page).to_not have_content(budget5.name) + end + + + scenario "Current filter is properly highlighted" do + filters_links = {'open' => 'Open', 'finished' => 'Finished'} + + visit admin_budgets_path + + expect(page).to_not have_link(filters_links.values.first) + filters_links.keys.drop(1).each { |filter| expect(page).to have_link(filters_links[filter]) } + + filters_links.each_pair do |current_filter, link| + visit admin_budgets_path(filter: current_filter) + + expect(page).to_not have_link(link) + + (filters_links.keys - [current_filter]).each do |filter| + expect(page).to have_link(filters_links[filter]) + end + end + end + + end +end \ No newline at end of file From a9c3629de7e77455042f6614040e1ec65b95363c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Thu, 28 Jul 2016 12:37:00 +0200 Subject: [PATCH 03/15] adds missing trait to testing factories --- spec/factories.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/factories.rb b/spec/factories.rb index 263900ecd..bca0c51e3 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -193,6 +193,10 @@ FactoryGirl.define do currency_symbol "€" phase 'on_hold' + trait :accepting do + phase 'accepting' + end + trait :selecting do phase 'selecting' end From 958cfb1338500d0d5f32467ebb6878762dde1fe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Thu, 28 Jul 2016 12:37:12 +0200 Subject: [PATCH 04/15] adds budgets to admin's menu --- app/views/admin/_menu.html.erb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 7ea48b2c6..d1feaeb1e 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -35,6 +35,14 @@ <% end %> + <%# if feature?(:budgets) %> +
  • > + <%= link_to admin_budgets_path do %> + <%= t("admin.menu.budgets") %> + <% end %> +
  • + <%# end %> +
  • > <%= link_to admin_banners_path do %> <%= t("admin.menu.banner") %> From 6bb09185e4db3c0ee5d74ed127b1930269459691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Thu, 28 Jul 2016 12:40:57 +0200 Subject: [PATCH 05/15] makes i18n-tasks ignore filter keys in budgets --- config/i18n-tasks.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index 250ed18f9..e24d3af0c 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -112,6 +112,7 @@ ignore_unused: - 'admin.banners.index.filters.*' - 'admin.debates.index.filter*' - 'admin.proposals.index.filter*' + - 'admin.budgets.index.filter*' - 'admin.spending_proposals.index.filter*' - 'admin.organizations.index.filter*' - 'admin.users.index.filter*' From b69308b770781e054ec4c5c67b49b0ce6b54d5e9 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Thu, 28 Jul 2016 13:04:30 +0200 Subject: [PATCH 06/15] Adds example content for admin budget new --- app/assets/stylesheets/admin.scss | 5 + app/controllers/admin/budgets_controller.rb | 3 + app/views/admin/budgets/new.html.erb | 137 ++++++++++++++++++++ config/locales/admin.es.yml | 16 +++ 4 files changed, 161 insertions(+) create mode 100644 app/views/admin/budgets/new.html.erb diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index cd8241fca..11a481c1e 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -36,6 +36,11 @@ body.admin { input[type="text"], textarea { width: 100%; } + + .input-group input[type="text"] { + border-radius: 0; + margin-bottom: 0 !important; + } } table { diff --git a/app/controllers/admin/budgets_controller.rb b/app/controllers/admin/budgets_controller.rb index a2f92a39e..7953aae75 100644 --- a/app/controllers/admin/budgets_controller.rb +++ b/app/controllers/admin/budgets_controller.rb @@ -6,4 +6,7 @@ class Admin::BudgetsController < Admin::BaseController @budgets = Budget.send(@current_filter).order(created_at: :desc).page(params[:page]) end + def new + end + end diff --git a/app/views/admin/budgets/new.html.erb b/app/views/admin/budgets/new.html.erb new file mode 100644 index 000000000..66484f7b4 --- /dev/null +++ b/app/views/admin/budgets/new.html.erb @@ -0,0 +1,137 @@ +
    +
    +

    <%= t("admin.budgets.new.title") %>

    + +
    + + "> + + +
    +
    + +
    +
    + +
    +
    + " class="button success"> +
    +
    +
    + +
    + + +
    +
    +

    Nombre del budget

    + + <%= link_to t("admin.budgets.new.add_group"), "#", class: "button float-right" %> + +
    + + "> +
    +
    +
    + +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Nombre del grupo + <%= link_to t("admin.budgets.new.add_heading"), "#", class: "button float-right" %> +
    <%= t("admin.budgets.new.table_heading") %><%= t("admin.budgets.new.table_amount") %><%= t("admin.budgets.new.table_geozone") %>
    +
    + <%= t("admin.budgets.new.no_heading") %> +
    +
    +
    +
    + + + + "> +
    + ", class="button success"> +
    +
    +
    +
    + Heading 1 name + + 9999€ + + +
    + Heading 2 name + + 24000000€ + + +
    + Heading 3 name + + 1265000€ + + +
    +
    +
    diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index c5f0df247..0045eebfe 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -65,6 +65,22 @@ es: filters: open: Abiertos finished: Terminados + new: + title: Nuevo presupuesto ciudadano + create: Crear presupuesto + name: Nombre del presupuesto + description: Descripción + phase: Fase + currency: Divisa + group: Nombre del grupo + add_group: Añadir nuevo grupo + heading: Nombre de la partida + add_heading: Añadir partida + save_heading: Guardar partida + no_heading: Este grupo no tiene ninguna partida asignada. + table_heading: Partida + table_amount: Cantidad + table_geozone: Ámbito de actuación comments: index: filter: Filtro From 3e892c6e7611dbb03d46331e38dda920f0e2897e Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Thu, 28 Jul 2016 19:21:53 +0200 Subject: [PATCH 07/15] Adds translations and improve example content --- app/assets/stylesheets/admin.scss | 4 ++ app/views/admin/budgets/new.html.erb | 62 +++++++++++++++------------- config/locales/admin.en.yml | 22 +++++++++- config/locales/admin.es.yml | 4 ++ 4 files changed, 62 insertions(+), 30 deletions(-) diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index 11a481c1e..196d0be17 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -47,6 +47,10 @@ body.admin { th { text-align: left; + + &.with-button { + line-height: $line-height*2; + } } tr { diff --git a/app/views/admin/budgets/new.html.erb b/app/views/admin/budgets/new.html.erb index 66484f7b4..f71e7c7a5 100644 --- a/app/views/admin/budgets/new.html.erb +++ b/app/views/admin/budgets/new.html.erb @@ -31,9 +31,6 @@ -
    - -

    Nombre del budget

    @@ -41,20 +38,25 @@ <%= link_to t("admin.budgets.new.add_group"), "#", class: "button float-right" %>
    - - "> +
    + + + + "> +
    + ", class="button success"> +
    +
    -
    -
    - @@ -79,30 +81,37 @@ - + + @@ -110,12 +119,10 @@ Heading 2 name @@ -123,14 +130,13 @@ Heading 3 name +
    + Nombre del grupo <%= link_to t("admin.budgets.new.add_heading"), "#", class: "button float-right" %>
    -
    - - - - "> -
    - ", class="button success"> + + "> + +
    +
    + + "> +
    +
    + +
    + + ", class="button success">
    Heading 1 name - 9999€ + 190.000€ - + Geozone B
    - 24000000€ + 24.000.000€ - + Does not apply
    - 1265000€ + 1.265.000€ - + Geozone A
    diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 7d32e3291..a778f6745 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -32,8 +32,6 @@ en: editing: Edit banner form: submit_button: Save changes - errors: - form: errors: form: error: @@ -67,6 +65,26 @@ en: filters: open: Open finished: Finished + new: + title: New participatory budget + create: Create budget + name: Budget's name + description: Description + phase: Phase + currency: Currency + group: Group's name + add_group: Add new group + create_group: Create group + heading: Heading's name + add_heading: Add heading + amount: Amount + save_heading: Save heading + no_heading: This group has no assigned heading. + geozone: Scope of operation + no_geozone: Does not apply + table_heading: Heading + table_amount: Amount + table_geozone: Scope of operation comments: index: filter: Filter diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 0045eebfe..3154060bf 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -74,10 +74,14 @@ es: currency: Divisa group: Nombre del grupo add_group: Añadir nuevo grupo + create_group: Crear grupo heading: Nombre de la partida add_heading: Añadir partida + amount: Cantidad save_heading: Guardar partida no_heading: Este grupo no tiene ninguna partida asignada. + geozone: Ámbito de actuación + no_geozone: No aplica table_heading: Partida table_amount: Cantidad table_geozone: Ámbito de actuación From 9014de269323581462be1aea4e61a822b559f033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Fri, 29 Jul 2016 13:34:11 +0200 Subject: [PATCH 08/15] adds budgets_helper --- app/helpers/budgets_helper.rb | 11 +++++++++++ app/models/budget.rb | 2 ++ 2 files changed, 13 insertions(+) create mode 100644 app/helpers/budgets_helper.rb diff --git a/app/helpers/budgets_helper.rb b/app/helpers/budgets_helper.rb new file mode 100644 index 000000000..d281ef182 --- /dev/null +++ b/app/helpers/budgets_helper.rb @@ -0,0 +1,11 @@ +module BudgetsHelper + + def budget_phases_select_options + Budget::VALID_PHASES.map { |ph| [ t("budget.phase.#{ph}"), ph ] } + end + + def budget_currency_symbol_select_options + Budget::CURRENCY_SYMBOLS.map { |cs| [ cs, cs ] } + end + +end \ No newline at end of file diff --git a/app/models/budget.rb b/app/models/budget.rb index d642e7d0c..18f30ba7c 100644 --- a/app/models/budget.rb +++ b/app/models/budget.rb @@ -1,7 +1,9 @@ class Budget < ActiveRecord::Base VALID_PHASES = %W{on_hold accepting selecting balloting finished} + CURRENCY_SYMBOLS = %W{€ $ £ ¥} + validates :name, presence: true validates :phase, inclusion: { in: VALID_PHASES } has_many :investments, dependent: :destroy From 6fce9df4513817b45163e8dbab1ff1a32d7b47ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Fri, 29 Jul 2016 13:34:41 +0200 Subject: [PATCH 09/15] adds admin creation of budgets --- app/controllers/admin/budgets_controller.rb | 16 +++ app/views/admin/budgets/new.html.erb | 145 +++----------------- config/locales/admin.en.yml | 2 + config/locales/admin.es.yml | 2 + config/locales/es.yml | 2 +- spec/features/admin/budgets_spec.rb | 35 ++++- 6 files changed, 67 insertions(+), 135 deletions(-) diff --git a/app/controllers/admin/budgets_controller.rb b/app/controllers/admin/budgets_controller.rb index 7953aae75..d6f2789e6 100644 --- a/app/controllers/admin/budgets_controller.rb +++ b/app/controllers/admin/budgets_controller.rb @@ -7,6 +7,22 @@ class Admin::BudgetsController < Admin::BaseController end def new + @budget = Budget.new end + def create + @budget = Budget.new(budget_params) + if @budget.save + redirect_to admin_budgets_path, notice: t('admin.budgets.create.notice') + else + render :new + end + end + + private + + def budget_params + params.require(:budget).permit(:name, :description, :phase, :currency_symbol) + end + end diff --git a/app/views/admin/budgets/new.html.erb b/app/views/admin/budgets/new.html.erb index f71e7c7a5..c7985b98f 100644 --- a/app/views/admin/budgets/new.html.erb +++ b/app/views/admin/budgets/new.html.erb @@ -2,142 +2,29 @@

    <%= t("admin.budgets.new.title") %>

    -
    - - "> - - + <%= form_for [:admin, @budget] do |f| %> + + <%= f.label :name, t("admin.budgets.new.name") %> + <%= f.text_field :name, + label: false, + maxlength: 30, + placeholder: t("admin.budgets.new.name") %> + + <%= f.label :description, t("admin.budgets.new.description") %> + <%= f.text_area :description, rows: 3, maxlength: 6000, label: false, placeholder: t("admin.budgets.new.description") %> +
    - + <%= f.label :description, t("admin.budgets.new.phase") %> + <%= f.select :phase, budget_phases_select_options, {label: false} %>
    - + <%= f.label :description, t("admin.budgets.new.currency") %> + <%= f.select :currency_symbol, budget_currency_symbol_select_options, {label: false} %>
    " class="button success"> -
    + <% end %>
    -
    -
    -

    Nombre del budget

    - - <%= link_to t("admin.budgets.new.add_group"), "#", class: "button float-right" %> - -
    -
    - - - - "> -
    - ", class="button success"> -
    -
    -
    -
    -
    - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Nombre del grupo - <%= link_to t("admin.budgets.new.add_heading"), "#", class: "button float-right" %> -
    <%= t("admin.budgets.new.table_heading") %><%= t("admin.budgets.new.table_amount") %><%= t("admin.budgets.new.table_geozone") %>
    -
    - <%= t("admin.budgets.new.no_heading") %> -
    -
    -
    - - "> - -
    -
    - - "> -
    -
    - - -
    -
    - - ", class="button success"> -
    -
    - Heading 1 name - - 190.000€ - - Geozone B -
    - Heading 2 name - - 24.000.000€ - - Does not apply -
    - Heading 3 name - - 1.265.000€ - - Geozone A -
    -
    -
    diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index a778f6745..d55d24726 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -65,6 +65,8 @@ en: filters: open: Open finished: Finished + create: + notice: New participatory budget created successfully! new: title: New participatory budget create: Create budget diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 3154060bf..8ed57d4d8 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -65,6 +65,8 @@ es: filters: open: Abiertos finished: Terminados + create: + notice: ¡Nueva campaña de presupuestos participativos creada con éxito! new: title: Nuevo presupuesto ciudadano create: Crear presupuesto diff --git a/config/locales/es.yml b/config/locales/es.yml index 282340395..195a80766 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -35,7 +35,7 @@ es: menu: Menú budget: phase: - on_hold: Pausa + on_hold: En pausa accepting: Aceptando propuestas selecting: Fase de selección balloting: Fase de Votación diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb index 8326a5dac..c684d8a55 100644 --- a/spec/features/admin/budgets_spec.rb +++ b/spec/features/admin/budgets_spec.rb @@ -7,7 +7,7 @@ feature 'Admin budgets' do login_as(admin.user) end - context "Feature flag" do + context 'Feature flag' do xscenario 'Disabled with a feature flag' do Setting['feature.budgets'] = nil @@ -16,7 +16,7 @@ feature 'Admin budgets' do end - context "Index" do + context 'Index' do scenario 'Displaying budgets' do budget = create(:budget) @@ -40,14 +40,14 @@ feature 'Admin budgets' do expect(page).to have_content(budget4.name) expect(page).to_not have_content(budget5.name) - click_link "Finished" + click_link 'Finished' expect(page).to_not have_content(budget1.name) expect(page).to_not have_content(budget2.name) expect(page).to_not have_content(budget3.name) expect(page).to_not have_content(budget4.name) expect(page).to have_content(budget5.name) - click_link "Open" + click_link 'Open' expect(page).to have_content(budget1.name) expect(page).to have_content(budget2.name) expect(page).to have_content(budget3.name) @@ -56,7 +56,7 @@ feature 'Admin budgets' do end - scenario "Current filter is properly highlighted" do + scenario 'Current filter is properly highlighted' do filters_links = {'open' => 'Open', 'finished' => 'Finished'} visit admin_budgets_path @@ -76,4 +76,29 @@ feature 'Admin budgets' do end end + + context 'New' do + scenario 'Create budget' do + visit admin_budgets_path + click_link 'Create new' + + fill_in 'budget_name', with: 'M30 - Summer campaign' + fill_in 'budget_description', with: 'Budgeting for summer 2017 maintenance and improvements of the road M-30' + select 'Accepting proposals', from: 'budget[phase]' + + click_button 'Create budget' + + expect(page).to have_content 'New participatory budget created successfully!' + expect(page).to have_content 'M30 - Summer campaign' + end + + scenario 'Name is mandatory' do + visit new_admin_budget_path + click_button 'Create budget' + + expect(page).to_not have_content 'New participatory budget created successfully!' + expect(page).to have_css("label.error", text: "Budget's name") + end + + end end \ No newline at end of file From 49bc6533e8e2e2c13c8c1487dbc05031ee41ef8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Fri, 29 Jul 2016 13:39:08 +0200 Subject: [PATCH 10/15] adds explicit permission to admin to read budgets --- app/controllers/admin/budgets_controller.rb | 2 ++ app/models/abilities/administrator.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/budgets_controller.rb b/app/controllers/admin/budgets_controller.rb index d6f2789e6..02894240e 100644 --- a/app/controllers/admin/budgets_controller.rb +++ b/app/controllers/admin/budgets_controller.rb @@ -2,6 +2,8 @@ class Admin::BudgetsController < Admin::BaseController has_filters %w{open finished}, only: :index + load_and_authorize_resource + def index @budgets = Budget.send(@current_filter).order(created_at: :desc).page(params[:page]) end diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index 42e4ecbd3..65f97db2e 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -42,7 +42,7 @@ module Abilities can [:read, :update, :valuate, :destroy, :summary], SpendingProposal - can [:create, :update], Budget + can [:read, :create, :update], Budget can [:hide, :update], Budget::Investment can :valuate, Budget::Investment, budget: { valuating: true } can :create, Budget::ValuatorAssignment From 724ccf175c1a23a1e882c363f7d6fa54a565e1d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Fri, 29 Jul 2016 14:52:37 +0200 Subject: [PATCH 11/15] adds budget show to admin --- app/controllers/admin/budgets_controller.rb | 5 ++++- app/views/admin/budgets/new.html.erb | 3 +-- app/views/admin/budgets/show.html.erb | 12 ++++++++++++ config/locales/admin.en.yml | 3 +++ config/locales/admin.es.yml | 3 +++ spec/features/admin/budgets_spec.rb | 2 +- 6 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 app/views/admin/budgets/show.html.erb diff --git a/app/controllers/admin/budgets_controller.rb b/app/controllers/admin/budgets_controller.rb index 02894240e..2e8a28fe6 100644 --- a/app/controllers/admin/budgets_controller.rb +++ b/app/controllers/admin/budgets_controller.rb @@ -8,6 +8,9 @@ class Admin::BudgetsController < Admin::BaseController @budgets = Budget.send(@current_filter).order(created_at: :desc).page(params[:page]) end + def show + end + def new @budget = Budget.new end @@ -15,7 +18,7 @@ class Admin::BudgetsController < Admin::BaseController def create @budget = Budget.new(budget_params) if @budget.save - redirect_to admin_budgets_path, notice: t('admin.budgets.create.notice') + redirect_to admin_budget_path(@budget), notice: t('admin.budgets.create.notice') else render :new end diff --git a/app/views/admin/budgets/new.html.erb b/app/views/admin/budgets/new.html.erb index c7985b98f..019ca460f 100644 --- a/app/views/admin/budgets/new.html.erb +++ b/app/views/admin/budgets/new.html.erb @@ -26,5 +26,4 @@ " class="button success"> <% end %> - - + \ No newline at end of file diff --git a/app/views/admin/budgets/show.html.erb b/app/views/admin/budgets/show.html.erb new file mode 100644 index 000000000..20185b2ba --- /dev/null +++ b/app/views/admin/budgets/show.html.erb @@ -0,0 +1,12 @@ +
    +
    +

    <%= @budget.name %>

    + + <%= simple_format(text_with_links(@budget.description), {}, sanitize: false) %> + +

    + <%= t('admin.budgets.show.phase') %>: <%= t("budget.phase.#{@budget.phase}") %> | + <%= t('admin.budgets.show.currency') %>: <%= @budget.currency_symbol %> +

    +
    +
    \ No newline at end of file diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index d55d24726..812e1a45c 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -87,6 +87,9 @@ en: table_heading: Heading table_amount: Amount table_geozone: Scope of operation + show: + phase: Current phase + currency: Currency comments: index: filter: Filter diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 8ed57d4d8..1afc01ef2 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -87,6 +87,9 @@ es: table_heading: Partida table_amount: Cantidad table_geozone: Ámbito de actuación + show: + phase: Fase actual + currency: Divisa comments: index: filter: Filtro diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb index c684d8a55..f38d2c9f5 100644 --- a/spec/features/admin/budgets_spec.rb +++ b/spec/features/admin/budgets_spec.rb @@ -55,7 +55,6 @@ feature 'Admin budgets' do expect(page).to_not have_content(budget5.name) end - scenario 'Current filter is properly highlighted' do filters_links = {'open' => 'Open', 'finished' => 'Finished'} @@ -78,6 +77,7 @@ feature 'Admin budgets' do end context 'New' do + scenario 'Create budget' do visit admin_budgets_path click_link 'Create new' From c4768e380d01efbbac3d63a52f86fb49861b2abc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Sat, 30 Jul 2016 09:56:13 +0200 Subject: [PATCH 12/15] saves querys --- app/views/shared/_admin_login_items.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/shared/_admin_login_items.html.erb b/app/views/shared/_admin_login_items.html.erb index 6ba10bbca..013320f38 100644 --- a/app/views/shared/_admin_login_items.html.erb +++ b/app/views/shared/_admin_login_items.html.erb @@ -5,13 +5,13 @@
  • <% end %> - <% if current_user.moderator? || current_user.administrator? %> + <% if current_user.administrator? || current_user.moderator? %>
  • <%= link_to t("layouts.header.moderation"), moderation_root_path %>
  • <% end %> - <% if feature?(:spending_proposals) && (current_user.valuator? || current_user.administrator?) %> + <% if feature?(:spending_proposals) && (current_user.administrator? || current_user.valuator?) %>
  • <%= link_to t("layouts.header.valuation"), valuation_root_path %>
  • From 64a614c67f2ce55e815980df5bd989879945e131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Wed, 3 Aug 2016 20:20:52 +0200 Subject: [PATCH 13/15] adds geozone helper to map ids and names --- app/helpers/geozones_helper.rb | 5 +++++ spec/helpers/geozones_helper_spec.rb | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/app/helpers/geozones_helper.rb b/app/helpers/geozones_helper.rb index bfc5f9105..ce03e0579 100644 --- a/app/helpers/geozones_helper.rb +++ b/app/helpers/geozones_helper.rb @@ -8,4 +8,9 @@ module GeozonesHelper Geozone.all.order(name: :asc).collect { |g| [ g.name, g.id ] } end + def geozone_name_from_id(g_id) + @all_geozones ||= Geozone.all.collect{ |g| [ g.id, g.name ] }.to_h + @all_geozones[g_id] || t("geozones.none") + end + end diff --git a/spec/helpers/geozones_helper_spec.rb b/spec/helpers/geozones_helper_spec.rb index 605a774a6..0c0c13d70 100644 --- a/spec/helpers/geozones_helper_spec.rb +++ b/spec/helpers/geozones_helper_spec.rb @@ -31,4 +31,19 @@ describe GeozonesHelper do end end + describe "#geozone_name_from_id" do + + it "returns geozone name if present" do + g1 = create(:geozone, name: "AAA") + g2 = create(:geozone, name: "BBB") + + expect(geozone_name_from_id(g1.id)).to eq "AAA" + expect(geozone_name_from_id(g2.id)).to eq "BBB" + end + + it "returns default string for no geozone if geozone is blank" do + expect(geozone_name_from_id(nil)).to eq "All city" + end + end + end From 0f7e23bec49a2494dce28c771a0b521ea549111e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Wed, 3 Aug 2016 20:23:41 +0200 Subject: [PATCH 14/15] adds budget's groups & headings to admin --- .../admin/budget_groups_controller.rb | 15 ++++ .../admin/budget_headings_controller.rb | 16 ++++ app/controllers/admin/budgets_controller.rb | 1 + app/models/abilities/administrator.rb | 4 +- app/views/admin/budget_groups/create.js.erb | 2 + app/views/admin/budget_headings/create.js.erb | 2 + app/views/admin/budgets/_group.html.erb | 76 +++++++++++++++++++ app/views/admin/budgets/_groups.html.erb | 34 +++++++++ app/views/admin/budgets/new.html.erb | 2 +- app/views/admin/budgets/show.html.erb | 4 + config/locales/admin.en.yml | 9 ++- config/locales/admin.es.yml | 9 ++- spec/features/admin/budgets_spec.rb | 54 +++++++++++++ 13 files changed, 220 insertions(+), 8 deletions(-) create mode 100644 app/controllers/admin/budget_groups_controller.rb create mode 100644 app/controllers/admin/budget_headings_controller.rb create mode 100644 app/views/admin/budget_groups/create.js.erb create mode 100644 app/views/admin/budget_headings/create.js.erb create mode 100644 app/views/admin/budgets/_group.html.erb create mode 100644 app/views/admin/budgets/_groups.html.erb diff --git a/app/controllers/admin/budget_groups_controller.rb b/app/controllers/admin/budget_groups_controller.rb new file mode 100644 index 000000000..18f5a6b12 --- /dev/null +++ b/app/controllers/admin/budget_groups_controller.rb @@ -0,0 +1,15 @@ +class Admin::BudgetGroupsController < Admin::BaseController + + def create + @budget = Budget.find params[:budget_id] + @budget.groups.create(budget_group_params) + @groups = @budget.groups.includes(:headings) + end + + private + + def budget_group_params + params.require(:budget_group).permit(:name) + end + +end \ No newline at end of file diff --git a/app/controllers/admin/budget_headings_controller.rb b/app/controllers/admin/budget_headings_controller.rb new file mode 100644 index 000000000..3c8ccafa0 --- /dev/null +++ b/app/controllers/admin/budget_headings_controller.rb @@ -0,0 +1,16 @@ +class Admin::BudgetHeadingsController < Admin::BaseController + + def create + @budget = Budget.find params[:budget_id] + @budget_group = @budget.groups.find params[:budget_group_id] + @budget_group.headings.create(budget_heading_params) + @headings = @budget_group.headings + end + + private + + def budget_heading_params + params.require(:budget_heading).permit(:name, :price, :geozone_id) + end + +end \ No newline at end of file diff --git a/app/controllers/admin/budgets_controller.rb b/app/controllers/admin/budgets_controller.rb index 2e8a28fe6..144b43a7f 100644 --- a/app/controllers/admin/budgets_controller.rb +++ b/app/controllers/admin/budgets_controller.rb @@ -9,6 +9,7 @@ class Admin::BudgetsController < Admin::BaseController end def show + @budget = Budget.includes(groups: :headings).find(params[:id]) end def new diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index 65f97db2e..f3f0b8f9b 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -42,7 +42,9 @@ module Abilities can [:read, :update, :valuate, :destroy, :summary], SpendingProposal - can [:read, :create, :update], Budget + can [:index, :read, :new, :create, :update, :destroy], Budget + can [:read, :create, :update, :destroy], Budget::Group + can [:read, :create, :update, :destroy], Budget::Heading can [:hide, :update], Budget::Investment can :valuate, Budget::Investment, budget: { valuating: true } can :create, Budget::ValuatorAssignment diff --git a/app/views/admin/budget_groups/create.js.erb b/app/views/admin/budget_groups/create.js.erb new file mode 100644 index 000000000..cb926a7c6 --- /dev/null +++ b/app/views/admin/budget_groups/create.js.erb @@ -0,0 +1,2 @@ +$("#<%= dom_id(@budget) %>_groups").html('<%= j render("admin/budgets/groups", groups: @groups) %>'); +App.Forms.toggleLink(); \ No newline at end of file diff --git a/app/views/admin/budget_headings/create.js.erb b/app/views/admin/budget_headings/create.js.erb new file mode 100644 index 000000000..5d8eefb2d --- /dev/null +++ b/app/views/admin/budget_headings/create.js.erb @@ -0,0 +1,2 @@ +$("#<%= dom_id(@budget_group) %>").html('<%= j render("admin/budgets/group", group: @budget_group, headings: @headings) %>'); +App.Forms.toggleLink(); \ No newline at end of file diff --git a/app/views/admin/budgets/_group.html.erb b/app/views/admin/budgets/_group.html.erb new file mode 100644 index 000000000..3660fa0c1 --- /dev/null +++ b/app/views/admin/budgets/_group.html.erb @@ -0,0 +1,76 @@ +
    + + + + + + + <% if headings.blank? %> + + + + + <% else %> + + + + + + + + <% end %> + + + + + + + + <% headings.each do |heading| %> + + + + + + <% end %> + + +
    + <%= group.name %> + <%= link_to t("admin.budgets.form.add_heading"), "#", class: "button float-right js-toggle-link", data: { "toggle-selector" => "#group-#{group.id}-new-heading-form" } %> +
    +
    + <%= t("admin.budgets.form.no_heading") %> +
    +
    <%= t("admin.budgets.form.table_heading") %><%= t("admin.budgets.form.table_amount") %><%= t("admin.budgets.form.table_geozone") %>
    + <%= heading.name %> + + <%= heading.price %> + + <%= geozone_name_from_id heading.geozone_id %> +
    +
    \ No newline at end of file diff --git a/app/views/admin/budgets/_groups.html.erb b/app/views/admin/budgets/_groups.html.erb new file mode 100644 index 000000000..ba785ee0c --- /dev/null +++ b/app/views/admin/budgets/_groups.html.erb @@ -0,0 +1,34 @@ +
    +

    <%= t('admin.budgets.show.groups') %>

    + <% if groups.blank? %> +
    + <%= t("admin.budgets.form.no_groups") %> + <%= link_to t("admin.budgets.form.add_group"), "#", + class: "js-toggle-link", + data: { "toggle-selector" => "#new-group-form" } %> +
    + <% else %> + <%= link_to t("admin.budgets.form.add_group"), "#", class: "button float-right js-toggle-link", data: { "toggle-selector" => "#new-group-form" } %> + <% end %> + + <%= form_for [:admin, @budget, Budget::Group.new], html: {id: "new-group-form", style: "display:none"}, remote: true do |f| %> +
    + + + + <%= f.text_field :name, + label: false, + maxlength: 50, + placeholder: t("admin.budgets.form.group") %> +
    + <%= f.submit t("admin.budgets.form.create_group"), class: "button success" %> +
    +
    + <% end %> + + <% groups.each do |group| %> +
    + <%= render "admin/budgets/group", group: group, headings: group.headings %> +
    + <% end %> +
    \ No newline at end of file diff --git a/app/views/admin/budgets/new.html.erb b/app/views/admin/budgets/new.html.erb index 019ca460f..9ca0f34a5 100644 --- a/app/views/admin/budgets/new.html.erb +++ b/app/views/admin/budgets/new.html.erb @@ -23,7 +23,7 @@ <%= f.select :currency_symbol, budget_currency_symbol_select_options, {label: false} %> - " class="button success"> + <%= f.submit t("admin.budgets.new.create"), class: "button success" %> <% end %> \ No newline at end of file diff --git a/app/views/admin/budgets/show.html.erb b/app/views/admin/budgets/show.html.erb index 20185b2ba..847aa2f60 100644 --- a/app/views/admin/budgets/show.html.erb +++ b/app/views/admin/budgets/show.html.erb @@ -9,4 +9,8 @@ <%= t('admin.budgets.show.currency') %>: <%= @budget.currency_symbol %>

    + + +
    + <%= render "groups", groups: @budget.groups %>
    \ No newline at end of file diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 812e1a45c..d8154efc1 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -74,7 +74,13 @@ en: description: Description phase: Phase currency: Currency + show: + phase: Current phase + currency: Currency + groups: Groups of budget headings + form: group: Group's name + no_groups: No groups created yet. Each user will be able to vote in only one heading per group. add_group: Add new group create_group: Create group heading: Heading's name @@ -87,9 +93,6 @@ en: table_heading: Heading table_amount: Amount table_geozone: Scope of operation - show: - phase: Current phase - currency: Currency comments: index: filter: Filter diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 1afc01ef2..1d4ead16b 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -74,7 +74,13 @@ es: description: Descripción phase: Fase currency: Divisa + show: + phase: Fase actual + currency: Divisa + groups: Grupos de partidas presupuestarias + form: group: Nombre del grupo + no_groups: No hay grupos creados todavía. Cada usuario podrá votar en una sola partida de cada grupo. add_group: Añadir nuevo grupo create_group: Crear grupo heading: Nombre de la partida @@ -87,9 +93,6 @@ es: table_heading: Partida table_amount: Cantidad table_geozone: Ámbito de actuación - show: - phase: Fase actual - currency: Divisa comments: index: filter: Filtro diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb index f38d2c9f5..123ca43e8 100644 --- a/spec/features/admin/budgets_spec.rb +++ b/spec/features/admin/budgets_spec.rb @@ -101,4 +101,58 @@ feature 'Admin budgets' do end end + + context 'Manage groups and headings' do + + scenario 'Create group', :js do + create(:budget, name: 'Yearly participatory budget') + + visit admin_budgets_path + click_link 'Yearly participatory budget' + + expect(page).to have_content 'No groups created yet.' + + click_link 'Add new group' + + fill_in 'budget_group_name', with: 'General improvments' + click_button 'Create group' + + expect(page).to have_content 'Yearly participatory budget' + expect(page).to_not have_content 'No groups created yet.' + + visit admin_budgets_path + click_link 'Yearly participatory budget' + + expect(page).to have_content 'Yearly participatory budget' + expect(page).to_not have_content 'No groups created yet.' + end + + scenario 'Create heading', :js do + budget = create(:budget, name: 'Yearly participatory budget') + group = create(:budget_group, budget: budget, name: 'Districts improvments') + + visit admin_budget_path(budget) + + within("#budget_group_#{group.id}") do + expect(page).to have_content 'This group has no assigned heading.' + click_link 'Add heading' + + fill_in 'budget_heading_name', with: 'District 9 reconstruction' + fill_in 'budget_heading_price', with: '6785' + click_button 'Save heading' + end + + expect(page).to_not have_content 'This group has no assigned heading.' + + visit admin_budget_path(budget) + within("#budget_group_#{group.id}") do + expect(page).to_not have_content 'This group has no assigned heading.' + + expect(page).to have_content 'District 9 reconstruction' + expect(page).to have_content '6785' + expect(page).to have_content 'All city' + end + end + + end end \ No newline at end of file From f24886560b2f6636fc5cd958ecbb04a6e2909aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Thu, 1 Sep 2016 12:46:43 +0200 Subject: [PATCH 15/15] removes unused i18n entry --- config/locales/admin.en.yml | 1 - config/locales/admin.es.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index d8154efc1..78a3a6d6c 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -89,7 +89,6 @@ en: save_heading: Save heading no_heading: This group has no assigned heading. geozone: Scope of operation - no_geozone: Does not apply table_heading: Heading table_amount: Amount table_geozone: Scope of operation diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 1d4ead16b..496a0208d 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -89,7 +89,6 @@ es: save_heading: Guardar partida no_heading: Este grupo no tiene ninguna partida asignada. geozone: Ámbito de actuación - no_geozone: No aplica table_heading: Partida table_amount: Cantidad table_geozone: Ámbito de actuación