Permalink
Cannot retrieve contributors at this time
296 lines (244 sloc)
9.82 KB
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
module Decidim | |
module Proposals | |
# Exposes the proposal resource so users can view and create them. | |
class ProposalsController < Decidim::Proposals::ApplicationController | |
helper Decidim::WidgetUrlsHelper | |
helper ProposalWizardHelper | |
helper ParticipatoryTextsHelper | |
include Decidim::ApplicationHelper | |
include Flaggable | |
include Withdrawable | |
include FormFactory | |
include FilterResource | |
include Decidim::Proposals::Orderable | |
include Paginable | |
helper_method :proposal_presenter, :form_presenter | |
before_action :authenticate_user!, only: [:new, :create, :complete] | |
before_action :ensure_is_draft, only: [:compare, :complete, :preview, :publish, :edit_draft, :update_draft, :destroy_draft] | |
before_action :set_proposal, only: [:show, :edit, :update, :withdraw] | |
before_action :edit_form, only: [:edit_draft, :edit] | |
before_action :set_participatory_text | |
def index | |
if component_settings.participatory_texts_enabled? | |
@proposals = Decidim::Proposals::Proposal | |
.where(component: current_component) | |
.published | |
.not_hidden | |
.only_amendables | |
.includes(:category, :scope) | |
.order(position: :asc) | |
render "decidim/proposals/proposals/participatory_texts/participatory_text" | |
else | |
@proposals = search | |
.results | |
.published | |
.not_hidden | |
.includes(:amendable, :category, :component, :resource_permission, :scope) | |
@voted_proposals = if current_user | |
ProposalVote.where( | |
author: current_user, | |
proposal: @proposals.pluck(:id) | |
).pluck(:decidim_proposal_id) | |
else | |
[] | |
end | |
@proposals = paginate(@proposals) | |
@proposals = reorder(@proposals) | |
end | |
end | |
def show | |
raise ActionController::RoutingError, "Not Found" if @proposal.blank? || !can_show_proposal? | |
@report_form = form(Decidim::ReportForm).from_params(reason: "spam") | |
end | |
def new | |
enforce_permission_to :create, :proposal | |
@step = :step_1 | |
if proposal_draft.present? | |
redirect_to edit_draft_proposal_path(proposal_draft, component_id: proposal_draft.component.id, question_slug: proposal_draft.component.participatory_space.slug) | |
else | |
@form = form(ProposalWizardCreateStepForm).from_params(body: translated_proposal_body_template) | |
end | |
end | |
def create | |
enforce_permission_to :create, :proposal | |
@step = :step_1 | |
@form = form(ProposalWizardCreateStepForm).from_params(proposal_creation_params) | |
CreateProposal.call(@form, current_user) do | |
on(:ok) do |proposal| | |
flash[:notice] = I18n.t("proposals.create.success", scope: "decidim") | |
redirect_to "#{Decidim::ResourceLocatorPresenter.new(proposal).path}/compare" | |
end | |
on(:invalid) do | |
flash.now[:alert] = I18n.t("proposals.create.error", scope: "decidim") | |
render :new | |
end | |
end | |
end | |
def compare | |
@step = :step_2 | |
@similar_proposals ||= Decidim::Proposals::SimilarProposals | |
.for(current_component, @proposal) | |
.all | |
if @similar_proposals.blank? | |
flash[:notice] = I18n.t("proposals.proposals.compare.no_similars_found", scope: "decidim") | |
redirect_to "#{Decidim::ResourceLocatorPresenter.new(@proposal).path}/complete" | |
end | |
end | |
def complete | |
enforce_permission_to :create, :proposal | |
@step = :step_3 | |
@form = form_proposal_model | |
@form.attachment = form_attachment_new | |
end | |
def preview | |
@step = :step_4 | |
end | |
def publish | |
@step = :step_4 | |
PublishProposal.call(@proposal, current_user) do | |
on(:ok) do | |
flash[:notice] = I18n.t("proposals.publish.success", scope: "decidim") | |
redirect_to proposal_path(@proposal) | |
end | |
on(:invalid) do | |
flash.now[:alert] = I18n.t("proposals.publish.error", scope: "decidim") | |
render :edit_draft | |
end | |
end | |
end | |
def edit_draft | |
@step = :step_3 | |
enforce_permission_to :edit, :proposal, proposal: @proposal | |
end | |
def update_draft | |
@step = :step_1 | |
enforce_permission_to :edit, :proposal, proposal: @proposal | |
@form = form_proposal_params | |
UpdateProposal.call(@form, current_user, @proposal) do | |
on(:ok) do |proposal| | |
flash[:notice] = I18n.t("proposals.update_draft.success", scope: "decidim") | |
redirect_to "#{Decidim::ResourceLocatorPresenter.new(proposal).path}/preview" | |
end | |
on(:invalid) do | |
flash.now[:alert] = I18n.t("proposals.update_draft.error", scope: "decidim") | |
render :edit_draft | |
end | |
end | |
end | |
def destroy_draft | |
enforce_permission_to :edit, :proposal, proposal: @proposal | |
DestroyProposal.call(@proposal, current_user) do | |
on(:ok) do | |
flash[:notice] = I18n.t("proposals.destroy_draft.success", scope: "decidim") | |
redirect_to new_proposal_path | |
end | |
on(:invalid) do | |
flash.now[:alert] = I18n.t("proposals.destroy_draft.error", scope: "decidim") | |
render :edit_draft | |
end | |
end | |
end | |
def edit | |
enforce_permission_to :edit, :proposal, proposal: @proposal | |
end | |
def update | |
enforce_permission_to :edit, :proposal, proposal: @proposal | |
@form = form_proposal_params | |
UpdateProposal.call(@form, current_user, @proposal) do | |
on(:ok) do |proposal| | |
flash[:notice] = I18n.t("proposals.update.success", scope: "decidim") | |
redirect_to Decidim::ResourceLocatorPresenter.new(proposal).path | |
end | |
on(:invalid) do | |
flash.now[:alert] = I18n.t("proposals.update.error", scope: "decidim") | |
render :edit | |
end | |
end | |
end | |
def withdraw | |
enforce_permission_to :withdraw, :proposal, proposal: @proposal | |
WithdrawProposal.call(@proposal, current_user) do | |
on(:ok) do | |
flash[:notice] = I18n.t("proposals.update.success", scope: "decidim") | |
redirect_to Decidim::ResourceLocatorPresenter.new(@proposal).path | |
end | |
on(:has_supports) do | |
flash[:alert] = I18n.t("proposals.withdraw.errors.has_supports", scope: "decidim") | |
redirect_to Decidim::ResourceLocatorPresenter.new(@proposal).path | |
end | |
end | |
end | |
private | |
def search_klass | |
ProposalSearch | |
end | |
def default_filter_params | |
{ | |
search_text: "", | |
origin: default_filter_origin_params, | |
activity: "all", | |
category_id: default_filter_category_params, | |
state: %w(accepted evaluating state_not_published), | |
scope_id: default_filter_scope_params, | |
related_to: "", | |
type: "all" | |
} | |
end | |
def default_filter_origin_params | |
filter_origin_params = %w(citizens meeting) | |
filter_origin_params << "official" if component_settings.official_proposals_enabled | |
filter_origin_params << "user_group" if current_organization.user_groups_enabled? | |
filter_origin_params | |
end | |
def proposal_draft | |
Proposal.from_all_author_identities(current_user).not_hidden.only_amendables | |
.where(component: current_component).find_by(published_at: nil) | |
end | |
def ensure_is_draft | |
@proposal = Proposal.not_hidden.where(component: current_component).find(params[:id]) | |
redirect_to Decidim::ResourceLocatorPresenter.new(@proposal).path unless @proposal.draft? | |
end | |
def set_proposal | |
@proposal = Proposal.published.not_hidden.where(component: current_component).find_by(id: params[:id]) | |
end | |
# Returns true if the proposal is NOT an emendation or the user IS an admin. | |
# Returns false if the proposal is not found or the proposal IS an emendation | |
# and is NOT visible to the user based on the component's amendments settings. | |
def can_show_proposal? | |
return true if @proposal&.amendable? || current_user&.admin? | |
Proposal.only_visible_emendations_for(current_user, current_component).published.include?(@proposal) | |
end | |
def proposal_presenter | |
@proposal_presenter ||= present(@proposal) | |
end | |
def form_proposal_params | |
form(ProposalForm).from_params(params) | |
end | |
def form_proposal_model | |
form(ProposalForm).from_model(@proposal) | |
end | |
def form_presenter | |
@form_presenter ||= present(@form, presenter_class: Decidim::Proposals::ProposalPresenter) | |
end | |
def form_attachment_new | |
form(AttachmentForm).from_model(Attachment.new) | |
end | |
def edit_form | |
form_attachment_model = form(AttachmentForm).from_model(@proposal.attachments.first) | |
@form = form_proposal_model | |
@form.attachment = form_attachment_model | |
@form | |
end | |
def set_participatory_text | |
@participatory_text = Decidim::Proposals::ParticipatoryText.find_by(component: current_component) | |
end | |
def translated_proposal_body_template | |
translated_attribute component_settings.new_proposal_body_template | |
end | |
def proposal_creation_params | |
params[:proposal].merge(body_template: translated_proposal_body_template) | |
end | |
end | |
end | |
end |