# == Schema Information # # Table name: exported_plans # # id :integer not null, primary key # format :string # created_at :datetime not null # updated_at :datetime not null # phase_id :integer # plan_id :integer # user_id :integer # class ExportedPlan < ActiveRecord::Base include ValidationMessages include GlobalHelpers include SettingsTemplateHelper #associations between tables belongs_to :plan belongs_to :user validates :plan, presence: { message: PRESENCE_MESSAGE } validates :format, presence: { message: PRESENCE_MESSAGE } # Store settings with the exported plan so it can be recreated later # if necessary (otherwise the settings associated with the plan at a # given time can be lost) has_settings :export, class_name: 'Settings::Template' do |s| s.key :export, defaults: Settings::Template::DEFAULT_SETTINGS end # TODO: Consider removing the accessor methods, they add no value. The view/controller could # just access the value directly from the project/plan: exported_plan.plan.project.title # Getters to match Settings::Template::VALID_ADMIN_FIELDS def project_name name = self.plan.template.title name += " - #{self.plan.title}" if self.plan.template.phases.count > 1 name end def project_identifier self.plan.identifier end def grant_title self.plan.grant_number end def principal_investigator self.plan.principal_investigator end def project_data_contact self.plan.data_contact end def project_description self.plan.description end def owner self.plan.roles.to_a.select{ |role| role.creator? }.first.user end def funder org = self.plan.template.try(:org) org.name if org.present? && org.funder? end def institution plan.owner.org.try(:name) end def orcid scheme = IdentifierScheme.find_by(name: 'orcid') if self.owner.nil? '' else orcid = self.owner.user_identifiers.where(identifier_scheme: scheme).first (orcid.nil? ? '' : orcid.identifier) end end def sections self.phase_id ||= self.plan.template.phases.first.id Section.where({phase_id: phase_id}).order(:number) end def questions_for_section(section_id) Question.where(id: questions).where(section_id: section_id).order(:number) end def admin_details @admin_details ||= self.settings(:export).fields[:admin] end # Retrieves the title field def title self.settings(:export).title end # Export formats def as_csv(sections, unanswered_questions, question_headings) CSV.generate do |csv| if question_headings csv << [_('Section'),_('Question'),_('Answer'),_('Selected option(s)'),_('Answered by'),_('Answered at')] else csv << [_('Section'),_('Answer'),_('Selected option(s)'),_('Answered by'),_('Answered at')] end sections.each do |section| section.questions.each do |question| answer = Answer.where(plan_id: self.plan_id, question_id: question.id).first # skip unansewered questions if answer.blank? && !unanswered_questions next end answer_text = answer.present? ? answer.text : '' q_format = question.question_format if q_format.option_based? options_string = answer.question_options.collect {|o| o.text}.join('; ') else options_string = '' end if question_headings csv << [ section.title, sanitize_text(question.text), question.option_comment_display ? sanitize_text(answer_text) : '', options_string, user.name, answer.updated_at ] else csv << [ section.title, question.option_comment_display ? sanitize_text(answer_text) : '', options_string, user.name, answer.updated_at ] end end end end end def as_txt(sections, unanswered_questions, question_headings, details) output = "#{self.plan.title}\n\n#{self.plan.template.title}\n" output += "\n"+ _('Details') +"\n\n" if details self.admin_details.each do |at| value = self.send(at) if value.present? output += admin_field_t(at.to_s) + ": " + value + "\n" else output += admin_field_t(at.to_s) + ": " + _('-') + "\n" end end end sections.each do |section| if question_headings output += "\n#{section.title}\n" end section.questions.each do |question| answer = self.plan.answer(question.id, false) #skip if question un-answered if answer.nil? && !unanswered_questions then next end if question_headings qtext = sanitize_text( question.text.gsub(/<li>/, ' * ') ) output += "\n* #{qtext}" end if answer.nil? output += _('Question not answered.') + "\n" else q_format = question.question_format if q_format.option_based? output += answer.question_options.collect {|o| o.text}.join("\n") if question.option_comment_display output += "\n#{sanitize_text(answer.text)}\n" end else output += "\n#{sanitize_text(answer.text)}\n" end end end end output end private # Returns an Array of question_ids for the exported settings stored for a plan def questions question_settings = self.settings(:export).fields[:questions] @questions ||= if question_settings.present? if question_settings == :all Question.where(section_id: self.plan.sections.collect { |s| s.id }).pluck(:id) elsif question_settings.is_a?(Array) question_settings else [] end else [] end end def sanitize_text(text) if (!text.nil?) then ActionView::Base.full_sanitizer.sanitize(text.gsub(/ /i,"")) end end end