quby-compiler 0.5.4 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 298486fbde9a0b1e4873a639011c6a4fe6c00dd98430a42d2a79afdb0fb92584
4
- data.tar.gz: e79bee94168384f1c17fa9abdfd2f9f0d4fd6036a166047474d44f4ab95c7da7
3
+ metadata.gz: 05f509c76c1f6c67029abdd77d29469b7a825708e86ea0d7d535e1ea05f4f57c
4
+ data.tar.gz: 1b78d9c1fed73f4642f2e76d942ba5c5619f2bb354ff0024ff3a22d92b3c8aff
5
5
  SHA512:
6
- metadata.gz: 23233110d98eae072f27e537f2a2ad2c60e47c7a9b76448502f9f73f1ccc3ee8dbda257e88c048b37c74a38f90afeff239e261dd0f6e85a1fe219c534078f880
7
- data.tar.gz: b2a3ab1acf6c92160a9a5a23affcb8b9174f032b476d3deb613d5f1d6e352e15bb2447f9a8ed2bdb0ab91f2364e6dc29b378294b0094b516256ee077d5dc3b6e
6
+ metadata.gz: 9c599463543dff5a691a135d97d374e858b9bf41f971d7bb61dea7448836bc36b3b179cf59dc4d9779a1e890a50d5c3b016fc15c63e634fde10a59ae1623ec41
7
+ data.tar.gz: b1b8baa09ce07637d8b502421332be3c33bf1eee95d4d9845b5daae4235703cfdef89022858326e90f96dbc3fa8e5a9f91795f56bd58ef1fa6e4fdfe787cffb1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ # 0.5.6
2
+
3
+ * quby2.json:
4
+ * Add checkAllOption and uncheckAllOption to checkbox questions.
5
+ * Added type to subscore_schema (string, float, integer)
6
+ * roqua.json:
7
+ * Added type to subscores
8
+
9
+ # 0.5.5
10
+
11
+ * roqua.json:
12
+ * Add sbg_key to scores
13
+
1
14
  # 0.5.4
2
15
 
3
16
  * quby2:
@@ -212,21 +212,22 @@ module Quby
212
212
  def score(key, **options, &block)
213
213
  @questionnaire.errors.add "Score #{key}", 'misses label in score call' if options[:label].blank?
214
214
  schema = options.delete(:schema)
215
- score_schema(key, options[:label], schema) if schema.present?
215
+ score_schema(key, options[:label], schema, sbg_key: options[:sbg_key]) if schema.present?
216
216
  variable(key, score: true, **options, &block)
217
217
  end
218
218
 
219
- def score_schema(key, label, options = nil, &block)
219
+ def score_schema(key, label, subscore_schemas = nil, sbg_key: nil, &block)
220
220
  if block
221
- schema, calculations = ScoreSchemaBuilder.build(key: key, label: label, &block)
221
+ schema, calculations = ScoreSchemaBuilder.build(key:, label:, sbg_key:, &block)
222
222
  @questionnaire.add_score_schema schema
223
223
  calculations.each do |calculation|
224
224
  @questionnaire.add_score_calculation calculation
225
225
  end
226
226
  else
227
- @questionnaire.add_score_schema Entities::ScoreSchema.new key: key,
228
- label: label,
229
- subscore_schemas: options
227
+ @questionnaire.add_score_schema Entities::ScoreSchema.new key:,
228
+ label:,
229
+ sbg_key:,
230
+ subscore_schemas:
230
231
  end
231
232
  end
232
233
 
@@ -4,9 +4,10 @@ module Quby
4
4
  module Compiler
5
5
  module DSL
6
6
  class ScoreSchemaBuilder < Base
7
- def initialize(key:, label:, &block)
7
+ def initialize(key:, label:, sbg_key: nil, &block)
8
8
  @score_key = key
9
9
  @score_label = label
10
+ @score_sbg_key = sbg_key
10
11
  @subschema_params = []
11
12
  @generated_calculations = []
12
13
  end
@@ -14,6 +15,7 @@ module Quby
14
15
  def build
15
16
  score_schema = Entities::ScoreSchema.new key: @score_key,
16
17
  label: @score_label,
18
+ sbg_key: @score_sbg_key,
17
19
  subscore_schemas: @subschema_params
18
20
  [score_schema, @generated_calculations + [generate_score_calculation(score_schema)]]
19
21
  end
@@ -44,6 +46,7 @@ module Quby
44
46
  score_code_string = "score do\n {#{inner_hash_string}}\nend"
45
47
  Entities::ScoreCalculation.new score_schema.key,
46
48
  label: score_schema.label,
49
+ sbg_key: score_schema.sbg_key,
47
50
  score: true,
48
51
  ruby_string: score_code_string
49
52
  end
@@ -77,42 +77,9 @@ module Quby
77
77
  end
78
78
  end
79
79
 
80
- # returns a human readable string description given a key of a question,
81
- # question component (date components, checkbox options), score, flag or textvar
82
- def description_for_variable(key)
83
- # for questionnaires where we do not check_key_clashes we cannot reliably retrace the variable keys,
84
- # since they contain conflicts between option keys and question keys
85
- # in order to be safe we return a string explaining the issue
86
- return "No description due to question/option key clash" if option_hash.key?(key) && question_hash.key?(key)
87
-
88
- variable_description(key)
89
- end
90
-
91
80
  def as_json
92
81
  question_hash.as_json
93
82
  end
94
-
95
- private
96
-
97
- # warning, will contain a result even if option/answer key clashes exist for a given key
98
- def variable_description(key)
99
- @question_variable_descriptions ||= @questionnaire.questions
100
- .map(&:variable_descriptions)
101
- .reduce({}, &:merge!)
102
- @question_variable_descriptions[key] ||
103
- score_descriptions[key] ||
104
- @questionnaire.flags[key]&.variable_description ||
105
- @questionnaire.textvars[key]&.description
106
- end
107
-
108
- def score_descriptions
109
- @score_variable_descriptions ||=
110
- @questionnaire.score_schemas.values.map do |score_schema|
111
- score_schema.subscore_schemas.map do |subschema|
112
- [subschema.export_key, "#{score_schema.label} #{subschema.label}"]
113
- end
114
- end.flatten(1).to_h.with_indifferent_access
115
- end
116
83
  end
117
84
  end
118
85
  end
@@ -27,10 +27,6 @@ module Quby
27
27
  yield if answer_flags[key] == trigger_on
28
28
  end
29
29
 
30
- def variable_description
31
- "#{description} (true - '#{description_true}', false - '#{description_false}')"
32
- end
33
-
34
30
  private
35
31
 
36
32
  def ensure_valid_descriptions
@@ -326,10 +326,6 @@ module Quby
326
326
  def subquestion?
327
327
  !parent_option_key.nil?
328
328
  end
329
-
330
- def variable_descriptions
331
- {key => context_free_title_or_title}.with_indifferent_access
332
- end
333
329
  end
334
330
  end
335
331
  end
@@ -200,21 +200,6 @@ module Quby
200
200
  @license = type
201
201
  end
202
202
 
203
- def as_json(options = {})
204
- {
205
- key: key,
206
- title: title,
207
- description: description,
208
- outcomeDescription: outcome_description,
209
- shortDescription: short_description,
210
- panels: panels,
211
- questions: fields.question_hash.as_json,
212
- flags: flags,
213
- textvars: textvars,
214
- visibilityRules: visibility_rules
215
- }
216
- end
217
-
218
203
  def key_in_use?(key)
219
204
  fields.key_in_use?(key) || score_calculations.key?(key)
220
205
  end
@@ -50,13 +50,6 @@ module Quby
50
50
  end
51
51
  end
52
52
 
53
- def variable_descriptions
54
- options.each_with_object(key => context_free_title_or_title) do |option, hash|
55
- next if option.input_key.blank?
56
- hash[option.input_key] = "#{context_free_title_or_title} - #{option.description}"
57
- end.with_indifferent_access
58
- end
59
-
60
53
  def claimed_keys
61
54
  [key]
62
55
  end
@@ -67,7 +60,11 @@ module Quby
67
60
  end
68
61
 
69
62
  def as_json(options = {})
70
- super.merge(children: @options.as_json)
63
+ super.tap do |json|
64
+ json[:children] = @options.as_json
65
+ json[:checkAllOption] = check_all_option if check_all_option.present?
66
+ json[:uncheckAllOption] = uncheck_all_option if uncheck_all_option.present?
67
+ end
71
68
  end
72
69
  end
73
70
  end
@@ -54,13 +54,6 @@ module Quby
54
54
  end
55
55
  end
56
56
 
57
- def variable_descriptions
58
- components.each_with_object(key => context_free_title_or_title) do |component, hash|
59
- key = send("#{component}_key")
60
- hash[key] = "#{context_free_title_or_title} (#{I18n.t component})"
61
- end.with_indifferent_access
62
- end
63
-
64
57
  def as_json(options = {})
65
58
  super.merge(
66
59
  type: 'date_parts',
@@ -13,6 +13,8 @@ module Quby
13
13
  attribute :key, Types::Symbol
14
14
  # A label describing the general purpose of the score
15
15
  attribute :label, Types::String
16
+ # Alternative key used by some external systems
17
+ attribute :sbg_key?, Types::String.optional
16
18
  # An array of SubscoreSchemas describing each key that can be returned in the result hash of a score.
17
19
  attribute :subscore_schemas, Types::Array(Entities::SubscoreSchema)
18
20
 
@@ -18,6 +18,7 @@ module Quby
18
18
  # differ in subscores too much to be shown as one table. By default, all scores end up in the `:main` table.
19
19
  # When outcome_table is explicitly nil, the value should not be shown in outcome tables
20
20
  attribute :outcome_table, Types::Symbol.optional.default(:main)
21
+ attribute :type, Types::Symbol.enum(:string, :integer, :float).meta(omittable: true)
21
22
  end
22
23
  end
23
24
  end
@@ -1,3 +1,5 @@
1
+ require 'quby/compiler/services/transform_quby1_values_into_quby2_values.rb'
2
+
1
3
  module Quby
2
4
  module Compiler
3
5
  module Outputs
@@ -6,10 +8,23 @@ module Quby
6
8
  @questionnaire = questionnaire
7
9
  end
8
10
 
9
- # TODO: Move all attributes here from Questionnaire#as_json
11
+ delegate_missing_to :@questionnaire
12
+
10
13
  def as_json(options = {})
11
- @questionnaire.as_json.merge \
12
- validations: validations
14
+ {
15
+ key: key,
16
+ title: title,
17
+ description: description,
18
+ outcomeDescription: outcome_description,
19
+ shortDescription: short_description,
20
+ defaultAnswerValue: Services::TransformQuby1ValuesIntoQuby2Values.run!(@questionnaire, default_answer_value),
21
+ panels: panels,
22
+ questions: fields.question_hash.as_json,
23
+ flags: flags,
24
+ textvars: textvars,
25
+ validations: validations,
26
+ visibilityRules: visibility_rules
27
+ }
13
28
  end
14
29
 
15
30
  def validations
@@ -19,6 +34,8 @@ module Quby
19
34
  .tap do |validation_hsh|
20
35
  # otherwise ruby will put a (?-mix around the regex, which js errors on.
21
36
  validation_hsh['matcher'] = validation_hsh['matcher'].source.to_s if validation_hsh['matcher']
37
+ validation_hsh['type'] = 'minimum_date' if validation_hsh['type'] == :minimum && validation_hsh['subtype'] == :date
38
+ validation_hsh['type'] = 'maximum_date' if validation_hsh['type'] == :maximum && validation_hsh['subtype'] == :date
22
39
  end.as_json
23
40
  end
24
41
  end
@@ -248,8 +248,9 @@ module Quby
248
248
  {
249
249
  key: score.key,
250
250
  label: score.label,
251
+ sbg_key: score.sbg_key,
251
252
  subscores: subscores_for(score)
252
- }
253
+ }.compact
253
254
  }
254
255
  end
255
256
 
@@ -260,7 +261,8 @@ module Quby
260
261
  key: subscore.key,
261
262
  label: subscore.label,
262
263
  export_key: subscore.export_key,
263
- only_for_export: subscore.only_for_export.presence
264
+ only_for_export: subscore.only_for_export.presence,
265
+ type: subscore.type
264
266
  }.compact
265
267
  }
266
268
  end
@@ -0,0 +1,49 @@
1
+ # Copied from RoQua for default_answer_values.
2
+ # Temporary: should change the values when quby1 is off the table
3
+ class Quby::Compiler::Services::TransformQuby1ValuesIntoQuby2Values
4
+ attr_accessor :questionnaire, :values
5
+
6
+ def self.run!(...)
7
+ new(...).execute
8
+ end
9
+
10
+ def initialize(questionnaire, values)
11
+ @questionnaire = questionnaire
12
+ @values = (values || {}).with_indifferent_access
13
+ end
14
+
15
+ # Edits hash in place!
16
+ # extra v_3 key is not in quby1, but can't really hurt keeping it in.
17
+ # {v_3: {year: '2020'}} to {'v_3_yyyy' => '2020', v_3: {year: '2020'}}
18
+ # {v_4: ['a2']} to {v_4_a1: 0, v_4_a2: 1, v_4: {v_4_a1: 0, v_4_a2: 1}}
19
+ def execute
20
+ questionnaire.questions.each do |question|
21
+ case question.type
22
+ when :date then transform_date_parts(question)
23
+ when :check_box then transform_multi_select(question)
24
+ end
25
+ end
26
+ values
27
+ end
28
+
29
+ private
30
+
31
+ def transform_date_parts(question)
32
+ date_parts = question.components.map { OpenStruct.new(part: _1, key: question.send("#{_1}_key")) }
33
+ return if date_parts.all? { values[_1.key].nil? }
34
+
35
+ values[question.key] = date_parts.to_h { |date_part|
36
+ [date_part.part, values[date_part.key]]
37
+ }.compact
38
+
39
+ date_parts.each { values.delete(_1.key) }
40
+ end
41
+
42
+ def transform_multi_select(question)
43
+ return if values[question.key].nil?
44
+
45
+ quby2_style_value = question.options.select { |option| values[question.key][option.key] == 1 }.map(&:key)
46
+ values[question.key] = quby2_style_value
47
+ question.options.each { values.delete(_1.key) }
48
+ end
49
+ end
@@ -1,5 +1,5 @@
1
1
  module Quby
2
2
  module Compiler
3
- VERSION = "0.5.4"
3
+ VERSION = "0.5.6"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quby-compiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.4
4
+ version: 0.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marten Veldthuis
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-07-10 00:00:00.000000000 Z
11
+ date: 2023-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -219,6 +219,7 @@ files:
219
219
  - lib/quby/compiler/services/quby_proxy.rb
220
220
  - lib/quby/compiler/services/seed_diff.rb
221
221
  - lib/quby/compiler/services/text_transformation.rb
222
+ - lib/quby/compiler/services/transform_quby1_values_into_quby2_values.rb
222
223
  - lib/quby/compiler/type_validator.rb
223
224
  - lib/quby/compiler/version.rb
224
225
  - lib/quby/range_categories.rb
@@ -244,7 +245,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
244
245
  - !ruby/object:Gem::Version
245
246
  version: '0'
246
247
  requirements: []
247
- rubygems_version: 3.4.10
248
+ rubygems_version: 3.4.19
248
249
  signing_key:
249
250
  specification_version: 4
250
251
  summary: Quby::Compiler compiles a DSL for questionnaires to JSON