# frozen_string_literal: true module Decidim module Proposals # This class serializes a Proposal so can be exported to CSV, JSON or other # formats. class ProposalSerializer < Decidim::Exporters::Serializer include Decidim::ApplicationHelper include Decidim::ResourceHelper include Decidim::TranslationsHelper include HtmlToPlainText # Public: Initializes the serializer with a proposal. def initialize(proposal) @proposal = proposal end # Public: Exports a hash with the serialized data for this proposal. def serialize { id: proposal.id, category: { id: proposal.category.try(:id), name: proposal.category.try(:name) || empty_translatable }, scope: { id: proposal.scope.try(:id), name: proposal.scope.try(:name) || empty_translatable }, participatory_space: { id: proposal.participatory_space.id, url: Decidim::ResourceLocatorPresenter.new(proposal.participatory_space).url }, component: { id: component.id }, title: proposal.title, body: convert_to_plain_text(proposal.body), address: proposal.address, latitude: proposal.latitude, longitude: proposal.longitude, state: proposal.state.to_s, reference: proposal.reference, answer: ensure_translatable(proposal.answer), supports: proposal.proposal_votes_count, endorsements: { total_count: proposal.endorsements.size, user_endorsements: }, comments: proposal.comments_count, attachments: proposal.attachments.count, followers: proposal.follows.size, published_at: proposal.published_at, url:, meeting_urls: meetings, related_proposals:, is_amend: proposal.emendation?, original_proposal: { title: proposal&.amendable&.title, url: original_proposal_url } } end private attr_reader :proposal alias resource proposal def component proposal.component end def meetings proposal.linked_resources(:meetings, "proposals_from_meeting").map do |meeting| Decidim::ResourceLocatorPresenter.new(meeting).url end end def related_proposals proposal.linked_resources(:proposals, "copied_from_component").map do |proposal| Decidim::ResourceLocatorPresenter.new(proposal).url end end def url Decidim::ResourceLocatorPresenter.new(proposal).url end def user_endorsements proposal.endorsements.for_listing.map { |identity| identity.normalized_author&.name } end def original_proposal_url return unless proposal.emendation? && proposal.amendable.present? Decidim::ResourceLocatorPresenter.new(proposal.amendable).url end # Recursively strips HTML tags from given Hash strings using convert_to_text from Premailer def convert_to_plain_text(value) return value.transform_values { |v| convert_to_plain_text(v) } if value.is_a?(Hash) convert_to_text(value) end end end end