diff --git a/app/controllers/budgets/ballot/lines_controller.rb b/app/controllers/budgets/ballot/lines_controller.rb new file mode 100644 index 000000000..5483f40a3 --- /dev/null +++ b/app/controllers/budgets/ballot/lines_controller.rb @@ -0,0 +1,77 @@ +module Budgets + module Ballot + class LinesController < ApplicationController + before_action :authenticate_user! + #before_action :ensure_final_voting_allowed + before_action :load_budget + before_action :load_ballot + + before_action :load_investments + + load_and_authorize_resource :budget + load_and_authorize_resource :ballot, class: "Budget::Ballot" + load_and_authorize_resource :line, through: :ballot, find_by: :investment_id, class: "Budget::Ballot::Line" + + def create + load_investment + load_heading + + if @ballot.add_investment(@investment) + #@ballot.set_geozone(@geozone) + #@current_user.update(representative_id: nil) + if request.get? + redirect_to @spending_proposal, notice: t('spending_proposals.notice.voted') + end + else + if request.get? + redirect_to @spending_proposal, notice: t('spending_proposals.notice.could_not_vote') + else + render :new + end + end + end + + def destroy + @investment = @line.investment + load_heading + + @line.destroy + load_investments + #@ballot.reset_geozone + end + + private + + def ensure_final_voting_allowed + return head(:forbidden) unless @budget.balloting? + end + + def line_params + params.permit(:investment_id) + end + + def load_budget + @budget = Budget.find(params[:budget_id]) + end + + def load_ballot + @ballot = Budget::Ballot.where(user: current_user, budget: @budget).first_or_create + end + + def load_investment + @investment = Budget::Investment.find(params[:investment_id]) + end + + def load_investments + if params[:investments_ids].present? + @investments = Budget::Investment.where(id: params[:investments_ids]) + end + end + + def load_heading + @heading = @investment.heading + end + + end + end +end \ No newline at end of file diff --git a/app/controllers/budgets/ballots_controller.rb b/app/controllers/budgets/ballots_controller.rb new file mode 100644 index 000000000..3c163253d --- /dev/null +++ b/app/controllers/budgets/ballots_controller.rb @@ -0,0 +1,18 @@ +module Budgets + class BallotsController < ApplicationController + before_action :authenticate_user! + load_and_authorize_resource :budget + before_action :load_ballot + + def show + render template: "budgets/ballot/show" + end + + private + + def load_ballot + @ballot = Budget::Ballot.where(user: current_user, budget: @budget).first_or_create + end + + end +end \ No newline at end of file diff --git a/app/controllers/budgets/groups_controller.rb b/app/controllers/budgets/groups_controller.rb new file mode 100644 index 000000000..e55974a6a --- /dev/null +++ b/app/controllers/budgets/groups_controller.rb @@ -0,0 +1,10 @@ +module Budgets + class GroupsController < ApplicationController + load_and_authorize_resource :budget + load_and_authorize_resource :group, class: "Budget::Group" + + def show + end + + end +end \ No newline at end of file diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index 44e6efd73..fafea9734 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -99,7 +99,7 @@ module Budgets end def load_heading - @heading = @budget.headings.find(params[:heading_id]) if params[:geozone_id].present? + @heading = @budget.headings.find(params[:heading_id]) if params[:heading_id].present? end end diff --git a/app/helpers/ballots_helper.rb b/app/helpers/ballots_helper.rb new file mode 100644 index 000000000..ece1be9fa --- /dev/null +++ b/app/helpers/ballots_helper.rb @@ -0,0 +1,7 @@ +module BallotsHelper + + def progress_bar_width(amount_available, amount_spent) + (amount_spent/amount_available.to_f * 100).to_s + "%" + end + +end \ No newline at end of file diff --git a/app/helpers/budget_helper.rb b/app/helpers/budget_helper.rb index 8c19516e8..af239f074 100644 --- a/app/helpers/budget_helper.rb +++ b/app/helpers/budget_helper.rb @@ -20,4 +20,17 @@ module BudgetHelper budget_investment_path(investment, options) end end + + def display_budget_countdown?(budget) + budget.balloting? + end + + def css_for_ballot_heading(heading) + return '' unless current_ballot.present? + current_ballot.has_lines_in_heading?(heading) ? 'active' : '' + end + + def current_ballot + Budget::Ballot.where(user: current_user, budget: @budget).first + end end diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb index fb03cbea2..fddf4918b 100644 --- a/app/models/abilities/common.rb +++ b/app/models/abilities/common.rb @@ -45,9 +45,10 @@ module Abilities can :vote, SpendingProposal can :create, SpendingProposal - can :create, Budget::Investment, budget: { phase: "accepting" } - can :vote, Budget::Investment, budget: { phase: "selecting" } - can :create, Budget::Ballot, budget: { phase: "balloting" } + can :create, Budget::Investment, budget: { phase: "accepting" } + can :vote, Budget::Investment, budget: { phase: "selecting" } + can [:show, :create], Budget::Ballot, budget: { phase: "balloting" } + can [:create, :destroy], Budget::Ballot::Line#, budget: { phase: "balloting" } can :create, DirectMessage can :show, DirectMessage, sender_id: user.id diff --git a/app/models/abilities/everyone.rb b/app/models/abilities/everyone.rb index 561ac5994..cf8af477b 100644 --- a/app/models/abilities/everyone.rb +++ b/app/models/abilities/everyone.rb @@ -6,13 +6,14 @@ module Abilities can [:read, :map], Debate can [:read, :map, :summary], Proposal can :read, Comment - can :read, Budget + can [:read, :welcome], Budget can :read, Budget::Investment can :read, SpendingProposal can :read, Legislation can :read, User can [:search, :read], Annotation can [:read], Budget + can [:read], Budget::Group can [:read], Budget::Investment can :new, DirectMessage end diff --git a/app/models/budget/ballot.rb b/app/models/budget/ballot.rb index 848e2f22d..fa7317dc8 100644 --- a/app/models/budget/ballot.rb +++ b/app/models/budget/ballot.rb @@ -5,6 +5,8 @@ class Budget has_many :lines, dependent: :destroy has_many :investments, through: :lines + has_many :groups, -> { uniq }, through: :lines + has_many :headings, -> { uniq }, through: :groups def add_investment(investment) lines.create!(budget: budget, investment: investment, heading: investment.heading, group_id: investment.heading.group_id) @@ -22,6 +24,10 @@ class Budget budget.heading_price(heading) - amount_spent(heading.id) end + def has_lines_in_group?(group) + self.groups.include?(group) + end + def valid_heading?(heading) group = heading.group return false if group.budget_id != budget_id @@ -40,8 +46,17 @@ class Budget self.heading_id.present? end + def has_lines_in_heading?(heading) + investments.by_heading(heading.id).any? + end + def has_investment?(investment) self.investment_ids.include?(investment.id) end + + def heading_for_group(group) + self.headings.where(group: group).first + end + end end diff --git a/app/models/budget/ballot/line.rb b/app/models/budget/ballot/line.rb index 8f0375a58..31cdcd230 100644 --- a/app/models/budget/ballot/line.rb +++ b/app/models/budget/ballot/line.rb @@ -13,15 +13,15 @@ class Budget #needed? validates :ballot_id, :budget_id, :group_id, :heading_id, :investment_id, presence: true def insufficient_funds - errors.add(:money, "") if ballot.amount_available(investment.heading) < investment.price.to_i + errors.add(:money, "insufficient funds") if ballot.amount_available(investment.heading) < investment.price.to_i end def different_geozone - errors.add(:heading, "") if (ballot.heading.present? && investment.heading != ballot.heading) + errors.add(:heading, "different heading assigned") if (ballot.heading.present? && investment.heading != ballot.heading) end def unfeasible - errors.add(:unfeasible, "") unless investment.feasible? + errors.add(:unfeasible, "unfeasible investment") unless investment.feasible? end def heading_proposal? diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 56ae67d41..619602b2a 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -45,6 +45,7 @@ class Budget scope :undecided, -> { where(feasibility: "undecided") } scope :with_supports, -> { where('cached_votes_up > 0') } + scope :by_group, -> (group_id) { where(group_id: group_id) } scope :by_heading, -> (heading_id) { where(heading_id: heading_id) } scope :by_admin, -> (admin_id) { where(administrator_id: admin_id) } scope :by_tag, -> (tag_name) { tagged_with(tag_name) } diff --git a/app/views/budgets/ballots/_add.html.erb b/app/views/budgets/ballot/_add.html.erb similarity index 100% rename from app/views/budgets/ballots/_add.html.erb rename to app/views/budgets/ballot/_add.html.erb diff --git a/app/views/budgets/ballot/_ballot.html.erb b/app/views/budgets/ballot/_ballot.html.erb new file mode 100644 index 000000000..a6529306b --- /dev/null +++ b/app/views/budgets/ballot/_ballot.html.erb @@ -0,0 +1,55 @@ +
+ + <%= t("budgets.ballots.show.voted_info_html") %> + +
+
+ <%= t("budgets.ballots.show.zero") %>
+ <%= link_to t("budgets.ballots.show.heading_link"),
+ budget_investments_path(budget, heading_id: heading.id),
+ data: { no_turbolink: true } %>
+
+ <%= format_price(@budget, @ballot.amount_spent(@heading.id)) %> + + <%= t("spending_proposals.index.available") %> + <%= format_price(@budget, @ballot.amount_available(@heading)) %> + +
+ +- <%= format_price(investment.price) %> + <%= format_price(@budget, investment.price) %>
<% if @budget.balloting? %> <%= link_to t('budgets.ballots.show.remove'), - ballot_line_path(id: investment.id, + budget_ballot_line_path(id: investment.id, investments_ids: investment_ids), class: "delete small expanded", method: :delete, diff --git a/app/views/budgets/ballot/lines/_refresh_ballots.js.erb b/app/views/budgets/ballot/lines/_refresh_ballots.js.erb new file mode 100644 index 000000000..69b5aae0b --- /dev/null +++ b/app/views/budgets/ballot/lines/_refresh_ballots.js.erb @@ -0,0 +1,5 @@ +<% if @investments.present? %> + <% @investments.each do |investment| %> + $("#<%= dom_id(investment) %>_ballot").html('<%= j render("budgets/investments/ballot", investment: investment) %>'); + <% end %> +<% end %> \ No newline at end of file diff --git a/app/views/budgets/ballot/lines/create.js.erb b/app/views/budgets/ballot/lines/create.js.erb new file mode 100644 index 000000000..5680fb063 --- /dev/null +++ b/app/views/budgets/ballot/lines/create.js.erb @@ -0,0 +1,5 @@ +$("#progress_bar").html('<%= j render("budgets/ballot/progress_bar", ballot: @ballot) %>'); +$("#sidebar").html('<%= j render("budgets/investments/sidebar") %>'); +$("#<%= dom_id(@investment) %>_ballot").html('<%= j render("budgets/investments/ballot", investment: @investment) %>'); + +<%= render 'refresh_ballots' %> diff --git a/app/views/budgets/ballot/lines/destroy.js.erb b/app/views/budgets/ballot/lines/destroy.js.erb new file mode 100644 index 000000000..aaa5ea302 --- /dev/null +++ b/app/views/budgets/ballot/lines/destroy.js.erb @@ -0,0 +1,6 @@ +$("#progress_bar").html('<%= j render("budgets/ballot/progress_bar", ballot: @ballot) %>'); +$("#sidebar").html('<%= j render("budgets/investments/sidebar") %>'); +$("#ballot").html('<%= j render("budgets/ballot/ballot") %>') +$("#<%= dom_id(@investment) %>_ballot").html('<%= j render("budgets/investments/ballot", investment: @investment) %>'); + +<%= render 'refresh_ballots' %> diff --git a/app/views/budgets/ballot/lines/new.js.erb b/app/views/budgets/ballot/lines/new.js.erb new file mode 100644 index 000000000..2e8254866 --- /dev/null +++ b/app/views/budgets/ballot/lines/new.js.erb @@ -0,0 +1,2 @@ +$("#<%= dom_id(@spending_proposal) %>_ballot").html('<%= j render("spending_proposals/ballot", spending_proposal: @spending_proposal) %>'); +$(".no-supports-allowed").show(); \ No newline at end of file diff --git a/app/views/budgets/ballot/show.html.erb b/app/views/budgets/ballot/show.html.erb new file mode 100644 index 000000000..b4aaa2d46 --- /dev/null +++ b/app/views/budgets/ballot/show.html.erb @@ -0,0 +1,3 @@ +- - <%= t("budgets.ballots.show.voted_info_html") %> - -
-
- <%= t("budgets.ballots.show.zero") %>
- <%= link_to t("budgets.ballots.show.city_link"),
- investments_path(geozone: 'all'),
- data: { no_turbolink: true } %>
-
- <%= t("budgets.ballots.show.zero") %>
- <%= link_to t("budgets.ballots.show.districts_link"), select_district_path %>
-
<%= t("budget.investments.header.different_heading_active") %> @@ -32,7 +39,7 @@
<% else %>