Merge pull request #2705 from consul/budget_statuses

Budget statuses
This commit is contained in:
Alberto
2018-06-27 18:18:13 +02:00
committed by GitHub
20 changed files with 342 additions and 3 deletions

View File

@@ -0,0 +1,51 @@
class Admin::BudgetInvestmentStatusesController < Admin::BaseController
before_action :load_status, only: [:edit, :update, :destroy]
def index
@statuses = Budget::Investment::Status.all
end
def new
@status = Budget::Investment::Status.new
end
def create
@status = Budget::Investment::Status.new(status_params)
if @status.save
redirect_to admin_budget_investment_statuses_path,
notice: t('admin.statuses.create.notice')
else
render :new
end
end
def edit
end
def update
if @status.update(status_params)
redirect_to admin_budget_investment_statuses_path,
notice: t('admin.statuses.update.notice')
else
render :edit
end
end
def destroy
@status.destroy
redirect_to admin_budget_investment_statuses_path,
notice: t('admin.statuses.delete.notice')
end
private
def load_status
@status = Budget::Investment::Status.find(params[:id])
end
def status_params
params.require(:budget_investment_status).permit([:name, :description])
end
end

View File

@@ -0,0 +1,7 @@
class Budget::Investment::Status < ActiveRecord::Base
acts_as_paranoid column: :hidden_at
has_many :milestones
validates :name, presence: true
end

View File

@@ -49,7 +49,8 @@
<% end %> <% end %>
<% if feature?(:budgets) %> <% if feature?(:budgets) %>
<li class="section-title <%= "is-active" if controller_name == "budgets" %>"> <li class="section-title <%= "is-active" if controller_name == "budgets" ||
"budget_investment_statuses" %>">
<%= link_to admin_budgets_path do %> <%= link_to admin_budgets_path do %>
<span class="icon-budget"></span> <span class="icon-budget"></span>
<strong><%= t("admin.menu.budgets") %></strong> <strong><%= t("admin.menu.budgets") %></strong>

View File

@@ -0,0 +1,10 @@
<%= form_for [:admin, @status] do |f| %>
<%= render 'shared/errors', resource: @status %>
<%= f.text_field :name %>
<%= f.text_area :description %>
<div class="margin-top">
<%= f.submit class: "button success" %>
</div>
<% end %>

View File

@@ -0,0 +1,5 @@
<%= back_link_to admin_budget_investment_statuses_path %>
<h2><%= t("admin.statuses.edit.title") %></h2>
<%= render '/admin/budget_investment_statuses/form' %>

View File

@@ -0,0 +1,41 @@
<h2 class="inline-block"><%= t("admin.statuses.index.title") %></h2>
<%= link_to t("admin.statuses.index.new_status"),
new_admin_budget_investment_status_path,
class: "button float-right margin-right" %>
<% if @statuses.any? %>
<table>
<thead>
<tr>
<th><%= t("admin.statuses.index.table_name") %></th>
<th><%= t("admin.statuses.index.table_description") %></th>
<th><%= t("admin.statuses.index.table_actions") %></th>
</tr>
</thead>
<tbody>
<% @statuses.each do |status| %>
<tr id="<%= dom_id(status) %>" class="budget_investment_status">
<td>
<%= status.name %>
</td>
<td>
<%= status.description %>
</td>
<td>
<%= link_to t("admin.statuses.index.edit"),
edit_admin_budget_investment_status_path(status),
method: :get, class: "button hollow" %>
<%= link_to t("admin.statuses.index.delete"),
admin_budget_investment_status_path(status),
method: :delete, class: "button hollow alert" %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<div data-alert class="callout primary margin-top clear">
<%= t("admin.statuses.index.empty_statuses") %>
</div>
<% end %>

View File

@@ -0,0 +1,5 @@
<%= back_link_to admin_budget_investment_statuses_path %>
<h2><%= t("admin.statuses.new.title") %></h2>
<%= render '/admin/budget_investment_statuses/form' %>

View File

@@ -13,6 +13,9 @@ en:
budget/investment/milestone: budget/investment/milestone:
one: "milestone" one: "milestone"
other: "milestones" other: "milestones"
budget/investment/status:
one: "Investment status"
other: "Investment statuses"
comment: comment:
one: "Comment" one: "Comment"
other: "Comments" other: "Comments"
@@ -126,6 +129,9 @@ en:
title: "Title" title: "Title"
description: "Description" description: "Description"
publication_date: "Publication date" publication_date: "Publication date"
budget/investment/status:
name: "Name"
description: "Description (optional)"
budget/heading: budget/heading:
name: "Heading name" name: "Heading name"
price: "Price" price: "Price"

View File

@@ -272,6 +272,26 @@ en:
notice: Milestone updated successfully notice: Milestone updated successfully
delete: delete:
notice: Milestone successfully deleted notice: Milestone successfully deleted
statuses:
index:
title: Investment statuses
empty_statuses: There are no investment statuses created
new_status: Create new investment status
table_name: Name
table_description: Description
table_actions: Actions
delete: Delete
edit: Edit
edit:
title: Edit investment status
update:
notice: Investment status updated successfully
new:
title: Create investment status
create:
notice: Investment status created successfully
delete:
notice: Investment status deleted successfully
comments: comments:
index: index:
filter: Filter filter: Filter

View File

@@ -36,10 +36,20 @@ en:
groups: groups:
all_city: All City all_city: All City
districts: Districts districts: Districts
valuator_groups:
culture_and_sports: Culture & Sports
gender_and_diversity: Gender & Diversity Policies
urban_development: Sustainable Urban Development
equity_and_employment: Equity & Employment
statuses:
studying_project: Studying the project
bidding: Bidding
executing_project: Executing the project
executed: Executed
polls: polls:
current_poll: "Current Poll" current_poll: "Current Poll"
current_poll_geozone_restricted: "Current Poll Geozone Restricted" current_poll_geozone_restricted: "Current Poll Geozone Restricted"
incoming_poll: "Incoming Poll" incoming_poll: "Incoming Poll"
recounting_poll: "Recounting Poll" recounting_poll: "Recounting Poll"
expired_poll_without_stats: "Expired Poll without Stats & Results" expired_poll_without_stats: "Expired Poll without Stats & Results"
expired_poll_with_stats: "Expired Poll with Stats & Results" expired_poll_with_stats: "Expired Poll with Stats & Results"

View File

@@ -13,6 +13,9 @@ es:
budget/investment/milestone: budget/investment/milestone:
one: "hito" one: "hito"
other: "hitos" other: "hitos"
budget/investment/status:
one: "Estado de proyecto"
other: "Estados de proyecto"
comment: comment:
one: "Comentario" one: "Comentario"
other: "Comentarios" other: "Comentarios"
@@ -126,6 +129,9 @@ es:
title: "Título" title: "Título"
description: "Descripción" description: "Descripción"
publication_date: "Fecha de publicación" publication_date: "Fecha de publicación"
budget/investment/status:
name: "Nombre"
description: "Descripción (opcional)"
budget/heading: budget/heading:
name: "Nombre de la partida" name: "Nombre de la partida"
price: "Cantidad" price: "Cantidad"

View File

@@ -272,6 +272,26 @@ es:
notice: Hito actualizado notice: Hito actualizado
delete: delete:
notice: Hito borrado correctamente notice: Hito borrado correctamente
statuses:
index:
title: Estados de proyectos
empty_statuses: Aún no se ha creado ningún estado de proyecto
new_status: Crear nuevo estado de proyecto
table_name: Nombre
table_description: Descripción
table_actions: Acciones
delete: Borrar
edit: Editar
edit:
title: Editar estado de proyecto
update:
notice: Estado de proyecto editado correctamente
new:
title: Crear estado de proyecto
create:
notice: Estado de proyecto creado correctamente
delete:
notice: Estado de proyecto eliminado correctamente
comments: comments:
index: index:
filter: Filtro filter: Filtro

View File

@@ -36,10 +36,20 @@ es:
groups: groups:
all_city: Toda la Ciudad all_city: Toda la Ciudad
districts: Distritos districts: Distritos
valuator_groups:
culture_and_sports: Cultura y Deportes
gender_and_diversity: Políticas de Género y Diversidad
urban_development: Desarrollo Urbano Sostenible
equity_and_employment: Equidad y Empleo
statuses:
studying_project: Estudiando el proyecto
bidding: Licitación
executing_project: Ejecutando el proyecto
executed: Ejecutado
polls: polls:
current_poll: "Votación Abierta" current_poll: "Votación Abierta"
current_poll_geozone_restricted: "Votación Abierta restringida por geozona" current_poll_geozone_restricted: "Votación Abierta restringida por geozona"
incoming_poll: "Siguiente Votación" incoming_poll: "Siguiente Votación"
recounting_poll: "Votación en Recuento" recounting_poll: "Votación en Recuento"
expired_poll_without_stats: "Votación Finalizada (sin Estadísticas o Resultados)" expired_poll_without_stats: "Votación Finalizada (sin Estadísticas o Resultados)"
expired_poll_with_stats: "Votación Finalizada (con Estadísticas y Resultado)" expired_poll_with_stats: "Votación Finalizada (con Estadísticas y Resultado)"

View File

@@ -55,6 +55,8 @@ namespace :admin do
resources :budget_phases, only: [:edit, :update] resources :budget_phases, only: [:edit, :update]
end end
resources :budget_investment_statuses, only: [:index, :new, :create, :update, :edit, :destroy]
resources :signature_sheets, only: [:index, :new, :create, :show] resources :signature_sheets, only: [:index, :new, :create, :show]
resources :banners, only: [:index, :new, :create, :edit, :update, :destroy] do resources :banners, only: [:index, :new, :create, :edit, :update, :destroy] do

View File

@@ -123,3 +123,10 @@ section "Creating investment milestones" do
end end
end end
end end
section "Creating default Investment Milestone Statuses" do
Budget::Investment::Status.create(name: I18n.t('seeds.budgets.statuses.studying_project'))
Budget::Investment::Status.create(name: I18n.t('seeds.budgets.statuses.bidding'))
Budget::Investment::Status.create(name: I18n.t('seeds.budgets.statuses.executing_project'))
Budget::Investment::Status.create(name: I18n.t('seeds.budgets.statuses.executed'))
end

View File

@@ -0,0 +1,11 @@
class CreateBudgetInvestmentStatuses < ActiveRecord::Migration
def change
create_table :budget_investment_statuses do |t|
t.string :name
t.text :description
t.datetime :hidden_at, index: true
t.timestamps null: false
end
end
end

View File

@@ -139,6 +139,16 @@ ActiveRecord::Schema.define(version: 20180519132610) do
t.datetime "publication_date" t.datetime "publication_date"
end end
create_table "budget_investment_statuses", force: :cascade do |t|
t.string "name"
t.text "description"
t.datetime "hidden_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "budget_investment_statuses", ["hidden_at"], name: "index_budget_investment_statuses_on_hidden_at", using: :btree
create_table "budget_investments", force: :cascade do |t| create_table "budget_investments", force: :cascade do |t|
t.integer "author_id" t.integer "author_id"
t.integer "administrator_id" t.integer "administrator_id"

View File

@@ -404,6 +404,11 @@ FactoryBot.define do
reason "unfeasible" reason "unfeasible"
end end
factory :budget_investment_status, class: 'Budget::Investment::Status' do
sequence(:name) { |n| "Budget investment status #{n} name" }
sequence(:description) { |n| "Budget investment status #{n} description" }
end
factory :budget_investment_milestone, class: 'Budget::Investment::Milestone' do factory :budget_investment_milestone, class: 'Budget::Investment::Milestone' do
association :investment, factory: :budget_investment association :investment, factory: :budget_investment
sequence(:title) { |n| "Budget investment milestone #{n} title" } sequence(:title) { |n| "Budget investment milestone #{n} title" }

View File

@@ -0,0 +1,95 @@
require 'rails_helper'
feature 'Admin budget investment statuses' do
background do
admin = create(:administrator)
login_as(admin.user)
end
context "Index" do
scenario 'Displaying only not hidden statuses' do
status1 = create(:budget_investment_status)
status2 = create(:budget_investment_status)
status1.destroy
visit admin_budget_investment_statuses_path
expect(page).not_to have_content status1.name
expect(page).not_to have_content status1.description
expect(page).to have_content status2.name
expect(page).to have_content status2.description
end
scenario 'Displaying no statuses text' do
visit admin_budget_investment_statuses_path
expect(page).to have_content("There are no investment statuses created")
end
end
context "New" do
scenario "Create status" do
visit admin_budget_investment_statuses_path
click_link 'Create new investment status'
fill_in 'budget_investment_status_name', with: 'New status name'
fill_in 'budget_investment_status_description', with: 'This status description'
click_button 'Create Investment status'
expect(page).to have_content 'New status name'
expect(page).to have_content 'This status description'
end
scenario "Show validation errors in status form" do
visit admin_budget_investment_statuses_path
click_link 'Create new investment status'
fill_in 'budget_investment_status_description', with: 'This status description'
click_button 'Create Investment status'
within "#new_budget_investment_status" do
expect(page).to have_content "can't be blank", count: 1
end
end
end
context "Edit" do
scenario "Change name and description" do
status = create(:budget_investment_status)
visit admin_budget_investment_statuses_path
within("#budget_investment_status_#{status.id}") do
click_link "Edit"
end
fill_in 'budget_investment_status_name', with: 'Other status name'
fill_in 'budget_investment_status_description', with: 'Other status description'
click_button 'Update Investment status'
expect(page).to have_content 'Other status name'
expect(page).to have_content 'Other status description'
end
end
context "Delete" do
scenario "Hides status" do
status = create(:budget_investment_status)
visit admin_budget_investment_statuses_path
within("#budget_investment_status_#{status.id}") do
click_link "Delete"
end
expect(page).not_to have_content status.name
expect(page).not_to have_content status.description
end
end
end

View File

@@ -0,0 +1,17 @@
require 'rails_helper'
describe Budget::Investment::Status do
describe "Validations" do
let(:status) { build(:budget_investment_status) }
it "is valid" do
expect(status).to be_valid
end
it "is not valid without a name" do
status.name = nil
expect(status).not_to be_valid
end
end
end