diff --git a/app/models/forms/export.rb b/app/models/forms/export.rb index 33a72bf287..bb592982fa 100644 --- a/app/models/forms/export.rb +++ b/app/models/forms/export.rb @@ -24,8 +24,9 @@ def to_csv # rubocop:disable Metrics/MethodLength, Metrics/BlockLength, Metrics/AbcSize, Metrics/PerceivedComplexity def to_xls # TODO - # Repeat groups with nested "begin/end repeat" and "begin/end group" lines - # skip logic with formatted info in "relevant" column using ${name} = ... syntax + # - Constraints + # - option set "levels"? + # - Make question types compatible with XLSForm, e.g., "long_text" should just be "text", "counter" does not exist, etc. book = Spreadsheet::Workbook.new @@ -35,7 +36,7 @@ def to_xls settings = book.create_worksheet(name: "settings") # Write sheet headings at row index 0 - questions.row(0).push("type", "name", "label", "required", "relevant") + questions.row(0).push("type", "name", "label", "required", "relevant", "constraint") choices.row(0).push("list_name", "name", "label") settings.row(0).push("form_title", "form_id", "version", "default_language") @@ -95,7 +96,63 @@ def to_xls code_to_push = "#{q.full_dotted_rank}_#{q.code}" # Write the question row - questions.row(i + index_mod).push(type_to_push, code_to_push, q.name, q.required.to_s, "TODO") + questions.row(i + index_mod).push(type_to_push, code_to_push, q.name, q.required.to_s) + end + + # if we have any relevant conditions, add them to the end of the row + if q.display_conditions.any? + # start building string of conditions to print + relevant_to_push = "" + concatenator = q.display_if == "all_met" ? "and" : "or" + + # how many conditions? + dc_length = q.display_conditions.length + + q.display_conditions.each_with_index do |dc, i| + # prep left side of expression + left_qing = Questioning.find(dc.left_qing_id) + left_to_push = "${#{left_qing.full_dotted_rank}_#{left_qing.code}}" + + # prep right side of expression + if dc.right_side_is_qing? + right_qing = Questioning.find(dc.right_qing_id) + right_to_push = "${#{right_qing.full_dotted_rank}_#{right_qing.code}}" + else + # to respect XLSform rules, surround with single quotes unless it's a number + if Float(dc.value, exception: false).nil? # it's not a number + right_to_push = "'#{dc.value}'" + else + right_to_push = "#{dc.value}" + end + end + + case dc.op + when "eq" + op = "=" + when "neq" + op = "!=" + when "lt" + op = "<" + when "leq" + op = "<=" + when "gt" + op = ">" + when "geq" + op = ">=" + end + + # omit the concatenator on the last condition only + if i + 1 == dc_length + relevant_to_push = "#{relevant_to_push}#{left_to_push} #{op} #{right_to_push}" + else + relevant_to_push = "#{relevant_to_push}#{left_to_push} #{op} #{right_to_push} #{concatenator} " + end + end + questions.row(i + index_mod).push(relevant_to_push) + end + + if q.constraints.any? + #TODO end end