Class: Quby::Answers::Entities::Answer

Inherits:
Object
  • Object
show all
Extended by:
ActiveModel::Naming, ActiveModel::Translation
Defined in:
lib/quby/answers/entities/answer.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(_id: nil, questionnaire_id: nil, questionnaire_key: nil, questionnaire: nil, raw_params: nil, value: nil, patient_id: nil, patient: nil, token: nil, active: true, test: false, created_at: nil, updated_at: nil, started_at: nil, completed_at: nil, observation_time: nil, entered_at: nil, outcome: nil, outcome_generated_at: nil, scores: nil, actions: nil, completion: nil, dsl_last_update: nil, import_notes: nil, flags: nil, textvars: nil) ⇒ Answer

accepts completed_at for now, setting observation_time and entered_at



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/quby/answers/entities/answer.rb', line 87

def initialize(_id: nil, questionnaire_id: nil, questionnaire_key: nil, questionnaire: nil,
  raw_params: nil, value: nil, patient_id: nil, patient: nil,
  token: nil, active: true, test: false, created_at: nil, updated_at: nil,
  started_at: nil, completed_at: nil, observation_time: nil, entered_at: nil,
  outcome: nil, outcome_generated_at: nil,
  scores: nil, actions: nil, completion: nil, dsl_last_update: nil, import_notes: nil,
  flags: nil, textvars: nil)

  self._id = _id
  self.questionnaire_id = questionnaire_id
  self.questionnaire_key = questionnaire_key
  self.raw_params = raw_params || {}
  self.value = value || {}
  self.patient_id = patient_id
  self.patient = patient || {}
  self.token = token
  self.active = active
  self.test = test
  self.created_at = created_at
  self.updated_at = updated_at
  self.started_at = started_at
  self.entered_at = entered_at || completed_at
  self.observation_time = observation_time || entered_at
  self.outcome_generated_at = outcome_generated_at
  self.scores = scores || {}
  self.actions = actions || {}
  self.completion = completion || {}
  self.dsl_last_update = dsl_last_update
  self.import_notes = import_notes || {}
  self.flags = flags
  self.textvars = textvars

  @questionnaire = questionnaire
end

Instance Attribute Details

#_idString

Returns:

  • (String)


15
16
17
# File 'lib/quby/answers/entities/answer.rb', line 15

def _id
  @_id
end

#abortedObject

Returns the value of attribute aborted.



84
85
86
# File 'lib/quby/answers/entities/answer.rb', line 84

def aborted
  @aborted
end

#actionsObject



289
290
291
# File 'lib/quby/answers/entities/answer.rb', line 289

def actions
  outcome.actions
end

#activeBoolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/quby/answers/entities/answer.rb', line 41

def active
  @active
end

#completionObject



293
294
295
# File 'lib/quby/answers/entities/answer.rb', line 293

def completion
  outcome.completion
end

#created_atTime

Returns:

  • (Time)


47
48
49
# File 'lib/quby/answers/entities/answer.rb', line 47

def created_at
  @created_at
end

#dsl_last_updateTime

Returns:

  • (Time)


67
68
69
# File 'lib/quby/answers/entities/answer.rb', line 67

def dsl_last_update
  @dsl_last_update
end

#entered_atTime

The time at which the response was entered into the system for the first time, not necessarily the same as the observation time

Returns:

  • (Time)


64
65
66
# File 'lib/quby/answers/entities/answer.rb', line 64

def entered_at
  @entered_at
end

#flagsHash<String, Boolean>

Returns:

  • (Hash<String, Boolean>)


74
75
76
# File 'lib/quby/answers/entities/answer.rb', line 74

def flags
  @flags
end

#import_notesHash

For answers that are imported from external sources

Returns:

  • (Hash)


71
72
73
# File 'lib/quby/answers/entities/answer.rb', line 71

def import_notes
  @import_notes
end

#observation_timeTime

The observation time of the response, the date at which the information in the response was collected. Defaults to entered_at, but always set, to make querying easier. This is used to calculate the age of the respondent at the time of filling out

Returns:

  • (Time)


59
60
61
# File 'lib/quby/answers/entities/answer.rb', line 59

def observation_time
  @observation_time
end

#outcome_generated_atObject

Returns the value of attribute outcome_generated_at.



79
80
81
# File 'lib/quby/answers/entities/answer.rb', line 79

def outcome_generated_at
  @outcome_generated_at
end

#patientHash

Returns:

  • (Hash)


35
36
37
# File 'lib/quby/answers/entities/answer.rb', line 35

def patient
  @patient
end

#patient_idObject



187
188
189
# File 'lib/quby/answers/entities/answer.rb', line 187

def patient_id
  patient[:id] || @patient_id
end

#questionnaire_idString

Returns:

  • (String)


18
19
20
# File 'lib/quby/answers/entities/answer.rb', line 18

def questionnaire_id
  @questionnaire_id
end

#questionnaire_keyString

Returns:

  • (String)


21
22
23
# File 'lib/quby/answers/entities/answer.rb', line 21

def questionnaire_key
  @questionnaire_key
end

#raw_paramsHash

The raw form data (for recovery purposes)

Returns:

  • (Hash)


25
26
27
# File 'lib/quby/answers/entities/answer.rb', line 25

def raw_params
  @raw_params
end

#scoresObject



277
278
279
# File 'lib/quby/answers/entities/answer.rb', line 277

def scores
  outcome.scores
end

#started_atTime

Returns:

  • (Time)


53
54
55
# File 'lib/quby/answers/entities/answer.rb', line 53

def started_at
  @started_at
end

#testBoolean

Returns:

  • (Boolean)


44
45
46
# File 'lib/quby/answers/entities/answer.rb', line 44

def test
  @test
end

#textvarsHash<String, String>

Returns:

  • (Hash<String, String>)


77
78
79
# File 'lib/quby/answers/entities/answer.rb', line 77

def textvars
  @textvars
end

#tokenString

Returns:

  • (String)


38
39
40
# File 'lib/quby/answers/entities/answer.rb', line 38

def token
  @token
end

#updated_atTime

Returns:

  • (Time)


50
51
52
# File 'lib/quby/answers/entities/answer.rb', line 50

def updated_at
  @updated_at
end

#valueHash

The filtered and transformed form data

Returns:

  • (Hash)


29
30
31
# File 'lib/quby/answers/entities/answer.rb', line 29

def value
  @value
end

Instance Method Details

#actionObject



297
298
299
# File 'lib/quby/answers/entities/answer.rb', line 297

def action
  outcome.action
end

#all_blank?Boolean

Returns:

  • (Boolean)


324
325
326
327
328
329
# File 'lib/quby/answers/entities/answer.rb', line 324

def all_blank?
  questionnaire.questions.reduce(true) do |all_blank, question|
    next all_blank unless question
    all_blank and send(question.key).blank?
  end
end

#as_json(options = {}) ⇒ Object



311
312
313
314
315
316
317
318
# File 'lib/quby/answers/entities/answer.rb', line 311

def as_json(options = {})
  attributes.merge(
      id: id,
      value_by_values: value_by_values,
      scores: scores,
      is_completed: self.completed? ? true : false
  )
end

#attributesObject



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/quby/answers/entities/answer.rb', line 134

def attributes
  HashWithIndifferentAccess.new({
    _id: _id,
    questionnaire_id: questionnaire_id,
    questionnaire_key: questionnaire_key,
    raw_params: raw_params,
    value: value,
    patient_id: patient_id,
    patient: patient,
    token: token,
    active: active,
    test: test,
    created_at: created_at,
    updated_at: updated_at,
    started_at: started_at,
    entered_at: entered_at,
    observation_time: observation_time,
    outcome_generated_at: outcome_generated_at,
    scores: scores,
    actions: actions,
    completion: completion,
    dsl_last_update: dsl_last_update,
    import_notes: import_notes,
    flags: flags,
    textvars: textvars
  })
end

#completed?Boolean

Returns:

  • (Boolean)


320
321
322
# File 'lib/quby/answers/entities/answer.rb', line 320

def completed?
  !all_blank? && valid?
end

#enhance_by_dslObject



183
184
185
# File 'lib/quby/answers/entities/answer.rb', line 183

def enhance_by_dsl
  DSL.enhance(self)
end

#errorsObject



162
163
164
# File 'lib/quby/answers/entities/answer.rb', line 162

def errors
  @errors ||= ActiveModel::Errors.new(self)
end

#extra_failed_validationsObject



203
204
205
206
207
208
209
210
211
212
# File 'lib/quby/answers/entities/answer.rb', line 203

def extra_failed_validations
  @extra_failed_validations = {}
  questionnaire.questions.each do |q|
    next unless q
    unless q.raw_content.blank?
      @extra_failed_validations[q.key] = errors[q.key] if errors[q.key].present?
    end
  end
  @extra_failed_validations.to_json
end

#extra_question_valuesObject



191
192
193
194
195
196
197
198
199
200
201
# File 'lib/quby/answers/entities/answer.rb', line 191

def extra_question_values
  @extra_question_values = {}
  questionnaire.questions.each do |q|
    next unless q
    unless q.raw_content.blank?
      @extra_question_values[q.key] = send(q.key)
    end
  end

  @extra_question_values.to_json
end

#idObject



122
123
124
# File 'lib/quby/answers/entities/answer.rb', line 122

def id
  _id
end

#mark_completed(start_time) ⇒ Object



175
176
177
178
179
180
181
# File 'lib/quby/answers/entities/answer.rb', line 175

def mark_completed(start_time)
  if completed? || @aborted
    self.started_at = start_time if started_at.blank?
    self.entered_at ||= Time.now
    self.observation_time ||= entered_at
  end
end

#outcomeOutcome

Returns:



266
267
268
# File 'lib/quby/answers/entities/answer.rb', line 266

def outcome
  Outcome.new(scores: @scores, actions: @actions, completion: @completion, generated_at: @outcome_generated_at)
end

#outcome=(outcome) ⇒ Object



270
271
272
273
274
275
# File 'lib/quby/answers/entities/answer.rb', line 270

def outcome=(outcome)
  self.scores               = outcome.scores
  self.actions              = outcome.actions
  self.completion           = outcome.completion
  self.outcome_generated_at = outcome.generated_at
end

#questionnaireObject

Faux belongs_to :questionnaire



171
172
173
# File 'lib/quby/answers/entities/answer.rb', line 171

def questionnaire
  @questionnaire ||= Quby.questionnaires.find(questionnaire_key)
end

#read_attribute_for_validation(attr) ⇒ Object

Required for ActiveModel::Errors



346
347
348
# File 'lib/quby/answers/entities/answer.rb', line 346

def read_attribute_for_validation(attr)
  send(attr)
end

#score_objectsObject



281
282
283
284
285
286
287
# File 'lib/quby/answers/entities/answer.rb', line 281

def score_objects
  scores.map do |score_key, score_hash|
    score = Score.new score_schema: questionnaire.score_schemas[score_key],
                      score_hash: score_hash
    [score_key, score]
  end.to_h.with_indifferent_access
end

#to_paramObject



130
131
132
# File 'lib/quby/answers/entities/answer.rb', line 130

def to_param
  id
end

#url_params(options = {}) ⇒ Object



331
332
333
334
335
336
337
338
339
340
341
342
343
# File 'lib/quby/answers/entities/answer.rb', line 331

def url_params(options = {})
  timestamp = Time.now.getgm.strftime("%Y-%m-%dT%H:%M:%S+00:00")
  plain_token = [Quby::Settings.shared_secret, token, timestamp].join('|')

  # double slash removed from return_url (it's either this or removing the
  # final slash in Settings.application_url)
  options.merge(
      display_mode: options[:display_mode] || "paged",
      token: token,
      timestamp: timestamp,
      hmac: Digest::SHA1.hexdigest(plain_token)
  )
end

#valid?Boolean

Returns:

  • (Boolean)


166
167
168
# File 'lib/quby/answers/entities/answer.rb', line 166

def valid?
  errors.empty?
end

#value_by_regular_valuesObject



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/quby/answers/entities/answer.rb', line 238

def value_by_regular_values
  result = {}
  if value
    result = value.dup
    value.each do |key, answer|
      question = questionnaire.questions.find { |q| q&.key.to_s == key.to_s }
      next unless question
      if question.type == :radio || question.type == :scale || question.type == :select
        option = question.options.find { |o| o.key.to_s == value[key].to_s }
        result[key] = option.value if option
      elsif question.type == :integer
        result[key] = answer.to_i if answer
      elsif question.type == :float
        result[key] = answer.to_f if answer
      end
    end
  end
  result
rescue Exception => e
  if defined? Roqua::Support::Errors
    Roqua::Support::Errors.report e, root_path: Rails.root.to_s
  end
  raise e if Rails.env.development? || Rails.env.test?
  Rails.logger.error "RESCUED #{e.message} \n #{e.backtrace.join('\n')}"
  {}
end

#value_by_valuesObject



214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/quby/answers/entities/answer.rb', line 214

def value_by_values
  result = {}
  if value
    result = value.dup
    value.each_key do |key|
      question = questionnaire.questions.find { |q| q&.key.to_s == key.to_s }
      if question and (question.type == :radio || question.type == :scale || question.type == :select)
        option = question.options.find { |o| o.key.to_s == value[key].to_s }
        if option
          result[key] = option.value.to_s
        end
      end
    end
  end
  result
rescue Exception => e
  if defined? Roqua::Support::Errors
    Roqua::Support::Errors.report e, root_path: Rails.root.to_s
  end
  raise e if Rails.env.development? || Rails.env.test?
  Rails.logger.error "RESCUED #{e.message} \n #{e.backtrace.join('\n')}"
  {}
end