Merge pull request #2706 from consul/milestone_status
Investment milestone's project status
This commit is contained in:
@@ -627,6 +627,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
.milestone-status {
|
||||
background: $budget;
|
||||
border-radius: rem-calc(4);
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
margin-top: $line-height / 6;
|
||||
padding: $line-height / 4 $line-height / 2;
|
||||
}
|
||||
|
||||
.show-actions-menu {
|
||||
|
||||
[class^="icon-"] {
|
||||
|
||||
@@ -3,6 +3,7 @@ class Admin::BudgetInvestmentMilestonesController < Admin::BaseController
|
||||
|
||||
before_action :load_budget_investment, only: [:index, :new, :create, :edit, :update, :destroy]
|
||||
before_action :load_budget_investment_milestone, only: [:edit, :update, :destroy]
|
||||
before_action :load_statuses, only: [:index, :new, :create, :edit, :update]
|
||||
|
||||
def index
|
||||
end
|
||||
@@ -45,7 +46,7 @@ class Admin::BudgetInvestmentMilestonesController < Admin::BaseController
|
||||
def milestone_params
|
||||
image_attributes = [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy]
|
||||
documents_attributes = [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy]
|
||||
attributes = [:title, :description, :publication_date, :budget_investment_id,
|
||||
attributes = [:title, :description, :publication_date, :budget_investment_id, :status_id,
|
||||
image_attributes: image_attributes, documents_attributes: documents_attributes]
|
||||
|
||||
params.require(:budget_investment_milestone).permit(*attributes, translation_params(params[:budget_investment_milestone]))
|
||||
@@ -71,4 +72,8 @@ class Admin::BudgetInvestmentMilestonesController < Admin::BaseController
|
||||
get_milestone
|
||||
end
|
||||
|
||||
def load_statuses
|
||||
@statuses = Budget::Investment::Status.all
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -11,11 +11,12 @@ class Budget
|
||||
globalize_accessors locales: [:en, :es, :fr, :nl, :val, :pt_br]
|
||||
|
||||
belongs_to :investment
|
||||
belongs_to :status, class_name: 'Budget::Investment::Status'
|
||||
|
||||
validates :title, presence: true
|
||||
validates :description, presence: true
|
||||
validates :investment, presence: true
|
||||
validates :publication_date, presence: true
|
||||
validate :description_or_status_present?
|
||||
|
||||
scope :order_by_publication_date, -> { order(publication_date: :asc) }
|
||||
|
||||
@@ -23,6 +24,11 @@ class Budget
|
||||
80
|
||||
end
|
||||
|
||||
def description_or_status_present?
|
||||
unless description.present? || status_id.present?
|
||||
errors.add(:description)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,6 +5,15 @@
|
||||
<%= f.hidden_field :title, value: l(Time.current, format: :datetime),
|
||||
maxlength: Budget::Investment::Milestone.title_max_length %>
|
||||
|
||||
<div class="small-12 medium-6 margin-bottom">
|
||||
<%= f.select :status_id,
|
||||
@statuses.collect { |s| [s.name, s.id] },
|
||||
{ include_blank: @statuses.any? ? '' : t('admin.milestones.form.no_statuses_defined') },
|
||||
{ disabled: @statuses.blank? } %>
|
||||
<%= link_to t('admin.milestones.form.admin_statuses'),
|
||||
admin_budget_investment_statuses_path %>
|
||||
</div>
|
||||
|
||||
<%= f.label :description, t("admin.milestones.new.description") %>
|
||||
<% @milestone.globalize_locales.each do |locale| %>
|
||||
<%= hidden_field_tag "delete_translations[#{locale}]", 0 %>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<th><%= t("admin.milestones.index.table_title") %></th>
|
||||
<th><%= t("admin.milestones.index.table_description") %></th>
|
||||
<th><%= t("admin.milestones.index.table_publication_date") %></th>
|
||||
<th><%= t("admin.milestones.index.table_status") %></th>
|
||||
<th><%= t("admin.milestones.index.image") %></th>
|
||||
<th><%= t("admin.milestones.index.documents") %></th>
|
||||
<th><%= t("admin.milestones.index.table_actions") %></th>
|
||||
@@ -25,6 +26,9 @@
|
||||
<td class="small">
|
||||
<%= l(milestone.publication_date.to_date) if milestone.publication_date.present? %>
|
||||
</td>
|
||||
<td class="small">
|
||||
<%= milestone.status.present? ? milestone.status.name : '' %>
|
||||
</td>
|
||||
<td class="small">
|
||||
<%= link_to t("admin.milestones.index.show_image"),
|
||||
milestone.image_url(:large),
|
||||
|
||||
@@ -10,6 +10,18 @@
|
||||
</span>
|
||||
<% end %>
|
||||
|
||||
<% if milestone.status.present? %>
|
||||
<p>
|
||||
<strong>
|
||||
<%= t("budgets.investments.show.milestone_status_changed") %>
|
||||
</strong>
|
||||
<br>
|
||||
<span class="milestone-status">
|
||||
<%= milestone.status.name %>
|
||||
</span>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<%= image_tag(milestone.image_url(:large), { id: "image_#{milestone.id}", alt: milestone.image.title, class: "margin" }) if milestone.image.present? %>
|
||||
|
||||
<% globalize(neutral_locale(locale)) do %>
|
||||
|
||||
@@ -126,8 +126,9 @@ en:
|
||||
image: "Proposal descriptive image"
|
||||
image_title: "Image title"
|
||||
budget/investment/milestone:
|
||||
status_id: "Current investment status (optional)"
|
||||
title: "Title"
|
||||
description: "Description"
|
||||
description: "Description (optional if there's an status assigned)"
|
||||
publication_date: "Publication date"
|
||||
budget/investment/status:
|
||||
name: "Name"
|
||||
|
||||
@@ -251,6 +251,7 @@ en:
|
||||
table_title: "Title"
|
||||
table_description: "Description"
|
||||
table_publication_date: "Publication date"
|
||||
table_status: Status
|
||||
table_actions: "Actions"
|
||||
delete: "Delete milestone"
|
||||
no_milestones: "Don't have defined milestones"
|
||||
@@ -260,6 +261,8 @@ en:
|
||||
form:
|
||||
add_language: Add language
|
||||
remove_language: Remove language
|
||||
admin_statuses: Admin investment statuses
|
||||
no_statuses_defined: There are no defined investment statuses yet
|
||||
new:
|
||||
creating: Create milestone
|
||||
date: Date
|
||||
|
||||
@@ -124,6 +124,7 @@ en:
|
||||
milestones_tab: Milestones
|
||||
no_milestones: Don't have defined milestones
|
||||
milestone_publication_date: "Published %{publication_date}"
|
||||
milestone_status_changed: Investment status changed to
|
||||
author: Author
|
||||
project_unfeasible_html: 'This investment project <strong>has been marked as not feasible</strong> and will not go to balloting phase.'
|
||||
project_not_selected_html: 'This investment project <strong>has not been selected</strong> for balloting phase.'
|
||||
|
||||
@@ -126,8 +126,9 @@ es:
|
||||
image: "Imagen descriptiva del proyecto de gasto"
|
||||
image_title: "Título de la imagen"
|
||||
budget/investment/milestone:
|
||||
status_id: "Estado actual del proyecto (opcional)"
|
||||
title: "Título"
|
||||
description: "Descripción"
|
||||
description: "Descripción (opcional si se ha asignado un estado de proyecto)"
|
||||
publication_date: "Fecha de publicación"
|
||||
budget/investment/status:
|
||||
name: "Nombre"
|
||||
|
||||
@@ -251,6 +251,7 @@ es:
|
||||
table_title: "Título"
|
||||
table_description: "Descripción"
|
||||
table_publication_date: "Fecha de publicación"
|
||||
table_status: Estado
|
||||
table_actions: "Acciones"
|
||||
delete: "Eliminar hito"
|
||||
no_milestones: "No hay hitos definidos"
|
||||
@@ -260,6 +261,8 @@ es:
|
||||
form:
|
||||
add_language: Añadir idioma
|
||||
remove_language: Eliminar idioma
|
||||
admin_statuses: Gestionar estados de proyectos
|
||||
no_statuses_defined: No hay estados definidos
|
||||
new:
|
||||
creating: Crear hito
|
||||
date: Fecha
|
||||
|
||||
@@ -124,6 +124,7 @@ es:
|
||||
milestones_tab: Seguimiento
|
||||
no_milestones: No hay hitos definidos
|
||||
milestone_publication_date: "Publicado el %{publication_date}"
|
||||
milestone_status_changed: El proyecto ha cambiado al estado
|
||||
author: Autor
|
||||
project_unfeasible_html: 'Este proyecto de inversión <strong>ha sido marcado como inviable</strong> y no pasará a la fase de votación.'
|
||||
project_not_selected_html: 'Este proyecto de inversión <strong>no ha sido seleccionado</strong> para la fase de votación.'
|
||||
|
||||
8
db/migrate/20180321180149_add_status_to_milestones.rb
Normal file
8
db/migrate/20180321180149_add_status_to_milestones.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
class AddStatusToMilestones < ActiveRecord::Migration
|
||||
disable_ddl_transaction!
|
||||
|
||||
def change
|
||||
add_column :budget_investment_milestones, :status_id, :integer
|
||||
add_index :budget_investment_milestones, :status_id, algorithm: :concurrently
|
||||
end
|
||||
end
|
||||
@@ -137,8 +137,11 @@ ActiveRecord::Schema.define(version: 20180519132610) do
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.datetime "publication_date"
|
||||
t.integer "status_id"
|
||||
end
|
||||
|
||||
add_index "budget_investment_milestones", ["status_id"], name: "index_budget_investment_milestones_on_status_id", using: :btree
|
||||
|
||||
create_table "budget_investment_statuses", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.text "description"
|
||||
|
||||
@@ -411,6 +411,7 @@ FactoryBot.define do
|
||||
|
||||
factory :budget_investment_milestone, class: 'Budget::Investment::Milestone' do
|
||||
association :investment, factory: :budget_investment
|
||||
association :status, factory: :budget_investment_status
|
||||
sequence(:title) { |n| "Budget investment milestone #{n} title" }
|
||||
description 'Milestone description'
|
||||
publication_date Date.current
|
||||
|
||||
@@ -21,6 +21,7 @@ feature 'Admin budget investment milestones' do
|
||||
expect(page).to have_content(milestone.title)
|
||||
expect(page).to have_content(milestone.id)
|
||||
expect(page).to have_content(milestone.publication_date.to_date)
|
||||
expect(page).to have_content(milestone.status.name)
|
||||
expect(page).to have_link 'Show image'
|
||||
expect(page).to have_link document.title
|
||||
end
|
||||
@@ -35,10 +36,12 @@ feature 'Admin budget investment milestones' do
|
||||
|
||||
context "New" do
|
||||
scenario "Add milestone" do
|
||||
status = create(:budget_investment_status)
|
||||
visit admin_budget_budget_investment_path(@investment.budget, @investment)
|
||||
|
||||
click_link 'Create new milestone'
|
||||
|
||||
select status.name, from: 'budget_investment_milestone_status_id'
|
||||
fill_in 'budget_investment_milestone_description_en', with: 'New description milestone'
|
||||
fill_in 'budget_investment_milestone_publication_date', with: Date.current
|
||||
|
||||
@@ -46,6 +49,14 @@ feature 'Admin budget investment milestones' do
|
||||
|
||||
expect(page).to have_content 'New description milestone'
|
||||
expect(page).to have_content Date.current
|
||||
expect(page).to have_content status.name
|
||||
end
|
||||
|
||||
scenario "Status select is disabled if there are no statuses available" do
|
||||
visit admin_budget_budget_investment_path(@investment.budget, @investment)
|
||||
|
||||
click_link 'Create new milestone'
|
||||
expect(find("#budget_investment_milestone_status_id").disabled?).to be true
|
||||
end
|
||||
|
||||
scenario "Show validation errors on milestone form" do
|
||||
|
||||
@@ -1017,6 +1017,7 @@ feature 'Budget Investments' do
|
||||
expect(page.find("#image_#{first_milestone.id}")['alt']).to have_content(image.title)
|
||||
expect(page).to have_link(document.title)
|
||||
expect(page).to have_link("https://consul.dev")
|
||||
expect(page).to have_content(first_milestone.status.name)
|
||||
end
|
||||
|
||||
select('Español', from: 'locale-switcher')
|
||||
|
||||
@@ -14,15 +14,59 @@ describe Budget::Investment::Milestone do
|
||||
expect(milestone).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid without a description" do
|
||||
it "is not valid without a description if status is empty" do
|
||||
milestone.status = nil
|
||||
milestone.description = nil
|
||||
expect(milestone).not_to be_valid
|
||||
end
|
||||
|
||||
it "is valid without a description if status is present" do
|
||||
milestone.description = nil
|
||||
expect(milestone).to be_valid
|
||||
end
|
||||
|
||||
it "is not valid without an investment" do
|
||||
milestone.investment_id = nil
|
||||
expect(milestone).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid if description and status are not present" do
|
||||
milestone.description = nil
|
||||
milestone.status_id = nil
|
||||
expect(milestone).not_to be_valid
|
||||
end
|
||||
|
||||
it "is valid without status if description is present" do
|
||||
milestone.status_id = nil
|
||||
expect(milestone).to be_valid
|
||||
end
|
||||
|
||||
it "is valid without description if status is present" do
|
||||
milestone.description = nil
|
||||
expect(milestone).to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe "#description_or_status_present?" do
|
||||
let(:milestone) { build(:budget_investment_milestone) }
|
||||
|
||||
it "is not valid when status is removed and there's no description" do
|
||||
milestone.update(description: nil)
|
||||
expect(milestone.update(status_id: nil)).to be false
|
||||
end
|
||||
|
||||
it "is not valid when description is removed and there's no status" do
|
||||
milestone.update(status_id: nil)
|
||||
expect(milestone.update(description: nil)).to be false
|
||||
end
|
||||
|
||||
it "is valid when description is removed and there is a status" do
|
||||
expect(milestone.update(description: nil)).to be true
|
||||
end
|
||||
|
||||
it "is valid when status is removed and there is a description" do
|
||||
expect(milestone.update(status_id: nil)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user