app/models/decidim/proposals/proposal.rb in decidim-proposals-0.26.10 vs app/models/decidim/proposals/proposal.rb in decidim-proposals-0.27.0.rc1

- old
+ new

@@ -16,19 +16,20 @@ include Decidim::Proposals::CommentableProposal include Decidim::Searchable include Decidim::Traceable include Decidim::Loggable include Decidim::Fingerprintable - include Decidim::DataPortability + include Decidim::DownloadYourData include Decidim::Proposals::ParticipatoryTextSection include Decidim::Amendable include Decidim::NewsletterParticipant include Decidim::Randomable include Decidim::Endorsable include Decidim::Proposals::Valuatable include Decidim::TranslatableResource include Decidim::TranslatableAttributes + include Decidim::FilterableResource translatable_fields :title, :body POSSIBLE_STATES = %w(not_answered evaluating accepted rejected withdrawn).freeze @@ -65,22 +66,47 @@ scope :evaluating, -> { state_published.where(state: "evaluating") } scope :withdrawn, -> { where(state: "withdrawn") } scope :except_rejected, -> { where.not(state: "rejected").or(state_not_published) } scope :except_withdrawn, -> { where.not(state: "withdrawn").or(where(state: nil)) } scope :drafts, -> { where(published_at: nil) } - scope :except_drafts, -> { where.not(published_at: nil) } scope :published, -> { where.not(published_at: nil) } scope :order_by_most_recent, -> { order(created_at: :desc) } + scope :with_availability, lambda { |state_key| + case state_key + when "withdrawn" + withdrawn + else + except_withdrawn + end + } + + scope :with_type, lambda { |type_key, user, component| + case type_key + when "proposals" + only_amendables + when "amendments" + only_visible_emendations_for(user, component) + else # Assume 'all' + amendables_and_visible_emendations_for(user, component) + end + } + + scope :voted_by, lambda { |user| + includes(:votes).where(decidim_proposals_proposal_votes: { decidim_author_id: user }) + } + scope :sort_by_valuation_assignments_count_asc, lambda { order(Arel.sql("#{sort_by_valuation_assignments_count_nulls_last_query} ASC NULLS FIRST").to_s) } scope :sort_by_valuation_assignments_count_desc, lambda { order(Arel.sql("#{sort_by_valuation_assignments_count_nulls_last_query} DESC NULLS LAST").to_s) } + scope_search_multi :with_any_state, [:accepted, :rejected, :evaluating, :state_not_published] + def self.with_valuation_assigned_to(user, space) valuator_roles = space.user_roles(:valuator).where(user: user) includes(:valuation_assignments) .where(decidim_proposals_valuation_assignments: { valuator_role_id: valuator_roles }) @@ -101,11 +127,11 @@ def self.log_presenter_class_for(_log) Decidim::Proposals::AdminLog::ProposalPresenter end # Returns a collection scoped by an author. - # Overrides this method in DataPortability to support Coauthorable. + # Overrides this method in DownloadYourData to support Coauthorable. def self.user_collection(author) return unless author.is_a?(Decidim::User) joins(:coauthorships) .where(decidim_coauthorships: { coauthorable_type: name }) @@ -239,22 +265,23 @@ def reported_attributes [:title, :body] end # Public: Overrides the `reported_searchable_content_extras` Reportable concern method. + # Returns authors name or title in case it's a meeting def reported_searchable_content_extras - [authors.map(&:name).join("\n")] + [authors.map { |p| p.respond_to?(:name) ? p.name : p.title }.join("\n")] end # Public: Whether the proposal is official or not. def official? authors.first.is_a?(Decidim::Organization) end # Public: Whether the proposal is created in a meeting or not. def official_meeting? - authors.first.class.name == "Decidim::Meetings::Meeting" + authors.first.instance_of?(Decidim::Meetings::Meeting) end # Public: The maximum amount of votes allowed for this proposal. # # Returns an Integer with the maximum amount of votes, nil otherwise. @@ -300,10 +327,14 @@ # Public: Whether the proposal is a draft or not. def draft? published_at.nil? end + def self.ransack(params = {}, options = {}) + ProposalSearch.new(self, params, options) + end + # Defines the base query so that ransack can actually sort by this value def self.sort_by_valuation_assignments_count_nulls_last_query <<-SQL.squish ( SELECT COUNT(decidim_proposals_valuation_assignments.id) @@ -325,14 +356,22 @@ ) SQL where(query, value: value) end - def self.ransackable_scopes(_auth = nil) - [:valuator_role_ids_has] + def self.ransackable_scopes(auth_object = nil) + base = [:with_any_origin, :with_any_state, :voted_by, :coauthored_by, :related_to, :with_any_scope, :with_any_category] + return base unless auth_object&.admin? + + # Add extra scopes for admins for the admin panel searches + base + [:valuator_role_ids_has] end + # Create i18n ransackers for :title and :body. + # Create the :search_text ransacker alias for searching from both of these. + ransacker_i18n_multi :search_text, [:title, :body] + ransacker :state_published do Arel.sql("CASE WHEN EXISTS ( SELECT 1 FROM decidim_amendments WHERE decidim_amendments.decidim_emendation_type = 'Decidim::Proposals::Proposal' @@ -377,10 +416,10 @@ def self.export_serializer Decidim::Proposals::ProposalSerializer end - def self.data_portability_images(user) + def self.download_your_data_images(user) user_collection(user).map { |p| p.attachments.collect(&:file) } end # Public: Overrides the `allow_resource_permissions?` Resourceable concern method. def allow_resource_permissions?