diff --git a/lib/quby/compiler/entities/subscore_schema.rb b/lib/quby/compiler/entities/subscore_schema.rb index 8091d9deab6db18c8b483e0f65c52419ea9b5999..b265898e8b1d5c1e7100be395e35169b09f6f626 100644 --- a/lib/quby/compiler/entities/subscore_schema.rb +++ b/lib/quby/compiler/entities/subscore_schema.rb @@ -14,6 +14,9 @@ module Quby attribute :only_for_export?, Types::Bool # [Optional] The key of the variable definition used to calculate the subscore result. attribute :calculation_key?, Types::Symbol + # [Optional argument] The name of the outcome table where this subscore should be shown. Used for cases where scores + # differ in subscores too much to be shown as one table. By default, all scores end up in the `:main` table. + attribute :outcome_table, Types::Symbol.default(:main).meta(omittable: true) end end end diff --git a/lib/quby/compiler/outputs/roqua_serializer.rb b/lib/quby/compiler/outputs/roqua_serializer.rb index 9238afb499f8d136b307e5714894e7fe1016752b..4fb85654d0a07603bf6a8f59369f02316fca1187 100644 --- a/lib/quby/compiler/outputs/roqua_serializer.rb +++ b/lib/quby/compiler/outputs/roqua_serializer.rb @@ -21,6 +21,7 @@ module Quby respondent_types: questionnaire.respondent_types, tags: questionnaire.tags.to_h.keys, charts: charts, + outcome_tables_schema: outcome_tables_schema, } end @@ -73,6 +74,34 @@ module Quby end } end + + # configuration for outcome tables. + # tables: + # <outcome_table_name:Symbol>: # each entry is a table. + # score_keys: Set[<schema.key:Symbol>] # rows in the table + # subscore_keys: Set[<subschema.key:Symbol>] # columns in the table + # headers: + # <subscore_key:Symbol>: <subscore.label:String> # headers for each subscore key for all tables. + + def outcome_tables_schema + # hash of tables, with the score keys (rows) and subscore keys (columns) used for each + tables = Hash.new{ |hash, key| hash[key] = {score_keys: Set.new, subscore_keys: Set.new } } + # hash of `subscore_key: subscore_label` pairs used in tables + headers = {} + + questionnaire.score_schemas.values.each do |schema| + schema.subscore_schemas.each do |subschema| + tables[subschema.outcome_table][:subscore_keys] << subschema.key + tables[subschema.outcome_table][:score_keys] << schema.key + headers[subschema.key] = subschema.label + end + end + + { + headers: headers, + tables: tables, + } + end end end end diff --git a/spec/quby/compiler/outputs/roqua_serializer_spec.rb b/spec/quby/compiler/outputs/roqua_serializer_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..44c57b024269265ef01aa80af1aeacd8ba260f9b --- /dev/null +++ b/spec/quby/compiler/outputs/roqua_serializer_spec.rb @@ -0,0 +1,53 @@ +require 'spec_helper' + +describe Quby::Compiler::Outputs::RoquaSerializer do + it 'generates outcome schemas' do + questionnaire = dsl("test") do + title "Test Quest" + + score_schema :score0, 'Score 0' do + # By default, scores end up in the :main table + subscore :something, 'Nog iets', export_key: :score0 do + 'Iets' + end + end + + score_schema :score1, 'Score 1' do + subscore :value, 'Waarde', export_key: :score1, outcome_table: :values do + 1 + end + subscore :int, 'Interpretatie', export_key: :score1_i, outcome_table: :values do + 'Wah' + end + end + + score_schema :score2, 'Score 2' do + subscore :value, 'Waarde', export_key: :score2, outcome_table: :values do + 2 + end + end + + score_schema :score3, 'Score 3' do + subscore :mean, 'Gemiddelde', export_key: :score3, outcome_table: :means do + 1 + end + end + end + serializer = described_class.new(questionnaire) + expect(serializer.as_json).to \ + include({ + outcome_tables_schema: { + headers: {int: "Interpretatie", mean: "Gemiddelde", something: "Nog iets", value: "Waarde"}, + tables: { + main: {:score_keys => [:score0], :subscore_keys => [:something]}, + values: {:score_keys => [:score1, :score2], :subscore_keys => [:value, :int]}, + means: {:score_keys => [:score3], :subscore_keys => [:mean]} + } + } + }) + end + + def dsl(key, &block) + Quby::Compiler::DSL.build(key, nil, &block) + end +end \ No newline at end of file