From 6aef3f0900c735a75f8dc29668692a89949165c3 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Thu, 4 Nov 2021 13:30:20 +0000 Subject: [PATCH 01/55] JsonValidate_Initial --- app/helpers/json_schema_validation.rb | 88 +++++++++++++++++++++++++ spec/fixtures/forms/test_validator.json | 24 +++++++ 2 files changed, 112 insertions(+) create mode 100644 app/helpers/json_schema_validation.rb create mode 100644 spec/fixtures/forms/test_validator.json diff --git a/app/helpers/json_schema_validation.rb b/app/helpers/json_schema_validation.rb new file mode 100644 index 000000000..be0a4db3a --- /dev/null +++ b/app/helpers/json_schema_validation.rb @@ -0,0 +1,88 @@ +require "json-schema" +require "json" + +# "form_type": "lettings", +# "start_year": 2021, +# "end_year": 2022, +# "sections": { +# "about_this_log": { +# "label": "About this log", +# "subsections": { +# "about_this_log": { +# "label": "About this log", +# "pages": { + # "tenant_code": { + # "header": "", + # "description": "", + # "questions": { + # "tenant_code": { + # "check_answer_label": "Tenant code", + # "header": "What is the tenant code?", + # "hint_text": "", + # "type": "text" + # } + # } + # }, + +schema = { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://example.com/product.schema.json", + "title": "Form", + "description": "A form", + "type": "object", + "properties": { + "form_type": { + "description": "", + "type": "string" + }, + "start_year": { + "description": "", + "type": "int" + }, + "end_year": { + "description": "", + "type": "int" + }, + "sections": { + "description": "", + "type": "object", + "properties": { + "page_name": { + "description": "", + "type": "string" + }, + } + } + } +} + +begin + + # file = File.open("config/forms/2021_2022.json") + file = File.open("spec/fixtures/forms/test_validator.json") + data = JSON.parse(file.read) + + if JSON::Validator.validate!(schema, data) + puts "Success" + else + puts "Validation failed" + end + + begin + JSON::Validator.validate!(schema, data) + rescue JSON::Schema::ValidationError => e + e.message + end + + # def get_all_form_paths + # form_paths = [] + # directories = ["config/forms", "spec/fixtures/forms"] + # directories.each do |directory| + # Dir.glob("#{directory}/*.json").each do |form_path| + # form_path = form_path.sub(".json", "").split("/")[-1] + # form_paths.push(form_path) + # end + # end + # form_paths + # end +end diff --git a/spec/fixtures/forms/test_validator.json b/spec/fixtures/forms/test_validator.json new file mode 100644 index 000000000..2ac97e26d --- /dev/null +++ b/spec/fixtures/forms/test_validator.json @@ -0,0 +1,24 @@ +{ + "form_type": "lettings", + "sections": { + "household": { + "label": "About the household", + "subsections": { + "household_characteristics": { + "label": "Household characteristics", + "pages": { + "tenant_code": { + "questions": { + "tenant_code": { + "check_answer_label": "Tenant code", + "header": "What is the tenant code?", + "type": "text" + } + } + } + } + } + } + } + } +} From 6c272dad87defd5e3fe30958e9fb56188cf22f36 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Thu, 4 Nov 2021 15:51:01 +0000 Subject: [PATCH 02/55] can't find jsonspec --- app/helpers/json_schema_validation.rb | 63 ++++++++++++++------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/app/helpers/json_schema_validation.rb b/app/helpers/json_schema_validation.rb index be0a4db3a..777ffc39a 100644 --- a/app/helpers/json_schema_validation.rb +++ b/app/helpers/json_schema_validation.rb @@ -23,44 +23,45 @@ require "json" # } # } # }, +begin -schema = { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://example.com/product.schema.json", - "title": "Form", - "description": "A form", - "type": "object", - "properties": { - "form_type": { - "description": "", - "type": "string" - }, - "start_year": { - "description": "", - "type": "int" - }, - "end_year": { - "description": "", - "type": "int" - }, - "sections": { - "description": "", - "type": "object", - "properties": { - "page_name": { - "description": "", - "type": "string" - }, + schema = { + "$schema": "https://json-schema.org/draft-04/schema#", + "$id": "https://example.com/product.schema.json", + "title": "Form", + "description": "A form", + "type": "object", + "properties": { + "form_type": { + "description": "", + "type": "string" + }, + "start_year": { + "description": "", + "type": "int" + }, + "end_year": { + "description": "", + "type": "int" + }, + "sections": { + "description": "", + "type": "object", + "properties": { + "page_name": { + "description": "", + "type": "string" + }, + } } } } -} - -begin # file = File.open("config/forms/2021_2022.json") file = File.open("spec/fixtures/forms/test_validator.json") - data = JSON.parse(file.read) + puts data = JSON.parse(file.read) + + puts JSON::Validator.validate(schema, data) if JSON::Validator.validate!(schema, data) puts "Success" From a0d73baf6ab4b7ad9a35d66e49b3f3e750a995e8 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Fri, 5 Nov 2021 16:58:44 +0000 Subject: [PATCH 03/55] basic intial operation --- app/helpers/json_schema_validation.rb | 24 +++++++++++++----------- spec/fixtures/forms/test_validator.json | 2 ++ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/app/helpers/json_schema_validation.rb b/app/helpers/json_schema_validation.rb index 777ffc39a..dcb0c20a4 100644 --- a/app/helpers/json_schema_validation.rb +++ b/app/helpers/json_schema_validation.rb @@ -26,7 +26,7 @@ require "json" begin schema = { - "$schema": "https://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-04/schema", "$id": "https://example.com/product.schema.json", "title": "Form", "description": "A form", @@ -47,27 +47,29 @@ begin "sections": { "description": "", "type": "object", - "properties": { - "page_name": { + "patternProperties": { + "^[0-9]+$": { "description": "", "type": "string" }, + "label": { + "description": "", + "type": "string" + } } } } } - # file = File.open("config/forms/2021_2022.json") - file = File.open("spec/fixtures/forms/test_validator.json") - puts data = JSON.parse(file.read) + path = "spec/fixtures/forms/test_validator.json" + # path = "config/forms/2021_2022.json" + + file = File.open(path) + data = JSON.parse(file.read) puts JSON::Validator.validate(schema, data) - if JSON::Validator.validate!(schema, data) - puts "Success" - else - puts "Validation failed" - end + puts JSON::Validator.fully_validate(schema, data, :strict => true) begin JSON::Validator.validate!(schema, data) diff --git a/spec/fixtures/forms/test_validator.json b/spec/fixtures/forms/test_validator.json index 2ac97e26d..0539a719b 100644 --- a/spec/fixtures/forms/test_validator.json +++ b/spec/fixtures/forms/test_validator.json @@ -1,5 +1,7 @@ { "form_type": "lettings", + "start_year": 2021, + "end_year": 2022, "sections": { "household": { "label": "About the household", From ceb8ea03cb4d56f231441463781362e14eb9de2e Mon Sep 17 00:00:00 2001 From: magicmilo Date: Fri, 5 Nov 2021 17:06:13 +0000 Subject: [PATCH 04/55] and check schema --- app/helpers/json_schema_validation.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/helpers/json_schema_validation.rb b/app/helpers/json_schema_validation.rb index dcb0c20a4..4d947c450 100644 --- a/app/helpers/json_schema_validation.rb +++ b/app/helpers/json_schema_validation.rb @@ -55,12 +55,24 @@ begin "label": { "description": "", "type": "string" + }, + "subsections": { + "type": "object" } } } } } + metaschema = JSON::Validator.validator_for_name("draft4").metaschema + # => true + if JSON::Validator.validate(metaschema, schema) + puts "schema valid" + else + puts "schema not valid" + return + end + path = "spec/fixtures/forms/test_validator.json" # path = "config/forms/2021_2022.json" From 614851af34258c8d3496d8df6e8e50676a3d1bc2 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Sun, 7 Nov 2021 18:37:43 +0000 Subject: [PATCH 05/55] generated schema, is real 2021_2022 valid --- app/helpers/json_schema_validation.rb | 435 ++++++++++++++++++++---- spec/fixtures/forms/test_validator.json | 1 + 2 files changed, 375 insertions(+), 61 deletions(-) diff --git a/app/helpers/json_schema_validation.rb b/app/helpers/json_schema_validation.rb index 4d947c450..d500e018d 100644 --- a/app/helpers/json_schema_validation.rb +++ b/app/helpers/json_schema_validation.rb @@ -5,72 +5,385 @@ require "json" # "start_year": 2021, # "end_year": 2022, # "sections": { +# "about_this_log": { +# "label": "About this log", +# "subsections": { # "about_this_log": { # "label": "About this log", -# "subsections": { -# "about_this_log": { -# "label": "About this log", -# "pages": { - # "tenant_code": { - # "header": "", - # "description": "", - # "questions": { - # "tenant_code": { - # "check_answer_label": "Tenant code", - # "header": "What is the tenant code?", - # "hint_text": "", - # "type": "text" - # } - # } - # }, +# "pages": { + # "tenant_code": { + # "header": "", + # "description": "", + # "questions": { + # "tenant_code": { + # "check_answer_label": "Tenant code", + # "header": "What is the tenant code?", + # "hint_text": "", + # "type": "text" + # } + # } + # }, begin schema = { - "$schema": "http://json-schema.org/draft-04/schema", - "$id": "https://example.com/product.schema.json", - "title": "Form", - "description": "A form", - "type": "object", - "properties": { - "form_type": { - "description": "", - "type": "string" - }, - "start_year": { - "description": "", - "type": "int" - }, - "end_year": { - "description": "", - "type": "int" - }, + "$schema": "http://json-schema.org/draft-04/schema", + "$id": "http://example.com/example.json", + "type": "object", + "title": "The root schema", + "description": "The root schema comprises the entire JSON document.", + "default": {}, + "examples": [ + { + "form_type": "lettings", + "start_year": 2021, + "end_year": 2022, "sections": { - "description": "", - "type": "object", - "patternProperties": { - "^[0-9]+$": { - "description": "", - "type": "string" - }, - "label": { - "description": "", - "type": "string" - }, + "household": { + "label": "About the household", "subsections": { - "type": "object" + "household_characteristics": { + "label": "Household characteristics", + "pages": { + "tenant_code": { + "questions": { + "tenant_code": { + "check_answer_label": "Tenant code", + "header": "What is the tenant code?", + "type": "text" + } + } + } + } + } } } } } - } + ], + "required": [ + "form_type", + "start_year", + "end_year", + "sections" + ], + "properties": { + "form_type": { + "$id": "#/properties/form_type", + "type": "string", + "title": "The form_type schema", + "description": "An explanation about the purpose of this instance.", + "default": "", + "examples": [ + "lettings" + ] + }, + "start_year": { + "$id": "#/properties/start_year", + "type": "integer", + "title": "The start_year schema", + "description": "An explanation about the purpose of this instance.", + "default": 0, + "examples": [ + 2021 + ] + }, + "end_year": { + "$id": "#/properties/end_year", + "type": "integer", + "title": "The end_year schema", + "description": "An explanation about the purpose of this instance.", + "default": 0, + "examples": [ + 2022 + ] + }, + "sections": { + "$id": "#/properties/sections", + "type": "object", + "title": "The sections schema", + "description": "An explanation about the purpose of this instance.", + "default": {}, + "examples": [ + { + "household": { + "label": "About the household", + "subsections": { + "household_characteristics": { + "label": "Household characteristics", + "pages": { + "tenant_code": { + "questions": { + "tenant_code": { + "check_answer_label": "Tenant code", + "header": "What is the tenant code?", + "type": "text" + } + } + } + } + } + } + } + } + ], + "required": [ + "household" + ], + "properties": { + "household": { + "$id": "#/properties/sections/properties/household", + "type": "object", + "title": "The household schema", + "description": "An explanation about the purpose of this instance.", + "default": {}, + "examples": [ + { + "label": "About the household", + "subsections": { + "household_characteristics": { + "label": "Household characteristics", + "pages": { + "tenant_code": { + "questions": { + "tenant_code": { + "check_answer_label": "Tenant code", + "header": "What is the tenant code?", + "type": "text" + } + } + } + } + } + } + } + ], + "required": [ + "label", + "subsections" + ], + "properties": { + "label": { + "$id": "#/properties/sections/properties/household/properties/label", + "type": "string", + "title": "The label schema", + "description": "An explanation about the purpose of this instance.", + "default": "", + "examples": [ + "About the household" + ] + }, + "subsections": { + "$id": "#/properties/sections/properties/household/properties/subsections", + "type": "object", + "title": "The subsections schema", + "description": "An explanation about the purpose of this instance.", + "default": {}, + "examples": [ + { + "household_characteristics": { + "label": "Household characteristics", + "pages": { + "tenant_code": { + "questions": { + "tenant_code": { + "check_answer_label": "Tenant code", + "header": "What is the tenant code?", + "type": "text" + } + } + } + } + } + } + ], + "required": [ + "household_characteristics" + ], + "properties": { + "household_characteristics": { + "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics", + "type": "object", + "title": "The household_characteristics schema", + "description": "An explanation about the purpose of this instance.", + "default": {}, + "examples": [ + { + "label": "Household characteristics", + "pages": { + "tenant_code": { + "questions": { + "tenant_code": { + "check_answer_label": "Tenant code", + "header": "What is the tenant code?", + "type": "text" + } + } + } + } + } + ], + "required": [ + "label", + "pages" + ], + "properties": { + "label": { + "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics/properties/label", + "type": "string", + "title": "The label schema", + "description": "An explanation about the purpose of this instance.", + "default": "", + "examples": [ + "Household characteristics" + ] + }, + "pages": { + "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics/properties/pages", + "type": "object", + "title": "The pages schema", + "description": "An explanation about the purpose of this instance.", + "default": {}, + "examples": [ + { + "tenant_code": { + "questions": { + "tenant_code": { + "check_answer_label": "Tenant code", + "header": "What is the tenant code?", + "type": "text" + } + } + } + } + ], + "required": [ + "tenant_code" + ], + "properties": { + "tenant_code": { + "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics/properties/pages/properties/tenant_code", + "type": "object", + "title": "The tenant_code schema", + "description": "An explanation about the purpose of this instance.", + "default": {}, + "examples": [ + { + "questions": { + "tenant_code": { + "check_answer_label": "Tenant code", + "header": "What is the tenant code?", + "type": "text" + } + } + } + ], + "required": [ + "questions" + ], + "properties": { + "questions": { + "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics/properties/pages/properties/tenant_code/properties/questions", + "type": "object", + "title": "The questions schema", + "description": "An explanation about the purpose of this instance.", + "default": {}, + "examples": [ + { + "tenant_code": { + "check_answer_label": "Tenant code", + "header": "What is the tenant code?", + "type": "text" + } + } + ], + "required": [ + "tenant_code" + ], + "properties": { + "tenant_code": { + "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics/properties/pages/properties/tenant_code/properties/questions/properties/tenant_code", + "type": "object", + "title": "The tenant_code schema", + "description": "An explanation about the purpose of this instance.", + "default": {}, + "examples": [ + { + "check_answer_label": "Tenant code", + "header": "What is the tenant code?", + "type": "text" + } + ], + "required": [ + "check_answer_label", + "header", + "type" + ], + "properties": { + "check_answer_label": { + "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics/properties/pages/properties/tenant_code/properties/questions/properties/tenant_code/properties/check_answer_label", + "type": "string", + "title": "The check_answer_label schema", + "description": "An explanation about the purpose of this instance.", + "default": "", + "examples": [ + "Tenant code" + ] + }, + "header": { + "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics/properties/pages/properties/tenant_code/properties/questions/properties/tenant_code/properties/header", + "type": "string", + "title": "The header schema", + "description": "An explanation about the purpose of this instance.", + "default": "", + "examples": [ + "What is the tenant code?" + ] + }, + "type": { + "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics/properties/pages/properties/tenant_code/properties/questions/properties/tenant_code/properties/type", + "type": "string", + "title": "The type schema", + "description": "An explanation about the purpose of this instance.", + "default": "", + "examples": [ + "text" + ] + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true +} metaschema = JSON::Validator.validator_for_name("draft4").metaschema - # => true + if JSON::Validator.validate(metaschema, schema) - puts "schema valid" + puts "schema valid" else - puts "schema not valid" - return + puts "schema not valid" + return end path = "spec/fixtures/forms/test_validator.json" @@ -84,20 +397,20 @@ begin puts JSON::Validator.fully_validate(schema, data, :strict => true) begin - JSON::Validator.validate!(schema, data) + JSON::Validator.validate!(schema, data) rescue JSON::Schema::ValidationError => e - e.message + e.message end # def get_all_form_paths - # form_paths = [] - # directories = ["config/forms", "spec/fixtures/forms"] - # directories.each do |directory| - # Dir.glob("#{directory}/*.json").each do |form_path| - # form_path = form_path.sub(".json", "").split("/")[-1] - # form_paths.push(form_path) - # end + # form_paths = [] + # directories = ["config/forms", "spec/fixtures/forms"] + # directories.each do |directory| + # Dir.glob("#{directory}/*.json").each do |form_path| + # form_path = form_path.sub(".json", "").split("/")[-1] + # form_paths.push(form_path) # end - # form_paths + # end + # form_paths # end end diff --git a/spec/fixtures/forms/test_validator.json b/spec/fixtures/forms/test_validator.json index 0539a719b..13aed9e5f 100644 --- a/spec/fixtures/forms/test_validator.json +++ b/spec/fixtures/forms/test_validator.json @@ -8,6 +8,7 @@ "subsections": { "household_characteristics": { "label": "Household characteristics", + "baddata": "Shouldn't be here but what you gonna do?", "pages": { "tenant_code": { "questions": { From cf6e5a099462ce89ae602cce49944f9555ae96c8 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Sun, 7 Nov 2021 19:20:46 +0000 Subject: [PATCH 06/55] move about --- app/helpers/json_schema_validation.rb | 414 +---- config/forms/schema/2021_2022.json | 2134 +++++++++++++++++++++++++ config/forms/schema/generic.json | 38 + 3 files changed, 2206 insertions(+), 380 deletions(-) create mode 100644 config/forms/schema/2021_2022.json create mode 100644 config/forms/schema/generic.json diff --git a/app/helpers/json_schema_validation.rb b/app/helpers/json_schema_validation.rb index d500e018d..3e46be8e0 100644 --- a/app/helpers/json_schema_validation.rb +++ b/app/helpers/json_schema_validation.rb @@ -5,385 +5,39 @@ require "json" # "start_year": 2021, # "end_year": 2022, # "sections": { -# "about_this_log": { -# "label": "About this log", -# "subsections": { # "about_this_log": { # "label": "About this log", -# "pages": { - # "tenant_code": { - # "header": "", - # "description": "", - # "questions": { - # "tenant_code": { - # "check_answer_label": "Tenant code", - # "header": "What is the tenant code?", - # "hint_text": "", - # "type": "text" - # } - # } - # }, +# "subsections": { +# "about_this_log": { +# "label": "About this log", +# "pages": { + # "tenant_code": { + # "header": "", + # "description": "", + # "questions": { + # "tenant_code": { + # "check_answer_label": "Tenant code", + # "header": "What is the tenant code?", + # "hint_text": "", + # "type": "text" + # } + # } + # }, begin - schema = { - "$schema": "http://json-schema.org/draft-04/schema", - "$id": "http://example.com/example.json", - "type": "object", - "title": "The root schema", - "description": "The root schema comprises the entire JSON document.", - "default": {}, - "examples": [ - { - "form_type": "lettings", - "start_year": 2021, - "end_year": 2022, - "sections": { - "household": { - "label": "About the household", - "subsections": { - "household_characteristics": { - "label": "Household characteristics", - "pages": { - "tenant_code": { - "questions": { - "tenant_code": { - "check_answer_label": "Tenant code", - "header": "What is the tenant code?", - "type": "text" - } - } - } - } - } - } - } - } - } - ], - "required": [ - "form_type", - "start_year", - "end_year", - "sections" - ], - "properties": { - "form_type": { - "$id": "#/properties/form_type", - "type": "string", - "title": "The form_type schema", - "description": "An explanation about the purpose of this instance.", - "default": "", - "examples": [ - "lettings" - ] - }, - "start_year": { - "$id": "#/properties/start_year", - "type": "integer", - "title": "The start_year schema", - "description": "An explanation about the purpose of this instance.", - "default": 0, - "examples": [ - 2021 - ] - }, - "end_year": { - "$id": "#/properties/end_year", - "type": "integer", - "title": "The end_year schema", - "description": "An explanation about the purpose of this instance.", - "default": 0, - "examples": [ - 2022 - ] - }, - "sections": { - "$id": "#/properties/sections", - "type": "object", - "title": "The sections schema", - "description": "An explanation about the purpose of this instance.", - "default": {}, - "examples": [ - { - "household": { - "label": "About the household", - "subsections": { - "household_characteristics": { - "label": "Household characteristics", - "pages": { - "tenant_code": { - "questions": { - "tenant_code": { - "check_answer_label": "Tenant code", - "header": "What is the tenant code?", - "type": "text" - } - } - } - } - } - } - } - } - ], - "required": [ - "household" - ], - "properties": { - "household": { - "$id": "#/properties/sections/properties/household", - "type": "object", - "title": "The household schema", - "description": "An explanation about the purpose of this instance.", - "default": {}, - "examples": [ - { - "label": "About the household", - "subsections": { - "household_characteristics": { - "label": "Household characteristics", - "pages": { - "tenant_code": { - "questions": { - "tenant_code": { - "check_answer_label": "Tenant code", - "header": "What is the tenant code?", - "type": "text" - } - } - } - } - } - } - } - ], - "required": [ - "label", - "subsections" - ], - "properties": { - "label": { - "$id": "#/properties/sections/properties/household/properties/label", - "type": "string", - "title": "The label schema", - "description": "An explanation about the purpose of this instance.", - "default": "", - "examples": [ - "About the household" - ] - }, - "subsections": { - "$id": "#/properties/sections/properties/household/properties/subsections", - "type": "object", - "title": "The subsections schema", - "description": "An explanation about the purpose of this instance.", - "default": {}, - "examples": [ - { - "household_characteristics": { - "label": "Household characteristics", - "pages": { - "tenant_code": { - "questions": { - "tenant_code": { - "check_answer_label": "Tenant code", - "header": "What is the tenant code?", - "type": "text" - } - } - } - } - } - } - ], - "required": [ - "household_characteristics" - ], - "properties": { - "household_characteristics": { - "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics", - "type": "object", - "title": "The household_characteristics schema", - "description": "An explanation about the purpose of this instance.", - "default": {}, - "examples": [ - { - "label": "Household characteristics", - "pages": { - "tenant_code": { - "questions": { - "tenant_code": { - "check_answer_label": "Tenant code", - "header": "What is the tenant code?", - "type": "text" - } - } - } - } - } - ], - "required": [ - "label", - "pages" - ], - "properties": { - "label": { - "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics/properties/label", - "type": "string", - "title": "The label schema", - "description": "An explanation about the purpose of this instance.", - "default": "", - "examples": [ - "Household characteristics" - ] - }, - "pages": { - "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics/properties/pages", - "type": "object", - "title": "The pages schema", - "description": "An explanation about the purpose of this instance.", - "default": {}, - "examples": [ - { - "tenant_code": { - "questions": { - "tenant_code": { - "check_answer_label": "Tenant code", - "header": "What is the tenant code?", - "type": "text" - } - } - } - } - ], - "required": [ - "tenant_code" - ], - "properties": { - "tenant_code": { - "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics/properties/pages/properties/tenant_code", - "type": "object", - "title": "The tenant_code schema", - "description": "An explanation about the purpose of this instance.", - "default": {}, - "examples": [ - { - "questions": { - "tenant_code": { - "check_answer_label": "Tenant code", - "header": "What is the tenant code?", - "type": "text" - } - } - } - ], - "required": [ - "questions" - ], - "properties": { - "questions": { - "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics/properties/pages/properties/tenant_code/properties/questions", - "type": "object", - "title": "The questions schema", - "description": "An explanation about the purpose of this instance.", - "default": {}, - "examples": [ - { - "tenant_code": { - "check_answer_label": "Tenant code", - "header": "What is the tenant code?", - "type": "text" - } - } - ], - "required": [ - "tenant_code" - ], - "properties": { - "tenant_code": { - "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics/properties/pages/properties/tenant_code/properties/questions/properties/tenant_code", - "type": "object", - "title": "The tenant_code schema", - "description": "An explanation about the purpose of this instance.", - "default": {}, - "examples": [ - { - "check_answer_label": "Tenant code", - "header": "What is the tenant code?", - "type": "text" - } - ], - "required": [ - "check_answer_label", - "header", - "type" - ], - "properties": { - "check_answer_label": { - "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics/properties/pages/properties/tenant_code/properties/questions/properties/tenant_code/properties/check_answer_label", - "type": "string", - "title": "The check_answer_label schema", - "description": "An explanation about the purpose of this instance.", - "default": "", - "examples": [ - "Tenant code" - ] - }, - "header": { - "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics/properties/pages/properties/tenant_code/properties/questions/properties/tenant_code/properties/header", - "type": "string", - "title": "The header schema", - "description": "An explanation about the purpose of this instance.", - "default": "", - "examples": [ - "What is the tenant code?" - ] - }, - "type": { - "$id": "#/properties/sections/properties/household/properties/subsections/properties/household_characteristics/properties/pages/properties/tenant_code/properties/questions/properties/tenant_code/properties/type", - "type": "string", - "title": "The type schema", - "description": "An explanation about the purpose of this instance.", - "default": "", - "examples": [ - "text" - ] - } - }, - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "additionalProperties": true -} + path = "config/forms/schema/generic.json" + # path = "config/forms/schema/2021_2022.json" + + file = File.open(path) + schema = JSON.parse(file.read) metaschema = JSON::Validator.validator_for_name("draft4").metaschema if JSON::Validator.validate(metaschema, schema) - puts "schema valid" + puts "schema valid" else - puts "schema not valid" - return + puts "schema not valid" + return end path = "spec/fixtures/forms/test_validator.json" @@ -397,20 +51,20 @@ begin puts JSON::Validator.fully_validate(schema, data, :strict => true) begin - JSON::Validator.validate!(schema, data) + JSON::Validator.validate!(schema, data) rescue JSON::Schema::ValidationError => e - e.message + e.message end # def get_all_form_paths - # form_paths = [] - # directories = ["config/forms", "spec/fixtures/forms"] - # directories.each do |directory| - # Dir.glob("#{directory}/*.json").each do |form_path| - # form_path = form_path.sub(".json", "").split("/")[-1] - # form_paths.push(form_path) + # form_paths = [] + # directories = ["config/forms", "spec/fixtures/forms"] + # directories.each do |directory| + # Dir.glob("#{directory}/*.json").each do |form_path| + # form_path = form_path.sub(".json", "").split("/")[-1] + # form_paths.push(form_path) + # end # end - # end - # form_paths + # form_paths # end end diff --git a/config/forms/schema/2021_2022.json b/config/forms/schema/2021_2022.json new file mode 100644 index 000000000..2a825ffb8 --- /dev/null +++ b/config/forms/schema/2021_2022.json @@ -0,0 +1,2134 @@ +{ + "form_type": "lettings", + "start_year": 2021, + "end_year": 2022, + "sections": { + "household": { + "label": "About the household", + "subsections": { + "household_characteristics": { + "label": "Household characteristics", + "pages": { + "tenant_code": { + "header": "", + "description": "", + "questions": { + "tenant_code": { + "check_answer_label": "Tenant code", + "header": "What is the tenant code?", + "hint_text": "", + "type": "text" + } + } + }, + "person_1_age": { + "header": "", + "description": "", + "questions": { + "person_1_age": { + "check_answer_label": "Tenant's age", + "header": "What is the tenant's age?", + "hint_text": "", + "type": "numeric", + "min": 0, + "max": 120, + "step": 1 + } + } + }, + "person_1_gender": { + "header": "", + "description": "", + "questions": { + "person_1_gender": { + "check_answer_label": "Tenant's gender", + "header": "Which of these best describes the tenant's gender identity?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Female", + "1": "Male", + "2": "Non-binary", + "3": "Prefer not to say" + } + } + } + }, + "tenant_ethnic_group": { + "header": "", + "description": "", + "questions": { + "tenant_ethnic_group": { + "check_answer_label": "Ethnicity", + "header": "What is the tenant's ethnic group?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "White: English/Scottish/Welsh/Northern Irish/British", + "1": "White: Irish", + "2": "White: Gypsy/Irish Traveller", + "3": "White: Other", + "4": "Mixed: White & Black Caribbean", + "5": "Mixed: White & Black African", + "6": "Mixed: White & Asian", + "7": "Mixed: Other", + "8": "Asian or Asian British: Indian", + "9": "Asian or Asian British: Pakistani", + "10": "Asian or Asian British: Bangladeshi", + "11": "Asian or Asian British: Chinese", + "12": "Asian or Asian British: Other", + "13": "Black: Caribbean", + "14": "Black: African", + "15": "Black: Other", + "16": "Other Ethnic Group: Arab", + "17": "Other Ethnic Group: Other", + "18": "Prefer not to say" + } + } + } + }, + "tenant_nationality": { + "header": "", + "description": "", + "questions": { + "tenant_nationality": { + "check_answer_label": "Nationality", + "header": "What is the tenant's nationality?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "UK national resident in UK", + "1": "A current or former reserve in the UK Armed Forces (exc. National Service)", + "2": "UK national returning from residence overseas", + "3": "Czech Republic", + "4": "Estonia", + "5": "Hungary", + "6": "Latvia", + "7": "Lithuania", + "8": "Poland", + "9": "Slovakia", + "10": "Bulgaria", + "11": "Romania", + "12": "Ireland", + "13": "Other EU Economic Area (EEA country)", + "14": "Any other country", + "15": "Prefer not to say" + } + } + } + }, + "tenant_economic_status": { + "header": "", + "description": "", + "questions": { + "person_1_economic_status": { + "check_answer_label": "Work", + "header": "Which of these best describes the tenant's working situation?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Part-time - Less than 30 hours", + "1": "Full-time - 30 hours or more", + "2": "In government training into work, such as New Deal", + "3": "Jobseeker", + "4": "Retired", + "5": "Not seeking work", + "6": "Full-time student", + "7": "Unable to work because of long term sick or disability", + "8": "Child under 16", + "9": "Other", + "10": "Prefer not to say" + } + } + } + }, + "household_number_of_other_members": { + "header": "", + "description": "", + "questions": { + "household_number_of_other_members": { + "check_answer_label": "Number of Other Household Members", + "header": "How many other people are there in the household?", + "hint_text": "The maximum number of others is 7", + "type": "numeric", + "min": 0, + "max": 7, + "step": 1, + "conditional_for": { + "person_2_relationship": ">0", + "person_2_age": ">0", + "person_2_gender": ">0", + "person_2_economic_status": ">0", + "person_3_relationship": ">1", + "person_3_age": ">1", + "person_3_gender": ">1", + "person_3_economic_status": ">1", + "person_4_relationship": ">2", + "person_4_age": ">2", + "person_4_gender": ">2", + "person_4_economic_status": ">2", + "person_5_relationship": ">3", + "person_5_age": ">3", + "person_5_gender": ">3", + "person_5_economic_status": ">3", + "person_6_relationship": ">4", + "person_6_age": ">4", + "person_6_gender": ">4", + "person_6_economic_status": ">4", + "person_7_relationship": ">5", + "person_7_age": ">5", + "person_7_gender": ">5", + "person_7_economic_status": ">5", + "person_8_relationship": ">6", + "person_8_age": ">6", + "person_8_gender": ">6", + "person_8_economic_status": ">6" + } + }, + "person_2_relationship": { + "check_answer_label": "Person 2's relationship to lead tenant", + "header": "What's person 2's relationship to lead tenant", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Partner", + "1": "Child - includes young adult and grown-up", + "2": "Other", + "3": "Prefer not to say" + } + }, + "person_2_age": { + "check_answer_label": "Person 2's age", + "header": "What's person 2's age", + "hint_text": "", + "type": "numeric", + "min": 0, + "max": 150, + "step": 1 + }, + "person_2_gender": { + "check_answer_label": "Person 2's gender", + "header": "Which of these best describes person 2's gender identity?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Female", + "1": "Male", + "2": "Non-binary", + "3": "Prefer not to say" + } + }, + "person_2_economic_status": { + "check_answer_label": "Person 2's Work", + "header": "Which of these best describes person 2's working situation?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Part-time - Less than 30 hours", + "1": "Full-time - 30 hours or more", + "2": "In government training into work, such as New Deal", + "3": "Jobseeker", + "4": "Retired", + "5": "Not seeking work", + "6": "Full-time student", + "7": "Unable to work because of long term sick or disability", + "8": "Child under 16", + "9": "Other", + "10": "Prefer not to say" + } + }, + "person_3_relationship": { + "check_answer_label": "Person 3's relationship to lead tenant", + "header": "What's person 3's relationship to lead tenant", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Partner", + "1": "Child - includes young adult and grown-up", + "2": "Other", + "3": "Prefer not to say" + } + }, + "person_3_age": { + "check_answer_label": "Person 3's age", + "header": "What's person 3's age", + "hint_text": "", + "type": "numeric", + "min": 0, + "max": 150, + "step": 1 + }, + "person_3_gender": { + "check_answer_label": "Person 3's gender", + "header": "Which of these best describes person 3's gender identity?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Female", + "1": "Male", + "2": "Non-binary", + "3": "Prefer not to say" + } + }, + "person_3_economic_status": { + "check_answer_label": "Person 3's Work", + "header": "Which of these best describes person 3's working situation?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Part-time - Less than 30 hours", + "1": "Full-time - 30 hours or more", + "2": "In government training into work, such as New Deal", + "3": "Jobseeker", + "4": "Retired", + "5": "Not seeking work", + "6": "Full-time student", + "7": "Unable to work because of long term sick or disability", + "8": "Child under 16", + "9": "Other", + "10": "Prefer not to say" + } + }, + "person_4_relationship": { + "check_answer_label": "Person 4's relationship to lead tenant", + "header": "What's person 4's relationship to lead tenant", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Partner", + "1": "Child - includes young adult and grown-up", + "2": "Other", + "3": "Prefer not to say" + } + }, + "person_4_age": { + "check_answer_label": "Person 4's age", + "header": "What's person 4's age", + "hint_text": "", + "type": "numeric", + "min": 0, + "max": 150, + "step": 1 + }, + "person_4_gender": { + "check_answer_label": "Person 4's gender", + "header": "Which of these best describes person 4's gender identity?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Female", + "1": "Male", + "2": "Non-binary", + "3": "Prefer not to say" + } + }, + "person_4_economic_status": { + "check_answer_label": "Person 4's Work", + "header": "Which of these best describes person 4's working situation?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Part-time - Less than 30 hours", + "1": "Full-time - 30 hours or more", + "2": "In government training into work, such as New Deal", + "3": "Jobseeker", + "4": "Retired", + "5": "Not seeking work", + "6": "Full-time student", + "7": "Unable to work because of long term sick or disability", + "8": "Child under 16", + "9": "Other", + "10": "Prefer not to say" + } + }, + "person_5_relationship": { + "check_answer_label": "Person 5's relationship to lead tenant", + "header": "What's person 5's relationship to lead tenant", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Partner", + "1": "Child - includes young adult and grown-up", + "2": "Other", + "3": "Prefer not to say" + } + }, + "person_5_age": { + "check_answer_label": "Person 5's age", + "header": "What's person 5's age", + "hint_text": "", + "type": "numeric", + "min": 0, + "max": 150, + "step": 1 + }, + "person_5_gender": { + "check_answer_label": "Person 5's gender", + "header": "Which of these best describes person 5's gender identity?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Female", + "1": "Male", + "2": "Non-binary", + "3": "Prefer not to say" + } + }, + "person_5_economic_status": { + "check_answer_label": "Person 5's Work", + "header": "Which of these best describes person 5's working situation?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Part-time - Less than 30 hours", + "1": "Full-time - 30 hours or more", + "2": "In government training into work, such as New Deal", + "3": "Jobseeker", + "4": "Retired", + "5": "Not seeking work", + "6": "Full-time student", + "7": "Unable to work because of long term sick or disability", + "8": "Child under 16", + "9": "Other", + "10": "Prefer not to say" + } + }, + "person_6_relationship": { + "check_answer_label": "Person 6's relationship to lead tenant", + "header": "What's person 6's relationship to lead tenant", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Partner", + "1": "Child - includes young adult and grown-up", + "2": "Other", + "3": "Prefer not to say" + } + }, + "person_6_age": { + "check_answer_label": "Person 6's age", + "header": "What's person 6's age", + "hint_text": "", + "type": "numeric", + "min": 0, + "max": 150, + "step": 1 + }, + "person_6_gender": { + "check_answer_label": "Person 6's gender", + "header": "Which of these best describes person 6's gender identity?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Female", + "1": "Male", + "2": "Non-binary", + "3": "Prefer not to say" + } + }, + "person_6_economic_status": { + "check_answer_label": "Person 6's Work", + "header": "Which of these best describes person 6's working situation?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Part-time - Less than 30 hours", + "1": "Full-time - 30 hours or more", + "2": "In government training into work, such as New Deal", + "3": "Jobseeker", + "4": "Retired", + "5": "Not seeking work", + "6": "Full-time student", + "7": "Unable to work because of long term sick or disability", + "8": "Child under 16", + "9": "Other", + "10": "Prefer not to say" + } + }, + "person_7_relationship": { + "check_answer_label": "Person 7's relationship to lead tenant", + "header": "What's person 7's relationship to lead tenant", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Partner", + "1": "Child - includes young adult and grown-up", + "2": "Other", + "3": "Prefer not to say" + } + }, + "person_7_age": { + "check_answer_label": "Person 7's age", + "header": "What's person 7's age", + "hint_text": "", + "type": "numeric", + "min": 0, + "max": 150, + "step": 1 + }, + "person_7_gender": { + "check_answer_label": "Person 7's gender", + "header": "Which of these best describes person 7's gender identity?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Female", + "1": "Male", + "2": "Non-binary", + "3": "Prefer not to say" + } + }, + "person_7_economic_status": { + "check_answer_label": "Person 7's Work", + "header": "Which of these best describes person 7's working situation?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Part-time - Less than 30 hours", + "1": "Full-time - 30 hours or more", + "2": "In government training into work, such as New Deal", + "3": "Jobseeker", + "4": "Retired", + "5": "Not seeking work", + "6": "Full-time student", + "7": "Unable to work because of long term sick or disability", + "8": "Child under 16", + "9": "Other", + "10": "Prefer not to say" + } + }, + "person_8_relationship": { + "check_answer_label": "Person 8's relationship to lead tenant", + "header": "What's person 8's relationship to lead tenant", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Partner", + "1": "Child - includes young adult and grown-up", + "2": "Other", + "3": "Prefer not to say" + } + }, + "person_8_age": { + "check_answer_label": "Person 8's age", + "header": "What's person 8's age", + "hint_text": "", + "type": "numeric", + "min": 0, + "max": 150, + "step": 1 + }, + "person_8_gender": { + "check_answer_label": "Person 8's gender", + "header": "Which of these best describes person 8's gender identity?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Female", + "1": "Male", + "2": "Non-binary", + "3": "Prefer not to say" + } + }, + "person_8_economic_status": { + "check_answer_label": "Person 8's Work", + "header": "Which of these best describes person 8's working situation?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Part-time - Less than 30 hours", + "1": "Full-time - 30 hours or more", + "2": "In government training into work, such as New Deal", + "3": "Jobseeker", + "4": "Retired", + "5": "Not seeking work", + "6": "Full-time student", + "7": "Unable to work because of long term sick or disability", + "8": "Child under 16", + "9": "Other", + "10": "Prefer not to say" + } + } + } + } + } + }, + "household_situation": { + "label": "Household situation", + "pages": { + "previous_housing_situation": { + "header": "", + "description": "", + "questions": { + "previous_housing_situation": { + "header": "What was the tenant’s housing situation immediately before this letting?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Owner occupation (private) ", + "1": "Owner occupation (low cost home ownership)", + "2": "Private sector tenancy", + "3": "Tied housing or rented with job", + "4": "Supported housing", + "5": "Sheltered accomodation", + "6": "Residential care home", + "7": "Living with friends or family", + "8": "Refuge", + "9": "Hospital", + "10": "Prison / approved probation hostel", + "11": "Direct access hostel", + "12": "Bed & Breakfast", + "13": "Mobile home / caravan", + "14": "Any other temporary accommodation", + "15": "Home Office Asylum Support", + "16": "Children’s home / foster care", + "17": "Rough sleeping", + "18": "Other", + "19": "Fixed term Local Authority General Needs tenancy", + "20": "Lifetime Local Authority General Needs tenancy", + "21": "Fixed term PRP General Needs tenancy", + "22": "Lifetime PRP General Needs tenancy" + } + } + } + }, + "homelessness": { + "header": "", + "description": "", + "questions": { + "homelessness": { + "header": "Did the tenant experience homelessness immediately before this letting?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Yes - assessed as homeless by a local authority and owed a homelessness duty. Including if threatened with homelessness within 56 days", + "1": "Yes - other homelessness ", + "2": "No" + } + } + } + }, + "reason_for_leaving_last_settled_home": { + "header": "Leaving their last settled home", + "description": "", + "questions": { + "reason_for_leaving_last_settled_home": { + "header": "What is the tenant’s main reason for leaving?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Permanently decanted from another property owned by this landlord", + "1": "Left home country as a refugee", + "2": "Loss of tied accommodation", + "3": "Domestic abuse", + "4": "(Non violent) relationship breakdown with partner", + "5": "Asked to leave by family or friends", + "6": "Racial harassment", + "7": "Other problems with neighbours", + "8": "Property unsuitable because of overcrowding", + "9": "End of assured shorthold tenancy - no fault", + "10": "End of assured shorthold tenancy - tenant's fault", + "11": "End of fixed term tenancy - no fault", + "12": "End of fixed term tenancy - tenant's fault", + "13": "Repossession", + "14": "Under occupation - offered incentive to downsize", + "15": "Under occupation - no incentive", + "16": "Property unsuitable because of ill health / disability", + "17": "Property unsuitable because of poor condition", + "18": "Couldn't afford fees attached to renewing the tenancy", + "19": "Couldn't afford increase in rent", + "20": "Couldn't afford rent or mortgage - welfare reforms", + "21": "Couldn't afford rent or mortgage - employment", + "22": "Couldn't afford rent or mortgage - other", + "23": "To move nearer to family / friends / school", + "24": "To move nearer to work", + "25": "To move to accomodation with support", + "26": "To move to independent accomodation", + "27": "Hate crime", + "28": "Death of household member in last settled accomodation", + "29": "Discharged from prison", + "30": "Discharged from long stay hospital or similar institution", + "31": "Other", + "32": "Do not know", + "33": "Prefer not to say" + }, + "conditional_for": { + "other_reason_for_leaving_last_settled_home": ["Other"] + } + }, + "other_reason_for_leaving_last_settled_home": { + "header": "Please state the reason for leaving last settled home", + "hint_text": "", + "type": "text" + }, + "benefit_cap_spare_room_subsidy": { + "header": "Was the reason for leaving because of the benefit cap or removal of the spare room subsidy?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Yes - benefit cap", + "1": "Yes - removal of the spare room subsidy", + "2": "Yes - both the benefit cap and the removal of the spare room subsidy", + "3": "No", + "4": "Do not know", + "5": "Prefer not to say" + } + } + } + } + } + }, + "household_needs": { + "label": "Household needs", + "pages": { + "armed_forces": { + "header": "Experience of the UK Armed Forces", + "description": "", + "questions": { + "armed_forces": { + "header": "Has the tenant ever served in the UK armed forces?", + "hint_text": "", + "type": "radio", + "check_answer_label": "Armed Forces", + "answer_options": { + "0": "Yes - a regular", + "1": "Yes - a reserve", + "2": "No", + "3": "Prefer not to say" + }, + "conditional_for": { + "armed_forces_active": ["Yes - a regular", "Yes - a reserve"], + "armed_forces_injured": ["Yes - a regular", "Yes - a reserve"] + } + }, + "armed_forces_active": { + "header": "Are they still serving?", + "hint_text": "", + "type": "radio", + "check_answer_label": "When did they leave the Armed Forces?", + "answer_options": { + "0": "Yes", + "1": "No - they left up to 5 years ago", + "2": "No - they left more than 5 years ago", + "3": "Prefer not to say" + } + }, + "armed_forces_injured": { + "header": "Were they seriously injured or ill as a result of their service?", + "hint_text": "", + "type": "radio", + "check_answer_label": "Has anyone in the household been seriously injured or ill as a result of their service in the armed forces?", + "answer_options": { + "0": "Yes", + "1": "No", + "2": "Prefer not to say" + } + }, + "armed_forces_partner": { + "header": "Was the tenant the spouse or civil partner of someone who served in the UK armed forces?", + "hint_text": "", + "type": "radio", + "check_answer_label": "Was the tenant the spouse or civil partner of someone who served in the UK armed forces?", + "answer_options": { + "0": "Yes - was the spouse or civil partner of a UK Armed Forces member and have separated within the last 2 years", + "1": "Yes - was the spouse or civil partner of a UK Armed Forces member who died within the last 2 years", + "2": "No", + "3": "Prefer not to say" + } + } + } + }, + "medical_conditions": { + "header": "", + "description": "", + "questions": { + "medical_conditions": { + "header": "Does anyone in the household have any of the following that they expect to last for 12 months or more:
  • Physical Condition
  • Mental Health Condition
  • Other Illness
", + "hint_text": "", + "type": "radio", + "check_answer_label": "Physical, mental health or illness in the household", + "answer_options": { + "0": "Yes", + "1": "No", + "2": "Do not know", + "3": "Prefer not to say" + } + } + } + }, + "pregnancy": { + "header": "", + "description": "", + "questions": { + "pregnancy": { + "header": "Is anyone in the household pregnant?", + "hint_text": "", + "type": "radio", + "check_answer_label": "Pregnancy in the household", + "answer_options": { + "0": "Yes", + "1": "No", + "2": "Prefer not to say" + } + } + } + }, + "accessibility_requirements": { + "header": "", + "description": "", + "questions": { + "accessibility_requirements": { + "header": "Are any of these affected by their condition or illness?", + "hint_text": "Select all that apply", + "type": "checkbox", + "check_answer_label": "Disability requirements", + "answer_options": { + "accessibility_requirements_fully_wheelchair_accessible_housing": "Fully wheelchair accessible housing", + "accessibility_requirements_wheelchair_access_to_essential_rooms": "Wheelchair access to essential rooms", + "accessibility_requirements_level_access_housing": "Level access housing", + "accessibility_requirements_other_disability_requirements": "Other disability requirements", + "accessibility_requirements_no_disability_requirements": "No disability requirements", + "divider_a": true, + "accessibility_requirements_do_not_know": "Do not know", + "divider_b": true, + "accessibility_requirements_prefer_not_to_say": "Prefer not to say" + } + } + } + }, + "condition_effects": { + "header": "", + "description": "", + "questions": { + "condition_effects": { + "header": "Are any of these affected by their condition or illness?", + "hint_text": "Select all that apply", + "type": "checkbox", + "check_answer_label": "Conditions or illnesses", + "answer_options": { + "condition_effects_vision": "Vision - such as blindness or partial sight", + "condition_effects_hearing": "Hearing - such as deafness or partial hearing", + "condition_effects_mobility": "Mobility - such as walking short distances or climbing stairs", + "condition_effects_dexterity": "Dexterity - such as lifting and carrying objects or using a keyboard", + "condition_effects_stamina": "Stamina or breathing or fatigue", + "condition_effects_learning": "Learning or understanding or concentrating", + "condition_effects_memory": "Memory", + "condition_effects_mental_health": "Mental health - such as depression, anxiety, schizophrenia or bipolar", + "condition_effects_social_or_behavioral": "Socially or behaviourally - such as those associated with autism spectral disorder (ASD) including Aspergers’ or attention deficit hyperactivity disorder (ADHD))", + "condition_effects_other": "Other", + "divider": true, + "condition_effects_prefer_not_to_say": "Prefer not to say" + } + } + } + } + } + } + } + }, + "tenancy_and_property": { + "label": "Tenancy and property information", + "subsections": { + "tenancy_information": { + "label": "Tenancy information", + "pages": { + "tenancy_code": { + "header": "", + "description": "", + "questions": { + "tenancy_code": { + "check_answer_label": "What is the tenancy code?", + "header": "What is the tenancy code?", + "hint_text": "", + "type": "text" + } + } + }, + "tenancy_start_date": { + "header": "", + "description": "", + "questions": { + "tenancy_start_date": { + "check_answer_label": "When is the tenancy start date?", + "header": "What is the tenancy start date?", + "hint_text": "For example, 27 3 2007", + "type": "date" + } + } + }, + "starter_tenancy": { + "header": "", + "description": "", + "questions": { + "starter_tenancy": { + "check_answer_label": "Is this a starter or introductory tenancy?", + "header": "Is this a starter tenancy?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Yes", + "1": "No" + } + } + } + }, + "fixed_term_tenancy": { + "header": "", + "description": "", + "questions": { + "fixed_term_tenancy": { + "check_answer_label": "If the main tenancy is a fixed term tenancy, please provide the length of the fixed term (to the nearest year) excluding any starter/introductory period", + "header": "If fixed-term, what is the length of the fixed-term tenancy after any starter period?", + "hint_text": "To the nearest year", + "type": "numeric", + "min": 0, + "max": 150, + "step": 1 + } + } + }, + "tenancy_type": { + "header": "", + "description": "", + "questions": { + "tenancy_type": { + "check_answer_label": "Type of main tenancy (after any starter/introductory period)", + "header": "What is the type of tenancy after the starter period has ended?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Fixed term – Secure", + "1": "Fixed term – Assured Shorthold Tenancy (AST)", + "2": "Lifetime – Secure", + "3": "Lifetime – Assured", + "4": "License agreement", + "5": "Other" + }, + "conditional_for": { + "other_tenancy_type": ["Other"] + } + }, + "other_tenancy_type": { + "header": "Please state the tenancy type", + "hint_text": "", + "type": "text" + } + } + }, + "letting_type": { + "header": "", + "description": "", + "questions": { + "letting_type": { + "check_answer_label": "Type of letting", + "header": "Which type of letting is this?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Social Rent - General Needs", + "1": "Social Rent - Supporting Housing", + "2": "Affordable Rent - General Needs", + "3": "Affordable Rent - Supporting Housing", + "4": "Rent To Buy - General Needs", + "5": "Rent To Buy - Supported Housing" + } + } + } + }, + "letting_provider": { + "header": "", + "description": "", + "questions": { + "letting_provider": { + "check_answer_label": "Provider", + "header": "Who is the letting provider?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "This landlord", + "1": "Another registered provider - includes housing association or local authority" + } + } + } + } + } + }, + "property_information": { + "label": "Property information", + "pages": { + "property_location": { + "header": "", + "description": "", + "questions": { + "property_location": { + "check_answer_label": "Property Location", + "header": "Property location", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Adur", + "1": "Allerdale", + "2": "Amber Valley", + "3": "Arun", + "4": "Ashfield", + "5": "Ashford", + "6": "Babergh", + "7": "Barking & Dagenham", + "8": "Barnet", + "9": "Barnsley", + "10": "Barrow-in-Furness", + "11": "Basildon", + "12": "Basingstoke & Deane", + "13": "Bassetlaw", + "14": "Bath & NE Somerset", + "15": "Bedford Borough Council", + "16": "Bexley", + "17": "Birmingham", + "18": "Blaby", + "19": "Blackburn", + "20": "Blackpool", + "21": "Bolsover", + "22": "Bolton", + "23": "Boston", + "24": "Bournemouth & Christchurch & Poole", + "25": "Bracknell Forest", + "26": "Bradford", + "27": "Braintree", + "28": "Breckland", + "29": "Brent", + "30": "Brentwood", + "31": "Brighton & Hove", + "32": "Bristol", + "33": "Broadland", + "34": "Bromley", + "35": "Bromsgrove", + "36": "Broxbourne", + "37": "Broxtowe", + "38": "Buckinghamshire", + "39": "Burnley", + "40": "Bury", + "41": "Calderdale", + "42": "Cambridge", + "43": "Camden", + "44": "Cannock Chase", + "45": "Canterbury", + "46": "Carlisle", + "47": "Castle Point", + "48": "Central Bedfordshire", + "49": "Charnwood", + "50": "Chelmsford", + "51": "Cheltenham", + "52": "Cherwell", + "53": "Cheshire West & Chester", + "54": "Chesterfield", + "55": "Chichester", + "56": "Chorley", + "57": "City of London", + "58": "Colchester", + "59": "Copeland", + "60": "Cornwall", + "61": "Cotswold", + "62": "Coventry", + "63": "Craven", + "64": "Crawley", + "65": "Croydon", + "66": "Dacorum", + "67": "Darlington", + "68": "Dartford", + "69": "Derby", + "70": "Derbyshire Dales", + "71": "Doncaster", + "72": "Dorset", + "73": "Dover", + "74": "Dudley", + "75": "Durham", + "76": "Ealing", + "77": "East Cambridgeshire", + "78": "East Cheshire", + "79": "East Devon", + "80": "East Hampshire", + "81": "East Herts", + "82": "East Lindsey", + "83": "East Riding", + "84": "East Staffordshire", + "85": "East Suffolk", + "86": "Eastbourne", + "87": "Eastleigh", + "88": "Eden", + "89": "Elmbridge", + "90": "Enfield", + "91": "Epping Forest", + "92": "Epsom & Ewell", + "93": "Erewash", + "94": "Exeter", + "95": "Fareham", + "96": "Fenland", + "97": "Folkestone & Hythe", + "98": "Forest of Dean", + "99": "Fylde", + "100": "Gateshead", + "101": "Gedling", + "102": "Gloucester", + "103": "Gosport", + "104": "Gravesham", + "105": "Great Yarmouth", + "106": "Greenwich", + "107": "Guildford", + "108": "Hackney", + "109": "Halton", + "110": "Hambleton", + "111": "Hammersmith & Fulham", + "112": "Harborough", + "113": "Haringey", + "114": "Harlow", + "115": "Harrogate", + "116": "Harrow", + "117": "Hart", + "118": "Hartlepool", + "119": "Hastings", + "120": "Havant", + "121": "Havering", + "122": "Herefordshire", + "123": "Hertsmere", + "124": "High Peak", + "125": "Hillingdon", + "126": "Hinckley & Bosworth", + "127": "Horsham", + "128": "Hounslow", + "129": "Huntingdonshire", + "130": "Hyndburn", + "131": "Ipswich", + "132": "Isle of Wight", + "133": "Isles of Scilly", + "134": "Islington", + "135": "Kensington & Chelsea", + "136": "Kings Lynn & West Norfolk", + "137": "Kingston-upon-Hull", + "138": "Kingston-upon-Thames", + "139": "Kirklees", + "140": "Knowsley", + "141": "Lambeth", + "142": "Lancaster", + "143": "Leeds", + "144": "Leicester", + "145": "Lewes", + "146": "Lewisham", + "147": "Lichfield", + "148": "Lincoln", + "149": "Liverpool", + "150": "Luton", + "151": "Maidstone", + "152": "Maldon", + "153": "Malvern Hills", + "154": "Manchester", + "155": "Mansfield", + "156": "Medway", + "157": "Melton", + "158": "Mendip", + "159": "Merton", + "160": "Mid Devon", + "161": "Mid Suffolk", + "162": "Mid Sussex", + "163": "Middlesbrough", + "164": "Milton Keynes", + "165": "Mole Valley", + "166": "N. Ireland", + "167": "New Forest", + "168": "Newark", + "169": "Newcastle-under-Lyme", + "170": "Newcastle-upon-Tyne", + "171": "Newham", + "172": "North Devon", + "173": "North East Derbyshire", + "174": "North East Lincolnshire", + "175": "North Hertfordshire", + "176": "North Kesteven", + "177": "North Lincolnshire", + "178": "North Norfolk", + "179": "North Northamptonshire", + "180": "North Somerset", + "181": "North Tyneside", + "182": "North Warwickshire", + "183": "North West Leics", + "184": "Northumberland", + "185": "Norwich", + "186": "Nottingham", + "187": "Nuneaton & Bedworth", + "188": "Oadby & Wigston", + "189": "Oldham", + "190": "Outside UK", + "191": "Oxford", + "192": "Pendle", + "193": "Peterborough", + "194": "Plymouth", + "195": "Portsmouth", + "196": "Preston", + "197": "Reading", + "198": "Redbridge", + "199": "Redcar & Cleveland", + "200": "Redditch", + "201": "Reigate & Banstead", + "202": "Ribble Valley", + "203": "Richmond-upon-Thames", + "204": "Richmondshire", + "205": "Rochdale", + "206": "Rochford", + "207": "Rossendale", + "208": "Rother", + "209": "Rotherham", + "210": "Rugby", + "211": "Runnymede", + "212": "Rushcliffe", + "213": "Rushmoor", + "214": "Rutland", + "215": "Ryedale", + "216": "Salford", + "217": "Sandwell", + "218": "Scarborough", + "219": "Scotland", + "220": "Sedgemoor", + "221": "Sefton", + "222": "Selby", + "223": "Sevenoaks", + "224": "Sheffield", + "225": "Shropshire", + "226": "Slough", + "227": "Solihull", + "228": "Somerset West & Taunton", + "229": "South Cambridgeshire", + "230": "South Derbyshire", + "231": "South Gloucestershire", + "232": "South Hams", + "233": "South Holland", + "234": "South Kesteven", + "235": "South Lakeland", + "236": "South Norfolk", + "237": "South Oxfordshire", + "238": "South Ribble", + "239": "South Somerset", + "240": "South Staffordshire", + "241": "South Tyneside", + "242": "Southampton", + "243": "Southend-on-Sea", + "244": "Southwark", + "245": "Spelthorne", + "246": "St Albans", + "247": "St Helens", + "248": "Stafford", + "249": "Staffordshire Moorlands", + "250": "Stevenage", + "251": "Stockport", + "252": "Stockton-on-Tees", + "253": "Stoke-on-Trent", + "254": "Stratford-on-Avon", + "255": "Stroud", + "256": "Sunderland", + "257": "Surrey Heath", + "258": "Sutton", + "259": "Swale", + "260": "Swindon", + "261": "Tameside", + "262": "Tamworth", + "263": "Tandridge", + "264": "Teignbridge", + "265": "Telford & Wrekin", + "266": "Tendring", + "267": "Test Valley", + "268": "Tewkesbury", + "269": "Thanet", + "270": "Three Rivers", + "271": "Thurrock", + "272": "Tonbridge & Malling", + "273": "Torbay", + "274": "Torridge", + "275": "Tower Hamlets", + "276": "Trafford", + "277": "Tunbridge Wells", + "278": "Uttlesford", + "279": "Vale of White Horse", + "280": "Wakefield", + "281": "Wales", + "282": "Walsall", + "283": "Waltham Forest", + "284": "Wandsworth", + "285": "Warrington", + "286": "Warwick", + "287": "Watford", + "288": "Waverley", + "289": "Wealden", + "290": "Welwyn Hatfield", + "291": "West Berkshire", + "292": "West Devon", + "293": "West Lancashire", + "294": "West Lindsey", + "295": "West Northamptonshire", + "296": "West Oxfordshire", + "297": "West Suffolk", + "298": "Westminster", + "299": "Wigan", + "300": "Wiltshire", + "301": "Winchester", + "302": "Windsor & Maidenhead", + "303": "Wirral", + "304": "Woking", + "305": "Wokingham", + "306": "Wolverhampton", + "307": "Worcester", + "308": "Worthing", + "309": "Wychavon", + "310": "Wyre", + "311": "Wyre Forest", + "312": "York" + } + } + } + }, + "property_postcode": { + "header": "", + "description": "", + "questions": { + "property_postcode": { + "check_answer_label": "What was the previous postcode?", + "header": "What is the property's postcode?", + "hint_text": "", + "type": "text" + } + } + }, + "property_relet": { + "header": "", + "description": "", + "questions": { + "property_relet": { + "check_answer_label": "Which type was the property most recently let as?", + "header": "Is this property a relet?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Yes", + "1": "No" + } + } + } + }, + "property_vacancy_reason": { + "header": "", + "description": "", + "questions": { + "property_vacancy_reason": { + "check_answer_label": "What is the reason for the property vacancy?", + "header": "What is the reason for the property vacancy?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "First let of newbuild property", + "1": "First let of conversion/rehabilitation/acquired property", + "2": "First let of leased property", + "3": "Relet - tenant evicted due to arrears", + "4": "Relet - tenant evicted due to ASB or other reason", + "5": "Relet - tenant died (no succession)", + "6": "Relet - tenant moved to other social housing provider", + "7": "Relet - tenant abandoned property", + "8": "Relet - tenant moved to private sector or other accommodation", + "9": "Relet - to tenant who occupied same property as temporary accommodation", + "10": "Relet – internal transfer (excluding renewals of a fixed-term tenancy)", + "11": "Relet – renewal of fixed-term tenancy", + "12": "Relet – tenant moved to care home", + "13": "Relet – tenant involved in a succession downsize" + } + } + } + }, + "property_reference": { + "header": "", + "description": "", + "questions": { + "property_reference": { + "check_answer_label": "What’s the property reference?", + "header": "What's the property reference?", + "hint_text": "", + "type": "text" + } + } + }, + "property_unit_type": { + "header": "", + "description": "", + "questions": { + "property_unit_type": { + "check_answer_label": "Which type of unit is the property?", + "header": "Which type of unit is the property?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Flat / maisonette", + "1": "Bed-sit", + "2": "House", + "3": "Bungalow", + "4": "Shared flat / maisonette", + "5": "Shared house", + "6": "Shared bungalow", + "7": "Other" + } + } + } + }, + "property_number_of_bedrooms": { + "header": "", + "description": "", + "questions": { + "property_number_of_bedrooms": { + "check_answer_label": "How many bedrooms are there in the property?", + "header": "How many bedrooms are there in the property?", + "hint_text": "If shared accommodation, enter number of bedrooms occupied by this household; a bed-sit has 1 bedroom", + "type": "numeric", + "min": 0, + "max": 150, + "step": 1 + } + } + }, + "property_major_repairs": { + "header": "", + "description": "", + "questions": { + "property_major_repairs": { + "check_answer_label": "Were major repairs carried out during the void period?", + "header": "Were any major repairs completed during the void period?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Yes", + "1": "No" + }, + "conditional_for": { + "property_major_repairs_date": ["Yes"] + } + }, + "property_major_repairs_date": { + "check_answer_label": "What was the major repairs completion date?", + "header": "What was the major repairs completion date?", + "hint_text": "For example, 27 3 2007", + "type": "date" + } + } + }, + "property_number_of_times_relet": { + "header": "", + "description": "", + "questions": { + "property_number_of_times_relet": { + "check_answer_label": "How many times has this unit been previously offered since becoming available for relet since the last tenancy ended or as a first let?", + "header": "How many times has this unit been previously offered since becoming available for relet since the last tenancy ended or as a first let? ", + "hint_text": "For an Affordable Rent or Intermediate Rent Letting, only include number of offers as that type. For a property let at the first attempt enter '0' ", + "type": "numeric", + "min": 0, + "max": 150, + "step": 1 + } + } + }, + "property_wheelchair_accessible": { + "header": "", + "description": "", + "questions": { + "property_wheelchair_accessible": { + "check_answer_label": "Is property built or adapted to wheelchair user standards?", + "header": "Is property built or adapted to wheelchair user standards?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Yes", + "1": "No" + } + } + } + } + } + } + } + }, + "rent_and_charges": { + "label": "Rent and charges", + "subsections": { + "income_and_benefits": { + "label": "Income and benefits", + "pages": { + "net_income": { + "header": "", + "description": "", + "questions": { + "net_income_known": { + "check_answer_label": "Income known", + "header": "Do you know the tenant and their partner's net income?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Yes", + "1": "No", + "2": "Tenant prefers not to say" + }, + "conditional_for": { + "net_income": ["Yes"], + "net_income_frequency": ["Yes"] + } + }, + "net_income": { + "check_answer_label": "Income", + "header": "What is the tenant’s /and partner’s combined income after tax?", + "hint_text": "", + "type": "numeric", + "min": 0, + "step": "1" + }, + "net_income_frequency": { + "check_answer_label": "Income Frequency", + "header": "How often do they receive this income?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Weekly", + "1": "Monthly", + "2": "Yearly" + } + } + }, + "soft_validations": { + "override_net_income_validation": { + "check_answer_label": "Net income confirmed?", + "type": "validation_override", + "answer_options": { + "override_net_income_validation": "Yes" + } + } + } + }, + "net_income_uc_proportion": { + "header": "", + "description": "", + "questions": { + "net_income_uc_proportion": { + "check_answer_label": "Benefits as a proportion of income", + "header": "How much of the tenant’s income is from Universal Credit, state pensions or benefits?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "All", + "1": "Some", + "2": "None", + "3": "Do not know" + } + } + } + }, + "housing_benefit": { + "header": "", + "description": "", + "questions": { + "housing_benefit": { + "check_answer_label": "Universal Credit & Housing Benefit\t", + "header": "Is the tenant likely to be in receipt of any of these housing-related benefits?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Housing Benefit, but not Universal Credit", + "1": "Universal Credit with housing element, but not Housing Benefit", + "2": "Universal Credit without housing element and no Housing Benefit", + "3": "Universal Credit and Housing Benefit", + "4": "Not Housing Benefit or Universal Credit", + "5": "Do not know", + "6": "Prefer not to say" + } + } + } + } + } + }, + "rent": { + "label": "Rent", + "pages": { + "rent": { + "header": "", + "description": "", + "questions": { + "rent_frequency": { + "check_answer_label": "Rent Period", + "header": "Which period are rent and other charges due?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Weekly for 52 weeks", + "1": "Fortnightly", + "2": "Four-weekly", + "3": "Calendar monthly", + "4": "Weekly for 50 weeks", + "5": "Weekly for 49 weeks", + "6": "Weekly for 48 weeks", + "7": "Weekly for 47 weeks", + "8": "Weekly for 46 weeks", + "9": "Weekly for 53 weeks" + } + }, + "basic_rent": { + "check_answer_label": "Basic Rent", + "header": "What is the basic rent?", + "hint_text": "Eligible for housing benefit or Universal Credit", + "type": "numeric", + "min": 0, + "step": 1, + "fields-to-add": ["basic_rent", "service_charge", "personal_service_charge", "support_charge"], + "result-field": "total_charge" + }, + "service_charge": { + "check_answer_label": "Service Charge", + "header": "What is the service charge?", + "hint_text": "Eligible for housing benefit or Universal Credit", + "type": "numeric", + "min": 0, + "step": 1, + "fields-to-add": ["basic_rent", "service_charge", "personal_service_charge", "support_charge"], + "result-field": "total_charge" + }, + "personal_service_charge": { + "check_answer_label": "Personal Service Charge", + "header": "What is the personal service charge?", + "hint_text": "Not eligible for housing benefit or Universal Credit. For example, hot water excluding water rates.", + "type": "numeric", + "min": 0, + "step": 1, + "fields-to-add": ["basic_rent", "service_charge", "personal_service_charge", "support_charge"], + "result-field": "total_charge" + }, + "support_charge": { + "check_answer_label": "Support Charge", + "header": "What is the support charge?", + "hint_text": "This is to fund housing-related support services included in the tenancy agreement", + "type": "numeric", + "min": 0, + "step": 1, + "fields-to-add": ["basic_rent", "service_charge", "personal_service_charge", "support_charge"], + "result-field": "total_charge" + }, + "total_charge": { + "check_answer_label": "Total Charge", + "header": "Total charge?", + "hint_text": "This is the total of rent and all charges", + "type": "numeric", + "min": 0, + "step": 1, + "readonly": true + }, + "outstanding_rent_or_charges": { + "check_answer_label": "After housing benefit and/or housing element of UC payment is received, will there be an outstanding amount for basic rent and/or benefit eligible charges?", + "header": "After housing benefit and/or housing element of UC payment is received, will there be an outstanding amount for basic rent and/or benefit eligible charges?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Yes", + "1": "No" + }, + "conditional_for": { + "outstanding_amount": ["Yes"] + } + }, + "outstanding_amount": { + "check_answer_label": "Outstanding amount", + "header": "What do you expect the amount to be?", + "hint_text": "If the amount is unknown you can estimate", + "type": "numeric", + "min": 0, + "step": 1 + } + } + } + } + } + } + }, + "local_authority": { + "label": "Local authority", + "subsections": { + "local_authority": { + "label": "Local authority", + "pages": { + "time_lived_in_la": { + "header": "", + "description": "", + "questions": { + "time_lived_in_la": { + "check_answer_label": "How long has the household continuously lived in the local authority area where the new letting is located?", + "header": "How long has the household continuously lived in the local authority area where the new letting is located?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Just moved to local authority area", + "1": "Less than 1 year", + "2": "1 to 2 years", + "3": "2 to 3 years", + "4": "3 to 4 years", + "5": "4 to 5 years", + "6": "5 years or more", + "7": "Do not know" + } + } + } + }, + "time_on_la_waiting_list": { + "header": "", + "description": "", + "questions": { + "time_on_la_waiting_list": { + "check_answer_label": "How long has the household been on the local authority waiting list where the new letting is located?", + "header": "How long has the household been on the local authority waiting list where the new letting is located?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Just moved to local authority area", + "1": "Less than 1 year", + "2": "1 to 2 years", + "3": "2 to 3 years", + "4": "3 to 4 years", + "5": "4 to 5 years", + "6": "5 years or more", + "7": "Do not know" + } + } + } + }, + "previous_la": { + "header": "", + "description": "", + "questions": { + "previous_la": { + "check_answer_label": "The LA in which household lived immediately before this letting\t", + "header": "Which local authority area did the household live in immediately before this letting?", + "hint_text": "Includes temporary accommodation", + "type": "radio", + "answer_options": { + "0": "Adur", + "1": "Allerdale", + "2": "Amber Valley", + "3": "Arun", + "4": "Ashfield", + "5": "Ashford", + "6": "Babergh", + "7": "Barking & Dagenham", + "8": "Barnet", + "9": "Barnsley", + "10": "Barrow-in-Furness", + "11": "Basildon", + "12": "Basingstoke & Deane", + "13": "Bassetlaw", + "14": "Bath & NE Somerset", + "15": "Bedford Borough Council", + "16": "Bexley", + "17": "Birmingham", + "18": "Blaby", + "19": "Blackburn", + "20": "Blackpool", + "21": "Bolsover", + "22": "Bolton", + "23": "Boston", + "24": "Bournemouth & Christchurch & Poole", + "25": "Bracknell Forest", + "26": "Bradford", + "27": "Braintree", + "28": "Breckland", + "29": "Brent", + "30": "Brentwood", + "31": "Brighton & Hove", + "32": "Bristol", + "33": "Broadland", + "34": "Bromley", + "35": "Bromsgrove", + "36": "Broxbourne", + "37": "Broxtowe", + "38": "Buckinghamshire", + "39": "Burnley", + "40": "Bury", + "41": "Calderdale", + "42": "Cambridge", + "43": "Camden", + "44": "Cannock Chase", + "45": "Canterbury", + "46": "Carlisle", + "47": "Castle Point", + "48": "Central Bedfordshire", + "49": "Charnwood", + "50": "Chelmsford", + "51": "Cheltenham", + "52": "Cherwell", + "53": "Cheshire West & Chester", + "54": "Chesterfield", + "55": "Chichester", + "56": "Chorley", + "57": "City of London", + "58": "Colchester", + "59": "Copeland", + "60": "Cornwall", + "61": "Cotswold", + "62": "Coventry", + "63": "Craven", + "64": "Crawley", + "65": "Croydon", + "66": "Dacorum", + "67": "Darlington", + "68": "Dartford", + "69": "Derby", + "70": "Derbyshire Dales", + "71": "Doncaster", + "72": "Dorset", + "73": "Dover", + "74": "Dudley", + "75": "Durham", + "76": "Ealing", + "77": "East Cambridgeshire", + "78": "East Cheshire", + "79": "East Devon", + "80": "East Hampshire", + "81": "East Herts", + "82": "East Lindsey", + "83": "East Riding", + "84": "East Staffordshire", + "85": "East Suffolk", + "86": "Eastbourne", + "87": "Eastleigh", + "88": "Eden", + "89": "Elmbridge", + "90": "Enfield", + "91": "Epping Forest", + "92": "Epsom & Ewell", + "93": "Erewash", + "94": "Exeter", + "95": "Fareham", + "96": "Fenland", + "97": "Folkestone & Hythe", + "98": "Forest of Dean", + "99": "Fylde", + "100": "Gateshead", + "101": "Gedling", + "102": "Gloucester", + "103": "Gosport", + "104": "Gravesham", + "105": "Great Yarmouth", + "106": "Greenwich", + "107": "Guildford", + "108": "Hackney", + "109": "Halton", + "110": "Hambleton", + "111": "Hammersmith & Fulham", + "112": "Harborough", + "113": "Haringey", + "114": "Harlow", + "115": "Harrogate", + "116": "Harrow", + "117": "Hart", + "118": "Hartlepool", + "119": "Hastings", + "120": "Havant", + "121": "Havering", + "122": "Herefordshire", + "123": "Hertsmere", + "124": "High Peak", + "125": "Hillingdon", + "126": "Hinckley & Bosworth", + "127": "Horsham", + "128": "Hounslow", + "129": "Huntingdonshire", + "130": "Hyndburn", + "131": "Ipswich", + "132": "Isle of Wight", + "133": "Isles of Scilly", + "134": "Islington", + "135": "Kensington & Chelsea", + "136": "Kings Lynn & West Norfolk", + "137": "Kingston-upon-Hull", + "138": "Kingston-upon-Thames", + "139": "Kirklees", + "140": "Knowsley", + "141": "Lambeth", + "142": "Lancaster", + "143": "Leeds", + "144": "Leicester", + "145": "Lewes", + "146": "Lewisham", + "147": "Lichfield", + "148": "Lincoln", + "149": "Liverpool", + "150": "Luton", + "151": "Maidstone", + "152": "Maldon", + "153": "Malvern Hills", + "154": "Manchester", + "155": "Mansfield", + "156": "Medway", + "157": "Melton", + "158": "Mendip", + "159": "Merton", + "160": "Mid Devon", + "161": "Mid Suffolk", + "162": "Mid Sussex", + "163": "Middlesbrough", + "164": "Milton Keynes", + "165": "Mole Valley", + "166": "N. Ireland", + "167": "New Forest", + "168": "Newark", + "169": "Newcastle-under-Lyme", + "170": "Newcastle-upon-Tyne", + "171": "Newham", + "172": "North Devon", + "173": "North East Derbyshire", + "174": "North East Lincolnshire", + "175": "North Hertfordshire", + "176": "North Kesteven", + "177": "North Lincolnshire", + "178": "North Norfolk", + "179": "North Northamptonshire", + "180": "North Somerset", + "181": "North Tyneside", + "182": "North Warwickshire", + "183": "North West Leics", + "184": "Northumberland", + "185": "Norwich", + "186": "Nottingham", + "187": "Nuneaton & Bedworth", + "188": "Oadby & Wigston", + "189": "Oldham", + "190": "Outside UK", + "191": "Oxford", + "192": "Pendle", + "193": "Peterborough", + "194": "Plymouth", + "195": "Portsmouth", + "196": "Preston", + "197": "Reading", + "198": "Redbridge", + "199": "Redcar & Cleveland", + "200": "Redditch", + "201": "Reigate & Banstead", + "202": "Ribble Valley", + "203": "Richmond-upon-Thames", + "204": "Richmondshire", + "205": "Rochdale", + "206": "Rochford", + "207": "Rossendale", + "208": "Rother", + "209": "Rotherham", + "210": "Rugby", + "211": "Runnymede", + "212": "Rushcliffe", + "213": "Rushmoor", + "214": "Rutland", + "215": "Ryedale", + "216": "Salford", + "217": "Sandwell", + "218": "Scarborough", + "219": "Scotland", + "220": "Sedgemoor", + "221": "Sefton", + "222": "Selby", + "223": "Sevenoaks", + "224": "Sheffield", + "225": "Shropshire", + "226": "Slough", + "227": "Solihull", + "228": "Somerset West & Taunton", + "229": "South Cambridgeshire", + "230": "South Derbyshire", + "231": "South Gloucestershire", + "232": "South Hams", + "233": "South Holland", + "234": "South Kesteven", + "235": "South Lakeland", + "236": "South Norfolk", + "237": "South Oxfordshire", + "238": "South Ribble", + "239": "South Somerset", + "240": "South Staffordshire", + "241": "South Tyneside", + "242": "Southampton", + "243": "Southend-on-Sea", + "244": "Southwark", + "245": "Spelthorne", + "246": "St Albans", + "247": "St Helens", + "248": "Stafford", + "249": "Staffordshire Moorlands", + "250": "Stevenage", + "251": "Stockport", + "252": "Stockton-on-Tees", + "253": "Stoke-on-Trent", + "254": "Stratford-on-Avon", + "255": "Stroud", + "256": "Sunderland", + "257": "Surrey Heath", + "258": "Sutton", + "259": "Swale", + "260": "Swindon", + "261": "Tameside", + "262": "Tamworth", + "263": "Tandridge", + "264": "Teignbridge", + "265": "Telford & Wrekin", + "266": "Tendring", + "267": "Test Valley", + "268": "Tewkesbury", + "269": "Thanet", + "270": "Three Rivers", + "271": "Thurrock", + "272": "Tonbridge & Malling", + "273": "Torbay", + "274": "Torridge", + "275": "Tower Hamlets", + "276": "Trafford", + "277": "Tunbridge Wells", + "278": "Uttlesford", + "279": "Vale of White Horse", + "280": "Wakefield", + "281": "Wales", + "282": "Walsall", + "283": "Waltham Forest", + "284": "Wandsworth", + "285": "Warrington", + "286": "Warwick", + "287": "Watford", + "288": "Waverley", + "289": "Wealden", + "290": "Welwyn Hatfield", + "291": "West Berkshire", + "292": "West Devon", + "293": "West Lancashire", + "294": "West Lindsey", + "295": "West Northamptonshire", + "296": "West Oxfordshire", + "297": "West Suffolk", + "298": "Westminster", + "299": "Wigan", + "300": "Wiltshire", + "301": "Winchester", + "302": "Windsor & Maidenhead", + "303": "Wirral", + "304": "Woking", + "305": "Wokingham", + "306": "Wolverhampton", + "307": "Worcester", + "308": "Worthing", + "309": "Wychavon", + "310": "Wyre", + "311": "Wyre Forest", + "312": "York" + } + } + } + }, + "previous_postcode": { + "header": "", + "description": "", + "questions": { + "previous_postcode": { + "check_answer_label": "Postcode of previous accomodation if the household has moved from settled accommodation", + "header": "Postcode for the previous accommodation", + "hint_text": "If the household has moved from settled accommodation immediately prior to being re-housed", + "type": "text" + } + } + }, + "reasonable_preference": { + "header": "", + "description": "", + "questions": { + "reasonable_preference": { + "check_answer_label": "Was the household given Reasonable Preference (i.e. priority) for housing by the Local Authority?", + "header": "Was the household given reasonable preference by the local authority?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Yes", + "1": "No" + }, + "conditional_for": { + "reasonable_preference_reason": ["Yes"] + } + }, + "reasonable_preference_reason": { + "check_answer_label": "Reason for reasonable preference", + "header": "Why were they given reasonable preference?", + "hint_text": "Select all that apply", + "type": "checkbox", + "answer_options": { + "reasonable_preference_reason_homeless": "Homeless or about to lose their home (within 56 days)", + "reasonable_preference_reason_unsatisfactory_housing": "Living in insanitary or overcrowded or unsatisfactory housing", + "reasonable_preference_reason_medical_grounds": "A need to move on medical and welfare grounds (including a disability)", + "reasonable_preference_reason_avoid_hardship": "A need to move to avoid hardship to themselves or others", + "divider": true, + "reasonable_preference_reason_do_not_know": "Do not know" + } + } + } + }, + "lettings_policy": { + "header": "", + "description": "", + "questions": { + "cbl_letting": { + "check_answer_label": "Choice-based letting?", + "header": "Was the letting made under choice-based lettings (CBL)? ", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Yes", + "1": "No" + } + }, + "chr_letting": { + "check_answer_label": "Common housing register letting?", + "header": "Was the letting made under common housing register (CHR)? ", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Yes", + "1": "No" + } + }, + "cap_letting": { + "check_answer_label": "Common allocation policy letting?", + "header": "Was the letting made under common allocation policy (CAP)? ", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Yes", + "1": "No" + } + } + } + } + } + } + } + }, + "submission": { + "label": "Submission", + "subsections": { + "declaration": { + "label": "Declaration", + "pages": { + "declaration": { + "header": "", + "description": "", + "questions": { + "declaration": { + "check_answer_label": "", + "header": "What is the tenant code?", + "hint_text": "", + "type": "text" + } + } + } + } + } + } + } + } + } + \ No newline at end of file diff --git a/config/forms/schema/generic.json b/config/forms/schema/generic.json new file mode 100644 index 000000000..a52897c43 --- /dev/null +++ b/config/forms/schema/generic.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema", + "$id": "https://example.com/product.schema.json", + "title": "Form", + "description": "A form", + "type": "object", + "properties": { + "form_type": { + "description": "", + "type": "string" + }, + "start_year": { + "description": "", + "type": "integer" + }, + "end_year": { + "description": "", + "type": "integer" + }, + "sections": { + "description": "", + "type": "object", + "patternProperties": { + "^[0-9]+$": { + "description": "", + "type": "string" + }, + "label": { + "description": "", + "type": "string" + }, + "subsections": { + "type": "object" + } + } + } + } +} \ No newline at end of file From 78547d4a2c3c397bbadb8ef1845aa38f6ebf5bdb Mon Sep 17 00:00:00 2001 From: magicmilo Date: Sun, 7 Nov 2021 22:24:04 +0000 Subject: [PATCH 07/55] dir loop --- app/helpers/json_schema_validation.rb | 91 ++++++++++++++------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/app/helpers/json_schema_validation.rb b/app/helpers/json_schema_validation.rb index 3e46be8e0..329186831 100644 --- a/app/helpers/json_schema_validation.rb +++ b/app/helpers/json_schema_validation.rb @@ -2,35 +2,45 @@ require "json-schema" require "json" # "form_type": "lettings", -# "start_year": 2021, -# "end_year": 2022, -# "sections": { -# "about_this_log": { -# "label": "About this log", -# "subsections": { -# "about_this_log": { -# "label": "About this log", -# "pages": { - # "tenant_code": { - # "header": "", - # "description": "", - # "questions": { - # "tenant_code": { - # "check_answer_label": "Tenant code", - # "header": "What is the tenant code?", - # "hint_text": "", - # "type": "text" - # } - # } - # }, +#start_year": 2021, +#end_year": 2022, +#sections": { +# about_this_log": { +# label": "About this log", +# subsections": { +# about_this_log": { +# label": "About this log", +# pages": { +# "tenant_code": { +# header": "", +# description": "", +# questions": { +# tenant_code": { +# check_answer_label": "Tenant code", +# header": "What is the tenant code?", +# hint_text": "", +# type": "text" +# } +# } +# } + +def get_all_form_paths(directories) + form_paths = [] + directories.each do |directory| + Dir.glob("#{directory}/*.json").each do |form_path| + form_paths.push(form_path) + end + end + form_paths +end + begin - path = "config/forms/schema/generic.json" - # path = "config/forms/schema/2021_2022.json" + # path = "config/forms/schema/generic.json" + path = "config/forms/schema/2021_2022.json" file = File.open(path) schema = JSON.parse(file.read) - metaschema = JSON::Validator.validator_for_name("draft4").metaschema if JSON::Validator.validate(metaschema, schema) @@ -43,28 +53,21 @@ begin path = "spec/fixtures/forms/test_validator.json" # path = "config/forms/2021_2022.json" - file = File.open(path) - data = JSON.parse(file.read) + directories = ["config/forms", "spec/fixtures/forms"] - puts JSON::Validator.validate(schema, data) + get_all_form_paths(directories).each do |path| + puts path + file = File.open(path) + data = JSON.parse(file.read) - puts JSON::Validator.fully_validate(schema, data, :strict => true) + puts JSON::Validator.validate(schema, data) - begin - JSON::Validator.validate!(schema, data) - rescue JSON::Schema::ValidationError => e - e.message - end + puts JSON::Validator.fully_validate(schema, data, :strict => true) - # def get_all_form_paths - # form_paths = [] - # directories = ["config/forms", "spec/fixtures/forms"] - # directories.each do |directory| - # Dir.glob("#{directory}/*.json").each do |form_path| - # form_path = form_path.sub(".json", "").split("/")[-1] - # form_paths.push(form_path) - # end - # end - # form_paths - # end + begin + JSON::Validator.validate!(schema, data) + rescue JSON::Schema::ValidationError => e + e.message + end + end end From dc35b066a39e57e33f00b01ccc2e8aae979b490e Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Mon, 8 Nov 2021 09:20:54 +0000 Subject: [PATCH 08/55] Migrate the remaining checkbox fields to integer; (#80) --- .../20211108091320_change_checkbox_types.rb | 15 +++++++++++++++ db/schema.rb | 6 +++--- 2 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20211108091320_change_checkbox_types.rb diff --git a/db/migrate/20211108091320_change_checkbox_types.rb b/db/migrate/20211108091320_change_checkbox_types.rb new file mode 100644 index 000000000..67b2ac00a --- /dev/null +++ b/db/migrate/20211108091320_change_checkbox_types.rb @@ -0,0 +1,15 @@ +class ChangeCheckboxTypes < ActiveRecord::Migration[6.1] + def up + change_table :case_logs, bulk: true do |t| + t.change :accessibility_requirements_prefer_not_to_say, "integer USING accessibility_requirements_prefer_not_to_say::integer" + t.change :condition_effects_prefer_not_to_say, "integer USING condition_effects_prefer_not_to_say::integer" + end + end + + def down + change_table :case_logs, bulk: true do |t| + t.change :accessibility_requirements_prefer_not_to_say, "boolean USING accessibility_requirements_prefer_not_to_say::boolean" + t.change :condition_effects_prefer_not_to_say, "boolean USING condition_effects_prefer_not_to_say::boolean" + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 91f0eff45..005086022 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_11_05_164644) do +ActiveRecord::Schema.define(version: 2021_11_08_091320) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -114,7 +114,7 @@ ActiveRecord::Schema.define(version: 2021_11_05_164644) do t.integer "housingneeds_f" t.integer "housingneeds_g" t.integer "housingneeds_h" - t.boolean "accessibility_requirements_prefer_not_to_say" + t.integer "accessibility_requirements_prefer_not_to_say" t.integer "illness_type_1" t.integer "illness_type_2" t.integer "illness_type_3" @@ -125,7 +125,7 @@ ActiveRecord::Schema.define(version: 2021_11_05_164644) do t.integer "illness_type_7" t.integer "illness_type_9" t.integer "illness_type_10" - t.boolean "condition_effects_prefer_not_to_say" + t.integer "condition_effects_prefer_not_to_say" t.integer "rp_homeless" t.integer "rp_insan_unsat" t.integer "rp_medwel" From ebc79e49828f211dc4aaba62abdad535173cf0d9 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Mon, 8 Nov 2021 09:44:40 +0000 Subject: [PATCH 09/55] . --- app/helpers/json_schema_validation.rb | 4 ++-- config/forms/schema/generic.json | 6 ++++-- spec/fixtures/forms/test_validator.json | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/app/helpers/json_schema_validation.rb b/app/helpers/json_schema_validation.rb index 329186831..5435f02e6 100644 --- a/app/helpers/json_schema_validation.rb +++ b/app/helpers/json_schema_validation.rb @@ -36,8 +36,8 @@ end begin - # path = "config/forms/schema/generic.json" - path = "config/forms/schema/2021_2022.json" + path = "config/forms/schema/generic.json" + # path = "config/forms/schema/2021_2022.json" file = File.open(path) schema = JSON.parse(file.read) diff --git a/config/forms/schema/generic.json b/config/forms/schema/generic.json index a52897c43..024990b8b 100644 --- a/config/forms/schema/generic.json +++ b/config/forms/schema/generic.json @@ -11,11 +11,13 @@ }, "start_year": { "description": "", - "type": "integer" + "type": "integer", + "optional": "true" }, "end_year": { "description": "", - "type": "integer" + "type": "integer", + "required": "false" }, "sections": { "description": "", diff --git a/spec/fixtures/forms/test_validator.json b/spec/fixtures/forms/test_validator.json index 13aed9e5f..e0fe13361 100644 --- a/spec/fixtures/forms/test_validator.json +++ b/spec/fixtures/forms/test_validator.json @@ -19,6 +19,21 @@ } } } + }, + "person_1_age": { + "header": "", + "description": "", + "questions": { + "person_1_age": { + "check_answer_label": "Tenant's age", + "header": "What is the tenant's age?", + "hint_text": "", + "type": "numeric", + "min": 0, + "max": 120, + "step": 1 + } + } } } } From dbef8dfba4fb091c4213c11aeb71a51153093f75 Mon Sep 17 00:00:00 2001 From: Daniel Baark <5101747+baarkerlounger@users.noreply.github.com> Date: Tue, 9 Nov 2021 13:36:52 +0000 Subject: [PATCH 10/55] CLDC-642: Soft validation UI bug fix (#82) * Soft validation UI needs to be on both questions being validated * Fix whether the box is checked or not * All checkboxes are integers now * Fix * Use enums as well for consistency * Use capybara matcher for less flakiness * Click link already waits * Add a retry to our fetch so tests are more resilient to intermittent network issues --- app/constants/db_enums.rb | 7 +++++++ .../controllers/soft_validations_controller.js | 14 +++++++++++--- app/models/case_log.rb | 1 + app/validations/soft_validations.rb | 2 +- .../form/_validation_override_question.html.erb | 3 ++- config/forms/2021_2022.json | 9 +++++++++ spec/features/case_log_spec.rb | 2 +- 7 files changed, 32 insertions(+), 6 deletions(-) diff --git a/app/constants/db_enums.rb b/app/constants/db_enums.rb index 536620915..84f7d3837 100644 --- a/app/constants/db_enums.rb +++ b/app/constants/db_enums.rb @@ -213,6 +213,13 @@ module DbEnums } end + def self.override_soft_validation + { + "No" => 0, + "Yes" => 1, + } + end + def self.benefits { "All" => 1, diff --git a/app/javascript/controllers/soft_validations_controller.js b/app/javascript/controllers/soft_validations_controller.js index 963dd7a76..a408e4460 100644 --- a/app/javascript/controllers/soft_validations_controller.js +++ b/app/javascript/controllers/soft_validations_controller.js @@ -5,8 +5,13 @@ export default class extends Controller { initialize() { let url = window.location.href + "/soft_validations" + this.fetch_retry(url, { headers: { accept: "application/json" } }, 2) + } + + fetch_retry(url, options, n) { + let self = this let div = this.overrideTarget - fetch(url, { headers: { accept: "application/json" } }) + fetch(url, options) .then(response => response.json()) .then((response) => { if(response["show"]){ @@ -22,7 +27,10 @@ export default class extends Controller { button.checked = false }) } - } - ) + }) + .catch(function(error) { + if (n === 1) throw error + return self.fetch_retry(url, options, n - 1) + }) } } diff --git a/app/models/case_log.rb b/app/models/case_log.rb index ac37461da..b77534795 100644 --- a/app/models/case_log.rb +++ b/app/models/case_log.rb @@ -65,6 +65,7 @@ class CaseLog < ApplicationRecord enum leftreg: DbEnums.leftreg, _suffix: true enum illness: DbEnums.illness, _suffix: true enum preg_occ: DbEnums.pregnancy, _suffix: true + enum override_net_income_validation: DbEnums.override_soft_validation, _suffix: true enum housingneeds_a: DbEnums.polar, _suffix: true enum housingneeds_b: DbEnums.polar, _suffix: true enum housingneeds_c: DbEnums.polar, _suffix: true diff --git a/app/validations/soft_validations.rb b/app/validations/soft_validations.rb index ce03fafc6..451988b66 100644 --- a/app/validations/soft_validations.rb +++ b/app/validations/soft_validations.rb @@ -8,7 +8,7 @@ module SoftValidations end def soft_errors_overridden? - !public_send(soft_errors.keys.first).zero? if soft_errors.present? + public_send(soft_errors.keys.first) == "Yes" if soft_errors.present? end private diff --git a/app/views/form/_validation_override_question.html.erb b/app/views/form/_validation_override_question.html.erb index 5e42b32b8..10a6a60e7 100644 --- a/app/views/form/_validation_override_question.html.erb +++ b/app/views/form/_validation_override_question.html.erb @@ -8,7 +8,8 @@ hint: { text: "soft-validations-placeholder-hint-text" } do %> <%= f.govuk_check_box page_info["soft_validations"]&.keys&.first, page_info["soft_validations"]&.keys&.first, - label: { text: "Yes" } + label: { text: "Yes" }, + checked: @case_log[page_info["soft_validations"]&.keys&.first] == "Yes" %> <% end %> diff --git a/config/forms/2021_2022.json b/config/forms/2021_2022.json index 498e064b2..5229155e0 100644 --- a/config/forms/2021_2022.json +++ b/config/forms/2021_2022.json @@ -315,6 +315,15 @@ "10": "Prefer not to say" } } + }, + "soft_validations": { + "override_net_income_validation": { + "check_answer_label": "Net income confirmed?", + "type": "validation_override", + "answer_options": { + "override_net_income_validation": "Yes" + } + } } }, "household_number_of_other_members": { diff --git a/spec/features/case_log_spec.rb b/spec/features/case_log_spec.rb index 160bb883b..0e2ae338b 100644 --- a/spec/features/case_log_spec.rb +++ b/spec/features/case_log_spec.rb @@ -431,7 +431,7 @@ RSpec.describe "Test Features" do fill_in("case-log-earnings-field", with: income_under_soft_limit) click_button("Save and continue") click_link(text: "Back") - expect(page).not_to have_content("Are you sure this is correct?") + expect(page).to have_no_content("Are you sure this is correct?") end it "does not clear the confirmation question if the page is returned to using the back button and the amount is still over the soft limit", js: true do From f844f9273e263ab84ec7026463ce216cb872fd46 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Tue, 9 Nov 2021 14:34:17 +0000 Subject: [PATCH 11/55] outline --- app/helpers/json_schema_validation.rb | 30 ++----------- config/forms/schema/generic.json | 63 +++++++++++++++++++++++++-- spec/fixtures/forms/test_form.json | 2 + 3 files changed, 64 insertions(+), 31 deletions(-) diff --git a/app/helpers/json_schema_validation.rb b/app/helpers/json_schema_validation.rb index 5435f02e6..dd0655d3b 100644 --- a/app/helpers/json_schema_validation.rb +++ b/app/helpers/json_schema_validation.rb @@ -1,29 +1,6 @@ require "json-schema" require "json" -# "form_type": "lettings", -#start_year": 2021, -#end_year": 2022, -#sections": { -# about_this_log": { -# label": "About this log", -# subsections": { -# about_this_log": { -# label": "About this log", -# pages": { -# "tenant_code": { -# header": "", -# description": "", -# questions": { -# tenant_code": { -# check_answer_label": "Tenant code", -# header": "What is the tenant code?", -# hint_text": "", -# type": "text" -# } -# } -# } - def get_all_form_paths(directories) form_paths = [] directories.each do |directory| @@ -43,6 +20,8 @@ begin schema = JSON.parse(file.read) metaschema = JSON::Validator.validator_for_name("draft4").metaschema + puts path + if JSON::Validator.validate(metaschema, schema) puts "schema valid" else @@ -50,9 +29,6 @@ begin return end - path = "spec/fixtures/forms/test_validator.json" - # path = "config/forms/2021_2022.json" - directories = ["config/forms", "spec/fixtures/forms"] get_all_form_paths(directories).each do |path| @@ -60,7 +36,7 @@ begin file = File.open(path) data = JSON.parse(file.read) - puts JSON::Validator.validate(schema, data) + puts JSON::Validator.validate(schema, data, :strict => true) puts JSON::Validator.fully_validate(schema, data, :strict => true) diff --git a/config/forms/schema/generic.json b/config/forms/schema/generic.json index 024990b8b..b9502c0e1 100644 --- a/config/forms/schema/generic.json +++ b/config/forms/schema/generic.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema", + "$schema": "http://json-schema.org/draft-04/schema#", "$id": "https://example.com/product.schema.json", "title": "Form", "description": "A form", @@ -16,8 +16,7 @@ }, "end_year": { "description": "", - "type": "integer", - "required": "false" + "type": "integer" }, "sections": { "description": "", @@ -32,7 +31,63 @@ "type": "string" }, "subsections": { - "type": "object" + "description": "", + "type": "object", + "patternProperties": { + "^[0-9]+$": { + "description": "", + "type": "string" + }, + "label": { + "description": "", + "type": "string" + }, + "subsections": { + "description": "", + "type": "object", + "patternProperties": { + "^[0-9]+$": { + "description": "", + "type": "string" + }, + "label": { + "description": "", + "type": "string" + }, + "pages": { + "description": "", + "type": "object", + "patternProperties": { + "^[0-9]+$": { + "description": "", + "type": "string" + } + }, + "questions": { + "description": "", + "type": "object", + "patternProperties": { + "^[0-9]+$": { + "description": "", + "type": "string" + }, + "conditional_for": { + "type": "object", + "properties": "" + } + } + }, + "conditional_route_to": { + "type": "object", + "properties": "" + }, + "default_next_page": { + "type" : "string" + } + } + } + } + } } } } diff --git a/spec/fixtures/forms/test_form.json b/spec/fixtures/forms/test_form.json index 2bcd34aaa..0d26827fa 100644 --- a/spec/fixtures/forms/test_form.json +++ b/spec/fixtures/forms/test_form.json @@ -1,5 +1,7 @@ { "form_type": "lettings", + "start_year": 2021, + "end_year": 2022, "sections": { "household": { "label": "About the household", From e1f758ba07df15d91720f28c222acfd1cb37052e Mon Sep 17 00:00:00 2001 From: magicmilo Date: Tue, 9 Nov 2021 16:44:18 +0000 Subject: [PATCH 12/55] save --- app/helpers/json_schema_validation.rb | 3 +- config/forms/schema/generic.json | 4 +- config/forms/schema/test.json | 80 ++++ spec/fixtures/forms/test_form.json | 515 +------------------------- 4 files changed, 85 insertions(+), 517 deletions(-) create mode 100644 config/forms/schema/test.json diff --git a/app/helpers/json_schema_validation.rb b/app/helpers/json_schema_validation.rb index dd0655d3b..12084b020 100644 --- a/app/helpers/json_schema_validation.rb +++ b/app/helpers/json_schema_validation.rb @@ -13,7 +13,8 @@ end begin - path = "config/forms/schema/generic.json" + # path = "config/forms/schema/generic.json" + path = "config/forms/schema/test.json" # path = "config/forms/schema/2021_2022.json" file = File.open(path) diff --git a/config/forms/schema/generic.json b/config/forms/schema/generic.json index b9502c0e1..d7e71468d 100644 --- a/config/forms/schema/generic.json +++ b/config/forms/schema/generic.json @@ -4,6 +4,7 @@ "title": "Form", "description": "A form", "type": "object", + "required": ["form_type", "start_year", "end_year", "sections"], "properties": { "form_type": { "description": "", @@ -11,8 +12,7 @@ }, "start_year": { "description": "", - "type": "integer", - "optional": "true" + "type": "integer" }, "end_year": { "description": "", diff --git a/config/forms/schema/test.json b/config/forms/schema/test.json new file mode 100644 index 000000000..998146adf --- /dev/null +++ b/config/forms/schema/test.json @@ -0,0 +1,80 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "$id": "https://example.com/product.schema.json", + "title": "Form", + "description": "A form", + "type": "object", + "required": ["form_type", "start_year", "end_year", "sections"], + "properties": { + "form_type": { + "description": "", + "type": "string" + }, + "start_year": { + "description": "", + "type": "integer" + }, + "end_year": { + "description": "", + "type": "integer" + }, + "sections": { + "type": "object", + "patternProperties": { + "^[0-9]+$": { + "description": "", + "type": "string" + }, + "properties": { + "label": { + "description": "", + "type": "string" + }, + "subsections": { + "description": "", + "type": "object", + "patternProperties": { + "^[0-9]+$": { + "description": "", + "type": "object", + "required": ["label"], + "properties": { + "label": { + "description": "", + "type": "string" + }, + "pages": { + "type": "object", + "patternProperties": { + "^[0-9]+$": { + "properties": { + "header": { + "description": "", + "type": "string" + }, + "description": { + "description": "", + "type": "string" + }, + "questions": { + "type": "object", + "properties": { + + } + } + } + } + } + } + } + }, + "additionalProperties": false, + "maxProperties": 1, + "minProperties": 1 + } + } + } + } + } + } +} \ No newline at end of file diff --git a/spec/fixtures/forms/test_form.json b/spec/fixtures/forms/test_form.json index 0d26827fa..73df96635 100644 --- a/spec/fixtures/forms/test_form.json +++ b/spec/fixtures/forms/test_form.json @@ -17,520 +17,6 @@ "type": "text" } } - }, - "person_1_age": { - "questions": { - "person_1_age": { - "check_answer_label": "Tenant's age", - "header": "What is the tenant's age?", - "type": "numeric", - "min": 0, - "max": 150, - "step": 1 - } - } - }, - "person_1_gender": { - "questions": { - "person_1_gender": { - "check_answer_label": "Tenant's gender", - "header": "Which of these best describes the tenant's gender identity?", - "type": "radio", - "answer_options": { - "0": "Female", - "1": "Male", - "2": "Non-binary", - "3": "Prefer not to say" - } - } - } - }, - "household_number_of_other_members": { - "questions": { - "household_number_of_other_members": { - "check_answer_label": "Number of Other Household Members", - "header": "How many other people are there in the household?", - "hint_text": "The maximum number of others is 1", - "type": "numeric", - "min": 0, - "max": 1, - "step": 1, - "conditional_for": { - "person_2_relationship": ">0", - "person_2_age": ">0", - "person_2_gender": ">0", - "person_2_economic_status": ">0" - } - }, - "person_2_relationship": { - "check_answer_label": "Person 2's relationship to lead tenant", - "header": "What's person 2's relationship to lead tenant", - "type": "radio", - "answer_options": { - "0": "Other", - "1": "Prefer not to say" - } - }, - "person_2_age": { - "check_answer_label": "Person 2's age", - "header": "What's person 2's age", - "type": "numeric", - "min": 0, - "max": 150, - "step": 1 - }, - "person_2_gender": { - "check_answer_label": "Person 2's gender", - "header": "Which of these best describes person 2's gender identity?", - "type": "radio", - "answer_options": { - "0": "Female", - "1": "Male", - "2": "Non-binary", - "3": "Prefer not to say" - } - }, - "person_2_economic_status": { - "check_answer_label": "Person 2's Work", - "header": "Which of these best describes person 2's working situation?", - "type": "radio", - "answer_options": { - "0": "Other", - "1": "Prefer not to say" - } - } - } - } - } - }, - "household_needs": { - "label": "Household needs", - "pages": { - "armed_forces": { - "header": "Experience of the UK Armed Forces", - "questions": { - "armed_forces": { - "header": "Has the tenant ever served in the UK armed forces?", - "type": "radio", - "check_answer_label": "Armed Forces", - "answer_options": { - "0": "Yes - a regular", - "1": "Yes - a reserve", - "2": "No", - "3": "Prefer not to say" - }, - "conditional_for": { - "armed_forces_active": [ - "Yes - a regular", - "Yes - a reserve" - ], - "armed_forces_injured": [ - "Yes - a regular", - "Yes - a reserve" - ] - } - }, - "armed_forces_active": { - "header": "Are they still serving?", - "type": "radio", - "check_answer_label": "When did they leave the Armed Forces?", - "answer_options": { - "0": "Yes", - "1": "No - they left up to 5 years ago", - "2": "No - they left more than 5 years ago", - "3": "Prefer not to say" - } - }, - "armed_forces_injured": { - "header": "Were they seriously injured or ill as a result of their service?", - "type": "radio", - "check_answer_label": "Has anyone in the household been seriously injured or ill as a result of their service in the armed forces?", - "answer_options": { - "0": "Yes", - "1": "No", - "2": "Prefer not to say" - } - } - } - }, - "medical_conditions": { - "questions": { - "medical_conditions": { - "header": "Does anyone in the household have any of the following that they expect to last for 12 months or more:
  • Physical Condition
  • Mental Health Condition
  • Other Illness
", - "type": "radio", - "check_answer_label": "Physical, mental health or illness in the household", - "answer_options": { - "0": "Yes", - "1": "No", - "2": "Do not know", - "3": "Prefer not to say" - } - } - } - }, - "accessibility_requirements": { - "questions": { - "accessibility_requirements": { - "header": "Are any of these affected by their condition or illness?", - "hint_text": "Select all that apply", - "type": "checkbox", - "check_answer_label": "Disability requirements", - "answer_options": { - "accessibility_requirements_fully_wheelchair_accessible_housing": "Fully wheelchair accessible housing", - "accessibility_requirements_wheelchair_access_to_essential_rooms": "Wheelchair access to essential rooms", - "accessibility_requirements_level_access_housing": "Level access housing", - "divider_a": true, - "accessibility_requirements_do_not_know": "Do not know" - } - } - } - }, - "condition_effects": { - "questions": { - "condition_effects": { - "header": "Are any of these affected by their condition or illness?", - "hint_text": "Select all that apply", - "type": "checkbox", - "check_answer_label": "Conditions or illnesses", - "answer_options": { - "condition_effects_vision": "Vision - such as blindness or partial sight", - "condition_effects_hearing": "Hearing - such as deafness or partial hearing" - } - } - } - } - } - } - } - }, - "tenancy_and_property": { - "label": "Tenancy and property information", - "subsections": { - "tenancy_information": { - "label": "Tenancy information", - "pages": { - "tenancy_code": { - "questions": { - "tenancy_code": { - "check_answer_label": "What is the tenancy code?", - "header": "What is the tenancy code?", - "type": "text" - } - } - } - } - }, - "property_information": { - "label": "Property information", - "pages": { - "property_wheelchair_accessible": { - "questions": { - "property_wheelchair_accessible": { - "check_answer_label": "Is property built or adapted to wheelchair user standards?", - "header": "Is property built or adapted to wheelchair user standards?", - "type": "radio", - "answer_options": { - "0": "Yes", - "1": "No" - } - } - } - } - } - }, - "conditional_question": { - "label": "Conditional question", - "pages": { - "conditional_question": { - "questions": { - "pregnancy": { - "check_answer_label": "Has the condition been met?", - "header": "Has the condition been met?", - "type": "radio", - "answer_options": { - "0": "Yes", - "1": "No" - } - } - }, - "conditional_route_to": { - "rent": { "pregnancy": "Yes", "person_1_gender": "Female" }, - "conditional_question_yes_page": { "pregnancy": "Yes" }, - "conditional_question_no_page": { "pregnancy": "No" } - }, - "default_next_page": "check_answers" - }, - "conditional_question_yes_page": { - "questions": { - "cbl_letting": { - "check_answer_label": "Has the next condition been met?", - "header": "Has the next condition been met?", - "type": "radio", - "answer_options": { - "0": "Yes", - "1": "No" - } - } - }, - "default_next_page": "check_answers" - }, - "conditional_question_no_page": { - "questions": { - "conditional_question_no_question": { - "check_answer_label": "Has the condition not been met?", - "header": "Has the next condition not been met?", - "type": "radio", - "answer_options": { - "0": "Yes", - "1": "No" - } - } - }, - "default_next_page": "conditional_question_no_second_page" - }, - "conditional_question_no_second_page": { - "questions": { - "conditional_question_no_second_question": { - "check_answer_label": "Has the condition not been met again?", - "header": "Has the next condition not been met again?", - "type": "radio", - "answer_options": { - "0": "Yes", - "1": "No" - } - } - } - } - } - } - } - }, - "rent_and_charges": { - "label": "Rent and charges", - "subsections": { - "income_and_benefits": { - "label": "Income and benefits", - "pages": { - "net_income": { - "questions": { - "net_income": { - "check_answer_label": "Income", - "header": "What is the tenant’s /and partner’s combined income after tax?", - "type": "numeric", - "min": 0, - "step": "1" - }, - "net_income_frequency": { - "check_answer_label": "Income Frequency", - "header": "How often do they receive this income?", - "type": "radio", - "answer_options": { - "0": "Weekly", - "1": "Monthly", - "2": "Yearly" - } - } - }, - "soft_validations": { - "override_net_income_validation": { - "check_answer_label": "Net income confirmed?", - "type": "validation_override", - "answer_options": { - "override_net_income_validation": "Yes" - } - } - } - }, - "net_income_uc_proportion": { - "questions": { - "net_income_uc_proportion": { - "check_answer_label": "Benefits as a proportion of income", - "header": "How much of the tenant’s income is from Universal Credit, state pensions or benefits?", - "type": "radio", - "answer_options": { - "0": "All", - "1": "Some" - } - } - } - }, - "housing_benefit": { - "questions": { - "housing_benefit": { - "check_answer_label": "Universal Credit & Housing Benefit", - "header": "Is the tenant likely to be in receipt of any of these housing-related benefits?", - "type": "radio", - "answer_options": { - "0": "Housing Benefit, but not Universal Credit", - "1": "Prefer not to say" - } - } - } - } - } - }, - "rent": { - "label": "Rent", - "pages": { - "rent": { - "questions": { - "rent_frequency": { - "check_answer_label": "Rent Period", - "header": "Which period are rent and other charges due?", - "type": "radio", - "answer_options": { - "0": "Weekly for 52 weeks", - "1": "Fortnightly" - } - }, - "basic_rent": { - "check_answer_label": "Basic Rent", - "header": "What is the basic rent?", - "hint_text": "Eligible for housing benefit or Universal Credit", - "type": "numeric", - "min": 0, - "step": 1, - "fields-to-add": [ - "basic_rent", - "service_charge", - "personal_service_charge", - "support_charge" - ], - "result-field": "total_charge" - }, - "service_charge": { - "check_answer_label": "Service Charge", - "header": "What is the service charge?", - "hint_text": "Eligible for housing benefit or Universal Credit", - "type": "numeric", - "min": 0, - "step": 1, - "fields-to-add": [ - "basic_rent", - "service_charge", - "personal_service_charge", - "support_charge" - ], - "result-field": "total_charge" - }, - "personal_service_charge": { - "check_answer_label": "Personal Service Charge", - "header": "What is the personal service charge?", - "hint_text": "Not eligible for housing benefit or Universal Credit. For example, hot water excluding water rates.", - "type": "numeric", - "min": 0, - "step": 1, - "fields-to-add": [ - "basic_rent", - "service_charge", - "personal_service_charge", - "support_charge" - ], - "result-field": "total_charge" - }, - "support_charge": { - "check_answer_label": "Support Charge", - "header": "What is the support charge?", - "hint_text": "This is to fund housing-related support services included in the tenancy agreement", - "type": "numeric", - "min": 0, - "step": 1, - "fields-to-add": [ - "basic_rent", - "service_charge", - "personal_service_charge", - "support_charge" - ], - "result-field": "total_charge" - }, - "total_charge": { - "check_answer_label": "Total Charge", - "header": "Total charge?", - "hint_text": "This is the total of rent and all charges", - "type": "numeric", - "min": 0, - "step": 1, - "readonly": true - } - } - } - } - } - } - }, - "local_authority": { - "label": "Local authority", - "subsections": { - "local_authority": { - "label": "Local authority", - "pages": { - "time_lived_in_la": { - "questions": { - "time_lived_in_la": { - "check_answer_label": "How long has the household continuously lived in the local authority area where the new letting is located?", - "header": "How long has the household continuously lived in the local authority area where the new letting is located?", - "type": "radio", - "answer_options": { - "0": "Just moved to local authority area", - "1": "Less than 1 year", - "2": "1 to 2 years", - "3": "2 to 3 years", - "4": "3 to 4 years", - "5": "4 to 5 years", - "6": "5 years or more", - "7": "Do not know" - } - } - } - }, - "time_on_la_waiting_list": { - "questions": { - "time_on_la_waiting_list": { - "check_answer_label": "How long has the household been on the local authority waiting list where the new letting is located?", - "header": "How long has the household been on the local authority waiting list where the new letting is located?", - "type": "radio", - "answer_options": { - "0": "Just moved to local authority area", - "1": "Less than 1 year", - "2": "1 to 2 years", - "3": "2 to 3 years", - "4": "3 to 4 years", - "5": "4 to 5 years", - "6": "5 years or more", - "7": "Do not know" - } - } - } - }, - "previous_postcode": { - "questions": { - "previous_postcode": { - "check_answer_label": "Postcode of previous accomodation if the household has moved from settled accommodation", - "header": "Postcode for the previous accommodation", - "hint_text": "If the household has moved from settled accommodation immediately prior to being re-housed", - "type": "text", - "conditional_for": { "faake_key": "fake_condition" } - } - } - } - } - } - } - }, - "submission": { - "label": "Submission", - "subsections": { - "declaration": { - "label": "Declaration", - "pages": { - "declaration": { - "questions": { - "declaration": { - "check_answer_label": "", - "header": "What is the tenant code?", - "type": "text" - } - } } } } @@ -538,3 +24,4 @@ } } } + \ No newline at end of file From 152e3a17f0d4533d424c953ba455b76a5f066779 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Wed, 10 Nov 2021 09:58:45 +0000 Subject: [PATCH 13/55] . --- config/forms/schema/test.json | 1 + 1 file changed, 1 insertion(+) diff --git a/config/forms/schema/test.json b/config/forms/schema/test.json index 998146adf..9058f70c4 100644 --- a/config/forms/schema/test.json +++ b/config/forms/schema/test.json @@ -45,6 +45,7 @@ }, "pages": { "type": "object", + "required": ["header"], "patternProperties": { "^[0-9]+$": { "properties": { From 15bbe798df52c1711b09fb09469917087d486917 Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Wed, 10 Nov 2021 13:55:10 +0000 Subject: [PATCH 14/55] Cldc 591/further data changes (#83) * Remove condition_effects_prefer_not_to_say field * Change reason type * Remove prefer not to say from illness * add majorrepairs,propcode and infer postcode * Update previous location and la * Update majorrepairs, national and reasonpref * Update housing benefits fields * rename file * Add previous postcode * Move inferred postcode to model * refactor infered poscode method * Remove unneeded import * update miration and some mappings * Remove duplicate migration command --- Gemfile | 1 + Gemfile.lock | 2 + app/admin/case_logs.rb | 2 +- app/constants/db_enums.rb | 448 +++++++++++++++++- app/models/case_log.rb | 35 +- app/validations/financial_validations.rb | 8 +- app/validations/household_validations.rb | 4 +- config/forms/2021_2022.json | 63 +-- .../20211108134601_further_core_migrations.rb | 57 +++ db/schema.rb | 25 +- docs/api/DLUHC-CORE-Data.v1.json | 36 +- spec/controllers/case_logs_controller_spec.rb | 27 ++ spec/factories/case_log.rb | 4 +- spec/features/case_log_spec.rb | 6 +- spec/fixtures/complete_case_log.json | 23 +- spec/fixtures/forms/test_form.json | 12 +- spec/helpers/check_answers_helper_spec.rb | 2 +- spec/helpers/tasklist_helper_spec.rb | 2 +- spec/models/case_log_spec.rb | 14 +- spec/models/form_spec.rb | 2 +- 20 files changed, 676 insertions(+), 97 deletions(-) create mode 100644 db/migrate/20211108134601_further_core_migrations.rb diff --git a/Gemfile b/Gemfile index fa743fa4a..8308b7274 100644 --- a/Gemfile +++ b/Gemfile @@ -29,6 +29,7 @@ gem "discard" gem "activeadmin" # Admin charts gem "chartkick" +gem "uk_postcode" group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console diff --git a/Gemfile.lock b/Gemfile.lock index fa3d1a27d..c7ce5acfe 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -358,6 +358,7 @@ GEM rails (>= 6.0.0) tzinfo (2.0.4) concurrent-ruby (~> 1.0) + uk_postcode (2.1.6) unicode-display_width (2.1.0) view_component (2.39.0) activesupport (>= 5.0.0, < 8.0) @@ -417,6 +418,7 @@ DEPENDENCIES selenium-webdriver simplecov tzinfo-data + uk_postcode web-console (>= 4.1.0) webpacker (~> 5.0) diff --git a/app/admin/case_logs.rb b/app/admin/case_logs.rb index f14d33a3a..c3716ad6d 100644 --- a/app/admin/case_logs.rb +++ b/app/admin/case_logs.rb @@ -2,7 +2,7 @@ ActiveAdmin.register CaseLog do # See permitted parameters documentation: # https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters permit_params do - permitted = %i[status tenant_code age1 sex1 tenant_ethnic_group tenant_nationality previous_housing_situation armed_forces ecstat1 hhmemb relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 person_7_gender ecstat7 relat8 age8 sex8 ecstat8 homelessness reason_for_leaving_last_settled_home benefit_cap_spare_room_subsidy armed_forces_active armed_forces_injured armed_forces_partner medical_conditions pregnancy accessibility_requirements condition_effects tenancy_code tenancy_start_date starter_tenancy fixed_term_tenancy tenancy_type letting_type letting_provider property_location previous_postcode property_relet property_vacancy_reason property_reference property_unit_type property_building_type property_number_of_bedrooms property_void_date property_major_repairs property_major_repairs_date property_number_of_times_relet property_wheelchair_accessible net_income net_income_frequency net_income_uc_proportion housing_benefit rent_frequency basic_rent service_charge personal_service_charge support_charge total_charge outstanding_amount time_lived_in_la time_on_la_waiting_list previous_la property_postcode reasonable_preference reasonable_preference_reason cbl_letting chr_letting cap_letting outstanding_rent_or_charges other_reason_for_leaving_last_settled_home accessibility_requirements_fully_wheelchair_accessible_housing accessibility_requirements_wheelchair_access_to_essential_rooms accessibility_requirements_level_access_housing accessibility_requirements_other_disability_requirements accessibility_requirements_no_disability_requirements accessibility_requirements_do_not_know accessibility_requirements_prefer_not_to_say condition_effects_vision condition_effects_hearing condition_effects_mobility condition_effects_dexterity condition_effects_stamina condition_effects_learning condition_effects_memory condition_effects_mental_health condition_effects_social_or_behavioral condition_effects_other condition_effects_prefer_not_to_say reasonable_preference_reason_homeless reasonable_preference_reason_unsatisfactory_housing reasonable_preference_reason_medical_grounds reasonable_preference_reason_avoid_hardship reasonable_preference_reason_do_not_know other_tenancy_type override_net_income_validation net_income_known] + permitted = %i[status tenant_code age1 sex1 tenant_ethnic_group tenant_nationality previous_housing_situation armed_forces ecstat1 hhmemb relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 person_7_gender ecstat7 relat8 age8 sex8 ecstat8 homelessness reason benefit_cap_spare_room_subsidy armed_forces_active armed_forces_injured armed_forces_partner medical_conditions pregnancy accessibility_requirements condition_effects tenancy_code tenancy_start_date starter_tenancy fixed_term_tenancy tenancy_type letting_type letting_provider la previous_postcode property_relet property_vacancy_reason property_reference property_unit_type property_building_type property_number_of_bedrooms property_void_date property_major_repairs property_major_repairs_date property_number_of_times_relet property_wheelchair_accessible net_income net_income_frequency net_income_uc_proportion hb rent_frequency basic_rent service_charge personal_service_charge support_charge total_charge tshortfall time_lived_in_la time_on_la_waiting_list prevloc property_postcode reasonable_preference reasonable_preference_reason cbl_letting chr_letting cap_letting hbrentshortfall other_reason accessibility_requirements_fully_wheelchair_accessible_housing accessibility_requirements_wheelchair_access_to_essential_rooms accessibility_requirements_level_access_housing accessibility_requirements_other_disability_requirements accessibility_requirements_no_disability_requirements accessibility_requirements_do_not_know accessibility_requirements_prefer_not_to_say condition_effects_vision condition_effects_hearing condition_effects_mobility condition_effects_dexterity condition_effects_stamina condition_effects_learning condition_effects_memory condition_effects_mental_health condition_effects_social_or_behavioral condition_effects_other condition_effects_prefer_not_to_say reasonable_preference_reason_homeless reasonable_preference_reason_unsatisfactory_housing reasonable_preference_reason_medical_grounds reasonable_preference_reason_avoid_hardship reasonable_preference_reason_do_not_know other_tenancy_type override_net_income_validation net_income_known] permitted end diff --git a/app/constants/db_enums.rb b/app/constants/db_enums.rb index 84f7d3837..23e4b4bd4 100644 --- a/app/constants/db_enums.rb +++ b/app/constants/db_enums.rb @@ -20,7 +20,7 @@ module DbEnums "Not seeking work" => 6, "Full-time student" => 7, "Unable to work because of long term sick or disability" => 8, - "Child under 16" => 100, + "Child under 16" => 9, "Other" => 0, "Prefer not to say" => 10, } @@ -63,7 +63,6 @@ module DbEnums "Yes" => 1, "No" => 2, "Do not know" => 3, - "Prefer not to say" => 100, } end @@ -91,6 +90,8 @@ module DbEnums "Bulgaria" => 14, "Romania" => 15, "Ireland" => 17, + "Slovenia" => 10, + "Croatia" => 16, "Other EU Economic Area (EEA country)" => 11, "Any other country" => 12, "Prefer not to say" => 13, @@ -155,6 +156,14 @@ module DbEnums } end + def self.polar_with_unknown + { + "No" => 2, + "Yes" => 1, + "Do not know" => 3, + } + end + def self.tenancy { "Fixed term – Secure" => 1, @@ -256,4 +265,439 @@ module DbEnums "Do not know" => 6, } end + + def self.housing_benefit + { + "Housing Benefit, but not Universal Credit" => 1, + "Universal Credit with housing element, but not Housing Benefit" => 6, + "Universal Credit without housing element and no Housing Benefit" => 7, + "Universal Credit and Housing Benefit" => 8, + "Not Housing Benefit or Universal Credit" => 9, + "Do not know" => 3, + "Prefer not to say" => 100, + } + end + + def self.reason + { + "Permanently decanted from another property owned by this landlord" => 1, + "Left home country as a refugee" => 2, + "Loss of tied accommodation" => 4, + "Domestic abuse" => 7, + "(Non violent) relationship breakdown with partner" => 8, + "Asked to leave by family or friends" => 9, + "Racial harassment" => 10, + "Other problems with neighbours" => 11, + "Property unsuitable because of overcrowding" => 12, + "End of assured shorthold tenancy - no fault" => 40, + "End of assured shorthold tenancy - tenant's fault" => 41, + "End of fixed term tenancy - no fault" => 42, + "End of fixed term tenancy - tenant's fault" => 43, + "Repossession" => 34, + "Under occupation - offered incentive to downsize" => 29, + "Under occupation - no incentive" => 30, + "Property unsuitable because of ill health / disability" => 13, + "Property unsuitable because of poor condition" => 14, + "Couldn't afford fees attached to renewing the tenancy" => 35, + "Couldn't afford increase in rent" => 36, + "Couldn't afford rent or mortgage - welfare reforms" => 37, + "Couldn't afford rent or mortgage - employment" => 38, + "Couldn't afford rent or mortgage - other" => 39, + "To move nearer to family / friends / school" => 16, + "To move nearer to work" => 17, + "To move to accomodation with support" => 18, + "To move to independent accomodation" => 19, + "Hate crime" => 31, + "Death of household member in last settled accomodation" => 46, + "Discharged from prison" => 44, + "Discharged from long stay hospital or similar institution" => 45, + "Other" => 20, + "Do not know" => 28, + "Prefer not to say" => 100, + } + end + + def self.la + { + "Hartlepool" => "E06000001", + "Na h-Eileanan Siar" => "S12000013", + "Middlesbrough" => "E06000002", + "Redcar and Cleveland" => "E06000003", + "Stockton-on-Tees" => "E06000004", + "Darlington" => "E06000005", + "Halton" => "E06000006", + "Warrington" => "E06000007", + "Blackburn with Darwen" => "E06000008", + "Blackpool" => "E06000009", + "Kingston upon Hull, City of" => "E06000010", + "East Riding of Yorkshire" => "E06000011", + "North East Lincolnshire" => "E06000012", + "North Lincolnshire" => "E06000013", + "York" => "E06000014", + "Derby" => "E06000015", + "Leicester" => "E06000016", + "Rutland" => "E06000017", + "Nottingham" => "E06000018", + "Herefordshire, County of" => "E06000019", + "Telford and Wrekin" => "E06000020", + "Stoke-on-Trent" => "E06000021", + "Bath and North East Somerset" => "E06000022", + "Bristol, City of" => "E06000023", + "North Somerset" => "E06000024", + "South Gloucestershire" => "E06000025", + "Plymouth" => "E06000026", + "Torbay" => "E06000027", + "Swindon" => "E06000030", + "Peterborough" => "E06000031", + "Luton" => "E06000032", + "Southend-on-Sea" => "E06000033", + "Thurrock" => "E06000034", + "Medway" => "E06000035", + "Bracknell Forest" => "E06000036", + "West Berkshire" => "E06000037", + "Reading" => "E06000038", + "Slough" => "E06000039", + "Windsor and Maidenhead" => "E06000040", + "Wokingham" => "E06000041", + "Milton Keynes" => "E06000042", + "Brighton and Hove" => "E06000043", + "Portsmouth" => "E06000044", + "Southampton" => "E06000045", + "Isle of Wight" => "E06000046", + "County Durham" => "E06000047", + "Cheshire East" => "E06000049", + "Cheshire West and Chester" => "E06000050", + "Shropshire" => "E06000051", + "Cornwall" => "E06000052", + "Isles of Scilly" => "E06000053", + "Wiltshire" => "E06000054", + "Bedford" => "E06000055", + "Central Bedfordshire" => "E06000056", + "Northumberland" => "E06000057", + "Bournemouth, Christchurch and Poole" => "E06000058", + "North Warwickshire" => "E07000218", + "Nuneaton and Bedworth" => "E07000219", + "Rugby" => "E07000220", + "Stratford-on-Avon" => "E07000221", + "Warwick" => "E07000222", + "Adur" => "E07000223", + "Arun" => "E07000224", + "Chichester" => "E07000225", + "Crawley" => "E07000226", + "Horsham" => "E07000227", + "Mid Sussex" => "E07000228", + "Worthing" => "E07000229", + "Bromsgrove" => "E07000234", + "Malvern Hills" => "E07000235", + "Redditch" => "E07000236", + "Worcester" => "E07000237", + "Wychavon" => "E07000238", + "Wyre Forest" => "E07000239", + "St Albans" => "E07000240", + "Welwyn Hatfield" => "E07000241", + "East Hertfordshire" => "E07000242", + "Stevenage" => "E07000243", + "East Suffolk" => "E07000244", + "West Suffolk" => "E07000245", + "Somerset West and Taunton" => "E07000246", + "Bolton" => "E08000001", + "Bury" => "E08000002", + "Manchester" => "E08000003", + "Oldham" => "E08000004", + "Rochdale" => "E08000005", + "Salford" => "E08000006", + "Stockport" => "E08000007", + "Tameside" => "E08000008", + "Trafford" => "E08000009", + "Wigan" => "E08000010", + "Knowsley" => "E08000011", + "Liverpool" => "E08000012", + "St. Helens" => "E08000013", + "Sefton" => "E08000014", + "Wirral" => "E08000015", + "Barnsley" => "E08000016", + "Doncaster" => "E08000017", + "Rotherham" => "E08000018", + "Sheffield" => "E08000019", + "Newcastle upon Tyne" => "E08000021", + "North Tyneside" => "E08000022", + "South Tyneside" => "E08000023", + "Sunderland" => "E08000024", + "Birmingham" => "E08000025", + "Coventry" => "E08000026", + "Dudley" => "E08000027", + "Sandwell" => "E08000028", + "Solihull" => "E08000029", + "Walsall" => "E08000030", + "Dorset" => "E06000059", + "Wolverhampton" => "E08000031", + "Falkirk" => "S12000014", + "Highland" => "S12000017", + "Inverclyde" => "S12000018", + "Midlothian" => "S12000019", + "Moray" => "S12000020", + "North Ayrshire" => "S12000021", + "Orkney Islands" => "S12000023", + "Scottish Borders" => "S12000026", + "Shetland Islands" => "S12000027", + "South Ayrshire" => "S12000028", + "South Lanarkshire" => "S12000029", + "Stirling" => "S12000030", + "Aberdeen City" => "S12000033", + "Aberdeenshire" => "S12000034", + "Argyll and Bute" => "S12000035", + "City of Edinburgh" => "S12000036", + "Renfrewshire" => "S12000038", + "West Dunbartonshire" => "S12000039", + "West Lothian" => "S12000040", + "Angus" => "S12000041", + "Dundee City" => "S12000042", + "East Dunbartonshire" => "S12000045", + "Buckinghamshire" => "E06000060", + "Fife" => "S12000047", + "Cambridge" => "E07000008", + "Perth and Kinross" => "S12000048", + "East Cambridgeshire" => "E07000009", + "Glasgow City" => "S12000049", + "Fenland" => "E07000010", + "North Lanarkshire" => "S12000050", + "Huntingdonshire" => "E07000011", + "Isle of Anglesey" => "W06000001", + "South Cambridgeshire" => "E07000012", + "Gwynedd" => "W06000002", + "Allerdale" => "E07000026", + "Conwy" => "W06000003", + "Barrow-in-Furness" => "E07000027", + "Denbighshire" => "W06000004", + "Carlisle" => "E07000028", + "Flintshire" => "W06000005", + "Copeland" => "E07000029", + "Wrexham" => "W06000006", + "Eden" => "E07000030", + "Ceredigion" => "W06000008", + "South Lakeland" => "E07000031", + "Pembrokeshire" => "W06000009", + "Amber Valley" => "E07000032", + "Carmarthenshire" => "W06000010", + "Bolsover" => "E07000033", + "Swansea" => "W06000011", + "Chesterfield" => "E07000034", + "Neath Port Talbot" => "W06000012", + "Derbyshire Dales" => "E07000035", + "Bridgend" => "W06000013", + "Erewash" => "E07000036", + "Vale of Glamorgan" => "W06000014", + "High Peak" => "E07000037", + "Cardiff" => "W06000015", + "North East Derbyshire" => "E07000038", + "Rhondda Cynon Taf" => "W06000016", + "South Derbyshire" => "E07000039", + "Caerphilly" => "W06000018", + "East Devon" => "E07000040", + "Blaenau Gwent" => "W06000019", + "Exeter" => "E07000041", + "Torfaen" => "W06000020", + "Mid Devon" => "E07000042", + "Monmouthshire" => "W06000021", + "North Devon" => "E07000043", + "Newport" => "W06000022", + "South Hams" => "E07000044", + "Powys" => "W06000023", + "Teignbridge" => "E07000045", + "Merthyr Tydfil" => "W06000024", + "Torridge" => "E07000046", + "West Devon" => "E07000047", + "Eastbourne" => "E07000061", + "Hastings" => "E07000062", + "Lewes" => "E07000063", + "Rother" => "E07000064", + "Wealden" => "E07000065", + "Basildon" => "E07000066", + "Braintree" => "E07000067", + "Brentwood" => "E07000068", + "Castle Point" => "E07000069", + "Chelmsford" => "E07000070", + "Colchester" => "E07000071", + "Epping Forest" => "E07000072", + "Harlow" => "E07000073", + "Maldon" => "E07000074", + "Rochford" => "E07000075", + "Tendring" => "E07000076", + "Uttlesford" => "E07000077", + "Cheltenham" => "E07000078", + "Cotswold" => "E07000079", + "Forest of Dean" => "E07000080", + "Gloucester" => "E07000081", + "Stroud" => "E07000082", + "Tewkesbury" => "E07000083", + "Basingstoke and Deane" => "E07000084", + "East Hampshire" => "E07000085", + "King’s Lynn and West Norfolk" => "E07000146", + "Eastleigh" => "E07000086", + "North Norfolk" => "E07000147", + "Norwich" => "E07000148", + "South Norfolk" => "E07000149", + "Corby" => "E07000150", + "Daventry" => "E07000151", + "East Northamptonshire" => "E07000152", + "Kettering" => "E07000153", + "Northampton" => "E07000154", + "South Northamptonshire" => "E07000155", + "Wellingborough" => "E07000156", + "Craven" => "E07000163", + "Hambleton" => "E07000164", + "Harrogate" => "E07000165", + "Richmondshire" => "E07000166", + "Ryedale" => "E07000167", + "Scarborough" => "E07000168", + "Selby" => "E07000169", + "Ashfield" => "E07000170", + "Bassetlaw" => "E07000171", + "Broxtowe" => "E07000172", + "Gedling" => "E07000173", + "Mansfield" => "E07000174", + "Newark and Sherwood" => "E07000175", + "Rushcliffe" => "E07000176", + "Cherwell" => "E07000177", + "Oxford" => "E07000178", + "South Oxfordshire" => "E07000179", + "Vale of White Horse" => "E07000180", + "West Oxfordshire" => "E07000181", + "Mendip" => "E07000187", + "Sedgemoor" => "E07000188", + "South Somerset" => "E07000189", + "Cannock Chase" => "E07000192", + "East Staffordshire" => "E07000193", + "Lichfield" => "E07000194", + "Newcastle-under-Lyme" => "E07000195", + "South Staffordshire" => "E07000196", + "Stafford" => "E07000197", + "Staffordshire Moorlands" => "E07000198", + "Tamworth" => "E07000199", + "Babergh" => "E07000200", + "Ipswich" => "E07000202", + "Mid Suffolk" => "E07000203", + "Elmbridge" => "E07000207", + "Epsom and Ewell" => "E07000208", + "Guildford" => "E07000209", + "Mole Valley" => "E07000210", + "Reigate and Banstead" => "E07000211", + "Runnymede" => "E07000212", + "Spelthorne" => "E07000213", + "Surrey Heath" => "E07000214", + "Tandridge" => "E07000215", + "Waverley" => "E07000216", + "Woking" => "E07000217", + "Fareham" => "E07000087", + "Gosport" => "E07000088", + "Hart" => "E07000089", + "Havant" => "E07000090", + "New Forest" => "E07000091", + "Rushmoor" => "E07000092", + "Test Valley" => "E07000093", + "Winchester" => "E07000094", + "Broxbourne" => "E07000095", + "Dacorum" => "E07000096", + "Hertsmere" => "E07000098", + "North Hertfordshire" => "E07000099", + "Three Rivers" => "E07000102", + "Watford" => "E07000103", + "Ashford" => "E07000105", + "Canterbury" => "E07000106", + "Dartford" => "E07000107", + "Dover" => "E07000108", + "Gravesham" => "E07000109", + "Maidstone" => "E07000110", + "Sevenoaks" => "E07000111", + "Folkestone and Hythe" => "E07000112", + "Swale" => "E07000113", + "Thanet" => "E07000114", + "Tonbridge and Malling" => "E07000115", + "Tunbridge Wells" => "E07000116", + "Burnley" => "E07000117", + "Chorley" => "E07000118", + "Fylde" => "E07000119", + "Hyndburn" => "E07000120", + "Lancaster" => "E07000121", + "Pendle" => "E07000122", + "Preston" => "E07000123", + "Ribble Valley" => "E07000124", + "Rossendale" => "E07000125", + "South Ribble" => "E07000126", + "West Lancashire" => "E07000127", + "Wyre" => "E07000128", + "Blaby" => "E07000129", + "Charnwood" => "E07000130", + "Harborough" => "E07000131", + "Hinckley and Bosworth" => "E07000132", + "Melton" => "E07000133", + "North West Leicestershire" => "E07000134", + "Oadby and Wigston" => "E07000135", + "Boston" => "E07000136", + "East Lindsey" => "E07000137", + "Lincoln" => "E07000138", + "North Kesteven" => "E07000139", + "South Holland" => "E07000140", + "South Kesteven" => "E07000141", + "West Lindsey" => "E07000142", + "Breckland" => "E07000143", + "Broadland" => "E07000144", + "Great Yarmouth" => "E07000145", + "Bradford" => "E08000032", + "Calderdale" => "E08000033", + "Kirklees" => "E08000034", + "Leeds" => "E08000035", + "Wakefield" => "E08000036", + "Gateshead" => "E08000037", + "City of London" => "E09000001", + "Barking and Dagenham" => "E09000002", + "Barnet" => "E09000003", + "Bexley" => "E09000004", + "Brent" => "E09000005", + "Bromley" => "E09000006", + "Camden" => "E09000007", + "Croydon" => "E09000008", + "Ealing" => "E09000009", + "Enfield" => "E09000010", + "Greenwich" => "E09000011", + "Hackney" => "E09000012", + "Hammersmith and Fulham" => "E09000013", + "Haringey" => "E09000014", + "Harrow" => "E09000015", + "Havering" => "E09000016", + "Hillingdon" => "E09000017", + "Hounslow" => "E09000018", + "Islington" => "E09000019", + "Kensington and Chelsea" => "E09000020", + "Kingston upon Thames" => "E09000021", + "Lambeth" => "E09000022", + "Lewisham" => "E09000023", + "Merton" => "E09000024", + "Newham" => "E09000025", + "Redbridge" => "E09000026", + "Richmond upon Thames" => "E09000027", + "Southwark" => "E09000028", + "Sutton" => "E09000029", + "Tower Hamlets" => "E09000030", + "Waltham Forest" => "E09000031", + "Wandsworth" => "E09000032", + "Westminster" => "E09000033", + "Antrim and Newtownabbey" => "N09000001", + "Armagh City, Banbridge and Craigavon" => "N09000002", + "Belfast" => "N09000003", + "Causeway Coast and Glens" => "N09000004", + "Derry City and Strabane" => "N09000005", + "Fermanagh and Omagh" => "N09000006", + "Lisburn and Castlereagh" => "N09000007", + "Mid and East Antrim" => "N09000008", + "Mid Ulster" => "N09000009", + "Newry, Mourne and Down" => "N09000010", + "Ards and North Down" => "N09000011", + "Clackmannanshire" => "S12000005", + "Dumfries and Galloway" => "S12000006", + "East Ayrshire" => "S12000008", + "East Lothian" => "S12000010", + "East Renfrewshire" => "S12000011", + } + end end diff --git a/app/models/case_log.rb b/app/models/case_log.rb index b77534795..c058fb5f3 100644 --- a/app/models/case_log.rb +++ b/app/models/case_log.rb @@ -101,7 +101,14 @@ class CaseLog < ApplicationRecord enum period: DbEnums.period, _suffix: true enum layear: DbEnums.latime, _suffix: true enum lawaitlist: DbEnums.latime, _suffix: true - enum reasonpref: DbEnums.polar2, _suffix: true + enum reasonpref: DbEnums.polar_with_unknown, _suffix: true + enum reason: DbEnums.reason, _suffix: true + enum la: DbEnums.la, _suffix: true + enum prevloc: DbEnums.la, _suffix: true + enum majorrepairs: DbEnums.polar, _suffix: true + enum hb: DbEnums.housing_benefit, _suffix: true + enum hbrentshortfall: DbEnums.polar_with_unknown, _suffix: true + enum property_relet: DbEnums.polar, _suffix: true AUTOGENERATED_FIELDS = %w[id status created_at updated_at discarded_at].freeze @@ -132,6 +139,30 @@ class CaseLog < ApplicationRecord end end + def postcode + if property_postcode.present? + UKPostcode.parse(property_postcode).outcode + end + end + + def postcod2 + if property_postcode.present? + UKPostcode.parse(property_postcode).incode + end + end + + def ppostc1 + if previous_postcode.present? + UKPostcode.parse(previous_postcode).outcode + end + end + + def ppostc2 + if previous_postcode.present? + UKPostcode.parse(previous_postcode).incode + end + end + def applicable_income_range return unless ecstat1 @@ -163,7 +194,7 @@ private dynamically_not_required = [] - if reason_for_leaving_last_settled_home != "Other" + if reason != "Other" dynamically_not_required << "other_reason_for_leaving_last_settled_home" end diff --git a/app/validations/financial_validations.rb b/app/validations/financial_validations.rb index dd4b58baf..3d2ce8732 100644 --- a/app/validations/financial_validations.rb +++ b/app/validations/financial_validations.rb @@ -2,11 +2,11 @@ module FinancialValidations # Validations methods need to be called 'validate_' to run on model save # or 'validate_' to run on submit as well def validate_outstanding_rent_amount(record) - if record.outstanding_rent_or_charges == "Yes" && record.outstanding_amount.blank? - record.errors.add :outstanding_amount, "You must answer the oustanding amout question if you have outstanding rent or charges." + if record.hbrentshortfall == "Yes" && record.tshortfall.blank? + record.errors.add :tshortfall, "You must answer the oustanding amout question if you have outstanding rent or charges." end - if record.outstanding_rent_or_charges == "No" && record.outstanding_amount.present? - record.errors.add :outstanding_amount, "You must not answer the oustanding amout question if you don't have outstanding rent or charges." + if record.hbrentshortfall == "No" && record.tshortfall.present? + record.errors.add :tshortfall, "You must not answer the oustanding amout question if you don't have outstanding rent or charges." end end diff --git a/app/validations/household_validations.rb b/app/validations/household_validations.rb index ca8d887e9..b36972667 100644 --- a/app/validations/household_validations.rb +++ b/app/validations/household_validations.rb @@ -16,11 +16,11 @@ module HouseholdValidations end def validate_other_reason_for_leaving_last_settled_home(record) - validate_other_field(record, "reason_for_leaving_last_settled_home", "other_reason_for_leaving_last_settled_home") + validate_other_field(record, "reason", "other_reason_for_leaving_last_settled_home") end def validate_reason_for_leaving_last_settled_home(record) - if record.reason_for_leaving_last_settled_home == "Do not know" && record.underoccupation_benefitcap != "Do not know" + if record.reason == "Do not know" && record.underoccupation_benefitcap != "Do not know" record.errors.add :underoccupation_benefitcap, "must be do not know if tenant’s main reason for leaving is do not know" end end diff --git a/config/forms/2021_2022.json b/config/forms/2021_2022.json index 5229155e0..52d80f8ee 100644 --- a/config/forms/2021_2022.json +++ b/config/forms/2021_2022.json @@ -273,21 +273,23 @@ "type": "radio", "answer_options": { "0": "UK national resident in UK", - "1": "A current or former reserve in the UK Armed Forces (exc. National Service)", - "2": "UK national returning from residence overseas", - "3": "Czech Republic", - "4": "Estonia", - "5": "Hungary", - "6": "Latvia", - "7": "Lithuania", - "8": "Poland", - "9": "Slovakia", - "10": "Bulgaria", - "11": "Romania", - "12": "Ireland", - "13": "Other EU Economic Area (EEA country)", - "14": "Any other country", - "15": "Prefer not to say" + "1": "UK national returning from residence overseas", + "2": "Czech Republic", + "3": "Estonia", + "4": "Hungary", + "5": "Latvia", + "6": "Lithuania", + "7": "Poland", + "8": "Slovakia", + "9": "Bulgaria", + "10": "Romania", + "11": "Ireland", + "12": "Slovakia", + "13":"Slovenia", + "14": "Croatia", + "15": "Other EU Economic Area (EEA country)", + "16": "Any other country", + "17": "Prefer not to say" } } } @@ -796,7 +798,7 @@ "header": "Leaving their last settled home", "description": "", "questions": { - "reason_for_leaving_last_settled_home": { + "reason": { "header": "What is the tenant’s main reason for leaving?", "hint_text": "", "type": "radio", @@ -934,8 +936,7 @@ "answer_options": { "0": "Yes", "1": "No", - "2": "Do not know", - "3": "Prefer not to say" + "2": "Prefer not to say" } } } @@ -999,9 +1000,7 @@ "illness_type_6": "Memory", "illness_type_7": "Mental health - such as depression, anxiety, schizophrenia or bipolar", "illness_type_9": "Socially or behaviourally - such as those associated with autism spectral disorder (ASD) including Aspergers’ or attention deficit hyperactivity disorder (ADHD))", - "illness_type_10": "Other", - "divider": true, - "condition_effects_prefer_not_to_say": "Prefer not to say" + "illness_type_10": "Other" } } } @@ -1144,7 +1143,7 @@ "header": "", "description": "", "questions": { - "property_location": { + "la": { "check_answer_label": "Property Location", "header": "Property location", "hint_text": "", @@ -1527,7 +1526,7 @@ "header": "", "description": "", "questions": { - "property_reference": { + "propcode": { "check_answer_label": "What’s the property reference?", "header": "What's the property reference?", "hint_text": "", @@ -1576,7 +1575,7 @@ "header": "", "description": "", "questions": { - "property_major_repairs": { + "majorrepairs": { "check_answer_label": "Were major repairs carried out during the void period?", "header": "Were any major repairs completed during the void period?", "hint_text": "", @@ -1709,7 +1708,7 @@ "header": "", "description": "", "questions": { - "housing_benefit": { + "hb": { "check_answer_label": "Universal Credit & Housing Benefit", "header": "Is the tenant likely to be in receipt of any of these housing-related benefits?", "hint_text": "", @@ -1822,20 +1821,21 @@ "step": 1, "readonly": true }, - "outstanding_rent_or_charges": { + "hbrentshortfall": { "check_answer_label": "After housing benefit and/or housing element of UC payment is received, will there be an outstanding amount for basic rent and/or benefit eligible charges?", "header": "After housing benefit and/or housing element of UC payment is received, will there be an outstanding amount for basic rent and/or benefit eligible charges?", "hint_text": "", "type": "radio", "answer_options": { "0": "Yes", - "1": "No" + "1": "No", + "2": "Do not know" }, "conditional_for": { - "outstanding_amount": ["Yes"] + "tshortfall": ["Yes"] } }, - "outstanding_amount": { + "tshortfall": { "check_answer_label": "Outstanding amount", "header": "What do you expect the amount to be?", "hint_text": "If the amount is unknown you can estimate", @@ -1903,7 +1903,7 @@ "header": "", "description": "", "questions": { - "previous_la": { + "prevloc": { "check_answer_label": "The LA in which household lived immediately before this letting\t", "header": "Which local authority area did the household live in immediately before this letting?", "hint_text": "Includes temporary accommodation", @@ -2249,7 +2249,8 @@ "type": "radio", "answer_options": { "0": "Yes", - "1": "No" + "1": "No", + "2": "Do not know" }, "conditional_for": { "reasonable_preference_reason": ["Yes"] diff --git a/db/migrate/20211108134601_further_core_migrations.rb b/db/migrate/20211108134601_further_core_migrations.rb new file mode 100644 index 000000000..b6008e66e --- /dev/null +++ b/db/migrate/20211108134601_further_core_migrations.rb @@ -0,0 +1,57 @@ +class FurtherCoreMigrations < ActiveRecord::Migration[6.1] + def up + change_table :case_logs, bulk: true do |t| + t.remove :condition_effects_prefer_not_to_say + t.remove :reason_for_leaving_last_settled_home + t.column :reason, :integer + t.remove :property_reference + t.column :propcode, :string + t.remove :property_major_repairs + t.column :majorrepairs, :integer + t.remove :property_location + t.column :la, :string + t.remove :previous_la + t.column :prevloc, :string + t.remove :housing_benefit + t.column :hb, :integer + t.remove :outstanding_rent_or_charges + t.column :hbrentshortfall, :integer + t.remove :outstanding_amount + t.column :tshortfall, :integer + t.column :postcode, :string + t.column :postcod2, :string + t.column :ppostc1, :string + t.column :ppostc2, :string + t.remove :property_relet + t.column :property_relet, :integer + end + end + + def down + change_table :case_logs, bulk: true do |t| + t.column :condition_effects_prefer_not_to_say, :integer + t.column :reason_for_leaving_last_settled_home, :string + t.remove :reason + t.column :property_reference, :string + t.remove :propcode + t.column :property_major_repairs, :string + t.remove :majorrepairs + t.column :property_location, :string + t.remove :la + t.column :previous_la, :string + t.remove :prevloc + t.column :housing_benefit, :string + t.remove :hb + t.column :outstanding_rent_or_charges, :string + t.remove :hbrentshortfall + t.column :outstanding_amount, :string + t.remove :tshortfall + t.remove :postcode + t.remove :postcod2 + t.remove :ppostc1 + t.remove :ppostc2 + t.remove :property_relet + t.column :property_relet, :string + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 005086022..a1b19f7f2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_11_08_091320) do +ActiveRecord::Schema.define(version: 2021_11_08_134601) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -57,7 +57,6 @@ ActiveRecord::Schema.define(version: 2021_11_08_091320) do t.string "sex8" t.integer "ecstat8" t.integer "homeless" - t.string "reason_for_leaving_last_settled_home" t.integer "underoccupation_benefitcap" t.integer "leftreg" t.integer "reservist" @@ -73,40 +72,32 @@ ActiveRecord::Schema.define(version: 2021_11_08_091320) do t.integer "tenancy" t.string "lettype" t.integer "landlord" - t.string "property_location" t.string "previous_postcode" - t.string "property_relet" t.integer "rsnvac" - t.string "property_reference" t.integer "unittype_gn" t.string "property_building_type" t.integer "beds" t.string "property_void_date" - t.string "property_major_repairs" t.string "property_major_repairs_date" t.integer "offered" t.integer "wchair" t.integer "earnings" t.integer "incfreq" t.integer "benefits" - t.string "housing_benefit" t.integer "period" t.integer "brent" t.integer "scharge" t.integer "pscharge" t.integer "supcharg" t.integer "tcharge" - t.string "outstanding_amount" t.integer "layear" t.integer "lawaitlist" - t.string "previous_la" t.string "property_postcode" t.integer "reasonpref" t.string "reasonable_preference_reason" t.integer "cbl" t.integer "chr" t.integer "cap" - t.string "outstanding_rent_or_charges" t.string "other_reason_for_leaving_last_settled_home" t.integer "housingneeds_a" t.integer "housingneeds_b" @@ -125,7 +116,6 @@ ActiveRecord::Schema.define(version: 2021_11_08_091320) do t.integer "illness_type_7" t.integer "illness_type_9" t.integer "illness_type_10" - t.integer "condition_effects_prefer_not_to_say" t.integer "rp_homeless" t.integer "rp_insan_unsat" t.integer "rp_medwel" @@ -146,6 +136,19 @@ ActiveRecord::Schema.define(version: 2021_11_08_091320) do t.string "needs_type" t.string "sale_completion_date" t.string "purchaser_code" + t.integer "reason" + t.string "propcode" + t.integer "majorrepairs" + t.string "la" + t.string "prevloc" + t.integer "hb" + t.integer "hbrentshortfall" + t.integer "tshortfall" + t.string "postcode" + t.string "postcod2" + t.string "ppostc1" + t.string "ppostc2" + t.integer "property_relet" t.index ["discarded_at"], name: "index_case_logs_on_discarded_at" end diff --git a/docs/api/DLUHC-CORE-Data.v1.json b/docs/api/DLUHC-CORE-Data.v1.json index 47c068472..654307a59 100644 --- a/docs/api/DLUHC-CORE-Data.v1.json +++ b/docs/api/DLUHC-CORE-Data.v1.json @@ -293,7 +293,7 @@ "sex8": "Prefer not to say", "ecstat8": "Child under 16", "homeless": "No", - "reason_for_leaving_last_settled_home": "Other problems with neighbours", + "reason": "Other problems with neighbours", "underoccupation_benefitcap": "No", "leftreg": "No", "reservist": "No", @@ -309,7 +309,7 @@ "tenancy": "Fixed term – Secure", "lettype": "Affordable Rent - General Needs", "landlord": "This landlord", - "property_location": "Barnet", + "la": "Barnet", "previous_postcode": "NW1 5TY", "property_relet": "No", "rsnvac": "Relet - tenant abandoned property", @@ -325,24 +325,24 @@ "earnings": 1000, "incfreq": "Monthly", "benefits": "Some", - "housing_benefit": "Universal Credit with housing element, but not Housing Benefit", + "hb": "Universal Credit with housing element, but not Housing Benefit", "period": "Weekly", "brent": 200, "scharge": 50, "pscharge": 40, "supcharg": 35, "tcharge": 325, - "outstanding_amount": "Yes", + "tshortfall": "Yes", "layear": "1 to 2 years", "lawaitlist": "Less than 1 year", - "previous_la": "Ashford", + "prevloc": "Ashford", "property_postcode": "SE2 6RT", "reasonpref": "Yes", "reasonable_preference_reason": "dummy", "cbl": true, "chr": false, "cap": false, - "outstanding_rent_or_charges": 25, + "hbrentshortfall": "Yes", "other_reason_for_leaving_last_settled_home": "Other reason", "housingneeds_a": true, "housingneeds_b": false, @@ -727,7 +727,7 @@ "type": "string", "minLength": 1 }, - "reason_for_leaving_last_settled_home": { + "reason": { "type": "string", "minLength": 1, "enum": [ @@ -836,7 +836,7 @@ "type": "string", "minLength": 1 }, - "property_location": { + "la": { "type": "string", "minLength": 1 }, @@ -902,7 +902,7 @@ "minLength": 1, "enum": ["All", "Some", "None", "Do not know"] }, - "housing_benefit": { + "hb": { "type": "string", "minLength": 1 }, @@ -925,7 +925,7 @@ "tcharge": { "type": "number" }, - "outstanding_amount": { + "tshortfall": { "type": "string", "minLength": 1 }, @@ -937,7 +937,7 @@ "type": "string", "minLength": 1 }, - "previous_la": { + "prevloc": { "type": "string", "minLength": 1 }, @@ -962,7 +962,7 @@ "cap": { "type": "boolean" }, - "outstanding_rent_or_charges": { + "hbrentshortfall": { "type": "number" }, "other_reason_for_leaving_last_settled_home": { @@ -1082,7 +1082,7 @@ "sex8", "ecstat8", "homeless", - "reason_for_leaving_last_settled_home", + "reason", "underoccupation_benefitcap", "leftreg", "reservist", @@ -1098,7 +1098,7 @@ "tenancy", "lettype", "landlord", - "property_location", + "la", "previous_postcode", "property_relet", "rsnvac", @@ -1114,24 +1114,24 @@ "earnings", "incfreq", "benefits", - "housing_benefit", + "hb", "period", "brent", "scharge", "pscharge", "supcharg", "tcharge", - "outstanding_amount", + "tshortfall", "layear", "lawaitlist", - "previous_la", + "prevloc", "property_postcode", "reasonpref", "reasonable_preference_reason", "cbl", "chr", "cap", - "outstanding_rent_or_charges", + "hbrentshortfall", "other_reason_for_leaving_last_settled_home", "housingneeds_a", "housingneeds_b", diff --git a/spec/controllers/case_logs_controller_spec.rb b/spec/controllers/case_logs_controller_spec.rb index 2eecfdfe2..40d93cc59 100644 --- a/spec/controllers/case_logs_controller_spec.rb +++ b/spec/controllers/case_logs_controller_spec.rb @@ -150,6 +150,33 @@ RSpec.describe CaseLogsController, type: :controller do expect(response).to redirect_to("/case_logs/#{id}/conditional_question_no_page") end end + + context "partition postcode" do + let(:case_log_with_postcode) do + { + property_postcode: "M1 1AE", + previous_postcode: "M2 2AE", + page: "property_postcode", + } + end + it "saves full and partial postcodes" do + post :submit_form, params: { id: id, case_log: case_log_with_postcode } + case_log.reload + + expect(case_log.property_postcode).to eq("M1 1AE") + expect(case_log.postcode).to eq("M1") + expect(case_log.postcod2).to eq("1AE") + end + + it "saves full and partial previous postcodes" do + post :submit_form, params: { id: id, case_log: case_log_with_postcode } + case_log.reload + + expect(case_log.previous_postcode).to eq("M2 2AE") + expect(case_log.ppostc1).to eq("M2") + expect(case_log.ppostc2).to eq("2AE") + end + end end describe "get_next_page_path" do diff --git a/spec/factories/case_log.rb b/spec/factories/case_log.rb index 4528a7749..b46606279 100644 --- a/spec/factories/case_log.rb +++ b/spec/factories/case_log.rb @@ -4,8 +4,8 @@ FactoryBot.define do trait :in_progress do status { 1 } tenant_code { "TH356" } - property_postcode { "SW2 6HI" } - previous_postcode { "P0 5ST" } + property_postcode { "P0 5ST" } + previous_postcode { "SW2 6HI" } age1 { "17" } end trait :completed do diff --git a/spec/features/case_log_spec.rb b/spec/features/case_log_spec.rb index 0e2ae338b..aa53b8c7d 100644 --- a/spec/features/case_log_spec.rb +++ b/spec/features/case_log_spec.rb @@ -25,7 +25,7 @@ RSpec.describe "Test Features" do click_button("Save and continue") choose("case-log-benefits-all-field") click_button("Save and continue") - choose("case-log-housing-benefit-housing-benefit-but-not-universal-credit-field") + choose("case-log-hb-housing-benefit-but-not-universal-credit-field") click_button("Save and continue") end @@ -175,8 +175,8 @@ RSpec.describe "Test Features" do end it "displays number answers in inputs if they are already saved" do - visit("/case_logs/#{id}/previous_postcode") - expect(page).to have_field("case-log-previous-postcode-field", with: "P0 5ST") + visit("/case_logs/#{id}/property_postcode") + expect(page).to have_field("case-log-property-postcode-field", with: "P0 5ST") end it "displays text answers in inputs if they are already saved" do diff --git a/spec/fixtures/complete_case_log.json b/spec/fixtures/complete_case_log.json index 3d466170b..7bca4a575 100644 --- a/spec/fixtures/complete_case_log.json +++ b/spec/fixtures/complete_case_log.json @@ -38,7 +38,7 @@ "sex8": "Prefer not to say", "ecstat8": "Child under 16", "homeless": "Yes - other homelessness", - "reason_for_leaving_last_settled_home": "Other problems with neighbours", + "reason": 1, "underoccupation_benefitcap": "No", "leftreg": "No - they left up to 5 years ago", "reservist": "No", @@ -54,8 +54,8 @@ "tenancy": "Fixed term – Secure", "lettype": "Affordable Rent - General Needs", "landlord": "This landlord", - "property_location": "Barnet", - "previous_postcode": "NW1 5TY", + "la": "Barnet", + "property_postcode": "NW1 5TY", "property_relet": "No", "rsnvac": "Relet - tenant abandoned property", "property_reference": "P9876", @@ -71,7 +71,7 @@ "earnings": 0, "incfreq": null, "benefits": "Some", - "housing_benefit": "Universal Credit with housing element, but not Housing Benefit", + "hb": "Universal Credit with housing element, but not Housing Benefit", "period": "Fortnightly", "brent": 200, "scharge": 50, @@ -81,14 +81,15 @@ "outstanding_amount": "Yes", "layear": "1 to 2 years", "lawaitlist": "Less than 1 year", - "previous_la": "Ashford", - "property_postcode": "SE2 6RT", + "prevloc": "Ashford", + "previous_postcode": "SE2 6RT", "reasonpref": "Yes", "reasonable_preference_reason": "dummy", "cbl": "Yes", "chr": "Yes", "cap": "No", - "outstanding_rent_or_charges": 25, + "hbrentshortfall": "Yes", + "tshortfall": 12, "other_reason_for_leaving_last_settled_home": null, "housingneeds_a": "Yes", "housingneeds_b": "No", @@ -125,6 +126,12 @@ "intermediate_rent_product_name": "", "needs_type": "", "sale_completion_date": "", - "purchaser_code": "" + "purchaser_code": "", + "propcode": "123", + "majorrepairs": "Yes", + "postcode": "a1", + "postcod2": "w3", + "ppostc1": "w3", + "ppostc2": "w3" } } diff --git a/spec/fixtures/forms/test_form.json b/spec/fixtures/forms/test_form.json index a52768299..15764300b 100644 --- a/spec/fixtures/forms/test_form.json +++ b/spec/fixtures/forms/test_form.json @@ -348,7 +348,7 @@ }, "housing_benefit": { "questions": { - "housing_benefit": { + "hb": { "check_answer_label": "Universal Credit & Housing Benefit", "header": "Is the tenant likely to be in receipt of any of these housing-related benefits?", "type": "radio", @@ -494,14 +494,20 @@ } } }, - "previous_postcode": { + "property_postcode": { "questions": { - "previous_postcode": { + "property_postcode": { "check_answer_label": "Postcode of previous accomodation if the household has moved from settled accommodation", "header": "Postcode for the previous accommodation", "hint_text": "If the household has moved from settled accommodation immediately prior to being re-housed", "type": "text", "conditional_for": { "faake_key": "fake_condition" } + }, + "previous_postcode": { + "check_answer_label": "Postcode of previous accomodation if the household has moved from settled accommodation", + "header": "Postcode for the previous accommodation", + "hint_text": "If the household has moved from settled accommodation immediately prior to being re-housed", + "type": "text" } } } diff --git a/spec/helpers/check_answers_helper_spec.rb b/spec/helpers/check_answers_helper_spec.rb index fb8deec77..7ad04f081 100644 --- a/spec/helpers/check_answers_helper_spec.rb +++ b/spec/helpers/check_answers_helper_spec.rb @@ -127,7 +127,7 @@ RSpec.describe CheckAnswersHelper do it "returns total questions" do result = total_questions(subsection, case_log, form) expect(result.class).to eq(Hash) - expected_keys = %w[earnings incfreq benefits housing_benefit] + expected_keys = %w[earnings incfreq benefits hb] expect(result.keys).to eq(expected_keys) end diff --git a/spec/helpers/tasklist_helper_spec.rb b/spec/helpers/tasklist_helper_spec.rb index db9ac3cae..e900363f2 100644 --- a/spec/helpers/tasklist_helper_spec.rb +++ b/spec/helpers/tasklist_helper_spec.rb @@ -33,7 +33,7 @@ RSpec.describe TasklistHelper do case_log["earnings"] = "value" case_log["incfreq"] = "Weekly" case_log["benefits"] = "All" - case_log["housing_benefit"] = "Do not know" + case_log["hb"] = "Do not know" status = get_subsection_status("income_and_benefits", case_log, income_and_benefits_questions) expect(status).to eq(:completed) diff --git a/spec/models/case_log_spec.rb b/spec/models/case_log_spec.rb index 75bc1f1a6..438bf3c55 100644 --- a/spec/models/case_log_spec.rb +++ b/spec/models/case_log_spec.rb @@ -60,7 +60,7 @@ RSpec.describe Form, type: :model do context "reason for leaving last settled home validation" do it "Reason for leaving must be don't know if reason for leaving settled home (Q9a) is don't know." do expect { - CaseLog.create!(reason_for_leaving_last_settled_home: "Do not know", + CaseLog.create!(reason: "Do not know", underoccupation_benefitcap: "Yes - benefit cap") }.to raise_error(ActiveRecord::RecordInvalid) end @@ -68,14 +68,14 @@ RSpec.describe Form, type: :model do context "other reason for leaving last settled home validation" do it "must be provided if main reason for leaving last settled home was given as other" do expect { - CaseLog.create!(reason_for_leaving_last_settled_home: "Other", + CaseLog.create!(reason: "Other", other_reason_for_leaving_last_settled_home: nil) }.to raise_error(ActiveRecord::RecordInvalid) end it "must not be provided if the main reason for leaving settled home is not other" do expect { - CaseLog.create!(reason_for_leaving_last_settled_home: "Repossession", + CaseLog.create!(reason: "Repossession", other_reason_for_leaving_last_settled_home: "the other reason provided") }.to raise_error(ActiveRecord::RecordInvalid) end @@ -139,15 +139,15 @@ RSpec.describe Form, type: :model do context "outstanding rent or charges validation" do it "must be anwered if answered yes to outstanding rent or charges" do expect { - CaseLog.create!(outstanding_rent_or_charges: "Yes", - outstanding_amount: nil) + CaseLog.create!(hbrentshortfall: "Yes", + tshortfall: nil) }.to raise_error(ActiveRecord::RecordInvalid) end it "must be not be anwered if answered no to outstanding rent or charges" do expect { - CaseLog.create!(outstanding_rent_or_charges: "No", - outstanding_amount: 99) + CaseLog.create!(hbrentshortfall: "No", + tshortfall: 99) }.to raise_error(ActiveRecord::RecordInvalid) end end diff --git a/spec/models/form_spec.rb b/spec/models/form_spec.rb index f4e554356..18e15c6b4 100644 --- a/spec/models/form_spec.rb +++ b/spec/models/form_spec.rb @@ -39,7 +39,7 @@ RSpec.describe Form, type: :model do it "returns all questions for subsection" do result = form.questions_for_subsection(subsection) expect(result.length).to eq(4) - expect(result.keys).to eq(%w[earnings incfreq benefits housing_benefit]) + expect(result.keys).to eq(%w[earnings incfreq benefits hb]) end end end From 8517613c64344daca12c4b2674403021abeb98e7 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Wed, 10 Nov 2021 14:20:22 +0000 Subject: [PATCH 15/55] . --- config/forms/schema/generic.json | 113 ++++++++++++++--------------- config/forms/schema/test.json | 75 +++++++------------ spec/fixtures/forms/test_form.json | 9 --- 3 files changed, 80 insertions(+), 117 deletions(-) diff --git a/config/forms/schema/generic.json b/config/forms/schema/generic.json index d7e71468d..50c08369c 100644 --- a/config/forms/schema/generic.json +++ b/config/forms/schema/generic.json @@ -19,77 +19,74 @@ "type": "integer" }, "sections": { - "description": "", "type": "object", "patternProperties": { - "^[0-9]+$": { - "description": "", - "type": "string" - }, - "label": { + "[a-z_\/#]+": { "description": "", - "type": "string" + "type": "object" }, - "subsections": { - "description": "", - "type": "object", - "patternProperties": { - "^[0-9]+$": { - "description": "", - "type": "string" - }, - "label": { - "description": "", - "type": "string" - }, - "subsections": { - "description": "", - "type": "object", - "patternProperties": { - "^[0-9]+$": { - "description": "", - "type": "string" - }, - "label": { - "description": "", - "type": "string" - }, - "pages": { - "description": "", - "type": "object", - "patternProperties": { - "^[0-9]+$": { - "description": "", - "type": "string" - } - }, - "questions": { + "properties": { + "label": { + "description": "", + "type": "string" + }, + "subsections": { + "description": "", + "type": "object", + "patternProperties": { + "[a-z_\/#]+": { + "description": "", + "type": "object", + "required": ["label"], + "properties": { + "label": { "description": "", + "type": "string", + "required": "true" + }, + "pages": { "type": "object", + "required": ["header"], "patternProperties": { - "^[0-9]+$": { - "description": "", - "type": "string" - }, - "conditional_for": { - "type": "object", - "properties": "" + "type": "object", + "[a-z_]+": { + "properties": { + "header": { + "description": "", + "type": "string" + }, + "description": { + "description": "", + "type": "string" + }, + "questions": { + "type": "object", + "patternProperties": { + "type": "object", + "[a-z_]+": { + "properties": { + "check_answer_label": { + "type": "string" + } + } + } + }, + "minProperties": 8 + }, + "minProperties": 8 + } } - } - }, - "conditional_route_to": { - "type": "object", - "properties": "" - }, - "default_next_page": { - "type" : "string" + }, + "minProperties": 8 } } } - } + }, + "minProperties": 8 } } - } + }, + "minProperties": 1 } } } \ No newline at end of file diff --git a/config/forms/schema/test.json b/config/forms/schema/test.json index 9058f70c4..90a06942d 100644 --- a/config/forms/schema/test.json +++ b/config/forms/schema/test.json @@ -21,61 +21,36 @@ "sections": { "type": "object", "patternProperties": { - "^[0-9]+$": { + "[a-z_\/#]+": { "description": "", - "type": "string" - }, - "properties": { - "label": { - "description": "", - "type": "string" - }, - "subsections": { - "description": "", - "type": "object", - "patternProperties": { - "^[0-9]+$": { - "description": "", - "type": "object", - "required": ["label"], - "properties": { - "label": { - "description": "", - "type": "string" - }, - "pages": { - "type": "object", - "required": ["header"], - "patternProperties": { - "^[0-9]+$": { - "properties": { - "header": { - "description": "", - "type": "string" - }, - "description": { - "description": "", - "type": "string" - }, - "questions": { - "type": "object", - "properties": { - - } - } - } - } + "type": "object", + "properties": { + "label": { + "description": "", + "type": "string" + }, + "subsections": { + "type": "object", + "patternProperties": { + "[a-z_\/#]+": { + "description": "", + "type": "object", + "required": ["label"], + "properties": { + "label": { + "description": "", + "type": "string" } - } + }, + "minProperties": 1 } - }, - "additionalProperties": false, - "maxProperties": 1, - "minProperties": 1 + } } - } + }, + "minProperties": 2 } - } + }, + "minProperties": 1 } } } \ No newline at end of file diff --git a/spec/fixtures/forms/test_form.json b/spec/fixtures/forms/test_form.json index 73df96635..b5467a48f 100644 --- a/spec/fixtures/forms/test_form.json +++ b/spec/fixtures/forms/test_form.json @@ -9,15 +9,6 @@ "household_characteristics": { "label": "Household characteristics", "pages": { - "tenant_code": { - "questions": { - "tenant_code": { - "check_answer_label": "Tenant code", - "header": "What is the tenant code?", - "type": "text" - } - } - } } } } From 16685a25e2a5d327d85afc52884540d3b2fed485 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Wed, 10 Nov 2021 19:50:02 +0000 Subject: [PATCH 16/55] nearly working --- config/forms/schema/test.json | 35 +++++++++++++++++++++++++++++++++++ db/schema.rb | 13 ++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/config/forms/schema/test.json b/config/forms/schema/test.json index 90a06942d..f81b52d6c 100644 --- a/config/forms/schema/test.json +++ b/config/forms/schema/test.json @@ -40,6 +40,41 @@ "label": { "description": "", "type": "string" + }, + "pages": { + "type": "object", + "patternProperties": { + "[a-z_\/#]+": { + "description": "", + "type": "object", + "properties": { + "questions": { + "type": "object", + "patternProperties": { + "[a-z_\/#]+": { + "description": "", + "type": "object", + "properties": { + "check_answer_label": { + "description": "", + "type": "string" + }, + "header": { + "description": "", + "type": "string" + }, + "type": { + "description": "", + "type": "string" + } + } + } + } + } + }, + "minProperties": 1 + } + } } }, "minProperties": 1 diff --git a/db/schema.rb b/db/schema.rb index 7f75e5e87..ddd456c43 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_10_28_095000) do +ActiveRecord::Schema.define(version: 2021_11_02_100820) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -133,6 +133,17 @@ ActiveRecord::Schema.define(version: 2021_10_28_095000) do t.boolean "reasonable_preference_reason_do_not_know" t.datetime "discarded_at" t.string "other_tenancy_type" + t.string "gdpr_acceptance" + t.string "gdpr_declined" + t.string "property_owner_organisation" + t.string "property_manager_organisation" + t.string "sale_or_letting" + t.string "tenant_same_property_renewal" + t.string "rent_type" + t.string "intermediate_rent_product_name" + t.string "needs_type" + t.string "sale_completion_date" + t.string "purchaser_code" t.boolean "override_net_income_validation" t.string "net_income_known" t.index ["discarded_at"], name: "index_case_logs_on_discarded_at" From 5dacd38187693731e2907798cd466f165dce194f Mon Sep 17 00:00:00 2001 From: magicmilo Date: Wed, 10 Nov 2021 20:05:54 +0000 Subject: [PATCH 17/55] blank conditional for --- config/forms/schema/test.json | 25 +++++++++++++++++++++---- spec/fixtures/forms/test_validator.json | 2 +- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/config/forms/schema/test.json b/config/forms/schema/test.json index f81b52d6c..93eaf9a6d 100644 --- a/config/forms/schema/test.json +++ b/config/forms/schema/test.json @@ -21,7 +21,7 @@ "sections": { "type": "object", "patternProperties": { - "[a-z_\/#]+": { + "[a-z_]+": { "description": "", "type": "object", "properties": { @@ -32,7 +32,7 @@ "subsections": { "type": "object", "patternProperties": { - "[a-z_\/#]+": { + "[a-z_]+": { "description": "", "type": "object", "required": ["label"], @@ -44,16 +44,25 @@ "pages": { "type": "object", "patternProperties": { - "[a-z_\/#]+": { + "[a-z_]+": { "description": "", "type": "object", "properties": { + "header": { + "description": "", + "type": "string" + }, + "description": { + "description": "", + "type": "string" + }, "questions": { "type": "object", "patternProperties": { - "[a-z_\/#]+": { + "[a-z_]+": { "description": "", "type": "object", + "required": ["header"], "properties": { "check_answer_label": { "description": "", @@ -66,6 +75,14 @@ "type": { "description": "", "type": "string" + }, + "hint_text": { + "description": "", + "type": "string" + }, + "answer_options": { + "description": "", + "type": "string" } } } diff --git a/spec/fixtures/forms/test_validator.json b/spec/fixtures/forms/test_validator.json index e0fe13361..e83c4d970 100644 --- a/spec/fixtures/forms/test_validator.json +++ b/spec/fixtures/forms/test_validator.json @@ -8,7 +8,7 @@ "subsections": { "household_characteristics": { "label": "Household characteristics", - "baddata": "Shouldn't be here but what you gonna do?", + "ShouldThrowError": "Shouldn't be here but what you gonna do?", "pages": { "tenant_code": { "questions": { From 109947bb97a6040eb4083fe636ac8b9e9de65f41 Mon Sep 17 00:00:00 2001 From: Kat Date: Thu, 11 Nov 2021 09:28:09 +0000 Subject: [PATCH 18/55] Update majorrepairs field name in docs and test file --- app/admin/case_logs.rb | 2 +- docs/api/DLUHC-CORE-Data.v1.json | 6 +++--- spec/fixtures/complete_case_log.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/admin/case_logs.rb b/app/admin/case_logs.rb index c3716ad6d..6768befae 100644 --- a/app/admin/case_logs.rb +++ b/app/admin/case_logs.rb @@ -2,7 +2,7 @@ ActiveAdmin.register CaseLog do # See permitted parameters documentation: # https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters permit_params do - permitted = %i[status tenant_code age1 sex1 tenant_ethnic_group tenant_nationality previous_housing_situation armed_forces ecstat1 hhmemb relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 person_7_gender ecstat7 relat8 age8 sex8 ecstat8 homelessness reason benefit_cap_spare_room_subsidy armed_forces_active armed_forces_injured armed_forces_partner medical_conditions pregnancy accessibility_requirements condition_effects tenancy_code tenancy_start_date starter_tenancy fixed_term_tenancy tenancy_type letting_type letting_provider la previous_postcode property_relet property_vacancy_reason property_reference property_unit_type property_building_type property_number_of_bedrooms property_void_date property_major_repairs property_major_repairs_date property_number_of_times_relet property_wheelchair_accessible net_income net_income_frequency net_income_uc_proportion hb rent_frequency basic_rent service_charge personal_service_charge support_charge total_charge tshortfall time_lived_in_la time_on_la_waiting_list prevloc property_postcode reasonable_preference reasonable_preference_reason cbl_letting chr_letting cap_letting hbrentshortfall other_reason accessibility_requirements_fully_wheelchair_accessible_housing accessibility_requirements_wheelchair_access_to_essential_rooms accessibility_requirements_level_access_housing accessibility_requirements_other_disability_requirements accessibility_requirements_no_disability_requirements accessibility_requirements_do_not_know accessibility_requirements_prefer_not_to_say condition_effects_vision condition_effects_hearing condition_effects_mobility condition_effects_dexterity condition_effects_stamina condition_effects_learning condition_effects_memory condition_effects_mental_health condition_effects_social_or_behavioral condition_effects_other condition_effects_prefer_not_to_say reasonable_preference_reason_homeless reasonable_preference_reason_unsatisfactory_housing reasonable_preference_reason_medical_grounds reasonable_preference_reason_avoid_hardship reasonable_preference_reason_do_not_know other_tenancy_type override_net_income_validation net_income_known] + permitted = %i[status tenant_code age1 sex1 tenant_ethnic_group tenant_nationality previous_housing_situation armed_forces ecstat1 hhmemb relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 person_7_gender ecstat7 relat8 age8 sex8 ecstat8 homelessness reason benefit_cap_spare_room_subsidy armed_forces_active armed_forces_injured armed_forces_partner medical_conditions pregnancy accessibility_requirements condition_effects tenancy_code tenancy_start_date starter_tenancy fixed_term_tenancy tenancy_type letting_type letting_provider la previous_postcode property_relet property_vacancy_reason property_reference property_unit_type property_building_type property_number_of_bedrooms property_void_date majorrepairs property_major_repairs_date property_number_of_times_relet property_wheelchair_accessible net_income net_income_frequency net_income_uc_proportion hb rent_frequency basic_rent service_charge personal_service_charge support_charge total_charge tshortfall time_lived_in_la time_on_la_waiting_list prevloc property_postcode reasonable_preference reasonable_preference_reason cbl_letting chr_letting cap_letting hbrentshortfall other_reason accessibility_requirements_fully_wheelchair_accessible_housing accessibility_requirements_wheelchair_access_to_essential_rooms accessibility_requirements_level_access_housing accessibility_requirements_other_disability_requirements accessibility_requirements_no_disability_requirements accessibility_requirements_do_not_know accessibility_requirements_prefer_not_to_say condition_effects_vision condition_effects_hearing condition_effects_mobility condition_effects_dexterity condition_effects_stamina condition_effects_learning condition_effects_memory condition_effects_mental_health condition_effects_social_or_behavioral condition_effects_other condition_effects_prefer_not_to_say reasonable_preference_reason_homeless reasonable_preference_reason_unsatisfactory_housing reasonable_preference_reason_medical_grounds reasonable_preference_reason_avoid_hardship reasonable_preference_reason_do_not_know other_tenancy_type override_net_income_validation net_income_known] permitted end diff --git a/docs/api/DLUHC-CORE-Data.v1.json b/docs/api/DLUHC-CORE-Data.v1.json index 654307a59..860255260 100644 --- a/docs/api/DLUHC-CORE-Data.v1.json +++ b/docs/api/DLUHC-CORE-Data.v1.json @@ -318,7 +318,7 @@ "property_building_type": "dummy", "beds": 3, "property_void_date": "03/11/2019", - "property_major_repairs": "Yes", + "majorrepairs": "Yes", "property_major_repairs_date": "05/05/2020", "offered": 2, "wchair": true, @@ -871,7 +871,7 @@ "type": "string", "minLength": 1 }, - "property_major_repairs": { + "majorrepairs": { "type": "string", "minLength": 1 }, @@ -1107,7 +1107,7 @@ "property_building_type", "beds", "property_void_date", - "property_major_repairs", + "majorrepairs", "property_major_repairs_date", "offered", "wchair", diff --git a/spec/fixtures/complete_case_log.json b/spec/fixtures/complete_case_log.json index 7bca4a575..01fc5d998 100644 --- a/spec/fixtures/complete_case_log.json +++ b/spec/fixtures/complete_case_log.json @@ -63,7 +63,7 @@ "property_building_type": "dummy", "beds": 3, "property_void_date": "03/11/2019", - "property_major_repairs": "Yes", + "majorrepairs": "Yes", "property_major_repairs_date": "05/05/2020", "offered": 2, "wchair": "Yes", From 8c27ae6ffc63ec17ca4594462bd11522a3e30ea2 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Thu, 11 Nov 2021 11:39:02 +0000 Subject: [PATCH 19/55] Validate structure correctly --- app/helpers/json_schema_validation.rb | 3 +- config/forms/schema/2021_2022.json | 2230 ++--------------------- config/forms/schema/generic.json | 140 +- config/forms/schema/test.json | 108 -- spec/fixtures/forms/test_form.json | 18 - spec/fixtures/forms/test_validator.json | 3 +- 6 files changed, 191 insertions(+), 2311 deletions(-) delete mode 100644 config/forms/schema/test.json delete mode 100644 spec/fixtures/forms/test_form.json diff --git a/app/helpers/json_schema_validation.rb b/app/helpers/json_schema_validation.rb index 12084b020..dd0655d3b 100644 --- a/app/helpers/json_schema_validation.rb +++ b/app/helpers/json_schema_validation.rb @@ -13,8 +13,7 @@ end begin - # path = "config/forms/schema/generic.json" - path = "config/forms/schema/test.json" + path = "config/forms/schema/generic.json" # path = "config/forms/schema/2021_2022.json" file = File.open(path) diff --git a/config/forms/schema/2021_2022.json b/config/forms/schema/2021_2022.json index 2a825ffb8..cd8f13530 100644 --- a/config/forms/schema/2021_2022.json +++ b/config/forms/schema/2021_2022.json @@ -1,2134 +1,112 @@ { - "form_type": "lettings", - "start_year": 2021, - "end_year": 2022, + "$schema": "http://json-schema.org/draft-04/schema#", + "$id": "https://example.com/product.schema.json", + "title": "Form", + "description": "A form", + "type": "object", + "required": ["form_type", "start_year", "end_year", "sections"], + "properties": { + "form_type": { + "description": "", + "type": "string" + }, + "start_year": { + "description": "", + "type": "integer" + }, + "end_year": { + "description": "", + "type": "integer" + }, "sections": { - "household": { - "label": "About the household", - "subsections": { - "household_characteristics": { - "label": "Household characteristics", - "pages": { - "tenant_code": { - "header": "", - "description": "", - "questions": { - "tenant_code": { - "check_answer_label": "Tenant code", - "header": "What is the tenant code?", - "hint_text": "", - "type": "text" - } - } - }, - "person_1_age": { - "header": "", - "description": "", - "questions": { - "person_1_age": { - "check_answer_label": "Tenant's age", - "header": "What is the tenant's age?", - "hint_text": "", - "type": "numeric", - "min": 0, - "max": 120, - "step": 1 - } - } - }, - "person_1_gender": { - "header": "", - "description": "", - "questions": { - "person_1_gender": { - "check_answer_label": "Tenant's gender", - "header": "Which of these best describes the tenant's gender identity?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Female", - "1": "Male", - "2": "Non-binary", - "3": "Prefer not to say" - } - } - } - }, - "tenant_ethnic_group": { - "header": "", - "description": "", - "questions": { - "tenant_ethnic_group": { - "check_answer_label": "Ethnicity", - "header": "What is the tenant's ethnic group?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "White: English/Scottish/Welsh/Northern Irish/British", - "1": "White: Irish", - "2": "White: Gypsy/Irish Traveller", - "3": "White: Other", - "4": "Mixed: White & Black Caribbean", - "5": "Mixed: White & Black African", - "6": "Mixed: White & Asian", - "7": "Mixed: Other", - "8": "Asian or Asian British: Indian", - "9": "Asian or Asian British: Pakistani", - "10": "Asian or Asian British: Bangladeshi", - "11": "Asian or Asian British: Chinese", - "12": "Asian or Asian British: Other", - "13": "Black: Caribbean", - "14": "Black: African", - "15": "Black: Other", - "16": "Other Ethnic Group: Arab", - "17": "Other Ethnic Group: Other", - "18": "Prefer not to say" - } - } - } - }, - "tenant_nationality": { - "header": "", - "description": "", - "questions": { - "tenant_nationality": { - "check_answer_label": "Nationality", - "header": "What is the tenant's nationality?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "UK national resident in UK", - "1": "A current or former reserve in the UK Armed Forces (exc. National Service)", - "2": "UK national returning from residence overseas", - "3": "Czech Republic", - "4": "Estonia", - "5": "Hungary", - "6": "Latvia", - "7": "Lithuania", - "8": "Poland", - "9": "Slovakia", - "10": "Bulgaria", - "11": "Romania", - "12": "Ireland", - "13": "Other EU Economic Area (EEA country)", - "14": "Any other country", - "15": "Prefer not to say" - } - } - } - }, - "tenant_economic_status": { - "header": "", - "description": "", - "questions": { - "person_1_economic_status": { - "check_answer_label": "Work", - "header": "Which of these best describes the tenant's working situation?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Part-time - Less than 30 hours", - "1": "Full-time - 30 hours or more", - "2": "In government training into work, such as New Deal", - "3": "Jobseeker", - "4": "Retired", - "5": "Not seeking work", - "6": "Full-time student", - "7": "Unable to work because of long term sick or disability", - "8": "Child under 16", - "9": "Other", - "10": "Prefer not to say" - } - } - } - }, - "household_number_of_other_members": { - "header": "", - "description": "", - "questions": { - "household_number_of_other_members": { - "check_answer_label": "Number of Other Household Members", - "header": "How many other people are there in the household?", - "hint_text": "The maximum number of others is 7", - "type": "numeric", - "min": 0, - "max": 7, - "step": 1, - "conditional_for": { - "person_2_relationship": ">0", - "person_2_age": ">0", - "person_2_gender": ">0", - "person_2_economic_status": ">0", - "person_3_relationship": ">1", - "person_3_age": ">1", - "person_3_gender": ">1", - "person_3_economic_status": ">1", - "person_4_relationship": ">2", - "person_4_age": ">2", - "person_4_gender": ">2", - "person_4_economic_status": ">2", - "person_5_relationship": ">3", - "person_5_age": ">3", - "person_5_gender": ">3", - "person_5_economic_status": ">3", - "person_6_relationship": ">4", - "person_6_age": ">4", - "person_6_gender": ">4", - "person_6_economic_status": ">4", - "person_7_relationship": ">5", - "person_7_age": ">5", - "person_7_gender": ">5", - "person_7_economic_status": ">5", - "person_8_relationship": ">6", - "person_8_age": ">6", - "person_8_gender": ">6", - "person_8_economic_status": ">6" - } - }, - "person_2_relationship": { - "check_answer_label": "Person 2's relationship to lead tenant", - "header": "What's person 2's relationship to lead tenant", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Partner", - "1": "Child - includes young adult and grown-up", - "2": "Other", - "3": "Prefer not to say" - } - }, - "person_2_age": { - "check_answer_label": "Person 2's age", - "header": "What's person 2's age", - "hint_text": "", - "type": "numeric", - "min": 0, - "max": 150, - "step": 1 - }, - "person_2_gender": { - "check_answer_label": "Person 2's gender", - "header": "Which of these best describes person 2's gender identity?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Female", - "1": "Male", - "2": "Non-binary", - "3": "Prefer not to say" - } - }, - "person_2_economic_status": { - "check_answer_label": "Person 2's Work", - "header": "Which of these best describes person 2's working situation?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Part-time - Less than 30 hours", - "1": "Full-time - 30 hours or more", - "2": "In government training into work, such as New Deal", - "3": "Jobseeker", - "4": "Retired", - "5": "Not seeking work", - "6": "Full-time student", - "7": "Unable to work because of long term sick or disability", - "8": "Child under 16", - "9": "Other", - "10": "Prefer not to say" - } - }, - "person_3_relationship": { - "check_answer_label": "Person 3's relationship to lead tenant", - "header": "What's person 3's relationship to lead tenant", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Partner", - "1": "Child - includes young adult and grown-up", - "2": "Other", - "3": "Prefer not to say" - } - }, - "person_3_age": { - "check_answer_label": "Person 3's age", - "header": "What's person 3's age", - "hint_text": "", - "type": "numeric", - "min": 0, - "max": 150, - "step": 1 - }, - "person_3_gender": { - "check_answer_label": "Person 3's gender", - "header": "Which of these best describes person 3's gender identity?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Female", - "1": "Male", - "2": "Non-binary", - "3": "Prefer not to say" - } - }, - "person_3_economic_status": { - "check_answer_label": "Person 3's Work", - "header": "Which of these best describes person 3's working situation?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Part-time - Less than 30 hours", - "1": "Full-time - 30 hours or more", - "2": "In government training into work, such as New Deal", - "3": "Jobseeker", - "4": "Retired", - "5": "Not seeking work", - "6": "Full-time student", - "7": "Unable to work because of long term sick or disability", - "8": "Child under 16", - "9": "Other", - "10": "Prefer not to say" - } - }, - "person_4_relationship": { - "check_answer_label": "Person 4's relationship to lead tenant", - "header": "What's person 4's relationship to lead tenant", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Partner", - "1": "Child - includes young adult and grown-up", - "2": "Other", - "3": "Prefer not to say" - } - }, - "person_4_age": { - "check_answer_label": "Person 4's age", - "header": "What's person 4's age", - "hint_text": "", - "type": "numeric", - "min": 0, - "max": 150, - "step": 1 - }, - "person_4_gender": { - "check_answer_label": "Person 4's gender", - "header": "Which of these best describes person 4's gender identity?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Female", - "1": "Male", - "2": "Non-binary", - "3": "Prefer not to say" - } - }, - "person_4_economic_status": { - "check_answer_label": "Person 4's Work", - "header": "Which of these best describes person 4's working situation?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Part-time - Less than 30 hours", - "1": "Full-time - 30 hours or more", - "2": "In government training into work, such as New Deal", - "3": "Jobseeker", - "4": "Retired", - "5": "Not seeking work", - "6": "Full-time student", - "7": "Unable to work because of long term sick or disability", - "8": "Child under 16", - "9": "Other", - "10": "Prefer not to say" - } - }, - "person_5_relationship": { - "check_answer_label": "Person 5's relationship to lead tenant", - "header": "What's person 5's relationship to lead tenant", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Partner", - "1": "Child - includes young adult and grown-up", - "2": "Other", - "3": "Prefer not to say" - } - }, - "person_5_age": { - "check_answer_label": "Person 5's age", - "header": "What's person 5's age", - "hint_text": "", - "type": "numeric", - "min": 0, - "max": 150, - "step": 1 - }, - "person_5_gender": { - "check_answer_label": "Person 5's gender", - "header": "Which of these best describes person 5's gender identity?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Female", - "1": "Male", - "2": "Non-binary", - "3": "Prefer not to say" - } - }, - "person_5_economic_status": { - "check_answer_label": "Person 5's Work", - "header": "Which of these best describes person 5's working situation?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Part-time - Less than 30 hours", - "1": "Full-time - 30 hours or more", - "2": "In government training into work, such as New Deal", - "3": "Jobseeker", - "4": "Retired", - "5": "Not seeking work", - "6": "Full-time student", - "7": "Unable to work because of long term sick or disability", - "8": "Child under 16", - "9": "Other", - "10": "Prefer not to say" - } - }, - "person_6_relationship": { - "check_answer_label": "Person 6's relationship to lead tenant", - "header": "What's person 6's relationship to lead tenant", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Partner", - "1": "Child - includes young adult and grown-up", - "2": "Other", - "3": "Prefer not to say" - } - }, - "person_6_age": { - "check_answer_label": "Person 6's age", - "header": "What's person 6's age", - "hint_text": "", - "type": "numeric", - "min": 0, - "max": 150, - "step": 1 - }, - "person_6_gender": { - "check_answer_label": "Person 6's gender", - "header": "Which of these best describes person 6's gender identity?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Female", - "1": "Male", - "2": "Non-binary", - "3": "Prefer not to say" - } - }, - "person_6_economic_status": { - "check_answer_label": "Person 6's Work", - "header": "Which of these best describes person 6's working situation?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Part-time - Less than 30 hours", - "1": "Full-time - 30 hours or more", - "2": "In government training into work, such as New Deal", - "3": "Jobseeker", - "4": "Retired", - "5": "Not seeking work", - "6": "Full-time student", - "7": "Unable to work because of long term sick or disability", - "8": "Child under 16", - "9": "Other", - "10": "Prefer not to say" - } - }, - "person_7_relationship": { - "check_answer_label": "Person 7's relationship to lead tenant", - "header": "What's person 7's relationship to lead tenant", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Partner", - "1": "Child - includes young adult and grown-up", - "2": "Other", - "3": "Prefer not to say" - } - }, - "person_7_age": { - "check_answer_label": "Person 7's age", - "header": "What's person 7's age", - "hint_text": "", - "type": "numeric", - "min": 0, - "max": 150, - "step": 1 - }, - "person_7_gender": { - "check_answer_label": "Person 7's gender", - "header": "Which of these best describes person 7's gender identity?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Female", - "1": "Male", - "2": "Non-binary", - "3": "Prefer not to say" - } - }, - "person_7_economic_status": { - "check_answer_label": "Person 7's Work", - "header": "Which of these best describes person 7's working situation?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Part-time - Less than 30 hours", - "1": "Full-time - 30 hours or more", - "2": "In government training into work, such as New Deal", - "3": "Jobseeker", - "4": "Retired", - "5": "Not seeking work", - "6": "Full-time student", - "7": "Unable to work because of long term sick or disability", - "8": "Child under 16", - "9": "Other", - "10": "Prefer not to say" - } - }, - "person_8_relationship": { - "check_answer_label": "Person 8's relationship to lead tenant", - "header": "What's person 8's relationship to lead tenant", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Partner", - "1": "Child - includes young adult and grown-up", - "2": "Other", - "3": "Prefer not to say" - } - }, - "person_8_age": { - "check_answer_label": "Person 8's age", - "header": "What's person 8's age", - "hint_text": "", - "type": "numeric", - "min": 0, - "max": 150, - "step": 1 - }, - "person_8_gender": { - "check_answer_label": "Person 8's gender", - "header": "Which of these best describes person 8's gender identity?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Female", - "1": "Male", - "2": "Non-binary", - "3": "Prefer not to say" - } - }, - "person_8_economic_status": { - "check_answer_label": "Person 8's Work", - "header": "Which of these best describes person 8's working situation?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Part-time - Less than 30 hours", - "1": "Full-time - 30 hours or more", - "2": "In government training into work, such as New Deal", - "3": "Jobseeker", - "4": "Retired", - "5": "Not seeking work", - "6": "Full-time student", - "7": "Unable to work because of long term sick or disability", - "8": "Child under 16", - "9": "Other", - "10": "Prefer not to say" - } - } - } - } - } - }, - "household_situation": { - "label": "Household situation", - "pages": { - "previous_housing_situation": { - "header": "", - "description": "", - "questions": { - "previous_housing_situation": { - "header": "What was the tenant’s housing situation immediately before this letting?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Owner occupation (private) ", - "1": "Owner occupation (low cost home ownership)", - "2": "Private sector tenancy", - "3": "Tied housing or rented with job", - "4": "Supported housing", - "5": "Sheltered accomodation", - "6": "Residential care home", - "7": "Living with friends or family", - "8": "Refuge", - "9": "Hospital", - "10": "Prison / approved probation hostel", - "11": "Direct access hostel", - "12": "Bed & Breakfast", - "13": "Mobile home / caravan", - "14": "Any other temporary accommodation", - "15": "Home Office Asylum Support", - "16": "Children’s home / foster care", - "17": "Rough sleeping", - "18": "Other", - "19": "Fixed term Local Authority General Needs tenancy", - "20": "Lifetime Local Authority General Needs tenancy", - "21": "Fixed term PRP General Needs tenancy", - "22": "Lifetime PRP General Needs tenancy" - } - } - } - }, - "homelessness": { - "header": "", - "description": "", - "questions": { - "homelessness": { - "header": "Did the tenant experience homelessness immediately before this letting?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Yes - assessed as homeless by a local authority and owed a homelessness duty. Including if threatened with homelessness within 56 days", - "1": "Yes - other homelessness ", - "2": "No" - } - } - } - }, - "reason_for_leaving_last_settled_home": { - "header": "Leaving their last settled home", - "description": "", - "questions": { - "reason_for_leaving_last_settled_home": { - "header": "What is the tenant’s main reason for leaving?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Permanently decanted from another property owned by this landlord", - "1": "Left home country as a refugee", - "2": "Loss of tied accommodation", - "3": "Domestic abuse", - "4": "(Non violent) relationship breakdown with partner", - "5": "Asked to leave by family or friends", - "6": "Racial harassment", - "7": "Other problems with neighbours", - "8": "Property unsuitable because of overcrowding", - "9": "End of assured shorthold tenancy - no fault", - "10": "End of assured shorthold tenancy - tenant's fault", - "11": "End of fixed term tenancy - no fault", - "12": "End of fixed term tenancy - tenant's fault", - "13": "Repossession", - "14": "Under occupation - offered incentive to downsize", - "15": "Under occupation - no incentive", - "16": "Property unsuitable because of ill health / disability", - "17": "Property unsuitable because of poor condition", - "18": "Couldn't afford fees attached to renewing the tenancy", - "19": "Couldn't afford increase in rent", - "20": "Couldn't afford rent or mortgage - welfare reforms", - "21": "Couldn't afford rent or mortgage - employment", - "22": "Couldn't afford rent or mortgage - other", - "23": "To move nearer to family / friends / school", - "24": "To move nearer to work", - "25": "To move to accomodation with support", - "26": "To move to independent accomodation", - "27": "Hate crime", - "28": "Death of household member in last settled accomodation", - "29": "Discharged from prison", - "30": "Discharged from long stay hospital or similar institution", - "31": "Other", - "32": "Do not know", - "33": "Prefer not to say" - }, - "conditional_for": { - "other_reason_for_leaving_last_settled_home": ["Other"] - } - }, - "other_reason_for_leaving_last_settled_home": { - "header": "Please state the reason for leaving last settled home", - "hint_text": "", - "type": "text" - }, - "benefit_cap_spare_room_subsidy": { - "header": "Was the reason for leaving because of the benefit cap or removal of the spare room subsidy?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Yes - benefit cap", - "1": "Yes - removal of the spare room subsidy", - "2": "Yes - both the benefit cap and the removal of the spare room subsidy", - "3": "No", - "4": "Do not know", - "5": "Prefer not to say" - } - } - } - } - } - }, - "household_needs": { - "label": "Household needs", - "pages": { - "armed_forces": { - "header": "Experience of the UK Armed Forces", - "description": "", - "questions": { - "armed_forces": { - "header": "Has the tenant ever served in the UK armed forces?", - "hint_text": "", - "type": "radio", - "check_answer_label": "Armed Forces", - "answer_options": { - "0": "Yes - a regular", - "1": "Yes - a reserve", - "2": "No", - "3": "Prefer not to say" - }, - "conditional_for": { - "armed_forces_active": ["Yes - a regular", "Yes - a reserve"], - "armed_forces_injured": ["Yes - a regular", "Yes - a reserve"] - } - }, - "armed_forces_active": { - "header": "Are they still serving?", - "hint_text": "", - "type": "radio", - "check_answer_label": "When did they leave the Armed Forces?", - "answer_options": { - "0": "Yes", - "1": "No - they left up to 5 years ago", - "2": "No - they left more than 5 years ago", - "3": "Prefer not to say" - } - }, - "armed_forces_injured": { - "header": "Were they seriously injured or ill as a result of their service?", - "hint_text": "", - "type": "radio", - "check_answer_label": "Has anyone in the household been seriously injured or ill as a result of their service in the armed forces?", - "answer_options": { - "0": "Yes", - "1": "No", - "2": "Prefer not to say" - } - }, - "armed_forces_partner": { - "header": "Was the tenant the spouse or civil partner of someone who served in the UK armed forces?", - "hint_text": "", - "type": "radio", - "check_answer_label": "Was the tenant the spouse or civil partner of someone who served in the UK armed forces?", - "answer_options": { - "0": "Yes - was the spouse or civil partner of a UK Armed Forces member and have separated within the last 2 years", - "1": "Yes - was the spouse or civil partner of a UK Armed Forces member who died within the last 2 years", - "2": "No", - "3": "Prefer not to say" - } - } - } - }, - "medical_conditions": { - "header": "", - "description": "", - "questions": { - "medical_conditions": { - "header": "Does anyone in the household have any of the following that they expect to last for 12 months or more:
  • Physical Condition
  • Mental Health Condition
  • Other Illness
", - "hint_text": "", - "type": "radio", - "check_answer_label": "Physical, mental health or illness in the household", - "answer_options": { - "0": "Yes", - "1": "No", - "2": "Do not know", - "3": "Prefer not to say" - } - } - } - }, - "pregnancy": { - "header": "", - "description": "", - "questions": { - "pregnancy": { - "header": "Is anyone in the household pregnant?", - "hint_text": "", - "type": "radio", - "check_answer_label": "Pregnancy in the household", - "answer_options": { - "0": "Yes", - "1": "No", - "2": "Prefer not to say" - } - } - } - }, - "accessibility_requirements": { - "header": "", - "description": "", - "questions": { - "accessibility_requirements": { - "header": "Are any of these affected by their condition or illness?", - "hint_text": "Select all that apply", - "type": "checkbox", - "check_answer_label": "Disability requirements", - "answer_options": { - "accessibility_requirements_fully_wheelchair_accessible_housing": "Fully wheelchair accessible housing", - "accessibility_requirements_wheelchair_access_to_essential_rooms": "Wheelchair access to essential rooms", - "accessibility_requirements_level_access_housing": "Level access housing", - "accessibility_requirements_other_disability_requirements": "Other disability requirements", - "accessibility_requirements_no_disability_requirements": "No disability requirements", - "divider_a": true, - "accessibility_requirements_do_not_know": "Do not know", - "divider_b": true, - "accessibility_requirements_prefer_not_to_say": "Prefer not to say" - } - } - } - }, - "condition_effects": { - "header": "", - "description": "", - "questions": { - "condition_effects": { - "header": "Are any of these affected by their condition or illness?", - "hint_text": "Select all that apply", - "type": "checkbox", - "check_answer_label": "Conditions or illnesses", - "answer_options": { - "condition_effects_vision": "Vision - such as blindness or partial sight", - "condition_effects_hearing": "Hearing - such as deafness or partial hearing", - "condition_effects_mobility": "Mobility - such as walking short distances or climbing stairs", - "condition_effects_dexterity": "Dexterity - such as lifting and carrying objects or using a keyboard", - "condition_effects_stamina": "Stamina or breathing or fatigue", - "condition_effects_learning": "Learning or understanding or concentrating", - "condition_effects_memory": "Memory", - "condition_effects_mental_health": "Mental health - such as depression, anxiety, schizophrenia or bipolar", - "condition_effects_social_or_behavioral": "Socially or behaviourally - such as those associated with autism spectral disorder (ASD) including Aspergers’ or attention deficit hyperactivity disorder (ADHD))", - "condition_effects_other": "Other", - "divider": true, - "condition_effects_prefer_not_to_say": "Prefer not to say" - } - } - } - } - } - } - } - }, - "tenancy_and_property": { - "label": "Tenancy and property information", - "subsections": { - "tenancy_information": { - "label": "Tenancy information", - "pages": { - "tenancy_code": { - "header": "", - "description": "", - "questions": { - "tenancy_code": { - "check_answer_label": "What is the tenancy code?", - "header": "What is the tenancy code?", - "hint_text": "", - "type": "text" - } - } - }, - "tenancy_start_date": { - "header": "", - "description": "", - "questions": { - "tenancy_start_date": { - "check_answer_label": "When is the tenancy start date?", - "header": "What is the tenancy start date?", - "hint_text": "For example, 27 3 2007", - "type": "date" - } - } - }, - "starter_tenancy": { - "header": "", - "description": "", - "questions": { - "starter_tenancy": { - "check_answer_label": "Is this a starter or introductory tenancy?", - "header": "Is this a starter tenancy?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Yes", - "1": "No" - } - } - } - }, - "fixed_term_tenancy": { - "header": "", - "description": "", - "questions": { - "fixed_term_tenancy": { - "check_answer_label": "If the main tenancy is a fixed term tenancy, please provide the length of the fixed term (to the nearest year) excluding any starter/introductory period", - "header": "If fixed-term, what is the length of the fixed-term tenancy after any starter period?", - "hint_text": "To the nearest year", - "type": "numeric", - "min": 0, - "max": 150, - "step": 1 - } - } - }, - "tenancy_type": { - "header": "", - "description": "", - "questions": { - "tenancy_type": { - "check_answer_label": "Type of main tenancy (after any starter/introductory period)", - "header": "What is the type of tenancy after the starter period has ended?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Fixed term – Secure", - "1": "Fixed term – Assured Shorthold Tenancy (AST)", - "2": "Lifetime – Secure", - "3": "Lifetime – Assured", - "4": "License agreement", - "5": "Other" - }, - "conditional_for": { - "other_tenancy_type": ["Other"] - } - }, - "other_tenancy_type": { - "header": "Please state the tenancy type", - "hint_text": "", - "type": "text" - } - } - }, - "letting_type": { - "header": "", - "description": "", - "questions": { - "letting_type": { - "check_answer_label": "Type of letting", - "header": "Which type of letting is this?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Social Rent - General Needs", - "1": "Social Rent - Supporting Housing", - "2": "Affordable Rent - General Needs", - "3": "Affordable Rent - Supporting Housing", - "4": "Rent To Buy - General Needs", - "5": "Rent To Buy - Supported Housing" - } - } - } - }, - "letting_provider": { - "header": "", - "description": "", - "questions": { - "letting_provider": { - "check_answer_label": "Provider", - "header": "Who is the letting provider?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "This landlord", - "1": "Another registered provider - includes housing association or local authority" - } - } - } - } - } - }, - "property_information": { - "label": "Property information", - "pages": { - "property_location": { - "header": "", - "description": "", - "questions": { - "property_location": { - "check_answer_label": "Property Location", - "header": "Property location", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Adur", - "1": "Allerdale", - "2": "Amber Valley", - "3": "Arun", - "4": "Ashfield", - "5": "Ashford", - "6": "Babergh", - "7": "Barking & Dagenham", - "8": "Barnet", - "9": "Barnsley", - "10": "Barrow-in-Furness", - "11": "Basildon", - "12": "Basingstoke & Deane", - "13": "Bassetlaw", - "14": "Bath & NE Somerset", - "15": "Bedford Borough Council", - "16": "Bexley", - "17": "Birmingham", - "18": "Blaby", - "19": "Blackburn", - "20": "Blackpool", - "21": "Bolsover", - "22": "Bolton", - "23": "Boston", - "24": "Bournemouth & Christchurch & Poole", - "25": "Bracknell Forest", - "26": "Bradford", - "27": "Braintree", - "28": "Breckland", - "29": "Brent", - "30": "Brentwood", - "31": "Brighton & Hove", - "32": "Bristol", - "33": "Broadland", - "34": "Bromley", - "35": "Bromsgrove", - "36": "Broxbourne", - "37": "Broxtowe", - "38": "Buckinghamshire", - "39": "Burnley", - "40": "Bury", - "41": "Calderdale", - "42": "Cambridge", - "43": "Camden", - "44": "Cannock Chase", - "45": "Canterbury", - "46": "Carlisle", - "47": "Castle Point", - "48": "Central Bedfordshire", - "49": "Charnwood", - "50": "Chelmsford", - "51": "Cheltenham", - "52": "Cherwell", - "53": "Cheshire West & Chester", - "54": "Chesterfield", - "55": "Chichester", - "56": "Chorley", - "57": "City of London", - "58": "Colchester", - "59": "Copeland", - "60": "Cornwall", - "61": "Cotswold", - "62": "Coventry", - "63": "Craven", - "64": "Crawley", - "65": "Croydon", - "66": "Dacorum", - "67": "Darlington", - "68": "Dartford", - "69": "Derby", - "70": "Derbyshire Dales", - "71": "Doncaster", - "72": "Dorset", - "73": "Dover", - "74": "Dudley", - "75": "Durham", - "76": "Ealing", - "77": "East Cambridgeshire", - "78": "East Cheshire", - "79": "East Devon", - "80": "East Hampshire", - "81": "East Herts", - "82": "East Lindsey", - "83": "East Riding", - "84": "East Staffordshire", - "85": "East Suffolk", - "86": "Eastbourne", - "87": "Eastleigh", - "88": "Eden", - "89": "Elmbridge", - "90": "Enfield", - "91": "Epping Forest", - "92": "Epsom & Ewell", - "93": "Erewash", - "94": "Exeter", - "95": "Fareham", - "96": "Fenland", - "97": "Folkestone & Hythe", - "98": "Forest of Dean", - "99": "Fylde", - "100": "Gateshead", - "101": "Gedling", - "102": "Gloucester", - "103": "Gosport", - "104": "Gravesham", - "105": "Great Yarmouth", - "106": "Greenwich", - "107": "Guildford", - "108": "Hackney", - "109": "Halton", - "110": "Hambleton", - "111": "Hammersmith & Fulham", - "112": "Harborough", - "113": "Haringey", - "114": "Harlow", - "115": "Harrogate", - "116": "Harrow", - "117": "Hart", - "118": "Hartlepool", - "119": "Hastings", - "120": "Havant", - "121": "Havering", - "122": "Herefordshire", - "123": "Hertsmere", - "124": "High Peak", - "125": "Hillingdon", - "126": "Hinckley & Bosworth", - "127": "Horsham", - "128": "Hounslow", - "129": "Huntingdonshire", - "130": "Hyndburn", - "131": "Ipswich", - "132": "Isle of Wight", - "133": "Isles of Scilly", - "134": "Islington", - "135": "Kensington & Chelsea", - "136": "Kings Lynn & West Norfolk", - "137": "Kingston-upon-Hull", - "138": "Kingston-upon-Thames", - "139": "Kirklees", - "140": "Knowsley", - "141": "Lambeth", - "142": "Lancaster", - "143": "Leeds", - "144": "Leicester", - "145": "Lewes", - "146": "Lewisham", - "147": "Lichfield", - "148": "Lincoln", - "149": "Liverpool", - "150": "Luton", - "151": "Maidstone", - "152": "Maldon", - "153": "Malvern Hills", - "154": "Manchester", - "155": "Mansfield", - "156": "Medway", - "157": "Melton", - "158": "Mendip", - "159": "Merton", - "160": "Mid Devon", - "161": "Mid Suffolk", - "162": "Mid Sussex", - "163": "Middlesbrough", - "164": "Milton Keynes", - "165": "Mole Valley", - "166": "N. Ireland", - "167": "New Forest", - "168": "Newark", - "169": "Newcastle-under-Lyme", - "170": "Newcastle-upon-Tyne", - "171": "Newham", - "172": "North Devon", - "173": "North East Derbyshire", - "174": "North East Lincolnshire", - "175": "North Hertfordshire", - "176": "North Kesteven", - "177": "North Lincolnshire", - "178": "North Norfolk", - "179": "North Northamptonshire", - "180": "North Somerset", - "181": "North Tyneside", - "182": "North Warwickshire", - "183": "North West Leics", - "184": "Northumberland", - "185": "Norwich", - "186": "Nottingham", - "187": "Nuneaton & Bedworth", - "188": "Oadby & Wigston", - "189": "Oldham", - "190": "Outside UK", - "191": "Oxford", - "192": "Pendle", - "193": "Peterborough", - "194": "Plymouth", - "195": "Portsmouth", - "196": "Preston", - "197": "Reading", - "198": "Redbridge", - "199": "Redcar & Cleveland", - "200": "Redditch", - "201": "Reigate & Banstead", - "202": "Ribble Valley", - "203": "Richmond-upon-Thames", - "204": "Richmondshire", - "205": "Rochdale", - "206": "Rochford", - "207": "Rossendale", - "208": "Rother", - "209": "Rotherham", - "210": "Rugby", - "211": "Runnymede", - "212": "Rushcliffe", - "213": "Rushmoor", - "214": "Rutland", - "215": "Ryedale", - "216": "Salford", - "217": "Sandwell", - "218": "Scarborough", - "219": "Scotland", - "220": "Sedgemoor", - "221": "Sefton", - "222": "Selby", - "223": "Sevenoaks", - "224": "Sheffield", - "225": "Shropshire", - "226": "Slough", - "227": "Solihull", - "228": "Somerset West & Taunton", - "229": "South Cambridgeshire", - "230": "South Derbyshire", - "231": "South Gloucestershire", - "232": "South Hams", - "233": "South Holland", - "234": "South Kesteven", - "235": "South Lakeland", - "236": "South Norfolk", - "237": "South Oxfordshire", - "238": "South Ribble", - "239": "South Somerset", - "240": "South Staffordshire", - "241": "South Tyneside", - "242": "Southampton", - "243": "Southend-on-Sea", - "244": "Southwark", - "245": "Spelthorne", - "246": "St Albans", - "247": "St Helens", - "248": "Stafford", - "249": "Staffordshire Moorlands", - "250": "Stevenage", - "251": "Stockport", - "252": "Stockton-on-Tees", - "253": "Stoke-on-Trent", - "254": "Stratford-on-Avon", - "255": "Stroud", - "256": "Sunderland", - "257": "Surrey Heath", - "258": "Sutton", - "259": "Swale", - "260": "Swindon", - "261": "Tameside", - "262": "Tamworth", - "263": "Tandridge", - "264": "Teignbridge", - "265": "Telford & Wrekin", - "266": "Tendring", - "267": "Test Valley", - "268": "Tewkesbury", - "269": "Thanet", - "270": "Three Rivers", - "271": "Thurrock", - "272": "Tonbridge & Malling", - "273": "Torbay", - "274": "Torridge", - "275": "Tower Hamlets", - "276": "Trafford", - "277": "Tunbridge Wells", - "278": "Uttlesford", - "279": "Vale of White Horse", - "280": "Wakefield", - "281": "Wales", - "282": "Walsall", - "283": "Waltham Forest", - "284": "Wandsworth", - "285": "Warrington", - "286": "Warwick", - "287": "Watford", - "288": "Waverley", - "289": "Wealden", - "290": "Welwyn Hatfield", - "291": "West Berkshire", - "292": "West Devon", - "293": "West Lancashire", - "294": "West Lindsey", - "295": "West Northamptonshire", - "296": "West Oxfordshire", - "297": "West Suffolk", - "298": "Westminster", - "299": "Wigan", - "300": "Wiltshire", - "301": "Winchester", - "302": "Windsor & Maidenhead", - "303": "Wirral", - "304": "Woking", - "305": "Wokingham", - "306": "Wolverhampton", - "307": "Worcester", - "308": "Worthing", - "309": "Wychavon", - "310": "Wyre", - "311": "Wyre Forest", - "312": "York" - } - } - } - }, - "property_postcode": { - "header": "", - "description": "", - "questions": { - "property_postcode": { - "check_answer_label": "What was the previous postcode?", - "header": "What is the property's postcode?", - "hint_text": "", - "type": "text" - } - } - }, - "property_relet": { - "header": "", - "description": "", - "questions": { - "property_relet": { - "check_answer_label": "Which type was the property most recently let as?", - "header": "Is this property a relet?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Yes", - "1": "No" - } - } - } - }, - "property_vacancy_reason": { - "header": "", - "description": "", - "questions": { - "property_vacancy_reason": { - "check_answer_label": "What is the reason for the property vacancy?", - "header": "What is the reason for the property vacancy?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "First let of newbuild property", - "1": "First let of conversion/rehabilitation/acquired property", - "2": "First let of leased property", - "3": "Relet - tenant evicted due to arrears", - "4": "Relet - tenant evicted due to ASB or other reason", - "5": "Relet - tenant died (no succession)", - "6": "Relet - tenant moved to other social housing provider", - "7": "Relet - tenant abandoned property", - "8": "Relet - tenant moved to private sector or other accommodation", - "9": "Relet - to tenant who occupied same property as temporary accommodation", - "10": "Relet – internal transfer (excluding renewals of a fixed-term tenancy)", - "11": "Relet – renewal of fixed-term tenancy", - "12": "Relet – tenant moved to care home", - "13": "Relet – tenant involved in a succession downsize" - } - } - } - }, - "property_reference": { - "header": "", - "description": "", - "questions": { - "property_reference": { - "check_answer_label": "What’s the property reference?", - "header": "What's the property reference?", - "hint_text": "", - "type": "text" - } - } - }, - "property_unit_type": { - "header": "", - "description": "", - "questions": { - "property_unit_type": { - "check_answer_label": "Which type of unit is the property?", - "header": "Which type of unit is the property?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Flat / maisonette", - "1": "Bed-sit", - "2": "House", - "3": "Bungalow", - "4": "Shared flat / maisonette", - "5": "Shared house", - "6": "Shared bungalow", - "7": "Other" - } - } - } - }, - "property_number_of_bedrooms": { - "header": "", - "description": "", - "questions": { - "property_number_of_bedrooms": { - "check_answer_label": "How many bedrooms are there in the property?", - "header": "How many bedrooms are there in the property?", - "hint_text": "If shared accommodation, enter number of bedrooms occupied by this household; a bed-sit has 1 bedroom", - "type": "numeric", - "min": 0, - "max": 150, - "step": 1 - } - } - }, - "property_major_repairs": { - "header": "", - "description": "", - "questions": { - "property_major_repairs": { - "check_answer_label": "Were major repairs carried out during the void period?", - "header": "Were any major repairs completed during the void period?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Yes", - "1": "No" + "type": "object", + "patternProperties": { + "[a-z_]+": { + "description": "", + "type": "object", + "properties": { + "label": { + "description": "", + "type": "string" + }, + "subsections": { + "type": "object", + "patternProperties": { + "[a-z_]+": { + "description": "", + "type": "object", + "required": ["label"], + "properties": { + "label": { + "description": "", + "type": "string" }, - "conditional_for": { - "property_major_repairs_date": ["Yes"] - } - }, - "property_major_repairs_date": { - "check_answer_label": "What was the major repairs completion date?", - "header": "What was the major repairs completion date?", - "hint_text": "For example, 27 3 2007", - "type": "date" - } - } - }, - "property_number_of_times_relet": { - "header": "", - "description": "", - "questions": { - "property_number_of_times_relet": { - "check_answer_label": "How many times has this unit been previously offered since becoming available for relet since the last tenancy ended or as a first let?", - "header": "How many times has this unit been previously offered since becoming available for relet since the last tenancy ended or as a first let? ", - "hint_text": "For an Affordable Rent or Intermediate Rent Letting, only include number of offers as that type. For a property let at the first attempt enter '0' ", - "type": "numeric", - "min": 0, - "max": 150, - "step": 1 - } - } - }, - "property_wheelchair_accessible": { - "header": "", - "description": "", - "questions": { - "property_wheelchair_accessible": { - "check_answer_label": "Is property built or adapted to wheelchair user standards?", - "header": "Is property built or adapted to wheelchair user standards?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Yes", - "1": "No" - } - } - } - } + "pages": { + "type": "object", + "patternProperties": { + "[a-z_]+": { + "description": "", + "type": "object", + "properties": { + "header": { + "description": "", + "type": "string" + }, + "description": { + "description": "", + "type": "string" + }, + "questions": { + "type": "object", + "patternProperties": { + "[a-z_]+": { + "description": "", + "type": "object", + "required": ["header", "check_answer_label"], + "properties": { + "check_answer_label": { + "description": "", + "type": "string" + }, + "header": { + "description": "", + "type": "string" + }, + "type": { + "description": "", + "type": "string" + }, + "hint_text": { + "description": "", + "type": "string" + }, + "answer_options": { + "description": "", + "type": "object" + }, + "conditional_for": { + "description": "", + "type": "object" + } + } + } + } + } + }, + "minProperties": 1 + } + } + } + }, + "minProperties": 1 + } + } } - } + }, + "minProperties": 2 } }, - "rent_and_charges": { - "label": "Rent and charges", - "subsections": { - "income_and_benefits": { - "label": "Income and benefits", - "pages": { - "net_income": { - "header": "", - "description": "", - "questions": { - "net_income_known": { - "check_answer_label": "Income known", - "header": "Do you know the tenant and their partner's net income?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Yes", - "1": "No", - "2": "Tenant prefers not to say" - }, - "conditional_for": { - "net_income": ["Yes"], - "net_income_frequency": ["Yes"] - } - }, - "net_income": { - "check_answer_label": "Income", - "header": "What is the tenant’s /and partner’s combined income after tax?", - "hint_text": "", - "type": "numeric", - "min": 0, - "step": "1" - }, - "net_income_frequency": { - "check_answer_label": "Income Frequency", - "header": "How often do they receive this income?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Weekly", - "1": "Monthly", - "2": "Yearly" - } - } - }, - "soft_validations": { - "override_net_income_validation": { - "check_answer_label": "Net income confirmed?", - "type": "validation_override", - "answer_options": { - "override_net_income_validation": "Yes" - } - } - } - }, - "net_income_uc_proportion": { - "header": "", - "description": "", - "questions": { - "net_income_uc_proportion": { - "check_answer_label": "Benefits as a proportion of income", - "header": "How much of the tenant’s income is from Universal Credit, state pensions or benefits?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "All", - "1": "Some", - "2": "None", - "3": "Do not know" - } - } - } - }, - "housing_benefit": { - "header": "", - "description": "", - "questions": { - "housing_benefit": { - "check_answer_label": "Universal Credit & Housing Benefit\t", - "header": "Is the tenant likely to be in receipt of any of these housing-related benefits?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Housing Benefit, but not Universal Credit", - "1": "Universal Credit with housing element, but not Housing Benefit", - "2": "Universal Credit without housing element and no Housing Benefit", - "3": "Universal Credit and Housing Benefit", - "4": "Not Housing Benefit or Universal Credit", - "5": "Do not know", - "6": "Prefer not to say" - } - } - } - } - } - }, - "rent": { - "label": "Rent", - "pages": { - "rent": { - "header": "", - "description": "", - "questions": { - "rent_frequency": { - "check_answer_label": "Rent Period", - "header": "Which period are rent and other charges due?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Weekly for 52 weeks", - "1": "Fortnightly", - "2": "Four-weekly", - "3": "Calendar monthly", - "4": "Weekly for 50 weeks", - "5": "Weekly for 49 weeks", - "6": "Weekly for 48 weeks", - "7": "Weekly for 47 weeks", - "8": "Weekly for 46 weeks", - "9": "Weekly for 53 weeks" - } - }, - "basic_rent": { - "check_answer_label": "Basic Rent", - "header": "What is the basic rent?", - "hint_text": "Eligible for housing benefit or Universal Credit", - "type": "numeric", - "min": 0, - "step": 1, - "fields-to-add": ["basic_rent", "service_charge", "personal_service_charge", "support_charge"], - "result-field": "total_charge" - }, - "service_charge": { - "check_answer_label": "Service Charge", - "header": "What is the service charge?", - "hint_text": "Eligible for housing benefit or Universal Credit", - "type": "numeric", - "min": 0, - "step": 1, - "fields-to-add": ["basic_rent", "service_charge", "personal_service_charge", "support_charge"], - "result-field": "total_charge" - }, - "personal_service_charge": { - "check_answer_label": "Personal Service Charge", - "header": "What is the personal service charge?", - "hint_text": "Not eligible for housing benefit or Universal Credit. For example, hot water excluding water rates.", - "type": "numeric", - "min": 0, - "step": 1, - "fields-to-add": ["basic_rent", "service_charge", "personal_service_charge", "support_charge"], - "result-field": "total_charge" - }, - "support_charge": { - "check_answer_label": "Support Charge", - "header": "What is the support charge?", - "hint_text": "This is to fund housing-related support services included in the tenancy agreement", - "type": "numeric", - "min": 0, - "step": 1, - "fields-to-add": ["basic_rent", "service_charge", "personal_service_charge", "support_charge"], - "result-field": "total_charge" - }, - "total_charge": { - "check_answer_label": "Total Charge", - "header": "Total charge?", - "hint_text": "This is the total of rent and all charges", - "type": "numeric", - "min": 0, - "step": 1, - "readonly": true - }, - "outstanding_rent_or_charges": { - "check_answer_label": "After housing benefit and/or housing element of UC payment is received, will there be an outstanding amount for basic rent and/or benefit eligible charges?", - "header": "After housing benefit and/or housing element of UC payment is received, will there be an outstanding amount for basic rent and/or benefit eligible charges?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Yes", - "1": "No" - }, - "conditional_for": { - "outstanding_amount": ["Yes"] - } - }, - "outstanding_amount": { - "check_answer_label": "Outstanding amount", - "header": "What do you expect the amount to be?", - "hint_text": "If the amount is unknown you can estimate", - "type": "numeric", - "min": 0, - "step": 1 - } - } - } - } - } - } - }, - "local_authority": { - "label": "Local authority", - "subsections": { - "local_authority": { - "label": "Local authority", - "pages": { - "time_lived_in_la": { - "header": "", - "description": "", - "questions": { - "time_lived_in_la": { - "check_answer_label": "How long has the household continuously lived in the local authority area where the new letting is located?", - "header": "How long has the household continuously lived in the local authority area where the new letting is located?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Just moved to local authority area", - "1": "Less than 1 year", - "2": "1 to 2 years", - "3": "2 to 3 years", - "4": "3 to 4 years", - "5": "4 to 5 years", - "6": "5 years or more", - "7": "Do not know" - } - } - } - }, - "time_on_la_waiting_list": { - "header": "", - "description": "", - "questions": { - "time_on_la_waiting_list": { - "check_answer_label": "How long has the household been on the local authority waiting list where the new letting is located?", - "header": "How long has the household been on the local authority waiting list where the new letting is located?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Just moved to local authority area", - "1": "Less than 1 year", - "2": "1 to 2 years", - "3": "2 to 3 years", - "4": "3 to 4 years", - "5": "4 to 5 years", - "6": "5 years or more", - "7": "Do not know" - } - } - } - }, - "previous_la": { - "header": "", - "description": "", - "questions": { - "previous_la": { - "check_answer_label": "The LA in which household lived immediately before this letting\t", - "header": "Which local authority area did the household live in immediately before this letting?", - "hint_text": "Includes temporary accommodation", - "type": "radio", - "answer_options": { - "0": "Adur", - "1": "Allerdale", - "2": "Amber Valley", - "3": "Arun", - "4": "Ashfield", - "5": "Ashford", - "6": "Babergh", - "7": "Barking & Dagenham", - "8": "Barnet", - "9": "Barnsley", - "10": "Barrow-in-Furness", - "11": "Basildon", - "12": "Basingstoke & Deane", - "13": "Bassetlaw", - "14": "Bath & NE Somerset", - "15": "Bedford Borough Council", - "16": "Bexley", - "17": "Birmingham", - "18": "Blaby", - "19": "Blackburn", - "20": "Blackpool", - "21": "Bolsover", - "22": "Bolton", - "23": "Boston", - "24": "Bournemouth & Christchurch & Poole", - "25": "Bracknell Forest", - "26": "Bradford", - "27": "Braintree", - "28": "Breckland", - "29": "Brent", - "30": "Brentwood", - "31": "Brighton & Hove", - "32": "Bristol", - "33": "Broadland", - "34": "Bromley", - "35": "Bromsgrove", - "36": "Broxbourne", - "37": "Broxtowe", - "38": "Buckinghamshire", - "39": "Burnley", - "40": "Bury", - "41": "Calderdale", - "42": "Cambridge", - "43": "Camden", - "44": "Cannock Chase", - "45": "Canterbury", - "46": "Carlisle", - "47": "Castle Point", - "48": "Central Bedfordshire", - "49": "Charnwood", - "50": "Chelmsford", - "51": "Cheltenham", - "52": "Cherwell", - "53": "Cheshire West & Chester", - "54": "Chesterfield", - "55": "Chichester", - "56": "Chorley", - "57": "City of London", - "58": "Colchester", - "59": "Copeland", - "60": "Cornwall", - "61": "Cotswold", - "62": "Coventry", - "63": "Craven", - "64": "Crawley", - "65": "Croydon", - "66": "Dacorum", - "67": "Darlington", - "68": "Dartford", - "69": "Derby", - "70": "Derbyshire Dales", - "71": "Doncaster", - "72": "Dorset", - "73": "Dover", - "74": "Dudley", - "75": "Durham", - "76": "Ealing", - "77": "East Cambridgeshire", - "78": "East Cheshire", - "79": "East Devon", - "80": "East Hampshire", - "81": "East Herts", - "82": "East Lindsey", - "83": "East Riding", - "84": "East Staffordshire", - "85": "East Suffolk", - "86": "Eastbourne", - "87": "Eastleigh", - "88": "Eden", - "89": "Elmbridge", - "90": "Enfield", - "91": "Epping Forest", - "92": "Epsom & Ewell", - "93": "Erewash", - "94": "Exeter", - "95": "Fareham", - "96": "Fenland", - "97": "Folkestone & Hythe", - "98": "Forest of Dean", - "99": "Fylde", - "100": "Gateshead", - "101": "Gedling", - "102": "Gloucester", - "103": "Gosport", - "104": "Gravesham", - "105": "Great Yarmouth", - "106": "Greenwich", - "107": "Guildford", - "108": "Hackney", - "109": "Halton", - "110": "Hambleton", - "111": "Hammersmith & Fulham", - "112": "Harborough", - "113": "Haringey", - "114": "Harlow", - "115": "Harrogate", - "116": "Harrow", - "117": "Hart", - "118": "Hartlepool", - "119": "Hastings", - "120": "Havant", - "121": "Havering", - "122": "Herefordshire", - "123": "Hertsmere", - "124": "High Peak", - "125": "Hillingdon", - "126": "Hinckley & Bosworth", - "127": "Horsham", - "128": "Hounslow", - "129": "Huntingdonshire", - "130": "Hyndburn", - "131": "Ipswich", - "132": "Isle of Wight", - "133": "Isles of Scilly", - "134": "Islington", - "135": "Kensington & Chelsea", - "136": "Kings Lynn & West Norfolk", - "137": "Kingston-upon-Hull", - "138": "Kingston-upon-Thames", - "139": "Kirklees", - "140": "Knowsley", - "141": "Lambeth", - "142": "Lancaster", - "143": "Leeds", - "144": "Leicester", - "145": "Lewes", - "146": "Lewisham", - "147": "Lichfield", - "148": "Lincoln", - "149": "Liverpool", - "150": "Luton", - "151": "Maidstone", - "152": "Maldon", - "153": "Malvern Hills", - "154": "Manchester", - "155": "Mansfield", - "156": "Medway", - "157": "Melton", - "158": "Mendip", - "159": "Merton", - "160": "Mid Devon", - "161": "Mid Suffolk", - "162": "Mid Sussex", - "163": "Middlesbrough", - "164": "Milton Keynes", - "165": "Mole Valley", - "166": "N. Ireland", - "167": "New Forest", - "168": "Newark", - "169": "Newcastle-under-Lyme", - "170": "Newcastle-upon-Tyne", - "171": "Newham", - "172": "North Devon", - "173": "North East Derbyshire", - "174": "North East Lincolnshire", - "175": "North Hertfordshire", - "176": "North Kesteven", - "177": "North Lincolnshire", - "178": "North Norfolk", - "179": "North Northamptonshire", - "180": "North Somerset", - "181": "North Tyneside", - "182": "North Warwickshire", - "183": "North West Leics", - "184": "Northumberland", - "185": "Norwich", - "186": "Nottingham", - "187": "Nuneaton & Bedworth", - "188": "Oadby & Wigston", - "189": "Oldham", - "190": "Outside UK", - "191": "Oxford", - "192": "Pendle", - "193": "Peterborough", - "194": "Plymouth", - "195": "Portsmouth", - "196": "Preston", - "197": "Reading", - "198": "Redbridge", - "199": "Redcar & Cleveland", - "200": "Redditch", - "201": "Reigate & Banstead", - "202": "Ribble Valley", - "203": "Richmond-upon-Thames", - "204": "Richmondshire", - "205": "Rochdale", - "206": "Rochford", - "207": "Rossendale", - "208": "Rother", - "209": "Rotherham", - "210": "Rugby", - "211": "Runnymede", - "212": "Rushcliffe", - "213": "Rushmoor", - "214": "Rutland", - "215": "Ryedale", - "216": "Salford", - "217": "Sandwell", - "218": "Scarborough", - "219": "Scotland", - "220": "Sedgemoor", - "221": "Sefton", - "222": "Selby", - "223": "Sevenoaks", - "224": "Sheffield", - "225": "Shropshire", - "226": "Slough", - "227": "Solihull", - "228": "Somerset West & Taunton", - "229": "South Cambridgeshire", - "230": "South Derbyshire", - "231": "South Gloucestershire", - "232": "South Hams", - "233": "South Holland", - "234": "South Kesteven", - "235": "South Lakeland", - "236": "South Norfolk", - "237": "South Oxfordshire", - "238": "South Ribble", - "239": "South Somerset", - "240": "South Staffordshire", - "241": "South Tyneside", - "242": "Southampton", - "243": "Southend-on-Sea", - "244": "Southwark", - "245": "Spelthorne", - "246": "St Albans", - "247": "St Helens", - "248": "Stafford", - "249": "Staffordshire Moorlands", - "250": "Stevenage", - "251": "Stockport", - "252": "Stockton-on-Tees", - "253": "Stoke-on-Trent", - "254": "Stratford-on-Avon", - "255": "Stroud", - "256": "Sunderland", - "257": "Surrey Heath", - "258": "Sutton", - "259": "Swale", - "260": "Swindon", - "261": "Tameside", - "262": "Tamworth", - "263": "Tandridge", - "264": "Teignbridge", - "265": "Telford & Wrekin", - "266": "Tendring", - "267": "Test Valley", - "268": "Tewkesbury", - "269": "Thanet", - "270": "Three Rivers", - "271": "Thurrock", - "272": "Tonbridge & Malling", - "273": "Torbay", - "274": "Torridge", - "275": "Tower Hamlets", - "276": "Trafford", - "277": "Tunbridge Wells", - "278": "Uttlesford", - "279": "Vale of White Horse", - "280": "Wakefield", - "281": "Wales", - "282": "Walsall", - "283": "Waltham Forest", - "284": "Wandsworth", - "285": "Warrington", - "286": "Warwick", - "287": "Watford", - "288": "Waverley", - "289": "Wealden", - "290": "Welwyn Hatfield", - "291": "West Berkshire", - "292": "West Devon", - "293": "West Lancashire", - "294": "West Lindsey", - "295": "West Northamptonshire", - "296": "West Oxfordshire", - "297": "West Suffolk", - "298": "Westminster", - "299": "Wigan", - "300": "Wiltshire", - "301": "Winchester", - "302": "Windsor & Maidenhead", - "303": "Wirral", - "304": "Woking", - "305": "Wokingham", - "306": "Wolverhampton", - "307": "Worcester", - "308": "Worthing", - "309": "Wychavon", - "310": "Wyre", - "311": "Wyre Forest", - "312": "York" - } - } - } - }, - "previous_postcode": { - "header": "", - "description": "", - "questions": { - "previous_postcode": { - "check_answer_label": "Postcode of previous accomodation if the household has moved from settled accommodation", - "header": "Postcode for the previous accommodation", - "hint_text": "If the household has moved from settled accommodation immediately prior to being re-housed", - "type": "text" - } - } - }, - "reasonable_preference": { - "header": "", - "description": "", - "questions": { - "reasonable_preference": { - "check_answer_label": "Was the household given Reasonable Preference (i.e. priority) for housing by the Local Authority?", - "header": "Was the household given reasonable preference by the local authority?", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Yes", - "1": "No" - }, - "conditional_for": { - "reasonable_preference_reason": ["Yes"] - } - }, - "reasonable_preference_reason": { - "check_answer_label": "Reason for reasonable preference", - "header": "Why were they given reasonable preference?", - "hint_text": "Select all that apply", - "type": "checkbox", - "answer_options": { - "reasonable_preference_reason_homeless": "Homeless or about to lose their home (within 56 days)", - "reasonable_preference_reason_unsatisfactory_housing": "Living in insanitary or overcrowded or unsatisfactory housing", - "reasonable_preference_reason_medical_grounds": "A need to move on medical and welfare grounds (including a disability)", - "reasonable_preference_reason_avoid_hardship": "A need to move to avoid hardship to themselves or others", - "divider": true, - "reasonable_preference_reason_do_not_know": "Do not know" - } - } - } - }, - "lettings_policy": { - "header": "", - "description": "", - "questions": { - "cbl_letting": { - "check_answer_label": "Choice-based letting?", - "header": "Was the letting made under choice-based lettings (CBL)? ", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Yes", - "1": "No" - } - }, - "chr_letting": { - "check_answer_label": "Common housing register letting?", - "header": "Was the letting made under common housing register (CHR)? ", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Yes", - "1": "No" - } - }, - "cap_letting": { - "check_answer_label": "Common allocation policy letting?", - "header": "Was the letting made under common allocation policy (CAP)? ", - "hint_text": "", - "type": "radio", - "answer_options": { - "0": "Yes", - "1": "No" - } - } - } - } - } - } - } - }, - "submission": { - "label": "Submission", - "subsections": { - "declaration": { - "label": "Declaration", - "pages": { - "declaration": { - "header": "", - "description": "", - "questions": { - "declaration": { - "check_answer_label": "", - "header": "What is the tenant code?", - "hint_text": "", - "type": "text" - } - } - } - } - } - } - } + "minProperties": 1 } } - \ No newline at end of file +} \ No newline at end of file diff --git a/config/forms/schema/generic.json b/config/forms/schema/generic.json index 50c08369c..d7654e063 100644 --- a/config/forms/schema/generic.json +++ b/config/forms/schema/generic.json @@ -21,69 +21,97 @@ "sections": { "type": "object", "patternProperties": { - "[a-z_\/#]+": { - "description": "", - "type": "object" - }, - "properties": { - "label": { - "description": "", - "type": "string" - }, - "subsections": { - "description": "", - "type": "object", - "patternProperties": { - "[a-z_\/#]+": { - "description": "", - "type": "object", - "required": ["label"], - "properties": { - "label": { - "description": "", - "type": "string", - "required": "true" - }, - "pages": { - "type": "object", - "required": ["header"], - "patternProperties": { + "[a-z_]+": { + "description": "Section Name", + "type": "object", + "properties": { + "label": { + "description": "", + "type": "string" + }, + "subsections": { + "type": "object", + "patternProperties": { + "[a-z_]+": { + "description": "SubSection Name", + "type": "object", + "required": ["label"], + "properties": { + "label": { + "description": "", + "type": "string" + }, + "pages": { "type": "object", - "[a-z_]+": { - "properties": { - "header": { - "description": "", - "type": "string" - }, - "description": { - "description": "", - "type": "string" - }, - "questions": { - "type": "object", - "patternProperties": { + "patternProperties": { + "[a-z_]+": { + "description": "Page Name", + "type": "object", + "required": ["header", "questions"], + "properties": { + "header": { + "description": "", + "type": "string" + }, + "description": { + "description": "", + "type": "string" + }, + "questions": { "type": "object", - "[a-z_]+": { - "properties": { - "check_answer_label": { - "type": "string" - } + "patternProperties": { + "[a-z_]+": { + "description": "Question Name", + "type": "object", + "required": ["header", "type"], + "properties": { + "header": { + "description": "", + "type": "string" + }, + "type": { + "description": "", + "type": "string" + } + }, + "additionalProperties": { + "hint_text": { + "optional": "true", + "description": "", + "type": "string" + }, + "answer_options": { + "optional": "true", + "description": "", + "type": "object" + }, + "check_answer_label": { + "description": "", + "type": "string" + } + }, + "minProperties": 1 } } - }, - "minProperties": 8 + } }, - "minProperties": 8 + "additionalProperties": { + "conditional_route_to": { + "description": "", + "type": "object" + } + }, + "minProperties": 1 } - } - }, - "minProperties": 8 - } + } + } + }, + "minProperties": 1 } - } - }, - "minProperties": 8 - } + } + } + }, + "minProperties": 2 } }, "minProperties": 1 diff --git a/config/forms/schema/test.json b/config/forms/schema/test.json deleted file mode 100644 index 93eaf9a6d..000000000 --- a/config/forms/schema/test.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "$id": "https://example.com/product.schema.json", - "title": "Form", - "description": "A form", - "type": "object", - "required": ["form_type", "start_year", "end_year", "sections"], - "properties": { - "form_type": { - "description": "", - "type": "string" - }, - "start_year": { - "description": "", - "type": "integer" - }, - "end_year": { - "description": "", - "type": "integer" - }, - "sections": { - "type": "object", - "patternProperties": { - "[a-z_]+": { - "description": "", - "type": "object", - "properties": { - "label": { - "description": "", - "type": "string" - }, - "subsections": { - "type": "object", - "patternProperties": { - "[a-z_]+": { - "description": "", - "type": "object", - "required": ["label"], - "properties": { - "label": { - "description": "", - "type": "string" - }, - "pages": { - "type": "object", - "patternProperties": { - "[a-z_]+": { - "description": "", - "type": "object", - "properties": { - "header": { - "description": "", - "type": "string" - }, - "description": { - "description": "", - "type": "string" - }, - "questions": { - "type": "object", - "patternProperties": { - "[a-z_]+": { - "description": "", - "type": "object", - "required": ["header"], - "properties": { - "check_answer_label": { - "description": "", - "type": "string" - }, - "header": { - "description": "", - "type": "string" - }, - "type": { - "description": "", - "type": "string" - }, - "hint_text": { - "description": "", - "type": "string" - }, - "answer_options": { - "description": "", - "type": "string" - } - } - } - } - } - }, - "minProperties": 1 - } - } - } - }, - "minProperties": 1 - } - } - } - }, - "minProperties": 2 - } - }, - "minProperties": 1 - } - } -} \ No newline at end of file diff --git a/spec/fixtures/forms/test_form.json b/spec/fixtures/forms/test_form.json deleted file mode 100644 index b5467a48f..000000000 --- a/spec/fixtures/forms/test_form.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "form_type": "lettings", - "start_year": 2021, - "end_year": 2022, - "sections": { - "household": { - "label": "About the household", - "subsections": { - "household_characteristics": { - "label": "Household characteristics", - "pages": { - } - } - } - } - } -} - \ No newline at end of file diff --git a/spec/fixtures/forms/test_validator.json b/spec/fixtures/forms/test_validator.json index e83c4d970..487b990f4 100644 --- a/spec/fixtures/forms/test_validator.json +++ b/spec/fixtures/forms/test_validator.json @@ -17,7 +17,8 @@ "header": "What is the tenant code?", "type": "text" } - } + }, + "conditional_route_to": {"test": "Yes"} } }, "person_1_age": { From d1db7528421d14c1ffff0250e6df5c0d4fb1c4a3 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Thu, 11 Nov 2021 11:45:33 +0000 Subject: [PATCH 20/55] only validate real forms --- app/helpers/json_schema_validation.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/helpers/json_schema_validation.rb b/app/helpers/json_schema_validation.rb index dd0655d3b..086110c54 100644 --- a/app/helpers/json_schema_validation.rb +++ b/app/helpers/json_schema_validation.rb @@ -29,7 +29,8 @@ begin return end - directories = ["config/forms", "spec/fixtures/forms"] + # directories = ["config/forms", "spec/fixtures/forms"] + directories = ["config/forms"] get_all_form_paths(directories).each do |path| puts path From c67fccdcd0da0b04cc55d744021adcc65224d8c4 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Thu, 11 Nov 2021 12:37:26 +0000 Subject: [PATCH 21/55] change pattern to ignore conditional_route_to --- app/helpers/json_schema_validation.rb | 1 - config/forms/schema/generic.json | 6 +++++- spec/fixtures/forms/test_validator.json | 4 +++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/helpers/json_schema_validation.rb b/app/helpers/json_schema_validation.rb index 086110c54..07ba995e6 100644 --- a/app/helpers/json_schema_validation.rb +++ b/app/helpers/json_schema_validation.rb @@ -14,7 +14,6 @@ end begin path = "config/forms/schema/generic.json" - # path = "config/forms/schema/2021_2022.json" file = File.open(path) schema = JSON.parse(file.read) diff --git a/config/forms/schema/generic.json b/config/forms/schema/generic.json index d7654e063..d9b0f8cc5 100644 --- a/config/forms/schema/generic.json +++ b/config/forms/schema/generic.json @@ -44,7 +44,7 @@ "pages": { "type": "object", "patternProperties": { - "[a-z_]+": { + "^(?!(conditional_route_to))[a-z_]+$": { "description": "Page Name", "type": "object", "required": ["header", "questions"], @@ -88,6 +88,10 @@ "check_answer_label": { "description": "", "type": "string" + }, + "conditional_for": { + "description": "", + "type": "object" } }, "minProperties": 1 diff --git a/spec/fixtures/forms/test_validator.json b/spec/fixtures/forms/test_validator.json index 487b990f4..630145f35 100644 --- a/spec/fixtures/forms/test_validator.json +++ b/spec/fixtures/forms/test_validator.json @@ -11,6 +11,7 @@ "ShouldThrowError": "Shouldn't be here but what you gonna do?", "pages": { "tenant_code": { + "ShouldThrowError": "Shouldn't be here but what you gonna do?", "questions": { "tenant_code": { "check_answer_label": "Tenant code", @@ -19,7 +20,8 @@ } }, "conditional_route_to": {"test": "Yes"} - } + }, + "conditional_route_to": {"test": "Yes"} }, "person_1_age": { "header": "", From 967ee6b0e1203f17d5e5c4ea685483b9be404fa8 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Thu, 11 Nov 2021 13:49:11 +0000 Subject: [PATCH 22/55] more fix --- app/helpers/json_schema_validation.rb | 4 ++-- spec/fixtures/forms/test_validator.json | 31 ++++++++++++++----------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/app/helpers/json_schema_validation.rb b/app/helpers/json_schema_validation.rb index 07ba995e6..d6eb46700 100644 --- a/app/helpers/json_schema_validation.rb +++ b/app/helpers/json_schema_validation.rb @@ -28,8 +28,8 @@ begin return end - # directories = ["config/forms", "spec/fixtures/forms"] - directories = ["config/forms"] + directories = ["config/forms", "spec/fixtures/forms"] + # directories = ["config/forms"] get_all_form_paths(directories).each do |path| puts path diff --git a/spec/fixtures/forms/test_validator.json b/spec/fixtures/forms/test_validator.json index 630145f35..2f8e770d3 100644 --- a/spec/fixtures/forms/test_validator.json +++ b/spec/fixtures/forms/test_validator.json @@ -11,30 +11,33 @@ "ShouldThrowError": "Shouldn't be here but what you gonna do?", "pages": { "tenant_code": { + "header": "", + "description": "", "ShouldThrowError": "Shouldn't be here but what you gonna do?", "questions": { "tenant_code": { "check_answer_label": "Tenant code", "header": "What is the tenant code?", + "description": "", "type": "text" } }, "conditional_route_to": {"test": "Yes"} }, - "conditional_route_to": {"test": "Yes"} - }, - "person_1_age": { - "header": "", - "description": "", - "questions": { - "person_1_age": { - "check_answer_label": "Tenant's age", - "header": "What is the tenant's age?", - "hint_text": "", - "type": "numeric", - "min": 0, - "max": 120, - "step": 1 + "conditional_route_to": {"test": "Yes"}, + "person_1_age": { + "header": "", + "description": "", + "questions": { + "person_1_age": { + "check_answer_label": "Tenant's age", + "header": "What is the tenant's age?", + "hint_text": "", + "type": "numeric", + "min": 0, + "max": 120, + "step": 1 + } } } } From 20bda98d4b8faff2337bc73a9ecdd72835174e2a Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Thu, 11 Nov 2021 14:44:55 +0000 Subject: [PATCH 23/55] Save mcr date as datetime, fix saving the dates (#85) --- app/admin/case_logs.rb | 2 +- app/controllers/case_logs_controller.rb | 6 +++++ app/models/case_log.rb | 20 +++++++++++++++++ config/forms/2021_2022.json | 4 ++-- db/migrate/20211110140928_add_mrc_dates.rb | 21 ++++++++++++++++++ db/schema.rb | 7 ++++-- docs/api/DLUHC-CORE-Data.v1.json | 6 ++--- spec/controllers/case_logs_controller_spec.rb | 22 +++++++++++++++++++ spec/fixtures/complete_case_log.json | 5 ++++- spec/fixtures/forms/test_form.json | 10 +++++++++ spec/models/form_handler_spec.rb | 2 +- 11 files changed, 95 insertions(+), 10 deletions(-) create mode 100644 db/migrate/20211110140928_add_mrc_dates.rb diff --git a/app/admin/case_logs.rb b/app/admin/case_logs.rb index 6768befae..f32cff52b 100644 --- a/app/admin/case_logs.rb +++ b/app/admin/case_logs.rb @@ -2,7 +2,7 @@ ActiveAdmin.register CaseLog do # See permitted parameters documentation: # https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters permit_params do - permitted = %i[status tenant_code age1 sex1 tenant_ethnic_group tenant_nationality previous_housing_situation armed_forces ecstat1 hhmemb relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 person_7_gender ecstat7 relat8 age8 sex8 ecstat8 homelessness reason benefit_cap_spare_room_subsidy armed_forces_active armed_forces_injured armed_forces_partner medical_conditions pregnancy accessibility_requirements condition_effects tenancy_code tenancy_start_date starter_tenancy fixed_term_tenancy tenancy_type letting_type letting_provider la previous_postcode property_relet property_vacancy_reason property_reference property_unit_type property_building_type property_number_of_bedrooms property_void_date majorrepairs property_major_repairs_date property_number_of_times_relet property_wheelchair_accessible net_income net_income_frequency net_income_uc_proportion hb rent_frequency basic_rent service_charge personal_service_charge support_charge total_charge tshortfall time_lived_in_la time_on_la_waiting_list prevloc property_postcode reasonable_preference reasonable_preference_reason cbl_letting chr_letting cap_letting hbrentshortfall other_reason accessibility_requirements_fully_wheelchair_accessible_housing accessibility_requirements_wheelchair_access_to_essential_rooms accessibility_requirements_level_access_housing accessibility_requirements_other_disability_requirements accessibility_requirements_no_disability_requirements accessibility_requirements_do_not_know accessibility_requirements_prefer_not_to_say condition_effects_vision condition_effects_hearing condition_effects_mobility condition_effects_dexterity condition_effects_stamina condition_effects_learning condition_effects_memory condition_effects_mental_health condition_effects_social_or_behavioral condition_effects_other condition_effects_prefer_not_to_say reasonable_preference_reason_homeless reasonable_preference_reason_unsatisfactory_housing reasonable_preference_reason_medical_grounds reasonable_preference_reason_avoid_hardship reasonable_preference_reason_do_not_know other_tenancy_type override_net_income_validation net_income_known] + permitted = %i[status tenant_code age1 sex1 tenant_ethnic_group tenant_nationality previous_housing_situation armed_forces ecstat1 hhmemb relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 person_7_gender ecstat7 relat8 age8 sex8 ecstat8 homelessness reason benefit_cap_spare_room_subsidy armed_forces_active armed_forces_injured armed_forces_partner medical_conditions pregnancy accessibility_requirements condition_effects tenancy_code tenancy_start_date starter_tenancy fixed_term_tenancy tenancy_type letting_type letting_provider la previous_postcode property_relet property_vacancy_reason property_reference property_unit_type property_building_type property_number_of_bedrooms property_void_date majorrepairs mrcdate property_number_of_times_relet property_wheelchair_accessible net_income net_income_frequency net_income_uc_proportion hb rent_frequency basic_rent service_charge personal_service_charge support_charge total_charge tshortfall time_lived_in_la time_on_la_waiting_list prevloc property_postcode reasonable_preference reasonable_preference_reason cbl_letting chr_letting cap_letting hbrentshortfall other_reason accessibility_requirements_fully_wheelchair_accessible_housing accessibility_requirements_wheelchair_access_to_essential_rooms accessibility_requirements_level_access_housing accessibility_requirements_other_disability_requirements accessibility_requirements_no_disability_requirements accessibility_requirements_do_not_know accessibility_requirements_prefer_not_to_say condition_effects_vision condition_effects_hearing condition_effects_mobility condition_effects_dexterity condition_effects_stamina condition_effects_learning condition_effects_memory condition_effects_mental_health condition_effects_social_or_behavioral condition_effects_other condition_effects_prefer_not_to_say reasonable_preference_reason_homeless reasonable_preference_reason_unsatisfactory_housing reasonable_preference_reason_medical_grounds reasonable_preference_reason_avoid_hardship reasonable_preference_reason_do_not_know other_tenancy_type override_net_income_validation net_income_known] permitted end diff --git a/app/controllers/case_logs_controller.rb b/app/controllers/case_logs_controller.rb index cc2a4b484..8eb60af6a 100644 --- a/app/controllers/case_logs_controller.rb +++ b/app/controllers/case_logs_controller.rb @@ -103,6 +103,12 @@ private form = FormHandler.instance.get_form("2021_2022") form.expected_responses_for_page(page).each_with_object({}) do |(question_key, question_info), result| question_params = params["case_log"][question_key] + if question_info["type"] == "date" + day = params["case_log"]["#{question_key}(3i)"] + month = params["case_log"]["#{question_key}(2i)"] + year = params["case_log"]["#{question_key}(1i)"] + result[question_key] = Date.new(year.to_i, month.to_i, day.to_i) + end next unless question_params if %w[checkbox validation_override].include?(question_info["type"]) diff --git a/app/models/case_log.rb b/app/models/case_log.rb index c058fb5f3..4d59ea91a 100644 --- a/app/models/case_log.rb +++ b/app/models/case_log.rb @@ -169,6 +169,26 @@ class CaseLog < ApplicationRecord IncomeRange::ALLOWED[ecstat1.to_sym] end + def mrcday + if mrcdate.present? + mrcdate.day + end + end + + def mrcmonth + if mrcdate.present? + mrcdate.month + end + end + + def mrcyear + if mrcdate.present? + mrcdate.year + end + end + + + private def update_status! diff --git a/config/forms/2021_2022.json b/config/forms/2021_2022.json index 52d80f8ee..5606f956e 100644 --- a/config/forms/2021_2022.json +++ b/config/forms/2021_2022.json @@ -1585,10 +1585,10 @@ "1": "No" }, "conditional_for": { - "property_major_repairs_date": ["Yes"] + "mrcdate": ["Yes"] } }, - "property_major_repairs_date": { + "mrcdate": { "check_answer_label": "What was the major repairs completion date?", "header": "What was the major repairs completion date?", "hint_text": "For example, 27 3 2007", diff --git a/db/migrate/20211110140928_add_mrc_dates.rb b/db/migrate/20211110140928_add_mrc_dates.rb new file mode 100644 index 000000000..08c1c70d3 --- /dev/null +++ b/db/migrate/20211110140928_add_mrc_dates.rb @@ -0,0 +1,21 @@ +class AddMrcDates < ActiveRecord::Migration[6.1] + def up + change_table :case_logs, bulk: true do |t| + t.remove :property_major_repairs_date + t.column :mrcdate, :datetime + t.column :mrcday, :integer + t.column :mrcmonth, :integer + t.column :mrcyear, :integer + end + end + + def down + change_table :case_logs, bulk: true do |t| + t.column :property_major_repairs_date, :string + t.remove :mrcdate + t.remove :mrcday + t.remove :mrcmonth + t.remove :mrcyear + end + end +end diff --git a/db/schema.rb b/db/schema.rb index a1b19f7f2..ba9b956dd 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_11_08_134601) do +ActiveRecord::Schema.define(version: 2021_11_10_140928) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -78,7 +78,6 @@ ActiveRecord::Schema.define(version: 2021_11_08_134601) do t.string "property_building_type" t.integer "beds" t.string "property_void_date" - t.string "property_major_repairs_date" t.integer "offered" t.integer "wchair" t.integer "earnings" @@ -149,6 +148,10 @@ ActiveRecord::Schema.define(version: 2021_11_08_134601) do t.string "ppostc1" t.string "ppostc2" t.integer "property_relet" + t.datetime "mrcdate" + t.integer "mrcday" + t.integer "mrcmonth" + t.integer "mrcyear" t.index ["discarded_at"], name: "index_case_logs_on_discarded_at" end diff --git a/docs/api/DLUHC-CORE-Data.v1.json b/docs/api/DLUHC-CORE-Data.v1.json index 860255260..e13ad4f17 100644 --- a/docs/api/DLUHC-CORE-Data.v1.json +++ b/docs/api/DLUHC-CORE-Data.v1.json @@ -319,7 +319,7 @@ "beds": 3, "property_void_date": "03/11/2019", "majorrepairs": "Yes", - "property_major_repairs_date": "05/05/2020", + "mrcdate": "05/05/2020", "offered": 2, "wchair": true, "earnings": 1000, @@ -875,7 +875,7 @@ "type": "string", "minLength": 1 }, - "property_major_repairs_date": { + "mrcdate": { "type": "string", "minLength": 1 }, @@ -1108,7 +1108,7 @@ "beds", "property_void_date", "majorrepairs", - "property_major_repairs_date", + "mrcdate", "offered", "wchair", "earnings", diff --git a/spec/controllers/case_logs_controller_spec.rb b/spec/controllers/case_logs_controller_spec.rb index 40d93cc59..007b76f8c 100644 --- a/spec/controllers/case_logs_controller_spec.rb +++ b/spec/controllers/case_logs_controller_spec.rb @@ -177,6 +177,28 @@ RSpec.describe CaseLogsController, type: :controller do expect(case_log.ppostc2).to eq("2AE") end end + + context "partition date" do + let(:case_log_with_date) do + { + :"mrcdate(1i)" => "2021", + :"mrcdate(2i)" => "05", + :"mrcdate(3i)" => "04", + :page => "major_repairs_date", + } + end + it "saves full and partial dates" do + post :submit_form, params: { id: id, case_log: case_log_with_date } + case_log.reload + + expect(case_log.mrcdate.day).to eq(4) + expect(case_log.mrcdate.month).to eq(5) + expect(case_log.mrcdate.year).to eq(2021) + expect(case_log.mrcday).to eq(4) + expect(case_log.mrcmonth).to eq(5) + expect(case_log.mrcyear).to eq(2021) + end + end end describe "get_next_page_path" do diff --git a/spec/fixtures/complete_case_log.json b/spec/fixtures/complete_case_log.json index 01fc5d998..97afaeaa0 100644 --- a/spec/fixtures/complete_case_log.json +++ b/spec/fixtures/complete_case_log.json @@ -64,7 +64,10 @@ "beds": 3, "property_void_date": "03/11/2019", "majorrepairs": "Yes", - "property_major_repairs_date": "05/05/2020", + "mrcdate": "05/05/2020", + "mrcday": 5, + "mrcmonth": 5, + "mrcyear": 2020, "offered": 2, "wchair": "Yes", "net_income_known": "Yes", diff --git a/spec/fixtures/forms/test_form.json b/spec/fixtures/forms/test_form.json index 15764300b..95ac050da 100644 --- a/spec/fixtures/forms/test_form.json +++ b/spec/fixtures/forms/test_form.json @@ -510,6 +510,16 @@ "type": "text" } } + }, + "major_repairs_date": { + "questions": { + "mrcdate": { + "check_answer_label": "What was the major repairs completion date?", + "header": "What was the major repairs completion date?", + "hint_text": "For example, 27 3 2007", + "type": "date" + } + } } } } diff --git a/spec/models/form_handler_spec.rb b/spec/models/form_handler_spec.rb index ff6d4dc0f..f998c5557 100644 --- a/spec/models/form_handler_spec.rb +++ b/spec/models/form_handler_spec.rb @@ -15,7 +15,7 @@ RSpec.describe FormHandler do form_handler = FormHandler.instance form = form_handler.get_form("test_form") expect(form).to be_a(Form) - expect(form.all_pages.count).to eq(22) + expect(form.all_pages.count).to eq(23) end end From ebdf41764b0bee1a5c9ef89fdceacf1d3958045b Mon Sep 17 00:00:00 2001 From: magicmilo Date: Thu, 11 Nov 2021 15:26:58 +0000 Subject: [PATCH 24/55] add check answer label requirement --- config/forms/schema/generic.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/config/forms/schema/generic.json b/config/forms/schema/generic.json index d9b0f8cc5..1499878f0 100644 --- a/config/forms/schema/generic.json +++ b/config/forms/schema/generic.json @@ -72,7 +72,12 @@ "type": { "description": "", "type": "string" - } + }, + "check_answer_label": { + "description": "", + "type": "string", + "optional": "true" + } }, "additionalProperties": { "hint_text": { From 894228c02e455d7b21ade57a6690c75c133352bb Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Thu, 11 Nov 2021 15:50:05 +0000 Subject: [PATCH 25/55] CLDC-678: Store total household members (#86) * Store other housdehold members and infer total household members * Remove redundant question --- app/admin/case_logs.rb | 2 +- app/models/case_log.rb | 8 +++++++- app/validations/household_validations.rb | 2 +- config/forms/2021_2022.json | 16 ++-------------- .../20211111143319_add_other_members_column.rb | 7 +++++++ db/schema.rb | 3 ++- docs/api/DLUHC-CORE-Data.v1.json | 6 +++--- spec/features/case_log_spec.rb | 4 ++-- spec/fixtures/complete_case_log.json | 3 ++- spec/fixtures/forms/test_form.json | 2 +- spec/helpers/check_answers_helper_spec.rb | 2 +- spec/models/case_log_spec.rb | 4 ++-- 12 files changed, 31 insertions(+), 28 deletions(-) create mode 100644 db/migrate/20211111143319_add_other_members_column.rb diff --git a/app/admin/case_logs.rb b/app/admin/case_logs.rb index f32cff52b..2a15fbb2a 100644 --- a/app/admin/case_logs.rb +++ b/app/admin/case_logs.rb @@ -2,7 +2,7 @@ ActiveAdmin.register CaseLog do # See permitted parameters documentation: # https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters permit_params do - permitted = %i[status tenant_code age1 sex1 tenant_ethnic_group tenant_nationality previous_housing_situation armed_forces ecstat1 hhmemb relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 person_7_gender ecstat7 relat8 age8 sex8 ecstat8 homelessness reason benefit_cap_spare_room_subsidy armed_forces_active armed_forces_injured armed_forces_partner medical_conditions pregnancy accessibility_requirements condition_effects tenancy_code tenancy_start_date starter_tenancy fixed_term_tenancy tenancy_type letting_type letting_provider la previous_postcode property_relet property_vacancy_reason property_reference property_unit_type property_building_type property_number_of_bedrooms property_void_date majorrepairs mrcdate property_number_of_times_relet property_wheelchair_accessible net_income net_income_frequency net_income_uc_proportion hb rent_frequency basic_rent service_charge personal_service_charge support_charge total_charge tshortfall time_lived_in_la time_on_la_waiting_list prevloc property_postcode reasonable_preference reasonable_preference_reason cbl_letting chr_letting cap_letting hbrentshortfall other_reason accessibility_requirements_fully_wheelchair_accessible_housing accessibility_requirements_wheelchair_access_to_essential_rooms accessibility_requirements_level_access_housing accessibility_requirements_other_disability_requirements accessibility_requirements_no_disability_requirements accessibility_requirements_do_not_know accessibility_requirements_prefer_not_to_say condition_effects_vision condition_effects_hearing condition_effects_mobility condition_effects_dexterity condition_effects_stamina condition_effects_learning condition_effects_memory condition_effects_mental_health condition_effects_social_or_behavioral condition_effects_other condition_effects_prefer_not_to_say reasonable_preference_reason_homeless reasonable_preference_reason_unsatisfactory_housing reasonable_preference_reason_medical_grounds reasonable_preference_reason_avoid_hardship reasonable_preference_reason_do_not_know other_tenancy_type override_net_income_validation net_income_known] + permitted = %i[status tenant_code age1 sex1 tenant_ethnic_group tenant_nationality previous_housing_situation armed_forces ecstat1 other_hhmemb relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 person_7_gender ecstat7 relat8 age8 sex8 ecstat8 homelessness reason benefit_cap_spare_room_subsidy armed_forces_active armed_forces_injured armed_forces_partner medical_conditions pregnancy accessibility_requirements condition_effects tenancy_code tenancy_start_date starter_tenancy fixed_term_tenancy tenancy_type letting_type letting_provider la previous_postcode property_relet property_vacancy_reason property_reference property_unit_type property_building_type property_number_of_bedrooms property_void_date majorrepairs mrcdate property_number_of_times_relet property_wheelchair_accessible net_income net_income_frequency net_income_uc_proportion hb rent_frequency basic_rent service_charge personal_service_charge support_charge total_charge tshortfall time_lived_in_la time_on_la_waiting_list prevloc property_postcode reasonable_preference reasonable_preference_reason cbl_letting chr_letting cap_letting hbrentshortfall other_reason accessibility_requirements_fully_wheelchair_accessible_housing accessibility_requirements_wheelchair_access_to_essential_rooms accessibility_requirements_level_access_housing accessibility_requirements_other_disability_requirements accessibility_requirements_no_disability_requirements accessibility_requirements_do_not_know accessibility_requirements_prefer_not_to_say condition_effects_vision condition_effects_hearing condition_effects_mobility condition_effects_dexterity condition_effects_stamina condition_effects_learning condition_effects_memory condition_effects_mental_health condition_effects_social_or_behavioral condition_effects_other condition_effects_prefer_not_to_say reasonable_preference_reason_homeless reasonable_preference_reason_unsatisfactory_housing reasonable_preference_reason_medical_grounds reasonable_preference_reason_avoid_hardship reasonable_preference_reason_do_not_know other_tenancy_type override_net_income_validation net_income_known] permitted end diff --git a/app/models/case_log.rb b/app/models/case_log.rb index 4d59ea91a..f21b3338d 100644 --- a/app/models/case_log.rb +++ b/app/models/case_log.rb @@ -163,6 +163,12 @@ class CaseLog < ApplicationRecord end end + def hhmemb + if other_hhmemb.present? + other_hhmemb + end + end + def applicable_income_range return unless ecstat1 @@ -239,7 +245,7 @@ private dynamically_not_required << "incfreq" end - start_range = (hhmemb || 0) + 2 + start_range = (other_hhmemb || 0) + 2 (start_range..8).each do |n| dynamically_not_required << "age#{n}" dynamically_not_required << "sex#{n}" diff --git a/app/validations/household_validations.rb b/app/validations/household_validations.rb index b36972667..d3536ae8a 100644 --- a/app/validations/household_validations.rb +++ b/app/validations/household_validations.rb @@ -80,7 +80,7 @@ module HouseholdValidations record.errors.add :unittype_gn, "A bedsit can only have one bedroom" end - if !record.hhmemb.nil? && record.hhmemb.positive? && (record.unittype_gn.include?("Shared") && !record.beds.to_i.between?(1, 7)) + if !record.other_hhmemb.nil? && record.other_hhmemb.positive? && (record.unittype_gn.include?("Shared") && !record.beds.to_i.between?(1, 7)) record.errors.add :unittype_gn, "A shared house must have 1 to 7 bedrooms" end diff --git a/config/forms/2021_2022.json b/config/forms/2021_2022.json index 5606f956e..5d06b8bd3 100644 --- a/config/forms/2021_2022.json +++ b/config/forms/2021_2022.json @@ -104,7 +104,7 @@ "header": "About this log", "description": "", "questions": { - "tenancy_start_date": { + "startdate": { "check_answer_label": "When is the tenancy start date?", "header": "What is the tenancy start date?", "hint_text": "For example, 27 3 2007", @@ -332,7 +332,7 @@ "header": "", "description": "", "questions": { - "hhmemb": { + "other_hhmemb": { "check_answer_label": "Number of Other Household Members", "header": "How many other people are there in the household?", "hint_text": "The maximum number of others is 7", @@ -1027,18 +1027,6 @@ } } }, - "tenancy_start_date": { - "header": "", - "description": "", - "questions": { - "startdate": { - "check_answer_label": "When is the tenancy start date?", - "header": "What is the tenancy start date?", - "hint_text": "For example, 27 3 2007", - "type": "date" - } - } - }, "starter_tenancy": { "header": "", "description": "", diff --git a/db/migrate/20211111143319_add_other_members_column.rb b/db/migrate/20211111143319_add_other_members_column.rb new file mode 100644 index 000000000..2c6ca2658 --- /dev/null +++ b/db/migrate/20211111143319_add_other_members_column.rb @@ -0,0 +1,7 @@ +class AddOtherMembersColumn < ActiveRecord::Migration[6.1] + def change + change_table :case_logs, bulk: true do |t| + t.column :other_hhmemb, :integer + end + end +end diff --git a/db/schema.rb b/db/schema.rb index ba9b956dd..5b1c02e62 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_11_10_140928) do +ActiveRecord::Schema.define(version: 2021_11_11_143319) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -152,6 +152,7 @@ ActiveRecord::Schema.define(version: 2021_11_10_140928) do t.integer "mrcday" t.integer "mrcmonth" t.integer "mrcyear" + t.integer "other_hhmemb" t.index ["discarded_at"], name: "index_case_logs_on_discarded_at" end diff --git a/docs/api/DLUHC-CORE-Data.v1.json b/docs/api/DLUHC-CORE-Data.v1.json index e13ad4f17..17560d14c 100644 --- a/docs/api/DLUHC-CORE-Data.v1.json +++ b/docs/api/DLUHC-CORE-Data.v1.json @@ -263,7 +263,7 @@ "prevten": "Private sector tenancy", "armed_forces": "Yes - a regular", "ecstat1": "Full-time - 30 hours or more", - "hhmemb": 7, + "other_hhmemb": 7, "relat2": "Partner", "age2": 32, "sex2": "Male", @@ -459,7 +459,7 @@ "Prefer not to say" ] }, - "hhmemb": { + "other_hhmemb": { "type": "number", "minimum": 0, "maximum": 7 @@ -1052,7 +1052,7 @@ "prevten", "armed_forces", "ecstat1", - "hhmemb", + "other_hhmemb", "relat2", "age2", "sex2", diff --git a/spec/features/case_log_spec.rb b/spec/features/case_log_spec.rb index aa53b8c7d..b48572d62 100644 --- a/spec/features/case_log_spec.rb +++ b/spec/features/case_log_spec.rb @@ -9,7 +9,7 @@ RSpec.describe "Test Features" do tenant_code: { type: "text", answer: "BZ737", path: "tenant_code" }, age1: { type: "numeric", answer: 25, path: "person_1_age" }, sex1: { type: "radio", answer: "Female", path: "person_1_gender" }, - hhmemb: { type: "numeric", answer: 2, path: "household_number_of_other_members" }, + other_hhmemb: { type: "numeric", answer: 2, path: "household_number_of_other_members" }, } def fill_in_number_question(case_log_id, question, value, path) @@ -265,7 +265,7 @@ RSpec.describe "Test Features" do let(:last_question_for_subsection) { "household_number_of_other_members" } it "redirects to the check answers page when answering the last question and clicking save and continue" do - fill_in_number_question(id, "hhmemb", 0, last_question_for_subsection) + fill_in_number_question(id, "other_hhmemb", 0, last_question_for_subsection) expect(page).to have_current_path("/case_logs/#{id}/#{subsection}/check_answers") end diff --git a/spec/fixtures/complete_case_log.json b/spec/fixtures/complete_case_log.json index 97afaeaa0..4656a04f8 100644 --- a/spec/fixtures/complete_case_log.json +++ b/spec/fixtures/complete_case_log.json @@ -8,7 +8,8 @@ "prevten": "Private sector tenancy", "armed_forces": "Yes - a regular", "ecstat1": "Full-time - 30 hours or more", - "hhmemb": 7, + "other_hhmemb": 7, + "hhmemb": 8, "relat2": "Partner", "age2": 32, "sex2": "Male", diff --git a/spec/fixtures/forms/test_form.json b/spec/fixtures/forms/test_form.json index 95ac050da..988d2176e 100644 --- a/spec/fixtures/forms/test_form.json +++ b/spec/fixtures/forms/test_form.json @@ -45,7 +45,7 @@ }, "household_number_of_other_members": { "questions": { - "hhmemb": { + "other_hhmemb": { "check_answer_label": "Number of Other Household Members", "header": "How many other people are there in the household?", "hint_text": "The maximum number of others is 1", diff --git a/spec/helpers/check_answers_helper_spec.rb b/spec/helpers/check_answers_helper_spec.rb index 7ad04f081..ac3000f6b 100644 --- a/spec/helpers/check_answers_helper_spec.rb +++ b/spec/helpers/check_answers_helper_spec.rb @@ -6,7 +6,7 @@ RSpec.describe CheckAnswersHelper do FactoryBot.create( :case_log, :in_progress, - hhmemb: 1, + other_hhmemb: 1, relat2: "Partner", ) end diff --git a/spec/models/case_log_spec.rb b/spec/models/case_log_spec.rb index 438bf3c55..e663937db 100644 --- a/spec/models/case_log_spec.rb +++ b/spec/models/case_log_spec.rb @@ -109,7 +109,7 @@ RSpec.describe Form, type: :model do expect { CaseLog.create!(unittype_gn: "Shared bungalow", beds: 8, - hhmemb: 1) + other_hhmemb: 1) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -117,7 +117,7 @@ RSpec.describe Form, type: :model do expect { CaseLog.create!(unittype_gn: "Shared bungalow", beds: 4, - hhmemb: 0) + other_hhmemb: 0) }.to raise_error(ActiveRecord::RecordInvalid) end From 3f885b4bc3101519784e0b0777a0c78207db8e54 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Thu, 11 Nov 2021 15:57:19 +0000 Subject: [PATCH 26/55] fix duplicate keys in form json letting_type --- config/forms/2021_2022.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/forms/2021_2022.json b/config/forms/2021_2022.json index 5606f956e..f28753d14 100644 --- a/config/forms/2021_2022.json +++ b/config/forms/2021_2022.json @@ -112,7 +112,7 @@ } } }, - "letting_type": { + "rent_type": { "header": "About this log", "description": "", "questions": { From 8a6207fb0091f641da2c35cc1531b4b664cc14ba Mon Sep 17 00:00:00 2001 From: magicmilo Date: Thu, 11 Nov 2021 16:49:46 +0000 Subject: [PATCH 27/55] Revert "fix duplicate keys in form json letting_type" This reverts commit 3f885b4bc3101519784e0b0777a0c78207db8e54. --- config/forms/2021_2022.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/forms/2021_2022.json b/config/forms/2021_2022.json index 859e5fa14..5d06b8bd3 100644 --- a/config/forms/2021_2022.json +++ b/config/forms/2021_2022.json @@ -112,7 +112,7 @@ } } }, - "rent_type": { + "letting_type": { "header": "About this log", "description": "", "questions": { From a714efeaf6b7b3646213ecdd51a49dc82124870f Mon Sep 17 00:00:00 2001 From: magicmilo Date: Thu, 11 Nov 2021 16:52:40 +0000 Subject: [PATCH 28/55] aggh reverted wrong commit --- config/forms/2021_2022.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/forms/2021_2022.json b/config/forms/2021_2022.json index 5d06b8bd3..859e5fa14 100644 --- a/config/forms/2021_2022.json +++ b/config/forms/2021_2022.json @@ -112,7 +112,7 @@ } } }, - "letting_type": { + "rent_type": { "header": "About this log", "description": "", "questions": { From 6d2a0a11b697d6c49b420c8fd1a5b7eac0a4c6c1 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Thu, 11 Nov 2021 19:44:57 +0000 Subject: [PATCH 29/55] Revert "Merge branch 'main' of https://github.com/communitiesuk/mhclg-data-collection-beta" This reverts commit d1ae40dc3bd4a03c6805e7c2462b1d6c706dfed6, reversing changes made to 3f885b4bc3101519784e0b0777a0c78207db8e54. --- app/admin/case_logs.rb | 2 +- app/models/case_log.rb | 8 +------- app/validations/household_validations.rb | 2 +- config/forms/2021_2022.json | 16 ++++++++++++++-- .../20211111143319_add_other_members_column.rb | 7 ------- db/schema.rb | 3 +-- docs/api/DLUHC-CORE-Data.v1.json | 6 +++--- spec/features/case_log_spec.rb | 4 ++-- spec/fixtures/complete_case_log.json | 3 +-- spec/fixtures/forms/test_form.json | 2 +- spec/helpers/check_answers_helper_spec.rb | 2 +- spec/models/case_log_spec.rb | 4 ++-- 12 files changed, 28 insertions(+), 31 deletions(-) delete mode 100644 db/migrate/20211111143319_add_other_members_column.rb diff --git a/app/admin/case_logs.rb b/app/admin/case_logs.rb index 2a15fbb2a..f32cff52b 100644 --- a/app/admin/case_logs.rb +++ b/app/admin/case_logs.rb @@ -2,7 +2,7 @@ ActiveAdmin.register CaseLog do # See permitted parameters documentation: # https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters permit_params do - permitted = %i[status tenant_code age1 sex1 tenant_ethnic_group tenant_nationality previous_housing_situation armed_forces ecstat1 other_hhmemb relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 person_7_gender ecstat7 relat8 age8 sex8 ecstat8 homelessness reason benefit_cap_spare_room_subsidy armed_forces_active armed_forces_injured armed_forces_partner medical_conditions pregnancy accessibility_requirements condition_effects tenancy_code tenancy_start_date starter_tenancy fixed_term_tenancy tenancy_type letting_type letting_provider la previous_postcode property_relet property_vacancy_reason property_reference property_unit_type property_building_type property_number_of_bedrooms property_void_date majorrepairs mrcdate property_number_of_times_relet property_wheelchair_accessible net_income net_income_frequency net_income_uc_proportion hb rent_frequency basic_rent service_charge personal_service_charge support_charge total_charge tshortfall time_lived_in_la time_on_la_waiting_list prevloc property_postcode reasonable_preference reasonable_preference_reason cbl_letting chr_letting cap_letting hbrentshortfall other_reason accessibility_requirements_fully_wheelchair_accessible_housing accessibility_requirements_wheelchair_access_to_essential_rooms accessibility_requirements_level_access_housing accessibility_requirements_other_disability_requirements accessibility_requirements_no_disability_requirements accessibility_requirements_do_not_know accessibility_requirements_prefer_not_to_say condition_effects_vision condition_effects_hearing condition_effects_mobility condition_effects_dexterity condition_effects_stamina condition_effects_learning condition_effects_memory condition_effects_mental_health condition_effects_social_or_behavioral condition_effects_other condition_effects_prefer_not_to_say reasonable_preference_reason_homeless reasonable_preference_reason_unsatisfactory_housing reasonable_preference_reason_medical_grounds reasonable_preference_reason_avoid_hardship reasonable_preference_reason_do_not_know other_tenancy_type override_net_income_validation net_income_known] + permitted = %i[status tenant_code age1 sex1 tenant_ethnic_group tenant_nationality previous_housing_situation armed_forces ecstat1 hhmemb relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 person_7_gender ecstat7 relat8 age8 sex8 ecstat8 homelessness reason benefit_cap_spare_room_subsidy armed_forces_active armed_forces_injured armed_forces_partner medical_conditions pregnancy accessibility_requirements condition_effects tenancy_code tenancy_start_date starter_tenancy fixed_term_tenancy tenancy_type letting_type letting_provider la previous_postcode property_relet property_vacancy_reason property_reference property_unit_type property_building_type property_number_of_bedrooms property_void_date majorrepairs mrcdate property_number_of_times_relet property_wheelchair_accessible net_income net_income_frequency net_income_uc_proportion hb rent_frequency basic_rent service_charge personal_service_charge support_charge total_charge tshortfall time_lived_in_la time_on_la_waiting_list prevloc property_postcode reasonable_preference reasonable_preference_reason cbl_letting chr_letting cap_letting hbrentshortfall other_reason accessibility_requirements_fully_wheelchair_accessible_housing accessibility_requirements_wheelchair_access_to_essential_rooms accessibility_requirements_level_access_housing accessibility_requirements_other_disability_requirements accessibility_requirements_no_disability_requirements accessibility_requirements_do_not_know accessibility_requirements_prefer_not_to_say condition_effects_vision condition_effects_hearing condition_effects_mobility condition_effects_dexterity condition_effects_stamina condition_effects_learning condition_effects_memory condition_effects_mental_health condition_effects_social_or_behavioral condition_effects_other condition_effects_prefer_not_to_say reasonable_preference_reason_homeless reasonable_preference_reason_unsatisfactory_housing reasonable_preference_reason_medical_grounds reasonable_preference_reason_avoid_hardship reasonable_preference_reason_do_not_know other_tenancy_type override_net_income_validation net_income_known] permitted end diff --git a/app/models/case_log.rb b/app/models/case_log.rb index f21b3338d..4d59ea91a 100644 --- a/app/models/case_log.rb +++ b/app/models/case_log.rb @@ -163,12 +163,6 @@ class CaseLog < ApplicationRecord end end - def hhmemb - if other_hhmemb.present? - other_hhmemb - end - end - def applicable_income_range return unless ecstat1 @@ -245,7 +239,7 @@ private dynamically_not_required << "incfreq" end - start_range = (other_hhmemb || 0) + 2 + start_range = (hhmemb || 0) + 2 (start_range..8).each do |n| dynamically_not_required << "age#{n}" dynamically_not_required << "sex#{n}" diff --git a/app/validations/household_validations.rb b/app/validations/household_validations.rb index d3536ae8a..b36972667 100644 --- a/app/validations/household_validations.rb +++ b/app/validations/household_validations.rb @@ -80,7 +80,7 @@ module HouseholdValidations record.errors.add :unittype_gn, "A bedsit can only have one bedroom" end - if !record.other_hhmemb.nil? && record.other_hhmemb.positive? && (record.unittype_gn.include?("Shared") && !record.beds.to_i.between?(1, 7)) + if !record.hhmemb.nil? && record.hhmemb.positive? && (record.unittype_gn.include?("Shared") && !record.beds.to_i.between?(1, 7)) record.errors.add :unittype_gn, "A shared house must have 1 to 7 bedrooms" end diff --git a/config/forms/2021_2022.json b/config/forms/2021_2022.json index 859e5fa14..f28753d14 100644 --- a/config/forms/2021_2022.json +++ b/config/forms/2021_2022.json @@ -104,7 +104,7 @@ "header": "About this log", "description": "", "questions": { - "startdate": { + "tenancy_start_date": { "check_answer_label": "When is the tenancy start date?", "header": "What is the tenancy start date?", "hint_text": "For example, 27 3 2007", @@ -332,7 +332,7 @@ "header": "", "description": "", "questions": { - "other_hhmemb": { + "hhmemb": { "check_answer_label": "Number of Other Household Members", "header": "How many other people are there in the household?", "hint_text": "The maximum number of others is 7", @@ -1027,6 +1027,18 @@ } } }, + "tenancy_start_date": { + "header": "", + "description": "", + "questions": { + "startdate": { + "check_answer_label": "When is the tenancy start date?", + "header": "What is the tenancy start date?", + "hint_text": "For example, 27 3 2007", + "type": "date" + } + } + }, "starter_tenancy": { "header": "", "description": "", diff --git a/db/migrate/20211111143319_add_other_members_column.rb b/db/migrate/20211111143319_add_other_members_column.rb deleted file mode 100644 index 2c6ca2658..000000000 --- a/db/migrate/20211111143319_add_other_members_column.rb +++ /dev/null @@ -1,7 +0,0 @@ -class AddOtherMembersColumn < ActiveRecord::Migration[6.1] - def change - change_table :case_logs, bulk: true do |t| - t.column :other_hhmemb, :integer - end - end -end diff --git a/db/schema.rb b/db/schema.rb index 5b1c02e62..ba9b956dd 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_11_11_143319) do +ActiveRecord::Schema.define(version: 2021_11_10_140928) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -152,7 +152,6 @@ ActiveRecord::Schema.define(version: 2021_11_11_143319) do t.integer "mrcday" t.integer "mrcmonth" t.integer "mrcyear" - t.integer "other_hhmemb" t.index ["discarded_at"], name: "index_case_logs_on_discarded_at" end diff --git a/docs/api/DLUHC-CORE-Data.v1.json b/docs/api/DLUHC-CORE-Data.v1.json index 17560d14c..e13ad4f17 100644 --- a/docs/api/DLUHC-CORE-Data.v1.json +++ b/docs/api/DLUHC-CORE-Data.v1.json @@ -263,7 +263,7 @@ "prevten": "Private sector tenancy", "armed_forces": "Yes - a regular", "ecstat1": "Full-time - 30 hours or more", - "other_hhmemb": 7, + "hhmemb": 7, "relat2": "Partner", "age2": 32, "sex2": "Male", @@ -459,7 +459,7 @@ "Prefer not to say" ] }, - "other_hhmemb": { + "hhmemb": { "type": "number", "minimum": 0, "maximum": 7 @@ -1052,7 +1052,7 @@ "prevten", "armed_forces", "ecstat1", - "other_hhmemb", + "hhmemb", "relat2", "age2", "sex2", diff --git a/spec/features/case_log_spec.rb b/spec/features/case_log_spec.rb index b48572d62..aa53b8c7d 100644 --- a/spec/features/case_log_spec.rb +++ b/spec/features/case_log_spec.rb @@ -9,7 +9,7 @@ RSpec.describe "Test Features" do tenant_code: { type: "text", answer: "BZ737", path: "tenant_code" }, age1: { type: "numeric", answer: 25, path: "person_1_age" }, sex1: { type: "radio", answer: "Female", path: "person_1_gender" }, - other_hhmemb: { type: "numeric", answer: 2, path: "household_number_of_other_members" }, + hhmemb: { type: "numeric", answer: 2, path: "household_number_of_other_members" }, } def fill_in_number_question(case_log_id, question, value, path) @@ -265,7 +265,7 @@ RSpec.describe "Test Features" do let(:last_question_for_subsection) { "household_number_of_other_members" } it "redirects to the check answers page when answering the last question and clicking save and continue" do - fill_in_number_question(id, "other_hhmemb", 0, last_question_for_subsection) + fill_in_number_question(id, "hhmemb", 0, last_question_for_subsection) expect(page).to have_current_path("/case_logs/#{id}/#{subsection}/check_answers") end diff --git a/spec/fixtures/complete_case_log.json b/spec/fixtures/complete_case_log.json index 4656a04f8..97afaeaa0 100644 --- a/spec/fixtures/complete_case_log.json +++ b/spec/fixtures/complete_case_log.json @@ -8,8 +8,7 @@ "prevten": "Private sector tenancy", "armed_forces": "Yes - a regular", "ecstat1": "Full-time - 30 hours or more", - "other_hhmemb": 7, - "hhmemb": 8, + "hhmemb": 7, "relat2": "Partner", "age2": 32, "sex2": "Male", diff --git a/spec/fixtures/forms/test_form.json b/spec/fixtures/forms/test_form.json index 988d2176e..95ac050da 100644 --- a/spec/fixtures/forms/test_form.json +++ b/spec/fixtures/forms/test_form.json @@ -45,7 +45,7 @@ }, "household_number_of_other_members": { "questions": { - "other_hhmemb": { + "hhmemb": { "check_answer_label": "Number of Other Household Members", "header": "How many other people are there in the household?", "hint_text": "The maximum number of others is 1", diff --git a/spec/helpers/check_answers_helper_spec.rb b/spec/helpers/check_answers_helper_spec.rb index ac3000f6b..7ad04f081 100644 --- a/spec/helpers/check_answers_helper_spec.rb +++ b/spec/helpers/check_answers_helper_spec.rb @@ -6,7 +6,7 @@ RSpec.describe CheckAnswersHelper do FactoryBot.create( :case_log, :in_progress, - other_hhmemb: 1, + hhmemb: 1, relat2: "Partner", ) end diff --git a/spec/models/case_log_spec.rb b/spec/models/case_log_spec.rb index e663937db..438bf3c55 100644 --- a/spec/models/case_log_spec.rb +++ b/spec/models/case_log_spec.rb @@ -109,7 +109,7 @@ RSpec.describe Form, type: :model do expect { CaseLog.create!(unittype_gn: "Shared bungalow", beds: 8, - other_hhmemb: 1) + hhmemb: 1) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -117,7 +117,7 @@ RSpec.describe Form, type: :model do expect { CaseLog.create!(unittype_gn: "Shared bungalow", beds: 4, - other_hhmemb: 0) + hhmemb: 0) }.to raise_error(ActiveRecord::RecordInvalid) end From ea992e8cf36d6617a550552c708c594e8bcb070f Mon Sep 17 00:00:00 2001 From: magicmilo Date: Fri, 12 Nov 2021 10:26:58 +0000 Subject: [PATCH 30/55] Revert "Revert "Merge branch 'main' of https://github.com/communitiesuk/mhclg-data-collection-beta"" This reverts commit 6d2a0a11b697d6c49b420c8fd1a5b7eac0a4c6c1. --- app/admin/case_logs.rb | 2 +- app/models/case_log.rb | 8 +++++++- app/validations/household_validations.rb | 2 +- config/forms/2021_2022.json | 16 ++-------------- .../20211111143319_add_other_members_column.rb | 7 +++++++ db/schema.rb | 3 ++- docs/api/DLUHC-CORE-Data.v1.json | 6 +++--- spec/features/case_log_spec.rb | 4 ++-- spec/fixtures/complete_case_log.json | 3 ++- spec/fixtures/forms/test_form.json | 2 +- spec/helpers/check_answers_helper_spec.rb | 2 +- spec/models/case_log_spec.rb | 4 ++-- 12 files changed, 31 insertions(+), 28 deletions(-) create mode 100644 db/migrate/20211111143319_add_other_members_column.rb diff --git a/app/admin/case_logs.rb b/app/admin/case_logs.rb index f32cff52b..2a15fbb2a 100644 --- a/app/admin/case_logs.rb +++ b/app/admin/case_logs.rb @@ -2,7 +2,7 @@ ActiveAdmin.register CaseLog do # See permitted parameters documentation: # https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters permit_params do - permitted = %i[status tenant_code age1 sex1 tenant_ethnic_group tenant_nationality previous_housing_situation armed_forces ecstat1 hhmemb relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 person_7_gender ecstat7 relat8 age8 sex8 ecstat8 homelessness reason benefit_cap_spare_room_subsidy armed_forces_active armed_forces_injured armed_forces_partner medical_conditions pregnancy accessibility_requirements condition_effects tenancy_code tenancy_start_date starter_tenancy fixed_term_tenancy tenancy_type letting_type letting_provider la previous_postcode property_relet property_vacancy_reason property_reference property_unit_type property_building_type property_number_of_bedrooms property_void_date majorrepairs mrcdate property_number_of_times_relet property_wheelchair_accessible net_income net_income_frequency net_income_uc_proportion hb rent_frequency basic_rent service_charge personal_service_charge support_charge total_charge tshortfall time_lived_in_la time_on_la_waiting_list prevloc property_postcode reasonable_preference reasonable_preference_reason cbl_letting chr_letting cap_letting hbrentshortfall other_reason accessibility_requirements_fully_wheelchair_accessible_housing accessibility_requirements_wheelchair_access_to_essential_rooms accessibility_requirements_level_access_housing accessibility_requirements_other_disability_requirements accessibility_requirements_no_disability_requirements accessibility_requirements_do_not_know accessibility_requirements_prefer_not_to_say condition_effects_vision condition_effects_hearing condition_effects_mobility condition_effects_dexterity condition_effects_stamina condition_effects_learning condition_effects_memory condition_effects_mental_health condition_effects_social_or_behavioral condition_effects_other condition_effects_prefer_not_to_say reasonable_preference_reason_homeless reasonable_preference_reason_unsatisfactory_housing reasonable_preference_reason_medical_grounds reasonable_preference_reason_avoid_hardship reasonable_preference_reason_do_not_know other_tenancy_type override_net_income_validation net_income_known] + permitted = %i[status tenant_code age1 sex1 tenant_ethnic_group tenant_nationality previous_housing_situation armed_forces ecstat1 other_hhmemb relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 person_7_gender ecstat7 relat8 age8 sex8 ecstat8 homelessness reason benefit_cap_spare_room_subsidy armed_forces_active armed_forces_injured armed_forces_partner medical_conditions pregnancy accessibility_requirements condition_effects tenancy_code tenancy_start_date starter_tenancy fixed_term_tenancy tenancy_type letting_type letting_provider la previous_postcode property_relet property_vacancy_reason property_reference property_unit_type property_building_type property_number_of_bedrooms property_void_date majorrepairs mrcdate property_number_of_times_relet property_wheelchair_accessible net_income net_income_frequency net_income_uc_proportion hb rent_frequency basic_rent service_charge personal_service_charge support_charge total_charge tshortfall time_lived_in_la time_on_la_waiting_list prevloc property_postcode reasonable_preference reasonable_preference_reason cbl_letting chr_letting cap_letting hbrentshortfall other_reason accessibility_requirements_fully_wheelchair_accessible_housing accessibility_requirements_wheelchair_access_to_essential_rooms accessibility_requirements_level_access_housing accessibility_requirements_other_disability_requirements accessibility_requirements_no_disability_requirements accessibility_requirements_do_not_know accessibility_requirements_prefer_not_to_say condition_effects_vision condition_effects_hearing condition_effects_mobility condition_effects_dexterity condition_effects_stamina condition_effects_learning condition_effects_memory condition_effects_mental_health condition_effects_social_or_behavioral condition_effects_other condition_effects_prefer_not_to_say reasonable_preference_reason_homeless reasonable_preference_reason_unsatisfactory_housing reasonable_preference_reason_medical_grounds reasonable_preference_reason_avoid_hardship reasonable_preference_reason_do_not_know other_tenancy_type override_net_income_validation net_income_known] permitted end diff --git a/app/models/case_log.rb b/app/models/case_log.rb index 4d59ea91a..f21b3338d 100644 --- a/app/models/case_log.rb +++ b/app/models/case_log.rb @@ -163,6 +163,12 @@ class CaseLog < ApplicationRecord end end + def hhmemb + if other_hhmemb.present? + other_hhmemb + end + end + def applicable_income_range return unless ecstat1 @@ -239,7 +245,7 @@ private dynamically_not_required << "incfreq" end - start_range = (hhmemb || 0) + 2 + start_range = (other_hhmemb || 0) + 2 (start_range..8).each do |n| dynamically_not_required << "age#{n}" dynamically_not_required << "sex#{n}" diff --git a/app/validations/household_validations.rb b/app/validations/household_validations.rb index b36972667..d3536ae8a 100644 --- a/app/validations/household_validations.rb +++ b/app/validations/household_validations.rb @@ -80,7 +80,7 @@ module HouseholdValidations record.errors.add :unittype_gn, "A bedsit can only have one bedroom" end - if !record.hhmemb.nil? && record.hhmemb.positive? && (record.unittype_gn.include?("Shared") && !record.beds.to_i.between?(1, 7)) + if !record.other_hhmemb.nil? && record.other_hhmemb.positive? && (record.unittype_gn.include?("Shared") && !record.beds.to_i.between?(1, 7)) record.errors.add :unittype_gn, "A shared house must have 1 to 7 bedrooms" end diff --git a/config/forms/2021_2022.json b/config/forms/2021_2022.json index f28753d14..859e5fa14 100644 --- a/config/forms/2021_2022.json +++ b/config/forms/2021_2022.json @@ -104,7 +104,7 @@ "header": "About this log", "description": "", "questions": { - "tenancy_start_date": { + "startdate": { "check_answer_label": "When is the tenancy start date?", "header": "What is the tenancy start date?", "hint_text": "For example, 27 3 2007", @@ -332,7 +332,7 @@ "header": "", "description": "", "questions": { - "hhmemb": { + "other_hhmemb": { "check_answer_label": "Number of Other Household Members", "header": "How many other people are there in the household?", "hint_text": "The maximum number of others is 7", @@ -1027,18 +1027,6 @@ } } }, - "tenancy_start_date": { - "header": "", - "description": "", - "questions": { - "startdate": { - "check_answer_label": "When is the tenancy start date?", - "header": "What is the tenancy start date?", - "hint_text": "For example, 27 3 2007", - "type": "date" - } - } - }, "starter_tenancy": { "header": "", "description": "", diff --git a/db/migrate/20211111143319_add_other_members_column.rb b/db/migrate/20211111143319_add_other_members_column.rb new file mode 100644 index 000000000..2c6ca2658 --- /dev/null +++ b/db/migrate/20211111143319_add_other_members_column.rb @@ -0,0 +1,7 @@ +class AddOtherMembersColumn < ActiveRecord::Migration[6.1] + def change + change_table :case_logs, bulk: true do |t| + t.column :other_hhmemb, :integer + end + end +end diff --git a/db/schema.rb b/db/schema.rb index ba9b956dd..5b1c02e62 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_11_10_140928) do +ActiveRecord::Schema.define(version: 2021_11_11_143319) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -152,6 +152,7 @@ ActiveRecord::Schema.define(version: 2021_11_10_140928) do t.integer "mrcday" t.integer "mrcmonth" t.integer "mrcyear" + t.integer "other_hhmemb" t.index ["discarded_at"], name: "index_case_logs_on_discarded_at" end diff --git a/docs/api/DLUHC-CORE-Data.v1.json b/docs/api/DLUHC-CORE-Data.v1.json index e13ad4f17..17560d14c 100644 --- a/docs/api/DLUHC-CORE-Data.v1.json +++ b/docs/api/DLUHC-CORE-Data.v1.json @@ -263,7 +263,7 @@ "prevten": "Private sector tenancy", "armed_forces": "Yes - a regular", "ecstat1": "Full-time - 30 hours or more", - "hhmemb": 7, + "other_hhmemb": 7, "relat2": "Partner", "age2": 32, "sex2": "Male", @@ -459,7 +459,7 @@ "Prefer not to say" ] }, - "hhmemb": { + "other_hhmemb": { "type": "number", "minimum": 0, "maximum": 7 @@ -1052,7 +1052,7 @@ "prevten", "armed_forces", "ecstat1", - "hhmemb", + "other_hhmemb", "relat2", "age2", "sex2", diff --git a/spec/features/case_log_spec.rb b/spec/features/case_log_spec.rb index aa53b8c7d..b48572d62 100644 --- a/spec/features/case_log_spec.rb +++ b/spec/features/case_log_spec.rb @@ -9,7 +9,7 @@ RSpec.describe "Test Features" do tenant_code: { type: "text", answer: "BZ737", path: "tenant_code" }, age1: { type: "numeric", answer: 25, path: "person_1_age" }, sex1: { type: "radio", answer: "Female", path: "person_1_gender" }, - hhmemb: { type: "numeric", answer: 2, path: "household_number_of_other_members" }, + other_hhmemb: { type: "numeric", answer: 2, path: "household_number_of_other_members" }, } def fill_in_number_question(case_log_id, question, value, path) @@ -265,7 +265,7 @@ RSpec.describe "Test Features" do let(:last_question_for_subsection) { "household_number_of_other_members" } it "redirects to the check answers page when answering the last question and clicking save and continue" do - fill_in_number_question(id, "hhmemb", 0, last_question_for_subsection) + fill_in_number_question(id, "other_hhmemb", 0, last_question_for_subsection) expect(page).to have_current_path("/case_logs/#{id}/#{subsection}/check_answers") end diff --git a/spec/fixtures/complete_case_log.json b/spec/fixtures/complete_case_log.json index 97afaeaa0..4656a04f8 100644 --- a/spec/fixtures/complete_case_log.json +++ b/spec/fixtures/complete_case_log.json @@ -8,7 +8,8 @@ "prevten": "Private sector tenancy", "armed_forces": "Yes - a regular", "ecstat1": "Full-time - 30 hours or more", - "hhmemb": 7, + "other_hhmemb": 7, + "hhmemb": 8, "relat2": "Partner", "age2": 32, "sex2": "Male", diff --git a/spec/fixtures/forms/test_form.json b/spec/fixtures/forms/test_form.json index 95ac050da..988d2176e 100644 --- a/spec/fixtures/forms/test_form.json +++ b/spec/fixtures/forms/test_form.json @@ -45,7 +45,7 @@ }, "household_number_of_other_members": { "questions": { - "hhmemb": { + "other_hhmemb": { "check_answer_label": "Number of Other Household Members", "header": "How many other people are there in the household?", "hint_text": "The maximum number of others is 1", diff --git a/spec/helpers/check_answers_helper_spec.rb b/spec/helpers/check_answers_helper_spec.rb index 7ad04f081..ac3000f6b 100644 --- a/spec/helpers/check_answers_helper_spec.rb +++ b/spec/helpers/check_answers_helper_spec.rb @@ -6,7 +6,7 @@ RSpec.describe CheckAnswersHelper do FactoryBot.create( :case_log, :in_progress, - hhmemb: 1, + other_hhmemb: 1, relat2: "Partner", ) end diff --git a/spec/models/case_log_spec.rb b/spec/models/case_log_spec.rb index 438bf3c55..e663937db 100644 --- a/spec/models/case_log_spec.rb +++ b/spec/models/case_log_spec.rb @@ -109,7 +109,7 @@ RSpec.describe Form, type: :model do expect { CaseLog.create!(unittype_gn: "Shared bungalow", beds: 8, - hhmemb: 1) + other_hhmemb: 1) }.to raise_error(ActiveRecord::RecordInvalid) end @@ -117,7 +117,7 @@ RSpec.describe Form, type: :model do expect { CaseLog.create!(unittype_gn: "Shared bungalow", beds: 4, - hhmemb: 0) + other_hhmemb: 0) }.to raise_error(ActiveRecord::RecordInvalid) end From 7942dec5c4ada3a295a58045eb929475097c1bed Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Fri, 12 Nov 2021 10:59:14 +0000 Subject: [PATCH 31/55] Add incref column (#87) * Add incref column * Rubocop * update migration version --- app/models/case_log.rb | 14 ++++++++++---- db/migrate/20211112105348_add_incref_field.rb | 8 ++++++++ db/schema.rb | 3 ++- spec/controllers/case_logs_controller_spec.rb | 8 ++++---- 4 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 db/migrate/20211112105348_add_incref_field.rb diff --git a/app/models/case_log.rb b/app/models/case_log.rb index f21b3338d..1842dc55a 100644 --- a/app/models/case_log.rb +++ b/app/models/case_log.rb @@ -164,9 +164,7 @@ class CaseLog < ApplicationRecord end def hhmemb - if other_hhmemb.present? - other_hhmemb - end + other_hhmemb.presence end def applicable_income_range @@ -193,7 +191,11 @@ class CaseLog < ApplicationRecord end end - + def incref + if net_income_known == "Prefer not to say" + 1 + end + end private @@ -253,6 +255,10 @@ private dynamically_not_required << "ecstat#{n}" end + if net_income_known != "Prefer not to say" + dynamically_not_required << "incref" + end + required.delete_if { |key, _value| dynamically_not_required.include?(key) } end end diff --git a/db/migrate/20211112105348_add_incref_field.rb b/db/migrate/20211112105348_add_incref_field.rb new file mode 100644 index 000000000..65df53aca --- /dev/null +++ b/db/migrate/20211112105348_add_incref_field.rb @@ -0,0 +1,8 @@ +class AddIncrefField < ActiveRecord::Migration[6.1] + def change + change_table :case_logs, bulk: true do |t| + t.column :incref, :integer + end + end +end + diff --git a/db/schema.rb b/db/schema.rb index 5b1c02e62..614c895c2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_11_11_143319) do +ActiveRecord::Schema.define(version: 2021_11_12_105348) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -153,6 +153,7 @@ ActiveRecord::Schema.define(version: 2021_11_11_143319) do t.integer "mrcmonth" t.integer "mrcyear" t.integer "other_hhmemb" + t.integer "incref" t.index ["discarded_at"], name: "index_case_logs_on_discarded_at" end diff --git a/spec/controllers/case_logs_controller_spec.rb b/spec/controllers/case_logs_controller_spec.rb index 007b76f8c..8192173fc 100644 --- a/spec/controllers/case_logs_controller_spec.rb +++ b/spec/controllers/case_logs_controller_spec.rb @@ -181,10 +181,10 @@ RSpec.describe CaseLogsController, type: :controller do context "partition date" do let(:case_log_with_date) do { - :"mrcdate(1i)" => "2021", - :"mrcdate(2i)" => "05", - :"mrcdate(3i)" => "04", - :page => "major_repairs_date", + "mrcdate(1i)": "2021", + "mrcdate(2i)": "05", + "mrcdate(3i)": "04", + page: "major_repairs_date", } end it "saves full and partial dates" do From bda09d78865ea1b0323d7d193913f3ffd574a979 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Fri, 12 Nov 2021 11:43:37 +0000 Subject: [PATCH 32/55] update readme for schema validation --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 5af61d33e..1b88f529f 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,7 @@ The JSON should follow the structure: "[snake_case_question_name_string]": { "header": String, "hint_text": String, + "check_answer_label": String, "type": "text" / "numeric" / "radio" / "checkbox" / "date", "min": Integer, // numeric only "max": Integer, // numeric only @@ -133,6 +134,10 @@ The JSON should follow the structure: "[snake_case_question_to_enable_2_name_string]": ["condition-that-enables"] } } + }, + "conditional_route_to": { + "[page_name_to_route_to]": {"question_name": "expected_answer"}, + "[page_name_to_route_to]": {"question_name": "expected_answer"} } } } @@ -155,6 +160,16 @@ Assumptions made by the format: - Radio question answer option selected matches one of conditional e.g. ["answer-options-1-string", "answer-option-3-string"] - Numeric question value matches condition e.g. [">2"], ["<7"] or ["== 6"] +## JSON Form Validation against Schema + +To validate the form JSON against the schema you can run: +`ruby app/helpers/json_schema_validation.rb` + +This will validate all forms in: +directories = ["config/forms", "spec/fixtures/forms"] + +against the schema in (config/forms/schema/generic.json) + ## Useful documentation (external dependencies) ### GOV.UK Design System Form Builder for Rails From fa86626d37570c0084aa3756e2a3742daf369eae Mon Sep 17 00:00:00 2001 From: magicmilo Date: Fri, 12 Nov 2021 13:37:58 +0000 Subject: [PATCH 33/55] added rake form_definition (can't load json-schema) --- README.md | 3 +++ app/helpers/json_schema_validation.rb | 5 +---- lib/tasks/form_definition.rake | 6 ++++++ 3 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 lib/tasks/form_definition.rake diff --git a/README.md b/README.md index 1b88f529f..98deac23e 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,9 @@ Assumptions made by the format: ## JSON Form Validation against Schema To validate the form JSON against the schema you can run: +`rake form_definition:validate` + +This will run: `ruby app/helpers/json_schema_validation.rb` This will validate all forms in: diff --git a/app/helpers/json_schema_validation.rb b/app/helpers/json_schema_validation.rb index d6eb46700..994955e4e 100644 --- a/app/helpers/json_schema_validation.rb +++ b/app/helpers/json_schema_validation.rb @@ -1,5 +1,5 @@ -require "json-schema" require "json" +require "json-schema" def get_all_form_paths(directories) form_paths = [] @@ -12,7 +12,6 @@ def get_all_form_paths(directories) end begin - path = "config/forms/schema/generic.json" file = File.open(path) @@ -36,8 +35,6 @@ begin file = File.open(path) data = JSON.parse(file.read) - puts JSON::Validator.validate(schema, data, :strict => true) - puts JSON::Validator.fully_validate(schema, data, :strict => true) begin diff --git a/lib/tasks/form_definition.rake b/lib/tasks/form_definition.rake new file mode 100644 index 000000000..c066e9a90 --- /dev/null +++ b/lib/tasks/form_definition.rake @@ -0,0 +1,6 @@ +namespace :form_definition do + desc "Validate JSON against Generic Form Schema" + task :validate do + ruby "app/helpers/json_schema_validation.rb" + end + end \ No newline at end of file From 5699c90e066e169186b8ec8429ab96f99da22f2f Mon Sep 17 00:00:00 2001 From: magicmilo Date: Fri, 12 Nov 2021 14:12:16 +0000 Subject: [PATCH 34/55] fixed dependency and updated readme --- Gemfile | 2 ++ Gemfile.lock | 3 +++ README.md | 2 +- lib/tasks/form_definition.rake | 5 ++++- {app/helpers => lib/tasks}/json_schema_validation.rb | 0 5 files changed, 10 insertions(+), 2 deletions(-) rename {app/helpers => lib/tasks}/json_schema_validation.rb (100%) diff --git a/Gemfile b/Gemfile index fa743fa4a..a147a5a2f 100644 --- a/Gemfile +++ b/Gemfile @@ -29,6 +29,8 @@ gem "discard" gem "activeadmin" # Admin charts gem "chartkick" +#Json Schema +gem "json-schema" group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console diff --git a/Gemfile.lock b/Gemfile.lock index 386f2d68b..df4d7bf5c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -196,6 +196,8 @@ GEM rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) + json-schema (2.8.1) + addressable (>= 2.4) kaminari (1.2.1) activesupport (>= 4.1.0) kaminari-actionview (= 1.2.1) @@ -398,6 +400,7 @@ DEPENDENCIES govuk_design_system_formbuilder hotwire-rails jbuilder (~> 2.7) + json-schema listen (~> 3.3) overcommit (>= 0.37.0) pg (~> 1.1) diff --git a/README.md b/README.md index 98deac23e..50d25ea40 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,7 @@ To validate the form JSON against the schema you can run: `rake form_definition:validate` This will run: -`ruby app/helpers/json_schema_validation.rb` +`ruby lib/tasks/json_schema_validation.rb` This will validate all forms in: directories = ["config/forms", "spec/fixtures/forms"] diff --git a/lib/tasks/form_definition.rake b/lib/tasks/form_definition.rake index c066e9a90..ed8be8c11 100644 --- a/lib/tasks/form_definition.rake +++ b/lib/tasks/form_definition.rake @@ -1,6 +1,9 @@ +# require "app/helpers/json_schema_validation.rb" + namespace :form_definition do desc "Validate JSON against Generic Form Schema" task :validate do - ruby "app/helpers/json_schema_validation.rb" + puts "#{Rails.root}" + ruby "lib/tasks/json_schema_validation.rb" end end \ No newline at end of file diff --git a/app/helpers/json_schema_validation.rb b/lib/tasks/json_schema_validation.rb similarity index 100% rename from app/helpers/json_schema_validation.rb rename to lib/tasks/json_schema_validation.rb From 57e117b09ef19a5bf1cc7428eac8dbed2280eec9 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Fri, 12 Nov 2021 14:33:21 +0000 Subject: [PATCH 35/55] run db migration --- db/schema.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 614c895c2..1ef990508 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -122,8 +122,6 @@ ActiveRecord::Schema.define(version: 2021_11_12_105348) do t.integer "rp_dontknow" t.datetime "discarded_at" t.string "tenancyother" - t.integer "override_net_income_validation" - t.string "net_income_known" t.string "gdpr_acceptance" t.string "gdpr_declined" t.string "property_owner_organisation" @@ -135,6 +133,8 @@ ActiveRecord::Schema.define(version: 2021_11_12_105348) do t.string "needs_type" t.string "sale_completion_date" t.string "purchaser_code" + t.integer "override_net_income_validation" + t.string "net_income_known" t.integer "reason" t.string "propcode" t.integer "majorrepairs" From 127958a47f06ec91605753aba08e2ce711a66572 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Fri, 12 Nov 2021 15:17:28 +0000 Subject: [PATCH 36/55] readd testform --- spec/fixtures/forms/test_form.json | 548 +++++++++++++++++++++++++++++ 1 file changed, 548 insertions(+) create mode 100644 spec/fixtures/forms/test_form.json diff --git a/spec/fixtures/forms/test_form.json b/spec/fixtures/forms/test_form.json new file mode 100644 index 000000000..28feb44b9 --- /dev/null +++ b/spec/fixtures/forms/test_form.json @@ -0,0 +1,548 @@ +{ + "form_type": "lettings", + "sections": { + "household": { + "label": "About the household", + "subsections": { + "household_characteristics": { + "label": "Household characteristics", + "pages": { + "tenant_code": { + "questions": { + "tenant_code": { + "check_answer_label": "Tenant code", + "header": "What is the tenant code?", + "type": "text" + } + } + }, + "person_1_age": { + "questions": { + "age1": { + "check_answer_label": "Tenant's age", + "header": "What is the tenant's age?", + "type": "numeric", + "min": 0, + "max": 150, + "step": 1 + } + } + }, + "person_1_gender": { + "questions": { + "sex1": { + "check_answer_label": "Tenant's gender", + "header": "Which of these best describes the tenant's gender identity?", + "type": "radio", + "answer_options": { + "0": "Female", + "1": "Male", + "2": "Non-binary", + "3": "Prefer not to say" + } + } + } + }, + "household_number_of_other_members": { + "questions": { + "other_hhmemb": { + "check_answer_label": "Number of Other Household Members", + "header": "How many other people are there in the household?", + "hint_text": "The maximum number of others is 1", + "type": "numeric", + "min": 0, + "max": 1, + "step": 1, + "conditional_for": { + "relat2": ">0", + "age2": ">0", + "sex2": ">0", + "ecstat2": ">0" + } + }, + "relat2": { + "check_answer_label": "Person 2's relationship to lead tenant", + "header": "What's person 2's relationship to lead tenant", + "type": "radio", + "answer_options": { + "0": "Other", + "1": "Prefer not to say" + } + }, + "age2": { + "check_answer_label": "Person 2's age", + "header": "What's person 2's age", + "type": "numeric", + "min": 0, + "max": 150, + "step": 1 + }, + "sex2": { + "check_answer_label": "Person 2's gender", + "header": "Which of these best describes person 2's gender identity?", + "type": "radio", + "answer_options": { + "0": "Female", + "1": "Male", + "2": "Non-binary", + "3": "Prefer not to say" + } + }, + "ecstat2": { + "check_answer_label": "Person 2's Work", + "header": "Which of these best describes person 2's working situation?", + "type": "radio", + "answer_options": { + "0": "Other", + "1": "Prefer not to say" + } + } + } + } + } + }, + "household_needs": { + "label": "Household needs", + "pages": { + "armed_forces": { + "header": "Experience of the UK Armed Forces", + "questions": { + "armed_forces": { + "header": "Has the tenant ever served in the UK armed forces?", + "type": "radio", + "check_answer_label": "Armed Forces", + "answer_options": { + "0": "Yes - a regular", + "1": "Yes - a reserve", + "2": "No", + "3": "Prefer not to say" + }, + "conditional_for": { + "leftreg": ["Yes - a regular", "Yes - a reserve"], + "reservist": ["Yes - a regular", "Yes - a reserve"] + } + }, + "leftreg": { + "header": "Are they still serving?", + "type": "radio", + "check_answer_label": "When did they leave the Armed Forces?", + "answer_options": { + "0": "Yes", + "1": "No - they left up to 5 years ago", + "2": "No - they left more than 5 years ago", + "3": "Prefer not to say" + } + }, + "reservist": { + "header": "Were they seriously injured or ill as a result of their service?", + "type": "radio", + "check_answer_label": "Has anyone in the household been seriously injured or ill as a result of their service in the armed forces?", + "answer_options": { + "0": "Yes", + "1": "No", + "2": "Prefer not to say" + } + } + } + }, + "medical_conditions": { + "questions": { + "illness": { + "header": "Does anyone in the household have any of the following that they expect to last for 12 months or more:
  • Physical Condition
  • Mental Health Condition
  • Other Illness
", + "type": "radio", + "check_answer_label": "Physical, mental health or illness in the household", + "answer_options": { + "0": "Yes", + "1": "No", + "2": "Do not know", + "3": "Prefer not to say" + } + } + } + }, + "accessibility_requirements": { + "questions": { + "accessibility_requirements": { + "header": "Are any of these affected by their condition or illness?", + "hint_text": "Select all that apply", + "type": "checkbox", + "check_answer_label": "Disability requirements", + "answer_options": { + "housingneeds_a": "Fully wheelchair accessible housing", + "housingneeds_b": "Wheelchair access to essential rooms", + "housingneeds_c": "Level access housing", + "divider_a": true, + "housingneeds_h": "Do not know" + } + } + } + }, + "condition_effects": { + "questions": { + "condition_effects": { + "header": "Are any of these affected by their condition or illness?", + "hint_text": "Select all that apply", + "type": "checkbox", + "check_answer_label": "Conditions or illnesses", + "answer_options": { + "illness_type_1": "Vision - such as blindness or partial sight", + "illness_type_2": "Hearing - such as deafness or partial hearing" + } + } + } + } + } + } + } + }, + "tenancy_and_property": { + "label": "Tenancy and property information", + "subsections": { + "tenancy_information": { + "label": "Tenancy information", + "pages": { + "tenancy_code": { + "questions": { + "tenancy_code": { + "check_answer_label": "What is the tenancy code?", + "header": "What is the tenancy code?", + "type": "text" + } + } + } + } + }, + "property_information": { + "label": "Property information", + "pages": { + "property_wheelchair_accessible": { + "questions": { + "wchair": { + "check_answer_label": "Is property built or adapted to wheelchair user standards?", + "header": "Is property built or adapted to wheelchair user standards?", + "type": "radio", + "answer_options": { + "0": "Yes", + "1": "No" + } + } + } + } + } + }, + "conditional_question": { + "label": "Conditional question", + "pages": { + "conditional_question": { + "questions": { + "preg_occ": { + "check_answer_label": "Has the condition been met?", + "header": "Has the condition been met?", + "type": "radio", + "answer_options": { + "0": "Yes", + "1": "No" + } + } + }, + "conditional_route_to": { + "rent": { "preg_occ": "Yes", "sex1": "Female" }, + "conditional_question_yes_page": { "preg_occ": "Yes" }, + "conditional_question_no_page": { "preg_occ": "No" } + }, + "default_next_page": "check_answers" + }, + "conditional_question_yes_page": { + "questions": { + "cbl": { + "check_answer_label": "Has the next condition been met?", + "header": "Has the next condition been met?", + "type": "radio", + "answer_options": { + "0": "Yes", + "1": "No" + } + } + }, + "default_next_page": "check_answers" + }, + "conditional_question_no_page": { + "questions": { + "conditional_question_no_question": { + "check_answer_label": "Has the condition not been met?", + "header": "Has the next condition not been met?", + "type": "radio", + "answer_options": { + "0": "Yes", + "1": "No" + } + } + }, + "default_next_page": "conditional_question_no_second_page" + }, + "conditional_question_no_second_page": { + "questions": { + "conditional_question_no_second_question": { + "check_answer_label": "Has the condition not been met again?", + "header": "Has the next condition not been met again?", + "type": "radio", + "answer_options": { + "0": "Yes", + "1": "No" + } + } + } + } + } + } + } + }, + "rent_and_charges": { + "label": "Rent and charges", + "subsections": { + "income_and_benefits": { + "label": "Income and benefits", + "pages": { + "net_income": { + "questions": { + "earnings": { + "check_answer_label": "Income", + "header": "What is the tenant’s /and partner’s combined income after tax?", + "type": "numeric", + "min": 0, + "step": "1" + }, + "incfreq": { + "check_answer_label": "Income Frequency", + "header": "How often do they receive this income?", + "type": "radio", + "answer_options": { + "0": "Weekly", + "1": "Monthly", + "2": "Yearly" + } + } + }, + "soft_validations": { + "override_net_income_validation": { + "check_answer_label": "Net income confirmed?", + "type": "validation_override", + "answer_options": { + "override_net_income_validation": "Yes" + } + } + } + }, + "net_income_uc_proportion": { + "questions": { + "benefits": { + "check_answer_label": "Benefits as a proportion of income", + "header": "How much of the tenant’s income is from Universal Credit, state pensions or benefits?", + "type": "radio", + "answer_options": { + "0": "All", + "1": "Some" + } + } + } + }, + "housing_benefit": { + "questions": { + "hb": { + "check_answer_label": "Universal Credit & Housing Benefit", + "header": "Is the tenant likely to be in receipt of any of these housing-related benefits?", + "type": "radio", + "answer_options": { + "0": "Housing Benefit, but not Universal Credit", + "1": "Prefer not to say" + } + } + } + } + } + }, + "rent": { + "label": "Rent", + "pages": { + "rent": { + "questions": { + "rent_frequency": { + "check_answer_label": "Rent Period", + "header": "Which period are rent and other charges due?", + "type": "radio", + "answer_options": { + "0": "Weekly for 52 weeks", + "1": "Fortnightly" + } + }, + "brent": { + "check_answer_label": "Basic Rent", + "header": "What is the basic rent?", + "hint_text": "Eligible for housing benefit or Universal Credit", + "type": "numeric", + "min": 0, + "step": 1, + "fields-to-add": [ + "brent", + "scharge", + "pscharge", + "supcharg" + ], + "result-field": "tcharge" + }, + "scharge": { + "check_answer_label": "Service Charge", + "header": "What is the service charge?", + "hint_text": "Eligible for housing benefit or Universal Credit", + "type": "numeric", + "min": 0, + "step": 1, + "fields-to-add": [ + "brent", + "scharge", + "pscharge", + "supcharg" + ], + "result-field": "tcharge" + }, + "pscharge": { + "check_answer_label": "Personal Service Charge", + "header": "What is the personal service charge?", + "hint_text": "Not eligible for housing benefit or Universal Credit. For example, hot water excluding water rates.", + "type": "numeric", + "min": 0, + "step": 1, + "fields-to-add": [ + "brent", + "scharge", + "pscharge", + "supcharg" + ], + "result-field": "tcharge" + }, + "supcharg": { + "check_answer_label": "Support Charge", + "header": "What is the support charge?", + "hint_text": "This is to fund housing-related support services included in the tenancy agreement", + "type": "numeric", + "min": 0, + "step": 1, + "fields-to-add": [ + "brent", + "scharge", + "pscharge", + "supcharg" + ], + "result-field": "tcharge" + }, + "tcharge": { + "check_answer_label": "Total Charge", + "header": "Total charge?", + "hint_text": "This is the total of rent and all charges", + "type": "numeric", + "min": 0, + "step": 1, + "readonly": true + } + } + } + } + } + } + }, + "local_authority": { + "label": "Local authority", + "subsections": { + "local_authority": { + "label": "Local authority", + "pages": { + "time_lived_in_la": { + "questions": { + "layear": { + "check_answer_label": "How long has the household continuously lived in the local authority area where the new letting is located?", + "header": "How long has the household continuously lived in the local authority area where the new letting is located?", + "type": "radio", + "answer_options": { + "0": "Just moved to local authority area", + "1": "Less than 1 year", + "2": "1 to 2 years", + "3": "2 to 3 years", + "4": "3 to 4 years", + "5": "4 to 5 years", + "6": "5 years or more", + "7": "Do not know" + } + } + } + }, + "time_on_la_waiting_list": { + "questions": { + "lawaitlist": { + "check_answer_label": "How long has the household been on the local authority waiting list where the new letting is located?", + "header": "How long has the household been on the local authority waiting list where the new letting is located?", + "type": "radio", + "answer_options": { + "0": "Just moved to local authority area", + "1": "Less than 1 year", + "2": "1 to 2 years", + "3": "2 to 3 years", + "4": "3 to 4 years", + "5": "4 to 5 years", + "6": "5 years or more", + "7": "Do not know" + } + } + } + }, + "property_postcode": { + "questions": { + "property_postcode": { + "check_answer_label": "Postcode of previous accomodation if the household has moved from settled accommodation", + "header": "Postcode for the previous accommodation", + "hint_text": "If the household has moved from settled accommodation immediately prior to being re-housed", + "type": "text", + "conditional_for": { "faake_key": "fake_condition" } + }, + "previous_postcode": { + "check_answer_label": "Postcode of previous accomodation if the household has moved from settled accommodation", + "header": "Postcode for the previous accommodation", + "hint_text": "If the household has moved from settled accommodation immediately prior to being re-housed", + "type": "text" + } + } + }, + "major_repairs_date": { + "questions": { + "mrcdate": { + "check_answer_label": "What was the major repairs completion date?", + "header": "What was the major repairs completion date?", + "hint_text": "For example, 27 3 2007", + "type": "date" + } + } + } + } + } + } + }, + "submission": { + "label": "Submission", + "subsections": { + "declaration": { + "label": "Declaration", + "pages": { + "declaration": { + "questions": { + "declaration": { + "check_answer_label": "", + "header": "What is the tenant code?", + "type": "text" + } + } + } + } + } + } + } + } + } \ No newline at end of file From c49b919a503cf9a2c901897f20671ca7d6161639 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Fri, 12 Nov 2021 15:23:18 +0000 Subject: [PATCH 37/55] put validation all into rake file --- lib/tasks/form_definition.rake | 47 +++++++++++++++++++++++++++-- lib/tasks/json_schema_validation.rb | 46 ---------------------------- 2 files changed, 44 insertions(+), 49 deletions(-) delete mode 100644 lib/tasks/json_schema_validation.rb diff --git a/lib/tasks/form_definition.rake b/lib/tasks/form_definition.rake index ed8be8c11..565728064 100644 --- a/lib/tasks/form_definition.rake +++ b/lib/tasks/form_definition.rake @@ -1,9 +1,50 @@ -# require "app/helpers/json_schema_validation.rb" +require "json" +require "json-schema" + +def get_all_form_paths(directories) + form_paths = [] + directories.each do |directory| + Dir.glob("#{directory}/*.json").each do |form_path| + form_paths.push(form_path) + end + end + form_paths +end namespace :form_definition do desc "Validate JSON against Generic Form Schema" task :validate do - puts "#{Rails.root}" - ruby "lib/tasks/json_schema_validation.rb" + puts "#{Rails.root}" + path = "config/forms/schema/generic.json" + + file = File.open(path) + schema = JSON.parse(file.read) + metaschema = JSON::Validator.validator_for_name("draft4").metaschema + + puts path + + if JSON::Validator.validate(metaschema, schema) + puts "schema valid" + else + puts "schema not valid" + return + end + + directories = ["config/forms", "spec/fixtures/forms"] + # directories = ["config/forms"] + + get_all_form_paths(directories).each do |path| + puts path + file = File.open(path) + data = JSON.parse(file.read) + + puts JSON::Validator.fully_validate(schema, data, :strict => true) + + begin + JSON::Validator.validate!(schema, data) + rescue JSON::Schema::ValidationError => e + e.message + end + end end end \ No newline at end of file diff --git a/lib/tasks/json_schema_validation.rb b/lib/tasks/json_schema_validation.rb deleted file mode 100644 index 994955e4e..000000000 --- a/lib/tasks/json_schema_validation.rb +++ /dev/null @@ -1,46 +0,0 @@ -require "json" -require "json-schema" - -def get_all_form_paths(directories) - form_paths = [] - directories.each do |directory| - Dir.glob("#{directory}/*.json").each do |form_path| - form_paths.push(form_path) - end - end - form_paths -end - -begin - path = "config/forms/schema/generic.json" - - file = File.open(path) - schema = JSON.parse(file.read) - metaschema = JSON::Validator.validator_for_name("draft4").metaschema - - puts path - - if JSON::Validator.validate(metaschema, schema) - puts "schema valid" - else - puts "schema not valid" - return - end - - directories = ["config/forms", "spec/fixtures/forms"] - # directories = ["config/forms"] - - get_all_form_paths(directories).each do |path| - puts path - file = File.open(path) - data = JSON.parse(file.read) - - puts JSON::Validator.fully_validate(schema, data, :strict => true) - - begin - JSON::Validator.validate!(schema, data) - rescue JSON::Schema::ValidationError => e - e.message - end - end -end From ba1afdbf653fd457c224fa77959932997a2dd813 Mon Sep 17 00:00:00 2001 From: magicmilo Date: Fri, 12 Nov 2021 15:24:06 +0000 Subject: [PATCH 38/55] change readme --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 50d25ea40..b637e606e 100644 --- a/README.md +++ b/README.md @@ -165,9 +165,6 @@ Assumptions made by the format: To validate the form JSON against the schema you can run: `rake form_definition:validate` -This will run: -`ruby lib/tasks/json_schema_validation.rb` - This will validate all forms in: directories = ["config/forms", "spec/fixtures/forms"] From a0ae5025bfbae5134cf7b2c77f87cb80810ee10c Mon Sep 17 00:00:00 2001 From: MadeTech Dushan Date: Mon, 1 Nov 2021 16:00:04 +0000 Subject: [PATCH 39/55] Add devise gem and a first test for user login Devise is a commonly used gem for user authentication and management. Using rails generators and Devise allows us to get a lot of boilerplate code for user authentication and management and means we don't have to revinvent the wheel. Styling will need to be done for the necessary pages and there are likely to be bits of generated code that can be deleted. This will act as a starting point to be built up from using TDD. --- Gemfile | 2 + Gemfile.lock | 11 + app/controllers/case_logs_controller.rb | 2 + app/models/user.rb | 5 + app/views/devise/confirmations/new.html.erb | 16 + .../mailer/confirmation_instructions.html.erb | 5 + .../devise/mailer/email_changed.html.erb | 7 + .../devise/mailer/password_change.html.erb | 3 + .../reset_password_instructions.html.erb | 8 + .../mailer/unlock_instructions.html.erb | 7 + app/views/devise/passwords/edit.html.erb | 25 ++ app/views/devise/passwords/new.html.erb | 16 + app/views/devise/registrations/edit.html.erb | 43 +++ app/views/devise/registrations/new.html.erb | 29 ++ app/views/devise/sessions/new.html.erb | 26 ++ .../devise/shared/_error_messages.html.erb | 15 + app/views/devise/shared/_links.html.erb | 25 ++ app/views/devise/unlocks/new.html.erb | 16 + app/views/layouts/application.html.erb | 2 + config/environments/development.rb | 2 + config/initializers/devise.rb | 311 ++++++++++++++++++ config/locales/devise.en.yml | 65 ++++ config/routes.rb | 1 + .../20211101103235_devise_create_users.rb | 44 +++ db/schema.rb | 12 + db/seeds.rb | 2 + spec/controllers/case_logs_controller_spec.rb | 2 + spec/factories/user.rb | 9 + spec/features/case_log_spec.rb | 6 +- spec/features/user_spec.rb | 10 + spec/rails_helper.rb | 6 + spec/support/controller_macros.rb | 16 + spec/support/devise.rb | 9 + 33 files changed, 757 insertions(+), 1 deletion(-) create mode 100644 app/models/user.rb create mode 100644 app/views/devise/confirmations/new.html.erb create mode 100644 app/views/devise/mailer/confirmation_instructions.html.erb create mode 100644 app/views/devise/mailer/email_changed.html.erb create mode 100644 app/views/devise/mailer/password_change.html.erb create mode 100644 app/views/devise/mailer/reset_password_instructions.html.erb create mode 100644 app/views/devise/mailer/unlock_instructions.html.erb create mode 100644 app/views/devise/passwords/edit.html.erb create mode 100644 app/views/devise/passwords/new.html.erb create mode 100644 app/views/devise/registrations/edit.html.erb create mode 100644 app/views/devise/registrations/new.html.erb create mode 100644 app/views/devise/sessions/new.html.erb create mode 100644 app/views/devise/shared/_error_messages.html.erb create mode 100644 app/views/devise/shared/_links.html.erb create mode 100644 app/views/devise/unlocks/new.html.erb create mode 100644 config/initializers/devise.rb create mode 100644 config/locales/devise.en.yml create mode 100644 db/migrate/20211101103235_devise_create_users.rb create mode 100644 spec/factories/user.rb create mode 100644 spec/features/user_spec.rb create mode 100644 spec/support/controller_macros.rb create mode 100644 spec/support/devise.rb diff --git a/Gemfile b/Gemfile index ed2af8973..f136a5f12 100644 --- a/Gemfile +++ b/Gemfile @@ -32,6 +32,8 @@ gem "chartkick" #Json Schema gem "json-schema" gem "uk_postcode" +# Authentication +gem "devise" group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console diff --git a/Gemfile.lock b/Gemfile.lock index d2a3b4a15..a5d222b0c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -122,6 +122,7 @@ GEM activesupport (>= 3.0.0, < 6.2) ruby2_keywords (>= 0.0.2, < 1.0) ast (2.4.2) + bcrypt (3.1.16) bindex (0.8.1) bootsnap (1.9.1) msgpack (~> 1.0) @@ -146,6 +147,12 @@ GEM database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) deep_merge (1.2.1) + devise (4.8.0) + bcrypt (~> 3.0) + orm_adapter (~> 0.1) + railties (>= 4.1.0) + responders + warden (~> 1.2.3) diff-lcs (1.4.4) discard (1.2.0) activerecord (>= 4.2, < 7) @@ -229,6 +236,7 @@ GEM racc (~> 1.4) nokogiri (1.12.5-x86_64-linux) racc (~> 1.4) + orm_adapter (0.5.0) overcommit (0.58.0) childprocess (>= 0.6.3, < 5) iniparse (~> 1.4) @@ -365,6 +373,8 @@ GEM view_component (2.39.0) activesupport (>= 5.0.0, < 8.0) method_source (~> 1.0) + warden (1.2.9) + rack (>= 2.0.9) web-console (4.1.0) actionview (>= 6.0.0) activemodel (>= 6.0.0) @@ -394,6 +404,7 @@ DEPENDENCIES capybara chartkick database_cleaner-active_record + devise discard dotenv-rails factory_bot_rails diff --git a/app/controllers/case_logs_controller.rb b/app/controllers/case_logs_controller.rb index 8eb60af6a..84c9ff11f 100644 --- a/app/controllers/case_logs_controller.rb +++ b/app/controllers/case_logs_controller.rb @@ -1,6 +1,8 @@ class CaseLogsController < ApplicationController skip_before_action :verify_authenticity_token, if: :json_api_request? before_action :authenticate, if: :json_api_request? + # TODO determine if it's worth splitting out an API controller + before_action :authenticate_user!, unless: :json_api_request? def index @completed_case_logs = CaseLog.completed diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 000000000..0ef982f25 --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,5 @@ +class User < ApplicationRecord + # Include default devise modules. Others available are: + # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable + devise :database_authenticatable, :recoverable, :rememberable, :validatable +end diff --git a/app/views/devise/confirmations/new.html.erb b/app/views/devise/confirmations/new.html.erb new file mode 100644 index 000000000..b12dd0cbe --- /dev/null +++ b/app/views/devise/confirmations/new.html.erb @@ -0,0 +1,16 @@ +

Resend confirmation instructions

+ +<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + +
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %> +
+ +
+ <%= f.submit "Resend confirmation instructions" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/devise/mailer/confirmation_instructions.html.erb b/app/views/devise/mailer/confirmation_instructions.html.erb new file mode 100644 index 000000000..dc55f64f6 --- /dev/null +++ b/app/views/devise/mailer/confirmation_instructions.html.erb @@ -0,0 +1,5 @@ +

Welcome <%= @email %>!

+ +

You can confirm your account email through the link below:

+ +

<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>

diff --git a/app/views/devise/mailer/email_changed.html.erb b/app/views/devise/mailer/email_changed.html.erb new file mode 100644 index 000000000..32f4ba803 --- /dev/null +++ b/app/views/devise/mailer/email_changed.html.erb @@ -0,0 +1,7 @@ +

Hello <%= @email %>!

+ +<% if @resource.try(:unconfirmed_email?) %> +

We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.

+<% else %> +

We're contacting you to notify you that your email has been changed to <%= @resource.email %>.

+<% end %> diff --git a/app/views/devise/mailer/password_change.html.erb b/app/views/devise/mailer/password_change.html.erb new file mode 100644 index 000000000..b41daf476 --- /dev/null +++ b/app/views/devise/mailer/password_change.html.erb @@ -0,0 +1,3 @@ +

Hello <%= @resource.email %>!

+ +

We're contacting you to notify you that your password has been changed.

diff --git a/app/views/devise/mailer/reset_password_instructions.html.erb b/app/views/devise/mailer/reset_password_instructions.html.erb new file mode 100644 index 000000000..f667dc12f --- /dev/null +++ b/app/views/devise/mailer/reset_password_instructions.html.erb @@ -0,0 +1,8 @@ +

Hello <%= @resource.email %>!

+ +

Someone has requested a link to change your password. You can do this through the link below.

+ +

<%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %>

+ +

If you didn't request this, please ignore this email.

+

Your password won't change until you access the link above and create a new one.

diff --git a/app/views/devise/mailer/unlock_instructions.html.erb b/app/views/devise/mailer/unlock_instructions.html.erb new file mode 100644 index 000000000..41e148bf2 --- /dev/null +++ b/app/views/devise/mailer/unlock_instructions.html.erb @@ -0,0 +1,7 @@ +

Hello <%= @resource.email %>!

+ +

Your account has been locked due to an excessive number of unsuccessful sign in attempts.

+ +

Click the link below to unlock your account:

+ +

<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>

diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb new file mode 100644 index 000000000..5fbb9ff0a --- /dev/null +++ b/app/views/devise/passwords/edit.html.erb @@ -0,0 +1,25 @@ +

Change your password

+ +<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + <%= f.hidden_field :reset_password_token %> + +
+ <%= f.label :password, "New password" %>
+ <% if @minimum_password_length %> + (<%= @minimum_password_length %> characters minimum)
+ <% end %> + <%= f.password_field :password, autofocus: true, autocomplete: "new-password" %> +
+ +
+ <%= f.label :password_confirmation, "Confirm new password" %>
+ <%= f.password_field :password_confirmation, autocomplete: "new-password" %> +
+ +
+ <%= f.submit "Change my password" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/devise/passwords/new.html.erb b/app/views/devise/passwords/new.html.erb new file mode 100644 index 000000000..9b486b81b --- /dev/null +++ b/app/views/devise/passwords/new.html.erb @@ -0,0 +1,16 @@ +

Forgot your password?

+ +<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + +
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %> +
+ +
+ <%= f.submit "Send me reset password instructions" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb new file mode 100644 index 000000000..38d95b85a --- /dev/null +++ b/app/views/devise/registrations/edit.html.erb @@ -0,0 +1,43 @@ +

Edit <%= resource_name.to_s.humanize %>

+ +<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + +
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %> +
+ + <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %> +
Currently waiting confirmation for: <%= resource.unconfirmed_email %>
+ <% end %> + +
+ <%= f.label :password %> (leave blank if you don't want to change it)
+ <%= f.password_field :password, autocomplete: "new-password" %> + <% if @minimum_password_length %> +
+ <%= @minimum_password_length %> characters minimum + <% end %> +
+ +
+ <%= f.label :password_confirmation %>
+ <%= f.password_field :password_confirmation, autocomplete: "new-password" %> +
+ +
+ <%= f.label :current_password %> (we need your current password to confirm your changes)
+ <%= f.password_field :current_password, autocomplete: "current-password" %> +
+ +
+ <%= f.submit "Update" %> +
+<% end %> + +

Cancel my account

+ +

Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %>

+ +<%= link_to "Back", :back %> diff --git a/app/views/devise/registrations/new.html.erb b/app/views/devise/registrations/new.html.erb new file mode 100644 index 000000000..d655b66f6 --- /dev/null +++ b/app/views/devise/registrations/new.html.erb @@ -0,0 +1,29 @@ +

Sign up

+ +<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + +
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %> +
+ +
+ <%= f.label :password %> + <% if @minimum_password_length %> + (<%= @minimum_password_length %> characters minimum) + <% end %>
+ <%= f.password_field :password, autocomplete: "new-password" %> +
+ +
+ <%= f.label :password_confirmation %>
+ <%= f.password_field :password_confirmation, autocomplete: "new-password" %> +
+ +
+ <%= f.submit "Sign up" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb new file mode 100644 index 000000000..5ede96489 --- /dev/null +++ b/app/views/devise/sessions/new.html.erb @@ -0,0 +1,26 @@ +

Log in

+ +<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %> +
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %> +
+ +
+ <%= f.label :password %>
+ <%= f.password_field :password, autocomplete: "current-password" %> +
+ + <% if devise_mapping.rememberable? %> +
+ <%= f.check_box :remember_me %> + <%= f.label :remember_me %> +
+ <% end %> + +
+ <%= f.submit "Log in" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/devise/shared/_error_messages.html.erb b/app/views/devise/shared/_error_messages.html.erb new file mode 100644 index 000000000..ba7ab8870 --- /dev/null +++ b/app/views/devise/shared/_error_messages.html.erb @@ -0,0 +1,15 @@ +<% if resource.errors.any? %> +
+

+ <%= I18n.t("errors.messages.not_saved", + count: resource.errors.count, + resource: resource.class.model_name.human.downcase) + %> +

+
    + <% resource.errors.full_messages.each do |message| %> +
  • <%= message %>
  • + <% end %> +
+
+<% end %> diff --git a/app/views/devise/shared/_links.html.erb b/app/views/devise/shared/_links.html.erb new file mode 100644 index 000000000..96a941241 --- /dev/null +++ b/app/views/devise/shared/_links.html.erb @@ -0,0 +1,25 @@ +<%- if controller_name != 'sessions' %> + <%= link_to "Log in", new_session_path(resource_name) %>
+<% end %> + +<%- if devise_mapping.registerable? && controller_name != 'registrations' %> + <%= link_to "Sign up", new_registration_path(resource_name) %>
+<% end %> + +<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %> + <%= link_to "Forgot your password?", new_password_path(resource_name) %>
+<% end %> + +<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> + <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %>
+<% end %> + +<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %> + <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %>
+<% end %> + +<%- if devise_mapping.omniauthable? %> + <%- resource_class.omniauth_providers.each do |provider| %> + <%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), method: :post %>
+ <% end %> +<% end %> diff --git a/app/views/devise/unlocks/new.html.erb b/app/views/devise/unlocks/new.html.erb new file mode 100644 index 000000000..ffc34de8d --- /dev/null +++ b/app/views/devise/unlocks/new.html.erb @@ -0,0 +1,16 @@ +

Resend unlock instructions

+ +<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + +
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %> +
+ +
+ <%= f.submit "Resend unlock instructions" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 343307b55..82b5f586c 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -16,6 +16,8 @@ <%= stylesheet_pack_tag 'application', media: 'all' %> <%= javascript_pack_tag 'application', defer: true %> +

<%= notice %>

+

<%= alert %>

<% if Rails.env.development? %>