# frozen_string_literal: true module ExportablePlan def as_pdf(coversheet = false) prepare(coversheet) end def as_csv(headings = true, unanswered = true, selected_phase = nil, show_custom_sections = true, show_coversheet = false) hash = prepare(show_coversheet) CSV.generate do |csv| if show_coversheet prepare_coversheet_for_csv(csv, headings, hash) end hdrs = (hash[:phases].many? ? [_("Phase")] : []) if headings hdrs << [_("Section"), _("Question"), _("Answer")] else hdrs << [_("Answer")] end customization = hash[:customization] csv << hdrs.flatten hash[:phases].each do |phase| if selected_phase.nil? || phase[:title] == selected_phase.title phase[:sections].each do |section| show_section = !customization show_section ||= customization && !section[:modifiable] show_section ||= customization && section[:modifiable] && show_custom_sections if show_section show_section_for_csv(csv, phase, section, headings, unanswered, hash) end end end end end end private def prepare(coversheet = false) hash = coversheet ? prepare_coversheet : {} template = Template.includes(phases: { sections: { questions: :question_format } }) .joins(phases: { sections: { questions: :question_format } }) .where(id: self.template_id) .order("sections.number", "questions.number").first hash[:customization] = template.customization_of.present? hash[:title] = self.title hash[:answers] = self.answers hash[:research_outputs] = self.research_outputs # add the relevant questions/answers phases = [] template.phases.order(:number).each do |phase| phs = { id: phase.id, title: phase.title, number: phase.number, sections: [] } phase.sections.order(:number).each do |section| sctn = { id: section.id, title: section.title, number: section.number, questions: [], modifiable: section.modifiable } section.questions.each do |question| txt = question.text sctn[:questions] << { id: question.id, text: txt, format: question.question_format } end phs[:sections] << sctn end phases << phs end hash[:phases] = phases record_plan_export(:pdf) hash end def prepare_coversheet hash = {} # name of owner and any co-owners attribution = self.owner.present? ? [self.owner.name(false)] : [] self.roles.administrator.not_creator.each do |role| attribution << role.user.name(false) end hash[:attribution] = attribution # Org name of plan owner's org hash[:affiliation] = self.owner.present? ? self.owner.org.name : "" # set the funder name hash[:funder] = self.funder_name.present? ? self.funder_name : (self.template.org.present? ? self.template.org.name : "") # set the template name and customizer name if applicable hash[:template] = self.template.title customizer = "" cust_questions = self.questions.where(modifiable: true).pluck(:id) # if the template is customized, and has custom answered questions if self.template.customization_of.present? && Answer.where(plan_id: self.id, question_id: cust_questions).present? customizer = _(" Customised By: ") + self.template.org.name end hash[:customizer] = customizer hash end def prepare_coversheet_for_csv(csv, headings, hash) csv << [ hash[:attribution].many? ? _("Creators: ") : _("Creator:"), _("%{authors}") % { authors: hash[:attribution].join(", ") } ] csv << [ "Affiliation: ", _("%{affiliation}") % { affiliation: hash[:affiliation] } ] if hash[:funder].present? csv << [ _("Template: "), _("%{funder}") % { funder: hash[:funder] } ] else csv << [ _("Template: "), _("%{template}") % { template: hash[:template] + hash[:customizer] } ] end if self.grant_number.present? csv << [ _("Grant number: "), _("%{grant_number}") % { grant_number: self.grant_number } ] end if self.description.present? csv << [ _("Project abstract: "), _("%{description}") % { description: Nokogiri::HTML(self.description).text } ] end csv << [ _("Last modified: "), _("%{date}") % { date: self.updated_at.to_date.strftime("%d-%m-%Y") } ] csv << [ _("Copyright information:"), _("The above plan creator(s) have agreed that others may use as much of the text of this plan as they would like in their own plans, and customise it as necessary. You do not need to credit the creator(s) as the source of the language used, but using any of the plan's text does not imply that the creator(s) endorse, or have any relationship to, your project or proposal") ] csv << [] csv << [] end def show_section_for_csv(csv, phase, section, headings, unanswered, hash) section[:questions].each do |question| answer = self.answer(question[:id], false) if answer.present? || (answer.blank? && unanswered) answer_text = answer.present? ? answer.text : (unanswered ? _("Not Answered") : "") if answer.present? && answer.question_options.any? answer_text = answer.question_options.pluck(:text).join(", ") end end flds = (hash[:phases].many? ? [phase[:title]] : []) if headings if question[:text].is_a? String question_text = question[:text] else question_text = (question[:text].many? ? question[:text].join(", ") : question[:text][0]) end flds << [ section[:title], sanitize_text(question_text), sanitize_text(answer_text) ] else flds << [ sanitize_text(answer_text) ] end csv << flds.flatten end end def record_plan_export(format) exported_plan = ExportedPlan.new.tap do |ep| ep.plan = self ep.phase_id = self.phases.first.id ep.format = format plan_settings = self.settings(:export) Settings::Template::DEFAULT_SETTINGS.each do |key, value| ep.settings(:export).send("#{key}=", plan_settings.send(key)) end end exported_plan.save end def sanitize_text(text) ActionView::Base.full_sanitizer.sanitize(text.to_s.gsub(/ /i, "")) end end