diff --git a/.env.example b/.env.example index b6a2bf14f..8b966b4f4 100644 --- a/.env.example +++ b/.env.example @@ -5,3 +5,4 @@ GOVUK_NOTIFY_API_KEY= OTP_SECRET_ENCRYPTION_KEY="" APP_HOST="http://localhost:3000" +OS_DATA_KEY=OS_DATA_KEY diff --git a/.env.test b/.env.test new file mode 100644 index 000000000..2ba1222ba --- /dev/null +++ b/.env.test @@ -0,0 +1,2 @@ +APP_HOST="http://localhost:3000" +OS_DATA_KEY=OS_DATA_KEY diff --git a/.github/workflows/production_pipeline.yml b/.github/workflows/production_pipeline.yml index 23bb69c00..0e479cbf0 100644 --- a/.github/workflows/production_pipeline.yml +++ b/.github/workflows/production_pipeline.yml @@ -42,6 +42,7 @@ jobs: DB_USERNAME: postgres DB_PASSWORD: password RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }} + PARALLEL_TEST_PROCESSORS: 4 steps: - name: Get latest release with tag @@ -71,7 +72,7 @@ jobs: - name: Create database run: | - bundle exec rake db:prepare + bundle exec rake parallel:setup - name: Compile Assets run: | @@ -79,7 +80,7 @@ jobs: - name: Run tests run: | - bundle exec rspec --exclude-pattern "features/*" --fail-fast + bundle exec rake parallel:spec['spec\/(?!features)'] feature_test: name: Feature Tests @@ -236,6 +237,7 @@ jobs: GOVUK_NOTIFY_API_KEY: ${{ secrets.GOVUK_NOTIFY_API_KEY }} APP_HOST: ${{ secrets.APP_HOST }} RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }} + OS_DATA_KEY: ${{ secrets.OS_DATA_KEY }} IMPORT_PAAS_INSTANCE: ${{ secrets.IMPORT_PAAS_INSTANCE }} EXPORT_PAAS_INSTANCE: ${{ secrets.EXPORT_PAAS_INSTANCE }} S3_CONFIG: ${{ secrets.S3_CONFIG }} @@ -248,6 +250,7 @@ jobs: cf set-env $APP_NAME GOVUK_NOTIFY_API_KEY $GOVUK_NOTIFY_API_KEY cf set-env $APP_NAME APP_HOST $APP_HOST cf set-env $APP_NAME RAILS_MASTER_KEY $RAILS_MASTER_KEY + cf set-env $APP_NAME OS_DATA_KEY $OS_DATA_KEY cf set-env $APP_NAME IMPORT_PAAS_INSTANCE $IMPORT_PAAS_INSTANCE cf set-env $APP_NAME EXPORT_PAAS_INSTANCE $EXPORT_PAAS_INSTANCE cf set-env $APP_NAME S3_CONFIG $S3_CONFIG diff --git a/.github/workflows/review_pipeline.yml b/.github/workflows/review_pipeline.yml index 5656898bc..8248c8f46 100644 --- a/.github/workflows/review_pipeline.yml +++ b/.github/workflows/review_pipeline.yml @@ -110,6 +110,7 @@ jobs: API_KEY: ${{ secrets.API_KEY }} GOVUK_NOTIFY_API_KEY: ${{ secrets.GOVUK_NOTIFY_API_KEY }} RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }} + OS_DATA_KEY: ${{ secrets.OS_DATA_KEY }} IMPORT_PAAS_INSTANCE: ${{ secrets.IMPORT_PAAS_INSTANCE }} EXPORT_PAAS_INSTANCE: ${{ secrets.EXPORT_PAAS_INSTANCE }} S3_CONFIG: ${{ secrets.S3_CONFIG }} @@ -120,10 +121,11 @@ jobs: cf set-env $APP_NAME API_KEY $API_KEY cf set-env $APP_NAME GOVUK_NOTIFY_API_KEY $GOVUK_NOTIFY_API_KEY cf set-env $APP_NAME RAILS_MASTER_KEY $RAILS_MASTER_KEY + cf set-env $APP_NAME OS_DATA_KEY $OS_DATA_KEY cf set-env $APP_NAME IMPORT_PAAS_INSTANCE $IMPORT_PAAS_INSTANCE cf set-env $APP_NAME EXPORT_PAAS_INSTANCE "dluhc-core-review-export-bucket" cf set-env $APP_NAME S3_CONFIG $S3_CONFIG - cf set-env $APP_NAME CSV_DOWNLOAD_PAAS_INSTANCE "dluhc-core-review-csv-bucket" + cf set-env $APP_NAME CSV_DOWNLOAD_PAAS_INSTANCE "dluhc-core-staging-csv-bucket" cf set-env $APP_NAME SENTRY_DSN $SENTRY_DSN cf set-env $APP_NAME APP_HOST "https://dluhc-core-review-${{ github.event.pull_request.number }}.london.cloudapps.digital" diff --git a/.github/workflows/staging_pipeline.yml b/.github/workflows/staging_pipeline.yml index 8d48f7b7e..987d18233 100644 --- a/.github/workflows/staging_pipeline.yml +++ b/.github/workflows/staging_pipeline.yml @@ -45,6 +45,7 @@ jobs: DB_USERNAME: postgres DB_PASSWORD: password RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }} + PARALLEL_TEST_PROCESSORS: 4 steps: - name: Checkout @@ -63,7 +64,7 @@ jobs: - name: Create database run: | - bundle exec rake db:prepare + bundle exec rake parallel:setup - name: Compile assets run: | @@ -71,7 +72,7 @@ jobs: - name: Run tests run: | - bundle exec rspec --exclude-pattern "features/*" --fail-fast + bundle exec rake parallel:spec['spec\/(?!features)'] feature_test: name: Feature Tests @@ -207,6 +208,7 @@ jobs: GOVUK_NOTIFY_API_KEY: ${{ secrets.GOVUK_NOTIFY_API_KEY }} APP_HOST: ${{ secrets.APP_HOST }} RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }} + OS_DATA_KEY: ${{ secrets.OS_DATA_KEY }} IMPORT_PAAS_INSTANCE: ${{ secrets.IMPORT_PAAS_INSTANCE }} EXPORT_PAAS_INSTANCE: ${{ secrets.EXPORT_PAAS_INSTANCE }} S3_CONFIG: ${{ secrets.S3_CONFIG }} @@ -221,6 +223,7 @@ jobs: cf set-env $APP_NAME GOVUK_NOTIFY_API_KEY $GOVUK_NOTIFY_API_KEY cf set-env $APP_NAME APP_HOST $APP_HOST cf set-env $APP_NAME RAILS_MASTER_KEY $RAILS_MASTER_KEY + cf set-env $APP_NAME OS_DATA_KEY $OS_DATA_KEY cf set-env $APP_NAME IMPORT_PAAS_INSTANCE $IMPORT_PAAS_INSTANCE cf set-env $APP_NAME EXPORT_PAAS_INSTANCE $EXPORT_PAAS_INSTANCE cf set-env $APP_NAME S3_CONFIG $S3_CONFIG diff --git a/Gemfile.lock b/Gemfile.lock index b9b16ab1e..9083ba67e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,67 +13,67 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (7.0.4.2) - actionpack (= 7.0.4.2) - activesupport (= 7.0.4.2) + actioncable (7.0.4.3) + actionpack (= 7.0.4.3) + activesupport (= 7.0.4.3) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (7.0.4.2) - actionpack (= 7.0.4.2) - activejob (= 7.0.4.2) - activerecord (= 7.0.4.2) - activestorage (= 7.0.4.2) - activesupport (= 7.0.4.2) + actionmailbox (7.0.4.3) + actionpack (= 7.0.4.3) + activejob (= 7.0.4.3) + activerecord (= 7.0.4.3) + activestorage (= 7.0.4.3) + activesupport (= 7.0.4.3) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.0.4.2) - actionpack (= 7.0.4.2) - actionview (= 7.0.4.2) - activejob (= 7.0.4.2) - activesupport (= 7.0.4.2) + actionmailer (7.0.4.3) + actionpack (= 7.0.4.3) + actionview (= 7.0.4.3) + activejob (= 7.0.4.3) + activesupport (= 7.0.4.3) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.0) - actionpack (7.0.4.2) - actionview (= 7.0.4.2) - activesupport (= 7.0.4.2) + actionpack (7.0.4.3) + actionview (= 7.0.4.3) + activesupport (= 7.0.4.3) rack (~> 2.0, >= 2.2.0) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (7.0.4.2) - actionpack (= 7.0.4.2) - activerecord (= 7.0.4.2) - activestorage (= 7.0.4.2) - activesupport (= 7.0.4.2) + actiontext (7.0.4.3) + actionpack (= 7.0.4.3) + activerecord (= 7.0.4.3) + activestorage (= 7.0.4.3) + activesupport (= 7.0.4.3) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.0.4.2) - activesupport (= 7.0.4.2) + actionview (7.0.4.3) + activesupport (= 7.0.4.3) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (7.0.4.2) - activesupport (= 7.0.4.2) + activejob (7.0.4.3) + activesupport (= 7.0.4.3) globalid (>= 0.3.6) - activemodel (7.0.4.2) - activesupport (= 7.0.4.2) - activerecord (7.0.4.2) - activemodel (= 7.0.4.2) - activesupport (= 7.0.4.2) - activestorage (7.0.4.2) - actionpack (= 7.0.4.2) - activejob (= 7.0.4.2) - activerecord (= 7.0.4.2) - activesupport (= 7.0.4.2) + activemodel (7.0.4.3) + activesupport (= 7.0.4.3) + activerecord (7.0.4.3) + activemodel (= 7.0.4.3) + activesupport (= 7.0.4.3) + activestorage (7.0.4.3) + actionpack (= 7.0.4.3) + activejob (= 7.0.4.3) + activerecord (= 7.0.4.3) + activesupport (= 7.0.4.3) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (7.0.4.2) + activesupport (7.0.4.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -134,7 +134,7 @@ GEM launchy childprocess (4.1.0) coderay (1.1.3) - concurrent-ruby (1.2.0) + concurrent-ruby (1.2.2) connection_pool (2.3.0) crack (0.4.5) rexml @@ -221,7 +221,7 @@ GEM matrix (0.4.2) method_source (1.0.0) mini_mime (1.1.2) - minitest (5.17.0) + minitest (5.18.0) msgpack (1.6.0) net-imap (0.3.4) date @@ -279,35 +279,35 @@ GEM nio4r (~> 2.0) raabro (1.4.0) racc (1.6.2) - rack (2.2.6.3) + rack (2.2.6.4) rack-attack (6.6.1) rack (>= 1.0, < 3) rack-mini-profiler (2.3.4) rack (>= 1.2.0) - rack-test (2.0.2) + rack-test (2.1.0) rack (>= 1.3) - rails (7.0.4.2) - actioncable (= 7.0.4.2) - actionmailbox (= 7.0.4.2) - actionmailer (= 7.0.4.2) - actionpack (= 7.0.4.2) - actiontext (= 7.0.4.2) - actionview (= 7.0.4.2) - activejob (= 7.0.4.2) - activemodel (= 7.0.4.2) - activerecord (= 7.0.4.2) - activestorage (= 7.0.4.2) - activesupport (= 7.0.4.2) + rails (7.0.4.3) + actioncable (= 7.0.4.3) + actionmailbox (= 7.0.4.3) + actionmailer (= 7.0.4.3) + actionpack (= 7.0.4.3) + actiontext (= 7.0.4.3) + actionview (= 7.0.4.3) + activejob (= 7.0.4.3) + activemodel (= 7.0.4.3) + activerecord (= 7.0.4.3) + activestorage (= 7.0.4.3) + activesupport (= 7.0.4.3) bundler (>= 1.15.0) - railties (= 7.0.4.2) + railties (= 7.0.4.3) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) rails-html-sanitizer (1.5.0) loofah (~> 2.19, >= 2.19.1) - railties (7.0.4.2) - actionpack (= 7.0.4.2) - activesupport (= 7.0.4.2) + railties (7.0.4.3) + actionpack (= 7.0.4.3) + activesupport (= 7.0.4.3) method_source rake (>= 12.2) thor (~> 1.0) diff --git a/app/components/bulk_upload_error_row_component.rb b/app/components/bulk_upload_error_row_component.rb index e19717954..13ac326ef 100644 --- a/app/components/bulk_upload_error_row_component.rb +++ b/app/components/bulk_upload_error_row_component.rb @@ -24,14 +24,7 @@ class BulkUploadErrorRowComponent < ViewComponent::Base end def question_for_field(field) - case bulk_upload.log_type - when "lettings" - BulkUpload::Lettings::Validator.question_for_field(field.to_sym) - when "sales" - BulkUpload::Sales::Validator.question_for_field(field.to_sym) - else - "Unknown question" - end + bulk_upload.prefix_namespace::RowParser.question_for_field(field.to_sym) end def bulk_upload diff --git a/app/components/bulk_upload_error_summary_table_component.html.erb b/app/components/bulk_upload_error_summary_table_component.html.erb index f1749ee92..2f9643271 100644 --- a/app/components/bulk_upload_error_summary_table_component.html.erb +++ b/app/components/bulk_upload_error_summary_table_component.html.erb @@ -1,24 +1,16 @@ -<%= govuk_table do |table| %> - <% table.caption(size: "m", text: bulk_upload.filename) %> - - <% table.head do |head| %> - <% head.row do |row| %> - <% row.cell(text: "Column", header: true) %> - <% row.cell(text: "Number of rows", header: true) %> - <% row.cell(text: "Question", header: true) %> - <% row.cell(text: "Error", header: true) %> - <% row.cell(text: "Specification", header: true) %> - <% end %> - <% end %> +<% sorted_errors.each do |error| %> + <%= govuk_table do |table| %> + <% table.head do |head| %> + <% head.row do |row| %> + <% row.cell(text: question_for_field(error[0][1].to_sym), header: true) %> + <% row.cell(text: "Column #{error[0][0]}", header: true, numeric: true) %> + <% end %> - <% table.body do |body| %> - <% sorted_errors.each do |error| %> - <% body.row do |row| %> - <% row.cell(text: error[0][0]) %> - <% row.cell(text: error[1]) %> - <% row.cell(text: BulkUpload::Lettings::Validator.question_for_field(error[0][1].to_sym)) %> - <% row.cell(text: error[0][2]) %> - <% row.cell(text: error[0][1]) %> + <% table.body do |body| %> + <% body.row do |row| %> + <% row.cell(text: error[0][2]) %> + <% row.cell(text: pluralize(error[1], "error"), numeric: true) %> + <% end %> <% end %> <% end %> <% end %> diff --git a/app/components/bulk_upload_error_summary_table_component.rb b/app/components/bulk_upload_error_summary_table_component.rb index a3d295110..909fb5f0d 100644 --- a/app/components/bulk_upload_error_summary_table_component.rb +++ b/app/components/bulk_upload_error_summary_table_component.rb @@ -3,6 +3,8 @@ class BulkUploadErrorSummaryTableComponent < ViewComponent::Base attr_reader :bulk_upload + delegate :question_for_field, to: :row_parser_class + def initialize(bulk_upload:) @bulk_upload = bulk_upload @@ -27,4 +29,8 @@ private def display_threshold DISPLAY_THRESHOLD end + + def row_parser_class + bulk_upload.prefix_namespace::RowParser + end end diff --git a/app/components/check_answers_summary_list_card_component.html.erb b/app/components/check_answers_summary_list_card_component.html.erb index e5b5388ab..3b4c4978a 100644 --- a/app/components/check_answers_summary_list_card_component.html.erb +++ b/app/components/check_answers_summary_list_card_component.html.erb @@ -10,7 +10,7 @@ <%= govuk_summary_list do |summary_list| %> <% applicable_questions.each do |question| %> <% summary_list.row do |row| %> - <% row.key { question.check_answer_label.to_s.presence || question.header.to_s } %> + <% row.key { get_question_label(question) } %> <% row.value do %> <%= get_answer_label(question) %> diff --git a/app/components/check_answers_summary_list_card_component.rb b/app/components/check_answers_summary_list_card_component.rb index e8ed971bc..62469e324 100644 --- a/app/components/check_answers_summary_list_card_component.rb +++ b/app/components/check_answers_summary_list_card_component.rb @@ -17,6 +17,10 @@ class CheckAnswersSummaryListCardComponent < ViewComponent::Base question.answer_label(log, user).presence || unanswered_value end + def get_question_label(question) + [question.question_number_string, question.check_answer_label.to_s.presence || question.header.to_s].compact.join(" - ") + end + def check_answers_card_title(question) return "Lead tenant" if question.form.type == "lettings" && question.check_answers_card_number == 1 return "Buyer #{question.check_answers_card_number}" if question.check_answers_card_number <= number_of_buyers diff --git a/app/controllers/bulk_upload_lettings_logs_controller.rb b/app/controllers/bulk_upload_lettings_logs_controller.rb index 9b37cd2b5..ec5975432 100644 --- a/app/controllers/bulk_upload_lettings_logs_controller.rb +++ b/app/controllers/bulk_upload_lettings_logs_controller.rb @@ -33,6 +33,8 @@ private end def in_crossover_period? + return true if FeatureToggle.force_crossover? + FormHandler.instance.lettings_in_crossover_period? end diff --git a/app/controllers/form_controller.rb b/app/controllers/form_controller.rb index 467b049df..92b62a511 100644 --- a/app/controllers/form_controller.rb +++ b/app/controllers/form_controller.rb @@ -160,7 +160,7 @@ private end def question_is_required?(question) - @log.class::OPTIONAL_FIELDS.exclude?(question.id) && required_questions.include?(question.id) + @log.optional_fields.exclude?(question.id) && required_questions.include?(question.id) end def required_questions diff --git a/app/controllers/lettings_logs_controller.rb b/app/controllers/lettings_logs_controller.rb index f86a55a27..e07878b0b 100644 --- a/app/controllers/lettings_logs_controller.rb +++ b/app/controllers/lettings_logs_controller.rb @@ -2,10 +2,16 @@ class LettingsLogsController < LogsController before_action :find_resource, except: %i[create index edit] before_action :session_filters, if: :current_user, only: %i[index email_csv download_csv] before_action :set_session_filters, if: :current_user, only: %i[index email_csv download_csv] + before_action :authenticate_scope!, only: %i[download_csv email_csv] before_action :extract_bulk_upload_from_session_filters, only: [:index] before_action :redirect_if_bulk_upload_resolved, only: [:index] + def authenticate_scope! + codes_only_export = codes_only_export?(params) + head :unauthorized and return unless current_user.support? || !codes_only_export + end + def index respond_to do |format| format.html do @@ -80,13 +86,19 @@ class LettingsLogsController < LogsController def download_csv unpaginated_filtered_logs = filtered_logs(current_user.lettings_logs, search_term, @session_filters) + codes_only = codes_only_export?(params) + + render "download_csv", locals: { search_term:, count: unpaginated_filtered_logs.size, post_path: email_csv_lettings_logs_path, codes_only: } + end - render "download_csv", locals: { search_term:, count: unpaginated_filtered_logs.size, post_path: email_csv_lettings_logs_path } + def codes_only_export?(params) + params.require(:codes_only) == "true" end def email_csv all_orgs = params["organisation_select"] == "all" - EmailCsvJob.perform_later(current_user, search_term, @session_filters, all_orgs) + codes_only_export = params.require(:codes_only) == "true" + EmailCsvJob.perform_later(current_user, search_term, @session_filters, all_orgs, nil, codes_only_export) redirect_to csv_confirmation_lettings_logs_path end diff --git a/app/controllers/locations_controller.rb b/app/controllers/locations_controller.rb index f01193f4c..5b39fa875 100644 --- a/app/controllers/locations_controller.rb +++ b/app/controllers/locations_controller.rb @@ -41,7 +41,7 @@ class LocationsController < ApplicationController def update_local_authority @location.location_admin_district = location_params[:location_admin_district] - @location.location_code = Location.local_authorities.key(location_params[:location_admin_district]) + @location.location_code = Location.local_authorities_for_current_year.key(location_params[:location_admin_district]) if @location.save(context: :location_admin_district) if return_to_check_your_answers? || params[:referrer] == "check_local_authority" redirect_to scheme_location_check_answers_path(@scheme, @location, route: params[:route]) diff --git a/app/controllers/organisations_controller.rb b/app/controllers/organisations_controller.rb index 211283ffe..418526960 100644 --- a/app/controllers/organisations_controller.rb +++ b/app/controllers/organisations_controller.rb @@ -107,12 +107,14 @@ class OrganisationsController < ApplicationController def download_csv organisation_logs = LettingsLog.all.where(owning_organisation_id: @organisation.id) unpaginated_filtered_logs = filtered_logs(organisation_logs, search_term, @session_filters) + codes_only = params.require(:codes_only) == "true" - render "logs/download_csv", locals: { search_term:, count: unpaginated_filtered_logs.size, post_path: logs_email_csv_organisation_path } + render "logs/download_csv", locals: { search_term:, count: unpaginated_filtered_logs.size, post_path: logs_email_csv_organisation_path, codes_only: } end def email_csv - EmailCsvJob.perform_later(current_user, search_term, @session_filters, false, @organisation) + codes_only_export = params.require(:codes_only) == "true" + EmailCsvJob.perform_later(current_user, search_term, @session_filters, false, @organisation, codes_only_export) redirect_to logs_csv_confirmation_organisation_path end diff --git a/app/controllers/start_controller.rb b/app/controllers/start_controller.rb index d09934cbc..d707d3e91 100644 --- a/app/controllers/start_controller.rb +++ b/app/controllers/start_controller.rb @@ -4,4 +4,28 @@ class StartController < ApplicationController redirect_to(lettings_logs_path) end end + + def download_23_24_sales_form + send_file( + Rails.root.join("public/files/2023_24_sales_paper_form.pdf"), + filename: "2023-24 Sales paper form.pdf", + type: "application/pdf", + ) + end + + def download_22_23_sales_form + send_file( + Rails.root.join("public/files/2022_23_sales_paper_form.pdf"), + filename: "2022-23 Sales paper form.pdf", + type: "application/pdf", + ) + end + + def download_23_24_lettings_form + send_file( + Rails.root.join("public/files/2023_24_lettings_paper_form.pdf"), + filename: "2023-24 Lettings paper form.pdf", + type: "application/pdf", + ) + end end diff --git a/app/helpers/check_answers_helper.rb b/app/helpers/check_answers_helper.rb index 66a833859..a29ab98d0 100644 --- a/app/helpers/check_answers_helper.rb +++ b/app/helpers/check_answers_helper.rb @@ -45,4 +45,8 @@ private def get_answer_label(question, lettings_log) question.answer_label(lettings_log, current_user).presence || "You didn’t answer this question".html_safe end + + def get_question_label(question) + [question.question_number_string, question.check_answer_label.to_s.presence || question.header.to_s].compact.join(" - ") + end end diff --git a/app/helpers/locations_helper.rb b/app/helpers/locations_helper.rb index 9b8661221..5c51fc88c 100644 --- a/app/helpers/locations_helper.rb +++ b/app/helpers/locations_helper.rb @@ -14,7 +14,7 @@ module LocationsHelper def local_authorities_selection null_option = [OpenStruct.new(id: "", name: "Select an option")] - null_option + Location.local_authorities.map { |code, name| OpenStruct.new(code:, name:) } + null_option + Location.local_authorities_for_current_year.map { |code, name| OpenStruct.new(code:, name:) } end def selection_options(resource) @@ -27,11 +27,11 @@ module LocationsHelper base_attributes = [ { name: "Postcode", value: location.postcode, attribute: "postcode" }, { name: "Location name", value: location.name, attribute: "name" }, - { name: "Local authority", value: location.location_admin_district, attribute: "local_authority" }, + { name: "Local authority", value: formatted_local_authority_timeline(location, "name"), attribute: "local_authority" }, { name: "Number of units", value: location.units, attribute: "units" }, { name: "Most common unit", value: location.type_of_unit, attribute: "type_of_unit" }, { name: "Mobility standards", value: location.mobility_type, attribute: "mobility_standards" }, - { name: "Location code", value: location.location_code, attribute: "location_code" }, + { name: "Location code", value: formatted_local_authority_timeline(location, "code"), attribute: "location_code" }, { name: "Availability", value: location_availability(location), attribute: "availability" }, ] @@ -46,7 +46,7 @@ module LocationsHelper [ { name: "Postcode", value: location.postcode, attribute: "postcode" }, { name: "Location name", value: location.name, attribute: "name" }, - { name: "Local authority", value: location.location_admin_district, attribute: "local_authority" }, + { name: "Local authority", value: formatted_local_authority_timeline(location, "name"), attribute: "local_authority" }, { name: "Number of units", value: location.units, attribute: "units" }, { name: "Most common unit", value: location.type_of_unit, attribute: "type_of_unit" }, { name: "Mobility standards", value: location.mobility_type, attribute: "mobility_standards" }, @@ -107,4 +107,15 @@ private [inner.deactivation_date, inner.reactivation_date].all? { |date| date.between?(outer.deactivation_date, outer.reactivation_date) } end + + def formatted_local_authority_timeline(location, field) + sorted_linked_authorities = location.linked_local_authorities.sort_by(&:start_date) + return sorted_linked_authorities.first[field] if sorted_linked_authorities.count == 1 + + sorted_linked_authorities.map { |linked_local_authority| + formatted_start_date = linked_local_authority.start_date.year == 2021 ? "until" : "#{linked_local_authority.start_date&.to_formatted_s(:govuk_date)} -" + formatted_end_date = linked_local_authority.end_date&.to_formatted_s(:govuk_date) || "present" + "#{linked_local_authority[field]} (#{formatted_start_date} #{formatted_end_date})" + }.join("\n") + end end diff --git a/app/helpers/logs_helper.rb b/app/helpers/logs_helper.rb index 7653b7e5c..aa132afd6 100644 --- a/app/helpers/logs_helper.rb +++ b/app/helpers/logs_helper.rb @@ -33,10 +33,9 @@ module LogsHelper end end - def csv_download_url_for_controller(controller) - case log_type_for_controller(controller) - when "lettings" - csv_download_lettings_logs_path(search: params["search"]) + def csv_download_url_for_controller(controller_type:, search:, codes_only:) + case log_type_for_controller(controller_type) + when "lettings" then csv_download_lettings_logs_path(search:, codes_only:) end end end diff --git a/app/helpers/question_view_helper.rb b/app/helpers/question_view_helper.rb index fc308b835..3ff84bc19 100644 --- a/app/helpers/question_view_helper.rb +++ b/app/helpers/question_view_helper.rb @@ -7,15 +7,17 @@ module QuestionViewHelper def legend(question, page_header, conditional) { - text: question.header.html_safe, - size: label_size(page_header, conditional), + text: [question.question_number_string(conditional:), question.header.html_safe].compact.join(" - "), + size: label_size(page_header, conditional, question), tag: label_tag(page_header, conditional), } end private - def label_size(page_header, conditional) + def label_size(page_header, conditional, question) + return if question.plain_label.present? + page_header.blank? && !conditional ? "l" : "m" end diff --git a/app/jobs/email_csv_job.rb b/app/jobs/email_csv_job.rb index c7009645f..6e7888f18 100644 --- a/app/jobs/email_csv_job.rb +++ b/app/jobs/email_csv_job.rb @@ -5,14 +5,14 @@ class EmailCsvJob < ApplicationJob EXPIRATION_TIME = 3.hours.to_i - def perform(user, search_term = nil, filters = {}, all_orgs = false, organisation = nil) # rubocop:disable Style/OptionalBooleanParameter - sidekiq can't serialise named params + def perform(user, search_term = nil, filters = {}, all_orgs = false, organisation = nil, codes_only_export = false) # rubocop:disable Style/OptionalBooleanParameter - sidekiq can't serialise named params unfiltered_logs = organisation.present? && user.support? ? LettingsLog.where(owning_organisation_id: organisation.id) : user.lettings_logs filtered_logs = FilterService.filter_logs(unfiltered_logs, search_term, filters, all_orgs, user) filename = organisation.present? ? "logs-#{organisation.name}-#{Time.zone.now}.csv" : "logs-#{Time.zone.now}.csv" storage_service = Storage::S3Service.new(Configuration::EnvConfigurationService.new, ENV["CSV_DOWNLOAD_PAAS_INSTANCE"]) - storage_service.write_file(filename, BYTE_ORDER_MARK + filtered_logs.to_csv(user)) + storage_service.write_file(filename, BYTE_ORDER_MARK + filtered_logs.to_csv(user, codes_only_export:)) url = storage_service.get_presigned_url(filename, EXPIRATION_TIME) diff --git a/app/mailers/bulk_upload_mailer.rb b/app/mailers/bulk_upload_mailer.rb index fe1e81517..144acb3e1 100644 --- a/app/mailers/bulk_upload_mailer.rb +++ b/app/mailers/bulk_upload_mailer.rb @@ -26,7 +26,7 @@ class BulkUploadMailer < NotifyMailer { title:, filename: bulk_upload.filename, - upload_timestamp: bulk_upload.created_at, + upload_timestamp: bulk_upload.created_at.to_fs(:govuk_date_and_time), success_description:, logs_link: url, }, @@ -73,11 +73,7 @@ class BulkUploadMailer < NotifyMailer start_bulk_upload_sales_logs_url end - validator_class = if bulk_upload.lettings? - BulkUpload::Lettings::Validator - else - BulkUpload::Sales::Validator - end + row_parser_class = bulk_upload.prefix_namespace::RowParser errors = bulk_upload .bulk_upload_errors @@ -87,7 +83,7 @@ class BulkUploadMailer < NotifyMailer .keys .sort_by { |_col, field| field } .map do |col, field| - "- Column #{col} (#{validator_class.question_for_field(field.to_sym)})" + "- #{row_parser_class.question_for_field(field.to_sym)} (Column #{col})" end send_email( @@ -104,7 +100,7 @@ class BulkUploadMailer < NotifyMailer ) end - def send_bulk_upload_failed_service_error_mail(bulk_upload:) + def send_bulk_upload_failed_service_error_mail(bulk_upload:, errors: []) bulk_upload_link = if bulk_upload.lettings? start_bulk_upload_lettings_logs_url else @@ -116,9 +112,10 @@ class BulkUploadMailer < NotifyMailer BULK_UPLOAD_FAILED_SERVICE_ERROR_TEMPLATE_ID, { filename: bulk_upload.filename, - upload_timestamp: bulk_upload.created_at, + upload_timestamp: bulk_upload.created_at.to_fs(:govuk_date_and_time), lettings_or_sales: bulk_upload.log_type, year_combo: bulk_upload.year_combo, + errors: errors.map { |e| "- #{e}" }.join("\n"), bulk_upload_link:, }, ) diff --git a/app/models/bulk_upload.rb b/app/models/bulk_upload.rb index 0adf0d84a..ff334b968 100644 --- a/app/models/bulk_upload.rb +++ b/app/models/bulk_upload.rb @@ -46,6 +46,28 @@ class BulkUpload < ApplicationRecord needstype == 2 end + def prefix_namespace + type_class = case log_type + when "lettings" + "Lettings" + when "sales" + "Sales" + else + raise "unknown log type" + end + + year_class = case year + when 2022 + "Year2022" + when 2023 + "Year2023" + else + raise "unknown year" + end + + "BulkUpload::#{type_class}::#{year_class}".constantize + end + private def generate_identifier diff --git a/app/models/derived_variables/sales_log_variables.rb b/app/models/derived_variables/sales_log_variables.rb index 525c12936..56d687f59 100644 --- a/app/models/derived_variables/sales_log_variables.rb +++ b/app/models/derived_variables/sales_log_variables.rb @@ -23,6 +23,15 @@ module DerivedVariables::SalesLogVariables self.totadult = total_adult + total_elder self.hhmemb = number_of_household_members self.hhtype = household_type + + if uprn_known&.zero? + self.uprn = nil + end + + if uprn_confirmed&.zero? + self.uprn = nil + self.uprn_known = 0 + end end private diff --git a/app/models/form.rb b/app/models/form.rb index f9959959e..c7bb4f2b0 100644 --- a/app/models/form.rb +++ b/app/models/form.rb @@ -160,7 +160,7 @@ class Form def invalidated_page_questions(log, current_user = nil) # we're already treating these fields as a special case and reset their values upon saving a log - callback_questions = %w[postcode_known la ppcodenk previous_la_known prevloc postcode_full ppostcode_full location_id] + callback_questions = %w[postcode_known la ppcodenk previous_la_known prevloc postcode_full ppostcode_full location_id address_line1 address_line2 town_or_city county] questions.reject { |q| q.page.routed_to?(log, current_user) || q.derived? || callback_questions.include?(q.id) } || [] end diff --git a/app/models/form/lettings/pages/lead_tenant_nationality.rb b/app/models/form/lettings/pages/lead_tenant_nationality.rb index ae67b1e32..09a25286c 100644 --- a/app/models/form/lettings/pages/lead_tenant_nationality.rb +++ b/app/models/form/lettings/pages/lead_tenant_nationality.rb @@ -6,6 +6,6 @@ class Form::Lettings::Pages::LeadTenantNationality < ::Form::Page end def questions - @questions ||= [Form::Lettings::Questions::National.new(nil, nil, self)] + @questions ||= [Form::Lettings::Questions::Nationality.new(nil, nil, self)] end end diff --git a/app/models/form/lettings/pages/max_rent_value_check.rb b/app/models/form/lettings/pages/max_rent_value_check.rb index 88d0561bf..59b2d14fe 100644 --- a/app/models/form/lettings/pages/max_rent_value_check.rb +++ b/app/models/form/lettings/pages/max_rent_value_check.rb @@ -4,11 +4,11 @@ class Form::Lettings::Pages::MaxRentValueCheck < ::Form::Page @id = "max_rent_value_check" @depends_on = [{ "rent_in_soft_max_range?" => true }] @title_text = { - "translation" => "soft_validations.rent.max.title_text", + "translation" => "soft_validations.rent.outside_range_title", "arguments" => [{ "key" => "brent", "label" => true, "i18n_template" => "brent" }], } @informative_text = { - "translation" => "soft_validations.rent.max.hint_text", + "translation" => "soft_validations.rent.max_hint_text", "arguments" => [ { "key" => "soft_max_for_period", diff --git a/app/models/form/lettings/pages/min_rent_value_check.rb b/app/models/form/lettings/pages/min_rent_value_check.rb index 3bcb95789..ed5ede781 100644 --- a/app/models/form/lettings/pages/min_rent_value_check.rb +++ b/app/models/form/lettings/pages/min_rent_value_check.rb @@ -4,11 +4,11 @@ class Form::Lettings::Pages::MinRentValueCheck < ::Form::Page @id = "min_rent_value_check" @depends_on = [{ "rent_in_soft_min_range?" => true }] @title_text = { - "translation" => "soft_validations.rent.min.title_text", + "translation" => "soft_validations.rent.outside_range_title", "arguments" => [{ "key" => "brent", "label" => true, "i18n_template" => "brent" }], } @informative_text = { - "translation" => "soft_validations.rent.min.hint_text", + "translation" => "soft_validations.rent.min_hint_text", "arguments" => [ { "key" => "soft_min_for_period", diff --git a/app/models/form/lettings/pages/person_age.rb b/app/models/form/lettings/pages/person_age.rb index 66f7d3d89..bbb5da01e 100644 --- a/app/models/form/lettings/pages/person_age.rb +++ b/app/models/form/lettings/pages/person_age.rb @@ -1,15 +1,21 @@ class Form::Lettings::Pages::PersonAge < ::Form::Page - def initialize(id, hsh, subsection, person_index:) + def initialize(id, hsh, subsection, person_index:, person_type: "non_child") super(id, hsh, subsection) - @id = "person_#{person_index}_age" - @depends_on = [{ "details_known_#{person_index}" => 0 }] + @id = "person_#{person_index}_age_#{person_type}" @person_index = person_index + @person_type = person_type + @depends_on = [ + { + "details_known_#{person_index}" => 0, + "person_#{person_index}_child_relation?" => (person_type == "child"), + }, + ] end def questions @questions ||= [ Form::Lettings::Questions::AgeKnown.new(nil, nil, self, person_index: @person_index), - Form::Lettings::Questions::Age.new(nil, nil, self, person_index: @person_index), + Form::Lettings::Questions::Age.new(nil, nil, self, person_index: @person_index, person_type: @person_type), ] end end diff --git a/app/models/form/lettings/pages/previous_housing_situation.rb b/app/models/form/lettings/pages/previous_housing_situation.rb index 82bbda675..aafabe7f3 100644 --- a/app/models/form/lettings/pages/previous_housing_situation.rb +++ b/app/models/form/lettings/pages/previous_housing_situation.rb @@ -2,10 +2,10 @@ class Form::Lettings::Pages::PreviousHousingSituation < ::Form::Page def initialize(id, hsh, subsection) super @id = "previous_housing_situation" - @depends_on = [{ "renewal" => 0 }] + @depends_on = [{ "is_renewal?" => false }] end def questions - @questions ||= [Form::Lettings::Questions::Prevten.new(nil, nil, self)] + @questions ||= [Form::Lettings::Questions::PreviousTenure.new(nil, nil, self)] end end diff --git a/app/models/form/lettings/pages/previous_housing_situation_renewal.rb b/app/models/form/lettings/pages/previous_housing_situation_renewal.rb index 7f22150bf..317350911 100644 --- a/app/models/form/lettings/pages/previous_housing_situation_renewal.rb +++ b/app/models/form/lettings/pages/previous_housing_situation_renewal.rb @@ -2,10 +2,10 @@ class Form::Lettings::Pages::PreviousHousingSituationRenewal < ::Form::Page def initialize(id, hsh, subsection) super @id = "previous_housing_situation_renewal" - @depends_on = [{ "renewal" => 1, "needstype" => 2 }] + @depends_on = [{ "is_renewal?" => true, "is_supported_housing?" => true }] end def questions - @questions ||= [Form::Lettings::Questions::PrevtenRenewal.new(nil, nil, self)] + @questions ||= [Form::Lettings::Questions::PreviousTenureRenewal.new(nil, nil, self)] end end diff --git a/app/models/form/lettings/pages/property_let_type.rb b/app/models/form/lettings/pages/property_let_type.rb index 1f31af370..f4d629b9e 100644 --- a/app/models/form/lettings/pages/property_let_type.rb +++ b/app/models/form/lettings/pages/property_let_type.rb @@ -6,6 +6,6 @@ class Form::Lettings::Pages::PropertyLetType < ::Form::Page end def questions - @questions ||= [Form::Lettings::Questions::Unitletas.new(nil, nil, self)] + @questions ||= [Form::Lettings::Questions::PreviousLetType.new(nil, nil, self)] end end diff --git a/app/models/form/lettings/pages/shelteredaccom.rb b/app/models/form/lettings/pages/sheltered_accommodation.rb similarity index 50% rename from app/models/form/lettings/pages/shelteredaccom.rb rename to app/models/form/lettings/pages/sheltered_accommodation.rb index df19b8c99..096ba61e5 100644 --- a/app/models/form/lettings/pages/shelteredaccom.rb +++ b/app/models/form/lettings/pages/sheltered_accommodation.rb @@ -1,8 +1,8 @@ -class Form::Lettings::Pages::Shelteredaccom < ::Form::Page +class Form::Lettings::Pages::ShelteredAccommodation < ::Form::Page def initialize(id, hsh, subsection) super - @id = "shelteredaccom" - @depends_on = [{ "needstype" => 2 }] + @id = "sheltered_accommodation" + @depends_on = [{ "is_supported_housing?" => true }] end def questions diff --git a/app/models/form/lettings/pages/starter_tenancy_type.rb b/app/models/form/lettings/pages/starter_tenancy_type.rb index c488b7b17..fe147bc77 100644 --- a/app/models/form/lettings/pages/starter_tenancy_type.rb +++ b/app/models/form/lettings/pages/starter_tenancy_type.rb @@ -2,13 +2,13 @@ class Form::Lettings::Pages::StarterTenancyType < ::Form::Page def initialize(id, hsh, subsection) super @id = "starter_tenancy_type" - @depends_on = [{ "startertenancy" => 1 }] + @depends_on = [{ "starter_tenancy?" => true }] end def questions @questions ||= [ - Form::Lettings::Questions::StarterTenancy.new(nil, nil, self), - Form::Lettings::Questions::Tenancyother.new(nil, nil, self), + Form::Lettings::Questions::StarterTenancyType.new(nil, nil, self), + Form::Lettings::Questions::TenancyOther.new(nil, nil, self), ] end end diff --git a/app/models/form/lettings/pages/tenancy_length.rb b/app/models/form/lettings/pages/tenancy_length.rb index 943ea2bc9..cb533dcf9 100644 --- a/app/models/form/lettings/pages/tenancy_length.rb +++ b/app/models/form/lettings/pages/tenancy_length.rb @@ -2,10 +2,10 @@ class Form::Lettings::Pages::TenancyLength < ::Form::Page def initialize(id, hsh, subsection) super @id = "tenancy_length" - @depends_on = [{ "tenancy" => 4 }, { "tenancy" => 6 }, { "tenancy" => 3 }] + @depends_on = [{ "tenancy_type_fixed_term?" => true }] end def questions - @questions ||= [Form::Lettings::Questions::Tenancylength.new(nil, nil, self)] + @questions ||= [Form::Lettings::Questions::TenancyLength.new(nil, nil, self)] end end diff --git a/app/models/form/lettings/pages/tenancy_type.rb b/app/models/form/lettings/pages/tenancy_type.rb index 8ee6c3bbc..c15f6f27a 100644 --- a/app/models/form/lettings/pages/tenancy_type.rb +++ b/app/models/form/lettings/pages/tenancy_type.rb @@ -2,13 +2,13 @@ class Form::Lettings::Pages::TenancyType < ::Form::Page def initialize(id, hsh, subsection) super @id = "tenancy_type" - @depends_on = [{ "startertenancy" => 2 }] + @depends_on = [{ "starter_tenancy?" => false }] end def questions @questions ||= [ - Form::Lettings::Questions::Tenancy.new(nil, nil, self), - Form::Lettings::Questions::Tenancyother.new(nil, nil, self), + Form::Lettings::Questions::TenancyType.new(nil, nil, self), + Form::Lettings::Questions::TenancyOther.new(nil, nil, self), ] end end diff --git a/app/models/form/lettings/questions/age.rb b/app/models/form/lettings/questions/age.rb index f160f1948..6b76a6945 100644 --- a/app/models/form/lettings/questions/age.rb +++ b/app/models/form/lettings/questions/age.rb @@ -1,5 +1,5 @@ class Form::Lettings::Questions::Age < ::Form::Question - def initialize(id, hsh, page, person_index:) + def initialize(id, hsh, page, person_index:, person_type:) super(id, hsh, page) @id = "age#{person_index}" @check_answer_label = "Person #{person_index}’s age" @@ -9,7 +9,9 @@ class Form::Lettings::Questions::Age < ::Form::Question @inferred_check_answers_value = [{ "condition" => { "age#{person_index}_known" => 1 }, "value" => "Not known" }] @check_answers_card_number = person_index @max = 120 - @min = 0 + @min = 1 @step = 1 + @hint_text = "For a child under 1, enter 1" if person_type == "child" + @question_number = 31 + (4 * person_index) end end diff --git a/app/models/form/lettings/questions/age1.rb b/app/models/form/lettings/questions/age1.rb index 24512af28..2f43ac7ab 100644 --- a/app/models/form/lettings/questions/age1.rb +++ b/app/models/form/lettings/questions/age1.rb @@ -11,5 +11,6 @@ class Form::Lettings::Questions::Age1 < ::Form::Question @max = 120 @min = 16 @step = 1 + @question_number = 32 end end diff --git a/app/models/form/lettings/questions/age1_known.rb b/app/models/form/lettings/questions/age1_known.rb index d9899eb12..aaf28e68a 100644 --- a/app/models/form/lettings/questions/age1_known.rb +++ b/app/models/form/lettings/questions/age1_known.rb @@ -10,6 +10,7 @@ class Form::Lettings::Questions::Age1Known < ::Form::Question @answer_options = ANSWER_OPTIONS @conditional_for = { "age1" => [0] } @hidden_in_check_answers = { "depends_on" => [{ "age1_known" => 0 }, { "age1_known" => 1 }] } + @question_number = 32 end ANSWER_OPTIONS = { "0" => { "value" => "Yes" }, "1" => { "value" => "No" } }.freeze diff --git a/app/models/form/lettings/questions/age_known.rb b/app/models/form/lettings/questions/age_known.rb index b7682c769..9f9264e7d 100644 --- a/app/models/form/lettings/questions/age_known.rb +++ b/app/models/form/lettings/questions/age_known.rb @@ -15,6 +15,7 @@ class Form::Lettings::Questions::AgeKnown < ::Form::Question { "age#{person_index}_known" => 1 }, ], } + @question_number = 31 + (4 * person_index) end ANSWER_OPTIONS = { "0" => { "value" => "Yes" }, "1" => { "value" => "No" } }.freeze diff --git a/app/models/form/lettings/questions/armedforces.rb b/app/models/form/lettings/questions/armedforces.rb index b5e34d81d..fb9a02a64 100644 --- a/app/models/form/lettings/questions/armedforces.rb +++ b/app/models/form/lettings/questions/armedforces.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Armedforces < ::Form::Question @check_answers_card_number = 0 @hint_text = "This excludes national service.

If there are several people in the household with links to the UK armed forces, you should answer for the regular. If there’s no regular, answer for the reserve. If there’s no reserve, answer for the spouse or civil partner." @answer_options = ANSWER_OPTIONS + @question_number = 66 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/beds.rb b/app/models/form/lettings/questions/beds.rb index cc3ceb885..75d2a835d 100644 --- a/app/models/form/lettings/questions/beds.rb +++ b/app/models/form/lettings/questions/beds.rb @@ -11,5 +11,6 @@ class Form::Lettings::Questions::Beds < ::Form::Question @min = 0 @hint_text = "If shared accommodation, enter the number of bedrooms occupied by this household. A bedsit has 1 bedroom." @step = 1 + @question_number = 22 end end diff --git a/app/models/form/lettings/questions/benefits.rb b/app/models/form/lettings/questions/benefits.rb index 27f90053d..3d23c50a1 100644 --- a/app/models/form/lettings/questions/benefits.rb +++ b/app/models/form/lettings/questions/benefits.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Benefits < ::Form::Question @check_answers_card_number = 0 @hint_text = "This excludes child and housing benefit, council tax support and tax credits." @answer_options = ANSWER_OPTIONS + @question_number = 90 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/brent_4_weekly.rb b/app/models/form/lettings/questions/brent_4_weekly.rb index c7659dbd4..6649b9a60 100644 --- a/app/models/form/lettings/questions/brent_4_weekly.rb +++ b/app/models/form/lettings/questions/brent_4_weekly.rb @@ -12,8 +12,8 @@ class Form::Lettings::Questions::Brent4Weekly < ::Form::Question @step = 0.01 @fields_to_add = %w[brent scharge pscharge supcharg] @result_field = "tcharge" - @hidden_in_check_answers = true @prefix = "£" @suffix = " every 4 weeks" + @question_number = 95 end end diff --git a/app/models/form/lettings/questions/brent_bi_weekly.rb b/app/models/form/lettings/questions/brent_bi_weekly.rb index 7b1e1d04e..37f1bfa20 100644 --- a/app/models/form/lettings/questions/brent_bi_weekly.rb +++ b/app/models/form/lettings/questions/brent_bi_weekly.rb @@ -12,8 +12,8 @@ class Form::Lettings::Questions::BrentBiWeekly < ::Form::Question @step = 0.01 @fields_to_add = %w[brent scharge pscharge supcharg] @result_field = "tcharge" - @hidden_in_check_answers = true @prefix = "£" @suffix = " every 2 weeks" + @question_number = 95 end end diff --git a/app/models/form/lettings/questions/brent_monthly.rb b/app/models/form/lettings/questions/brent_monthly.rb index c58a21175..e38a490b0 100644 --- a/app/models/form/lettings/questions/brent_monthly.rb +++ b/app/models/form/lettings/questions/brent_monthly.rb @@ -12,8 +12,8 @@ class Form::Lettings::Questions::BrentMonthly < ::Form::Question @step = 0.01 @fields_to_add = %w[brent scharge pscharge supcharg] @result_field = "tcharge" - @hidden_in_check_answers = true @prefix = "£" @suffix = " every month" + @question_number = 95 end end diff --git a/app/models/form/lettings/questions/brent_weekly.rb b/app/models/form/lettings/questions/brent_weekly.rb index 0ea1f5359..7a8adfc7a 100644 --- a/app/models/form/lettings/questions/brent_weekly.rb +++ b/app/models/form/lettings/questions/brent_weekly.rb @@ -12,8 +12,8 @@ class Form::Lettings::Questions::BrentWeekly < ::Form::Question @step = 0.01 @fields_to_add = %w[brent scharge pscharge supcharg] @result_field = "tcharge" - @hidden_in_check_answers = true @prefix = "£" @suffix = " every week" + @question_number = 95 end end diff --git a/app/models/form/lettings/questions/builtype.rb b/app/models/form/lettings/questions/builtype.rb index 087699e0d..9cda5649f 100644 --- a/app/models/form/lettings/questions/builtype.rb +++ b/app/models/form/lettings/questions/builtype.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Builtype < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 20 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/chcharge_4_weekly.rb b/app/models/form/lettings/questions/chcharge_4_weekly.rb index c755a933b..6e0923cc0 100644 --- a/app/models/form/lettings/questions/chcharge_4_weekly.rb +++ b/app/models/form/lettings/questions/chcharge_4_weekly.rb @@ -11,5 +11,6 @@ class Form::Lettings::Questions::Chcharge4Weekly < ::Form::Question @step = 0.01 @prefix = "£" @suffix = " every 4 weeks" + @question_number = 94 end end diff --git a/app/models/form/lettings/questions/chcharge_bi_weekly.rb b/app/models/form/lettings/questions/chcharge_bi_weekly.rb index e65dc59a1..273ec7ac0 100644 --- a/app/models/form/lettings/questions/chcharge_bi_weekly.rb +++ b/app/models/form/lettings/questions/chcharge_bi_weekly.rb @@ -11,5 +11,6 @@ class Form::Lettings::Questions::ChchargeBiWeekly < ::Form::Question @step = 0.01 @prefix = "£" @suffix = " every 2 weeks" + @question_number = 94 end end diff --git a/app/models/form/lettings/questions/chcharge_monthly.rb b/app/models/form/lettings/questions/chcharge_monthly.rb index f0bc7bb82..ab2da34ad 100644 --- a/app/models/form/lettings/questions/chcharge_monthly.rb +++ b/app/models/form/lettings/questions/chcharge_monthly.rb @@ -11,5 +11,6 @@ class Form::Lettings::Questions::ChchargeMonthly < ::Form::Question @step = 0.01 @prefix = "£" @suffix = " every month" + @question_number = 94 end end diff --git a/app/models/form/lettings/questions/chcharge_weekly.rb b/app/models/form/lettings/questions/chcharge_weekly.rb index 874259215..96b8de324 100644 --- a/app/models/form/lettings/questions/chcharge_weekly.rb +++ b/app/models/form/lettings/questions/chcharge_weekly.rb @@ -11,5 +11,6 @@ class Form::Lettings::Questions::ChchargeWeekly < ::Form::Question @step = 0.01 @prefix = "£" @suffix = " every week" + @question_number = 94 end end diff --git a/app/models/form/lettings/questions/condition_effects.rb b/app/models/form/lettings/questions/condition_effects.rb index f89cfb3f2..c8240f232 100644 --- a/app/models/form/lettings/questions/condition_effects.rb +++ b/app/models/form/lettings/questions/condition_effects.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::ConditionEffects < ::Form::Question @check_answers_card_number = 0 @hint_text = "Select all that apply." @answer_options = ANSWER_OPTIONS + @question_number = 74 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/declaration.rb b/app/models/form/lettings/questions/declaration.rb index a342fba6d..742545b96 100644 --- a/app/models/form/lettings/questions/declaration.rb +++ b/app/models/form/lettings/questions/declaration.rb @@ -3,11 +3,12 @@ class Form::Lettings::Questions::Declaration < ::Form::Question super @id = "declaration" @check_answer_label = "Tenant has seen the privacy notice" - @header = "" + @header = "Declaration" @type = "checkbox" @check_answers_card_number = 0 @guidance_partial = "privacy_notice_tenant" @answer_options = ANSWER_OPTIONS + @question_number = 30 end ANSWER_OPTIONS = { "declaration" => { "value" => "The tenant has seen the DLUHC privacy notice" } }.freeze diff --git a/app/models/form/lettings/questions/earnings.rb b/app/models/form/lettings/questions/earnings.rb index 2647d0179..445710f09 100644 --- a/app/models/form/lettings/questions/earnings.rb +++ b/app/models/form/lettings/questions/earnings.rb @@ -17,5 +17,6 @@ class Form::Lettings::Questions::Earnings < ::Form::Question { "label" => " every month", "depends_on" => { "incfreq" => 2 } }, { "label" => " every year", "depends_on" => { "incfreq" => 3 } }, ] + @question_number = 88 end end diff --git a/app/models/form/lettings/questions/ethnic_arab.rb b/app/models/form/lettings/questions/ethnic_arab.rb index 28b3591da..9884b69f0 100644 --- a/app/models/form/lettings/questions/ethnic_arab.rb +++ b/app/models/form/lettings/questions/ethnic_arab.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::EthnicArab < ::Form::Question @check_answers_card_number = 1 @hint_text = "The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest." @answer_options = ANSWER_OPTIONS + @question_number = 35 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/ethnic_asian.rb b/app/models/form/lettings/questions/ethnic_asian.rb index 96b8df9b5..17aa29d44 100644 --- a/app/models/form/lettings/questions/ethnic_asian.rb +++ b/app/models/form/lettings/questions/ethnic_asian.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::EthnicAsian < ::Form::Question @check_answers_card_number = 1 @hint_text = "The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest." @answer_options = ANSWER_OPTIONS + @question_number = 35 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/ethnic_black.rb b/app/models/form/lettings/questions/ethnic_black.rb index 68beca8ad..c6f0c81d5 100644 --- a/app/models/form/lettings/questions/ethnic_black.rb +++ b/app/models/form/lettings/questions/ethnic_black.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::EthnicBlack < ::Form::Question @check_answers_card_number = 1 @hint_text = "The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest." @answer_options = ANSWER_OPTIONS + @question_number = 35 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/ethnic_group.rb b/app/models/form/lettings/questions/ethnic_group.rb index 4f7364296..f9e392089 100644 --- a/app/models/form/lettings/questions/ethnic_group.rb +++ b/app/models/form/lettings/questions/ethnic_group.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::EthnicGroup < ::Form::Question @check_answers_card_number = 1 @hint_text = "The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest." @answer_options = ANSWER_OPTIONS + @question_number = 34 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/ethnic_mixed.rb b/app/models/form/lettings/questions/ethnic_mixed.rb index 6160e40a5..ac059837d 100644 --- a/app/models/form/lettings/questions/ethnic_mixed.rb +++ b/app/models/form/lettings/questions/ethnic_mixed.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::EthnicMixed < ::Form::Question @check_answers_card_number = 1 @hint_text = "The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest." @answer_options = ANSWER_OPTIONS + @question_number = 35 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/ethnic_white.rb b/app/models/form/lettings/questions/ethnic_white.rb index 993237a44..707330175 100644 --- a/app/models/form/lettings/questions/ethnic_white.rb +++ b/app/models/form/lettings/questions/ethnic_white.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::EthnicWhite < ::Form::Question @check_answers_card_number = 1 @hint_text = "The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest." @answer_options = ANSWER_OPTIONS + @question_number = 35 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/first_time_property_let_as_social_housing.rb b/app/models/form/lettings/questions/first_time_property_let_as_social_housing.rb index 62f0bba19..132eca0c2 100644 --- a/app/models/form/lettings/questions/first_time_property_let_as_social_housing.rb +++ b/app/models/form/lettings/questions/first_time_property_let_as_social_housing.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::FirstTimePropertyLetAsSocialHousing < ::Form::Q @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 14 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/gender_identity1.rb b/app/models/form/lettings/questions/gender_identity1.rb index 2f5c8f45e..769dc1850 100644 --- a/app/models/form/lettings/questions/gender_identity1.rb +++ b/app/models/form/lettings/questions/gender_identity1.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::GenderIdentity1 < ::Form::Question @check_answers_card_number = 1 @hint_text = "The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest." @answer_options = ANSWER_OPTIONS + @question_number = 33 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/hb.rb b/app/models/form/lettings/questions/hb.rb index e8da0e146..68dfc987b 100644 --- a/app/models/form/lettings/questions/hb.rb +++ b/app/models/form/lettings/questions/hb.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Hb < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 89 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/hbrentshortfall.rb b/app/models/form/lettings/questions/hbrentshortfall.rb index 687ac3aeb..828c36377 100644 --- a/app/models/form/lettings/questions/hbrentshortfall.rb +++ b/app/models/form/lettings/questions/hbrentshortfall.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Hbrentshortfall < ::Form::Question @check_answers_card_number = 0 @hint_text = "Also known as the ‘outstanding amount’." @answer_options = ANSWER_OPTIONS + @question_number = 99 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/hhmemb.rb b/app/models/form/lettings/questions/hhmemb.rb index 3c6e6c3af..fee0aced3 100644 --- a/app/models/form/lettings/questions/hhmemb.rb +++ b/app/models/form/lettings/questions/hhmemb.rb @@ -11,5 +11,6 @@ class Form::Lettings::Questions::Hhmemb < ::Form::Question @min = 1 @hint_text = "You can provide details for a maximum of 8 people." @step = 1 + @question_number = 31 end end diff --git a/app/models/form/lettings/questions/homeless.rb b/app/models/form/lettings/questions/homeless.rb index fcfc117d2..21a597a00 100644 --- a/app/models/form/lettings/questions/homeless.rb +++ b/app/models/form/lettings/questions/homeless.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Homeless < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 79 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/household_charge.rb b/app/models/form/lettings/questions/household_charge.rb index 1a8ade65a..da77cb361 100644 --- a/app/models/form/lettings/questions/household_charge.rb +++ b/app/models/form/lettings/questions/household_charge.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::HouseholdCharge < ::Form::Question @check_answers_card_number = 0 @hint_text = "If rent is charged on the property then answer Yes to this question, even if the tenants do not pay it themselves." @answer_options = ANSWER_OPTIONS + @question_number = 91 end ANSWER_OPTIONS = { "0" => { "value" => "Yes" }, "1" => { "value" => "No" } }.freeze diff --git a/app/models/form/lettings/questions/housingneeds.rb b/app/models/form/lettings/questions/housingneeds.rb index cd8a3275d..5b6775eec 100644 --- a/app/models/form/lettings/questions/housingneeds.rb +++ b/app/models/form/lettings/questions/housingneeds.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Housingneeds < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 70 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/housingneeds_other.rb b/app/models/form/lettings/questions/housingneeds_other.rb index 18d544ca9..fd1b463a0 100644 --- a/app/models/form/lettings/questions/housingneeds_other.rb +++ b/app/models/form/lettings/questions/housingneeds_other.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::HousingneedsOther < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 72 end ANSWER_OPTIONS = { "1" => { "value" => "Yes" }, "0" => { "value" => "No" } }.freeze diff --git a/app/models/form/lettings/questions/housingneeds_type.rb b/app/models/form/lettings/questions/housingneeds_type.rb index a06f28705..49a03e73d 100644 --- a/app/models/form/lettings/questions/housingneeds_type.rb +++ b/app/models/form/lettings/questions/housingneeds_type.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::HousingneedsType < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 71 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/illness.rb b/app/models/form/lettings/questions/illness.rb index d2a3b09dd..6a54c6a46 100644 --- a/app/models/form/lettings/questions/illness.rb +++ b/app/models/form/lettings/questions/illness.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Illness < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 73 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/incfreq.rb b/app/models/form/lettings/questions/incfreq.rb index 0d347c0da..c31f23fd5 100644 --- a/app/models/form/lettings/questions/incfreq.rb +++ b/app/models/form/lettings/questions/incfreq.rb @@ -9,6 +9,7 @@ class Form::Lettings::Questions::Incfreq < ::Form::Question @hint_text = "" @answer_options = ANSWER_OPTIONS @hidden_in_check_answers = true + @question_number = 87 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/irproduct_other.rb b/app/models/form/lettings/questions/irproduct_other.rb index 99945ceea..be21c3d27 100644 --- a/app/models/form/lettings/questions/irproduct_other.rb +++ b/app/models/form/lettings/questions/irproduct_other.rb @@ -5,5 +5,6 @@ class Form::Lettings::Questions::IrproductOther < ::Form::Question @check_answer_label = "Product name" @header = "Name of rent product" @type = "text" + @question_number = 6 end end diff --git a/app/models/form/lettings/questions/is_carehome.rb b/app/models/form/lettings/questions/is_carehome.rb index 6f17acc0d..9011d35bb 100644 --- a/app/models/form/lettings/questions/is_carehome.rb +++ b/app/models/form/lettings/questions/is_carehome.rb @@ -9,6 +9,7 @@ class Form::Lettings::Questions::IsCarehome < ::Form::Question @hint_text = "" @answer_options = ANSWER_OPTIONS @conditional_for = { "chcharge" => [1] } + @question_number = 93 end ANSWER_OPTIONS = { "0" => { "value" => "No" }, "1" => { "value" => "Yes" } }.freeze diff --git a/app/models/form/lettings/questions/joint.rb b/app/models/form/lettings/questions/joint.rb index 484678f2b..7b1d9c2c9 100644 --- a/app/models/form/lettings/questions/joint.rb +++ b/app/models/form/lettings/questions/joint.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Joint < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 25 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/la.rb b/app/models/form/lettings/questions/la.rb index a25bdac10..3cafda054 100644 --- a/app/models/form/lettings/questions/la.rb +++ b/app/models/form/lettings/questions/la.rb @@ -3,330 +3,14 @@ class Form::Lettings::Questions::La < ::Form::Question super @id = "la" @check_answer_label = "Local Authority" - @header = "What is the local authority of the property?" + @header = "What is the property’s local authority?" @type = "select" @check_answers_card_number = 0 @hint_text = "" - @answer_options = ANSWER_OPTIONS + @question_number = 13 end - ANSWER_OPTIONS = { - "" => "Select an option", - "E07000223" => "Adur", - "E07000026" => "Allerdale", - "E07000032" => "Amber Valley", - "E07000224" => "Arun", - "E07000170" => "Ashfield", - "E07000105" => "Ashford", - "E07000200" => "Babergh", - "E09000002" => "Barking and Dagenham", - "E09000003" => "Barnet", - "E08000016" => "Barnsley", - "E07000027" => "Barrow-in-Furness", - "E07000066" => "Basildon", - "E07000084" => "Basingstoke and Deane", - "E07000171" => "Bassetlaw", - "E06000022" => "Bath and North East Somerset", - "E06000055" => "Bedford", - "E09000004" => "Bexley", - "E08000025" => "Birmingham", - "E07000129" => "Blaby", - "E06000008" => "Blackburn with Darwen", - "E06000009" => "Blackpool", - "E07000033" => "Bolsover", - "E08000001" => "Bolton", - "E07000136" => "Boston", - "E06000058" => "Bournemouth, Christchurch and Poole", - "E06000036" => "Bracknell Forest", - "E08000032" => "Bradford", - "E07000067" => "Braintree", - "E07000143" => "Breckland", - "E09000005" => "Brent", - "E07000068" => "Brentwood", - "E06000043" => "Brighton and Hove", - "E06000023" => "Bristol, City of", - "E07000144" => "Broadland", - "E09000006" => "Bromley", - "E07000234" => "Bromsgrove", - "E07000095" => "Broxbourne", - "E07000172" => "Broxtowe", - "E06000060" => "Buckinghamshire", - "E07000117" => "Burnley", - "E08000002" => "Bury", - "E08000033" => "Calderdale", - "E07000008" => "Cambridge", - "E09000007" => "Camden", - "E07000192" => "Cannock Chase", - "E07000106" => "Canterbury", - "E07000028" => "Carlisle", - "E07000069" => "Castle Point", - "E06000056" => "Central Bedfordshire", - "E07000130" => "Charnwood", - "E07000070" => "Chelmsford", - "E07000078" => "Cheltenham", - "E07000177" => "Cherwell", - "E06000049" => "Cheshire East", - "E06000050" => "Cheshire West and Chester", - "E07000034" => "Chesterfield", - "E07000225" => "Chichester", - "E07000118" => "Chorley", - "E09000001" => "City of London", - "E07000071" => "Colchester", - "E07000029" => "Copeland", - "E07000150" => "Corby", - "E06000052" => "Cornwall", - "E07000079" => "Cotswold", - "E06000047" => "County Durham", - "E08000026" => "Coventry", - "E07000163" => "Craven", - "E07000226" => "Crawley", - "E09000008" => "Croydon", - "E07000096" => "Dacorum", - "E06000005" => "Darlington", - "E07000107" => "Dartford", - "E07000151" => "Daventry", - "E06000015" => "Derby", - "E07000035" => "Derbyshire Dales", - "E08000017" => "Doncaster", - "E06000059" => "Dorset", - "E07000108" => "Dover", - "E08000027" => "Dudley", - "E09000009" => "Ealing", - "E07000009" => "East Cambridgeshire", - "E07000040" => "East Devon", - "E07000085" => "East Hampshire", - "E07000242" => "East Hertfordshire", - "E07000137" => "East Lindsey", - "E07000152" => "East Northamptonshire", - "E06000011" => "East Riding of Yorkshire", - "E07000193" => "East Staffordshire", - "E07000244" => "East Suffolk", - "E07000061" => "Eastbourne", - "E07000086" => "Eastleigh", - "E07000030" => "Eden", - "E07000207" => "Elmbridge", - "E09000010" => "Enfield", - "E07000072" => "Epping Forest", - "E07000208" => "Epsom and Ewell", - "E07000036" => "Erewash", - "E07000041" => "Exeter", - "E07000087" => "Fareham", - "E07000010" => "Fenland", - "E07000112" => "Folkestone and Hythe", - "E07000080" => "Forest of Dean", - "E07000119" => "Fylde", - "E08000037" => "Gateshead", - "E07000173" => "Gedling", - "E07000081" => "Gloucester", - "E07000088" => "Gosport", - "E07000109" => "Gravesham", - "E07000145" => "Great Yarmouth", - "E09000011" => "Greenwich", - "E07000209" => "Guildford", - "W06000002" => "Gwynedd", - "E09000012" => "Hackney", - "E06000006" => "Halton", - "E07000164" => "Hambleton", - "E09000013" => "Hammersmith and Fulham", - "E07000131" => "Harborough", - "E09000014" => "Haringey", - "E07000073" => "Harlow", - "E07000165" => "Harrogate", - "E09000015" => "Harrow", - "E07000089" => "Hart", - "E06000001" => "Hartlepool", - "E07000062" => "Hastings", - "E07000090" => "Havant", - "E09000016" => "Havering", - "E06000019" => "Herefordshire, County of", - "E07000098" => "Hertsmere", - "E07000037" => "High Peak", - "S12000017" => "Highland", - "E09000017" => "Hillingdon", - "E07000132" => "Hinckley and Bosworth", - "E07000227" => "Horsham", - "E09000018" => "Hounslow", - "E07000011" => "Huntingdonshire", - "E07000120" => "Hyndburn", - "E07000202" => "Ipswich", - "E06000046" => "Isle of Wight", - "E06000053" => "Isles of Scilly", - "E09000019" => "Islington", - "E09000020" => "Kensington and Chelsea", - "E07000153" => "Kettering", - "E07000146" => "King’s Lynn and West Norfolk", - "E06000010" => "Kingston upon Hull, City of", - "E09000021" => "Kingston upon Thames", - "E08000034" => "Kirklees", - "E08000011" => "Knowsley", - "E09000022" => "Lambeth", - "E07000121" => "Lancaster", - "E08000035" => "Leeds", - "E06000016" => "Leicester", - "E07000063" => "Lewes", - "E09000023" => "Lewisham", - "E07000194" => "Lichfield", - "E07000138" => "Lincoln", - "E08000012" => "Liverpool", - "E06000032" => "Luton", - "E07000110" => "Maidstone", - "E07000074" => "Maldon", - "E07000235" => "Malvern Hills", - "E08000003" => "Manchester", - "E07000174" => "Mansfield", - "E06000035" => "Medway", - "E07000133" => "Melton", - "E07000187" => "Mendip", - "E09000024" => "Merton", - "E07000042" => "Mid Devon", - "E07000203" => "Mid Suffolk", - "E07000228" => "Mid Sussex", - "E06000002" => "Middlesbrough", - "E06000042" => "Milton Keynes", - "E07000210" => "Mole Valley", - "E07000091" => "New Forest", - "E07000175" => "Newark and Sherwood", - "E08000021" => "Newcastle upon Tyne", - "E07000195" => "Newcastle-under-Lyme", - "E09000025" => "Newham", - "E07000043" => "North Devon", - "E07000038" => "North East Derbyshire", - "E06000012" => "North East Lincolnshire", - "E07000099" => "North Hertfordshire", - "E07000139" => "North Kesteven", - "E06000013" => "North Lincolnshire", - "E07000147" => "North Norfolk", - "E06000024" => "North Somerset", - "E08000022" => "North Tyneside", - "E07000218" => "North Warwickshire", - "E07000134" => "North West Leicestershire", - "E07000154" => "Northampton", - "E06000057" => "Northumberland", - "E07000148" => "Norwich", - "E06000018" => "Nottingham", - "E07000219" => "Nuneaton and Bedworth", - "E07000135" => "Oadby and Wigston", - "E08000004" => "Oldham", - "E07000178" => "Oxford", - "E07000122" => "Pendle", - "E06000031" => "Peterborough", - "E06000026" => "Plymouth", - "E06000044" => "Portsmouth", - "E07000123" => "Preston", - "E06000038" => "Reading", - "E09000026" => "Redbridge", - "E06000003" => "Redcar and Cleveland", - "E07000236" => "Redditch", - "E07000211" => "Reigate and Banstead", - "E07000124" => "Ribble Valley", - "E09000027" => "Richmond upon Thames", - "E07000166" => "Richmondshire", - "E08000005" => "Rochdale", - "E07000075" => "Rochford", - "E07000125" => "Rossendale", - "E07000064" => "Rother", - "E08000018" => "Rotherham", - "E07000220" => "Rugby", - "E07000212" => "Runnymede", - "E07000176" => "Rushcliffe", - "E07000092" => "Rushmoor", - "E06000017" => "Rutland", - "E07000167" => "Ryedale", - "E08000006" => "Salford", - "E08000028" => "Sandwell", - "E07000168" => "Scarborough", - "E07000188" => "Sedgemoor", - "E08000014" => "Sefton", - "E07000169" => "Selby", - "E07000111" => "Sevenoaks", - "E08000019" => "Sheffield", - "E06000051" => "Shropshire", - "E06000039" => "Slough", - "E08000029" => "Solihull", - "E07000246" => "Somerset West and Taunton", - "E07000012" => "South Cambridgeshire", - "E07000039" => "South Derbyshire", - "E06000025" => "South Gloucestershire", - "E07000044" => "South Hams", - "E07000140" => "South Holland", - "E07000141" => "South Kesteven", - "E07000031" => "South Lakeland", - "E07000149" => "South Norfolk", - "E07000155" => "South Northamptonshire", - "E07000179" => "South Oxfordshire", - "E07000126" => "South Ribble", - "E07000189" => "South Somerset", - "E07000196" => "South Staffordshire", - "E08000023" => "South Tyneside", - "E06000045" => "Southampton", - "E06000033" => "Southend-on-Sea", - "E09000028" => "Southwark", - "E07000213" => "Spelthorne", - "E07000240" => "St Albans", - "E08000013" => "St. Helens", - "E07000197" => "Stafford", - "E07000198" => "Staffordshire Moorlands", - "E07000243" => "Stevenage", - "E08000007" => "Stockport", - "E06000004" => "Stockton-on-Tees", - "E06000021" => "Stoke-on-Trent", - "E07000221" => "Stratford-on-Avon", - "E07000082" => "Stroud", - "E08000024" => "Sunderland", - "E07000214" => "Surrey Heath", - "E09000029" => "Sutton", - "E07000113" => "Swale", - "E06000030" => "Swindon", - "E08000008" => "Tameside", - "E07000199" => "Tamworth", - "E07000215" => "Tandridge", - "E07000045" => "Teignbridge", - "E06000020" => "Telford and Wrekin", - "E07000076" => "Tendring", - "E07000093" => "Test Valley", - "E07000083" => "Tewkesbury", - "E07000114" => "Thanet", - "E07000102" => "Three Rivers", - "E06000034" => "Thurrock", - "E07000115" => "Tonbridge and Malling", - "E06000027" => "Torbay", - "E07000046" => "Torridge", - "E09000030" => "Tower Hamlets", - "E08000009" => "Trafford", - "E07000116" => "Tunbridge Wells", - "E07000077" => "Uttlesford", - "E07000180" => "Vale of White Horse", - "E08000036" => "Wakefield", - "E08000030" => "Walsall", - "E09000031" => "Waltham Forest", - "E09000032" => "Wandsworth", - "E06000007" => "Warrington", - "E07000222" => "Warwick", - "E07000103" => "Watford", - "E07000216" => "Waverley", - "E07000065" => "Wealden", - "E07000156" => "Wellingborough", - "E07000241" => "Welwyn Hatfield", - "E06000037" => "West Berkshire", - "E07000047" => "West Devon", - "E07000127" => "West Lancashire", - "E07000142" => "West Lindsey", - "E07000181" => "West Oxfordshire", - "E07000245" => "West Suffolk", - "E09000033" => "Westminster", - "E08000010" => "Wigan", - "E06000054" => "Wiltshire", - "E07000094" => "Winchester", - "E06000040" => "Windsor and Maidenhead", - "E08000015" => "Wirral", - "E07000217" => "Woking", - "E06000041" => "Wokingham", - "E08000031" => "Wolverhampton", - "E07000237" => "Worcester", - "E07000229" => "Worthing", - "E07000238" => "Wychavon", - "E07000128" => "Wyre", - "E07000239" => "Wyre Forest", - "E06000014" => "York", - }.freeze + def answer_options + { "" => "Select an option" }.merge(LocalAuthority.active(form.start_date).england.map { |la| [la.code, la.name] }.to_h) + end end diff --git a/app/models/form/lettings/questions/layear.rb b/app/models/form/lettings/questions/layear.rb index 14a334399..764253250 100644 --- a/app/models/form/lettings/questions/layear.rb +++ b/app/models/form/lettings/questions/layear.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Layear < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 75 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/leftreg.rb b/app/models/form/lettings/questions/leftreg.rb index 2601f351d..a6edecbc3 100644 --- a/app/models/form/lettings/questions/leftreg.rb +++ b/app/models/form/lettings/questions/leftreg.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Leftreg < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 67 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/letting_allocation.rb b/app/models/form/lettings/questions/letting_allocation.rb index e41f52b09..18c0a3042 100644 --- a/app/models/form/lettings/questions/letting_allocation.rb +++ b/app/models/form/lettings/questions/letting_allocation.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::LettingAllocation < ::Form::Question @check_answers_card_number = 0 @hint_text = "Select all that apply." @answer_options = ANSWER_OPTIONS + @question_number = 84 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/location_id.rb b/app/models/form/lettings/questions/location_id.rb index fc197cf82..ee97724b5 100644 --- a/app/models/form/lettings/questions/location_id.rb +++ b/app/models/form/lettings/questions/location_id.rb @@ -10,6 +10,7 @@ class Form::Lettings::Questions::LocationId < ::Form::Question "needstype": 2, }, } + @question_number = 10 end def answer_options diff --git a/app/models/form/lettings/questions/majorrepairs.rb b/app/models/form/lettings/questions/majorrepairs.rb index e0a6fdb01..83acf76a6 100644 --- a/app/models/form/lettings/questions/majorrepairs.rb +++ b/app/models/form/lettings/questions/majorrepairs.rb @@ -9,6 +9,7 @@ class Form::Lettings::Questions::Majorrepairs < ::Form::Question @hint_text = "Major repairs are works that could not be reasonably carried out with a tenant living at the property. For example, structural repairs." @answer_options = ANSWER_OPTIONS @conditional_for = { "mrcdate" => [1] } + @question_number = 24 end ANSWER_OPTIONS = { "1" => { "value" => "Yes" }, "0" => { "value" => "No" } }.freeze diff --git a/app/models/form/lettings/questions/managing_organisation.rb b/app/models/form/lettings/questions/managing_organisation.rb index bd9cbb8b9..7e4d318fe 100644 --- a/app/models/form/lettings/questions/managing_organisation.rb +++ b/app/models/form/lettings/questions/managing_organisation.rb @@ -5,6 +5,7 @@ class Form::Lettings::Questions::ManagingOrganisation < ::Form::Question @check_answer_label = "Managing agent" @header = "Which organisation manages this letting?" @type = "select" + @question_number = 2 end def answer_options(log = nil, user = nil) diff --git a/app/models/form/lettings/questions/mrcdate.rb b/app/models/form/lettings/questions/mrcdate.rb index a3718af47..cadcd3a7a 100644 --- a/app/models/form/lettings/questions/mrcdate.rb +++ b/app/models/form/lettings/questions/mrcdate.rb @@ -7,5 +7,6 @@ class Form::Lettings::Questions::Mrcdate < ::Form::Question @type = "date" @check_answers_card_number = 0 @hint_text = "For example, 27 3 2021." + @question_number = 24 end end diff --git a/app/models/form/lettings/questions/national.rb b/app/models/form/lettings/questions/nationality.rb similarity index 75% rename from app/models/form/lettings/questions/national.rb rename to app/models/form/lettings/questions/nationality.rb index 0bfe198e0..c86f93b09 100644 --- a/app/models/form/lettings/questions/national.rb +++ b/app/models/form/lettings/questions/nationality.rb @@ -1,19 +1,22 @@ -class Form::Lettings::Questions::National < ::Form::Question +class Form::Lettings::Questions::Nationality < ::Form::Question def initialize(id, hsh, page) super @id = "national" @check_answer_label = "Lead tenant’s nationality" - @header = "What is the lead tenant’s nationality?" + @header = "What is the nationality of the lead tenant?" @type = "radio" @check_answers_card_number = 1 @hint_text = "The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest." @answer_options = ANSWER_OPTIONS + @question_number = 36 end ANSWER_OPTIONS = { "18" => { "value" => "United Kingdom" }, "17" => { "value" => "Republic of Ireland" }, "19" => { "value" => "European Economic Area (EEA) country, excluding Ireland" }, + "20" => { "value" => "Afghanistan" }, + "21" => { "value" => "Ukraine" }, "12" => { "value" => "Other" }, "divider" => true, "13" => { "value" => "Tenant prefers not to say" }, diff --git a/app/models/form/lettings/questions/needs_type.rb b/app/models/form/lettings/questions/needs_type.rb index 331899821..eaa13cb9d 100644 --- a/app/models/form/lettings/questions/needs_type.rb +++ b/app/models/form/lettings/questions/needs_type.rb @@ -7,6 +7,7 @@ class Form::Lettings::Questions::NeedsType < ::Form::Question @hint_text = "General needs housing includes both self-contained and shared housing without support or specific adaptations. Supported housing can include direct access hostels, group homes, residential care and nursing homes." @type = "radio" @answer_options = ANSWER_OPTIONS + @question_number = 3 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/net_income_known.rb b/app/models/form/lettings/questions/net_income_known.rb index 760c20b9f..226569b9e 100644 --- a/app/models/form/lettings/questions/net_income_known.rb +++ b/app/models/form/lettings/questions/net_income_known.rb @@ -9,6 +9,7 @@ class Form::Lettings::Questions::NetIncomeKnown < ::Form::Question @guidance_partial = "what_counts_as_income" @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 86 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/offered.rb b/app/models/form/lettings/questions/offered.rb index ebc2bac1b..e41def301 100644 --- a/app/models/form/lettings/questions/offered.rb +++ b/app/models/form/lettings/questions/offered.rb @@ -2,14 +2,15 @@ class Form::Lettings::Questions::Offered < ::Form::Question def initialize(id, hsh, page) super @id = "offered" - @check_answer_label = "Times previously offered since becoming available" - @header = "Since becoming available for re-let, how many times has the property been previously offered?" + @check_answer_label = I18n.t("check_answer_labels.offered") + @header = I18n.t("questions.offered") @type = "numeric" @width = 2 @check_answers_card_number = 0 @max = 150 @min = 0 - @hint_text = "This is after the last tenancy ended. If the property is being offered for let for the first time, enter 0." + @hint_text = I18n.t("hints.offered") @step = 1 + @question_number = 18 end end diff --git a/app/models/form/lettings/questions/offered_social_let.rb b/app/models/form/lettings/questions/offered_social_let.rb index c87ffb998..d3ac29516 100644 --- a/app/models/form/lettings/questions/offered_social_let.rb +++ b/app/models/form/lettings/questions/offered_social_let.rb @@ -2,14 +2,15 @@ class Form::Lettings::Questions::OfferedSocialLet < ::Form::Question def initialize(id, hsh, page) super @id = "offered" - @check_answer_label = "Times previously offered since becoming available" - @header = "How many times was the property offered between becoming vacant and this letting?" + @check_answer_label = I18n.t("check_answer_labels.offered") + @header = I18n.t("questions.offered") @type = "numeric" @width = 2 @check_answers_card_number = 0 @max = 150 @min = 0 - @hint_text = "Do not include the offer that led to this letting.This is after the last tenancy ended. If the property is being offered for let for the first time, enter 0." + @hint_text = I18n.t("hints.offered") @step = 1 + @question_number = 18 end end diff --git a/app/models/form/lettings/questions/period.rb b/app/models/form/lettings/questions/period.rb index cf0b4d13a..08a8510c4 100644 --- a/app/models/form/lettings/questions/period.rb +++ b/app/models/form/lettings/questions/period.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Period < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 92 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/person_gender_identity.rb b/app/models/form/lettings/questions/person_gender_identity.rb index cb8f04ef2..1416a3414 100644 --- a/app/models/form/lettings/questions/person_gender_identity.rb +++ b/app/models/form/lettings/questions/person_gender_identity.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::PersonGenderIdentity < ::Form::Question @check_answers_card_number = person_index @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 32 + (4 * person_index) end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/person_relationship.rb b/app/models/form/lettings/questions/person_relationship.rb index debb14a03..0d54db949 100644 --- a/app/models/form/lettings/questions/person_relationship.rb +++ b/app/models/form/lettings/questions/person_relationship.rb @@ -8,13 +8,14 @@ class Form::Lettings::Questions::PersonRelationship < ::Form::Question @check_answers_card_number = person_index @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 30 + (4 * person_index) end ANSWER_OPTIONS = { "P" => { "value" => "Partner" }, "C" => { "value" => "Child", - "hint" => "Must be eligible for child benefit, aged under 16 or under 20 if still in full-time education.", + "hint" => "Must be eligible for child benefit: under age 16 or under 20 if still in full-time education.", }, "X" => { "value" => "Other" }, "divider" => { "value" => true }, diff --git a/app/models/form/lettings/questions/person_working_situation.rb b/app/models/form/lettings/questions/person_working_situation.rb index 9174930a2..d6e593e33 100644 --- a/app/models/form/lettings/questions/person_working_situation.rb +++ b/app/models/form/lettings/questions/person_working_situation.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::PersonWorkingSituation < ::Form::Question @check_answers_card_number = person_index @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 33 + (4 * person_index) end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/ppcodenk.rb b/app/models/form/lettings/questions/ppcodenk.rb index fa10f3d69..33b03d959 100644 --- a/app/models/form/lettings/questions/ppcodenk.rb +++ b/app/models/form/lettings/questions/ppcodenk.rb @@ -10,6 +10,7 @@ class Form::Lettings::Questions::Ppcodenk < ::Form::Question @answer_options = ANSWER_OPTIONS @conditional_for = { "ppostcode_full" => [1] } @hidden_in_check_answers = { "depends_on" => [{ "ppcodenk" => 0 }, { "ppcodenk" => 1 }] } + @question_number = 80 end ANSWER_OPTIONS = { "1" => { "value" => "Yes" }, "0" => { "value" => "No" } }.freeze diff --git a/app/models/form/lettings/questions/ppostcode_full.rb b/app/models/form/lettings/questions/ppostcode_full.rb index 736e06f16..0432d1b5b 100644 --- a/app/models/form/lettings/questions/ppostcode_full.rb +++ b/app/models/form/lettings/questions/ppostcode_full.rb @@ -10,5 +10,6 @@ class Form::Lettings::Questions::PpostcodeFull < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @inferred_answers = { "prevloc" => { "is_previous_la_inferred" => true } } + @question_number = 80 end end diff --git a/app/models/form/lettings/questions/preg_occ.rb b/app/models/form/lettings/questions/preg_occ.rb index c6b6f168f..8a863a870 100644 --- a/app/models/form/lettings/questions/preg_occ.rb +++ b/app/models/form/lettings/questions/preg_occ.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::PregOcc < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 69 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/previous_la_known.rb b/app/models/form/lettings/questions/previous_la_known.rb index 0f563b62a..a9ff11e55 100644 --- a/app/models/form/lettings/questions/previous_la_known.rb +++ b/app/models/form/lettings/questions/previous_la_known.rb @@ -10,6 +10,7 @@ class Form::Lettings::Questions::PreviousLaKnown < ::Form::Question @answer_options = ANSWER_OPTIONS @conditional_for = { "prevloc" => [1] } @hidden_in_check_answers = { "depends_on" => [{ "previous_la_known" => 0 }, { "previous_la_known" => 1 }] } + @question_number = 81 end ANSWER_OPTIONS = { "1" => { "value" => "Yes" }, "0" => { "value" => "No" } }.freeze diff --git a/app/models/form/lettings/questions/unitletas.rb b/app/models/form/lettings/questions/previous_let_type.rb similarity index 61% rename from app/models/form/lettings/questions/unitletas.rb rename to app/models/form/lettings/questions/previous_let_type.rb index e37a07b34..6c9947743 100644 --- a/app/models/form/lettings/questions/unitletas.rb +++ b/app/models/form/lettings/questions/previous_let_type.rb @@ -1,4 +1,4 @@ -class Form::Lettings::Questions::Unitletas < ::Form::Question +class Form::Lettings::Questions::PreviousLetType < ::Form::Question def initialize(id, hsh, page) super @id = "unitletas" @@ -8,12 +8,16 @@ class Form::Lettings::Questions::Unitletas < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 16 end ANSWER_OPTIONS = { "1" => { "value" => "Social rent basis" }, "2" => { "value" => "Affordable rent basis" }, - "4" => { "value" => "Intermediate rent basis" }, + "5" => { "value" => "A London Affordable Rent basis" }, + "6" => { "value" => "A Rent to Buy basis" }, + "7" => { "value" => "A London Living Rent basis" }, + "8" => { "value" => "Another Intermediate Rent basis" }, "divider" => { "value" => true }, "3" => { "value" => "Don’t know" }, }.freeze diff --git a/app/models/form/lettings/questions/previous_tenure.rb b/app/models/form/lettings/questions/previous_tenure.rb new file mode 100644 index 000000000..ca5b8d832 --- /dev/null +++ b/app/models/form/lettings/questions/previous_tenure.rb @@ -0,0 +1,42 @@ +class Form::Lettings::Questions::PreviousTenure < ::Form::Question + def initialize(id, hsh, page) + super + @id = "prevten" + @check_answer_label = "Where was the household immediately before this letting?" + @header = "Where was the household immediately before this letting?" + @type = "radio" + @check_answers_card_number = 0 + @hint_text = "This is where the household was the night before they moved." + @answer_options = ANSWER_OPTIONS + @question_number = 78 + end + + ANSWER_OPTIONS = { + "30" => { "value" => "Fixed-term local authority general needs tenancy" }, + "32" => { "value" => "Fixed-term private registered provider (PRP) general needs tenancy" }, + "31" => { "value" => "Lifetime local authority general needs tenancy" }, + "33" => { "value" => "Lifetime private registered provider (PRP) general needs tenancy" }, + "34" => { "value" => "Specialist retirement housing" }, + "36" => { "value" => "Sheltered housing for adults aged under 55 years" }, + "35" => { "value" => "Extra care housing" }, + "6" => { "value" => "Other supported housing" }, + "3" => { "value" => "Private sector tenancy" }, + "27" => { "value" => "Owner occupation (low-cost home ownership)" }, + "26" => { "value" => "Owner occupation (private)" }, + "28" => { "value" => "Living with friends or family" }, + "14" => { "value" => "Bed and breakfast" }, + "7" => { "value" => "Direct access hostel" }, + "10" => { "value" => "Hospital" }, + "29" => { "value" => "Prison or approved probation hostel" }, + "19" => { "value" => "Rough sleeping" }, + "18" => { "value" => "Any other temporary accommodation" }, + "13" => { "value" => "Children’s home or foster care" }, + "24" => { "value" => "Home Office Asylum Support" }, + "37" => { "value" => "Host family or similar refugee accommodation" }, + "23" => { "value" => "Mobile home or caravan" }, + "21" => { "value" => "Refuge" }, + "9" => { "value" => "Residential care home" }, + "4" => { "value" => "Tied housing or rented with job" }, + "25" => { "value" => "Any other accommodation" }, + }.freeze +end diff --git a/app/models/form/lettings/questions/prevten_renewal.rb b/app/models/form/lettings/questions/previous_tenure_renewal.rb similarity index 75% rename from app/models/form/lettings/questions/prevten_renewal.rb rename to app/models/form/lettings/questions/previous_tenure_renewal.rb index e8516e85e..56be9a95d 100644 --- a/app/models/form/lettings/questions/prevten_renewal.rb +++ b/app/models/form/lettings/questions/previous_tenure_renewal.rb @@ -1,4 +1,4 @@ -class Form::Lettings::Questions::PrevtenRenewal < ::Form::Question +class Form::Lettings::Questions::PreviousTenureRenewal < ::Form::Question def initialize(id, hsh, page) super @id = "prevten" @@ -8,10 +8,12 @@ class Form::Lettings::Questions::PrevtenRenewal < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 78 end ANSWER_OPTIONS = { "34" => { "value" => "Specialist retirement housing" }, + "36" => { "value" => "Sheltered housing for adults aged under 55 years" }, "35" => { "value" => "Extra care housing" }, "6" => { "value" => "Other supported housing" }, }.freeze diff --git a/app/models/form/lettings/questions/prevloc.rb b/app/models/form/lettings/questions/prevloc.rb index e5a433f3f..229af2c18 100644 --- a/app/models/form/lettings/questions/prevloc.rb +++ b/app/models/form/lettings/questions/prevloc.rb @@ -8,393 +8,10 @@ class Form::Lettings::Questions::Prevloc < ::Form::Question @inferred_check_answers_value = [{ "condition" => { "previous_la_known" => 0 }, "value" => "Not known" }] @check_answers_card_number = 0 @hint_text = "Select ‘Northern Ireland’, ‘Scotland’, ‘Wales’ or ‘Outside the UK’ if the household’s last settled home was outside England." - @answer_options = ANSWER_OPTIONS + @question_number = 81 end - ANSWER_OPTIONS = { - "" => "Select an option", - "S12000033" => "Aberdeen City", - "S12000034" => "Aberdeenshire", - "E07000223" => "Adur", - "E07000026" => "Allerdale", - "E07000032" => "Amber Valley", - "S12000041" => "Angus", - "N09000001" => "Antrim and Newtownabbey", - "N09000011" => "Ards and North Down", - "S12000035" => "Argyll and Bute", - "N09000002" => "Armagh City, Banbridge and Craigavon", - "E07000224" => "Arun", - "E07000170" => "Ashfield", - "E07000105" => "Ashford", - "E07000200" => "Babergh", - "E09000002" => "Barking and Dagenham", - "E09000003" => "Barnet", - "E08000016" => "Barnsley", - "E07000027" => "Barrow-in-Furness", - "E07000066" => "Basildon", - "E07000084" => "Basingstoke and Deane", - "E07000171" => "Bassetlaw", - "E06000022" => "Bath and North East Somerset", - "E06000055" => "Bedford", - "N09000003" => "Belfast", - "E09000004" => "Bexley", - "E08000025" => "Birmingham", - "E07000129" => "Blaby", - "E06000008" => "Blackburn with Darwen", - "E06000009" => "Blackpool", - "W06000019" => "Blaenau Gwent", - "E07000033" => "Bolsover", - "E08000001" => "Bolton", - "E07000136" => "Boston", - "E06000058" => "Bournemouth, Christchurch and Poole", - "E06000036" => "Bracknell Forest", - "E08000032" => "Bradford", - "E07000067" => "Braintree", - "E07000143" => "Breckland", - "E09000005" => "Brent", - "E07000068" => "Brentwood", - "W06000013" => "Bridgend", - "E06000043" => "Brighton and Hove", - "E06000023" => "Bristol, City of", - "E07000144" => "Broadland", - "E09000006" => "Bromley", - "E07000234" => "Bromsgrove", - "E07000095" => "Broxbourne", - "E07000172" => "Broxtowe", - "E06000060" => "Buckinghamshire", - "E07000117" => "Burnley", - "E08000002" => "Bury", - "W06000018" => "Caerphilly", - "E08000033" => "Calderdale", - "E07000008" => "Cambridge", - "E09000007" => "Camden", - "E07000192" => "Cannock Chase", - "E07000106" => "Canterbury", - "W06000015" => "Cardiff", - "E07000028" => "Carlisle", - "W06000010" => "Carmarthenshire", - "E07000069" => "Castle Point", - "N09000004" => "Causeway Coast and Glens", - "E06000056" => "Central Bedfordshire", - "W06000008" => "Ceredigion", - "E07000130" => "Charnwood", - "E07000070" => "Chelmsford", - "E07000078" => "Cheltenham", - "E07000177" => "Cherwell", - "E06000049" => "Cheshire East", - "E06000050" => "Cheshire West and Chester", - "E07000034" => "Chesterfield", - "E07000225" => "Chichester", - "E07000118" => "Chorley", - "S12000036" => "City of Edinburgh", - "E09000001" => "City of London", - "S12000005" => "Clackmannanshire", - "E07000071" => "Colchester", - "W06000003" => "Conwy", - "E07000029" => "Copeland", - "E07000150" => "Corby", - "E06000052" => "Cornwall", - "E07000079" => "Cotswold", - "E06000047" => "County Durham", - "E08000026" => "Coventry", - "E07000163" => "Craven", - "E07000226" => "Crawley", - "E09000008" => "Croydon", - "E07000096" => "Dacorum", - "E06000005" => "Darlington", - "E07000107" => "Dartford", - "E07000151" => "Daventry", - "W06000004" => "Denbighshire", - "E06000015" => "Derby", - "E07000035" => "Derbyshire Dales", - "N09000005" => "Derry City and Strabane", - "E08000017" => "Doncaster", - "E06000059" => "Dorset", - "E07000108" => "Dover", - "E08000027" => "Dudley", - "S12000006" => "Dumfries and Galloway", - "S12000042" => "Dundee City", - "E09000009" => "Ealing", - "S12000008" => "East Ayrshire", - "E07000009" => "East Cambridgeshire", - "E07000040" => "East Devon", - "S12000045" => "East Dunbartonshire", - "E07000085" => "East Hampshire", - "E07000242" => "East Hertfordshire", - "E07000137" => "East Lindsey", - "S12000010" => "East Lothian", - "E07000152" => "East Northamptonshire", - "S12000011" => "East Renfrewshire", - "E06000011" => "East Riding of Yorkshire", - "E07000193" => "East Staffordshire", - "E07000244" => "East Suffolk", - "E07000061" => "Eastbourne", - "E07000086" => "Eastleigh", - "E07000030" => "Eden", - "E07000207" => "Elmbridge", - "E09000010" => "Enfield", - "E07000072" => "Epping Forest", - "E07000208" => "Epsom and Ewell", - "E07000036" => "Erewash", - "E07000041" => "Exeter", - "S12000014" => "Falkirk", - "E07000087" => "Fareham", - "E07000010" => "Fenland", - "N09000006" => "Fermanagh and Omagh", - "S12000047" => "Fife", - "W06000005" => "Flintshire", - "E07000112" => "Folkestone and Hythe", - "E07000080" => "Forest of Dean", - "E07000119" => "Fylde", - "E08000037" => "Gateshead", - "E07000173" => "Gedling", - "S12000049" => "Glasgow City", - "E07000081" => "Gloucester", - "E07000088" => "Gosport", - "E07000109" => "Gravesham", - "E07000145" => "Great Yarmouth", - "E09000011" => "Greenwich", - "E07000209" => "Guildford", - "W06000002" => "Gwynedd", - "E09000012" => "Hackney", - "E06000006" => "Halton", - "E07000164" => "Hambleton", - "E09000013" => "Hammersmith and Fulham", - "E07000131" => "Harborough", - "E09000014" => "Haringey", - "E07000073" => "Harlow", - "E07000165" => "Harrogate", - "E09000015" => "Harrow", - "E07000089" => "Hart", - "E06000001" => "Hartlepool", - "E07000062" => "Hastings", - "E07000090" => "Havant", - "E09000016" => "Havering", - "E06000019" => "Herefordshire, County of", - "E07000098" => "Hertsmere", - "E07000037" => "High Peak", - "S12000017" => "Highland", - "E09000017" => "Hillingdon", - "E07000132" => "Hinckley and Bosworth", - "E07000227" => "Horsham", - "E09000018" => "Hounslow", - "E07000011" => "Huntingdonshire", - "E07000120" => "Hyndburn", - "S12000018" => "Inverclyde", - "E07000202" => "Ipswich", - "W06000001" => "Isle of Anglesey", - "E06000046" => "Isle of Wight", - "E06000053" => "Isles of Scilly", - "E09000019" => "Islington", - "E09000020" => "Kensington and Chelsea", - "E07000153" => "Kettering", - "E07000146" => "King’s Lynn and West Norfolk", - "E06000010" => "Kingston upon Hull, City of", - "E09000021" => "Kingston upon Thames", - "E08000034" => "Kirklees", - "E08000011" => "Knowsley", - "E09000022" => "Lambeth", - "E07000121" => "Lancaster", - "E08000035" => "Leeds", - "E06000016" => "Leicester", - "E07000063" => "Lewes", - "E09000023" => "Lewisham", - "E07000194" => "Lichfield", - "E07000138" => "Lincoln", - "N09000007" => "Lisburn and Castlereagh", - "E08000012" => "Liverpool", - "E06000032" => "Luton", - "E07000110" => "Maidstone", - "E07000074" => "Maldon", - "E07000235" => "Malvern Hills", - "E08000003" => "Manchester", - "E07000174" => "Mansfield", - "E06000035" => "Medway", - "E07000133" => "Melton", - "E07000187" => "Mendip", - "W06000024" => "Merthyr Tydfil", - "E09000024" => "Merton", - "E07000042" => "Mid Devon", - "E07000203" => "Mid Suffolk", - "E07000228" => "Mid Sussex", - "N09000009" => "Mid Ulster", - "N09000008" => "Mid and East Antrim", - "E06000002" => "Middlesbrough", - "S12000019" => "Midlothian", - "E06000042" => "Milton Keynes", - "E07000210" => "Mole Valley", - "W06000021" => "Monmouthshire", - "S12000020" => "Moray", - "S12000013" => "Na h-Eileanan Siar", - "W06000012" => "Neath Port Talbot", - "E07000091" => "New Forest", - "E07000175" => "Newark and Sherwood", - "E08000021" => "Newcastle upon Tyne", - "E07000195" => "Newcastle-under-Lyme", - "E09000025" => "Newham", - "W06000022" => "Newport", - "N09000010" => "Newry, Mourne and Down", - "S12000021" => "North Ayrshire", - "E07000043" => "North Devon", - "E07000038" => "North East Derbyshire", - "E06000012" => "North East Lincolnshire", - "E07000099" => "North Hertfordshire", - "E07000139" => "North Kesteven", - "S12000050" => "North Lanarkshire", - "E06000013" => "North Lincolnshire", - "E07000147" => "North Norfolk", - "E06000024" => "North Somerset", - "E08000022" => "North Tyneside", - "E07000218" => "North Warwickshire", - "E07000134" => "North West Leicestershire", - "E07000154" => "Northampton", - "E06000057" => "Northumberland", - "E07000148" => "Norwich", - "E06000018" => "Nottingham", - "E07000219" => "Nuneaton and Bedworth", - "E07000135" => "Oadby and Wigston", - "E08000004" => "Oldham", - "S12000023" => "Orkney Islands", - "E07000178" => "Oxford", - "W06000009" => "Pembrokeshire", - "E07000122" => "Pendle", - "S12000048" => "Perth and Kinross", - "E06000031" => "Peterborough", - "E06000026" => "Plymouth", - "E06000044" => "Portsmouth", - "W06000023" => "Powys", - "E07000123" => "Preston", - "E06000038" => "Reading", - "E09000026" => "Redbridge", - "E06000003" => "Redcar and Cleveland", - "E07000236" => "Redditch", - "E07000211" => "Reigate and Banstead", - "S12000038" => "Renfrewshire", - "W06000016" => "Rhondda Cynon Taf", - "E07000124" => "Ribble Valley", - "E09000027" => "Richmond upon Thames", - "E07000166" => "Richmondshire", - "E08000005" => "Rochdale", - "E07000075" => "Rochford", - "E07000125" => "Rossendale", - "E07000064" => "Rother", - "E08000018" => "Rotherham", - "E07000220" => "Rugby", - "E07000212" => "Runnymede", - "E07000176" => "Rushcliffe", - "E07000092" => "Rushmoor", - "E06000017" => "Rutland", - "E07000167" => "Ryedale", - "E08000006" => "Salford", - "E08000028" => "Sandwell", - "E07000168" => "Scarborough", - "S12000026" => "Scottish Borders", - "E07000188" => "Sedgemoor", - "E08000014" => "Sefton", - "E07000169" => "Selby", - "E07000111" => "Sevenoaks", - "E08000019" => "Sheffield", - "S12000027" => "Shetland Islands", - "E06000051" => "Shropshire", - "E06000039" => "Slough", - "E08000029" => "Solihull", - "E07000246" => "Somerset West and Taunton", - "S12000028" => "South Ayrshire", - "E07000012" => "South Cambridgeshire", - "E07000039" => "South Derbyshire", - "E06000025" => "South Gloucestershire", - "E07000044" => "South Hams", - "E07000140" => "South Holland", - "E07000141" => "South Kesteven", - "E07000031" => "South Lakeland", - "S12000029" => "South Lanarkshire", - "E07000149" => "South Norfolk", - "E07000155" => "South Northamptonshire", - "E07000179" => "South Oxfordshire", - "E07000126" => "South Ribble", - "E07000189" => "South Somerset", - "E07000196" => "South Staffordshire", - "E08000023" => "South Tyneside", - "E06000045" => "Southampton", - "E06000033" => "Southend-on-Sea", - "E09000028" => "Southwark", - "E07000213" => "Spelthorne", - "E07000240" => "St Albans", - "E08000013" => "St. Helens", - "E07000197" => "Stafford", - "E07000198" => "Staffordshire Moorlands", - "E07000243" => "Stevenage", - "S12000030" => "Stirling", - "E08000007" => "Stockport", - "E06000004" => "Stockton-on-Tees", - "E06000021" => "Stoke-on-Trent", - "E07000221" => "Stratford-on-Avon", - "E07000082" => "Stroud", - "E08000024" => "Sunderland", - "E07000214" => "Surrey Heath", - "E09000029" => "Sutton", - "E07000113" => "Swale", - "W06000011" => "Swansea", - "E06000030" => "Swindon", - "E08000008" => "Tameside", - "E07000199" => "Tamworth", - "E07000215" => "Tandridge", - "E07000045" => "Teignbridge", - "E06000020" => "Telford and Wrekin", - "E07000076" => "Tendring", - "E07000093" => "Test Valley", - "E07000083" => "Tewkesbury", - "E07000114" => "Thanet", - "E07000102" => "Three Rivers", - "E06000034" => "Thurrock", - "E07000115" => "Tonbridge and Malling", - "E06000027" => "Torbay", - "W06000020" => "Torfaen", - "E07000046" => "Torridge", - "E09000030" => "Tower Hamlets", - "E08000009" => "Trafford", - "E07000116" => "Tunbridge Wells", - "E07000077" => "Uttlesford", - "W06000014" => "Vale of Glamorgan", - "E07000180" => "Vale of White Horse", - "E08000036" => "Wakefield", - "E08000030" => "Walsall", - "E09000031" => "Waltham Forest", - "E09000032" => "Wandsworth", - "E06000007" => "Warrington", - "E07000222" => "Warwick", - "E07000103" => "Watford", - "E07000216" => "Waverley", - "E07000065" => "Wealden", - "E07000156" => "Wellingborough", - "E07000241" => "Welwyn Hatfield", - "E06000037" => "West Berkshire", - "E07000047" => "West Devon", - "S12000039" => "West Dunbartonshire", - "E07000127" => "West Lancashire", - "E07000142" => "West Lindsey", - "S12000040" => "West Lothian", - "E07000181" => "West Oxfordshire", - "E07000245" => "West Suffolk", - "E09000033" => "Westminster", - "E08000010" => "Wigan", - "E06000054" => "Wiltshire", - "E07000094" => "Winchester", - "E06000040" => "Windsor and Maidenhead", - "E08000015" => "Wirral", - "E07000217" => "Woking", - "E06000041" => "Wokingham", - "E08000031" => "Wolverhampton", - "E07000237" => "Worcester", - "E07000229" => "Worthing", - "W06000006" => "Wrexham", - "E07000238" => "Wychavon", - "E07000128" => "Wyre", - "E07000239" => "Wyre Forest", - "E06000014" => "York", - "N92000002" => "Northern Ireland", - "S92000003" => "Scotland", - "W92000004" => "Wales", - "9300000XX" => "Outside UK", - }.freeze + def answer_options + { "" => "Select an option" }.merge(LocalAuthority.active(form.start_date).map { |la| [la.code, la.name] }.to_h) + end end diff --git a/app/models/form/lettings/questions/prevten.rb b/app/models/form/lettings/questions/prevten.rb deleted file mode 100644 index 3d77f24bb..000000000 --- a/app/models/form/lettings/questions/prevten.rb +++ /dev/null @@ -1,87 +0,0 @@ -class Form::Lettings::Questions::Prevten < ::Form::Question - def initialize(id, hsh, page) - super - @id = "prevten" - @check_answer_label = "Where was the household immediately before this letting?" - @header = "Where was the household immediately before this letting?" - @type = "radio" - @check_answers_card_number = 0 - @hint_text = "This is where the household was the night before they moved." - @answer_options = ANSWER_OPTIONS - end - - ANSWER_OPTIONS = { - "30" => { - "value" => "Fixed-term local authority general needs tenancy", - }, - "32" => { - "value" => "Fixed-term private registered provider (PRP) general needs tenancy", - }, - "31" => { - "value" => "Lifetime local authority general needs tenancy", - }, - "33" => { - "value" => "Lifetime private registered provider (PRP) general needs tenancy", - }, - "34" => { - "value" => "Specialist retirement housing", - }, - "35" => { - "value" => "Extra care housing", - }, - "6" => { - "value" => "Other supported housing", - }, - "3" => { - "value" => "Private sector tenancy", - }, - "27" => { - "value" => "Owner occupation (low-cost home ownership)", - }, - "26" => { - "value" => "Owner occupation (private)", - }, - "28" => { - "value" => "Living with friends or family", - }, - "14" => { - "value" => "Bed and breakfast", - }, - "7" => { - "value" => "Direct access hostel", - }, - "10" => { - "value" => "Hospital", - }, - "29" => { - "value" => "Prison or approved probation hostel", - }, - "19" => { - "value" => "Rough sleeping", - }, - "18" => { - "value" => "Any other temporary accommodation", - }, - "13" => { - "value" => "Children’s home or foster care", - }, - "24" => { - "value" => "Home Office Asylum Support", - }, - "23" => { - "value" => "Mobile home or caravan", - }, - "21" => { - "value" => "Refuge", - }, - "9" => { - "value" => "Residential care home", - }, - "4" => { - "value" => "Tied housing or rented with job", - }, - "25" => { - "value" => "Any other accommodation", - }, - }.freeze -end diff --git a/app/models/form/lettings/questions/property_reference.rb b/app/models/form/lettings/questions/property_reference.rb index 75168f1bd..f93a57cee 100644 --- a/app/models/form/lettings/questions/property_reference.rb +++ b/app/models/form/lettings/questions/property_reference.rb @@ -7,5 +7,6 @@ class Form::Lettings::Questions::PropertyReference < ::Form::Question @hint_text = "This is how you usually refer to this property on your own systems." @type = "text" @width = 10 + @question_number = 8 end end diff --git a/app/models/form/lettings/questions/pscharge_4_weekly.rb b/app/models/form/lettings/questions/pscharge_4_weekly.rb index 2242cd692..cb716abd2 100644 --- a/app/models/form/lettings/questions/pscharge_4_weekly.rb +++ b/app/models/form/lettings/questions/pscharge_4_weekly.rb @@ -12,8 +12,8 @@ class Form::Lettings::Questions::Pscharge4Weekly < ::Form::Question @step = 0.01 @fields_to_add = %w[brent scharge pscharge supcharg] @result_field = "tcharge" - @hidden_in_check_answers = true @prefix = "£" @suffix = " every 4 weeks" + @question_number = 97 end end diff --git a/app/models/form/lettings/questions/pscharge_bi_weekly.rb b/app/models/form/lettings/questions/pscharge_bi_weekly.rb index 7a7c89443..bd3524b10 100644 --- a/app/models/form/lettings/questions/pscharge_bi_weekly.rb +++ b/app/models/form/lettings/questions/pscharge_bi_weekly.rb @@ -12,8 +12,8 @@ class Form::Lettings::Questions::PschargeBiWeekly < ::Form::Question @step = 0.01 @fields_to_add = %w[brent scharge pscharge supcharg] @result_field = "tcharge" - @hidden_in_check_answers = true @prefix = "£" @suffix = " every 2 weeks" + @question_number = 97 end end diff --git a/app/models/form/lettings/questions/pscharge_monthly.rb b/app/models/form/lettings/questions/pscharge_monthly.rb index 6aa1ae911..bae5bd459 100644 --- a/app/models/form/lettings/questions/pscharge_monthly.rb +++ b/app/models/form/lettings/questions/pscharge_monthly.rb @@ -12,8 +12,8 @@ class Form::Lettings::Questions::PschargeMonthly < ::Form::Question @step = 0.01 @fields_to_add = %w[brent scharge pscharge supcharg] @result_field = "tcharge" - @hidden_in_check_answers = true @prefix = "£" @suffix = " every month" + @question_number = 97 end end diff --git a/app/models/form/lettings/questions/pscharge_weekly.rb b/app/models/form/lettings/questions/pscharge_weekly.rb index 73f3d9323..1b24e9a10 100644 --- a/app/models/form/lettings/questions/pscharge_weekly.rb +++ b/app/models/form/lettings/questions/pscharge_weekly.rb @@ -12,8 +12,8 @@ class Form::Lettings::Questions::PschargeWeekly < ::Form::Question @step = 0.01 @fields_to_add = %w[brent scharge pscharge supcharg] @result_field = "tcharge" - @hidden_in_check_answers = true @prefix = "£" @suffix = " every week" + @question_number = 97 end end diff --git a/app/models/form/lettings/questions/reason.rb b/app/models/form/lettings/questions/reason.rb index 2f46fae35..9598780ec 100644 --- a/app/models/form/lettings/questions/reason.rb +++ b/app/models/form/lettings/questions/reason.rb @@ -13,6 +13,7 @@ class Form::Lettings::Questions::Reason < ::Form::Question 20, ], } + @question_number = 77 end ANSWER_OPTIONS = { @@ -58,8 +59,11 @@ class Form::Lettings::Questions::Reason < ::Form::Question "17" => { "value" => "To move nearer to work", }, - "7" => { - "value" => "Domestic abuse", + "48" => { + "value" => "Domestic abuse - previously joint tenancy with partner", + }, + "49" => { + "value" => "Domestic abuse - other", }, "31" => { "value" => "Hate crime", diff --git a/app/models/form/lettings/questions/reason_renewal.rb b/app/models/form/lettings/questions/reason_renewal.rb index c3a825c5e..9111ad8e7 100644 --- a/app/models/form/lettings/questions/reason_renewal.rb +++ b/app/models/form/lettings/questions/reason_renewal.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::ReasonRenewal < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 77 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/reasonable_preference_reason.rb b/app/models/form/lettings/questions/reasonable_preference_reason.rb index f582ccadf..631949685 100644 --- a/app/models/form/lettings/questions/reasonable_preference_reason.rb +++ b/app/models/form/lettings/questions/reasonable_preference_reason.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::ReasonablePreferenceReason < ::Form::Question @check_answers_card_number = 0 @hint_text = "Select all that apply." @answer_options = ANSWER_OPTIONS + @question_number = 83 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/reasonother.rb b/app/models/form/lettings/questions/reasonother.rb index 48306f7d7..e045c9aa3 100644 --- a/app/models/form/lettings/questions/reasonother.rb +++ b/app/models/form/lettings/questions/reasonother.rb @@ -7,5 +7,6 @@ class Form::Lettings::Questions::Reasonother < ::Form::Question @type = "text" @check_answers_card_number = 0 @hint_text = "" + @question_number = 77 end end diff --git a/app/models/form/lettings/questions/reasonpref.rb b/app/models/form/lettings/questions/reasonpref.rb index 571a7e3eb..43631a2fd 100644 --- a/app/models/form/lettings/questions/reasonpref.rb +++ b/app/models/form/lettings/questions/reasonpref.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Reasonpref < ::Form::Question @check_answers_card_number = 0 @hint_text = "Households may be given ‘reasonable preference’ for social housing, also known as ‘priority need’, by the local authority." @answer_options = ANSWER_OPTIONS + @question_number = 82 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/referral.rb b/app/models/form/lettings/questions/referral.rb index 83e5d3ae2..ca1e117a4 100644 --- a/app/models/form/lettings/questions/referral.rb +++ b/app/models/form/lettings/questions/referral.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Referral < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 85 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/referral_prp.rb b/app/models/form/lettings/questions/referral_prp.rb index 5651f431f..a602beea8 100644 --- a/app/models/form/lettings/questions/referral_prp.rb +++ b/app/models/form/lettings/questions/referral_prp.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::ReferralPrp < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 85 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/referral_supported_housing.rb b/app/models/form/lettings/questions/referral_supported_housing.rb index 5b286d94d..12d24cd53 100644 --- a/app/models/form/lettings/questions/referral_supported_housing.rb +++ b/app/models/form/lettings/questions/referral_supported_housing.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::ReferralSupportedHousing < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 85 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/referral_supported_housing_prp.rb b/app/models/form/lettings/questions/referral_supported_housing_prp.rb index 051f7b90b..4824dd6c5 100644 --- a/app/models/form/lettings/questions/referral_supported_housing_prp.rb +++ b/app/models/form/lettings/questions/referral_supported_housing_prp.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::ReferralSupportedHousingPrp < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 85 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/renewal.rb b/app/models/form/lettings/questions/renewal.rb index edf9c1e7b..ac9eca622 100644 --- a/app/models/form/lettings/questions/renewal.rb +++ b/app/models/form/lettings/questions/renewal.rb @@ -7,6 +7,7 @@ class Form::Lettings::Questions::Renewal < ::Form::Question @type = "radio" @answer_options = ANSWER_OPTIONS @hint_text = "A renewal is a letting to the same tenant in the same property" + @question_number = 4 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/rent_type.rb b/app/models/form/lettings/questions/rent_type.rb index 64e2839e2..ac9164f0c 100644 --- a/app/models/form/lettings/questions/rent_type.rb +++ b/app/models/form/lettings/questions/rent_type.rb @@ -7,6 +7,7 @@ class Form::Lettings::Questions::RentType < ::Form::Question @type = "radio" @answer_options = ANSWER_OPTIONS @conditional_for = { "irproduct_other" => [5] } + @question_number = 6 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/reservist.rb b/app/models/form/lettings/questions/reservist.rb index 695254c05..44eb8219d 100644 --- a/app/models/form/lettings/questions/reservist.rb +++ b/app/models/form/lettings/questions/reservist.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Reservist < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 68 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/rsnvac.rb b/app/models/form/lettings/questions/rsnvac.rb index 2899a9463..22d039748 100644 --- a/app/models/form/lettings/questions/rsnvac.rb +++ b/app/models/form/lettings/questions/rsnvac.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Rsnvac < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 17 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/rsnvac_first_let.rb b/app/models/form/lettings/questions/rsnvac_first_let.rb index a97e743db..8d7da0433 100644 --- a/app/models/form/lettings/questions/rsnvac_first_let.rb +++ b/app/models/form/lettings/questions/rsnvac_first_let.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::RsnvacFirstLet < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 15 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/scharge_4_weekly.rb b/app/models/form/lettings/questions/scharge_4_weekly.rb index 418c88157..b13c8339b 100644 --- a/app/models/form/lettings/questions/scharge_4_weekly.rb +++ b/app/models/form/lettings/questions/scharge_4_weekly.rb @@ -12,8 +12,8 @@ class Form::Lettings::Questions::Scharge4Weekly < ::Form::Question @step = 0.01 @fields_to_add = %w[brent scharge pscharge supcharg] @result_field = "tcharge" - @hidden_in_check_answers = true @prefix = "£" @suffix = " every 4 weeks" + @question_number = 96 end end diff --git a/app/models/form/lettings/questions/scharge_bi_weekly.rb b/app/models/form/lettings/questions/scharge_bi_weekly.rb index 913f49844..679662e64 100644 --- a/app/models/form/lettings/questions/scharge_bi_weekly.rb +++ b/app/models/form/lettings/questions/scharge_bi_weekly.rb @@ -12,8 +12,8 @@ class Form::Lettings::Questions::SchargeBiWeekly < ::Form::Question @step = 0.01 @fields_to_add = %w[brent scharge pscharge supcharg] @result_field = "tcharge" - @hidden_in_check_answers = true @prefix = "£" @suffix = " every 2 weeks" + @question_number = 96 end end diff --git a/app/models/form/lettings/questions/scharge_monthly.rb b/app/models/form/lettings/questions/scharge_monthly.rb index bec02543c..74f35578c 100644 --- a/app/models/form/lettings/questions/scharge_monthly.rb +++ b/app/models/form/lettings/questions/scharge_monthly.rb @@ -12,8 +12,8 @@ class Form::Lettings::Questions::SchargeMonthly < ::Form::Question @step = 0.01 @fields_to_add = %w[brent scharge pscharge supcharg] @result_field = "tcharge" - @hidden_in_check_answers = true @prefix = "£" @suffix = " every month" + @question_number = 96 end end diff --git a/app/models/form/lettings/questions/scharge_weekly.rb b/app/models/form/lettings/questions/scharge_weekly.rb index 11e79c111..c8788b7bd 100644 --- a/app/models/form/lettings/questions/scharge_weekly.rb +++ b/app/models/form/lettings/questions/scharge_weekly.rb @@ -12,8 +12,8 @@ class Form::Lettings::Questions::SchargeWeekly < ::Form::Question @step = 0.01 @fields_to_add = %w[brent scharge pscharge supcharg] @result_field = "tcharge" - @hidden_in_check_answers = true @prefix = "£" @suffix = " every week" + @question_number = 96 end end diff --git a/app/models/form/lettings/questions/scheme_id.rb b/app/models/form/lettings/questions/scheme_id.rb index 3f8225caa..a9147ba5f 100644 --- a/app/models/form/lettings/questions/scheme_id.rb +++ b/app/models/form/lettings/questions/scheme_id.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::SchemeId < ::Form::Question @answer_options = answer_options @guidance_position = GuidancePosition::BOTTOM @guidance_partial = "scheme_selection" + @question_number = 9 end def answer_options diff --git a/app/models/form/lettings/questions/sheltered.rb b/app/models/form/lettings/questions/sheltered.rb index 47899e261..67da39ce5 100644 --- a/app/models/form/lettings/questions/sheltered.rb +++ b/app/models/form/lettings/questions/sheltered.rb @@ -8,11 +8,13 @@ class Form::Lettings::Questions::Sheltered < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 29 end ANSWER_OPTIONS = { "2" => { "value" => "Yes – extra care housing" }, "1" => { "value" => "Yes – specialist retirement housing" }, + "5" => { "value" => "Yes – sheltered housing for adults aged under 55 years" }, "3" => { "value" => "No" }, "divider" => { "value" => true }, "4" => { "value" => "Don’t know" }, diff --git a/app/models/form/lettings/questions/starter_tenancy.rb b/app/models/form/lettings/questions/starter_tenancy.rb deleted file mode 100644 index 9e489c129..000000000 --- a/app/models/form/lettings/questions/starter_tenancy.rb +++ /dev/null @@ -1,22 +0,0 @@ -class Form::Lettings::Questions::StarterTenancy < ::Form::Question - def initialize(id, hsh, page) - super - @id = "tenancy" - @check_answer_label = "Type of main tenancy after the starter period has ended?" - @header = "What is the type of tenancy after the starter period has ended?" - @type = "radio" - @check_answers_card_number = 0 - @hint_text = "This is also known as an ‘introductory period’." - @answer_options = ANSWER_OPTIONS - @conditional_for = { "tenancyother" => [3] } - end - - ANSWER_OPTIONS = { - "4" => { "value" => "Assured Shorthold Tenancy (AST) – Fixed term" }, - "6" => { "value" => "Secure – fixed term" }, - "2" => { "value" => "Assured – lifetime" }, - "7" => { "value" => "Secure – lifetime" }, - "5" => { "value" => "Licence agreement" }, - "3" => { "value" => "Other" }, - }.freeze -end diff --git a/app/models/form/lettings/questions/starter_tenancy_type.rb b/app/models/form/lettings/questions/starter_tenancy_type.rb new file mode 100644 index 000000000..08fc8e56d --- /dev/null +++ b/app/models/form/lettings/questions/starter_tenancy_type.rb @@ -0,0 +1,38 @@ +class Form::Lettings::Questions::StarterTenancyType < ::Form::Question + def initialize(id, hsh, page) + super + @id = "tenancy" + @check_answer_label = "Type of main tenancy after the starter period has ended?" + @header = "What is the type of tenancy after the starter period has ended?" + @type = "radio" + @check_answers_card_number = 0 + @hint_text = "This is also known as an ‘introductory period’." + @answer_options = ANSWER_OPTIONS + @conditional_for = { "tenancyother" => [3] } + @question_number = 27 + end + + ANSWER_OPTIONS = { + "4" => { + "value" => "Assured Shorthold Tenancy (AST) – Fixed term", + "hint" => "Mostly housing associations provide these. Fixed term tenancies are intended to be for a set amount of time up to 20 years.", + }, + "6" => { + "value" => "Secure – fixed term", + "hint" => "Mostly local authorities provide these. Fixed term tenancies are intended to be for a set amount of time up to 20 years.", + }, + "2" => { + "value" => "Assured – lifetime", + }, + "7" => { + "value" => "Secure – lifetime", + }, + "5" => { + "value" => "Licence agreement", + "hint" => "Licence agreements are mostly used for Supported Housing and work on a rolling basis.", + }, + "3" => { + "value" => "Other", + }, + }.freeze +end diff --git a/app/models/form/lettings/questions/startertenancy.rb b/app/models/form/lettings/questions/startertenancy.rb index 8ae35bb02..10f5946d3 100644 --- a/app/models/form/lettings/questions/startertenancy.rb +++ b/app/models/form/lettings/questions/startertenancy.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Startertenancy < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 26 end ANSWER_OPTIONS = { "1" => { "value" => "Yes" }, "2" => { "value" => "No" } }.freeze diff --git a/app/models/form/lettings/questions/stock_owner.rb b/app/models/form/lettings/questions/stock_owner.rb index 531341739..3835838c5 100644 --- a/app/models/form/lettings/questions/stock_owner.rb +++ b/app/models/form/lettings/questions/stock_owner.rb @@ -5,6 +5,7 @@ class Form::Lettings::Questions::StockOwner < ::Form::Question @check_answer_label = "Stock owner" @header = "Which organisation owns this property?" @type = "select" + @question_number = 1 end def answer_options(log = nil, user = nil) diff --git a/app/models/form/lettings/questions/supcharg_4_weekly.rb b/app/models/form/lettings/questions/supcharg_4_weekly.rb index 5540b3555..1ca7da652 100644 --- a/app/models/form/lettings/questions/supcharg_4_weekly.rb +++ b/app/models/form/lettings/questions/supcharg_4_weekly.rb @@ -12,8 +12,8 @@ class Form::Lettings::Questions::Supcharg4Weekly < ::Form::Question @step = 0.01 @fields_to_add = %w[brent scharge pscharge supcharg] @result_field = "tcharge" - @hidden_in_check_answers = true @prefix = "£" @suffix = " every 4 weeks" + @question_number = 98 end end diff --git a/app/models/form/lettings/questions/supcharg_bi_weekly.rb b/app/models/form/lettings/questions/supcharg_bi_weekly.rb index cbda5e5c9..07150f6f0 100644 --- a/app/models/form/lettings/questions/supcharg_bi_weekly.rb +++ b/app/models/form/lettings/questions/supcharg_bi_weekly.rb @@ -12,8 +12,8 @@ class Form::Lettings::Questions::SupchargBiWeekly < ::Form::Question @step = 0.01 @fields_to_add = %w[brent scharge pscharge supcharg] @result_field = "tcharge" - @hidden_in_check_answers = true @prefix = "£" @suffix = " every 2 weeks" + @question_number = 98 end end diff --git a/app/models/form/lettings/questions/supcharg_monthly.rb b/app/models/form/lettings/questions/supcharg_monthly.rb index 6b799f547..224ddc31c 100644 --- a/app/models/form/lettings/questions/supcharg_monthly.rb +++ b/app/models/form/lettings/questions/supcharg_monthly.rb @@ -12,8 +12,8 @@ class Form::Lettings::Questions::SupchargMonthly < ::Form::Question @step = 0.01 @fields_to_add = %w[brent scharge pscharge supcharg] @result_field = "tcharge" - @hidden_in_check_answers = true @prefix = "£" @suffix = " every month" + @question_number = 98 end end diff --git a/app/models/form/lettings/questions/supcharg_weekly.rb b/app/models/form/lettings/questions/supcharg_weekly.rb index 6f843db94..4e0c99057 100644 --- a/app/models/form/lettings/questions/supcharg_weekly.rb +++ b/app/models/form/lettings/questions/supcharg_weekly.rb @@ -12,8 +12,8 @@ class Form::Lettings::Questions::SupchargWeekly < ::Form::Question @step = 0.01 @fields_to_add = %w[brent scharge pscharge supcharg] @result_field = "tcharge" - @hidden_in_check_answers = true @prefix = "£" @suffix = " every week" + @question_number = 98 end end diff --git a/app/models/form/lettings/questions/tcharge_4_weekly.rb b/app/models/form/lettings/questions/tcharge_4_weekly.rb index 7438f8527..3a353efe8 100644 --- a/app/models/form/lettings/questions/tcharge_4_weekly.rb +++ b/app/models/form/lettings/questions/tcharge_4_weekly.rb @@ -15,5 +15,6 @@ class Form::Lettings::Questions::Tcharge4Weekly < ::Form::Question @suffix = " every 4 weeks" @requires_js = true @fields_added = %w[brent scharge pscharge supcharg] + @hidden_in_check_answers = true end end diff --git a/app/models/form/lettings/questions/tcharge_bi_weekly.rb b/app/models/form/lettings/questions/tcharge_bi_weekly.rb index 1dee6f2bb..42fd9398b 100644 --- a/app/models/form/lettings/questions/tcharge_bi_weekly.rb +++ b/app/models/form/lettings/questions/tcharge_bi_weekly.rb @@ -15,5 +15,6 @@ class Form::Lettings::Questions::TchargeBiWeekly < ::Form::Question @suffix = " every 2 weeks" @requires_js = true @fields_added = %w[brent scharge pscharge supcharg] + @hidden_in_check_answers = true end end diff --git a/app/models/form/lettings/questions/tcharge_monthly.rb b/app/models/form/lettings/questions/tcharge_monthly.rb index dc67c3351..3fcabdace 100644 --- a/app/models/form/lettings/questions/tcharge_monthly.rb +++ b/app/models/form/lettings/questions/tcharge_monthly.rb @@ -15,5 +15,6 @@ class Form::Lettings::Questions::TchargeMonthly < ::Form::Question @suffix = " every month" @requires_js = true @fields_added = %w[brent scharge pscharge supcharg] + @hidden_in_check_answers = true end end diff --git a/app/models/form/lettings/questions/tcharge_weekly.rb b/app/models/form/lettings/questions/tcharge_weekly.rb index 03fb8e4e2..d1ac7cb34 100644 --- a/app/models/form/lettings/questions/tcharge_weekly.rb +++ b/app/models/form/lettings/questions/tcharge_weekly.rb @@ -15,5 +15,6 @@ class Form::Lettings::Questions::TchargeWeekly < ::Form::Question @suffix = " every week" @requires_js = true @fields_added = %w[brent scharge pscharge supcharg] + @hidden_in_check_answers = true end end diff --git a/app/models/form/lettings/questions/tenancy.rb b/app/models/form/lettings/questions/tenancy.rb deleted file mode 100644 index 06a8d4fce..000000000 --- a/app/models/form/lettings/questions/tenancy.rb +++ /dev/null @@ -1,22 +0,0 @@ -class Form::Lettings::Questions::Tenancy < ::Form::Question - def initialize(id, hsh, page) - super - @id = "tenancy" - @check_answer_label = "Type of main tenancy" - @header = "What is the type of tenancy?" - @type = "radio" - @check_answers_card_number = 0 - @hint_text = "" - @answer_options = ANSWER_OPTIONS - @conditional_for = { "tenancyother" => [3] } - end - - ANSWER_OPTIONS = { - "4" => { "value" => "Assured Shorthold Tenancy (AST) – Fixed term" }, - "6" => { "value" => "Secure – fixed term" }, - "2" => { "value" => "Assured – lifetime" }, - "7" => { "value" => "Secure – lifetime" }, - "5" => { "value" => "Licence agreement" }, - "3" => { "value" => "Other" }, - }.freeze -end diff --git a/app/models/form/lettings/questions/tenancylength.rb b/app/models/form/lettings/questions/tenancy_length.rb similarity index 81% rename from app/models/form/lettings/questions/tenancylength.rb rename to app/models/form/lettings/questions/tenancy_length.rb index 426a95669..90b34aa62 100644 --- a/app/models/form/lettings/questions/tenancylength.rb +++ b/app/models/form/lettings/questions/tenancy_length.rb @@ -1,4 +1,4 @@ -class Form::Lettings::Questions::Tenancylength < ::Form::Question +class Form::Lettings::Questions::TenancyLength < ::Form::Question def initialize(id, hsh, page) super @id = "tenancylength" @@ -11,5 +11,6 @@ class Form::Lettings::Questions::Tenancylength < ::Form::Question @min = 0 @hint_text = "Don’t include the starter or introductory period." @step = 1 + @question_number = 28 end end diff --git a/app/models/form/lettings/questions/tenancyother.rb b/app/models/form/lettings/questions/tenancy_other.rb similarity index 71% rename from app/models/form/lettings/questions/tenancyother.rb rename to app/models/form/lettings/questions/tenancy_other.rb index 468d592aa..c19b03703 100644 --- a/app/models/form/lettings/questions/tenancyother.rb +++ b/app/models/form/lettings/questions/tenancy_other.rb @@ -1,4 +1,4 @@ -class Form::Lettings::Questions::Tenancyother < ::Form::Question +class Form::Lettings::Questions::TenancyOther < ::Form::Question def initialize(id, hsh, page) super @id = "tenancyother" @@ -7,5 +7,6 @@ class Form::Lettings::Questions::Tenancyother < ::Form::Question @type = "text" @check_answers_card_number = 0 @hint_text = "" + @question_number = 27 end end diff --git a/app/models/form/lettings/questions/tenancy_start_date.rb b/app/models/form/lettings/questions/tenancy_start_date.rb index b50021597..fd9d63cec 100644 --- a/app/models/form/lettings/questions/tenancy_start_date.rb +++ b/app/models/form/lettings/questions/tenancy_start_date.rb @@ -6,5 +6,6 @@ class Form::Lettings::Questions::TenancyStartDate < ::Form::Question @header = "What is the tenancy start date?" @type = "date" @unresolved_hint_text = "Some scheme details have changed, and now this log needs updating. Check that the tenancy start date is correct." + @question_number = 5 end end diff --git a/app/models/form/lettings/questions/tenancy_type.rb b/app/models/form/lettings/questions/tenancy_type.rb new file mode 100644 index 000000000..95beffbca --- /dev/null +++ b/app/models/form/lettings/questions/tenancy_type.rb @@ -0,0 +1,38 @@ +class Form::Lettings::Questions::TenancyType < ::Form::Question + def initialize(id, hsh, page) + super + @id = "tenancy" + @check_answer_label = "Type of main tenancy" + @header = "What is the type of tenancy?" + @type = "radio" + @check_answers_card_number = 0 + @hint_text = "" + @answer_options = ANSWER_OPTIONS + @conditional_for = { "tenancyother" => [3] } + @question_number = 27 + end + + ANSWER_OPTIONS = { + "4" => { + "value" => "Assured Shorthold Tenancy (AST) – Fixed term", + "hint" => "Mostly housing associations provide these. Fixed term tenancies are intended to be for a set amount of time up to 20 years.", + }, + "6" => { + "value" => "Secure – fixed term", + "hint" => "Mostly local authorities provide these. Fixed term tenancies are intended to be for a set amount of time up to 20 years.", + }, + "2" => { + "value" => "Assured – lifetime", + }, + "7" => { + "value" => "Secure – lifetime", + }, + "5" => { + "value" => "Licence agreement", + "hint" => "Licence agreements are mostly used for Supported Housing and work on a rolling basis.", + }, + "3" => { + "value" => "Other", + }, + }.freeze +end diff --git a/app/models/form/lettings/questions/tenant_code.rb b/app/models/form/lettings/questions/tenant_code.rb index 1872ebe8e..f51d33c46 100644 --- a/app/models/form/lettings/questions/tenant_code.rb +++ b/app/models/form/lettings/questions/tenant_code.rb @@ -7,5 +7,6 @@ class Form::Lettings::Questions::TenantCode < ::Form::Question @hint_text = "This is how you usually refer to this tenancy on your own systems." @type = "text" @width = 10 + @question_number = 7 end end diff --git a/app/models/form/lettings/questions/tshortfall.rb b/app/models/form/lettings/questions/tshortfall.rb index ca88f3e81..af8d32c9c 100644 --- a/app/models/form/lettings/questions/tshortfall.rb +++ b/app/models/form/lettings/questions/tshortfall.rb @@ -21,5 +21,6 @@ class Form::Lettings::Questions::Tshortfall < ::Form::Question { "label" => " every week for 46 weeks", "depends_on" => { "period" => 9 } }, { "label" => " every week for 52 weeks", "depends_on" => { "period" => 1 } }, ] + @question_number = 100 end end diff --git a/app/models/form/lettings/questions/tshortfall_known.rb b/app/models/form/lettings/questions/tshortfall_known.rb index 4f934d75a..7082af4f3 100644 --- a/app/models/form/lettings/questions/tshortfall_known.rb +++ b/app/models/form/lettings/questions/tshortfall_known.rb @@ -9,6 +9,7 @@ class Form::Lettings::Questions::TshortfallKnown < ::Form::Question @hint_text = "You only need to give an approximate figure." @answer_options = ANSWER_OPTIONS @conditional_for = { "tshortfall" => [0] } + @question_number = 100 end ANSWER_OPTIONS = { "0" => { "value" => "Yes" }, "1" => { "value" => "No" } }.freeze diff --git a/app/models/form/lettings/questions/unittype_gn.rb b/app/models/form/lettings/questions/unittype_gn.rb index 82f582722..01f38b0b9 100644 --- a/app/models/form/lettings/questions/unittype_gn.rb +++ b/app/models/form/lettings/questions/unittype_gn.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::UnittypeGn < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 19 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/voiddate.rb b/app/models/form/lettings/questions/voiddate.rb index 78e57c1ee..a91ac6ddb 100644 --- a/app/models/form/lettings/questions/voiddate.rb +++ b/app/models/form/lettings/questions/voiddate.rb @@ -6,5 +6,6 @@ class Form::Lettings::Questions::Voiddate < ::Form::Question @header = "What is the void or renewal date?" @type = "date" @check_answers_card_number = 0 + @question_number = 23 end end diff --git a/app/models/form/lettings/questions/voiddate_new_build.rb b/app/models/form/lettings/questions/voiddate_new_build.rb index 9cda12522..dcf1326b0 100644 --- a/app/models/form/lettings/questions/voiddate_new_build.rb +++ b/app/models/form/lettings/questions/voiddate_new_build.rb @@ -7,5 +7,6 @@ class Form::Lettings::Questions::VoiddateNewBuild < ::Form::Question @type = "date" @check_answers_card_number = 0 @hint_text = "" + @question_number = 23 end end diff --git a/app/models/form/lettings/questions/waityear.rb b/app/models/form/lettings/questions/waityear.rb index 74239b775..569533a9d 100644 --- a/app/models/form/lettings/questions/waityear.rb +++ b/app/models/form/lettings/questions/waityear.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Waityear < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 76 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/wheelchair.rb b/app/models/form/lettings/questions/wheelchair.rb index a841c9b66..3ba4f081f 100644 --- a/app/models/form/lettings/questions/wheelchair.rb +++ b/app/models/form/lettings/questions/wheelchair.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::Wheelchair < ::Form::Question @check_answers_card_number = 0 @hint_text = "" @answer_options = ANSWER_OPTIONS + @question_number = 21 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/questions/working_situation1.rb b/app/models/form/lettings/questions/working_situation1.rb index 20f5dc984..4975b4125 100644 --- a/app/models/form/lettings/questions/working_situation1.rb +++ b/app/models/form/lettings/questions/working_situation1.rb @@ -8,6 +8,7 @@ class Form::Lettings::Questions::WorkingSituation1 < ::Form::Question @check_answers_card_number = 1 @hint_text = "The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest." @answer_options = ANSWER_OPTIONS + @question_number = 37 end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/subsections/household_characteristics.rb b/app/models/form/lettings/subsections/household_characteristics.rb index 8a5bdf8c1..9fc6948bd 100644 --- a/app/models/form/lettings/subsections/household_characteristics.rb +++ b/app/models/form/lettings/subsections/household_characteristics.rb @@ -30,6 +30,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Lettings::Pages::LeadTenantOverRetirementValueCheck.new(nil, nil, self), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 2), Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 2), + Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 2, person_type: "child"), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 2), Form::Lettings::Pages::NoFemalesPregnantHouseholdPersonAgeValueCheck.new(nil, nil, self, person_index: 2), @@ -44,6 +45,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Lettings::Pages::PersonOverRetirementValueCheck.new(nil, nil, self, person_index: 2), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 3), Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 3), + Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 3, person_type: "child"), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 3), Form::Lettings::Pages::NoFemalesPregnantHouseholdPersonAgeValueCheck.new(nil, nil, self, person_index: 3), @@ -58,6 +60,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Lettings::Pages::PersonOverRetirementValueCheck.new(nil, nil, self, person_index: 3), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 4), Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 4), + Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 4, person_type: "child"), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 4), Form::Lettings::Pages::NoFemalesPregnantHouseholdPersonAgeValueCheck.new(nil, nil, self, person_index: 4), @@ -72,6 +75,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Lettings::Pages::PersonOverRetirementValueCheck.new(nil, nil, self, person_index: 4), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 5), Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 5), + Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 5, person_type: "child"), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 5), Form::Lettings::Pages::NoFemalesPregnantHouseholdPersonAgeValueCheck.new(nil, nil, self, person_index: 5), @@ -86,6 +90,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Lettings::Pages::PersonOverRetirementValueCheck.new(nil, nil, self, person_index: 5), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 6), Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 6), + Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 6, person_type: "child"), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 6), Form::Lettings::Pages::NoFemalesPregnantHouseholdPersonAgeValueCheck.new(nil, nil, self, person_index: 6), @@ -100,6 +105,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Lettings::Pages::PersonOverRetirementValueCheck.new(nil, nil, self, person_index: 6), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 7), Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 7), + Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 7, person_type: "child"), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 7), Form::Lettings::Pages::NoFemalesPregnantHouseholdPersonAgeValueCheck.new(nil, nil, self, person_index: 7), @@ -114,6 +120,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Lettings::Pages::PersonOverRetirementValueCheck.new(nil, nil, self, person_index: 7), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 8), Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 8), + Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 8, person_type: "child"), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 8), Form::Lettings::Pages::NoFemalesPregnantHouseholdPersonAgeValueCheck.new(nil, nil, self, person_index: 8), diff --git a/app/models/form/lettings/subsections/tenancy_information.rb b/app/models/form/lettings/subsections/tenancy_information.rb index 5f2af5215..be8e4fdce 100644 --- a/app/models/form/lettings/subsections/tenancy_information.rb +++ b/app/models/form/lettings/subsections/tenancy_information.rb @@ -13,7 +13,7 @@ class Form::Lettings::Subsections::TenancyInformation < ::Form::Subsection Form::Lettings::Pages::TenancyType.new(nil, nil, self), Form::Lettings::Pages::StarterTenancyType.new(nil, nil, self), Form::Lettings::Pages::TenancyLength.new(nil, nil, self), - Form::Lettings::Pages::Shelteredaccom.new(nil, nil, self), + Form::Lettings::Pages::ShelteredAccommodation.new(nil, nil, self), ].compact end end diff --git a/app/models/form/page.rb b/app/models/form/page.rb index ea57bac66..2ac5a716a 100644 --- a/app/models/form/page.rb +++ b/app/models/form/page.rb @@ -1,6 +1,7 @@ class Form::Page attr_accessor :id, :header, :header_partial, :description, :questions, :depends_on, :title_text, - :informative_text, :subsection, :hide_subsection_label, :next_unresolved_page_id + :informative_text, :subsection, :hide_subsection_label, :next_unresolved_page_id, + :skip_text def initialize(id, hsh, subsection) @id = id @@ -15,6 +16,7 @@ class Form::Page @informative_text = hsh["informative_text"] @hide_subsection_label = hsh["hide_subsection_label"] @next_unresolved_page_id = hsh["next_unresolved_page_id"] + @skip_text = hsh["skip_text"] end end @@ -36,6 +38,8 @@ class Form::Page questions.all? { |question| question.type == "interruption_screen" } end + def skip_href(log = nil); end + private def conditional_question_ids diff --git a/app/models/form/question.rb b/app/models/form/question.rb index fffa0059e..de77674e6 100644 --- a/app/models/form/question.rb +++ b/app/models/form/question.rb @@ -4,7 +4,7 @@ class Form::Question :conditional_for, :readonly, :answer_options, :page, :check_answer_label, :inferred_answers, :hidden_in_check_answers, :inferred_check_answers_value, :guidance_partial, :prefix, :suffix, :requires_js, :fields_added, :derived, - :check_answers_card_number, :unresolved_hint_text + :check_answers_card_number, :unresolved_hint_text, :question_number, :plain_label module GuidancePosition TOP = 1 @@ -40,6 +40,8 @@ class Form::Question @fields_added = hsh["fields_added"] @check_answers_card_number = hsh["check_answers_card_number"] || 0 @unresolved_hint_text = hsh["unresolved_hint_text"] + @question_number = hsh["question_number"] + @plain_label = hsh["plain_label"] end end @@ -56,6 +58,8 @@ class Form::Question inferred_answer_value(log) || answer_label end + def notification_banner(_log = nil); end + def get_inferred_answers(log) return [] unless inferred_answers @@ -258,6 +262,12 @@ class Form::Question selected_answer_option_is_derived?(log) || has_inferred_check_answers_value?(log) end + def question_number_string(conditional: false) + if @question_number && !conditional && form.start_date.year >= 2023 + "Q#{@question_number}" + end + end + private def selected_answer_option_is_derived?(log) diff --git a/app/models/form/sales/pages/about_deposit_with_discount.rb b/app/models/form/sales/pages/about_deposit_with_discount.rb index 6a4a54071..1c684b0bc 100644 --- a/app/models/form/sales/pages/about_deposit_with_discount.rb +++ b/app/models/form/sales/pages/about_deposit_with_discount.rb @@ -8,7 +8,7 @@ class Form::Sales::Pages::AboutDepositWithDiscount < ::Form::Page def questions @questions ||= [ - Form::Sales::Questions::DepositAmount.new(nil, nil, self), + Form::Sales::Questions::DepositAmount.new(nil, nil, self, ownershipsch: 1), Form::Sales::Questions::DepositDiscount.new(nil, nil, self), ] end diff --git a/app/models/form/sales/pages/about_deposit_without_discount.rb b/app/models/form/sales/pages/about_deposit_without_discount.rb index e8e387eba..1114b8f84 100644 --- a/app/models/form/sales/pages/about_deposit_without_discount.rb +++ b/app/models/form/sales/pages/about_deposit_without_discount.rb @@ -1,15 +1,16 @@ class Form::Sales::Pages::AboutDepositWithoutDiscount < ::Form::Page - def initialize(id, hsh, subsection) - super + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) @header = "About the deposit" @depends_on = [{ "is_type_discount?" => false, "ownershipsch" => 1 }, { "ownershipsch" => 2 }, { "ownershipsch" => 3, "mortgageused" => 1 }] + @ownershipsch = ownershipsch end def questions @questions ||= [ - Form::Sales::Questions::DepositAmount.new(nil, nil, self), + Form::Sales::Questions::DepositAmount.new(nil, nil, self, ownershipsch: @ownershipsch), ] end end diff --git a/app/models/form/sales/pages/about_price_not_rtb.rb b/app/models/form/sales/pages/about_price_not_rtb.rb index c69b9a890..2f30548c7 100644 --- a/app/models/form/sales/pages/about_price_not_rtb.rb +++ b/app/models/form/sales/pages/about_price_not_rtb.rb @@ -11,7 +11,7 @@ class Form::Sales::Pages::AboutPriceNotRtb < ::Form::Page def questions @questions ||= [ - Form::Sales::Questions::PurchasePrice.new(nil, nil, self), + Form::Sales::Questions::PurchasePrice.new(nil, nil, self, ownershipsch: 2), Form::Sales::Questions::Grant.new(nil, nil, self), ] end diff --git a/app/models/form/sales/pages/about_price_rtb.rb b/app/models/form/sales/pages/about_price_rtb.rb index 35696e966..d8d20398f 100644 --- a/app/models/form/sales/pages/about_price_rtb.rb +++ b/app/models/form/sales/pages/about_price_rtb.rb @@ -10,7 +10,7 @@ class Form::Sales::Pages::AboutPriceRtb < ::Form::Page def questions @questions ||= [ - Form::Sales::Questions::PurchasePrice.new(nil, nil, self), + Form::Sales::Questions::PurchasePrice.new(nil, nil, self, ownershipsch: 2), Form::Sales::Questions::Discount.new(nil, nil, self), ] end diff --git a/app/models/form/sales/pages/about_staircase.rb b/app/models/form/sales/pages/about_staircase.rb index 2d1a17db4..4d5882916 100644 --- a/app/models/form/sales/pages/about_staircase.rb +++ b/app/models/form/sales/pages/about_staircase.rb @@ -1,17 +1,18 @@ class Form::Sales::Pages::AboutStaircase < ::Form::Page - def initialize(id, hsh, subsection) - super - @id = "about_staircasing" + def initialize(id, hsh, subsection, joint_purchase:) + super(id, hsh, subsection) + @joint_purchase = joint_purchase @header = "About the staircasing transaction" @depends_on = [{ "staircase" => 1, + "joint_purchase?" => joint_purchase, }] end def questions @questions ||= [ Form::Sales::Questions::StaircaseBought.new(nil, nil, self), - Form::Sales::Questions::StaircaseOwned.new(nil, nil, self), + Form::Sales::Questions::StaircaseOwned.new(nil, nil, self, joint_purchase: @joint_purchase), staircase_sale_question, ].compact end diff --git a/app/models/form/sales/pages/address.rb b/app/models/form/sales/pages/address.rb new file mode 100644 index 000000000..aa8ab7e0d --- /dev/null +++ b/app/models/form/sales/pages/address.rb @@ -0,0 +1,23 @@ +class Form::Sales::Pages::Address < ::Form::Page + def initialize(id, hsh, subsection) + super + @id = "address" + @header = "What is the property's address?" + end + + def questions + @questions ||= [ + Form::Sales::Questions::AddressLine1.new(nil, nil, self), + Form::Sales::Questions::AddressLine2.new(nil, nil, self), + Form::Sales::Questions::TownOrCity.new(nil, nil, self), + Form::Sales::Questions::County.new(nil, nil, self), + Form::Sales::Questions::PostcodeForFullAddress.new(nil, nil, self), + ] + end + + def routed_to?(log, _current_user = nil) + return false if log.uprn_known.nil? + + log.uprn_confirmed != 1 || log.uprn_known.zero? + end +end diff --git a/app/models/form/sales/pages/buyer2_live_in_property.rb b/app/models/form/sales/pages/buyer2_live_in_property.rb index 9ba67080b..3c0ce7b3b 100644 --- a/app/models/form/sales/pages/buyer2_live_in_property.rb +++ b/app/models/form/sales/pages/buyer2_live_in_property.rb @@ -4,12 +4,12 @@ class Form::Sales::Pages::Buyer2LiveInProperty < ::Form::Page @id = "buyer_2_live_in_property" @depends_on = [ { - "jointpur" => 1, + "joint_purchase?" => true, "privacynotice" => 1, }, { - "jointpur" => 1, - "noint" => 1, + "joint_purchase?" => true, + "buyer_not_interviewed?" => true, }, ] end diff --git a/app/models/form/sales/pages/buyer2_living_in.rb b/app/models/form/sales/pages/buyer2_living_in.rb new file mode 100644 index 000000000..b8d32ffdc --- /dev/null +++ b/app/models/form/sales/pages/buyer2_living_in.rb @@ -0,0 +1,11 @@ +class Form::Sales::Pages::Buyer2LivingIn < ::Form::Page + def initialize(id, hsh, subsection) + super + @id = "buyer_2_living_in" + @depends_on = [{ "buyer_two_will_live_in_property?" => true }] + end + + def questions + @questions = [Form::Sales::Questions::Buyer2LivingIn.new(nil, nil, self)] + end +end diff --git a/app/models/form/sales/pages/buyer2_nationality.rb b/app/models/form/sales/pages/buyer2_nationality.rb new file mode 100644 index 000000000..3771fe331 --- /dev/null +++ b/app/models/form/sales/pages/buyer2_nationality.rb @@ -0,0 +1,11 @@ +class Form::Sales::Pages::Buyer2Nationality < ::Form::Page + def initialize(id, hsh, subsection) + super + @id = "buyer_2_nationality" + @depends_on = [{ "joint_purchase?" => true }] + end + + def questions + @questions ||= [Form::Sales::Questions::Buyer2Nationality.new(nil, nil, self)] + end +end diff --git a/app/models/form/sales/pages/buyer2_previous_housing_situation.rb b/app/models/form/sales/pages/buyer2_previous_housing_situation.rb new file mode 100644 index 000000000..c6a511243 --- /dev/null +++ b/app/models/form/sales/pages/buyer2_previous_housing_situation.rb @@ -0,0 +1,11 @@ +class Form::Sales::Pages::Buyer2PreviousHousingSituation < ::Form::Page + def initialize(id, hsh, subsection) + super + @id = "buyer_2_previous_housing_situation" + @depends_on = [{ "buyer_two_not_already_living_in_property?" => true }] + end + + def questions + @questions = [Form::Sales::Questions::PreviousTenureBuyer2.new(nil, nil, self)] + end +end diff --git a/app/models/form/sales/pages/buyer_previous.rb b/app/models/form/sales/pages/buyer_previous.rb index 361b3ba47..f37c6a847 100644 --- a/app/models/form/sales/pages/buyer_previous.rb +++ b/app/models/form/sales/pages/buyer_previous.rb @@ -1,12 +1,13 @@ class Form::Sales::Pages::BuyerPrevious < ::Form::Page - def initialize(id, hsh, subsection) - super - @id = "buyer_previous" + def initialize(id, hsh, subsection, joint_purchase:) + super(id, hsh, subsection) + @joint_purchase = joint_purchase + @depends_on = [{ "joint_purchase?" => joint_purchase }] end def questions @questions ||= [ - Form::Sales::Questions::BuyerPrevious.new(nil, nil, self), + Form::Sales::Questions::BuyerPrevious.new(nil, nil, self, joint_purchase: @joint_purchase), ] end end diff --git a/app/models/form/sales/pages/extra_borrowing.rb b/app/models/form/sales/pages/extra_borrowing.rb index 7fb8b08a4..4bb8d0530 100644 --- a/app/models/form/sales/pages/extra_borrowing.rb +++ b/app/models/form/sales/pages/extra_borrowing.rb @@ -1,6 +1,7 @@ class Form::Sales::Pages::ExtraBorrowing < ::Form::Page - def initialize(id, hsh, subsection) - super + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) + @ownershipsch = ownershipsch @header = "" @description = "" @subsection = subsection @@ -11,7 +12,7 @@ class Form::Sales::Pages::ExtraBorrowing < ::Form::Page def questions @questions ||= [ - Form::Sales::Questions::ExtraBorrowing.new(nil, nil, self), + Form::Sales::Questions::ExtraBorrowing.new(nil, nil, self, ownershipsch: @ownershipsch), ] end end diff --git a/app/models/form/sales/pages/leasehold_charges.rb b/app/models/form/sales/pages/leasehold_charges.rb index 93382cf18..a27c25e1d 100644 --- a/app/models/form/sales/pages/leasehold_charges.rb +++ b/app/models/form/sales/pages/leasehold_charges.rb @@ -1,8 +1,13 @@ class Form::Sales::Pages::LeaseholdCharges < ::Form::Page + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) + @ownershipsch = ownershipsch + end + def questions @questions ||= [ - Form::Sales::Questions::LeaseholdChargesKnown.new(nil, nil, self), - Form::Sales::Questions::LeaseholdCharges.new(nil, nil, self), + Form::Sales::Questions::LeaseholdChargesKnown.new(nil, nil, self, ownershipsch: @ownershipsch), + Form::Sales::Questions::LeaseholdCharges.new(nil, nil, self, ownershipsch: @ownershipsch), ] end end diff --git a/app/models/form/sales/pages/living_before_purchase.rb b/app/models/form/sales/pages/living_before_purchase.rb index ac61ab1de..205b75e66 100644 --- a/app/models/form/sales/pages/living_before_purchase.rb +++ b/app/models/form/sales/pages/living_before_purchase.rb @@ -1,14 +1,19 @@ class Form::Sales::Pages::LivingBeforePurchase < ::Form::Page + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) + @ownershipsch = ownershipsch + end + def questions @questions ||= [ living_before_purchase, - Form::Sales::Questions::LivingBeforePurchaseYears.new(nil, nil, self), + Form::Sales::Questions::LivingBeforePurchaseYears.new(nil, nil, self, ownershipsch: @ownershipsch), ].compact end def living_before_purchase if form.start_date.year >= 2023 - Form::Sales::Questions::LivingBeforePurchase.new(nil, nil, self) + Form::Sales::Questions::LivingBeforePurchase.new(nil, nil, self, ownershipsch: @ownershipsch) end end end diff --git a/app/models/form/sales/pages/mortgage_amount.rb b/app/models/form/sales/pages/mortgage_amount.rb index 153c3bbe6..793570b46 100644 --- a/app/models/form/sales/pages/mortgage_amount.rb +++ b/app/models/form/sales/pages/mortgage_amount.rb @@ -1,6 +1,7 @@ class Form::Sales::Pages::MortgageAmount < ::Form::Page - def initialize(id, hsh, subsection) - super + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) + @ownershipsch = ownershipsch @header = "Mortgage Amount" @depends_on = [{ "mortgageused" => 1, @@ -9,7 +10,7 @@ class Form::Sales::Pages::MortgageAmount < ::Form::Page def questions @questions ||= [ - Form::Sales::Questions::MortgageAmount.new(nil, nil, self), + Form::Sales::Questions::MortgageAmount.new(nil, nil, self, ownershipsch: @ownershipsch), ] end end diff --git a/app/models/form/sales/pages/mortgage_lender.rb b/app/models/form/sales/pages/mortgage_lender.rb index 552d7abf8..f187815b1 100644 --- a/app/models/form/sales/pages/mortgage_lender.rb +++ b/app/models/form/sales/pages/mortgage_lender.rb @@ -1,6 +1,7 @@ class Form::Sales::Pages::MortgageLender < ::Form::Page - def initialize(id, hsh, subsection) - super + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) + @ownershipsch = ownershipsch @header = "" @description = "" @subsection = subsection @@ -11,7 +12,7 @@ class Form::Sales::Pages::MortgageLender < ::Form::Page def questions @questions ||= [ - Form::Sales::Questions::MortgageLender.new(nil, nil, self), + Form::Sales::Questions::MortgageLender.new(nil, nil, self, ownershipsch: @ownershipsch), ] end end diff --git a/app/models/form/sales/pages/mortgage_lender_other.rb b/app/models/form/sales/pages/mortgage_lender_other.rb index a4f6aaf90..903a7dba8 100644 --- a/app/models/form/sales/pages/mortgage_lender_other.rb +++ b/app/models/form/sales/pages/mortgage_lender_other.rb @@ -1,6 +1,7 @@ class Form::Sales::Pages::MortgageLenderOther < ::Form::Page - def initialize(id, hsh, subsection) - super + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) + @ownershipsch = ownershipsch @header = "" @description = "" @subsection = subsection @@ -11,7 +12,7 @@ class Form::Sales::Pages::MortgageLenderOther < ::Form::Page def questions @questions ||= [ - Form::Sales::Questions::MortgageLenderOther.new(nil, nil, self), + Form::Sales::Questions::MortgageLenderOther.new(nil, nil, self, ownershipsch: @ownershipsch), ] end end diff --git a/app/models/form/sales/pages/mortgage_length.rb b/app/models/form/sales/pages/mortgage_length.rb index 979369bdd..dbc01a695 100644 --- a/app/models/form/sales/pages/mortgage_length.rb +++ b/app/models/form/sales/pages/mortgage_length.rb @@ -1,6 +1,7 @@ class Form::Sales::Pages::MortgageLength < ::Form::Page - def initialize(id, hsh, subsection) - super + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) + @ownershipsch = ownershipsch @depends_on = [{ "mortgageused" => 1, }] @@ -8,7 +9,7 @@ class Form::Sales::Pages::MortgageLength < ::Form::Page def questions @questions ||= [ - Form::Sales::Questions::MortgageLength.new(nil, nil, self), + Form::Sales::Questions::MortgageLength.new(nil, nil, self, ownershipsch: @ownershipsch), ] end end diff --git a/app/models/form/sales/pages/mortgageused.rb b/app/models/form/sales/pages/mortgageused.rb index 4a22c480e..f9d8eae2e 100644 --- a/app/models/form/sales/pages/mortgageused.rb +++ b/app/models/form/sales/pages/mortgageused.rb @@ -1,7 +1,12 @@ class Form::Sales::Pages::Mortgageused < ::Form::Page + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) + @ownershipsch = ownershipsch + end + def questions @questions ||= [ - Form::Sales::Questions::Mortgageused.new(nil, nil, self), + Form::Sales::Questions::Mortgageused.new(nil, nil, self, ownershipsch: @ownershipsch), ] end end diff --git a/app/models/form/sales/pages/nationality1.rb b/app/models/form/sales/pages/nationality1.rb index 96723e857..8db4a64ea 100644 --- a/app/models/form/sales/pages/nationality1.rb +++ b/app/models/form/sales/pages/nationality1.rb @@ -7,15 +7,12 @@ class Form::Sales::Pages::Nationality1 < ::Form::Page "privacynotice" => 1, }, { - "noint" => 1, + "buyer_not_interviewed?" => true, }, ] end def questions - @questions ||= [ - Form::Sales::Questions::Nationality1.new(nil, nil, self), - Form::Sales::Questions::OtherNationality1.new(nil, nil, self), - ] + @questions ||= [Form::Sales::Questions::Nationality1.new(nil, nil, self)] end end diff --git a/app/models/form/sales/pages/person_student_not_child_value_check.rb b/app/models/form/sales/pages/person_student_not_child_value_check.rb new file mode 100644 index 000000000..e3513e169 --- /dev/null +++ b/app/models/form/sales/pages/person_student_not_child_value_check.rb @@ -0,0 +1,21 @@ +class Form::Sales::Pages::PersonStudentNotChildValueCheck < Form::Sales::Pages::Person + def initialize(id, hsh, subsection, person_index:) + super + @depends_on = [ + { + "person_#{person_index}_student_not_child?" => true, + }, + ] + @person_index = person_index + @title_text = { + "translation" => "soft_validations.student_not_child.title_text", + } + @informative_text = {} + end + + def questions + @questions ||= [ + Form::Sales::Questions::PersonStudentNotChildValueCheck.new(nil, nil, self, person_index: @person_index), + ] + end +end diff --git a/app/models/form/sales/pages/previous_bedrooms.rb b/app/models/form/sales/pages/previous_bedrooms.rb index 87632e305..722822c2d 100644 --- a/app/models/form/sales/pages/previous_bedrooms.rb +++ b/app/models/form/sales/pages/previous_bedrooms.rb @@ -3,9 +3,14 @@ class Form::Sales::Pages::PreviousBedrooms < ::Form::Page super @id = "previous_bedrooms" @header = "About the buyers’ previous property" - @depends_on = [{ - "soctenant" => 1, - }] + @depends_on = [ + { + "soctenant" => 1, + }, + { + "soctenant" => 0, + }, + ] end def questions diff --git a/app/models/form/sales/pages/previous_ownership.rb b/app/models/form/sales/pages/previous_ownership.rb index 88b438e07..50711baf7 100644 --- a/app/models/form/sales/pages/previous_ownership.rb +++ b/app/models/form/sales/pages/previous_ownership.rb @@ -1,12 +1,13 @@ class Form::Sales::Pages::PreviousOwnership < ::Form::Page - def initialize(id, hsh, subsection) - super - @id = "previous_ownership" + def initialize(id, hsh, subsection, joint_purchase:) + super(id, hsh, subsection) + @joint_purchase = joint_purchase + @depends_on = [{ "joint_purchase?" => @joint_purchase }] end def questions @questions ||= [ - Form::Sales::Questions::Prevown.new(nil, nil, self), + Form::Sales::Questions::Prevown.new(nil, nil, self, joint_purchase: @joint_purchase), ] end end diff --git a/app/models/form/sales/pages/previous_property_type.rb b/app/models/form/sales/pages/previous_property_type.rb index 8555fdc79..8c46963d0 100644 --- a/app/models/form/sales/pages/previous_property_type.rb +++ b/app/models/form/sales/pages/previous_property_type.rb @@ -5,9 +5,14 @@ class Form::Sales::Pages::PreviousPropertyType < ::Form::Page @header = "" @description = "" @subsection = subsection - @depends_on = [{ - "soctenant" => 1, - }] + @depends_on = [ + { + "soctenant" => 1, + }, + { + "soctenant" => 0, + }, + ] end def questions diff --git a/app/models/form/sales/pages/previous_tenure.rb b/app/models/form/sales/pages/previous_tenure.rb index a830898a0..0f4a4b250 100644 --- a/app/models/form/sales/pages/previous_tenure.rb +++ b/app/models/form/sales/pages/previous_tenure.rb @@ -5,9 +5,14 @@ class Form::Sales::Pages::PreviousTenure < ::Form::Page @header = "" @description = "" @subsection = subsection - @depends_on = [{ - "soctenant" => 1, - }] + @depends_on = [ + { + "soctenant" => 1, + }, + { + "soctenant" => 0, + }, + ] end def questions diff --git a/app/models/form/sales/pages/property_local_authority.rb b/app/models/form/sales/pages/property_local_authority.rb index 7e63b2f6c..66c4b965b 100644 --- a/app/models/form/sales/pages/property_local_authority.rb +++ b/app/models/form/sales/pages/property_local_authority.rb @@ -9,8 +9,20 @@ class Form::Sales::Pages::PropertyLocalAuthority < ::Form::Page def questions @questions ||= [ - Form::Sales::Questions::PropertyLocalAuthorityKnown.new(nil, nil, self), + la_known_question, Form::Sales::Questions::PropertyLocalAuthority.new(nil, nil, self), - ] + ].compact + end + + def routed_to?(log, _current_user = nil) + return false if log.uprn_known.nil? && form.start_date.year >= 2023 + + true + end + + def la_known_question + if form.start_date.year < 2023 + Form::Sales::Questions::PropertyLocalAuthorityKnown.new(nil, nil, self) + end end end diff --git a/app/models/form/sales/pages/purchase_price_outright_ownership.rb b/app/models/form/sales/pages/purchase_price_outright_ownership.rb index 6bf044d01..a5e995ed6 100644 --- a/app/models/form/sales/pages/purchase_price_outright_ownership.rb +++ b/app/models/form/sales/pages/purchase_price_outright_ownership.rb @@ -1,14 +1,15 @@ class Form::Sales::Pages::PurchasePriceOutrightOwnership < ::Form::Page - def initialize(id, hsh, subsection) - super + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) @depends_on = [ { "outright_sale_or_discounted_with_full_ownership?" => true }, ] + @ownershipsch = ownershipsch end def questions @questions ||= [ - Form::Sales::Questions::PurchasePriceOutrightOwnership.new(nil, nil, self), + Form::Sales::Questions::PurchasePrice.new(nil, nil, self, ownershipsch: @ownershipsch), ] end end diff --git a/app/models/form/sales/pages/uprn.rb b/app/models/form/sales/pages/uprn.rb new file mode 100644 index 000000000..e1835f8ca --- /dev/null +++ b/app/models/form/sales/pages/uprn.rb @@ -0,0 +1,26 @@ +class Form::Sales::Pages::Uprn < ::Form::Page + def initialize(id, hsh, subsection) + super + @id = "uprn" + end + + def questions + @questions ||= [ + Form::Sales::Questions::Uprn.new(nil, nil, self), + ] + end + + def routed_to?(log, _current_user = nil) + log.uprn_known == 1 + end + + def skip_text + "Enter address instead" + end + + def skip_href(log = nil) + return unless log + + "/#{log.model_name.param_key.dasherize}s/#{log.id}/address" + end +end diff --git a/app/models/form/sales/pages/uprn_confirmation.rb b/app/models/form/sales/pages/uprn_confirmation.rb new file mode 100644 index 000000000..d553972a3 --- /dev/null +++ b/app/models/form/sales/pages/uprn_confirmation.rb @@ -0,0 +1,17 @@ +class Form::Sales::Pages::UprnConfirmation < ::Form::Page + def initialize(id, hsh, subsection) + super + @id = "uprn_confirmation" + @header = "We found an address that might be this property" + end + + def questions + @questions ||= [ + Form::Sales::Questions::UprnConfirmation.new(nil, nil, self), + ] + end + + def routed_to?(log, _current_user = nil) + log.uprn.present? && log.uprn_known == 1 + end +end diff --git a/app/models/form/sales/pages/uprn_known.rb b/app/models/form/sales/pages/uprn_known.rb new file mode 100644 index 000000000..e2cbfe63f --- /dev/null +++ b/app/models/form/sales/pages/uprn_known.rb @@ -0,0 +1,12 @@ +class Form::Sales::Pages::UprnKnown < ::Form::Page + def initialize(id, hsh, subsection) + super + @id = "uprn_known" + end + + def questions + @questions ||= [ + Form::Sales::Questions::UprnKnown.new(nil, nil, self), + ] + end +end diff --git a/app/models/form/sales/questions/address_line1.rb b/app/models/form/sales/questions/address_line1.rb new file mode 100644 index 000000000..e8ccb17c0 --- /dev/null +++ b/app/models/form/sales/questions/address_line1.rb @@ -0,0 +1,37 @@ +class Form::Sales::Questions::AddressLine1 < ::Form::Question + def initialize(id, hsh, page) + super + @id = "address_line1" + @check_answer_label = "Address" + @header = "Address line 1" + @type = "text" + @plain_label = true + end + + def hidden_in_check_answers?(log, _current_user = nil) + return true if log.uprn_known.nil? + return false if log.uprn_known&.zero? + return true if log.uprn_confirmed.nil? && log.uprn.present? + return true if log.uprn_known == 1 && log.uprn.blank? + + log.uprn_confirmed == 1 + end + + def answer_label(log, _current_user = nil) + [ + log.address_line1, + log.address_line2, + log.postcode_full, + log.town_or_city, + log.county, + ].select(&:present?).join("\n") + end + + def get_extra_check_answer_value(log) + return unless log.is_la_inferred? + + la = LocalAuthority.find_by(code: log.la)&.name + + la.presence + end +end diff --git a/app/models/form/sales/questions/address_line2.rb b/app/models/form/sales/questions/address_line2.rb new file mode 100644 index 000000000..0b4ff661c --- /dev/null +++ b/app/models/form/sales/questions/address_line2.rb @@ -0,0 +1,13 @@ +class Form::Sales::Questions::AddressLine2 < ::Form::Question + def initialize(id, hsh, page) + super + @id = "address_line2" + @header = "Address line 2 (optional)" + @type = "text" + @plain_label = true + end + + def hidden_in_check_answers?(_log = nil, _current_user = nil) + true + end +end diff --git a/app/models/form/sales/questions/age1.rb b/app/models/form/sales/questions/age1.rb index 94d40100f..d32083b53 100644 --- a/app/models/form/sales/questions/age1.rb +++ b/app/models/form/sales/questions/age1.rb @@ -19,5 +19,6 @@ class Form::Sales::Questions::Age1 < ::Form::Question @check_answers_card_number = 1 @min = 16 @max = 110 + @question_number = 20 end end diff --git a/app/models/form/sales/questions/age2.rb b/app/models/form/sales/questions/age2.rb index 9ba347ec8..c0dc567a1 100644 --- a/app/models/form/sales/questions/age2.rb +++ b/app/models/form/sales/questions/age2.rb @@ -13,5 +13,6 @@ class Form::Sales::Questions::Age2 < ::Form::Question @check_answers_card_number = 2 @max = 110 @min = 0 + @question_number = 28 end end diff --git a/app/models/form/sales/questions/armed_forces.rb b/app/models/form/sales/questions/armed_forces.rb index af003c5b2..3d5aa5621 100644 --- a/app/models/form/sales/questions/armed_forces.rb +++ b/app/models/form/sales/questions/armed_forces.rb @@ -7,6 +7,7 @@ class Form::Sales::Questions::ArmedForces < ::Form::Question @type = "radio" @hint_text = "A regular is somebody who has served in the Royal Navy, the Royal Marines, the Royal Airforce or Army full time and does not include reserve forces" @answer_options = ANSWER_OPTIONS + @question_number = 62 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/armed_forces_spouse.rb b/app/models/form/sales/questions/armed_forces_spouse.rb index cf38bd434..f6857d6b7 100644 --- a/app/models/form/sales/questions/armed_forces_spouse.rb +++ b/app/models/form/sales/questions/armed_forces_spouse.rb @@ -6,6 +6,7 @@ class Form::Sales::Questions::ArmedForcesSpouse < ::Form::Question @header = "Are any of the buyers a spouse or civil partner of a UK armed forces regular who died in service within the last 2 years?" @type = "radio" @answer_options = ANSWER_OPTIONS + @question_number = 64 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer1_age_known.rb b/app/models/form/sales/questions/buyer1_age_known.rb index 761bacddb..566ae8f7d 100644 --- a/app/models/form/sales/questions/buyer1_age_known.rb +++ b/app/models/form/sales/questions/buyer1_age_known.rb @@ -24,6 +24,7 @@ class Form::Sales::Questions::Buyer1AgeKnown < ::Form::Question ], } @check_answers_card_number = 1 + @question_number = 20 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer1_ethnic_background_arab.rb b/app/models/form/sales/questions/buyer1_ethnic_background_arab.rb index 19526f5b7..5b603deda 100644 --- a/app/models/form/sales/questions/buyer1_ethnic_background_arab.rb +++ b/app/models/form/sales/questions/buyer1_ethnic_background_arab.rb @@ -3,11 +3,12 @@ class Form::Sales::Questions::Buyer1EthnicBackgroundArab < ::Form::Question super @id = "ethnic" @check_answer_label = "Buyer 1’s ethnic background" - @header = "Which of the following best describes the buyer 1’s Arab background?" + @header = "Which of the following best describes buyer 1’s Arab background?" @type = "radio" @answer_options = ANSWER_OPTIONS @hint_text = "Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest." @check_answers_card_number = 1 + @question_number = 23 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer1_ethnic_background_asian.rb b/app/models/form/sales/questions/buyer1_ethnic_background_asian.rb index ee910c054..4e851edd3 100644 --- a/app/models/form/sales/questions/buyer1_ethnic_background_asian.rb +++ b/app/models/form/sales/questions/buyer1_ethnic_background_asian.rb @@ -3,11 +3,12 @@ class Form::Sales::Questions::Buyer1EthnicBackgroundAsian < ::Form::Question super @id = "ethnic" @check_answer_label = "Buyer 1’s ethnic background" - @header = "Which of the following best describes the buyer 1’s Asian or Asian British background?" + @header = "Which of the following best describes buyer 1’s Asian or Asian British background?" @type = "radio" @answer_options = ANSWER_OPTIONS @hint_text = "Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest." @check_answers_card_number = 1 + @question_number = 23 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer1_ethnic_background_black.rb b/app/models/form/sales/questions/buyer1_ethnic_background_black.rb index 4c24f1433..16e341a5a 100644 --- a/app/models/form/sales/questions/buyer1_ethnic_background_black.rb +++ b/app/models/form/sales/questions/buyer1_ethnic_background_black.rb @@ -3,11 +3,12 @@ class Form::Sales::Questions::Buyer1EthnicBackgroundBlack < ::Form::Question super @id = "ethnic" @check_answer_label = "Buyer 1’s ethnic background" - @header = "Which of the following best describes the buyer 1’s Black, African, Caribbean or Black British background?" + @header = "Which of the following best describes buyer 1’s Black, African, Caribbean or Black British background?" @type = "radio" @answer_options = ANSWER_OPTIONS @hint_text = "Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest." @check_answers_card_number = 1 + @question_number = 23 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer1_ethnic_background_mixed.rb b/app/models/form/sales/questions/buyer1_ethnic_background_mixed.rb index 8fa879949..b35a4563f 100644 --- a/app/models/form/sales/questions/buyer1_ethnic_background_mixed.rb +++ b/app/models/form/sales/questions/buyer1_ethnic_background_mixed.rb @@ -3,11 +3,12 @@ class Form::Sales::Questions::Buyer1EthnicBackgroundMixed < ::Form::Question super @id = "ethnic" @check_answer_label = "Buyer 1’s ethnic background" - @header = "Which of the following best describes the buyer 1’s Mixed or Multiple ethnic groups background?" + @header = "Which of the following best describes buyer 1’s Mixed or Multiple ethnic groups background?" @type = "radio" @answer_options = ANSWER_OPTIONS @hint_text = "Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest." @check_answers_card_number = 1 + @question_number = 23 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer1_ethnic_background_white.rb b/app/models/form/sales/questions/buyer1_ethnic_background_white.rb index 4b7ec9182..644839979 100644 --- a/app/models/form/sales/questions/buyer1_ethnic_background_white.rb +++ b/app/models/form/sales/questions/buyer1_ethnic_background_white.rb @@ -3,11 +3,12 @@ class Form::Sales::Questions::Buyer1EthnicBackgroundWhite < ::Form::Question super @id = "ethnic" @check_answer_label = "Buyer 1’s ethnic background" - @header = "Which of the following best describes the buyer 1’s White background?" + @header = "Which of the following best describes buyer 1’s White background?" @type = "radio" @answer_options = ANSWER_OPTIONS @hint_text = "Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest." @check_answers_card_number = 1 + @question_number = 23 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer1_ethnic_group.rb b/app/models/form/sales/questions/buyer1_ethnic_group.rb index ab151d84d..c33641b73 100644 --- a/app/models/form/sales/questions/buyer1_ethnic_group.rb +++ b/app/models/form/sales/questions/buyer1_ethnic_group.rb @@ -14,6 +14,7 @@ class Form::Sales::Questions::Buyer1EthnicGroup < ::Form::Question "value" => "Prefers not to say", }] @check_answers_card_number = 1 + @question_number = 22 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer1_income.rb b/app/models/form/sales/questions/buyer1_income.rb index 43451af50..089747d8e 100644 --- a/app/models/form/sales/questions/buyer1_income.rb +++ b/app/models/form/sales/questions/buyer1_income.rb @@ -12,5 +12,6 @@ class Form::Sales::Questions::Buyer1Income < ::Form::Question @width = 5 @prefix = "£" @check_answers_card_number = 1 + @question_number = 67 end end diff --git a/app/models/form/sales/questions/buyer1_income_known.rb b/app/models/form/sales/questions/buyer1_income_known.rb index 64462fa59..b5fb9e1f1 100644 --- a/app/models/form/sales/questions/buyer1_income_known.rb +++ b/app/models/form/sales/questions/buyer1_income_known.rb @@ -2,7 +2,7 @@ class Form::Sales::Questions::Buyer1IncomeKnown < ::Form::Question def initialize(id, hsh, page) super @id = "income1nk" - @check_answer_label = "Buyer 1’s gross annual income" + @check_answer_label = "Buyer 1’s gross annual income known?" @header = "Do you know buyer 1’s annual income?" @type = "radio" @answer_options = ANSWER_OPTIONS @@ -10,6 +10,14 @@ class Form::Sales::Questions::Buyer1IncomeKnown < ::Form::Question "income1" => [0], } @check_answers_card_number = 1 + @question_number = 67 + @hidden_in_check_answers = { + "depends_on" => [ + { + "income1nk" => 0, + }, + ], + } end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer1_live_in_property.rb b/app/models/form/sales/questions/buyer1_live_in_property.rb index 4f18f60df..72c269fc9 100644 --- a/app/models/form/sales/questions/buyer1_live_in_property.rb +++ b/app/models/form/sales/questions/buyer1_live_in_property.rb @@ -8,6 +8,7 @@ class Form::Sales::Questions::Buyer1LiveInProperty < ::Form::Question @answer_options = ANSWER_OPTIONS @hint_text = "Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest." @check_answers_card_number = 1 + @question_number = 26 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer1_mortgage.rb b/app/models/form/sales/questions/buyer1_mortgage.rb index baaf00d4c..6db5a699f 100644 --- a/app/models/form/sales/questions/buyer1_mortgage.rb +++ b/app/models/form/sales/questions/buyer1_mortgage.rb @@ -7,6 +7,7 @@ class Form::Sales::Questions::Buyer1Mortgage < ::Form::Question @type = "radio" @answer_options = ANSWER_OPTIONS @check_answers_card_number = 1 + @question_number = 68 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer1_previous_tenure.rb b/app/models/form/sales/questions/buyer1_previous_tenure.rb index f3482a03f..6341bee8f 100644 --- a/app/models/form/sales/questions/buyer1_previous_tenure.rb +++ b/app/models/form/sales/questions/buyer1_previous_tenure.rb @@ -6,17 +6,18 @@ class Form::Sales::Questions::Buyer1PreviousTenure < ::Form::Question @header = "What was buyer 1’s previous tenure?" @type = "radio" @answer_options = answer_options + @question_number = 56 end def answer_options { - "1" => { "value" => "Local Authority" }, + "1" => { "value" => "Local authority tenant" }, "2" => { "value" => "Private registered provider or housing association tenant" }, "3" => { "value" => "Private tenant" }, "5" => { "value" => "Owner occupier" }, "4" => { "value" => "Tied home or renting with job" }, "6" => { "value" => "Living with family or friends" }, - "7" => { "value" => "Temporary accomodation" }, + "7" => { "value" => "Temporary accommodation" }, "9" => { "value" => "Other" }, "0" => { "value" => "Don’t know" }, } diff --git a/app/models/form/sales/questions/buyer1_working_situation.rb b/app/models/form/sales/questions/buyer1_working_situation.rb index 79db1790b..8d88e2422 100644 --- a/app/models/form/sales/questions/buyer1_working_situation.rb +++ b/app/models/form/sales/questions/buyer1_working_situation.rb @@ -14,6 +14,7 @@ class Form::Sales::Questions::Buyer1WorkingSituation < ::Form::Question }, "value" => "Prefers not to say", }] + @question_number = 25 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer2_age_known.rb b/app/models/form/sales/questions/buyer2_age_known.rb index c100d0b67..c71123452 100644 --- a/app/models/form/sales/questions/buyer2_age_known.rb +++ b/app/models/form/sales/questions/buyer2_age_known.rb @@ -20,6 +20,7 @@ class Form::Sales::Questions::Buyer2AgeKnown < ::Form::Question ], } @check_answers_card_number = 2 + @question_number = 28 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer2_ethnic_background_arab.rb b/app/models/form/sales/questions/buyer2_ethnic_background_arab.rb index 1766780b7..d2c590c0a 100644 --- a/app/models/form/sales/questions/buyer2_ethnic_background_arab.rb +++ b/app/models/form/sales/questions/buyer2_ethnic_background_arab.rb @@ -3,10 +3,11 @@ class Form::Sales::Questions::Buyer2EthnicBackgroundArab < ::Form::Question super @id = "ethnicbuy2" @check_answer_label = "Buyer 2’s ethnic background" - @header = "Which of the following best describes the buyer 2’s Arab background?" + @header = "Which of the following best describes buyer 2’s Arab background?" @type = "radio" @answer_options = ANSWER_OPTIONS @check_answers_card_number = 2 + @question_number = 31 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer2_ethnic_background_asian.rb b/app/models/form/sales/questions/buyer2_ethnic_background_asian.rb index 2578d220a..e74d5a4ba 100644 --- a/app/models/form/sales/questions/buyer2_ethnic_background_asian.rb +++ b/app/models/form/sales/questions/buyer2_ethnic_background_asian.rb @@ -3,10 +3,11 @@ class Form::Sales::Questions::Buyer2EthnicBackgroundAsian < ::Form::Question super @id = "ethnicbuy2" @check_answer_label = "Buyer 2’s ethnic background" - @header = "Which of the following best describes the buyer 2’s Asian or Asian British background?" + @header = "Which of the following best describes buyer 2’s Asian or Asian British background?" @type = "radio" @answer_options = ANSWER_OPTIONS @check_answers_card_number = 2 + @question_number = 31 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer2_ethnic_background_black.rb b/app/models/form/sales/questions/buyer2_ethnic_background_black.rb index 11d47790c..8442e9431 100644 --- a/app/models/form/sales/questions/buyer2_ethnic_background_black.rb +++ b/app/models/form/sales/questions/buyer2_ethnic_background_black.rb @@ -3,10 +3,11 @@ class Form::Sales::Questions::Buyer2EthnicBackgroundBlack < ::Form::Question super @id = "ethnicbuy2" @check_answer_label = "Buyer 2’s ethnic background" - @header = "Which of the following best describes the buyer 2’s Black, African, Caribbean or Black British background?" + @header = "Which of the following best describes buyer 2’s Black, African, Caribbean or Black British background?" @type = "radio" @answer_options = ANSWER_OPTIONS @check_answers_card_number = 2 + @question_number = 31 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer2_ethnic_background_mixed.rb b/app/models/form/sales/questions/buyer2_ethnic_background_mixed.rb index 78600af34..a610644ef 100644 --- a/app/models/form/sales/questions/buyer2_ethnic_background_mixed.rb +++ b/app/models/form/sales/questions/buyer2_ethnic_background_mixed.rb @@ -3,10 +3,11 @@ class Form::Sales::Questions::Buyer2EthnicBackgroundMixed < ::Form::Question super @id = "ethnicbuy2" @check_answer_label = "Buyer 2’s ethnic background" - @header = "Which of the following best describes the buyer 2’s Mixed or Multiple ethnic groups background?" + @header = "Which of the following best describes buyer 2’s Mixed or Multiple ethnic groups background?" @type = "radio" @answer_options = ANSWER_OPTIONS @check_answers_card_number = 2 + @question_number = 31 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer2_ethnic_background_white.rb b/app/models/form/sales/questions/buyer2_ethnic_background_white.rb index 5b5fc8e2c..1500072e1 100644 --- a/app/models/form/sales/questions/buyer2_ethnic_background_white.rb +++ b/app/models/form/sales/questions/buyer2_ethnic_background_white.rb @@ -3,10 +3,11 @@ class Form::Sales::Questions::Buyer2EthnicBackgroundWhite < ::Form::Question super @id = "ethnicbuy2" @check_answer_label = "Buyer 2’s ethnic background" - @header = "Which of the following best describes the buyer 2’s White background?" + @header = "Which of the following best describes buyer 2’s White background?" @type = "radio" @answer_options = ANSWER_OPTIONS @check_answers_card_number = 2 + @question_number = 31 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer2_ethnic_group.rb b/app/models/form/sales/questions/buyer2_ethnic_group.rb index 5366910fe..dd0ab8866 100644 --- a/app/models/form/sales/questions/buyer2_ethnic_group.rb +++ b/app/models/form/sales/questions/buyer2_ethnic_group.rb @@ -13,6 +13,7 @@ class Form::Sales::Questions::Buyer2EthnicGroup < ::Form::Question "value" => "Prefers not to say", }] @check_answers_card_number = 2 + @question_number = 30 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer2_income.rb b/app/models/form/sales/questions/buyer2_income.rb index f7d96720b..8cc0cd288 100644 --- a/app/models/form/sales/questions/buyer2_income.rb +++ b/app/models/form/sales/questions/buyer2_income.rb @@ -12,5 +12,6 @@ class Form::Sales::Questions::Buyer2Income < ::Form::Question @width = 5 @prefix = "£" @check_answers_card_number = 2 + @question_number = 69 end end diff --git a/app/models/form/sales/questions/buyer2_income_known.rb b/app/models/form/sales/questions/buyer2_income_known.rb index 0b4613809..7409383fa 100644 --- a/app/models/form/sales/questions/buyer2_income_known.rb +++ b/app/models/form/sales/questions/buyer2_income_known.rb @@ -2,7 +2,7 @@ class Form::Sales::Questions::Buyer2IncomeKnown < ::Form::Question def initialize(id, hsh, page) super @id = "income2nk" - @check_answer_label = "Buyer 2’s gross annual income" + @check_answer_label = "Buyer 2’s gross annual income known?" @header = "Do you know buyer 2’s annual income?" @type = "radio" @answer_options = ANSWER_OPTIONS @@ -10,6 +10,14 @@ class Form::Sales::Questions::Buyer2IncomeKnown < ::Form::Question "income2" => [0], } @check_answers_card_number = 2 + @question_number = 69 + @hidden_in_check_answers = { + "depends_on" => [ + { + "income2nk" => 0, + }, + ], + } end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer2_live_in_property.rb b/app/models/form/sales/questions/buyer2_live_in_property.rb index 162627905..367a434b4 100644 --- a/app/models/form/sales/questions/buyer2_live_in_property.rb +++ b/app/models/form/sales/questions/buyer2_live_in_property.rb @@ -7,6 +7,7 @@ class Form::Sales::Questions::Buyer2LiveInProperty < ::Form::Question @type = "radio" @answer_options = ANSWER_OPTIONS @check_answers_card_number = 2 + @question_number = 34 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer2_living_in.rb b/app/models/form/sales/questions/buyer2_living_in.rb new file mode 100644 index 000000000..9440e1370 --- /dev/null +++ b/app/models/form/sales/questions/buyer2_living_in.rb @@ -0,0 +1,18 @@ +class Form::Sales::Questions::Buyer2LivingIn < ::Form::Question + def initialize(id, hsh, page) + super + @id = "buy2living" + @check_answer_label = "Buyer 2 living at the same address" + @header = "At the time of purchase, was buyer 2 living at the same address as buyer 1?" + @type = "radio" + @hint_text = "" + @answer_options = ANSWER_OPTIONS + @question_number = 60 + end + + ANSWER_OPTIONS = { + "1" => { "value" => "Yes" }, + "2" => { "value" => "No" }, + "3" => { "value" => "Don't know" }, + }.freeze +end diff --git a/app/models/form/sales/questions/buyer2_mortgage.rb b/app/models/form/sales/questions/buyer2_mortgage.rb index 884137df1..9c0ef029f 100644 --- a/app/models/form/sales/questions/buyer2_mortgage.rb +++ b/app/models/form/sales/questions/buyer2_mortgage.rb @@ -7,6 +7,7 @@ class Form::Sales::Questions::Buyer2Mortgage < ::Form::Question @type = "radio" @answer_options = ANSWER_OPTIONS @check_answers_card_number = 2 + @question_number = 70 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer2_nationality.rb b/app/models/form/sales/questions/buyer2_nationality.rb new file mode 100644 index 000000000..d2056822e --- /dev/null +++ b/app/models/form/sales/questions/buyer2_nationality.rb @@ -0,0 +1,26 @@ +class Form::Sales::Questions::Buyer2Nationality < ::Form::Question + def initialize(id, hsh, page) + super + @id = "nationalbuy2" + @check_answer_label = "Buyer 2’s nationality" + @header = "What is buyer 2’s nationality?" + @type = "radio" + @answer_options = ANSWER_OPTIONS + @check_answers_card_number = 2 + @question_number = 32 + @inferred_check_answers_value = [{ + "condition" => { + "national" => 13, + }, + "value" => "Prefers not to say", + }] + end + + ANSWER_OPTIONS = { + "18" => { "value" => "United Kingdom" }, + "17" => { "value" => "Republic of Ireland" }, + "19" => { "value" => "European Economic Area (EEA), excluding ROI" }, + "12" => { "value" => "Other" }, + "13" => { "value" => "Buyer prefers not to say" }, + }.freeze +end diff --git a/app/models/form/sales/questions/buyer2_relationship_to_buyer1.rb b/app/models/form/sales/questions/buyer2_relationship_to_buyer1.rb index 678219be8..2d5ed8427 100644 --- a/app/models/form/sales/questions/buyer2_relationship_to_buyer1.rb +++ b/app/models/form/sales/questions/buyer2_relationship_to_buyer1.rb @@ -13,6 +13,7 @@ class Form::Sales::Questions::Buyer2RelationshipToBuyer1 < ::Form::Question }, "value" => "Prefers not to say", }] + @question_number = 27 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer2_working_situation.rb b/app/models/form/sales/questions/buyer2_working_situation.rb index 21c68b456..9cd82cd68 100644 --- a/app/models/form/sales/questions/buyer2_working_situation.rb +++ b/app/models/form/sales/questions/buyer2_working_situation.rb @@ -13,6 +13,7 @@ class Form::Sales::Questions::Buyer2WorkingSituation < ::Form::Question }, "value" => "Prefers not to say", }] + @question_number = 33 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer_company.rb b/app/models/form/sales/questions/buyer_company.rb index 1dac995b0..55a84019a 100644 --- a/app/models/form/sales/questions/buyer_company.rb +++ b/app/models/form/sales/questions/buyer_company.rb @@ -6,6 +6,7 @@ class Form::Sales::Questions::BuyerCompany < ::Form::Question @header = "Is the buyer a company?" @type = "radio" @answer_options = ANSWER_OPTIONS + @question_number = 7 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer_interview.rb b/app/models/form/sales/questions/buyer_interview.rb index b157c05cc..aa737171f 100644 --- a/app/models/form/sales/questions/buyer_interview.rb +++ b/app/models/form/sales/questions/buyer_interview.rb @@ -7,6 +7,7 @@ class Form::Sales::Questions::BuyerInterview < ::Form::Question @type = "radio" @hint_text = "You should still try to answer all questions even if the buyer wasn't interviewed in person" @answer_options = ANSWER_OPTIONS + @question_number = 18 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer_live.rb b/app/models/form/sales/questions/buyer_live.rb index a8aeb0401..ee0a79611 100644 --- a/app/models/form/sales/questions/buyer_live.rb +++ b/app/models/form/sales/questions/buyer_live.rb @@ -6,6 +6,7 @@ class Form::Sales::Questions::BuyerLive < ::Form::Question @header = "Will the buyers live in the property?" @type = "radio" @answer_options = ANSWER_OPTIONS + @question_number = 8 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyer_previous.rb b/app/models/form/sales/questions/buyer_previous.rb index 18ac019cb..aaea81cfc 100644 --- a/app/models/form/sales/questions/buyer_previous.rb +++ b/app/models/form/sales/questions/buyer_previous.rb @@ -1,15 +1,24 @@ class Form::Sales::Questions::BuyerPrevious < ::Form::Question - def initialize(id, hsh, page) - super + def initialize(id, hsh, page, joint_purchase:) + super(id, hsh, page) @id = "soctenant" - @check_answer_label = "Buyer was a registered provider, housing association or local authority tenant immediately before this sale?" - @header = "Was the buyer a private registered provider, housing association or local authority tenant immediately before this sale?" + @check_answer_label = I18n.t("check_answer_labels.soctenant", count: joint_purchase ? 2 : 1) + @header = I18n.t("questions.soctenant", count: joint_purchase ? 2 : 1) @type = "radio" @answer_options = ANSWER_OPTIONS + @question_number = 84 end ANSWER_OPTIONS = { "1" => { "value" => "Yes" }, "2" => { "value" => "No" }, + "0" => { "value" => "Don’t know" }, }.freeze + + def displayed_answer_options(_log, _user = nil) + { + "1" => { "value" => "Yes" }, + "2" => { "value" => "No" }, + } + end end diff --git a/app/models/form/sales/questions/buyer_still_serving.rb b/app/models/form/sales/questions/buyer_still_serving.rb index 04929fb42..75a525d1b 100644 --- a/app/models/form/sales/questions/buyer_still_serving.rb +++ b/app/models/form/sales/questions/buyer_still_serving.rb @@ -6,6 +6,7 @@ class Form::Sales::Questions::BuyerStillServing < ::Form::Question @header = "Is the buyer still serving in the UK armed forces?" @type = "radio" @answer_options = ANSWER_OPTIONS + @question_number = 63 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/buyers_organisations.rb b/app/models/form/sales/questions/buyers_organisations.rb index ec76aebcd..1ab8a81e8 100644 --- a/app/models/form/sales/questions/buyers_organisations.rb +++ b/app/models/form/sales/questions/buyers_organisations.rb @@ -7,6 +7,7 @@ class Form::Sales::Questions::BuyersOrganisations < ::Form::Question @type = "checkbox" @hint_text = "Select all that apply" @answer_options = ANSWER_OPTIONS + @question_number = 59 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/county.rb b/app/models/form/sales/questions/county.rb new file mode 100644 index 000000000..080ac809f --- /dev/null +++ b/app/models/form/sales/questions/county.rb @@ -0,0 +1,13 @@ +class Form::Sales::Questions::County < ::Form::Question + def initialize(id, hsh, page) + super + @id = "county" + @header = "County (optional)" + @type = "text" + @plain_label = true + end + + def hidden_in_check_answers?(_log = nil, _current_user = nil) + true + end +end diff --git a/app/models/form/sales/questions/deposit_amount.rb b/app/models/form/sales/questions/deposit_amount.rb index e4fd4ceb2..fb6c0e563 100644 --- a/app/models/form/sales/questions/deposit_amount.rb +++ b/app/models/form/sales/questions/deposit_amount.rb @@ -1,6 +1,6 @@ class Form::Sales::Questions::DepositAmount < ::Form::Question - def initialize(id, hsh, page) - super + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) @id = "deposit" @check_answer_label = "Cash deposit" @header = "How much cash deposit was paid on the property?" @@ -11,9 +11,22 @@ class Form::Sales::Questions::DepositAmount < ::Form::Question @prefix = "£" @hint_text = "Enter the total cash sum paid by the buyer towards the property that was not funded by the mortgage" @derived = true + @ownershipsch = ownershipsch + @question_number = question_number end def selected_answer_option_is_derived?(_log) true end + + def question_number + case @ownershipsch + when 1 + 95 + when 2 + 108 + when 3 + 116 + end + end end diff --git a/app/models/form/sales/questions/deposit_discount.rb b/app/models/form/sales/questions/deposit_discount.rb index b23a3e1b4..577da5a91 100644 --- a/app/models/form/sales/questions/deposit_discount.rb +++ b/app/models/form/sales/questions/deposit_discount.rb @@ -10,5 +10,6 @@ class Form::Sales::Questions::DepositDiscount < ::Form::Question @width = 5 @prefix = "£" @hint_text = "Enter the total cash discount given on the property being purchased through the Social HomeBuy scheme" + @question_number = 96 end end diff --git a/app/models/form/sales/questions/discount.rb b/app/models/form/sales/questions/discount.rb index 01ae38fd5..8c5cf7132 100644 --- a/app/models/form/sales/questions/discount.rb +++ b/app/models/form/sales/questions/discount.rb @@ -12,5 +12,6 @@ class Form::Sales::Questions::Discount < ::Form::Question @hint_text = "For Right to Buy (RTB), Preserved Right to Buy (PRTB), and Voluntary Right to Buy (VRTB)

If discount capped, enter capped %

If the property is being sold to an existing tenant under the RTB, PRTB, or VRTB schemes, enter the % discount from the full market value that is being given." + @question_number = 102 end end diff --git a/app/models/form/sales/questions/discounted_ownership_type.rb b/app/models/form/sales/questions/discounted_ownership_type.rb index f75d83c01..99e10b1db 100644 --- a/app/models/form/sales/questions/discounted_ownership_type.rb +++ b/app/models/form/sales/questions/discounted_ownership_type.rb @@ -6,6 +6,7 @@ class Form::Sales::Questions::DiscountedOwnershipType < ::Form::Question @header = "What is the type of discounted ownership sale?" @type = "radio" @answer_options = ANSWER_OPTIONS + @question_number = 5 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/equity.rb b/app/models/form/sales/questions/equity.rb index 7dec2ac37..0119fea69 100644 --- a/app/models/form/sales/questions/equity.rb +++ b/app/models/form/sales/questions/equity.rb @@ -10,5 +10,6 @@ class Form::Sales::Questions::Equity < ::Form::Question @width = 5 @suffix = "%" @hint_text = "Enter the amount of initial equity held by the purchaser (for example, 25% or 50%)" + @question_number = 89 end end diff --git a/app/models/form/sales/questions/exchange_date.rb b/app/models/form/sales/questions/exchange_date.rb index 69b8ec39f..9e3ede3f4 100644 --- a/app/models/form/sales/questions/exchange_date.rb +++ b/app/models/form/sales/questions/exchange_date.rb @@ -5,5 +5,6 @@ class Form::Sales::Questions::ExchangeDate < ::Form::Question @check_answer_label = "Exchange of contracts date" @header = "What is the exchange of contracts date?" @type = "date" + @question_number = 81 end end diff --git a/app/models/form/sales/questions/extra_borrowing.rb b/app/models/form/sales/questions/extra_borrowing.rb index 04f906b22..f63413bba 100644 --- a/app/models/form/sales/questions/extra_borrowing.rb +++ b/app/models/form/sales/questions/extra_borrowing.rb @@ -1,6 +1,6 @@ class Form::Sales::Questions::ExtraBorrowing < ::Form::Question - def initialize(id, hsh, page) - super + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) @id = "extrabor" @check_answer_label = "Any other borrowing?" @header = "Does this include any extra borrowing?" @@ -8,6 +8,8 @@ class Form::Sales::Questions::ExtraBorrowing < ::Form::Question @answer_options = ANSWER_OPTIONS @page = page @hint_text = "" + @ownershipsch = ownershipsch + @question_number = question_number end ANSWER_OPTIONS = { @@ -15,4 +17,15 @@ class Form::Sales::Questions::ExtraBorrowing < ::Form::Question "2" => { "value" => "No" }, "3" => { "value" => "Don't know" }, }.freeze + + def question_number + case @ownershipsch + when 1 + 94 + when 2 + 107 + when 3 + 115 + end + end end diff --git a/app/models/form/sales/questions/fromprop.rb b/app/models/form/sales/questions/fromprop.rb index af33c67ea..9d35a4ae3 100644 --- a/app/models/form/sales/questions/fromprop.rb +++ b/app/models/form/sales/questions/fromprop.rb @@ -8,6 +8,7 @@ class Form::Sales::Questions::Fromprop < ::Form::Question @hint_text = "" @page = page @answer_options = ANSWER_OPTIONS + @question_number = 86 end ANSWER_OPTIONS = { @@ -16,5 +17,16 @@ class Form::Sales::Questions::Fromprop < ::Form::Question "3" => { "value" => "House" }, "4" => { "value" => "Bungalow" }, "9" => { "value" => "Other" }, + "0" => { "value" => "Don’t know" }, }.freeze + + def displayed_answer_options(_log, _user = nil) + { + "1" => { "value" => "Flat or maisonette" }, + "2" => { "value" => "Bedsit" }, + "3" => { "value" => "House" }, + "4" => { "value" => "Bungalow" }, + "9" => { "value" => "Other" }, + } + end end diff --git a/app/models/form/sales/questions/gender_identity1.rb b/app/models/form/sales/questions/gender_identity1.rb index c31a9cc0b..b9b47ee0a 100644 --- a/app/models/form/sales/questions/gender_identity1.rb +++ b/app/models/form/sales/questions/gender_identity1.rb @@ -8,6 +8,7 @@ class Form::Sales::Questions::GenderIdentity1 < ::Form::Question @hint_text = "Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest." @answer_options = ANSWER_OPTIONS @check_answers_card_number = 1 + @question_number = 21 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/gender_identity2.rb b/app/models/form/sales/questions/gender_identity2.rb index e394ae325..15ef9fda1 100644 --- a/app/models/form/sales/questions/gender_identity2.rb +++ b/app/models/form/sales/questions/gender_identity2.rb @@ -13,6 +13,7 @@ class Form::Sales::Questions::GenderIdentity2 < ::Form::Question }, "value" => "Prefers not to say", }] + @question_number = 29 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/grant.rb b/app/models/form/sales/questions/grant.rb index beef93c58..9b0fd3091 100644 --- a/app/models/form/sales/questions/grant.rb +++ b/app/models/form/sales/questions/grant.rb @@ -9,6 +9,7 @@ class Form::Sales::Questions::Grant < ::Form::Question @max = 999_999 @width = 5 @prefix = "£" - @hint_text = "For all schemes except Right to Buy (RTB), Preserved Right to Buy (PRTB), Voluntary Right to Buy (VRTB)" + @hint_text = "For all schemes except Right to Buy (RTB), Preserved Right to Buy (PRTB), Voluntary Right to Buy (VRTB) and Rent to Buy" + @question_number = 101 end end diff --git a/app/models/form/sales/questions/handover_date.rb b/app/models/form/sales/questions/handover_date.rb index 06a89eb04..389fe75d5 100644 --- a/app/models/form/sales/questions/handover_date.rb +++ b/app/models/form/sales/questions/handover_date.rb @@ -6,5 +6,6 @@ class Form::Sales::Questions::HandoverDate < ::Form::Question @header = "What is the practical completion or handover date?" @type = "date" @hint_text = "This is the date on which the building contractor hands over responsibility for the completed property to the private registered provider (PRP)" + @question_number = 82 end end diff --git a/app/models/form/sales/questions/household_disability.rb b/app/models/form/sales/questions/household_disability.rb index c0edef69c..894024c27 100644 --- a/app/models/form/sales/questions/household_disability.rb +++ b/app/models/form/sales/questions/household_disability.rb @@ -7,6 +7,7 @@ class Form::Sales::Questions::HouseholdDisability < ::Form::Question @type = "radio" @answer_options = ANSWER_OPTIONS @hint_text = "This includes any long-term health condition that has an impact on the person's day-to-day life" + @question_number = 65 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/household_wheelchair.rb b/app/models/form/sales/questions/household_wheelchair.rb index 9266909dc..cff617bad 100644 --- a/app/models/form/sales/questions/household_wheelchair.rb +++ b/app/models/form/sales/questions/household_wheelchair.rb @@ -6,6 +6,7 @@ class Form::Sales::Questions::HouseholdWheelchair < ::Form::Question @type = "radio" @answer_options = ANSWER_OPTIONS @hint_text = "This can be inside or outside the home" + @question_number = 66 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/housing_benefits.rb b/app/models/form/sales/questions/housing_benefits.rb index a4af620e6..d1baa7d38 100644 --- a/app/models/form/sales/questions/housing_benefits.rb +++ b/app/models/form/sales/questions/housing_benefits.rb @@ -6,6 +6,7 @@ class Form::Sales::Questions::HousingBenefits < ::Form::Question @header = "#{joint_purchase ? 'Were the buyers' : 'Was the buyer'} receiving any of these housing-related benefits immediately before buying this property?" @type = "radio" @answer_options = ANSWER_OPTIONS + @question_number = 71 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/joint_purchase.rb b/app/models/form/sales/questions/joint_purchase.rb index e2bf0f754..3de66ae1e 100644 --- a/app/models/form/sales/questions/joint_purchase.rb +++ b/app/models/form/sales/questions/joint_purchase.rb @@ -6,6 +6,7 @@ class Form::Sales::Questions::JointPurchase < ::Form::Question @header = "Is this a joint purchase?" @type = "radio" @answer_options = ANSWER_OPTIONS + @question_number = 9 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/la_nominations.rb b/app/models/form/sales/questions/la_nominations.rb index 806f7cfdd..c43c99a02 100644 --- a/app/models/form/sales/questions/la_nominations.rb +++ b/app/models/form/sales/questions/la_nominations.rb @@ -7,6 +7,7 @@ class Form::Sales::Questions::LaNominations < ::Form::Question @type = "radio" @answer_options = ANSWER_OPTIONS @hint_text = "A local authority nominations agreement is a written agreement between a local authority and private registered provider (PRP) that some or all of its sales vacancies are offered to local authorities for rehousing" + @question_number = 83 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/leasehold_charges.rb b/app/models/form/sales/questions/leasehold_charges.rb index ef9260c56..697a91b26 100644 --- a/app/models/form/sales/questions/leasehold_charges.rb +++ b/app/models/form/sales/questions/leasehold_charges.rb @@ -1,6 +1,6 @@ class Form::Sales::Questions::LeaseholdCharges < ::Form::Question - def initialize(id, hsh, page) - super + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) @id = "mscharge" @check_answer_label = "Monthly leasehold charges" @header = "Enter the total monthly charge" @@ -8,5 +8,18 @@ class Form::Sales::Questions::LeaseholdCharges < ::Form::Question @min = 0 @width = 5 @prefix = "£" + @ownershipsch = ownershipsch + @question_number = question_number + end + + def question_number + case @ownershipsch + when 1 + 98 + when 2 + 109 + when 3 + 117 + end end end diff --git a/app/models/form/sales/questions/leasehold_charges_known.rb b/app/models/form/sales/questions/leasehold_charges_known.rb index 2c28e1814..a800690e4 100644 --- a/app/models/form/sales/questions/leasehold_charges_known.rb +++ b/app/models/form/sales/questions/leasehold_charges_known.rb @@ -1,6 +1,6 @@ class Form::Sales::Questions::LeaseholdChargesKnown < ::Form::Question - def initialize(id, hsh, page) - super + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) @id = "mscharge_known" @check_answer_label = "Monthly leasehold charges known?" @header = "Does the property have any monthly leasehold charges?" @@ -17,10 +17,23 @@ class Form::Sales::Questions::LeaseholdChargesKnown < ::Form::Question }, ], } + @ownershipsch = ownershipsch + @question_number = question_number end ANSWER_OPTIONS = { "1" => { "value" => "Yes" }, "0" => { "value" => "No" }, }.freeze + + def question_number + case @ownershipsch + when 1 + 98 + when 2 + 109 + when 3 + 117 + end + end end diff --git a/app/models/form/sales/questions/living_before_purchase.rb b/app/models/form/sales/questions/living_before_purchase.rb index f631220dc..4080e34b6 100644 --- a/app/models/form/sales/questions/living_before_purchase.rb +++ b/app/models/form/sales/questions/living_before_purchase.rb @@ -1,6 +1,6 @@ class Form::Sales::Questions::LivingBeforePurchase < ::Form::Question - def initialize(id, hsh, page) - super + def initialize(id, hsh, page, ownershipsch:) + super(id, hsh, page) @id = "proplen_asked" @check_answer_label = "Buyer lived in the property before purchasing" @header = "Did the buyer live in the property before purchasing it?" @@ -17,10 +17,21 @@ class Form::Sales::Questions::LivingBeforePurchase < ::Form::Question }, ], } + @ownershipsch = ownershipsch + @question_number = question_number end ANSWER_OPTIONS = { "0" => { "value" => "Yes" }, "1" => { "value" => "No" }, }.freeze + + def question_number + case @ownershipsch + when 1 + 75 + when 2 + 99 + end + end end diff --git a/app/models/form/sales/questions/living_before_purchase_years.rb b/app/models/form/sales/questions/living_before_purchase_years.rb index f3f1e58a7..ec9cd9d52 100644 --- a/app/models/form/sales/questions/living_before_purchase_years.rb +++ b/app/models/form/sales/questions/living_before_purchase_years.rb @@ -1,6 +1,6 @@ class Form::Sales::Questions::LivingBeforePurchaseYears < ::Form::Question - def initialize(id, hsh, page) - super + def initialize(id, hsh, page, ownershipsch:) + super(id, hsh, page) @id = "proplen" @check_answer_label = "Number of years living in the property before purchase" @header = header_text @@ -11,6 +11,8 @@ class Form::Sales::Questions::LivingBeforePurchaseYears < ::Form::Question @step = 1 @width = 5 @suffix = " years" + @ownershipsch = ownershipsch + @question_number = question_number end def header_text @@ -28,4 +30,13 @@ class Form::Sales::Questions::LivingBeforePurchaseYears < ::Form::Question "You should round this up to the nearest year. If the buyers haven't been living in the property, enter '0'" end end + + def question_number + case @ownershipsch + when 1 + 75 + when 2 + 99 + end + end end diff --git a/app/models/form/sales/questions/monthly_rent.rb b/app/models/form/sales/questions/monthly_rent.rb index 34ac1bed9..2a28bc691 100644 --- a/app/models/form/sales/questions/monthly_rent.rb +++ b/app/models/form/sales/questions/monthly_rent.rb @@ -9,5 +9,6 @@ class Form::Sales::Questions::MonthlyRent < ::Form::Question @width = 5 @prefix = "£" @hint_text = "Amount paid before any charges" + @question_number = 97 end end diff --git a/app/models/form/sales/questions/mortgage_amount.rb b/app/models/form/sales/questions/mortgage_amount.rb index bd4ae5e60..12959709a 100644 --- a/app/models/form/sales/questions/mortgage_amount.rb +++ b/app/models/form/sales/questions/mortgage_amount.rb @@ -1,6 +1,6 @@ class Form::Sales::Questions::MortgageAmount < ::Form::Question - def initialize(id, hsh, page) - super + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) @id = "mortgage" @check_answer_label = "Mortgage amount" @header = "What is the mortgage amount?" @@ -9,5 +9,18 @@ class Form::Sales::Questions::MortgageAmount < ::Form::Question @width = 5 @prefix = "£" @hint_text = "Enter the amount of mortgage agreed with the mortgage lender. Exclude any deposits or cash payments. Numeric in pounds. Rounded to the nearest pound." + @ownershipsch = ownershipsch + @question_number = question_number + end + + def question_number + case @ownershipsch + when 1 + 91 + when 2 + 104 + when 3 + 112 + end end end diff --git a/app/models/form/sales/questions/mortgage_lender.rb b/app/models/form/sales/questions/mortgage_lender.rb index 54c9a66c6..1fee10b8b 100644 --- a/app/models/form/sales/questions/mortgage_lender.rb +++ b/app/models/form/sales/questions/mortgage_lender.rb @@ -1,6 +1,6 @@ class Form::Sales::Questions::MortgageLender < ::Form::Question - def initialize(id, hsh, page) - super + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) @id = "mortgagelender" @check_answer_label = "Mortgage Lender" @header = "What is the name of the mortgage lender?" @@ -10,6 +10,8 @@ class Form::Sales::Questions::MortgageLender < ::Form::Question @answer_options = ANSWER_OPTIONS @guidance_position = GuidancePosition::BOTTOM @guidance_partial = "mortgage_lender" + @ownershipsch = ownershipsch + @question_number = question_number end ANSWER_OPTIONS = { @@ -55,4 +57,15 @@ class Form::Sales::Questions::MortgageLender < ::Form::Question "39" => "Yorkshire Building Society", "40" => "Other", }.freeze + + def question_number + case @ownershipsch + when 1 + 92 + when 2 + 105 + when 3 + 113 + end + end end diff --git a/app/models/form/sales/questions/mortgage_lender_other.rb b/app/models/form/sales/questions/mortgage_lender_other.rb index fa1fefa49..677b1c117 100644 --- a/app/models/form/sales/questions/mortgage_lender_other.rb +++ b/app/models/form/sales/questions/mortgage_lender_other.rb @@ -1,10 +1,23 @@ class Form::Sales::Questions::MortgageLenderOther < ::Form::Question - def initialize(id, hsh, page) - super + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) @id = "mortgagelenderother" @check_answer_label = "Other Mortgage Lender" @header = "What is the other mortgage lender?" @type = "text" @page = page + @ownershipsch = ownershipsch + @question_number = question_number + end + + def question_number + case @ownershipsch + when 1 + 92 + when 2 + 105 + when 3 + 113 + end end end diff --git a/app/models/form/sales/questions/mortgage_length.rb b/app/models/form/sales/questions/mortgage_length.rb index 3f1603b75..adaa94d01 100644 --- a/app/models/form/sales/questions/mortgage_length.rb +++ b/app/models/form/sales/questions/mortgage_length.rb @@ -1,6 +1,6 @@ class Form::Sales::Questions::MortgageLength < ::Form::Question - def initialize(id, hsh, page) - super + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) @id = "mortlen" @check_answer_label = "Length of mortgage" @header = "What is the length of the mortgage?" @@ -10,5 +10,18 @@ class Form::Sales::Questions::MortgageLength < ::Form::Question @width = 5 @suffix = " years" @hint_text = "You should round up to the nearest year. Value should not exceed 60 years." + @ownershipsch = ownershipsch + @question_number = question_number + end + + def question_number + case @ownershipsch + when 1 + 93 + when 2 + 106 + when 3 + 114 + end end end diff --git a/app/models/form/sales/questions/mortgageused.rb b/app/models/form/sales/questions/mortgageused.rb index ad18652c4..7f87b9230 100644 --- a/app/models/form/sales/questions/mortgageused.rb +++ b/app/models/form/sales/questions/mortgageused.rb @@ -1,11 +1,13 @@ class Form::Sales::Questions::Mortgageused < ::Form::Question - def initialize(id, hsh, page) - super + def initialize(id, hsh, subsection, ownershipsch:) + super(id, hsh, subsection) @id = "mortgageused" @check_answer_label = "Mortgage used" @header = "Was a mortgage used for the purchase of this property?" @type = "radio" @answer_options = ANSWER_OPTIONS + @ownershipsch = ownershipsch + @question_number = question_number end ANSWER_OPTIONS = { @@ -20,4 +22,15 @@ class Form::Sales::Questions::Mortgageused < ::Form::Question "2" => { "value" => "No" }, } end + + def question_number + case @ownershipsch + when 1 + 90 + when 2 + 103 + when 3 + 111 + end + end end diff --git a/app/models/form/sales/questions/nationality1.rb b/app/models/form/sales/questions/nationality1.rb index 53e9edc5f..68c2ce5ea 100644 --- a/app/models/form/sales/questions/nationality1.rb +++ b/app/models/form/sales/questions/nationality1.rb @@ -7,16 +7,6 @@ class Form::Sales::Questions::Nationality1 < ::Form::Question @type = "radio" @hint_text = "Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest." @answer_options = ANSWER_OPTIONS - @conditional_for = { - "othernational" => [12], - } - @hidden_in_check_answers = { - "depends_on" => [ - { - "national" => 12, - }, - ], - } @check_answers_card_number = 1 @inferred_check_answers_value = [{ "condition" => { @@ -24,6 +14,7 @@ class Form::Sales::Questions::Nationality1 < ::Form::Question }, "value" => "Prefers not to say", }] + @question_number = 24 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/number_joint_buyers.rb b/app/models/form/sales/questions/number_joint_buyers.rb index b9c2fc2e2..bd8a6ef3a 100644 --- a/app/models/form/sales/questions/number_joint_buyers.rb +++ b/app/models/form/sales/questions/number_joint_buyers.rb @@ -7,6 +7,7 @@ class Form::Sales::Questions::NumberJointBuyers < ::Form::Question @hint_text = "You should still try to answer all questions even if the buyer wasn't interviewed in person" @type = "radio" @answer_options = ANSWER_OPTIONS + @question_number = 10 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/number_of_others_in_property.rb b/app/models/form/sales/questions/number_of_others_in_property.rb index 97a873430..44e7e5563 100644 --- a/app/models/form/sales/questions/number_of_others_in_property.rb +++ b/app/models/form/sales/questions/number_of_others_in_property.rb @@ -9,6 +9,7 @@ class Form::Sales::Questions::NumberOfOthersInProperty < ::Form::Question @width = 2 @min = 0 @max = joint_purchase ? 4 : 5 + @question_number = 35 end private diff --git a/app/models/form/sales/questions/other_nationality1.rb b/app/models/form/sales/questions/other_nationality1.rb deleted file mode 100644 index 3eb6a48d7..000000000 --- a/app/models/form/sales/questions/other_nationality1.rb +++ /dev/null @@ -1,10 +0,0 @@ -class Form::Sales::Questions::OtherNationality1 < ::Form::Question - def initialize(id, hsh, page) - super - @id = "othernational" - @check_answer_label = "Buyer 1’s nationality" - @header = "Nationality" - @type = "text" - @check_answers_card_number = 1 - end -end diff --git a/app/models/form/sales/questions/other_ownership_type.rb b/app/models/form/sales/questions/other_ownership_type.rb index 428691381..08bd9955b 100644 --- a/app/models/form/sales/questions/other_ownership_type.rb +++ b/app/models/form/sales/questions/other_ownership_type.rb @@ -6,5 +6,6 @@ class Form::Sales::Questions::OtherOwnershipType < ::Form::Question @header = "What type of sale is it?" @type = "text" @width = 10 + @question_number = 6 end end diff --git a/app/models/form/sales/questions/outright_ownership_type.rb b/app/models/form/sales/questions/outright_ownership_type.rb index baead7f5a..01fa77a0d 100644 --- a/app/models/form/sales/questions/outright_ownership_type.rb +++ b/app/models/form/sales/questions/outright_ownership_type.rb @@ -9,6 +9,7 @@ class Form::Sales::Questions::OutrightOwnershipType < ::Form::Question @conditional_for = { "othtype" => [12], } + @question_number = 6 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/ownership_scheme.rb b/app/models/form/sales/questions/ownership_scheme.rb index fc30ce3b4..dc1d4fb29 100644 --- a/app/models/form/sales/questions/ownership_scheme.rb +++ b/app/models/form/sales/questions/ownership_scheme.rb @@ -6,6 +6,7 @@ class Form::Sales::Questions::OwnershipScheme < ::Form::Question @header = "Was this purchase made through an ownership scheme?" @type = "radio" @answer_options = ANSWER_OPTIONS + @question_number = 3 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/person_age.rb b/app/models/form/sales/questions/person_age.rb index c0a3e55a8..779e09669 100644 --- a/app/models/form/sales/questions/person_age.rb +++ b/app/models/form/sales/questions/person_age.rb @@ -12,5 +12,6 @@ class Form::Sales::Questions::PersonAge < ::Form::Question @check_answers_card_number = person_index @min = 0 @max = 110 + @question_number = 29 + (4 * person_index) end end diff --git a/app/models/form/sales/questions/person_age_known.rb b/app/models/form/sales/questions/person_age_known.rb index 198b4ed30..9272bb21e 100644 --- a/app/models/form/sales/questions/person_age_known.rb +++ b/app/models/form/sales/questions/person_age_known.rb @@ -19,6 +19,7 @@ class Form::Sales::Questions::PersonAgeKnown < ::Form::Question ], } @check_answers_card_number = person_index + @question_number = 29 + (4 * person_index) end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/person_gender_identity.rb b/app/models/form/sales/questions/person_gender_identity.rb index 01967e737..94774f5ce 100644 --- a/app/models/form/sales/questions/person_gender_identity.rb +++ b/app/models/form/sales/questions/person_gender_identity.rb @@ -12,6 +12,7 @@ class Form::Sales::Questions::PersonGenderIdentity < ::Form::Question }, "value" => "Prefers not to say", }] + @question_number = 30 + (4 * person_index) end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/person_relationship_to_buyer_1.rb b/app/models/form/sales/questions/person_relationship_to_buyer_1.rb index 774de4208..50f06c55e 100644 --- a/app/models/form/sales/questions/person_relationship_to_buyer_1.rb +++ b/app/models/form/sales/questions/person_relationship_to_buyer_1.rb @@ -12,6 +12,7 @@ class Form::Sales::Questions::PersonRelationshipToBuyer1 < ::Form::Question }, "value" => "Prefers not to say", }] + @question_number = 28 + (4 * person_index) end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/person_student_not_child_value_check.rb b/app/models/form/sales/questions/person_student_not_child_value_check.rb new file mode 100644 index 000000000..fba35d05b --- /dev/null +++ b/app/models/form/sales/questions/person_student_not_child_value_check.rb @@ -0,0 +1,24 @@ +class Form::Sales::Questions::PersonStudentNotChildValueCheck < ::Form::Question + def initialize(id, hsh, page, person_index:) + super(id, hsh, page) + @id = "student_not_child_value_check" + @check_answer_label = "Student not a child confirmation" + @type = "interruption_screen" + @answer_options = { + "0" => { "value" => "Yes" }, + "1" => { "value" => "No" }, + } + @hidden_in_check_answers = { + "depends_on" => [ + { + "student_not_child_value_check" => 0, + }, + { + "student_not_child_value_check" => 1, + }, + ], + } + @check_answers_card_number = person_index + @header = "Are you sure this person is not a child?" + end +end diff --git a/app/models/form/sales/questions/person_working_situation.rb b/app/models/form/sales/questions/person_working_situation.rb index 0740541b3..d74c38f14 100644 --- a/app/models/form/sales/questions/person_working_situation.rb +++ b/app/models/form/sales/questions/person_working_situation.rb @@ -12,6 +12,7 @@ class Form::Sales::Questions::PersonWorkingSituation < ::Form::Question }, "value" => "Prefers not to say", }] + @question_number = 31 + (4 * person_index) end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/postcode_for_full_address.rb b/app/models/form/sales/questions/postcode_for_full_address.rb new file mode 100644 index 000000000..a1e6f8633 --- /dev/null +++ b/app/models/form/sales/questions/postcode_for_full_address.rb @@ -0,0 +1,25 @@ +class Form::Sales::Questions::PostcodeForFullAddress < ::Form::Question + def initialize(id, hsh, page) + super + @id = "postcode_full" + @header = "Postcode" + @type = "text" + @width = 5 + @inferred_check_answers_value = [{ + "condition" => { + "pcodenk" => 1, + }, + "value" => "Not known", + }] + @inferred_answers = { + "la" => { + "is_la_inferred" => true, + }, + } + @plain_label = true + end + + def hidden_in_check_answers?(_log = nil, _current_user = nil) + true + end +end diff --git a/app/models/form/sales/questions/previous_bedrooms.rb b/app/models/form/sales/questions/previous_bedrooms.rb index 1bea6538c..d9f9aaddb 100644 --- a/app/models/form/sales/questions/previous_bedrooms.rb +++ b/app/models/form/sales/questions/previous_bedrooms.rb @@ -9,5 +9,6 @@ class Form::Sales::Questions::PreviousBedrooms < ::Form::Question @min = 1 @max = 6 @hint_text = "For bedsits enter 1" + @question_number = 85 end end diff --git a/app/models/form/sales/questions/previous_la_known.rb b/app/models/form/sales/questions/previous_la_known.rb index b38f5c560..1a9a646f3 100644 --- a/app/models/form/sales/questions/previous_la_known.rb +++ b/app/models/form/sales/questions/previous_la_known.rb @@ -20,6 +20,7 @@ class Form::Sales::Questions::PreviousLaKnown < ::Form::Question @conditional_for = { "prevloc" => [1], } + @question_number = 58 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/previous_postcode.rb b/app/models/form/sales/questions/previous_postcode.rb index 103a68ab6..568ba66ea 100644 --- a/app/models/form/sales/questions/previous_postcode.rb +++ b/app/models/form/sales/questions/previous_postcode.rb @@ -17,5 +17,6 @@ class Form::Sales::Questions::PreviousPostcode < ::Form::Question "is_previous_la_inferred" => true, }, } + @question_number = 57 end end diff --git a/app/models/form/sales/questions/previous_postcode_known.rb b/app/models/form/sales/questions/previous_postcode_known.rb index 9806d12e4..e83fda8d3 100644 --- a/app/models/form/sales/questions/previous_postcode_known.rb +++ b/app/models/form/sales/questions/previous_postcode_known.rb @@ -20,6 +20,7 @@ class Form::Sales::Questions::PreviousPostcodeKnown < ::Form::Question }, ], } + @question_number = 57 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/previous_tenure.rb b/app/models/form/sales/questions/previous_tenure.rb index e570ec90c..96b638cf8 100644 --- a/app/models/form/sales/questions/previous_tenure.rb +++ b/app/models/form/sales/questions/previous_tenure.rb @@ -8,6 +8,7 @@ class Form::Sales::Questions::PreviousTenure < ::Form::Question @hint_text = "" @page = page @answer_options = ANSWER_OPTIONS + @question_number = 87 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/previous_tenure_buyer2.rb b/app/models/form/sales/questions/previous_tenure_buyer2.rb new file mode 100644 index 000000000..e3d8ee27d --- /dev/null +++ b/app/models/form/sales/questions/previous_tenure_buyer2.rb @@ -0,0 +1,24 @@ +class Form::Sales::Questions::PreviousTenureBuyer2 < ::Form::Question + def initialize(id, hsh, page) + super + @id = "prevtenbuy2" + @check_answer_label = "Buyer 2’s previous tenure" + @header = "What was buyer 2’s previous tenure?" + @type = "radio" + @hint_text = "" + @answer_options = ANSWER_OPTIONS + @question_number = 61 + end + + ANSWER_OPTIONS = { + "1" => { "value" => "Local authority tenant" }, + "2" => { "value" => "Private registered provider or housing association tenant" }, + "3" => { "value" => "Private tenant" }, + "5" => { "value" => "Owner occupier" }, + "4" => { "value" => "Tied home or renting with job" }, + "6" => { "value" => "Living with family or friends" }, + "7" => { "value" => "Temporary accommodation" }, + "9" => { "value" => "Other" }, + "0" => { "value" => "Don't know" }, + }.freeze +end diff --git a/app/models/form/sales/questions/prevloc.rb b/app/models/form/sales/questions/prevloc.rb index 49a69ad39..75bb50e81 100644 --- a/app/models/form/sales/questions/prevloc.rb +++ b/app/models/form/sales/questions/prevloc.rb @@ -5,399 +5,16 @@ class Form::Sales::Questions::Prevloc < ::Form::Question @check_answer_label = "Local authority of buyer 1’s last settled accommodation" @header = "Select a local authority" @type = "select" - @answer_options = ANSWER_OPTIONS @inferred_check_answers_value = [{ "condition" => { "previous_la_known" => 0, }, "value" => "Not known", }] + @question_number = 58 end - ANSWER_OPTIONS = { - "" => "Select an option", - "S12000033" => "Aberdeen City", - "S12000034" => "Aberdeenshire", - "E07000223" => "Adur", - "E07000026" => "Allerdale", - "E07000032" => "Amber Valley", - "S12000041" => "Angus", - "N09000001" => "Antrim and Newtownabbey", - "N09000011" => "Ards and North Down", - "S12000035" => "Argyll and Bute", - "N09000002" => "Armagh City, Banbridge and Craigavon", - "E07000224" => "Arun", - "E07000170" => "Ashfield", - "E07000105" => "Ashford", - "E07000200" => "Babergh", - "E09000002" => "Barking and Dagenham", - "E09000003" => "Barnet", - "E08000016" => "Barnsley", - "E07000027" => "Barrow-in-Furness", - "E07000066" => "Basildon", - "E07000084" => "Basingstoke and Deane", - "E07000171" => "Bassetlaw", - "E06000022" => "Bath and North East Somerset", - "E06000055" => "Bedford", - "N09000003" => "Belfast", - "E09000004" => "Bexley", - "E08000025" => "Birmingham", - "E07000129" => "Blaby", - "E06000008" => "Blackburn with Darwen", - "E06000009" => "Blackpool", - "W06000019" => "Blaenau Gwent", - "E07000033" => "Bolsover", - "E08000001" => "Bolton", - "E07000136" => "Boston", - "E06000058" => "Bournemouth, Christchurch and Poole", - "E06000036" => "Bracknell Forest", - "E08000032" => "Bradford", - "E07000067" => "Braintree", - "E07000143" => "Breckland", - "E09000005" => "Brent", - "E07000068" => "Brentwood", - "W06000013" => "Bridgend", - "E06000043" => "Brighton and Hove", - "E06000023" => "Bristol, City of", - "E07000144" => "Broadland", - "E09000006" => "Bromley", - "E07000234" => "Bromsgrove", - "E07000095" => "Broxbourne", - "E07000172" => "Broxtowe", - "E06000060" => "Buckinghamshire", - "E07000117" => "Burnley", - "E08000002" => "Bury", - "W06000018" => "Caerphilly", - "E08000033" => "Calderdale", - "E07000008" => "Cambridge", - "E09000007" => "Camden", - "E07000192" => "Cannock Chase", - "E07000106" => "Canterbury", - "W06000015" => "Cardiff", - "E07000028" => "Carlisle", - "W06000010" => "Carmarthenshire", - "E07000069" => "Castle Point", - "N09000004" => "Causeway Coast and Glens", - "E06000056" => "Central Bedfordshire", - "W06000008" => "Ceredigion", - "E07000130" => "Charnwood", - "E07000070" => "Chelmsford", - "E07000078" => "Cheltenham", - "E07000177" => "Cherwell", - "E06000049" => "Cheshire East", - "E06000050" => "Cheshire West and Chester", - "E07000034" => "Chesterfield", - "E07000225" => "Chichester", - "E07000118" => "Chorley", - "S12000036" => "City of Edinburgh", - "E09000001" => "City of London", - "S12000005" => "Clackmannanshire", - "E07000071" => "Colchester", - "W06000003" => "Conwy", - "E07000029" => "Copeland", - "E07000150" => "Corby", - "E06000052" => "Cornwall", - "E07000079" => "Cotswold", - "E06000047" => "County Durham", - "E08000026" => "Coventry", - "E07000163" => "Craven", - "E07000226" => "Crawley", - "E09000008" => "Croydon", - "E07000096" => "Dacorum", - "E06000005" => "Darlington", - "E07000107" => "Dartford", - "E07000151" => "Daventry", - "W06000004" => "Denbighshire", - "E06000015" => "Derby", - "E07000035" => "Derbyshire Dales", - "N09000005" => "Derry City and Strabane", - "E08000017" => "Doncaster", - "E06000059" => "Dorset", - "E07000108" => "Dover", - "E08000027" => "Dudley", - "S12000006" => "Dumfries and Galloway", - "S12000042" => "Dundee City", - "E09000009" => "Ealing", - "S12000008" => "East Ayrshire", - "E07000009" => "East Cambridgeshire", - "E07000040" => "East Devon", - "S12000045" => "East Dunbartonshire", - "E07000085" => "East Hampshire", - "E07000242" => "East Hertfordshire", - "E07000137" => "East Lindsey", - "S12000010" => "East Lothian", - "E07000152" => "East Northamptonshire", - "S12000011" => "East Renfrewshire", - "E06000011" => "East Riding of Yorkshire", - "E07000193" => "East Staffordshire", - "E07000244" => "East Suffolk", - "E07000061" => "Eastbourne", - "E07000086" => "Eastleigh", - "E07000030" => "Eden", - "E07000207" => "Elmbridge", - "E09000010" => "Enfield", - "E07000072" => "Epping Forest", - "E07000208" => "Epsom and Ewell", - "E07000036" => "Erewash", - "E07000041" => "Exeter", - "S12000014" => "Falkirk", - "E07000087" => "Fareham", - "E07000010" => "Fenland", - "N09000006" => "Fermanagh and Omagh", - "S12000047" => "Fife", - "W06000005" => "Flintshire", - "E07000112" => "Folkestone and Hythe", - "E07000080" => "Forest of Dean", - "E07000119" => "Fylde", - "E08000037" => "Gateshead", - "E07000173" => "Gedling", - "S12000049" => "Glasgow City", - "E07000081" => "Gloucester", - "E07000088" => "Gosport", - "E07000109" => "Gravesham", - "E07000145" => "Great Yarmouth", - "E09000011" => "Greenwich", - "E07000209" => "Guildford", - "W06000002" => "Gwynedd", - "E09000012" => "Hackney", - "E06000006" => "Halton", - "E07000164" => "Hambleton", - "E09000013" => "Hammersmith and Fulham", - "E07000131" => "Harborough", - "E09000014" => "Haringey", - "E07000073" => "Harlow", - "E07000165" => "Harrogate", - "E09000015" => "Harrow", - "E07000089" => "Hart", - "E06000001" => "Hartlepool", - "E07000062" => "Hastings", - "E07000090" => "Havant", - "E09000016" => "Havering", - "E06000019" => "Herefordshire, County of", - "E07000098" => "Hertsmere", - "E07000037" => "High Peak", - "S12000017" => "Highland", - "E09000017" => "Hillingdon", - "E07000132" => "Hinckley and Bosworth", - "E07000227" => "Horsham", - "E09000018" => "Hounslow", - "E07000011" => "Huntingdonshire", - "E07000120" => "Hyndburn", - "S12000018" => "Inverclyde", - "E07000202" => "Ipswich", - "W06000001" => "Isle of Anglesey", - "E06000046" => "Isle of Wight", - "E06000053" => "Isles of Scilly", - "E09000019" => "Islington", - "E09000020" => "Kensington and Chelsea", - "E07000153" => "Kettering", - "E07000146" => "King’s Lynn and West Norfolk", - "E06000010" => "Kingston upon Hull, City of", - "E09000021" => "Kingston upon Thames", - "E08000034" => "Kirklees", - "E08000011" => "Knowsley", - "E09000022" => "Lambeth", - "E07000121" => "Lancaster", - "E08000035" => "Leeds", - "E06000016" => "Leicester", - "E07000063" => "Lewes", - "E09000023" => "Lewisham", - "E07000194" => "Lichfield", - "E07000138" => "Lincoln", - "N09000007" => "Lisburn and Castlereagh", - "E08000012" => "Liverpool", - "E06000032" => "Luton", - "E07000110" => "Maidstone", - "E07000074" => "Maldon", - "E07000235" => "Malvern Hills", - "E08000003" => "Manchester", - "E07000174" => "Mansfield", - "E06000035" => "Medway", - "E07000133" => "Melton", - "E07000187" => "Mendip", - "W06000024" => "Merthyr Tydfil", - "E09000024" => "Merton", - "E07000042" => "Mid Devon", - "E07000203" => "Mid Suffolk", - "E07000228" => "Mid Sussex", - "N09000009" => "Mid Ulster", - "N09000008" => "Mid and East Antrim", - "E06000002" => "Middlesbrough", - "S12000019" => "Midlothian", - "E06000042" => "Milton Keynes", - "E07000210" => "Mole Valley", - "W06000021" => "Monmouthshire", - "S12000020" => "Moray", - "S12000013" => "Na h-Eileanan Siar", - "W06000012" => "Neath Port Talbot", - "E07000091" => "New Forest", - "E07000175" => "Newark and Sherwood", - "E08000021" => "Newcastle upon Tyne", - "E07000195" => "Newcastle-under-Lyme", - "E09000025" => "Newham", - "W06000022" => "Newport", - "N09000010" => "Newry, Mourne and Down", - "S12000021" => "North Ayrshire", - "E07000043" => "North Devon", - "E07000038" => "North East Derbyshire", - "E06000012" => "North East Lincolnshire", - "E07000099" => "North Hertfordshire", - "E07000139" => "North Kesteven", - "S12000050" => "North Lanarkshire", - "E06000013" => "North Lincolnshire", - "E07000147" => "North Norfolk", - "E06000024" => "North Somerset", - "E08000022" => "North Tyneside", - "E07000218" => "North Warwickshire", - "E07000134" => "North West Leicestershire", - "E07000154" => "Northampton", - "E06000057" => "Northumberland", - "E07000148" => "Norwich", - "E06000018" => "Nottingham", - "E07000219" => "Nuneaton and Bedworth", - "E07000135" => "Oadby and Wigston", - "E08000004" => "Oldham", - "S12000023" => "Orkney Islands", - "E07000178" => "Oxford", - "W06000009" => "Pembrokeshire", - "E07000122" => "Pendle", - "S12000048" => "Perth and Kinross", - "E06000031" => "Peterborough", - "E06000026" => "Plymouth", - "E06000044" => "Portsmouth", - "W06000023" => "Powys", - "E07000123" => "Preston", - "E06000038" => "Reading", - "E09000026" => "Redbridge", - "E06000003" => "Redcar and Cleveland", - "E07000236" => "Redditch", - "E07000211" => "Reigate and Banstead", - "S12000038" => "Renfrewshire", - "W06000016" => "Rhondda Cynon Taf", - "E07000124" => "Ribble Valley", - "E09000027" => "Richmond upon Thames", - "E07000166" => "Richmondshire", - "E08000005" => "Rochdale", - "E07000075" => "Rochford", - "E07000125" => "Rossendale", - "E07000064" => "Rother", - "E08000018" => "Rotherham", - "E07000220" => "Rugby", - "E07000212" => "Runnymede", - "E07000176" => "Rushcliffe", - "E07000092" => "Rushmoor", - "E06000017" => "Rutland", - "E07000167" => "Ryedale", - "E08000006" => "Salford", - "E08000028" => "Sandwell", - "E07000168" => "Scarborough", - "S12000026" => "Scottish Borders", - "E07000188" => "Sedgemoor", - "E08000014" => "Sefton", - "E07000169" => "Selby", - "E07000111" => "Sevenoaks", - "E08000019" => "Sheffield", - "S12000027" => "Shetland Islands", - "E06000051" => "Shropshire", - "E06000039" => "Slough", - "E08000029" => "Solihull", - "E07000246" => "Somerset West and Taunton", - "S12000028" => "South Ayrshire", - "E07000012" => "South Cambridgeshire", - "E07000039" => "South Derbyshire", - "E06000025" => "South Gloucestershire", - "E07000044" => "South Hams", - "E07000140" => "South Holland", - "E07000141" => "South Kesteven", - "E07000031" => "South Lakeland", - "S12000029" => "South Lanarkshire", - "E07000149" => "South Norfolk", - "E07000155" => "South Northamptonshire", - "E07000179" => "South Oxfordshire", - "E07000126" => "South Ribble", - "E07000189" => "South Somerset", - "E07000196" => "South Staffordshire", - "E08000023" => "South Tyneside", - "E06000045" => "Southampton", - "E06000033" => "Southend-on-Sea", - "E09000028" => "Southwark", - "E07000213" => "Spelthorne", - "E07000240" => "St Albans", - "E08000013" => "St. Helens", - "E07000197" => "Stafford", - "E07000198" => "Staffordshire Moorlands", - "E07000243" => "Stevenage", - "S12000030" => "Stirling", - "E08000007" => "Stockport", - "E06000004" => "Stockton-on-Tees", - "E06000021" => "Stoke-on-Trent", - "E07000221" => "Stratford-on-Avon", - "E07000082" => "Stroud", - "E08000024" => "Sunderland", - "E07000214" => "Surrey Heath", - "E09000029" => "Sutton", - "E07000113" => "Swale", - "W06000011" => "Swansea", - "E06000030" => "Swindon", - "E08000008" => "Tameside", - "E07000199" => "Tamworth", - "E07000215" => "Tandridge", - "E07000045" => "Teignbridge", - "E06000020" => "Telford and Wrekin", - "E07000076" => "Tendring", - "E07000093" => "Test Valley", - "E07000083" => "Tewkesbury", - "E07000114" => "Thanet", - "E07000102" => "Three Rivers", - "E06000034" => "Thurrock", - "E07000115" => "Tonbridge and Malling", - "E06000027" => "Torbay", - "W06000020" => "Torfaen", - "E07000046" => "Torridge", - "E09000030" => "Tower Hamlets", - "E08000009" => "Trafford", - "E07000116" => "Tunbridge Wells", - "E07000077" => "Uttlesford", - "W06000014" => "Vale of Glamorgan", - "E07000180" => "Vale of White Horse", - "E08000036" => "Wakefield", - "E08000030" => "Walsall", - "E09000031" => "Waltham Forest", - "E09000032" => "Wandsworth", - "E06000007" => "Warrington", - "E07000222" => "Warwick", - "E07000103" => "Watford", - "E07000216" => "Waverley", - "E07000065" => "Wealden", - "E07000156" => "Wellingborough", - "E07000241" => "Welwyn Hatfield", - "E06000037" => "West Berkshire", - "E07000047" => "West Devon", - "S12000039" => "West Dunbartonshire", - "E07000127" => "West Lancashire", - "E07000142" => "West Lindsey", - "S12000040" => "West Lothian", - "E07000181" => "West Oxfordshire", - "E07000245" => "West Suffolk", - "E09000033" => "Westminster", - "E08000010" => "Wigan", - "E06000054" => "Wiltshire", - "E07000094" => "Winchester", - "E06000040" => "Windsor and Maidenhead", - "E08000015" => "Wirral", - "E07000217" => "Woking", - "E06000041" => "Wokingham", - "E08000031" => "Wolverhampton", - "E07000237" => "Worcester", - "E07000229" => "Worthing", - "W06000006" => "Wrexham", - "E07000238" => "Wychavon", - "E07000128" => "Wyre", - "E07000239" => "Wyre Forest", - "E06000014" => "York", - "N92000002" => "Northern Ireland", - "S92000003" => "Scotland", - "W92000004" => "Wales", - "9300000XX" => "Outside UK", - }.freeze + def answer_options + { "" => "Select an option" }.merge(LocalAuthority.active(form.start_date).map { |la| [la.code, la.name] }.to_h) + end end diff --git a/app/models/form/sales/questions/prevown.rb b/app/models/form/sales/questions/prevown.rb index a9a3b086b..1ae9fb90c 100644 --- a/app/models/form/sales/questions/prevown.rb +++ b/app/models/form/sales/questions/prevown.rb @@ -1,11 +1,12 @@ class Form::Sales::Questions::Prevown < ::Form::Question - def initialize(id, hsh, page) - super + def initialize(id, hsh, page, joint_purchase:) + super(id, hsh, page) @id = "prevown" - @check_answer_label = "Buyers previously owned a property" - @header = "Has the buyer previously owned a property?" + @check_answer_label = I18n.t("check_answer_labels.prevown", count: joint_purchase ? 2 : 1) + @header = I18n.t("questions.prevown", count: joint_purchase ? 2 : 1) @type = "radio" @answer_options = ANSWER_OPTIONS + @question_number = 73 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/prevshared.rb b/app/models/form/sales/questions/prevshared.rb index 2c09cf485..b319281d3 100644 --- a/app/models/form/sales/questions/prevshared.rb +++ b/app/models/form/sales/questions/prevshared.rb @@ -7,6 +7,7 @@ class Form::Sales::Questions::Prevshared < ::Form::Question @type = "radio" @answer_options = ANSWER_OPTIONS @hint = "For any buyer" + @question_number = 74 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/privacy_notice.rb b/app/models/form/sales/questions/privacy_notice.rb index 4d7bb61c6..c08e4be6a 100644 --- a/app/models/form/sales/questions/privacy_notice.rb +++ b/app/models/form/sales/questions/privacy_notice.rb @@ -7,6 +7,7 @@ class Form::Sales::Questions::PrivacyNotice < ::Form::Question @type = "checkbox" @answer_options = ANSWER_OPTIONS @guidance_partial = "privacy_notice_buyer" + @question_number = 19 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/property_building_type.rb b/app/models/form/sales/questions/property_building_type.rb index 80102cc7a..fea48ce02 100644 --- a/app/models/form/sales/questions/property_building_type.rb +++ b/app/models/form/sales/questions/property_building_type.rb @@ -6,6 +6,7 @@ class Form::Sales::Questions::PropertyBuildingType < ::Form::Question @header = "What type of building is the property?" @type = "radio" @answer_options = ANSWER_OPTIONS + @question_number = 13 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/property_local_authority.rb b/app/models/form/sales/questions/property_local_authority.rb index 8def2d9f3..04dbed347 100644 --- a/app/models/form/sales/questions/property_local_authority.rb +++ b/app/models/form/sales/questions/property_local_authority.rb @@ -3,328 +3,16 @@ class Form::Sales::Questions::PropertyLocalAuthority < ::Form::Question super @id = "la" @check_answer_label = "Local authority" - @header = "What is the local authority of the property?" + @header = "What is the property’s local authority?" @type = "select" - @answer_options = ANSWER_OPTIONS + @question_number = 16 end - ANSWER_OPTIONS = { - "" => "Select an option", - "E07000223" => "Adur", - "E07000026" => "Allerdale", - "E07000032" => "Amber Valley", - "E07000224" => "Arun", - "E07000170" => "Ashfield", - "E07000105" => "Ashford", - "E07000200" => "Babergh", - "E09000002" => "Barking and Dagenham", - "E09000003" => "Barnet", - "E08000016" => "Barnsley", - "E07000027" => "Barrow-in-Furness", - "E07000066" => "Basildon", - "E07000084" => "Basingstoke and Deane", - "E07000171" => "Bassetlaw", - "E06000022" => "Bath and North East Somerset", - "E06000055" => "Bedford", - "E09000004" => "Bexley", - "E08000025" => "Birmingham", - "E07000129" => "Blaby", - "E06000008" => "Blackburn with Darwen", - "E06000009" => "Blackpool", - "E07000033" => "Bolsover", - "E08000001" => "Bolton", - "E07000136" => "Boston", - "E06000058" => "Bournemouth, Christchurch and Poole", - "E06000036" => "Bracknell Forest", - "E08000032" => "Bradford", - "E07000067" => "Braintree", - "E07000143" => "Breckland", - "E09000005" => "Brent", - "E07000068" => "Brentwood", - "E06000043" => "Brighton and Hove", - "E06000023" => "Bristol, City of", - "E07000144" => "Broadland", - "E09000006" => "Bromley", - "E07000234" => "Bromsgrove", - "E07000095" => "Broxbourne", - "E07000172" => "Broxtowe", - "E06000060" => "Buckinghamshire", - "E07000117" => "Burnley", - "E08000002" => "Bury", - "E08000033" => "Calderdale", - "E07000008" => "Cambridge", - "E09000007" => "Camden", - "E07000192" => "Cannock Chase", - "E07000106" => "Canterbury", - "E07000028" => "Carlisle", - "E07000069" => "Castle Point", - "E06000056" => "Central Bedfordshire", - "E07000130" => "Charnwood", - "E07000070" => "Chelmsford", - "E07000078" => "Cheltenham", - "E07000177" => "Cherwell", - "E06000049" => "Cheshire East", - "E06000050" => "Cheshire West and Chester", - "E07000034" => "Chesterfield", - "E07000225" => "Chichester", - "E07000118" => "Chorley", - "E09000001" => "City of London", - "E07000071" => "Colchester", - "E07000029" => "Copeland", - "E07000150" => "Corby", - "E06000052" => "Cornwall", - "E07000079" => "Cotswold", - "E06000047" => "County Durham", - "E08000026" => "Coventry", - "E07000163" => "Craven", - "E07000226" => "Crawley", - "E09000008" => "Croydon", - "E07000096" => "Dacorum", - "E06000005" => "Darlington", - "E07000107" => "Dartford", - "E07000151" => "Daventry", - "E06000015" => "Derby", - "E07000035" => "Derbyshire Dales", - "E08000017" => "Doncaster", - "E06000059" => "Dorset", - "E07000108" => "Dover", - "E08000027" => "Dudley", - "E09000009" => "Ealing", - "E07000009" => "East Cambridgeshire", - "E07000040" => "East Devon", - "E07000085" => "East Hampshire", - "E07000242" => "East Hertfordshire", - "E07000137" => "East Lindsey", - "E07000152" => "East Northamptonshire", - "E06000011" => "East Riding of Yorkshire", - "E07000193" => "East Staffordshire", - "E07000244" => "East Suffolk", - "E07000061" => "Eastbourne", - "E07000086" => "Eastleigh", - "E07000030" => "Eden", - "E07000207" => "Elmbridge", - "E09000010" => "Enfield", - "E07000072" => "Epping Forest", - "E07000208" => "Epsom and Ewell", - "E07000036" => "Erewash", - "E07000041" => "Exeter", - "E07000087" => "Fareham", - "E07000010" => "Fenland", - "E07000112" => "Folkestone and Hythe", - "E07000080" => "Forest of Dean", - "E07000119" => "Fylde", - "E08000037" => "Gateshead", - "E07000173" => "Gedling", - "E07000081" => "Gloucester", - "E07000088" => "Gosport", - "E07000109" => "Gravesham", - "E07000145" => "Great Yarmouth", - "E09000011" => "Greenwich", - "E07000209" => "Guildford", - "W06000002" => "Gwynedd", - "E09000012" => "Hackney", - "E06000006" => "Halton", - "E07000164" => "Hambleton", - "E09000013" => "Hammersmith and Fulham", - "E07000131" => "Harborough", - "E09000014" => "Haringey", - "E07000073" => "Harlow", - "E07000165" => "Harrogate", - "E09000015" => "Harrow", - "E07000089" => "Hart", - "E06000001" => "Hartlepool", - "E07000062" => "Hastings", - "E07000090" => "Havant", - "E09000016" => "Havering", - "E06000019" => "Herefordshire, County of", - "E07000098" => "Hertsmere", - "E07000037" => "High Peak", - "S12000017" => "Highland", - "E09000017" => "Hillingdon", - "E07000132" => "Hinckley and Bosworth", - "E07000227" => "Horsham", - "E09000018" => "Hounslow", - "E07000011" => "Huntingdonshire", - "E07000120" => "Hyndburn", - "E07000202" => "Ipswich", - "E06000046" => "Isle of Wight", - "E06000053" => "Isles of Scilly", - "E09000019" => "Islington", - "E09000020" => "Kensington and Chelsea", - "E07000153" => "Kettering", - "E07000146" => "King’s Lynn and West Norfolk", - "E06000010" => "Kingston upon Hull, City of", - "E09000021" => "Kingston upon Thames", - "E08000034" => "Kirklees", - "E08000011" => "Knowsley", - "E09000022" => "Lambeth", - "E07000121" => "Lancaster", - "E08000035" => "Leeds", - "E06000016" => "Leicester", - "E07000063" => "Lewes", - "E09000023" => "Lewisham", - "E07000194" => "Lichfield", - "E07000138" => "Lincoln", - "E08000012" => "Liverpool", - "E06000032" => "Luton", - "E07000110" => "Maidstone", - "E07000074" => "Maldon", - "E07000235" => "Malvern Hills", - "E08000003" => "Manchester", - "E07000174" => "Mansfield", - "E06000035" => "Medway", - "E07000133" => "Melton", - "E07000187" => "Mendip", - "E09000024" => "Merton", - "E07000042" => "Mid Devon", - "E07000203" => "Mid Suffolk", - "E07000228" => "Mid Sussex", - "E06000002" => "Middlesbrough", - "E06000042" => "Milton Keynes", - "E07000210" => "Mole Valley", - "E07000091" => "New Forest", - "E07000175" => "Newark and Sherwood", - "E08000021" => "Newcastle upon Tyne", - "E07000195" => "Newcastle-under-Lyme", - "E09000025" => "Newham", - "E07000043" => "North Devon", - "E07000038" => "North East Derbyshire", - "E06000012" => "North East Lincolnshire", - "E07000099" => "North Hertfordshire", - "E07000139" => "North Kesteven", - "E06000013" => "North Lincolnshire", - "E07000147" => "North Norfolk", - "E06000024" => "North Somerset", - "E08000022" => "North Tyneside", - "E07000218" => "North Warwickshire", - "E07000134" => "North West Leicestershire", - "E07000154" => "Northampton", - "E06000057" => "Northumberland", - "E07000148" => "Norwich", - "E06000018" => "Nottingham", - "E07000219" => "Nuneaton and Bedworth", - "E07000135" => "Oadby and Wigston", - "E08000004" => "Oldham", - "E07000178" => "Oxford", - "E07000122" => "Pendle", - "E06000031" => "Peterborough", - "E06000026" => "Plymouth", - "E06000044" => "Portsmouth", - "E07000123" => "Preston", - "E06000038" => "Reading", - "E09000026" => "Redbridge", - "E06000003" => "Redcar and Cleveland", - "E07000236" => "Redditch", - "E07000211" => "Reigate and Banstead", - "E07000124" => "Ribble Valley", - "E09000027" => "Richmond upon Thames", - "E07000166" => "Richmondshire", - "E08000005" => "Rochdale", - "E07000075" => "Rochford", - "E07000125" => "Rossendale", - "E07000064" => "Rother", - "E08000018" => "Rotherham", - "E07000220" => "Rugby", - "E07000212" => "Runnymede", - "E07000176" => "Rushcliffe", - "E07000092" => "Rushmoor", - "E06000017" => "Rutland", - "E07000167" => "Ryedale", - "E08000006" => "Salford", - "E08000028" => "Sandwell", - "E07000168" => "Scarborough", - "E07000188" => "Sedgemoor", - "E08000014" => "Sefton", - "E07000169" => "Selby", - "E07000111" => "Sevenoaks", - "E08000019" => "Sheffield", - "E06000051" => "Shropshire", - "E06000039" => "Slough", - "E08000029" => "Solihull", - "E07000246" => "Somerset West and Taunton", - "E07000012" => "South Cambridgeshire", - "E07000039" => "South Derbyshire", - "E06000025" => "South Gloucestershire", - "E07000044" => "South Hams", - "E07000140" => "South Holland", - "E07000141" => "South Kesteven", - "E07000031" => "South Lakeland", - "E07000149" => "South Norfolk", - "E07000155" => "South Northamptonshire", - "E07000179" => "South Oxfordshire", - "E07000126" => "South Ribble", - "E07000189" => "South Somerset", - "E07000196" => "South Staffordshire", - "E08000023" => "South Tyneside", - "E06000045" => "Southampton", - "E06000033" => "Southend-on-Sea", - "E09000028" => "Southwark", - "E07000213" => "Spelthorne", - "E07000240" => "St Albans", - "E08000013" => "St. Helens", - "E07000197" => "Stafford", - "E07000198" => "Staffordshire Moorlands", - "E07000243" => "Stevenage", - "E08000007" => "Stockport", - "E06000004" => "Stockton-on-Tees", - "E06000021" => "Stoke-on-Trent", - "E07000221" => "Stratford-on-Avon", - "E07000082" => "Stroud", - "E08000024" => "Sunderland", - "E07000214" => "Surrey Heath", - "E09000029" => "Sutton", - "E07000113" => "Swale", - "E06000030" => "Swindon", - "E08000008" => "Tameside", - "E07000199" => "Tamworth", - "E07000215" => "Tandridge", - "E07000045" => "Teignbridge", - "E06000020" => "Telford and Wrekin", - "E07000076" => "Tendring", - "E07000093" => "Test Valley", - "E07000083" => "Tewkesbury", - "E07000114" => "Thanet", - "E07000102" => "Three Rivers", - "E06000034" => "Thurrock", - "E07000115" => "Tonbridge and Malling", - "E06000027" => "Torbay", - "E07000046" => "Torridge", - "E09000030" => "Tower Hamlets", - "E08000009" => "Trafford", - "E07000116" => "Tunbridge Wells", - "E07000077" => "Uttlesford", - "E07000180" => "Vale of White Horse", - "E08000036" => "Wakefield", - "E08000030" => "Walsall", - "E09000031" => "Waltham Forest", - "E09000032" => "Wandsworth", - "E06000007" => "Warrington", - "E07000222" => "Warwick", - "E07000103" => "Watford", - "E07000216" => "Waverley", - "E07000065" => "Wealden", - "E07000156" => "Wellingborough", - "E07000241" => "Welwyn Hatfield", - "E06000037" => "West Berkshire", - "E07000047" => "West Devon", - "E07000127" => "West Lancashire", - "E07000142" => "West Lindsey", - "E07000181" => "West Oxfordshire", - "E07000245" => "West Suffolk", - "E09000033" => "Westminster", - "E08000010" => "Wigan", - "E06000054" => "Wiltshire", - "E07000094" => "Winchester", - "E06000040" => "Windsor and Maidenhead", - "E08000015" => "Wirral", - "E07000217" => "Woking", - "E06000041" => "Wokingham", - "E08000031" => "Wolverhampton", - "E07000237" => "Worcester", - "E07000229" => "Worthing", - "E07000238" => "Wychavon", - "E07000128" => "Wyre", - "E07000239" => "Wyre Forest", - "E06000014" => "York", - }.freeze + def answer_options + { "" => "Select an option" }.merge(LocalAuthority.active(form.start_date).england.map { |la| [la.code, la.name] }.to_h) + end + + def hidden_in_check_answers?(log, _current_user = nil) + log.saledate && log.saledate.year >= 2023 && log.is_la_inferred? + end end diff --git a/app/models/form/sales/questions/property_local_authority_known.rb b/app/models/form/sales/questions/property_local_authority_known.rb index 912ddbd8e..196ee8e6a 100644 --- a/app/models/form/sales/questions/property_local_authority_known.rb +++ b/app/models/form/sales/questions/property_local_authority_known.rb @@ -14,6 +14,7 @@ class Form::Sales::Questions::PropertyLocalAuthorityKnown < ::Form::Question }, ], } + @question_number = 16 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/property_number_of_bedrooms.rb b/app/models/form/sales/questions/property_number_of_bedrooms.rb index e8ea674ea..9dbdbf3e8 100644 --- a/app/models/form/sales/questions/property_number_of_bedrooms.rb +++ b/app/models/form/sales/questions/property_number_of_bedrooms.rb @@ -9,5 +9,6 @@ class Form::Sales::Questions::PropertyNumberOfBedrooms < ::Form::Question @width = 10 @min = 1 @max = 9 + @question_number = 11 end end diff --git a/app/models/form/sales/questions/property_unit_type.rb b/app/models/form/sales/questions/property_unit_type.rb index afa4f0f38..f44bd67d3 100644 --- a/app/models/form/sales/questions/property_unit_type.rb +++ b/app/models/form/sales/questions/property_unit_type.rb @@ -6,6 +6,7 @@ class Form::Sales::Questions::PropertyUnitType < ::Form::Question @header = "What type of unit is the property?" @type = "radio" @answer_options = ANSWER_OPTIONS + @question_number = 12 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/property_wheelchair_accessible.rb b/app/models/form/sales/questions/property_wheelchair_accessible.rb index bfdd133c2..feb017be0 100644 --- a/app/models/form/sales/questions/property_wheelchair_accessible.rb +++ b/app/models/form/sales/questions/property_wheelchair_accessible.rb @@ -6,6 +6,7 @@ class Form::Sales::Questions::PropertyWheelchairAccessible < ::Form::Question @header = "Is the property build or adapted to wheelchair-user standards?" @type = "radio" @answer_options = ANSWER_OPTIONS + @question_number = 17 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/purchase_price.rb b/app/models/form/sales/questions/purchase_price.rb index 6242e45e8..c98a39ef3 100644 --- a/app/models/form/sales/questions/purchase_price.rb +++ b/app/models/form/sales/questions/purchase_price.rb @@ -1,6 +1,6 @@ class Form::Sales::Questions::PurchasePrice < ::Form::Question - def initialize(id, hsh, page) - super + def initialize(id, hsh, page, ownershipsch:) + super(id, hsh, page) @id = "value" @check_answer_label = "Purchase price" @header = "What is the full purchase price?" @@ -9,5 +9,16 @@ class Form::Sales::Questions::PurchasePrice < ::Form::Question @width = 5 @prefix = "£" @hint_text = "For all schemes, including Right to Acquire (RTA), Right to Buy (RTB), Voluntary Right to Buy (VRTB) or Preserved Right to Buy (PRTB) sales, enter the full price of the property without any discount" + @ownership_sch = ownershipsch + @question_number = question_number + end + + def question_number + case @ownership_sch + when 2 + 100 + when 3 + 110 + end end end diff --git a/app/models/form/sales/questions/purchase_price_outright_ownership.rb b/app/models/form/sales/questions/purchase_price_outright_ownership.rb deleted file mode 100644 index 9824a4629..000000000 --- a/app/models/form/sales/questions/purchase_price_outright_ownership.rb +++ /dev/null @@ -1,12 +0,0 @@ -class Form::Sales::Questions::PurchasePriceOutrightOwnership < ::Form::Question - def initialize(id, hsh, page) - super - @id = "value" - @check_answer_label = "Purchase price" - @header = "What is the full purchase price?" - @type = "numeric" - @min = 0 - @width = 5 - @prefix = "£" - end -end diff --git a/app/models/form/sales/questions/purchaser_code.rb b/app/models/form/sales/questions/purchaser_code.rb index 7a5cc4bf7..d288c9f5b 100644 --- a/app/models/form/sales/questions/purchaser_code.rb +++ b/app/models/form/sales/questions/purchaser_code.rb @@ -7,5 +7,6 @@ class Form::Sales::Questions::PurchaserCode < ::Form::Question @hint_text = "This is how you usually refer to the purchaser on your own systems." @type = "text" @width = 10 + @question_number = 2 end end diff --git a/app/models/form/sales/questions/resale.rb b/app/models/form/sales/questions/resale.rb index e67491d65..e0d2d99f5 100644 --- a/app/models/form/sales/questions/resale.rb +++ b/app/models/form/sales/questions/resale.rb @@ -7,6 +7,7 @@ class Form::Sales::Questions::Resale < ::Form::Question @type = "radio" @answer_options = ANSWER_OPTIONS @hint_text = "If the social landlord has previously sold the property to another buyer and is now reselling the property, select 'yes'. If this is the first time the property has been sold, select 'no'." + @question_number = 80 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/sale_date.rb b/app/models/form/sales/questions/sale_date.rb index ce085b646..735872a6c 100644 --- a/app/models/form/sales/questions/sale_date.rb +++ b/app/models/form/sales/questions/sale_date.rb @@ -5,5 +5,6 @@ class Form::Sales::Questions::SaleDate < ::Form::Question @check_answer_label = "Sale completion date" @header = "What is the sale completion date?" @type = "date" + @question_number = 1 end end diff --git a/app/models/form/sales/questions/savings.rb b/app/models/form/sales/questions/savings.rb index 920b87d4f..086a0ec8d 100644 --- a/app/models/form/sales/questions/savings.rb +++ b/app/models/form/sales/questions/savings.rb @@ -9,5 +9,6 @@ class Form::Sales::Questions::Savings < ::Form::Question @prefix = "£" @step = 1 @min = 0 + @question_number = 72 end end diff --git a/app/models/form/sales/questions/savings_nk.rb b/app/models/form/sales/questions/savings_nk.rb index f68b45560..515f0a544 100644 --- a/app/models/form/sales/questions/savings_nk.rb +++ b/app/models/form/sales/questions/savings_nk.rb @@ -16,6 +16,7 @@ class Form::Sales::Questions::SavingsNk < ::Form::Question }, ], } + @question_number = 72 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/shared_ownership_type.rb b/app/models/form/sales/questions/shared_ownership_type.rb index 73b6a4e17..e0cb5b486 100644 --- a/app/models/form/sales/questions/shared_ownership_type.rb +++ b/app/models/form/sales/questions/shared_ownership_type.rb @@ -7,6 +7,7 @@ class Form::Sales::Questions::SharedOwnershipType < ::Form::Question @hint_text = "A shared ownership sale is when the purchaser buys up to 75% of the property value and pays rent to the Private Registered Provider (PRP) on the remaining portion" @type = "radio" @answer_options = answer_options + @question_number = 4 end def answer_options diff --git a/app/models/form/sales/questions/staircase.rb b/app/models/form/sales/questions/staircase.rb index c03c24089..d01f0ea40 100644 --- a/app/models/form/sales/questions/staircase.rb +++ b/app/models/form/sales/questions/staircase.rb @@ -7,6 +7,7 @@ class Form::Sales::Questions::Staircase < ::Form::Question @type = "radio" @answer_options = ANSWER_OPTIONS @hint_text = "A staircasing transaction is when the household purchases more shares in their property, increasing the proportion they own and decreasing the proportion the housing association owns. Once the household purchases 100% of the shares, they own the property" + @question_number = 76 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/staircase_bought.rb b/app/models/form/sales/questions/staircase_bought.rb index 385cfb782..9e54e92d3 100644 --- a/app/models/form/sales/questions/staircase_bought.rb +++ b/app/models/form/sales/questions/staircase_bought.rb @@ -9,5 +9,6 @@ class Form::Sales::Questions::StaircaseBought < ::Form::Question @min = 0 @max = 100 @suffix = "%" + @question_number = 77 end end diff --git a/app/models/form/sales/questions/staircase_owned.rb b/app/models/form/sales/questions/staircase_owned.rb index 7e6dab5d6..b8d5a65ec 100644 --- a/app/models/form/sales/questions/staircase_owned.rb +++ b/app/models/form/sales/questions/staircase_owned.rb @@ -1,13 +1,14 @@ class Form::Sales::Questions::StaircaseOwned < ::Form::Question - def initialize(id, hsh, page) - super + def initialize(id, hsh, page, joint_purchase:) + super(id, hsh, page) @id = "stairowned" - @check_answer_label = "Percentage the buyer now owns in total" - @header = "What percentage of the property does the buyer now own in total?" + @check_answer_label = I18n.t("check_answer_labels.stairowned", count: joint_purchase ? 2 : 1) + @header = I18n.t("questions.stairowned", count: joint_purchase ? 2 : 1) @type = "numeric" @width = 5 @min = 0 @max = 100 @suffix = "%" + @question_number = 78 end end diff --git a/app/models/form/sales/questions/staircase_sale.rb b/app/models/form/sales/questions/staircase_sale.rb index fb56572cf..aaf2f6a08 100644 --- a/app/models/form/sales/questions/staircase_sale.rb +++ b/app/models/form/sales/questions/staircase_sale.rb @@ -6,6 +6,7 @@ class Form::Sales::Questions::StaircaseSale < ::Form::Question @header = "Is this transaction part of a back-to-back staircasing transaction to facilitate sale of the home on the open market?" @type = "radio" @answer_options = ANSWER_OPTIONS + @question_number = 79 end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/questions/town_or_city.rb b/app/models/form/sales/questions/town_or_city.rb new file mode 100644 index 000000000..9dde3aeb8 --- /dev/null +++ b/app/models/form/sales/questions/town_or_city.rb @@ -0,0 +1,13 @@ +class Form::Sales::Questions::TownOrCity < ::Form::Question + def initialize(id, hsh, page) + super + @id = "town_or_city" + @header = "Town or city" + @type = "text" + @plain_label = true + end + + def hidden_in_check_answers?(_log = nil, _current_user = nil) + true + end +end diff --git a/app/models/form/sales/questions/uprn.rb b/app/models/form/sales/questions/uprn.rb new file mode 100644 index 000000000..2c0b66dc8 --- /dev/null +++ b/app/models/form/sales/questions/uprn.rb @@ -0,0 +1,34 @@ +class Form::Sales::Questions::Uprn < ::Form::Question + def initialize(id, hsh, page) + super + @id = "uprn" + @check_answer_label = "UPRN" + @header = "What is the property's UPRN" + @type = "text" + @hint_text = "The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355." + @width = 10 + end + + def unanswered_error_message + I18n.t("validations.property.uprn.invalid") + end + + def get_extra_check_answer_value(log) + value = [ + log.address_line1, + log.address_line2, + log.town_or_city, + log.county, + log.postcode_full, + (LocalAuthority.find_by(code: log.la)&.name if log.la.present?), + ].select(&:present?) + + return unless value.any? + + "\n\n#{value.join("\n")}" + end + + def hidden_in_check_answers?(log, _current_user = nil) + log.uprn_known != 1 + end +end diff --git a/app/models/form/sales/questions/uprn_confirmation.rb b/app/models/form/sales/questions/uprn_confirmation.rb new file mode 100644 index 000000000..38ad9c938 --- /dev/null +++ b/app/models/form/sales/questions/uprn_confirmation.rb @@ -0,0 +1,34 @@ +class Form::Sales::Questions::UprnConfirmation < ::Form::Question + def initialize(id, hsh, page) + super + @id = "uprn_confirmed" + @header = "Is this the property address?" + @type = "radio" + @answer_options = ANSWER_OPTIONS + @check_answer_label = "Is this the right address?" + end + + ANSWER_OPTIONS = { + "1" => { "value" => "Yes" }, + "0" => { "value" => "No, I want to enter the address manually" }, + }.freeze + + def notification_banner(log = nil) + return unless log&.uprn + + { + title: "UPRN: #{log.uprn}", + heading: [ + log.address_line1, + log.address_line2, + log.postcode_full, + log.town_or_city, + log.county, + ].select(&:present?).join("\n"), + } + end + + def hidden_in_check_answers?(log, _current_user = nil) + log.uprn_known != 1 || log.uprn_confirmed.present? + end +end diff --git a/app/models/form/sales/questions/uprn_known.rb b/app/models/form/sales/questions/uprn_known.rb new file mode 100644 index 000000000..9f192f7de --- /dev/null +++ b/app/models/form/sales/questions/uprn_known.rb @@ -0,0 +1,21 @@ +class Form::Sales::Questions::UprnKnown < ::Form::Question + def initialize(id, hsh, page) + super + @id = "uprn_known" + @check_answer_label = "UPRN known?" + @header = "Do you know the property UPRN?" + @type = "radio" + @answer_options = ANSWER_OPTIONS + @hint_text = "The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355.

+ You can continue without the UPRN, but it means we will need you to enter the address of the property." + end + + ANSWER_OPTIONS = { + "1" => { "value" => "Yes" }, + "0" => { "value" => "No" }, + }.freeze + + def unanswered_error_message + I18n.t("validations.property.uprn_known.invalid") + end +end diff --git a/app/models/form/sales/questions/value.rb b/app/models/form/sales/questions/value.rb index 24e20e5ca..4736f37af 100644 --- a/app/models/form/sales/questions/value.rb +++ b/app/models/form/sales/questions/value.rb @@ -9,5 +9,6 @@ class Form::Sales::Questions::Value < ::Form::Question @width = 5 @prefix = "£" @hint_text = "Enter the full purchase price of the property before any discounts are applied. For shared ownership, enter the full purchase price paid for 100% equity (this is equal to the value of the share owned by the PRP plus the value bought by the purchaser)" + @question_number = 88 end end diff --git a/app/models/form/sales/subsections/discounted_ownership_scheme.rb b/app/models/form/sales/subsections/discounted_ownership_scheme.rb index a44f10ee9..f9292b6d6 100644 --- a/app/models/form/sales/subsections/discounted_ownership_scheme.rb +++ b/app/models/form/sales/subsections/discounted_ownership_scheme.rb @@ -8,30 +8,30 @@ class Form::Sales::Subsections::DiscountedOwnershipScheme < ::Form::Subsection def pages @pages ||= [ - Form::Sales::Pages::LivingBeforePurchase.new("living_before_purchase_discounted_ownership", nil, self), + Form::Sales::Pages::LivingBeforePurchase.new("living_before_purchase_discounted_ownership", nil, self, ownershipsch: 2), Form::Sales::Pages::AboutPriceRtb.new(nil, nil, self), Form::Sales::Pages::ExtraBorrowingValueCheck.new("extra_borrowing_price_value_check", nil, self), Form::Sales::Pages::AboutPriceNotRtb.new(nil, nil, self), Form::Sales::Pages::GrantValueCheck.new(nil, nil, self), - Form::Sales::Pages::PurchasePriceOutrightOwnership.new("purchase_price_outright_ownership", nil, self), + Form::Sales::Pages::PurchasePriceOutrightOwnership.new("purchase_price_discounted_ownership", nil, self, ownershipsch: 2), Form::Sales::Pages::AboutPriceValueCheck.new("about_price_discounted_ownership_value_check", nil, self), Form::Sales::Pages::DepositAndMortgageValueCheck.new("discounted_ownership_deposit_and_mortgage_value_check_after_value_and_discount", nil, self), - Form::Sales::Pages::Mortgageused.new("mortgage_used_discounted_ownership", nil, self), + Form::Sales::Pages::Mortgageused.new("mortgage_used_discounted_ownership", nil, self, ownershipsch: 2), Form::Sales::Pages::MortgageValueCheck.new("discounted_ownership_mortgage_used_mortgage_value_check", nil, self), - Form::Sales::Pages::MortgageAmount.new("mortgage_amount_discounted_ownership", nil, self), + Form::Sales::Pages::MortgageAmount.new("mortgage_amount_discounted_ownership", nil, self, ownershipsch: 2), Form::Sales::Pages::MortgageValueCheck.new("discounted_ownership_mortgage_amount_mortgage_value_check", nil, self), Form::Sales::Pages::ExtraBorrowingValueCheck.new("extra_borrowing_mortgage_value_check", nil, self), Form::Sales::Pages::DepositAndMortgageValueCheck.new("discounted_ownership_deposit_and_mortgage_value_check_after_mortgage", nil, self), - Form::Sales::Pages::MortgageLender.new("mortgage_lender_discounted_ownership", nil, self), - Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_discounted_ownership", nil, self), - Form::Sales::Pages::MortgageLength.new("mortgage_length_discounted_ownership", nil, self), - Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_discounted_ownership", nil, self), + Form::Sales::Pages::MortgageLender.new("mortgage_lender_discounted_ownership", nil, self, ownershipsch: 2), + Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_discounted_ownership", nil, self, ownershipsch: 2), + Form::Sales::Pages::MortgageLength.new("mortgage_length_discounted_ownership", nil, self, ownershipsch: 2), + Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_discounted_ownership", nil, self, ownershipsch: 2), Form::Sales::Pages::ExtraBorrowingValueCheck.new("extra_borrowing_value_check", nil, self), - Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_discounted_ownership", nil, self), + Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_discounted_ownership", nil, self, ownershipsch: 2), Form::Sales::Pages::ExtraBorrowingValueCheck.new("extra_borrowing_deposit_value_check", nil, self), Form::Sales::Pages::DepositValueCheck.new("discounted_ownership_deposit_value_check", nil, self), Form::Sales::Pages::DepositAndMortgageValueCheck.new("discounted_ownership_deposit_and_mortgage_value_check_after_deposit", nil, self), - Form::Sales::Pages::LeaseholdCharges.new("leasehold_charges_discounted_ownership", nil, self), + Form::Sales::Pages::LeaseholdCharges.new("leasehold_charges_discounted_ownership", nil, self, ownershipsch: 2), Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_discounted_ownership_value_check", nil, self), ] end diff --git a/app/models/form/sales/subsections/household_characteristics.rb b/app/models/form/sales/subsections/household_characteristics.rb index 571968c8f..922d95edd 100644 --- a/app/models/form/sales/subsections/household_characteristics.rb +++ b/app/models/form/sales/subsections/household_characteristics.rb @@ -3,7 +3,7 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection super @id = "household_characteristics" @label = "Household characteristics" - @depends_on = [{ "setup_completed?" => true }] + @depends_on = [{ "setup_completed?" => true, "company_buyer?" => false }] end def pages @@ -27,69 +27,94 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Sales::Pages::Buyer1IncomeValueCheck.new("working_situation_buyer_1_income_value_check", nil, self), Form::Sales::Pages::Buyer1LiveInProperty.new(nil, nil, self), Form::Sales::Pages::Buyer2RelationshipToBuyer1.new(nil, nil, self), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("buyer_2_relationship_student_not_child_value_check", nil, self, person_index: 2), Form::Sales::Pages::Age2.new(nil, nil, self), Form::Sales::Pages::OldPersonsSharedOwnershipValueCheck.new("age_2_old_persons_shared_ownership_value_check", nil, self), Form::Sales::Pages::RetirementValueCheck.new("age_2_buyer_retirement_value_check", nil, self, person_index: 2), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("buyer_2_age_student_not_child_value_check", nil, self, person_index: 2), Form::Sales::Pages::GenderIdentity2.new(nil, nil, self), Form::Sales::Pages::RetirementValueCheck.new("gender_2_buyer_retirement_value_check", nil, self, person_index: 2), - ethnic_pages_for_buyer_2, + buyer_2_ethnicity_nationality_pages, Form::Sales::Pages::Buyer2WorkingSituation.new(nil, nil, self), Form::Sales::Pages::RetirementValueCheck.new("working_situation_2_retirement_value_check_joint_purchase", nil, self, person_index: 2), Form::Sales::Pages::Buyer2IncomeValueCheck.new("working_situation_buyer_2_income_value_check", nil, self), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("buyer_2_working_situation_student_not_child_value_check", nil, self, person_index: 2), Form::Sales::Pages::Buyer2LiveInProperty.new(nil, nil, self), Form::Sales::Pages::NumberOfOthersInProperty.new("number_of_others_in_property", nil, self, joint_purchase: false), Form::Sales::Pages::NumberOfOthersInProperty.new("number_of_others_in_property_joint_purchase", nil, self, joint_purchase: true), Form::Sales::Pages::PersonKnown.new("person_2_known", nil, self, person_index: 2), Form::Sales::Pages::PersonRelationshipToBuyer1.new("person_2_relationship_to_buyer_1", nil, self, person_index: 2), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("relationship_2_student_not_child_value_check", nil, self, person_index: 2), Form::Sales::Pages::PersonAge.new("person_2_age", nil, self, person_index: 2), Form::Sales::Pages::RetirementValueCheck.new("age_2_retirement_value_check", nil, self, person_index: 2), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("age_2_student_not_child_value_check", nil, self, person_index: 2), Form::Sales::Pages::PersonGenderIdentity.new("person_2_gender_identity", nil, self, person_index: 2), Form::Sales::Pages::RetirementValueCheck.new("gender_2_retirement_value_check", nil, self, person_index: 2), Form::Sales::Pages::PersonWorkingSituation.new("person_2_working_situation", nil, self, person_index: 2), Form::Sales::Pages::RetirementValueCheck.new("working_situation_2_retirement_value_check", nil, self, person_index: 2), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("working_situation_2_student_not_child_value_check", nil, self, person_index: 2), Form::Sales::Pages::PersonKnown.new("person_3_known", nil, self, person_index: 3), Form::Sales::Pages::PersonRelationshipToBuyer1.new("person_3_relationship_to_buyer_1", nil, self, person_index: 3), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("relationship_3_student_not_child_value_check", nil, self, person_index: 3), Form::Sales::Pages::PersonAge.new("person_3_age", nil, self, person_index: 3), Form::Sales::Pages::RetirementValueCheck.new("age_3_retirement_value_check", nil, self, person_index: 3), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("age_3_student_not_child_value_check", nil, self, person_index: 3), Form::Sales::Pages::PersonGenderIdentity.new("person_3_gender_identity", nil, self, person_index: 3), Form::Sales::Pages::RetirementValueCheck.new("gender_3_retirement_value_check", nil, self, person_index: 3), Form::Sales::Pages::PersonWorkingSituation.new("person_3_working_situation", nil, self, person_index: 3), Form::Sales::Pages::RetirementValueCheck.new("working_situation_3_retirement_value_check", nil, self, person_index: 3), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("working_situation_3_student_not_child_value_check", nil, self, person_index: 3), Form::Sales::Pages::PersonKnown.new("person_4_known", nil, self, person_index: 4), Form::Sales::Pages::PersonRelationshipToBuyer1.new("person_4_relationship_to_buyer_1", nil, self, person_index: 4), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("relationship_4_student_not_child_value_check", nil, self, person_index: 4), Form::Sales::Pages::PersonAge.new("person_4_age", nil, self, person_index: 4), Form::Sales::Pages::RetirementValueCheck.new("age_4_retirement_value_check", nil, self, person_index: 4), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("age_4_student_not_child_value_check", nil, self, person_index: 4), Form::Sales::Pages::PersonGenderIdentity.new("person_4_gender_identity", nil, self, person_index: 4), Form::Sales::Pages::RetirementValueCheck.new("gender_4_retirement_value_check", nil, self, person_index: 4), Form::Sales::Pages::PersonWorkingSituation.new("person_4_working_situation", nil, self, person_index: 4), Form::Sales::Pages::RetirementValueCheck.new("working_situation_4_retirement_value_check", nil, self, person_index: 4), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("working_situation_4_student_not_child_value_check", nil, self, person_index: 4), Form::Sales::Pages::PersonKnown.new("person_5_known", nil, self, person_index: 5), Form::Sales::Pages::PersonRelationshipToBuyer1.new("person_5_relationship_to_buyer_1", nil, self, person_index: 5), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("relationship_5_student_not_child_value_check", nil, self, person_index: 5), Form::Sales::Pages::PersonAge.new("person_5_age", nil, self, person_index: 5), Form::Sales::Pages::RetirementValueCheck.new("age_5_retirement_value_check", nil, self, person_index: 5), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("age_5_student_not_child_value_check", nil, self, person_index: 5), Form::Sales::Pages::PersonGenderIdentity.new("person_5_gender_identity", nil, self, person_index: 5), Form::Sales::Pages::RetirementValueCheck.new("gender_5_retirement_value_check", nil, self, person_index: 5), Form::Sales::Pages::PersonWorkingSituation.new("person_5_working_situation", nil, self, person_index: 5), Form::Sales::Pages::RetirementValueCheck.new("working_situation_5_retirement_value_check", nil, self, person_index: 5), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("working_situation_5_student_not_child_value_check", nil, self, person_index: 5), Form::Sales::Pages::PersonKnown.new("person_6_known", nil, self, person_index: 6), Form::Sales::Pages::PersonRelationshipToBuyer1.new("person_6_relationship_to_buyer_1", nil, self, person_index: 6), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("relationship_6_student_not_child_value_check", nil, self, person_index: 6), Form::Sales::Pages::PersonAge.new("person_6_age", nil, self, person_index: 6), Form::Sales::Pages::RetirementValueCheck.new("age_6_retirement_value_check", nil, self, person_index: 6), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("age_6_student_not_child_value_check", nil, self, person_index: 6), Form::Sales::Pages::PersonGenderIdentity.new("person_6_gender_identity", nil, self, person_index: 6), Form::Sales::Pages::RetirementValueCheck.new("gender_6_retirement_value_check", nil, self, person_index: 6), Form::Sales::Pages::PersonWorkingSituation.new("person_6_working_situation", nil, self, person_index: 6), Form::Sales::Pages::RetirementValueCheck.new("working_situation_6_retirement_value_check", nil, self, person_index: 6), + Form::Sales::Pages::PersonStudentNotChildValueCheck.new("working_situation_6_student_not_child_value_check", nil, self, person_index: 6), ].flatten.compact end - def ethnic_pages_for_buyer_2 + def buyer_2_ethnicity_nationality_pages if form.start_date.year >= 2023 - [Form::Sales::Pages::Buyer2EthnicGroup.new(nil, nil, self), - Form::Sales::Pages::Buyer2EthnicBackgroundBlack.new(nil, nil, self), - Form::Sales::Pages::Buyer2EthnicBackgroundAsian.new(nil, nil, self), - Form::Sales::Pages::Buyer2EthnicBackgroundArab.new(nil, nil, self), - Form::Sales::Pages::Buyer2EthnicBackgroundMixed.new(nil, nil, self), - Form::Sales::Pages::Buyer2EthnicBackgroundWhite.new(nil, nil, self)] + [ + Form::Sales::Pages::Buyer2EthnicGroup.new(nil, nil, self), + Form::Sales::Pages::Buyer2EthnicBackgroundBlack.new(nil, nil, self), + Form::Sales::Pages::Buyer2EthnicBackgroundAsian.new(nil, nil, self), + Form::Sales::Pages::Buyer2EthnicBackgroundArab.new(nil, nil, self), + Form::Sales::Pages::Buyer2EthnicBackgroundMixed.new(nil, nil, self), + Form::Sales::Pages::Buyer2EthnicBackgroundWhite.new(nil, nil, self), + Form::Sales::Pages::Buyer2Nationality.new(nil, nil, self), + ] end end + + def displayed_in_tasklist?(log) + !log.company_buyer? + end end diff --git a/app/models/form/sales/subsections/household_situation.rb b/app/models/form/sales/subsections/household_situation.rb index a9d9306d6..225b1ae43 100644 --- a/app/models/form/sales/subsections/household_situation.rb +++ b/app/models/form/sales/subsections/household_situation.rb @@ -12,6 +12,16 @@ class Form::Sales::Subsections::HouseholdSituation < ::Form::Subsection Form::Sales::Pages::LastAccommodation.new(nil, nil, self), Form::Sales::Pages::LastAccommodationLa.new(nil, nil, self), Form::Sales::Pages::BuyersOrganisations.new(nil, nil, self), - ] + buyer_2_situation_pages, + ].flatten.compact + end + + def buyer_2_situation_pages + if form.start_date.year >= 2023 + [ + Form::Sales::Pages::Buyer2LivingIn.new(nil, nil, self), + Form::Sales::Pages::Buyer2PreviousHousingSituation.new(nil, nil, self), + ] + end end end diff --git a/app/models/form/sales/subsections/income_benefits_and_savings.rb b/app/models/form/sales/subsections/income_benefits_and_savings.rb index 9ff584d47..502b87fc9 100644 --- a/app/models/form/sales/subsections/income_benefits_and_savings.rb +++ b/app/models/form/sales/subsections/income_benefits_and_savings.rb @@ -23,7 +23,8 @@ class Form::Sales::Subsections::IncomeBenefitsAndSavings < ::Form::Subsection Form::Sales::Pages::Savings.new(nil, nil, self), Form::Sales::Pages::SavingsValueCheck.new("savings_value_check", nil, self), Form::Sales::Pages::DepositValueCheck.new("savings_deposit_value_check", nil, self), - Form::Sales::Pages::PreviousOwnership.new(nil, nil, self), + Form::Sales::Pages::PreviousOwnership.new("previous_ownership_joint_purchase", nil, self, joint_purchase: true), + Form::Sales::Pages::PreviousOwnership.new("previous_ownership_not_joint_purchase", nil, self, joint_purchase: false), previous_shared_page, ].compact end diff --git a/app/models/form/sales/subsections/outright_sale.rb b/app/models/form/sales/subsections/outright_sale.rb index 100c8fa64..d29dc5759 100644 --- a/app/models/form/sales/subsections/outright_sale.rb +++ b/app/models/form/sales/subsections/outright_sale.rb @@ -8,17 +8,17 @@ class Form::Sales::Subsections::OutrightSale < ::Form::Subsection def pages @pages ||= [ - Form::Sales::Pages::PurchasePriceOutrightOwnership.new("purchase_price_outright_sale", nil, self), + Form::Sales::Pages::PurchasePriceOutrightOwnership.new("purchase_price_outright_sale", nil, self, ownershipsch: 3), Form::Sales::Pages::AboutPriceValueCheck.new("about_price_outright_sale_value_check", nil, self), - Form::Sales::Pages::Mortgageused.new("mortgage_used_outright_sale", nil, self), + Form::Sales::Pages::Mortgageused.new("mortgage_used_outright_sale", nil, self, ownershipsch: 3), Form::Sales::Pages::MortgageValueCheck.new("outright_sale_mortgage_used_mortgage_value_check", nil, self), - Form::Sales::Pages::MortgageAmount.new("mortgage_amount_outright_sale", nil, self), + Form::Sales::Pages::MortgageAmount.new("mortgage_amount_outright_sale", nil, self, ownershipsch: 3), Form::Sales::Pages::MortgageValueCheck.new("outright_sale_mortgage_amount_mortgage_value_check", nil, self), - Form::Sales::Pages::MortgageLender.new("mortgage_lender_outright_sale", nil, self), - Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_outright_sale", nil, self), - Form::Sales::Pages::MortgageLength.new("mortgage_length_outright_sale", nil, self), - Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_outright_sale", nil, self), - Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_outright_sale", nil, self), + Form::Sales::Pages::MortgageLender.new("mortgage_lender_outright_sale", nil, self, ownershipsch: 3), + Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_outright_sale", nil, self, ownershipsch: 3), + Form::Sales::Pages::MortgageLength.new("mortgage_length_outright_sale", nil, self, ownershipsch: 3), + Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_outright_sale", nil, self, ownershipsch: 3), + Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_outright_sale", nil, self, ownershipsch: 3), Form::Sales::Pages::DepositValueCheck.new("outright_sale_deposit_value_check", nil, self), leasehold_charge_pages, Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_outright_sale_value_check", nil, self), @@ -31,7 +31,7 @@ class Form::Sales::Subsections::OutrightSale < ::Form::Subsection def leasehold_charge_pages if form.start_date.year >= 2023 - Form::Sales::Pages::LeaseholdCharges.new("leasehold_charges_outright_sale", nil, self) + Form::Sales::Pages::LeaseholdCharges.new("leasehold_charges_outright_sale", nil, self, ownershipsch: 3) end end end diff --git a/app/models/form/sales/subsections/property_information.rb b/app/models/form/sales/subsections/property_information.rb index a43607d7c..cca34a764 100644 --- a/app/models/form/sales/subsections/property_information.rb +++ b/app/models/form/sales/subsections/property_information.rb @@ -8,15 +8,36 @@ class Form::Sales::Subsections::PropertyInformation < ::Form::Subsection def pages @pages ||= [ + uprn_questions, Form::Sales::Pages::PropertyNumberOfBedrooms.new(nil, nil, self), Form::Sales::Pages::AboutPriceValueCheck.new("about_price_bedrooms_value_check", nil, self), Form::Sales::Pages::PropertyUnitType.new(nil, nil, self), Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_property_type_value_check", nil, self), Form::Sales::Pages::PropertyBuildingType.new(nil, nil, self), - Form::Sales::Pages::Postcode.new(nil, nil, self), - Form::Sales::Pages::PropertyLocalAuthority.new(nil, nil, self), + postcode_and_la_questions, Form::Sales::Pages::AboutPriceValueCheck.new("about_price_la_value_check", nil, self), Form::Sales::Pages::PropertyWheelchairAccessible.new(nil, nil, self), - ] + ].flatten.compact + end + + def uprn_questions + if form.start_date.year >= 2023 + [ + Form::Sales::Pages::UprnKnown.new(nil, nil, self), + Form::Sales::Pages::Uprn.new(nil, nil, self), + Form::Sales::Pages::UprnConfirmation.new(nil, nil, self), + Form::Sales::Pages::Address.new(nil, nil, self), + Form::Sales::Pages::PropertyLocalAuthority.new(nil, nil, self), + ] + end + end + + def postcode_and_la_questions + if form.start_date.year < 2023 + [ + Form::Sales::Pages::Postcode.new(nil, nil, self), + Form::Sales::Pages::PropertyLocalAuthority.new(nil, nil, self), + ] + end end end diff --git a/app/models/form/sales/subsections/shared_ownership_scheme.rb b/app/models/form/sales/subsections/shared_ownership_scheme.rb index 1f0cd6450..afd13ec47 100644 --- a/app/models/form/sales/subsections/shared_ownership_scheme.rb +++ b/app/models/form/sales/subsections/shared_ownership_scheme.rb @@ -8,37 +8,39 @@ class Form::Sales::Subsections::SharedOwnershipScheme < ::Form::Subsection def pages @pages ||= [ - Form::Sales::Pages::LivingBeforePurchase.new("living_before_purchase_shared_ownership", nil, self), + Form::Sales::Pages::LivingBeforePurchase.new("living_before_purchase_shared_ownership", nil, self, ownershipsch: 1), Form::Sales::Pages::Staircase.new(nil, nil, self), - Form::Sales::Pages::AboutStaircase.new(nil, nil, self), + Form::Sales::Pages::AboutStaircase.new("about_staircasing_joint_purchase", nil, self, joint_purchase: true), + Form::Sales::Pages::AboutStaircase.new("about_staircasing_not_joint_purchase", nil, self, joint_purchase: false), Form::Sales::Pages::StaircaseBoughtValueCheck.new(nil, nil, self), Form::Sales::Pages::Resale.new(nil, nil, self), Form::Sales::Pages::ExchangeDate.new(nil, nil, self), Form::Sales::Pages::HandoverDate.new(nil, nil, self), Form::Sales::Pages::HandoverDateCheck.new(nil, nil, self), Form::Sales::Pages::LaNominations.new(nil, nil, self), - Form::Sales::Pages::BuyerPrevious.new(nil, nil, self), + Form::Sales::Pages::BuyerPrevious.new("buyer_previous_joint_purchase", nil, self, joint_purchase: true), + Form::Sales::Pages::BuyerPrevious.new("buyer_previous_not_joint_purchase", nil, self, joint_purchase: false), Form::Sales::Pages::PreviousBedrooms.new(nil, nil, self), Form::Sales::Pages::PreviousPropertyType.new(nil, nil, self), Form::Sales::Pages::PreviousTenure.new(nil, nil, self), Form::Sales::Pages::AboutPriceSharedOwnership.new(nil, nil, self), Form::Sales::Pages::AboutPriceValueCheck.new("about_price_shared_ownership_value_check", nil, self), Form::Sales::Pages::SharedOwnershipDepositValueCheck.new("shared_ownership_equity_value_check", nil, self), - Form::Sales::Pages::Mortgageused.new("mortgage_used_shared_ownership", nil, self), + Form::Sales::Pages::Mortgageused.new("mortgage_used_shared_ownership", nil, self, ownershipsch: 1), Form::Sales::Pages::MortgageValueCheck.new("mortgage_used_mortgage_value_check", nil, self), - Form::Sales::Pages::MortgageAmount.new("mortgage_amount_shared_ownership", nil, self), + Form::Sales::Pages::MortgageAmount.new("mortgage_amount_shared_ownership", nil, self, ownershipsch: 1), Form::Sales::Pages::SharedOwnershipDepositValueCheck.new("shared_ownership_mortgage_amount_value_check", nil, self), Form::Sales::Pages::MortgageValueCheck.new("mortgage_amount_mortgage_value_check", nil, self), - Form::Sales::Pages::MortgageLender.new("mortgage_lender_shared_ownership", nil, self), - Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_shared_ownership", nil, self), - Form::Sales::Pages::MortgageLength.new("mortgage_length_shared_ownership", nil, self), - Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_shared_ownership", nil, self), + Form::Sales::Pages::MortgageLender.new("mortgage_lender_shared_ownership", nil, self, ownershipsch: 1), + Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_shared_ownership", nil, self, ownershipsch: 1), + Form::Sales::Pages::MortgageLength.new("mortgage_length_shared_ownership", nil, self, ownershipsch: 1), + Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_shared_ownership", nil, self, ownershipsch: 1), Form::Sales::Pages::AboutDepositWithDiscount.new(nil, nil, self), - Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_shared_ownership", nil, self), + Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_shared_ownership", nil, self, ownershipsch: 1), Form::Sales::Pages::DepositValueCheck.new("deposit_value_check", nil, self), Form::Sales::Pages::SharedOwnershipDepositValueCheck.new("shared_ownership_deposit_value_check", nil, self), Form::Sales::Pages::MonthlyRent.new(nil, nil, self), - Form::Sales::Pages::LeaseholdCharges.new("leasehold_charges_shared_ownership", nil, self), + Form::Sales::Pages::LeaseholdCharges.new("leasehold_charges_shared_ownership", nil, self, ownershipsch: 1), Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_shared_ownership_value_check", nil, self), ] end diff --git a/app/models/form_handler.rb b/app/models/form_handler.rb index 4ba300552..12ae4473b 100644 --- a/app/models/form_handler.rb +++ b/app/models/form_handler.rb @@ -79,12 +79,12 @@ class FormHandler def lettings_in_crossover_period?(now: Time.zone.now) forms = lettings_forms.values - forms.count { |form| form.start_date < now && now < form.end_date } > 1 + forms.count { |form| now.between?(form.start_date, form.end_date) } > 1 end def sales_in_crossover_period?(now: Time.zone.now) forms = sales_forms.values - forms.count { |form| form.start_date < now && now < form.end_date } > 1 + forms.count { |form| now.between?(form.start_date, form.end_date) } > 1 end def use_fake_forms! diff --git a/app/models/forms/bulk_upload_lettings/prepare_your_file.rb b/app/models/forms/bulk_upload_lettings/prepare_your_file.rb index b91d1dfc5..ad256ad0f 100644 --- a/app/models/forms/bulk_upload_lettings/prepare_your_file.rb +++ b/app/models/forms/bulk_upload_lettings/prepare_your_file.rb @@ -54,6 +54,8 @@ module Forms private def in_crossover_period? + return true if FeatureToggle.force_crossover? + FormHandler.instance.lettings_in_crossover_period? end end diff --git a/app/models/forms/bulk_upload_lettings/year.rb b/app/models/forms/bulk_upload_lettings/year.rb index 80324e53e..d958f27d4 100644 --- a/app/models/forms/bulk_upload_lettings/year.rb +++ b/app/models/forms/bulk_upload_lettings/year.rb @@ -34,7 +34,10 @@ module Forms private def possible_years - [FormHandler.instance.lettings_forms["current_lettings"].start_date.year, FormHandler.instance.lettings_forms["previous_lettings"].start_date.year] + [ + FormHandler.instance.lettings_forms["next_lettings"].start_date.year, + FormHandler.instance.lettings_forms["current_lettings"].start_date.year, + ] end end end diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index 6491c100f..4524ead12 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -84,7 +84,7 @@ class LettingsLog < Log def la if location - location.location_code + location.linked_local_authorities.active(form.start_date).first&.code || location.location_code else super end @@ -195,6 +195,14 @@ class LettingsLog < Log renewal == 1 end + def starter_tenancy? + startertenancy == 1 + end + + def tenancy_type_fixed_term? + [4, 6].include? tenancy + end + def is_general_needs? # 1: General Needs needstype == 1 @@ -417,27 +425,13 @@ class LettingsLog < Log created_by&.is_dpo end - delegate :service_name, :sensitive, :registered_under_care_act, :primary_client_group, :has_other_client_group, :secondary_client_group, :owning_organisation, :managing_organisation, :support_type, :intended_stay, :created_at, prefix: "scheme", to: :scheme, allow_nil: true - delegate :scheme_type, to: :scheme, allow_nil: true - def scheme_code scheme&.id ? "S#{scheme.id}" : nil end - def scheme_owning_organisation_name - scheme_owning_organisation&.name - end - - delegate :postcode, :name, :units, :type_of_unit, :mobility_type, :startdate, prefix: "location", to: :location, allow_nil: true - delegate :location_admin_district, to: :location, allow_nil: true - - # This is not the location_code in the db, location.id is just called code in the UI - def location_code - location&.id - end - - def self.to_csv(user = nil) - Csv::LettingsLogCsvService.new(user).to_csv + def self.to_csv(user = nil, codes_only_export:) + export_type = codes_only_export ? "codes" : "labels" + Csv::LettingsLogCsvService.new(user, export_type:).to_csv end def beds_for_la_rent_range @@ -568,6 +562,8 @@ private not_required << "tshortfall" if tshortfall_unknown? not_required << "tenancylength" if tenancylength_optional? + not_required |= %w[address_line2 county postcode_full] if startdate && startdate.year >= 2023 + not_required end diff --git a/app/models/local_authority.rb b/app/models/local_authority.rb new file mode 100644 index 000000000..fe11adf04 --- /dev/null +++ b/app/models/local_authority.rb @@ -0,0 +1,7 @@ +class LocalAuthority < ApplicationRecord + has_many :local_authority_links, dependent: :destroy + has_many :linked_local_authorities, class_name: "LocalAuthority", through: :local_authority_links + + scope :active, ->(date) { where("start_date <= ? AND (end_date IS NULL OR end_date >= ?)", date, date) } + scope :england, -> { where("code LIKE ?", "E%") } +end diff --git a/app/models/local_authority_link.rb b/app/models/local_authority_link.rb new file mode 100644 index 000000000..dcd339e76 --- /dev/null +++ b/app/models/local_authority_link.rb @@ -0,0 +1,4 @@ +class LocalAuthorityLink < ApplicationRecord + belongs_to :local_authority, class_name: "LocalAuthority" + belongs_to :linked_local_authority, class_name: "LocalAuthority" +end diff --git a/app/models/location.rb b/app/models/location.rb index 51943df3c..b96517e17 100644 --- a/app/models/location.rb +++ b/app/models/location.rb @@ -14,7 +14,7 @@ class Location < ApplicationRecord has_paper_trail - before_save :lookup_postcode!, if: :postcode_changed? + before_validation :lookup_postcode!, if: :postcode_changed? auto_strip_attributes :name @@ -24,326 +24,12 @@ class Location < ApplicationRecord scope :started, -> { where("startdate <= ?", Time.zone.today).or(where(startdate: nil)) } scope :active, -> { where(confirmed: true).and(started) } - LOCAL_AUTHORITIES = { - "E07000223": "Adur", - "E07000026": "Allerdale", - "E07000032": "Amber Valley", - "E07000224": "Arun", - "E07000170": "Ashfield", - "E07000105": "Ashford", - "E07000200": "Babergh", - "E09000002": "Barking and Dagenham", - "E09000003": "Barnet", - "E08000016": "Barnsley", - "E07000027": "Barrow-in-Furness", - "E07000066": "Basildon", - "E07000084": "Basingstoke and Deane", - "E07000171": "Bassetlaw", - "E06000022": "Bath and North East Somerset", - "E06000055": "Bedford", - "E09000004": "Bexley", - "E08000025": "Birmingham", - "E07000129": "Blaby", - "E06000008": "Blackburn with Darwen", - "E06000009": "Blackpool", - "E07000033": "Bolsover", - "E08000001": "Bolton", - "E07000136": "Boston", - "E06000058": "Bournemouth, Christchurch and Poole", - "E06000036": "Bracknell Forest", - "E08000032": "Bradford", - "E07000067": "Braintree", - "E07000143": "Breckland", - "E09000005": "Brent", - "E07000068": "Brentwood", - "E06000043": "Brighton and Hove", - "E06000023": "Bristol, City of", - "E07000144": "Broadland", - "E09000006": "Bromley", - "E07000234": "Bromsgrove", - "E07000095": "Broxbourne", - "E07000172": "Broxtowe", - "E06000060": "Buckinghamshire", - "E07000117": "Burnley", - "E08000002": "Bury", - "E08000033": "Calderdale", - "E07000008": "Cambridge", - "E09000007": "Camden", - "E07000192": "Cannock Chase", - "E07000106": "Canterbury", - "E07000028": "Carlisle", - "E07000069": "Castle Point", - "E06000056": "Central Bedfordshire", - "E07000130": "Charnwood", - "E07000070": "Chelmsford", - "E07000078": "Cheltenham", - "E07000177": "Cherwell", - "E06000049": "Cheshire East", - "E06000050": "Cheshire West and Chester", - "E07000034": "Chesterfield", - "E07000225": "Chichester", - "E07000118": "Chorley", - "E09000001": "City of London", - "E07000071": "Colchester", - "E07000029": "Copeland", - "E07000150": "Corby", - "E06000052": "Cornwall", - "E07000079": "Cotswold", - "E06000047": "County Durham", - "E08000026": "Coventry", - "E07000163": "Craven", - "E07000226": "Crawley", - "E09000008": "Croydon", - "E07000096": "Dacorum", - "E06000005": "Darlington", - "E07000107": "Dartford", - "E07000151": "Daventry", - "E06000015": "Derby", - "E07000035": "Derbyshire Dales", - "E08000017": "Doncaster", - "E06000059": "Dorset", - "E07000108": "Dover", - "E08000027": "Dudley", - "E09000009": "Ealing", - "E07000009": "East Cambridgeshire", - "E07000040": "East Devon", - "E07000085": "East Hampshire", - "E07000242": "East Hertfordshire", - "E07000137": "East Lindsey", - "E07000152": "East Northamptonshire", - "E06000011": "East Riding of Yorkshire", - "E07000193": "East Staffordshire", - "E07000244": "East Suffolk", - "E07000061": "Eastbourne", - "E07000086": "Eastleigh", - "E07000030": "Eden", - "E07000207": "Elmbridge", - "E09000010": "Enfield", - "E07000072": "Epping Forest", - "E07000208": "Epsom and Ewell", - "E07000036": "Erewash", - "E07000041": "Exeter", - "E07000087": "Fareham", - "E07000010": "Fenland", - "E07000112": "Folkestone and Hythe", - "E07000080": "Forest of Dean", - "E07000119": "Fylde", - "E08000037": "Gateshead", - "E07000173": "Gedling", - "E07000081": "Gloucester", - "E07000088": "Gosport", - "E07000109": "Gravesham", - "E07000145": "Great Yarmouth", - "E09000011": "Greenwich", - "E07000209": "Guildford", - "W06000002": "Gwynedd", - "E09000012": "Hackney", - "E06000006": "Halton", - "E07000164": "Hambleton", - "E09000013": "Hammersmith and Fulham", - "E07000131": "Harborough", - "E09000014": "Haringey", - "E07000073": "Harlow", - "E07000165": "Harrogate", - "E09000015": "Harrow", - "E07000089": "Hart", - "E06000001": "Hartlepool", - "E07000062": "Hastings", - "E07000090": "Havant", - "E09000016": "Havering", - "E06000019": "Herefordshire, County of", - "E07000098": "Hertsmere", - "E07000037": "High Peak", - "S12000017": "Highland", - "E09000017": "Hillingdon", - "E07000132": "Hinckley and Bosworth", - "E07000227": "Horsham", - "E09000018": "Hounslow", - "E07000011": "Huntingdonshire", - "E07000120": "Hyndburn", - "E07000202": "Ipswich", - "E06000046": "Isle of Wight", - "E06000053": "Isles of Scilly", - "E09000019": "Islington", - "E09000020": "Kensington and Chelsea", - "E07000153": "Kettering", - "E07000146": "King’s Lynn and West Norfolk", - "E06000010": "Kingston upon Hull, City of", - "E09000021": "Kingston upon Thames", - "E08000034": "Kirklees", - "E08000011": "Knowsley", - "E09000022": "Lambeth", - "E07000121": "Lancaster", - "E08000035": "Leeds", - "E06000016": "Leicester", - "E07000063": "Lewes", - "E09000023": "Lewisham", - "E07000194": "Lichfield", - "E07000138": "Lincoln", - "E08000012": "Liverpool", - "E06000032": "Luton", - "E07000110": "Maidstone", - "E07000074": "Maldon", - "E07000235": "Malvern Hills", - "E08000003": "Manchester", - "E07000174": "Mansfield", - "E06000035": "Medway", - "E07000133": "Melton", - "E07000187": "Mendip", - "E09000024": "Merton", - "E07000042": "Mid Devon", - "E07000203": "Mid Suffolk", - "E07000228": "Mid Sussex", - "E06000002": "Middlesbrough", - "E06000042": "Milton Keynes", - "E07000210": "Mole Valley", - "E07000091": "New Forest", - "E07000175": "Newark and Sherwood", - "E08000021": "Newcastle upon Tyne", - "E07000195": "Newcastle-under-Lyme", - "E09000025": "Newham", - "E07000043": "North Devon", - "E07000038": "North East Derbyshire", - "E06000012": "North East Lincolnshire", - "E07000099": "North Hertfordshire", - "E07000139": "North Kesteven", - "E06000013": "North Lincolnshire", - "E07000147": "North Norfolk", - "E06000024": "North Somerset", - "E08000022": "North Tyneside", - "E07000218": "North Warwickshire", - "E07000134": "North West Leicestershire", - "E07000154": "Northampton", - "E06000057": "Northumberland", - "E07000148": "Norwich", - "E06000018": "Nottingham", - "E07000219": "Nuneaton and Bedworth", - "E07000135": "Oadby and Wigston", - "E08000004": "Oldham", - "E07000178": "Oxford", - "E07000122": "Pendle", - "E06000031": "Peterborough", - "E06000026": "Plymouth", - "E06000044": "Portsmouth", - "E07000123": "Preston", - "E06000038": "Reading", - "E09000026": "Redbridge", - "E06000003": "Redcar and Cleveland", - "E07000236": "Redditch", - "E07000211": "Reigate and Banstead", - "E07000124": "Ribble Valley", - "E09000027": "Richmond upon Thames", - "E07000166": "Richmondshire", - "E08000005": "Rochdale", - "E07000075": "Rochford", - "E07000125": "Rossendale", - "E07000064": "Rother", - "E08000018": "Rotherham", - "E07000220": "Rugby", - "E07000212": "Runnymede", - "E07000176": "Rushcliffe", - "E07000092": "Rushmoor", - "E06000017": "Rutland", - "E07000167": "Ryedale", - "E08000006": "Salford", - "E08000028": "Sandwell", - "E07000168": "Scarborough", - "E07000188": "Sedgemoor", - "E08000014": "Sefton", - "E07000169": "Selby", - "E07000111": "Sevenoaks", - "E08000019": "Sheffield", - "E06000051": "Shropshire", - "E06000039": "Slough", - "E08000029": "Solihull", - "E07000246": "Somerset West and Taunton", - "E07000012": "South Cambridgeshire", - "E07000039": "South Derbyshire", - "E06000025": "South Gloucestershire", - "E07000044": "South Hams", - "E07000140": "South Holland", - "E07000141": "South Kesteven", - "E07000031": "South Lakeland", - "E07000149": "South Norfolk", - "E07000155": "South Northamptonshire", - "E07000179": "South Oxfordshire", - "E07000126": "South Ribble", - "E07000189": "South Somerset", - "E07000196": "South Staffordshire", - "E08000023": "South Tyneside", - "E06000045": "Southampton", - "E06000033": "Southend-on-Sea", - "E09000028": "Southwark", - "E07000213": "Spelthorne", - "E07000240": "St Albans", - "E08000013": "St. Helens", - "E07000197": "Stafford", - "E07000198": "Staffordshire Moorlands", - "E07000243": "Stevenage", - "E08000007": "Stockport", - "E06000004": "Stockton-on-Tees", - "E06000021": "Stoke-on-Trent", - "E07000221": "Stratford-on-Avon", - "E07000082": "Stroud", - "E08000024": "Sunderland", - "E07000214": "Surrey Heath", - "E09000029": "Sutton", - "E07000113": "Swale", - "E06000030": "Swindon", - "E08000008": "Tameside", - "E07000199": "Tamworth", - "E07000215": "Tandridge", - "E07000045": "Teignbridge", - "E06000020": "Telford and Wrekin", - "E07000076": "Tendring", - "E07000093": "Test Valley", - "E07000083": "Tewkesbury", - "E07000114": "Thanet", - "E07000102": "Three Rivers", - "E06000034": "Thurrock", - "E07000115": "Tonbridge and Malling", - "E06000027": "Torbay", - "E07000046": "Torridge", - "E09000030": "Tower Hamlets", - "E08000009": "Trafford", - "E07000116": "Tunbridge Wells", - "E07000077": "Uttlesford", - "E07000180": "Vale of White Horse", - "E08000036": "Wakefield", - "E08000030": "Walsall", - "E09000031": "Waltham Forest", - "E09000032": "Wandsworth", - "E06000007": "Warrington", - "E07000222": "Warwick", - "E07000103": "Watford", - "E07000216": "Waverley", - "E07000065": "Wealden", - "E07000156": "Wellingborough", - "E07000241": "Welwyn Hatfield", - "E06000037": "West Berkshire", - "E07000047": "West Devon", - "E07000127": "West Lancashire", - "E07000142": "West Lindsey", - "E07000181": "West Oxfordshire", - "E07000245": "West Suffolk", - "E09000033": "Westminster", - "E08000010": "Wigan", - "E06000054": "Wiltshire", - "E07000094": "Winchester", - "E06000040": "Windsor and Maidenhead", - "E08000015": "Wirral", - "E07000217": "Woking", - "E06000041": "Wokingham", - "E08000031": "Wolverhampton", - "E07000237": "Worcester", - "E07000229": "Worthing", - "E07000238": "Wychavon", - "E07000128": "Wyre", - "E07000239": "Wyre Forest", - "E06000014": "York", - }.freeze + LOCAL_AUTHORITIES = LocalAuthority.all.map { |la| [la.name, la.code] }.to_h enum local_authorities: LOCAL_AUTHORITIES + def self.local_authorities_for_current_year + LocalAuthority.all.active(Time.zone.today).england.map { |la| [la.code, la.name] }.to_h + end MOBILITY_TYPE = { "Wheelchair-user standard": "W", @@ -444,6 +130,13 @@ class Location < ApplicationRecord self.confirmed = [postcode, location_admin_district, location_code, units, type_of_unit, mobility_type].all?(&:present?) end + def linked_local_authorities + la = LocalAuthority.find_by(code: location_code) + return LocalAuthority.none unless la + + LocalAuthority.where(id: [la.id] + la.linked_local_authority_ids) + end + private PIO = PostcodeService.new diff --git a/app/models/log.rb b/app/models/log.rb index f6f5f4173..34c920bd5 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -31,6 +31,24 @@ class Log < ApplicationRecord } scope :created_by, ->(user) { where(created_by: user) } + def process_uprn_change! + if uprn.present? + service = UprnClient.new(uprn) + service.call + + return errors.add(:uprn, service.error) if service.error.present? + + presenter = UprnDataPresenter.new(service.result) + + self.uprn_confirmed = nil + self.address_line1 = presenter.address_line1 + self.address_line2 = presenter.address_line2 + self.town_or_city = presenter.town_or_city + self.postcode_full = presenter.postcode + process_postcode_changes! + end + end + def collection_start_year return @start_year if @start_year @@ -81,6 +99,12 @@ class Log < ApplicationRecord end end + (2..8).each do |person_num| + define_method("person_#{person_num}_child_relation?") do + send("relat#{person_num}") == "C" + end + end + private def plural_gender_for_person(person_num) @@ -129,9 +153,34 @@ private process_postcode(ppostcode_full, "ppcodenk", "is_previous_la_inferred", "prevloc") end + LA_CHANGES = { + "E07000027" => "E06000064", # Barrow-in-Furness => Westmorland and Furness + "E07000030" => "E06000064", # Eden => Westmorland and Furness + "E07000031" => "E06000064", # South Lakeland => Westmorland and Furness + "E07000026" => "E06000063", # Allerdale => Cumberland + "E07000028" => "E06000063", # Carlisle => Cumberland + "E07000029" => "E06000063", # Copeland => Cumberland + "E07000163" => "E06000065", # Craven => North Yorkshire + "E07000164" => "E06000065", # Hambleton => North Yorkshire + "E07000165" => "E06000065", # Harrogate => North Yorkshire + "E07000166" => "E06000065", # Richmondshire => North Yorkshire + "E07000167" => "E06000065", # Ryedale => North Yorkshire + "E07000168" => "E06000065", # Scarborough => North Yorkshire + "E07000169" => "E06000065", # Selby => North Yorkshire + "E07000187" => "E06000066", # Mendip => Somerset + "E07000188" => "E06000066", # Sedgemoor => Somerset + "E07000246" => "E06000066", # Somerset West and Taunton => Somerset + "E07000189" => "E06000066", # South Somerset => Somerset + }.freeze + def get_inferred_la(postcode) result = PIO.lookup(postcode) - result[:location_code] if result + location_code = result[:location_code] if result + if LA_CHANGES.key?(location_code) && form.start_date.year >= 2023 + LA_CHANGES[location_code] + elsif !(LA_CHANGES.value?(location_code) && form.start_date.year < 2023) + location_code + end end def upcase_and_remove_whitespace(string) diff --git a/app/models/organisation_relationship.rb b/app/models/organisation_relationship.rb index 5a4f86938..b763c03fc 100644 --- a/app/models/organisation_relationship.rb +++ b/app/models/organisation_relationship.rb @@ -7,6 +7,8 @@ class OrganisationRelationship < ApplicationRecord validates :child_organisation_id, uniqueness: { scope: :parent_organisation_id, message: I18n.t("validations.organisation.managing_agent.already_added") } validate :validate_stock_owner_owns_stock, on: :stock_owner + has_paper_trail + private def validate_stock_owner_owns_stock diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index 629215386..7385d8b43 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -31,6 +31,7 @@ class SalesLog < Log before_validation :reset_location_fields!, unless: :postcode_known? before_validation :reset_previous_location_fields!, unless: :previous_postcode_known? before_validation :set_derived_fields! + after_validation :process_uprn_change!, if: :should_process_uprn_change? scope :filter_by_year, ->(year) { where(saledate: Time.zone.local(year.to_i, 4, 1)...Time.zone.local(year.to_i + 1, 4, 1)) } scope :filter_by_purchaser_code, ->(purchid) { where("purchid ILIKE ?", "%#{purchid}%") } @@ -41,7 +42,7 @@ class SalesLog < Log } scope :filter_by_organisation, ->(org, _user = nil) { where(owning_organisation: org) } - OPTIONAL_FIELDS = %w[saledate_check purchid monthly_charges_value_check old_persons_shared_ownership_value_check].freeze + OPTIONAL_FIELDS = %w[saledate_check purchid monthly_charges_value_check old_persons_shared_ownership_value_check mortgagelender othtype].freeze RETIREMENT_AGES = { "M" => 65, "F" => 60, "X" => 65 }.freeze def lettings? @@ -77,6 +78,10 @@ class SalesLog < Log def dynamically_not_required not_required = [] not_required << "proplen" if proplen_optional? + not_required << "mortlen" if mortlen_optional? + not_required << "frombeds" if frombeds_optional? + + not_required |= %w[address_line2 county postcode_full] if saledate && saledate.year >= 2023 not_required end @@ -87,6 +92,18 @@ class SalesLog < Log collection_start_year < 2023 end + def mortlen_optional? + return false unless collection_start_year + + collection_start_year < 2023 + end + + def frombeds_optional? + return false unless collection_start_year + + collection_start_year < 2023 + end + def not_started? status == "not_started" end @@ -151,6 +168,14 @@ class SalesLog < Log inc1mort == 1 end + def buyer_two_will_live_in_property? + buy2livein == 1 + end + + def buyer_two_not_already_living_in_property? + buy2living == 2 + end + def income2_used_for_mortgage? inc2mort == 1 end @@ -250,6 +275,10 @@ class SalesLog < Log jointpur == 2 end + def buyer_not_interviewed? + noint == 1 + end + def old_persons_shared_ownership? type == 24 end @@ -262,6 +291,10 @@ class SalesLog < Log ownershipsch == 1 end + def company_buyer? + companybuy == 1 + end + def buyers_age_for_old_persons_shared_ownership_invalid? return unless old_persons_shared_ownership? @@ -293,4 +326,8 @@ class SalesLog < Log field_value = public_send(field_name) format_as_currency(field_value) end + + def should_process_uprn_change? + uprn_changed? && saledate && saledate.year >= 2023 + end end diff --git a/app/models/validations/date_validations.rb b/app/models/validations/date_validations.rb index 66e472ba0..ee7789171 100644 --- a/app/models/validations/date_validations.rb +++ b/app/models/validations/date_validations.rb @@ -33,16 +33,6 @@ module Validations::DateValidations def validate_startdate(record) return unless record.startdate && date_valid?("startdate", record) - created_at = record.created_at || Time.zone.now - - if created_at > first_collection_end_date && record.startdate < second_collection_start_date - record.errors.add :startdate, I18n.t("validations.date.outside_collection_window") - end - - if (record.startdate < first_collection_start_date || record.startdate > second_collection_end_date) && FeatureToggle.startdate_collection_window_validation_enabled? - record.errors.add :startdate, I18n.t("validations.date.outside_collection_window") - end - if FeatureToggle.startdate_two_week_validation_enabled? && record.startdate > Time.zone.today + 14 record.errors.add :startdate, I18n.t("validations.setup.startdate.later_than_14_days_after") end @@ -68,22 +58,6 @@ module Validations::DateValidations private - def first_collection_start_date - @first_collection_start_date ||= FormHandler.instance.lettings_forms["previous_lettings"].start_date - end - - def first_collection_end_date - @first_collection_end_date ||= FormHandler.instance.lettings_forms["previous_lettings"].end_date - end - - def second_collection_start_date - @second_collection_start_date ||= FormHandler.instance.lettings_forms["current_lettings"].start_date - end - - def second_collection_end_date - @second_collection_end_date ||= FormHandler.instance.lettings_forms["current_lettings"].end_date - end - def is_rsnvac_first_let?(record) [15, 16, 17].include?(record["rsnvac"]) end diff --git a/app/models/validations/property_validations.rb b/app/models/validations/property_validations.rb index 8b0988dd9..2e53b8385 100644 --- a/app/models/validations/property_validations.rb +++ b/app/models/validations/property_validations.rb @@ -75,4 +75,12 @@ module Validations::PropertyValidations record.errors.add :beds, I18n.t("validations.property.beds.over_max") end end + + def validate_uprn(record) + return unless record.uprn + + return if record.uprn.match?(/^[0-9]{1,12}$/) + + record.errors.add :uprn, I18n.t("validations.property.uprn.invalid") + end end diff --git a/app/models/validations/sales/financial_validations.rb b/app/models/validations/sales/financial_validations.rb index 21f3743ca..faf436afa 100644 --- a/app/models/validations/sales/financial_validations.rb +++ b/app/models/validations/sales/financial_validations.rb @@ -9,7 +9,7 @@ module Validations::Sales::FinancialValidations if record.london_property? && record.income1 > 90_000 relevant_fields.each { |field| record.errors.add field, I18n.t("validations.financial.income.over_hard_max_for_london") } elsif record.property_not_in_london? && record.income1 > 80_000 - relevant_fields.each { |field| record.errors.add field, I18n.t("validations.financial.income.over_hard_max_for_outside_london") } + relevant_fields.each { |field| record.errors.add field, :over_hard_max_for_outside_london, message: I18n.t("validations.financial.income.over_hard_max_for_outside_london") } end end @@ -52,10 +52,25 @@ module Validations::Sales::FinancialValidations end end + def validate_percentage_bought_at_least_threshold(record) + return unless record.stairbought && record.type + + threshold = if [2, 16, 18, 24].include? record.type + 10 + else + 1 + end + + if threshold && record.stairbought < threshold + record.errors.add :stairbought, I18n.t("validations.financial.staircasing.percentage_bought_must_be_at_least_threshold", threshold:) + record.errors.add :type, I18n.t("validations.setup.type.percentage_bought_must_be_at_least_threshold", threshold:) + end + end + def validate_child_income(record) return unless record.income2 && record.ecstat2 - if record.income2.positive? && is_economic_status_child?(record.ecstat2) + if record.income2.positive? && is_economic_status_child?(record.ecstat2) && record.form.start_date.year >= 2023 record.errors.add :ecstat2, I18n.t("validations.financial.income.child_has_income") record.errors.add :income2, I18n.t("validations.financial.income.child_has_income") end @@ -70,6 +85,22 @@ module Validations::Sales::FinancialValidations end end + def validate_equity_in_range_for_year_and_type(record) + return unless record.type && record.equity && record.collection_start_year + + ranges = EQUITY_RANGES_BY_YEAR.fetch(record.collection_start_year, DEFAULT_EQUITY_RANGES) + + return unless (range = ranges[record.type]) + + if record.equity < range.min + record.errors.add :type, I18n.t("validations.financial.equity.under_min", min_equity: range.min) + record.errors.add :equity, I18n.t("validations.financial.equity.under_min", min_equity: range.min) + elsif record.equity > range.max + record.errors.add :type, I18n.t("validations.financial.equity.over_max", max_equity: range.max) + record.errors.add :equity, I18n.t("validations.financial.equity.over_max", max_equity: range.max) + end + end + private def is_relationship_child?(relationship) @@ -79,4 +110,25 @@ private def is_economic_status_child?(economic_status) economic_status == 9 end + + EQUITY_RANGES_BY_YEAR = { + 2022 => { + 2 => 25..75, + 30 => 10..75, + 18 => 25..75, + 16 => 10..75, + 24 => 25..75, + 31 => 0..75, + }, + }.freeze + + DEFAULT_EQUITY_RANGES = { + 2 => 10..75, + 30 => 25..75, + 18 => 25..75, + 16 => 10..75, + 24 => 25..75, + 31 => 0..75, + 32 => 0..75, + }.freeze end diff --git a/app/models/validations/sales/household_validations.rb b/app/models/validations/sales/household_validations.rb index ec73b4abb..e53b7154e 100644 --- a/app/models/validations/sales/household_validations.rb +++ b/app/models/validations/sales/household_validations.rb @@ -45,12 +45,6 @@ private student = person_is_fulltime_student?(economic_status) child = person_is_child?(relationship) - if age_between_16_19 && student && !child - record.errors.add "age#{person_num}", I18n.t("validations.household.age.student_16_19.cannot_be_16_19.student_not_child") - record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.student_16_19.cannot_be_student.16_19_not_child") - record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.student_16_19.must_be_child") - end - if age_between_16_19 && !student && child record.errors.add "age#{person_num}", I18n.t("validations.household.age.student_16_19.cannot_be_16_19.child_not_student") record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.student_16_19.must_be_student") diff --git a/app/models/validations/sales/property_validations.rb b/app/models/validations/sales/property_validations.rb index 83f86ec8f..b1bdb5b62 100644 --- a/app/models/validations/sales/property_validations.rb +++ b/app/models/validations/sales/property_validations.rb @@ -16,4 +16,12 @@ module Validations::Sales::PropertyValidations record.errors.add :beds, I18n.t("validations.property.beds.bedsits_have_max_one_bedroom") end end + + def validate_uprn(record) + return unless record.uprn + + return if record.uprn.match?(/^[0-9]{1,12}$/) + + record.errors.add :uprn, I18n.t("validations.property.uprn.invalid") + end end diff --git a/app/models/validations/sales/sale_information_validations.rb b/app/models/validations/sales/sale_information_validations.rb index a1deb94f5..ae3bbfe8f 100644 --- a/app/models/validations/sales/sale_information_validations.rb +++ b/app/models/validations/sales/sale_information_validations.rb @@ -30,7 +30,7 @@ module Validations::Sales::SaleInformationValidations end if record.saledate - record.exdate >= 1.year - record.errors.add :exdate, I18n.t("validations.sale_information.exdate.must_be_less_than_1_year_from_saledate") + record.errors.add :exdate, :over_a_year_from_saledate, message: I18n.t("validations.sale_information.exdate.must_be_less_than_1_year_from_saledate") record.errors.add :saledate, I18n.t("validations.sale_information.saledate.must_be_less_than_1_year_from_exdate") end end @@ -46,7 +46,7 @@ module Validations::Sales::SaleInformationValidations def validate_discounted_ownership_value(record) return unless record.value && record.deposit && record.ownershipsch - return unless record.mortgage || record.mortgageused == 2 || record.mortgageused == 3 + return unless record.mortgage || record.mortgageused == 2 return unless record.discount || record.grant || record.type == 29 discount_amount = record.discount ? record.value * record.discount / 100 : 0 diff --git a/app/models/validations/sales/setup_validations.rb b/app/models/validations/sales/setup_validations.rb index e7090aabf..e76993907 100644 --- a/app/models/validations/sales/setup_validations.rb +++ b/app/models/validations/sales/setup_validations.rb @@ -3,10 +3,10 @@ module Validations::Sales::SetupValidations include CollectionTimeHelper def validate_saledate(record) - return unless record.saledate && date_valid?("saledate", record) + return unless record.saledate && date_valid?("saledate", record) && FeatureToggle.saledate_collection_window_validation_enabled? - unless record.saledate.between?(active_collection_start_date, current_collection_end_date) || !FeatureToggle.saledate_collection_window_validation_enabled? - record.errors.add :saledate, validation_error_message + unless record.saledate.between?(active_collection_start_date, current_collection_end_date) + record.errors.add :saledate, saledate_validation_error_message end end @@ -20,12 +20,12 @@ private end end - def validation_error_message + def saledate_validation_error_message current_end_year_long = current_collection_end_date.strftime("#{current_collection_end_date.day.ordinalize} %B %Y") if FormHandler.instance.sales_in_crossover_period? I18n.t( - "validations.setup.saledate.previous_and_current_financial_year", + "validations.setup.saledate.previous_and_current_collection_year", previous_start_year_short: previous_collection_start_date.strftime("%y"), previous_end_year_short: previous_collection_end_date.strftime("%y"), previous_start_year_long: previous_collection_start_date.strftime("#{previous_collection_start_date.day.ordinalize} %B %Y"), @@ -34,7 +34,7 @@ private ) else I18n.t( - "validations.setup.saledate.current_financial_year", + "validations.setup.saledate.current_collection_year", current_start_year_short: current_collection_start_date.strftime("%y"), current_end_year_short: current_collection_end_date.strftime("%y"), current_start_year_long: current_collection_start_date.strftime("#{current_collection_start_date.day.ordinalize} %B %Y"), diff --git a/app/models/validations/sales/soft_validations.rb b/app/models/validations/sales/soft_validations.rb index a44e0a293..5819b0fe1 100644 --- a/app/models/validations/sales/soft_validations.rb +++ b/app/models/validations/sales/soft_validations.rb @@ -103,6 +103,17 @@ module Validations::Sales::SoftValidations mscharge > soft_max end + (2..6).each do |person_num| + define_method("person_#{person_num}_student_not_child?") do + relat = send("relat#{person_num}") + ecstat = send("ecstat#{person_num}") + age = send("age#{person_num}") + return unless age && ecstat && relat + + age.between?(16, 19) && ecstat == 7 && relat != "C" + end + end + private def sale_range diff --git a/app/models/validations/setup_validations.rb b/app/models/validations/setup_validations.rb index 93105f9ea..0865ebae6 100644 --- a/app/models/validations/setup_validations.rb +++ b/app/models/validations/setup_validations.rb @@ -1,5 +1,14 @@ module Validations::SetupValidations include Validations::SharedValidations + include CollectionTimeHelper + + def validate_startdate_setup(record) + return unless record.startdate && date_valid?("startdate", record) && FeatureToggle.startdate_collection_window_validation_enabled? + + unless record.startdate.between?(active_collection_start_date, current_collection_end_date) + record.errors.add :startdate, startdate_validation_error_message + end + end def validate_irproduct_other(record) if intermediate_product_rent_type?(record) && record.irproduct_other.blank? @@ -27,6 +36,37 @@ module Validations::SetupValidations private + def active_collection_start_date + if FormHandler.instance.lettings_in_crossover_period? + previous_collection_start_date + else + current_collection_start_date + end + end + + def startdate_validation_error_message + current_end_year_long = current_collection_end_date.strftime("#{current_collection_end_date.day.ordinalize} %B %Y") + + if FormHandler.instance.lettings_in_crossover_period? + I18n.t( + "validations.setup.startdate.previous_and_current_collection_year", + previous_start_year_short: previous_collection_start_date.strftime("%y"), + previous_end_year_short: previous_collection_end_date.strftime("%y"), + previous_start_year_long: previous_collection_start_date.strftime("#{previous_collection_start_date.day.ordinalize} %B %Y"), + current_end_year_short: current_collection_end_date.strftime("%y"), + current_end_year_long:, + ) + else + I18n.t( + "validations.setup.startdate.current_collection_year", + current_start_year_short: current_collection_start_date.strftime("%y"), + current_end_year_short: current_collection_end_date.strftime("%y"), + current_start_year_long: current_collection_start_date.strftime("#{current_collection_start_date.day.ordinalize} %B %Y"), + current_end_year_long:, + ) + end + end + def intermediate_product_rent_type?(record) record.rent_type == 5 end diff --git a/app/services/bulk_upload/lettings/log_creator.rb b/app/services/bulk_upload/lettings/log_creator.rb index 625d53f43..089639d4f 100644 --- a/app/services/bulk_upload/lettings/log_creator.rb +++ b/app/services/bulk_upload/lettings/log_creator.rb @@ -26,7 +26,14 @@ class BulkUpload::Lettings::LogCreator private def csv_parser - @csv_parser ||= BulkUpload::Lettings::CsvParser.new(path:) + @csv_parser ||= case bulk_upload.year + when 2022 + BulkUpload::Lettings::Year2022::CsvParser.new(path:) + when 2023 + BulkUpload::Lettings::Year2023::CsvParser.new(path:) + else + raise "csv parser not found" + end end def row_offset diff --git a/app/services/bulk_upload/lettings/validator.rb b/app/services/bulk_upload/lettings/validator.rb index 779f0315b..e60435f75 100644 --- a/app/services/bulk_upload/lettings/validator.rb +++ b/app/services/bulk_upload/lettings/validator.rb @@ -6,146 +6,10 @@ class BulkUpload::Lettings::Validator include ActiveModel::Validations - QUESTIONS = { - field_1: "What is the letting type?", - field_2: "This question has been removed", - field_3: "This question has been removed", - field_4: "Management group code", - field_5: "Scheme code", - field_6: "This question has been removed", - field_7: "What is the tenant code?", - field_8: "Is this a starter tenancy?", - field_9: "What is the tenancy type?", - field_10: "If 'Other', what is the tenancy type?", - field_11: "What is the length of the fixed-term tenancy to the nearest year?", - field_12: "Age of Person 1", - field_13: "Age of Person 2", - field_14: "Age of Person 3", - field_15: "Age of Person 4", - field_16: "Age of Person 5", - field_17: "Age of Person 6", - field_18: "Age of Person 7", - field_19: "Age of Person 8", - field_20: "Gender identity of Person 1", - field_21: "Gender identity of Person 2", - field_22: "Gender identity of Person 3", - field_23: "Gender identity of Person 4", - field_24: "Gender identity of Person 5", - field_25: "Gender identity of Person 6", - field_26: "Gender identity of Person 7", - field_27: "Gender identity of Person 8", - field_28: "Relationship to Person 1 for Person 2", - field_29: "Relationship to Person 1 for Person 3", - field_30: "Relationship to Person 1 for Person 4", - field_31: "Relationship to Person 1 for Person 5", - field_32: "Relationship to Person 1 for Person 6", - field_33: "Relationship to Person 1 for Person 7", - field_34: "Relationship to Person 1 for Person 8", - field_35: "Working situation of Person 1", - field_36: "Working situation of Person 2", - field_37: "Working situation of Person 3", - field_38: "Working situation of Person 4", - field_39: "Working situation of Person 5", - field_40: "Working situation of Person 6", - field_41: "Working situation of Person 7", - field_42: "Working situation of Person 8", - field_43: "What is the lead tenant's ethnic group?", - field_44: "What is the lead tenant's nationality?", - field_45: "Does anybody in the household have links to the UK armed forces?", - field_46: "Was the person seriously injured or ill as a result of serving in the UK armed forces?", - field_47: "Is anybody in the household pregnant?", - field_48: "Is the tenant likely to be receiving benefits related to housing?", - field_49: "How much of the household's income is from Universal Credit, state pensions or benefits?", - field_50: "How much income does the household have in total?", - field_51: "Do you know the household's income?", - field_52: "What is the tenant's main reason for the household leaving their last settled home?", - field_53: "If 'Other', what was the main reason for leaving their last settled home?", - field_54: "This question has been removed", - field_55: "Does anybody in the household have any disabled access needs?", - field_56: "Does anybody in the household have any disabled access needs?", - field_57: "Does anybody in the household have any disabled access needs?", - field_58: "Does anybody in the household have any disabled access needs?", - field_59: "Does anybody in the household have any disabled access needs?", - field_60: "Does anybody in the household have any disabled access needs?", - field_61: "Where was the household immediately before this letting?", - field_62: "What is the local authority of the household's last settled home?", - field_63: "Part 1 of postcode of last settled home", - field_64: "Part 2 of postcode of last settled home", - field_65: "Do you know the postcode of last settled home?", - field_66: "How long has the household continuously lived in the local authority area of the new letting?", - field_67: "How long has the household been on the waiting list for the new letting?", - field_68: "Was the tenant homeless directly before this tenancy?", - field_69: "Was the household given 'reasonable preference' by the local authority?", - field_70: "Reasonable preference. They were homeless or about to lose their home (within 56 days)", - field_71: "Reasonable preference. They were living in insanitary, overcrowded or unsatisfactory housing", - field_72: "Reasonable preference. They needed to move on medical and welfare grounds (including a disability)", - field_73: "Reasonable preference. They needed to move to avoid hardship to themselves or others", - field_74: "Reasonable preference. Don't know", - field_75: "Was the letting made under any of the following allocations systems?", - field_76: "Was the letting made under any of the following allocations systems?", - field_77: "Was the letting made under any of the following allocations systems?", - field_78: "What was the source of referral for this letting?", - field_79: "How often does the household pay rent and other charges?", - field_80: "What is the basic rent?", - field_81: "What is the service charge?", - field_82: "What is the personal service charge?", - field_83: "What is the support charge?", - field_84: "Total Charge", - field_85: "If this is a care home, how much does the household pay every [time period]?", - field_86: "Does the household pay rent or other charges for the accommodation?", - field_87: "After the household has received any housing-related benefits, will they still need to pay basic rent and other charges?", - field_88: "What do you expect the outstanding amount to be?", - field_89: "What is the void or renewal date?", - field_90: "What is the void or renewal date?", - field_91: "What is the void or renewal date?", - field_92: "What date were major repairs completed on?", - field_93: "What date were major repairs completed on?", - field_94: "What date were major repairs completed on?", - field_95: "This question has been removed", - field_96: "What date did the tenancy start?", - field_97: "What date did the tenancy start?", - field_98: "What date did the tenancy start?", - field_99: "Since becoming available, how many times has the property been previously offered?", - field_100: "What is the property reference?", - field_101: "How many bedrooms does the property have?", - field_102: "What type of unit is the property?", - field_103: "Which type of building is the property?", - field_104: "Is the property built or adapted to wheelchair-user standards?", - field_105: "What type was the property most recently let as?", - field_106: "What is the reason for the property being vacant?", - field_107: "What is the local authority of the property?", - field_108: "Part 1 of postcode of the property", - field_109: "Part 2 of postcode of the property", - field_110: "This question has been removed", - field_111: "Which organisation owns this property?", - field_112: "Username field", - field_113: "Which organisation manages this property?", - field_114: "Is the person still serving in the UK armed forces?", - field_115: "This question has been removed", - field_116: "How often does the household receive income?", - field_117: "Is this letting sheltered accommodation?", - field_118: "Does anybody in the household have a physical or mental health condition (or other illness) expected to last for 12 months or more?", - field_119: "Vision, for example blindness or partial sight", - field_120: "Hearing, for example deafness or partial hearing", - field_121: "Mobility, for example walking short distances or climbing stairs", - field_122: "Dexterity, for example lifting and carrying objects, using a keyboard", - field_123: "Learning or understanding or concentrating", - field_124: "Memory", - field_125: "Mental health", - field_126: "Stamina or breathing or fatigue", - field_127: "Socially or behaviourally, for example associated with autism spectral disorder (ASD) which includes Aspergers' or attention deficit hyperactivity disorder (ADHD)", - field_128: "Other", - field_129: "Is this letting a London Affordable Rent letting?", - field_130: "Which type of Intermediate Rent is this letting?", - field_131: "Which 'Other' type of Intermediate Rent is this letting?", - field_132: "Data Protection", - field_133: "Is this a joint tenancy?", - field_134: "Is this letting a renewal?", - }.freeze - attr_reader :bulk_upload, :path validate :validate_file_not_empty + validate :validate_min_columns validate :validate_max_columns def initialize(bulk_upload:, path:) @@ -160,14 +24,16 @@ class BulkUpload::Lettings::Validator row = index + row_offset + 1 row_parser.errors.each do |error| + col = csv_parser.column_for_field(error.attribute.to_s) + bulk_upload.bulk_upload_errors.create!( field: error.attribute, error: error.message, - tenant_code: row_parser.field_7, - property_ref: row_parser.field_100, + tenant_code: row_parser.tenant_code, + property_ref: row_parser.property_ref, row:, - cell: "#{cols[field_number_for_attribute(error.attribute) - col_offset + 1]}#{row}", - col: cols[field_number_for_attribute(error.attribute) - col_offset + 1], + cell: "#{col}#{row}", + col:, category: error.options[:category], ) end @@ -175,7 +41,7 @@ class BulkUpload::Lettings::Validator end def create_logs? - return false if any_setup_sections_incomplete? + return false if any_setup_errors? return false if over_column_error_threshold? return false if row_parsers.any?(&:block_log_creation?) @@ -186,8 +52,12 @@ class BulkUpload::Lettings::Validator QUESTIONS[field] end - def any_setup_sections_incomplete? - row_parsers.any?(&:setup_section_incomplete?) + def any_setup_errors? + bulk_upload + .bulk_upload_errors + .where(category: "setup") + .count + .positive? end private @@ -206,7 +76,14 @@ private end def csv_parser - @csv_parser ||= BulkUpload::Lettings::CsvParser.new(path:) + @csv_parser ||= case bulk_upload.year + when 2022 + BulkUpload::Lettings::Year2022::CsvParser.new(path:) + when 2023 + BulkUpload::Lettings::Year2023::CsvParser.new(path:) + else + raise "csv parser not found" + end end def row_offset @@ -253,12 +130,20 @@ private end end + def validate_min_columns + return if halt_validations? + + column_count = rows.map(&:size).min + + errors.add(:base, :under_min_column_count) if column_count < csv_parser.class::MIN_COLUMNS + end + def validate_max_columns return if halt_validations? - max_row_size = rows.map(&:size).max + column_count = rows.map(&:size).max - errors.add(:file, :max_row_size) if max_row_size > 136 + errors.add(:base, :over_max_column_count) if column_count > csv_parser.class::MAX_COLUMNS end def halt_validations! diff --git a/app/services/bulk_upload/lettings/csv_parser.rb b/app/services/bulk_upload/lettings/year2022/csv_parser.rb similarity index 75% rename from app/services/bulk_upload/lettings/csv_parser.rb rename to app/services/bulk_upload/lettings/year2022/csv_parser.rb index 6cead61ab..c0d8d8900 100644 --- a/app/services/bulk_upload/lettings/csv_parser.rb +++ b/app/services/bulk_upload/lettings/year2022/csv_parser.rb @@ -1,6 +1,9 @@ require "csv" -class BulkUpload::Lettings::CsvParser +class BulkUpload::Lettings::Year2022::CsvParser + MIN_COLUMNS = 134 + MAX_COLUMNS = 136 + attr_reader :path def initialize(path:) @@ -25,7 +28,7 @@ class BulkUpload::Lettings::CsvParser headers = ("field_1".."field_134").to_a hash = Hash[headers.zip(stripped_row)] - BulkUpload::Lettings::RowParser.new(hash) + BulkUpload::Lettings::Year2022::RowParser.new(hash) end end @@ -37,8 +40,16 @@ class BulkUpload::Lettings::CsvParser @rows ||= CSV.parse(normalised_string, row_sep:) end + def column_for_field(field) + cols[headers.find_index(field) + col_offset] + end + private + def headers + @headers ||= ("field_1".."field_134").to_a + end + def with_headers? rows[0][0]&.match?(/\D+/) end diff --git a/app/services/bulk_upload/lettings/row_parser.rb b/app/services/bulk_upload/lettings/year2022/row_parser.rb similarity index 75% rename from app/services/bulk_upload/lettings/row_parser.rb rename to app/services/bulk_upload/lettings/year2022/row_parser.rb index f974613e4..11e65a402 100644 --- a/app/services/bulk_upload/lettings/row_parser.rb +++ b/app/services/bulk_upload/lettings/year2022/row_parser.rb @@ -1,7 +1,144 @@ -class BulkUpload::Lettings::RowParser +class BulkUpload::Lettings::Year2022::RowParser include ActiveModel::Model include ActiveModel::Attributes + QUESTIONS = { + field_1: "What is the letting type?", + field_2: "This question has been removed", + field_3: "This question has been removed", + field_4: "Management group code", + field_5: "Scheme code", + field_6: "This question has been removed", + field_7: "What is the tenant code?", + field_8: "Is this a starter tenancy?", + field_9: "What is the tenancy type?", + field_10: "If 'Other', what is the tenancy type?", + field_11: "What is the length of the fixed-term tenancy to the nearest year?", + field_12: "Age of Person 1", + field_13: "Age of Person 2", + field_14: "Age of Person 3", + field_15: "Age of Person 4", + field_16: "Age of Person 5", + field_17: "Age of Person 6", + field_18: "Age of Person 7", + field_19: "Age of Person 8", + field_20: "Gender identity of Person 1", + field_21: "Gender identity of Person 2", + field_22: "Gender identity of Person 3", + field_23: "Gender identity of Person 4", + field_24: "Gender identity of Person 5", + field_25: "Gender identity of Person 6", + field_26: "Gender identity of Person 7", + field_27: "Gender identity of Person 8", + field_28: "Relationship to Person 1 for Person 2", + field_29: "Relationship to Person 1 for Person 3", + field_30: "Relationship to Person 1 for Person 4", + field_31: "Relationship to Person 1 for Person 5", + field_32: "Relationship to Person 1 for Person 6", + field_33: "Relationship to Person 1 for Person 7", + field_34: "Relationship to Person 1 for Person 8", + field_35: "Working situation of Person 1", + field_36: "Working situation of Person 2", + field_37: "Working situation of Person 3", + field_38: "Working situation of Person 4", + field_39: "Working situation of Person 5", + field_40: "Working situation of Person 6", + field_41: "Working situation of Person 7", + field_42: "Working situation of Person 8", + field_43: "What is the lead tenant's ethnic group?", + field_44: "What is the lead tenant's nationality?", + field_45: "Does anybody in the household have links to the UK armed forces?", + field_46: "Was the person seriously injured or ill as a result of serving in the UK armed forces?", + field_47: "Is anybody in the household pregnant?", + field_48: "Is the tenant likely to be receiving benefits related to housing?", + field_49: "How much of the household's income is from Universal Credit, state pensions or benefits?", + field_50: "How much income does the household have in total?", + field_51: "Do you know the household's income?", + field_52: "What is the tenant's main reason for the household leaving their last settled home?", + field_53: "If 'Other', what was the main reason for leaving their last settled home?", + field_54: "This question has been removed", + field_55: "Does anybody in the household have any disabled access needs?", + field_56: "Does anybody in the household have any disabled access needs?", + field_57: "Does anybody in the household have any disabled access needs?", + field_58: "Does anybody in the household have any disabled access needs?", + field_59: "Does anybody in the household have any disabled access needs?", + field_60: "Does anybody in the household have any disabled access needs?", + field_61: "Where was the household immediately before this letting?", + field_62: "What is the local authority of the household's last settled home?", + field_63: "Part 1 of postcode of last settled home", + field_64: "Part 2 of postcode of last settled home", + field_65: "Do you know the postcode of last settled home?", + field_66: "How long has the household continuously lived in the local authority area of the new letting?", + field_67: "How long has the household been on the waiting list for the new letting?", + field_68: "Was the tenant homeless directly before this tenancy?", + field_69: "Was the household given 'reasonable preference' by the local authority?", + field_70: "Reasonable preference. They were homeless or about to lose their home (within 56 days)", + field_71: "Reasonable preference. They were living in insanitary, overcrowded or unsatisfactory housing", + field_72: "Reasonable preference. They needed to move on medical and welfare grounds (including a disability)", + field_73: "Reasonable preference. They needed to move to avoid hardship to themselves or others", + field_74: "Reasonable preference. Don't know", + field_75: "Was the letting made under any of the following allocations systems?", + field_76: "Was the letting made under any of the following allocations systems?", + field_77: "Was the letting made under any of the following allocations systems?", + field_78: "What was the source of referral for this letting?", + field_79: "How often does the household pay rent and other charges?", + field_80: "What is the basic rent?", + field_81: "What is the service charge?", + field_82: "What is the personal service charge?", + field_83: "What is the support charge?", + field_84: "Total Charge", + field_85: "If this is a care home, how much does the household pay every [time period]?", + field_86: "Does the household pay rent or other charges for the accommodation?", + field_87: "After the household has received any housing-related benefits, will they still need to pay basic rent and other charges?", + field_88: "What do you expect the outstanding amount to be?", + field_89: "What is the void or renewal date?", + field_90: "What is the void or renewal date?", + field_91: "What is the void or renewal date?", + field_92: "What date were major repairs completed on?", + field_93: "What date were major repairs completed on?", + field_94: "What date were major repairs completed on?", + field_95: "This question has been removed", + field_96: "What date did the tenancy start?", + field_97: "What date did the tenancy start?", + field_98: "What date did the tenancy start?", + field_99: "Since becoming available, how many times has the property been previously offered?", + field_100: "What is the property reference?", + field_101: "How many bedrooms does the property have?", + field_102: "What type of unit is the property?", + field_103: "Which type of building is the property?", + field_104: "Is the property built or adapted to wheelchair-user standards?", + field_105: "What type was the property most recently let as?", + field_106: "What is the reason for the property being vacant?", + field_107: "What is the local authority of the property?", + field_108: "Part 1 of postcode of the property", + field_109: "Part 2 of postcode of the property", + field_110: "This question has been removed", + field_111: "Which organisation owns this property?", + field_112: "Username field", + field_113: "Which organisation manages this property?", + field_114: "Is the person still serving in the UK armed forces?", + field_115: "This question has been removed", + field_116: "How often does the household receive income?", + field_117: "Is this letting sheltered accommodation?", + field_118: "Does anybody in the household have a physical or mental health condition (or other illness) expected to last for 12 months or more?", + field_119: "Vision, for example blindness or partial sight", + field_120: "Hearing, for example deafness or partial hearing", + field_121: "Mobility, for example walking short distances or climbing stairs", + field_122: "Dexterity, for example lifting and carrying objects, using a keyboard", + field_123: "Learning or understanding or concentrating", + field_124: "Memory", + field_125: "Mental health", + field_126: "Stamina or breathing or fatigue", + field_127: "Socially or behaviourally, for example associated with autism spectral disorder (ASD) which includes Aspergers' or attention deficit hyperactivity disorder (ADHD)", + field_128: "Other", + field_129: "Is this letting a London Affordable Rent letting?", + field_130: "Which type of Intermediate Rent is this letting?", + field_131: "Which 'Other' type of Intermediate Rent is this letting?", + field_132: "Data Protection", + field_133: "Is this a joint tenancy?", + field_134: "Is this letting a renewal?", + }.freeze + attribute :bulk_upload attribute :block_log_creation, :boolean, default: -> { false } @@ -174,15 +311,23 @@ class BulkUpload::Lettings::RowParser validate :validate_owning_org_permitted validate :validate_owning_org_owns_stock validate :validate_owning_org_exists + validate :validate_owning_org_data_given validate :validate_managing_org_related validate :validate_managing_org_exists + validate :validate_managing_org_data_given validate :validate_scheme_related validate :validate_scheme_exists + validate :validate_scheme_data_given validate :validate_location_related validate :validate_location_exists + validate :validate_location_data_given + + def self.question_for_field(field) + QUESTIONS[field] + end def valid? errors.clear @@ -207,7 +352,12 @@ class BulkUpload::Lettings::RowParser end def blank_row? - attribute_set.to_hash.reject { |k, _| %w[bulk_upload block_log_creation].include?(k) }.values.compact.empty? + attribute_set + .to_hash + .reject { |k, _| %w[bulk_upload block_log_creation].include?(k) } + .values + .compact + .empty? end def log @@ -222,8 +372,12 @@ class BulkUpload::Lettings::RowParser block_log_creation end - def setup_section_incomplete? - log.form.setup_sections[0].subsections[0].is_incomplete?(log) + def tenant_code + field_7 + end + + def property_ref + field_100 end private @@ -245,7 +399,13 @@ private def validate_location_exists if scheme && field_5.present? && location.nil? - errors.add(:field_5, "Location could be found with provided scheme code", category: :setup) + errors.add(:field_5, "Location could be found with provided scheme code") + end + end + + def validate_location_data_given + if bulk_upload.supported_housing? && field_5.blank? + errors.add(:field_5, "The scheme code must be present", category: "setup") end end @@ -263,7 +423,13 @@ private def validate_scheme_exists if field_4.present? && scheme.nil? - errors.add(:field_4, "The management group code is not correct", category: :setup) + errors.add(:field_4, "The management group code is not correct") + end + end + + def validate_scheme_data_given + if bulk_upload.supported_housing? && field_4.blank? + errors.add(:field_4, "The management group code is not correct", category: "setup") end end @@ -277,6 +443,12 @@ private def validate_managing_org_exists if managing_organisation.nil? errors.delete(:field_113) + errors.add(:field_113, "The managing organisation code is incorrect") + end + end + + def validate_managing_org_data_given + if field_113.blank? errors.add(:field_113, "The managing organisation code is incorrect", category: :setup) end end @@ -292,6 +464,12 @@ private def validate_owning_org_exists if owning_organisation.nil? errors.delete(:field_111) + errors.add(:field_111, "The owning organisation code is incorrect") + end + end + + def validate_owning_org_data_given + if field_111.blank? errors.add(:field_111, "The owning organisation code is incorrect", category: :setup) end end diff --git a/app/services/bulk_upload/lettings/year2023/csv_parser.rb b/app/services/bulk_upload/lettings/year2023/csv_parser.rb new file mode 100644 index 000000000..6f661922c --- /dev/null +++ b/app/services/bulk_upload/lettings/year2023/csv_parser.rb @@ -0,0 +1,81 @@ +require "csv" + +class BulkUpload::Lettings::Year2023::CsvParser + MIN_COLUMNS = 141 + MAX_COLUMNS = 143 + + attr_reader :path + + def initialize(path:) + @path = path + end + + def row_offset + if with_headers? + rows.find_index { |row| row[0].match(/field number/i) } + 1 + else + 0 + end + end + + def col_offset + with_headers? ? 1 : 0 + end + + def cols + @cols ||= ("A".."EL").to_a + end + + def row_parsers + @row_parsers ||= body_rows.map do |row| + stripped_row = row[col_offset..] + hash = Hash[field_numbers.zip(stripped_row)] + + BulkUpload::Lettings::Year2023::RowParser.new(hash) + end + end + + def body_rows + rows[row_offset..] + end + + def rows + @rows ||= CSV.parse(normalised_string, row_sep:) + end + + def column_for_field(field) + cols[field_numbers.find_index(field) + col_offset] + end + +private + + def default_field_numbers + [5, nil, nil, 15, 16, nil, 13, 40, 41, 42, 43, 46, 52, 56, 60, 64, 68, 72, 76, 47, 53, 57, 61, 65, 69, 73, 77, 51, 55, 59, 63, 67, 71, 75, 50, 54, 58, 62, 66, 70, 74, 78, 48, 49, 79, 81, 82, 123, 124, 122, 120, 102, 103, nil, 83, 84, 85, 86, 87, 88, 104, 109, 107, 108, 106, 100, 101, 105, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 126, 128, 129, 130, 131, 132, 127, 125, 133, 134, 33, 34, 35, 36, 37, 38, nil, 7, 8, 9, 28, 14, 32, 29, 30, 31, 26, 27, 25, 23, 24, nil, 1, 3, 2, 80, nil, 121, 44, 89, 98, 92, 95, 90, 91, 93, 94, 97, 96, 99, 10, 11, 12, 45, 39, 6, 4, 17, 18, 19, 20, 21, 22].map { |h| h.present? ? "field_#{h}" : "field_blank" } + end + + def field_numbers + @field_numbers ||= if with_headers? + rows[row_offset - 1][col_offset..].map { |h| h.present? ? "field_#{h}" : "field_blank" } + else + default_field_numbers + end + end + + def with_headers? + rows.map { |r| r[0] }.any? { |cell| cell&.match?(/field number/i) } + end + + def row_sep + "\n" + end + + def normalised_string + return @normalised_string if @normalised_string + + @normalised_string = File.read(path, encoding: "bom|utf-8") + @normalised_string.gsub!("\r\n", "\n") + @normalised_string.scrub!("") + + @normalised_string + end +end diff --git a/app/services/bulk_upload/lettings/year2023/row_parser.rb b/app/services/bulk_upload/lettings/year2023/row_parser.rb new file mode 100644 index 000000000..724b1c2ef --- /dev/null +++ b/app/services/bulk_upload/lettings/year2023/row_parser.rb @@ -0,0 +1,1241 @@ +class BulkUpload::Lettings::Year2023::RowParser + include ActiveModel::Model + include ActiveModel::Attributes + + QUESTIONS = { + field_1: "Which organisation owns this property?", + field_2: "Which organisation manages this letting?", + field_3: "What is the CORE username of the account this letting log should be assigned to?", + field_4: "What is the needs type?", + field_5: "What is the letting type?", + field_6: "Is this letting a renewal?", + field_7: "What is the tenancy start date?", + field_8: "What is the tenancy start date?", + field_9: "What is the tenancy start date?", + field_10: "Is this a London Affordable Rent letting?", + field_11: "Which type of Intermediate Rent is this letting?", + field_12: "Which 'Other' type of Intermediate Rent is this letting?", + field_13: "What is the tenant code?", + field_14: "What is the property reference?", + field_15: "What management group does this letting belong to?", + field_16: "What scheme does this letting belong to?", + field_17: "Which location is this letting for?", + field_18: "If known, provide this property’s UPRN", + field_19: "Address line 1", + field_20: "Address line 2", + field_21: "Town or city", + field_22: "County", + field_23: "Part 1 of the property's postcode", + field_24: "Part 2 of the property's postcode", + field_25: "What is the property's local authority?", + field_26: "What type was the property most recently let as?", + field_27: "What is the reason for the property being vacant?", + field_28: "How many times was the property offered between becoming vacant and this letting?", + field_29: "What type of unit is the property?", + field_30: "Which type of building is the property?", + field_31: "Is the property built or adapted to wheelchair-user standards?", + field_32: "How many bedrooms does the property have?", + field_33: "What is the void date?", + field_34: "What is the void date?", + field_35: "What is the void date?", + field_36: "What date were any major repairs completed on?", + field_37: "What date were any major repairs completed on?", + field_38: "What date were any major repairs completed on?", + field_39: "Is this a joint tenancy?", + field_40: "Is this a starter tenancy?", + field_41: "What is the type of tenancy?", + field_42: "If 'Other', what is the type of tenancy?", + field_43: "What is the length of the fixed-term tenancy to the nearest year?", + field_44: "Is this letting sheltered accommodation?", + field_45: "Has tenant seen the DLUHC privacy notice?", + field_46: "What is the lead tenant's age?", + field_47: "Which of these best describes the lead tenant's gender identity?", + field_48: "Which of these best describes the lead tenant's ethnic background?", + field_49: "What is the lead tenant's nationality?", + field_50: "Which of these best describes the lead tenant's working situation?", + field_51: "What is person 2's relationship to the lead tenant?", + field_52: "What is person 2's age?", + field_53: "Which of these best describes person 2's gender identity?", + field_54: "Which of these best describes person 2's working situation?", + field_55: "What is person 3's relationship to the lead tenant?", + field_56: "What is person 3's age?", + field_57: "Which of these best describes person 3's gender identity?", + field_58: "Which of these best describes person 3's working situation?", + field_59: "What is person 4's relationship to the lead tenant?", + field_60: "What is person 4's age?", + field_61: "Which of these best describes person 4's gender identity?", + field_62: "Which of these best describes person 4's working situation?", + field_63: "What is person 5's relationship to the lead tenant?", + field_64: "What is person 5's age?", + field_65: "Which of these best describes person 5's gender identity?", + field_66: "Which of these best describes person 5's working situation?", + field_67: "What is person 6's relationship to the lead tenant?", + field_68: "What is person 6's age?", + field_69: "Which of these best describes person 6's gender identity?", + field_70: "Which of these best describes person 6's working situation?", + field_71: "What is person 7's relationship to the lead tenant?", + field_72: "What is person 7's age?", + field_73: "Which of these best describes person 7's gender identity?", + field_74: "Which of these best describes person 7's working situation?", + field_75: "What is person 8's relationship to the lead tenant?", + field_76: "What is person 8's age?", + field_77: "Which of these best describes person 8's gender identity?", + field_78: "Which of these best describes person 8's working situation?", + field_79: "Does anybody in the household have links to the UK armed forces?", + field_80: "Is this person still serving in the UK armed forces?", + field_81: "Was this person seriously injured or ill as a result of serving in the UK armed forces?", + field_82: "Is anybody in the household pregnant?", + field_83: "Does anybody in the household have any disabled access needs?", + field_84: "Does anybody in the household have any disabled access needs?", + field_85: "Does anybody in the household have any disabled access needs?", + field_86: "Does anybody in the household have any disabled access needs?", + field_87: "Does anybody in the household have any disabled access needs?", + field_88: "Does anybody in the household have any disabled access needs?", + field_89: "Does anybody in the household have a physical or mental health condition (or other illness) expected to last 12 months or more?", + field_90: "Does this person's condition affect their dexterity?", + field_91: "Does this person's condition affect their learning or understanding or concentrating?", + field_92: "Does this person's condition affect their hearing?", + field_93: "Does this person's condition affect their memory?", + field_94: "Does this person's condition affect their mental health?", + field_95: "Does this person's condition affect their mobility?", + field_96: "Does this person's condition affect them socially or behaviourally?", + field_97: "Does this person's condition affect their stamina or breathing or fatigue?", + field_98: "Does this person's condition affect their vision?", + field_99: "Does this person's condition affect them in another way?", + field_100: "How long has the household continuously lived in the local authority area of the new letting?", + field_101: "How long has the household been on the local authority waiting list for the new letting?", + field_102: "What is the tenant’s main reason for the household leaving their last settled home?", + field_103: "If 'Other', what was the main reason for leaving their last settled home?", + field_104: "Where was the household immediately before this letting?", + field_105: "Did the household experience homelessness immediately before this letting?", + field_106: "Do you know the postcode of the household's last settled home?", + field_107: "What is the postcode of the household's last settled home?", + field_108: "What is the postcode of the household's last settled home?", + field_109: "What is the local authority of the household's last settled home?", + field_110: "Was the household given 'reasonable preference' by the local authority?", + field_111: "Reasonable preference reason They were homeless or about to lose their home (within 56 days)", + field_112: "Reasonable preference reason They were living in insanitary, overcrowded or unsatisfactory housing", + field_113: "Reasonable preference reason They needed to move on medical and welfare reasons (including disability)", + field_114: "Reasonable preference reason They needed to move to avoid hardship to themselves or others", + field_115: "Reasonable preference reason Don't know", + field_116: "How was this letting allocated?", + field_117: "How was this letting allocated?", + field_118: "How was this letting allocated?", + field_119: "What was the source of referral for this letting?", + field_120: "Do you know the household's combined total income after tax?", + field_121: "How often does the household receive income?", + field_122: "How much income does the household have in total?", + field_123: "Is the tenant likely to be receiving any of these housing-related benefits?", + field_124: "How much of the household's income is from Universal Credit, state pensions or benefits?", + field_125: "Does the household pay rent or other charges for the accommodation?", + field_126: "How often does the household pay rent and other charges?", + field_127: "If this is a care home, how much does the household pay every [time period]?", + field_128: "What is the basic rent?", + field_129: "What is the service charge?", + field_130: "What is the personal service charge?", + field_131: "What is the support charge?", + field_132: "Total charge", + field_133: "After the household has received any housing-related benefits, will they still need to pay for rent and charges?", + field_134: "What do you expect the outstanding amount to be?", + }.freeze + + attribute :bulk_upload + attribute :block_log_creation, :boolean, default: -> { false } + + attribute :field_blank + + attribute :field_1, :string + attribute :field_2, :string + attribute :field_3, :string + attribute :field_4, :integer + attribute :field_5, :integer + attribute :field_6, :integer + attribute :field_7, :integer + attribute :field_8, :integer + attribute :field_9, :integer + attribute :field_10, :integer + attribute :field_11, :integer + attribute :field_12, :string + attribute :field_13, :string + attribute :field_14, :string + attribute :field_15, :string + attribute :field_16, :string + attribute :field_17, :string + attribute :field_18, :string + attribute :field_19, :string + attribute :field_20, :string + attribute :field_21, :string + attribute :field_22, :string + attribute :field_23, :string + attribute :field_24, :string + attribute :field_25, :string + attribute :field_26, :integer + attribute :field_27, :integer + attribute :field_28, :integer + attribute :field_29, :integer + attribute :field_30, :integer + attribute :field_31, :integer + attribute :field_32, :integer + attribute :field_33, :integer + attribute :field_34, :integer + attribute :field_35, :integer + attribute :field_36, :integer + attribute :field_37, :integer + attribute :field_38, :integer + attribute :field_39, :integer + attribute :field_40, :integer + attribute :field_41, :integer + attribute :field_42, :string + attribute :field_43, :integer + attribute :field_44, :integer + attribute :field_45, :integer + attribute :field_46, :string + attribute :field_47, :string + attribute :field_48, :integer + attribute :field_49, :integer + attribute :field_50, :integer + attribute :field_51, :string + attribute :field_52, :string + attribute :field_53, :string + attribute :field_54, :integer + attribute :field_55, :string + attribute :field_56, :string + attribute :field_57, :string + attribute :field_58, :integer + attribute :field_59, :string + attribute :field_60, :string + attribute :field_61, :string + attribute :field_62, :integer + attribute :field_63, :string + attribute :field_64, :string + attribute :field_65, :string + attribute :field_66, :integer + attribute :field_67, :string + attribute :field_68, :string + attribute :field_69, :string + attribute :field_70, :integer + attribute :field_71, :string + attribute :field_72, :string + attribute :field_73, :string + attribute :field_74, :integer + attribute :field_75, :string + attribute :field_76, :string + attribute :field_77, :string + attribute :field_78, :integer + attribute :field_79, :integer + attribute :field_80, :integer + attribute :field_81, :integer + attribute :field_82, :integer + attribute :field_83, :integer + attribute :field_84, :integer + attribute :field_85, :integer + attribute :field_86, :integer + attribute :field_87, :integer + attribute :field_88, :integer + attribute :field_89, :integer + attribute :field_90, :integer + attribute :field_91, :integer + attribute :field_92, :integer + attribute :field_93, :integer + attribute :field_94, :integer + attribute :field_95, :integer + attribute :field_96, :integer + attribute :field_97, :integer + attribute :field_98, :integer + attribute :field_99, :integer + attribute :field_100, :integer + attribute :field_101, :integer + attribute :field_102, :integer + attribute :field_103, :string + attribute :field_104, :integer + attribute :field_105, :integer + attribute :field_106, :integer + attribute :field_107, :string + attribute :field_108, :string + attribute :field_109, :string + attribute :field_110, :integer + attribute :field_111, :integer + attribute :field_112, :integer + attribute :field_113, :integer + attribute :field_114, :integer + attribute :field_115, :integer + attribute :field_116, :integer + attribute :field_117, :integer + attribute :field_118, :integer + attribute :field_119, :integer + attribute :field_120, :integer + attribute :field_121, :integer + attribute :field_122, :decimal + attribute :field_123, :integer + attribute :field_124, :integer + attribute :field_125, :integer + attribute :field_126, :integer + attribute :field_127, :decimal + attribute :field_128, :decimal + attribute :field_129, :decimal + attribute :field_130, :decimal + attribute :field_131, :decimal + attribute :field_132, :decimal + attribute :field_133, :integer + attribute :field_134, :decimal + + validates :field_5, presence: { message: I18n.t("validations.not_answered", question: "letting type") }, + inclusion: { in: (1..12).to_a, message: I18n.t("validations.invalid_option", question: "letting type") } + validates :field_16, presence: { if: proc { [2, 4, 6, 8, 10, 12].include?(field_5) } } + + validates :field_46, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 1 must be a number or the letter R" } + validates :field_52, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 2 must be a number or the letter R" } + validates :field_56, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 3 must be a number or the letter R" } + validates :field_60, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 4 must be a number or the letter R" } + validates :field_64, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 5 must be a number or the letter R" } + validates :field_68, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 6 must be a number or the letter R" } + validates :field_72, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 7 must be a number or the letter R" } + validates :field_76, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 8 must be a number or the letter R" } + + validates :field_7, presence: { message: I18n.t("validations.not_answered", question: "tenancy start date (day)") } + validates :field_8, presence: { message: I18n.t("validations.not_answered", question: "tenancy start date (month)") } + validates :field_9, presence: { message: I18n.t("validations.not_answered", question: "tenancy start date (year)") } + + validates :field_9, format: { with: /\A\d{2}\z/, message: I18n.t("validations.setup.startdate.year_not_two_digits") } + + validate :validate_needs_type_present + validate :validate_data_types + validate :validate_nulls + validate :validate_relevant_collection_window + validate :validate_la_with_local_housing_referral + validate :validate_cannot_be_la_referral_if_general_needs_and_la + validate :validate_leaving_reason_for_renewal + validate :validate_lettings_type_matches_bulk_upload + validate :validate_only_one_housing_needs_type + validate :validate_no_disabled_needs_conjunction + validate :validate_dont_know_disabled_needs_conjunction + validate :validate_no_and_dont_know_disabled_needs_conjunction + + validate :validate_owning_org_permitted + validate :validate_owning_org_owns_stock + validate :validate_owning_org_exists + validate :validate_owning_org_data_given + + validate :validate_managing_org_related + validate :validate_managing_org_exists + validate :validate_managing_org_data_given + + validate :validate_scheme_related + validate :validate_scheme_exists + validate :validate_scheme_data_given + + validate :validate_location_related + validate :validate_location_exists + validate :validate_location_data_given + + def self.question_for_field(field) + QUESTIONS[field] + end + + def valid? + errors.clear + + return true if blank_row? + + super + + log.valid? + + log.errors.each do |error| + fields = field_mapping_for_errors[error.attribute] || [] + + fields.each do |field| + unless errors.include?(field) + errors.add(field, error.type) + end + end + end + + errors.blank? + end + + def blank_row? + attribute_set + .to_hash + .reject { |k, _| %w[bulk_upload block_log_creation field_blank].include?(k) } + .values + .compact + .empty? + end + + def log + @log ||= LettingsLog.new(attributes_for_log) + end + + def block_log_creation! + self.block_log_creation = true + end + + def block_log_creation? + block_log_creation + end + + def tenant_code + field_13 + end + + def property_ref + field_14 + end + +private + + def validate_needs_type_present + if field_4.blank? + errors.add(:field_4, I18n.t("validations.not_answered", question: "needs type")) + end + end + + def start_date + return if field_7.blank? || field_8.blank? || field_9.blank? + + Date.parse("20#{field_9.to_s.rjust(2, '0')}-#{field_8}-#{field_7}") + rescue StandardError + nil + end + + def validate_no_and_dont_know_disabled_needs_conjunction + if field_87 == 1 && field_88 == 1 + errors.add(:field_87, I18n.t("validations.household.housingneeds.no_and_dont_know_disabled_needs_conjunction")) + errors.add(:field_88, I18n.t("validations.household.housingneeds.no_and_dont_know_disabled_needs_conjunction")) + end + end + + def validate_dont_know_disabled_needs_conjunction + if field_88 == 1 && [field_83, field_84, field_85, field_86].compact.count.positive? + errors.add(:field_88, I18n.t("validations.household.housingneeds.dont_know_disabled_needs_conjunction")) + end + end + + def validate_no_disabled_needs_conjunction + if field_87 == 1 && [field_83, field_84, field_85, field_86].compact.count.positive? + errors.add(:field_87, I18n.t("validations.household.housingneeds.no_disabled_needs_conjunction")) + end + end + + def validate_only_one_housing_needs_type + if [field_83, field_84, field_85].compact.count.positive? + errors.add(:field_83, I18n.t("validations.household.housingneeds_type.only_one_option_permitted")) + errors.add(:field_84, I18n.t("validations.household.housingneeds_type.only_one_option_permitted")) + errors.add(:field_85, I18n.t("validations.household.housingneeds_type.only_one_option_permitted")) + end + end + + def validate_lettings_type_matches_bulk_upload + if [1, 3, 5, 7, 9, 11].include?(field_5) && !general_needs? + errors.add(:field_5, I18n.t("validations.setup.lettype.supported_housing_mismatch")) + end + + if [2, 4, 6, 8, 10, 12].include?(field_5) && !supported_housing? + errors.add(:field_5, I18n.t("validations.setup.lettype.general_needs_mismatch")) + end + end + + def validate_leaving_reason_for_renewal + if field_6 == 1 && ![40, 42].include?(field_102) + errors.add(:field_102, I18n.t("validations.household.reason.renewal_reason_needed")) + end + end + + def general_needs? + field_4 == 1 + end + + def supported_housing? + field_4 == 2 + end + + def validate_cannot_be_la_referral_if_general_needs_and_la + if field_119 == 4 && general_needs? && owning_organisation && owning_organisation.la? + errors.add :field_119, I18n.t("validations.household.referral.la_general_needs.prp_referred_by_la") + end + end + + def validate_la_with_local_housing_referral + if field_119 == 3 && owning_organisation && owning_organisation.la? + errors.add(:field_119, I18n.t("validations.household.referral.nominated_by_local_ha_but_la")) + end + end + + def validate_relevant_collection_window + return if start_date.blank? || bulk_upload.form.blank? + + unless bulk_upload.form.valid_start_date_for_form?(start_date) + errors.add(:field_7, I18n.t("validations.date.outside_collection_window")) + errors.add(:field_8, I18n.t("validations.date.outside_collection_window")) + errors.add(:field_9, I18n.t("validations.date.outside_collection_window")) + end + end + + def validate_data_types + unless attribute_set["field_5"].value_before_type_cast&.match?(/\A\d+\z/) + errors.add(:field_5, I18n.t("validations.invalid_number", question: "letting type")) + end + end + + def validate_nulls + field_mapping_for_errors.each do |error_key, fields| + question_id = error_key.to_s + question = questions.find { |q| q.id == question_id } + + next unless question + next if log.optional_fields.include?(question.id) + next if question.completed?(log) + + if setup_question?(question) + fields.each do |field| + if errors[field].present? + errors.add(field, I18n.t("validations.not_answered", question: question.check_answer_label&.downcase), category: :setup) + end + end + else + fields.each do |field| + unless errors.any? { |e| fields.include?(e.attribute) } + errors.add(field, I18n.t("validations.not_answered", question: question.check_answer_label&.downcase)) + end + end + end + end + end + + def validate_location_related + return if scheme.blank? || location.blank? + + unless location.scheme == scheme + block_log_creation! + errors.add(:field_17, "Scheme code must relate to a location that is owned by owning organisation or managing organisation") + end + end + + def validate_location_exists + if scheme && field_17.present? && location.nil? + errors.add(:field_17, "Location could be found with provided scheme code") + end + end + + def validate_location_data_given + if supported_housing? && field_17.blank? + errors.add(:field_17, "The scheme code must be present", category: "setup") + end + end + + def validate_scheme_related + return unless field_16.present? && scheme.present? + + owned_by_owning_org = owning_organisation && scheme.owning_organisation == owning_organisation + owned_by_managing_org = managing_organisation && scheme.owning_organisation == managing_organisation + + unless owned_by_owning_org || owned_by_managing_org + block_log_creation! + errors.add(:field_16, "This management group code does not belong to your organisation, or any of your stock owners / managing agents") + end + end + + def validate_scheme_exists + if field_16.present? && scheme.nil? + errors.add(:field_16, "The management group code is not correct") + end + end + + def validate_scheme_data_given + if supported_housing? && field_16.blank? + errors.add(:field_16, "The management group code is not correct", category: "setup") + end + end + + def validate_managing_org_related + if owning_organisation && managing_organisation && !owning_organisation.can_be_managed_by?(organisation: managing_organisation) + block_log_creation! + errors.add(:field_2, "This managing organisation does not have a relationship with the owning organisation") + end + end + + def validate_managing_org_exists + if managing_organisation.nil? + errors.delete(:field_2) + errors.add(:field_2, "The managing organisation code is incorrect") + end + end + + def validate_managing_org_data_given + if field_2.blank? + errors.add(:field_2, "The managing organisation code is incorrect", category: :setup) + end + end + + def validate_owning_org_owns_stock + if owning_organisation && !owning_organisation.holds_own_stock? + block_log_creation! + errors.delete(:field_1) + errors.add(:field_1, "The owning organisation code provided is for an organisation that does not own stock") + end + end + + def validate_owning_org_exists + if owning_organisation.nil? + errors.delete(:field_1) + errors.add(:field_1, "The owning organisation code is incorrect") + end + end + + def validate_owning_org_data_given + if field_1.blank? + errors.add(:field_1, "The owning organisation code is incorrect", category: :setup) + end + end + + def validate_owning_org_permitted + if owning_organisation && !bulk_upload.user.organisation.affiliated_stock_owners.include?(owning_organisation) + block_log_creation! + errors.delete(:field_1) + errors.add(:field_1, "You do not have permission to add logs for this owning organisation") + end + end + + def setup_question?(question) + log.form.setup_sections[0].subsections[0].questions.include?(question) + end + + def field_mapping_for_errors + { + lettype: [:field_5], + tenancycode: [:field_13], + postcode_known: %i[field_25 field_23 field_24], + postcode_full: %i[field_25 field_23 field_24], + la: %i[field_25], + owning_organisation: [:field_1], + managing_organisation: [:field_2], + owning_organisation_id: [:field_1], + managing_organisation_id: [:field_2], + renewal: [:field_6], + scheme: %i[field_16], + location: %i[field_17], + created_by: [], + needstype: [:field_4], + rent_type: %i[field_5 field_10 field_11], + startdate: %i[field_7 field_8 field_9], + unittype_gn: %i[field_29], + builtype: %i[field_30], + wchair: %i[field_31], + beds: %i[field_32], + joint: %i[field_39], + startertenancy: %i[field_40], + tenancy: %i[field_41], + tenancyother: %i[field_42], + tenancylength: %i[field_43], + declaration: %i[field_45], + + age1_known: %i[field_46], + age1: %i[field_46], + age2_known: %i[field_52], + age2: %i[field_52], + age3_known: %i[field_56], + age3: %i[field_56], + age4_known: %i[field_60], + age4: %i[field_60], + age5_known: %i[field_64], + age5: %i[field_64], + age6_known: %i[field_68], + age6: %i[field_68], + age7_known: %i[field_72], + age7: %i[field_72], + age8_known: %i[field_76], + age8: %i[field_76], + + sex1: %i[field_47], + sex2: %i[field_53], + sex3: %i[field_57], + sex4: %i[field_61], + sex5: %i[field_65], + sex6: %i[field_69], + sex7: %i[field_73], + sex8: %i[field_77], + + ethnic_group: %i[field_48], + ethnic: %i[field_48], + national: %i[field_49], + + relat2: %i[field_51], + relat3: %i[field_55], + relat4: %i[field_59], + relat5: %i[field_63], + relat6: %i[field_67], + relat7: %i[field_71], + relat8: %i[field_75], + + ecstat1: %i[field_50], + ecstat2: %i[field_54], + ecstat3: %i[field_58], + ecstat4: %i[field_62], + ecstat5: %i[field_66], + ecstat6: %i[field_70], + ecstat7: %i[field_74], + ecstat8: %i[field_78], + + armedforces: %i[field_79], + leftreg: %i[field_80], + reservist: %i[field_81], + preg_occ: %i[field_82], + housingneeds: %i[field_82], + + illness: %i[field_89], + + layear: %i[field_100], + waityear: %i[field_101], + reason: %i[field_102], + reasonother: %i[field_103], + prevten: %i[field_104], + homeless: %i[field_105], + + prevloc: %i[field_109], + previous_la_known: %i[field_109], + ppcodenk: %i[field_106], + ppostcode_full: %i[field_107 field_108], + + reasonpref: %i[field_110], + rp_homeless: %i[field_111], + rp_insan_unsat: %i[field_112], + rp_medwel: %i[field_113], + rp_hardship: %i[field_114], + rp_dontknow: %i[field_115], + + cbl: %i[field_116], + chr: %i[field_118], + cap: %i[field_117], + + referral: %i[field_119], + + net_income_known: %i[field_120], + earnings: %i[field_122], + incfreq: %i[field_121], + hb: %i[field_123], + benefits: %i[field_124], + + period: %i[field_126], + brent: %i[field_128], + scharge: %i[field_129], + pscharge: %i[field_130], + supcharg: %i[field_131], + tcharge: %i[field_132], + chcharge: %i[field_127], + household_charge: %i[field_125], + hbrentshortfall: %i[field_133], + tshortfall: %i[field_134], + + unitletas: %i[field_26], + rsnvac: %i[field_27], + sheltered: %i[field_44], + + illness_type_1: %i[field_98], + illness_type_2: %i[field_92], + illness_type_3: %i[field_95], + illness_type_4: %i[field_90], + illness_type_5: %i[field_91], + illness_type_6: %i[field_93], + illness_type_7: %i[field_94], + illness_type_8: %i[field_97], + illness_type_9: %i[field_96], + illness_type_10: %i[field_99], + + irproduct_other: %i[field_12], + + offered: %i[field_28], + propcode: %i[field_14], + + majorrepairs: %i[field_36 field_37 field_38], + mrcdate: %i[field_36 field_37 field_38], + + voiddate: %i[field_33 field_34 field_35], + } + end + + def attribute_set + @attribute_set ||= instance_variable_get(:@attributes) + end + + def questions + log.form.subsections.flat_map { |ss| ss.applicable_questions(log) } + end + + def attributes_for_log + attributes = {} + + attributes["lettype"] = field_5 + attributes["tenancycode"] = field_13 + attributes["la"] = field_25 + attributes["postcode_known"] = postcode_known + attributes["postcode_full"] = postcode_full + attributes["owning_organisation_id"] = owning_organisation_id + attributes["managing_organisation_id"] = managing_organisation_id + attributes["renewal"] = renewal + attributes["scheme"] = scheme + attributes["location"] = location + attributes["created_by"] = bulk_upload.user + attributes["needstype"] = field_4 + attributes["rent_type"] = rent_type + attributes["startdate"] = startdate + attributes["unittype_gn"] = field_29 + attributes["builtype"] = field_30 + attributes["wchair"] = field_31 + attributes["beds"] = field_32 + attributes["joint"] = field_39 + attributes["startertenancy"] = field_40 + attributes["tenancy"] = field_41 + attributes["tenancyother"] = field_42 + attributes["tenancylength"] = field_43 + attributes["declaration"] = field_45 + + attributes["age1_known"] = field_46 == "R" ? 1 : 0 + attributes["age1"] = field_46 if attributes["age1_known"].zero? && field_46&.match(/\A\d{1,3}\z|\AR\z/) + + attributes["age2_known"] = field_52 == "R" ? 1 : 0 + attributes["age2"] = field_52 if attributes["age2_known"].zero? && field_52&.match(/\A\d{1,3}\z|\AR\z/) + + attributes["age3_known"] = field_56 == "R" ? 1 : 0 + attributes["age3"] = field_56 if attributes["age3_known"].zero? && field_56&.match(/\A\d{1,3}\z|\AR\z/) + + attributes["age4_known"] = field_60 == "R" ? 1 : 0 + attributes["age4"] = field_60 if attributes["age4_known"].zero? && field_60&.match(/\A\d{1,3}\z|\AR\z/) + + attributes["age5_known"] = field_64 == "R" ? 1 : 0 + attributes["age5"] = field_64 if attributes["age5_known"].zero? && field_64&.match(/\A\d{1,3}\z|\AR\z/) + + attributes["age6_known"] = field_68 == "R" ? 1 : 0 + attributes["age6"] = field_68 if attributes["age6_known"].zero? && field_68&.match(/\A\d{1,3}\z|\AR\z/) + + attributes["age7_known"] = field_72 == "R" ? 1 : 0 + attributes["age7"] = field_72 if attributes["age7_known"].zero? && field_72&.match(/\A\d{1,3}\z|\AR\z/) + + attributes["age8_known"] = field_76 == "R" ? 1 : 0 + attributes["age8"] = field_76 if attributes["age8_known"].zero? && field_76&.match(/\A\d{1,3}\z|\AR\z/) + + attributes["sex1"] = field_47 + attributes["sex2"] = field_53 + attributes["sex3"] = field_57 + attributes["sex4"] = field_61 + attributes["sex5"] = field_65 + attributes["sex6"] = field_69 + attributes["sex7"] = field_73 + attributes["sex8"] = field_77 + + attributes["ethnic_group"] = ethnic_group_from_ethnic + attributes["ethnic"] = field_48 + attributes["national"] = field_49 + + attributes["relat2"] = field_51 + attributes["relat3"] = field_55 + attributes["relat4"] = field_59 + attributes["relat5"] = field_63 + attributes["relat6"] = field_67 + attributes["relat7"] = field_71 + attributes["relat8"] = field_75 + + attributes["ecstat1"] = field_50 + attributes["ecstat2"] = field_54 + attributes["ecstat3"] = field_58 + attributes["ecstat4"] = field_62 + attributes["ecstat5"] = field_66 + attributes["ecstat6"] = field_70 + attributes["ecstat7"] = field_74 + attributes["ecstat8"] = field_78 + + attributes["details_known_2"] = details_known(2) + attributes["details_known_3"] = details_known(3) + attributes["details_known_4"] = details_known(4) + attributes["details_known_5"] = details_known(5) + attributes["details_known_6"] = details_known(6) + attributes["details_known_7"] = details_known(7) + attributes["details_known_8"] = details_known(8) + + attributes["armedforces"] = field_79 + attributes["leftreg"] = leftreg + attributes["reservist"] = field_81 + + attributes["preg_occ"] = field_82 + + attributes["housingneeds"] = housingneeds + attributes["housingneeds_type"] = housingneeds_type + attributes["housingneeds_other"] = housingneeds_other + + attributes["illness"] = field_89 + + attributes["layear"] = field_100 + attributes["waityear"] = field_101 + attributes["reason"] = field_102 + attributes["reasonother"] = field_103 + attributes["prevten"] = field_104 + attributes["homeless"] = homeless + + attributes["prevloc"] = prevloc + attributes["previous_la_known"] = previous_la_known + attributes["ppcodenk"] = ppcodenk + attributes["ppostcode_full"] = ppostcode_full + + attributes["reasonpref"] = field_110 + attributes["rp_homeless"] = field_111 + attributes["rp_insan_unsat"] = field_112 + attributes["rp_medwel"] = field_113 + attributes["rp_hardship"] = field_114 + attributes["rp_dontknow"] = field_115 + + attributes["cbl"] = cbl + attributes["chr"] = chr + attributes["cap"] = cap + attributes["letting_allocation_unknown"] = letting_allocation_unknown + + attributes["referral"] = field_119 + + attributes["net_income_known"] = net_income_known + attributes["earnings"] = earnings + attributes["incfreq"] = field_121 + attributes["hb"] = field_123 + attributes["benefits"] = field_124 + + attributes["period"] = field_126 + attributes["brent"] = field_128 + attributes["scharge"] = field_129 + attributes["pscharge"] = field_130 + attributes["supcharg"] = field_131 + attributes["tcharge"] = field_132 + attributes["chcharge"] = field_127 + attributes["household_charge"] = field_125 + attributes["hbrentshortfall"] = field_133 + attributes["tshortfall_known"] = tshortfall_known + attributes["tshortfall"] = field_134 + + attributes["hhmemb"] = hhmemb + + attributes["unitletas"] = field_26 + attributes["rsnvac"] = rsnvac + attributes["sheltered"] = field_44 + + attributes["illness_type_1"] = field_98 + attributes["illness_type_2"] = field_92 + attributes["illness_type_3"] = field_95 + attributes["illness_type_4"] = field_90 + attributes["illness_type_5"] = field_91 + attributes["illness_type_6"] = field_93 + attributes["illness_type_7"] = field_94 + attributes["illness_type_8"] = field_97 + attributes["illness_type_9"] = field_96 + attributes["illness_type_10"] = field_99 + + attributes["irproduct_other"] = field_12 + + attributes["offered"] = field_28 + + attributes["propcode"] = field_14 + + attributes["majorrepairs"] = majorrepairs + + attributes["mrcdate"] = mrcdate + + attributes["voiddate"] = voiddate + + attributes["first_time_property_let_as_social_housing"] = first_time_property_let_as_social_housing + + attributes + end + + def postcode_known + if postcode_full.present? + 1 + elsif field_25.present? + 0 + end + end + + def postcode_full + "#{field_23} #{field_24}" if field_23 && field_24 + end + + def owning_organisation + Organisation.find_by_id_on_mulitple_fields(field_1) + end + + def owning_organisation_id + owning_organisation&.id + end + + def managing_organisation + Organisation.find_by_id_on_mulitple_fields(field_2) + end + + def managing_organisation_id + managing_organisation&.id + end + + def renewal + case field_6 + when 1 + 1 + when 2 + 0 + when nil + rsnvac == 14 ? 1 : 0 + else + field_6 + end + end + + def rsnvac + field_27 + end + + def scheme + @scheme ||= Scheme.find_by_id_on_mulitple_fields(field_16) + end + + def location + return if scheme.nil? + + @location ||= scheme.locations.find_by_id_on_mulitple_fields(field_17) + end + + def renttype + case field_5 + when 1, 2, 3, 4 + :social + when 5, 6, 7, 8 + :affordable + when 9, 10, 11, 12 + :intermediate + end + end + + def rent_type + case renttype + when :social + Imports::LettingsLogsImportService::RENT_TYPE[:social_rent] + when :affordable + if field_10 == 1 + Imports::LettingsLogsImportService::RENT_TYPE[:london_affordable_rent] + else + Imports::LettingsLogsImportService::RENT_TYPE[:affordable_rent] + end + when :intermediate + case field_11 + when 1 + Imports::LettingsLogsImportService::RENT_TYPE[:rent_to_buy] + when 2 + Imports::LettingsLogsImportService::RENT_TYPE[:london_living_rent] + when 3 + Imports::LettingsLogsImportService::RENT_TYPE[:other_intermediate_rent_product] + end + end + end + + def startdate + Date.new(field_9 + 2000, field_8, field_7) if field_9.present? && field_8.present? && field_7.present? + rescue Date::Error + Date.new + end + + def ethnic_group_from_ethnic + return nil if field_48.blank? + + case field_48 + when 1, 2, 3, 18 + 0 + when 4, 5, 6, 7 + 1 + when 8, 9, 10, 11, 15 + 2 + when 12, 13, 14 + 3 + when 16, 19 + 4 + when 17 + 17 + end + end + + def details_known(person_n) + send("person_#{person_n}_present?") ? 0 : 1 + end + + def person_2_present? + field_51.present? && field_52.present? && field_53.present? + end + + def person_3_present? + field_55.present? && field_56.present? && field_57.present? + end + + def person_4_present? + field_59.present? && field_60.present? && field_61.present? + end + + def person_5_present? + field_63.present? && field_64.present? && field_65.present? + end + + def person_6_present? + field_67.present? && field_68.present? && field_69.present? + end + + def person_7_present? + field_71.present? && field_72.present? && field_73.present? + end + + def person_8_present? + field_75.present? && field_76.present? && field_77.present? + end + + def leftreg + case field_80 + when 3 + 3 + when 4 + 1 + when 5 + 2 + when 6 + 0 + end + end + + def housingneeds + if field_87 == 1 + 2 + elsif field_88 == 1 + 3 + else + 2 + end + end + + def housingneeds_type + if field_83 == 1 + 0 + elsif field_84 == 1 + 1 + elsif field_85 == 1 + 2 + end + end + + def housingneeds_other + return 1 if field_86 == 1 + end + + def homeless + case field_105 + when 1 + 1 + when 12 + 11 + end + end + + def prevloc + field_109 + end + + def previous_la_known + prevloc.present? ? 1 : 0 + end + + def ppcodenk + case field_106 + when 1 + 1 + when 2 + 0 + end + end + + def ppostcode_full + "#{field_107} #{field_108}".strip.gsub(/\s+/, " ") + end + + def cbl + case field_116 + when 2 + 0 + when 1 + 1 + end + end + + def chr + case field_118 + when 2 + 0 + when 1 + 1 + end + end + + def cap + case field_117 + when 2 + 0 + when 1 + 1 + end + end + + def letting_allocation_unknown + [cbl, chr, cap].all?(0) ? 1 : 0 + end + + def net_income_known + case field_120 + when 1 + 0 + when 2 + 1 + when 3 + 1 + when 4 + 2 + end + end + + def earnings + field_122.round if field_122.present? + end + + def tshortfall_known + field_133 == 1 ? 0 : 1 + end + + def hhmemb + [ + person_2_present?, + person_3_present?, + person_4_present?, + person_5_present?, + person_6_present?, + person_7_present?, + person_8_present?, + ].count(true) + 1 + end + + def majorrepairs + mrcdate.present? ? 1 : 0 + end + + def mrcdate + Date.new(field_38 + 2000, field_37, field_36) if field_38.present? && field_37.present? && field_36.present? + end + + def voiddate + Date.new(field_35 + 2000, field_34, field_33) if field_35.present? && field_34.present? && field_33.present? + end + + def first_time_property_let_as_social_housing + case rsnvac + when 15, 16, 17 + 1 + else + 0 + end + end +end diff --git a/app/services/bulk_upload/processor.rb b/app/services/bulk_upload/processor.rb index dcf68e594..2d27464f0 100644 --- a/app/services/bulk_upload/processor.rb +++ b/app/services/bulk_upload/processor.rb @@ -8,11 +8,11 @@ class BulkUpload::Processor def call download - return send_failure_mail if validator.invalid? + return send_failure_mail(errors: validator.errors.full_messages) if validator.invalid? validator.call - if validator.any_setup_sections_incomplete? + if validator.any_setup_errors? send_setup_errors_mail elsif validator.create_logs? create_logs @@ -62,9 +62,9 @@ private validator.create_logs? && bulk_upload.logs.group(:status).count.keys == %w[completed] end - def send_failure_mail + def send_failure_mail(errors: []) BulkUploadMailer - .send_bulk_upload_failed_service_error_mail(bulk_upload:) + .send_bulk_upload_failed_service_error_mail(bulk_upload:, errors:) .deliver_later end diff --git a/app/services/bulk_upload/sales/row_parser.rb b/app/services/bulk_upload/sales/row_parser.rb deleted file mode 100644 index f7b74dfe1..000000000 --- a/app/services/bulk_upload/sales/row_parser.rb +++ /dev/null @@ -1,176 +0,0 @@ -class BulkUpload::Sales::RowParser - include ActiveModel::Model - include ActiveModel::Attributes - - attribute :field_1, :string - attribute :field_2, :integer - attribute :field_3, :integer - attribute :field_4, :integer - attribute :field_5 - attribute :field_6, :integer - attribute :field_7, :integer - attribute :field_8, :integer - attribute :field_9, :integer - attribute :field_10, :integer - attribute :field_11, :integer - attribute :field_12, :integer - attribute :field_13, :string - attribute :field_14, :string - attribute :field_15, :string - attribute :field_16, :string - attribute :field_17, :string - attribute :field_18, :string - attribute :field_19, :string - attribute :field_20, :integer - attribute :field_21, :integer - attribute :field_22, :integer - attribute :field_23, :integer - attribute :field_24, :integer - attribute :field_25, :integer - attribute :field_26, :integer - attribute :field_27, :integer - attribute :field_28, :integer - attribute :field_29, :integer - attribute :field_30, :integer - attribute :field_31, :integer - attribute :field_32, :integer - attribute :field_33, :integer - attribute :field_34, :integer - attribute :field_35, :integer - attribute :field_36, :integer - attribute :field_37, :integer - attribute :field_38 - attribute :field_39, :integer - attribute :field_40, :string - attribute :field_41, :string - attribute :field_42, :string - attribute :field_43, :integer - attribute :field_44, :integer - attribute :field_45, :integer - attribute :field_46, :integer - attribute :field_47, :integer - attribute :field_48, :integer - attribute :field_49, :integer - attribute :field_50, :integer - attribute :field_51, :integer - attribute :field_52, :integer - attribute :field_53, :string - attribute :field_54, :string - attribute :field_55, :string - attribute :field_56, :integer - attribute :field_57, :integer - attribute :field_58, :integer - attribute :field_59, :integer - attribute :field_60, :integer - attribute :field_61, :integer - attribute :field_62, :integer - attribute :field_63, :integer - attribute :field_64, :integer - attribute :field_65, :integer - attribute :field_66, :integer - attribute :field_67, :integer - attribute :field_68, :integer - attribute :field_69, :integer - attribute :field_70, :integer - attribute :field_71, :integer - attribute :field_72, :integer - attribute :field_73, :integer - attribute :field_74, :decimal - attribute :field_75, :decimal - attribute :field_76, :integer - attribute :field_77, :integer - attribute :field_78, :integer - attribute :field_79, :integer - attribute :field_80, :integer - attribute :field_81, :integer - attribute :field_82, :integer - attribute :field_83, :integer - attribute :field_84, :integer - attribute :field_85, :string - attribute :field_86 - attribute :field_87, :integer - attribute :field_88, :integer - attribute :field_89, :integer - attribute :field_90, :integer - attribute :field_91, :integer - attribute :field_92, :integer - attribute :field_93, :string - attribute :field_94 - attribute :field_95, :integer - attribute :field_96 - attribute :field_97, :integer - attribute :field_98, :integer - attribute :field_99, :string - attribute :field_100, :integer - attribute :field_101, :string - attribute :field_102, :integer - attribute :field_103, :string - attribute :field_104, :integer - attribute :field_105, :integer - attribute :field_106, :integer - attribute :field_107, :integer - attribute :field_108, :integer - attribute :field_109, :integer - attribute :field_110, :integer - attribute :field_111, :integer - attribute :field_112, :integer - attribute :field_113, :integer - attribute :field_114, :integer - attribute :field_115, :integer - attribute :field_116, :integer - attribute :field_117, :integer - attribute :field_118, :integer - attribute :field_119, :integer - attribute :field_120, :integer - attribute :field_121, :integer - attribute :field_122, :integer - attribute :field_123, :integer - attribute :field_124, :integer - attribute :field_125, :integer - - # validates :field_1, presence: true, numericality: { in: (1..12) } - # validates :field_4, numericality: { in: (1..999), allow_blank: true } - # validates :field_4, presence: true, if: :field_4_presence_check - - validate :validate_possible_answers - -# delegate :valid?, to: :native_object -# delegate :errors, to: :native_object - -private - - def native_object - @native_object ||= SalesLog.new(attributes_for_log) - end - - def field_mapping - { - field_117: :buy1livein, - } - end - - def validate_possible_answers - field_mapping.each do |field, attribute| - possible_answers = FormHandler.instance.current_sales_form.questions.find { |q| q.id == attribute.to_s }.answer_options.keys - - unless possible_answers.include?(public_send(field)) - errors.add(field, "Value supplied is not one of the permitted values") - end - end - end - - def attributes_for_log - hash = field_mapping.invert - attributes = {} - - hash.map do |k, v| - attributes[k] = public_send(v) - end - - attributes - end - - # def field_4_presence_check - # [1, 3, 5, 7, 9, 11].include?(field_1) - # end -end diff --git a/app/services/bulk_upload/sales/validator.rb b/app/services/bulk_upload/sales/validator.rb index 43b8c001d..bddbfd13f 100644 --- a/app/services/bulk_upload/sales/validator.rb +++ b/app/services/bulk_upload/sales/validator.rb @@ -1,138 +1,6 @@ class BulkUpload::Sales::Validator include ActiveModel::Validations - QUESTIONS = { - field_1: "What is the purchaser code?", - field_2: "What is the day of the sale completion date? - DD", - field_3: "What is the month of the sale completion date? - MM", - field_4: "What is the year of the sale completion date? - YY", - field_5: "This question has been removed", - field_6: "Was the buyer interviewed for any of the answers you will provide on this log?", - field_7: "Age of Buyer 1", - field_8: "Age of Person 2", - field_9: "Age of Person 3", - field_10: "Age of Person 4", - field_11: "Age of Person 5", - field_12: "Age of Person 6", - field_13: "Gender identity of Buyer 1", - field_14: "Gender identity of Person 2", - field_15: "Gender identity of Person 3", - field_16: "Gender identity of Person 4", - field_17: "Gender identity of Person 5", - field_18: "Gender identity of Person 6", - field_19: "Relationship to Buyer 1 for Person 2", - field_20: "Relationship to Buyer 1 for Person 3", - field_21: "Relationship to Buyer 1 for Person 4", - field_22: "Relationship to Buyer 1 for Person 5", - field_23: "Relationship to Buyer 1 for Person 6", - field_24: "Working situation of Buyer 1", - field_25: "Working situation of Person 2", - field_26: "Working situation of Person 3", - field_27: "Working situation of Person 4", - field_28: "Working situation of Person 5", - field_29: "Working situation of Person 6", - field_30: "What is buyer 1's ethnic group?", - field_31: "What is buyer 1's nationality?", - field_32: "What is buyer 1's gross annual income?", - field_33: "What is buyer 2's gross annual income?", - field_34: "Was buyer 1's income used for a mortgage application?", - field_35: "Was buyer 2's income used for a mortgage application?", - field_36: "What is the total amount the buyers had in savings before they paid any deposit for the property?", - field_37: "Have any of the purchasers previously owned a property?", - field_38: "This question has been removed", - field_39: "What was buyer 1's previous tenure?", - field_40: "What is the local authority of buyer 1's last settled home?", - field_41: "Part 1 of postcode of buyer 1's last settled home", - field_42: "Part 2 of postcode of buyer 1's last settled home", - field_43: "Do you know the postcode of buyer 1's last settled home?", - field_44: "Was the buyer registered with their PRP (HA)?", - field_45: "Was the buyer registered with the local authority?", - field_46: "Was the buyer registered with a Help to Buy agent?", - field_47: "Was the buyer registered with another PRP (HA)?", - field_48: "Does anyone in the household consider themselves to have a disability?", - field_49: "Does anyone in the household use a wheelchair?", - field_50: "How many bedrooms does the property have?", - field_51: "What type of unit is the property?", - field_52: "Which type of bulding is the property?", - field_53: "What is the local authority of the property?", - field_54: "Part 1 of postcode of property", - field_55: "Part 2 of postcode of property", - field_56: "Is the property built or adapted to wheelchair user standards?", - field_57: "What is the type of shared ownership sale?", - field_58: "Is this a resale?", - field_59: "What is the day of the practical completion or handover date?", - field_60: "What is the month of the practical completion or handover date?", - field_61: "What is the day of the exchange of contracts date?", - field_62: "What is the day of the practical completion or handover date?", - field_63: "What is the month of the practical completion or handover date?", - field_64: "What is the year of the practical completion or handover date?", - field_65: "Was the household re-housed under a local authority nominations agreement?", - field_66: "How many bedrooms did the buyer's previous property have?", - field_67: "What was the type of the buyer's previous property?", - field_68: "What was the full purchase price?", - field_69: "What was the initial percentage equity stake purchased?", - field_70: "What is the mortgage amount?", - field_71: "Does this include any extra borrowing?", - field_72: "How much was the cash deposit paid on the property?", - field_73: "How much cash discount was given through Social Homebuy?", - field_74: "What is the basic monthly rent?", - field_75: "What are the total monthly leasehold charges for the property?", - field_76: "What is the type of discounted ownership sale?", - field_77: "What was the full purchase price?", - field_78: "What was the amount of any loan, grant, discount or subsidy given?", - field_79: "What was the percentage discount?", - field_80: "What is the mortgage amount?", - field_81: "Does this include any extra borrowing?", - field_82: "How much was the cash deposit paid on the property?", - field_83: "What are the total monthly leasehold charges for the property?", - field_84: "What is the type of outright sale?", - field_85: "If 'other', what is the 'other' type?", - field_86: "This question has been removed", - field_87: "What is the full purchase price?", - field_88: "What is the mortgage amount?", - field_89: "Does this include any extra borrowing?", - field_90: "How much was the cash deposit paid on the property?", - field_91: "What are the total monthly leasehold charges for the property?", - field_92: "Which organisation owned this property before the sale?", - field_93: "Username", - field_94: "This question has been removed", - field_95: "Has the buyer ever served in the UK Armed Forces and for how long?", - field_96: "This question has been removed", - field_97: "Are any of the buyers a spouse or civil partner of a UK Armed Forces regular who died in service within the last 2 years?", - field_98: "What is the name of the mortgage lender? - Shared ownership", - field_99: "If 'other', what is the name of the mortgage lender?", - field_100: "What is the name of the mortgage lender? - Discounted ownership", - field_101: "If 'other', what is the name of the mortgage lender?", - field_102: "What is the name of the mortgage lender? - Outright sale", - field_103: "If 'other', what is the name of the mortgage lender?", - field_104: "Were the buyers receiving any of these housing-related benefits immediately before buying this property?", - field_105: "What is the length of the mortgage in years? - Shared ownership", - field_106: "What is the length of the mortgage in years? - Discounted ownership", - field_107: "What is the length of the mortgage in years? - Outright sale", - field_108: "How long have the buyers been living in the property before the purchase? - Discounted ownership", - field_109: "Are there more than two joint purchasers of this property?", - field_110: "How long have the buyers been living in the property before the purchase? - Shared ownership", - field_111: "Is this a staircasing transaction?", - field_112: "Data Protection question", - field_113: "Was this purchase made through an ownership scheme?", - field_114: "Is the buyer a company?", - field_115: "Will the buyers live in the property?", - field_116: "Is this a joint purchase?", - field_117: "Will buyer 1 live in the property?", - field_118: "Will buyer 2 live in the property?", - field_119: "Besides the buyers, how many people will live in the property?", - field_120: "What percentage of the property has been bought in this staircasing transaction?", - field_121: "What percentage of the property does the buyer now own in total?", - field_122: "What was the rent type of the buyer's previous property?", - field_123: "Was a mortgage used for the purchase of this property? - Shared ownership", - field_124: "Was a mortgage used for the purchase of this property? - Discounted ownership", - field_125: "Was a mortgage used for the purchase of this property? - Outright sale", - }.freeze - - def self.question_for_field(field) - QUESTIONS[field] - end - attr_reader :bulk_upload, :path validate :validate_file_not_empty @@ -193,7 +61,7 @@ private headers = ("field_1".."field_125").to_a hash = Hash[headers.zip(stripped_row)] - BulkUpload::Sales::RowParser.new(hash) + BulkUpload::Sales::Year2022::RowParser.new(hash) end end diff --git a/app/services/bulk_upload/sales/year2022/row_parser.rb b/app/services/bulk_upload/sales/year2022/row_parser.rb new file mode 100644 index 000000000..965c3547a --- /dev/null +++ b/app/services/bulk_upload/sales/year2022/row_parser.rb @@ -0,0 +1,308 @@ +class BulkUpload::Sales::Year2022::RowParser + include ActiveModel::Model + include ActiveModel::Attributes + + QUESTIONS = { + field_1: "What is the purchaser code?", + field_2: "What is the day of the sale completion date? - DD", + field_3: "What is the month of the sale completion date? - MM", + field_4: "What is the year of the sale completion date? - YY", + field_5: "This question has been removed", + field_6: "Was the buyer interviewed for any of the answers you will provide on this log?", + field_7: "Age of Buyer 1", + field_8: "Age of Person 2", + field_9: "Age of Person 3", + field_10: "Age of Person 4", + field_11: "Age of Person 5", + field_12: "Age of Person 6", + field_13: "Gender identity of Buyer 1", + field_14: "Gender identity of Person 2", + field_15: "Gender identity of Person 3", + field_16: "Gender identity of Person 4", + field_17: "Gender identity of Person 5", + field_18: "Gender identity of Person 6", + field_19: "Relationship to Buyer 1 for Person 2", + field_20: "Relationship to Buyer 1 for Person 3", + field_21: "Relationship to Buyer 1 for Person 4", + field_22: "Relationship to Buyer 1 for Person 5", + field_23: "Relationship to Buyer 1 for Person 6", + field_24: "Working situation of Buyer 1", + field_25: "Working situation of Person 2", + field_26: "Working situation of Person 3", + field_27: "Working situation of Person 4", + field_28: "Working situation of Person 5", + field_29: "Working situation of Person 6", + field_30: "What is buyer 1's ethnic group?", + field_31: "What is buyer 1's nationality?", + field_32: "What is buyer 1's gross annual income?", + field_33: "What is buyer 2's gross annual income?", + field_34: "Was buyer 1's income used for a mortgage application?", + field_35: "Was buyer 2's income used for a mortgage application?", + field_36: "What is the total amount the buyers had in savings before they paid any deposit for the property?", + field_37: "Have any of the purchasers previously owned a property?", + field_38: "This question has been removed", + field_39: "What was buyer 1's previous tenure?", + field_40: "What is the local authority of buyer 1's last settled home?", + field_41: "Part 1 of postcode of buyer 1's last settled home", + field_42: "Part 2 of postcode of buyer 1's last settled home", + field_43: "Do you know the postcode of buyer 1's last settled home?", + field_44: "Was the buyer registered with their PRP (HA)?", + field_45: "Was the buyer registered with the local authority?", + field_46: "Was the buyer registered with a Help to Buy agent?", + field_47: "Was the buyer registered with another PRP (HA)?", + field_48: "Does anyone in the household consider themselves to have a disability?", + field_49: "Does anyone in the household use a wheelchair?", + field_50: "How many bedrooms does the property have?", + field_51: "What type of unit is the property?", + field_52: "Which type of bulding is the property?", + field_53: "What is the local authority of the property?", + field_54: "Part 1 of postcode of property", + field_55: "Part 2 of postcode of property", + field_56: "Is the property built or adapted to wheelchair user standards?", + field_57: "What is the type of shared ownership sale?", + field_58: "Is this a resale?", + field_59: "What is the day of the practical completion or handover date?", + field_60: "What is the month of the practical completion or handover date?", + field_61: "What is the day of the exchange of contracts date?", + field_62: "What is the day of the practical completion or handover date?", + field_63: "What is the month of the practical completion or handover date?", + field_64: "What is the year of the practical completion or handover date?", + field_65: "Was the household re-housed under a local authority nominations agreement?", + field_66: "How many bedrooms did the buyer's previous property have?", + field_67: "What was the type of the buyer's previous property?", + field_68: "What was the full purchase price?", + field_69: "What was the initial percentage equity stake purchased?", + field_70: "What is the mortgage amount?", + field_71: "Does this include any extra borrowing?", + field_72: "How much was the cash deposit paid on the property?", + field_73: "How much cash discount was given through Social Homebuy?", + field_74: "What is the basic monthly rent?", + field_75: "What are the total monthly leasehold charges for the property?", + field_76: "What is the type of discounted ownership sale?", + field_77: "What was the full purchase price?", + field_78: "What was the amount of any loan, grant, discount or subsidy given?", + field_79: "What was the percentage discount?", + field_80: "What is the mortgage amount?", + field_81: "Does this include any extra borrowing?", + field_82: "How much was the cash deposit paid on the property?", + field_83: "What are the total monthly leasehold charges for the property?", + field_84: "What is the type of outright sale?", + field_85: "If 'other', what is the 'other' type?", + field_86: "This question has been removed", + field_87: "What is the full purchase price?", + field_88: "What is the mortgage amount?", + field_89: "Does this include any extra borrowing?", + field_90: "How much was the cash deposit paid on the property?", + field_91: "What are the total monthly leasehold charges for the property?", + field_92: "Which organisation owned this property before the sale?", + field_93: "Username", + field_94: "This question has been removed", + field_95: "Has the buyer ever served in the UK Armed Forces and for how long?", + field_96: "This question has been removed", + field_97: "Are any of the buyers a spouse or civil partner of a UK Armed Forces regular who died in service within the last 2 years?", + field_98: "What is the name of the mortgage lender? - Shared ownership", + field_99: "If 'other', what is the name of the mortgage lender?", + field_100: "What is the name of the mortgage lender? - Discounted ownership", + field_101: "If 'other', what is the name of the mortgage lender?", + field_102: "What is the name of the mortgage lender? - Outright sale", + field_103: "If 'other', what is the name of the mortgage lender?", + field_104: "Were the buyers receiving any of these housing-related benefits immediately before buying this property?", + field_105: "What is the length of the mortgage in years? - Shared ownership", + field_106: "What is the length of the mortgage in years? - Discounted ownership", + field_107: "What is the length of the mortgage in years? - Outright sale", + field_108: "How long have the buyers been living in the property before the purchase? - Discounted ownership", + field_109: "Are there more than two joint purchasers of this property?", + field_110: "How long have the buyers been living in the property before the purchase? - Shared ownership", + field_111: "Is this a staircasing transaction?", + field_112: "Data Protection question", + field_113: "Was this purchase made through an ownership scheme?", + field_114: "Is the buyer a company?", + field_115: "Will the buyers live in the property?", + field_116: "Is this a joint purchase?", + field_117: "Will buyer 1 live in the property?", + field_118: "Will buyer 2 live in the property?", + field_119: "Besides the buyers, how many people will live in the property?", + field_120: "What percentage of the property has been bought in this staircasing transaction?", + field_121: "What percentage of the property does the buyer now own in total?", + field_122: "What was the rent type of the buyer's previous property?", + field_123: "Was a mortgage used for the purchase of this property? - Shared ownership", + field_124: "Was a mortgage used for the purchase of this property? - Discounted ownership", + field_125: "Was a mortgage used for the purchase of this property? - Outright sale", + }.freeze + + attribute :field_1, :string + attribute :field_2, :integer + attribute :field_3, :integer + attribute :field_4, :integer + attribute :field_5 + attribute :field_6, :integer + attribute :field_7, :integer + attribute :field_8, :integer + attribute :field_9, :integer + attribute :field_10, :integer + attribute :field_11, :integer + attribute :field_12, :integer + attribute :field_13, :string + attribute :field_14, :string + attribute :field_15, :string + attribute :field_16, :string + attribute :field_17, :string + attribute :field_18, :string + attribute :field_19, :string + attribute :field_20, :integer + attribute :field_21, :integer + attribute :field_22, :integer + attribute :field_23, :integer + attribute :field_24, :integer + attribute :field_25, :integer + attribute :field_26, :integer + attribute :field_27, :integer + attribute :field_28, :integer + attribute :field_29, :integer + attribute :field_30, :integer + attribute :field_31, :integer + attribute :field_32, :integer + attribute :field_33, :integer + attribute :field_34, :integer + attribute :field_35, :integer + attribute :field_36, :integer + attribute :field_37, :integer + attribute :field_38 + attribute :field_39, :integer + attribute :field_40, :string + attribute :field_41, :string + attribute :field_42, :string + attribute :field_43, :integer + attribute :field_44, :integer + attribute :field_45, :integer + attribute :field_46, :integer + attribute :field_47, :integer + attribute :field_48, :integer + attribute :field_49, :integer + attribute :field_50, :integer + attribute :field_51, :integer + attribute :field_52, :integer + attribute :field_53, :string + attribute :field_54, :string + attribute :field_55, :string + attribute :field_56, :integer + attribute :field_57, :integer + attribute :field_58, :integer + attribute :field_59, :integer + attribute :field_60, :integer + attribute :field_61, :integer + attribute :field_62, :integer + attribute :field_63, :integer + attribute :field_64, :integer + attribute :field_65, :integer + attribute :field_66, :integer + attribute :field_67, :integer + attribute :field_68, :integer + attribute :field_69, :integer + attribute :field_70, :integer + attribute :field_71, :integer + attribute :field_72, :integer + attribute :field_73, :integer + attribute :field_74, :decimal + attribute :field_75, :decimal + attribute :field_76, :integer + attribute :field_77, :integer + attribute :field_78, :integer + attribute :field_79, :integer + attribute :field_80, :integer + attribute :field_81, :integer + attribute :field_82, :integer + attribute :field_83, :integer + attribute :field_84, :integer + attribute :field_85, :string + attribute :field_86 + attribute :field_87, :integer + attribute :field_88, :integer + attribute :field_89, :integer + attribute :field_90, :integer + attribute :field_91, :integer + attribute :field_92, :integer + attribute :field_93, :string + attribute :field_94 + attribute :field_95, :integer + attribute :field_96 + attribute :field_97, :integer + attribute :field_98, :integer + attribute :field_99, :string + attribute :field_100, :integer + attribute :field_101, :string + attribute :field_102, :integer + attribute :field_103, :string + attribute :field_104, :integer + attribute :field_105, :integer + attribute :field_106, :integer + attribute :field_107, :integer + attribute :field_108, :integer + attribute :field_109, :integer + attribute :field_110, :integer + attribute :field_111, :integer + attribute :field_112, :integer + attribute :field_113, :integer + attribute :field_114, :integer + attribute :field_115, :integer + attribute :field_116, :integer + attribute :field_117, :integer + attribute :field_118, :integer + attribute :field_119, :integer + attribute :field_120, :integer + attribute :field_121, :integer + attribute :field_122, :integer + attribute :field_123, :integer + attribute :field_124, :integer + attribute :field_125, :integer + + # validates :field_1, presence: true, numericality: { in: (1..12) } + # validates :field_4, numericality: { in: (1..999), allow_blank: true } + # validates :field_4, presence: true, if: :field_4_presence_check + + validate :validate_possible_answers + + # delegate :valid?, to: :native_object + # delegate :errors, to: :native_object + + def self.question_for_field(field) + QUESTIONS[field] + end + +private + + def native_object + @native_object ||= SalesLog.new(attributes_for_log) + end + + def field_mapping + { + field_117: :buy1livein, + } + end + + def validate_possible_answers + field_mapping.each do |field, attribute| + possible_answers = FormHandler.instance.current_sales_form.questions.find { |q| q.id == attribute.to_s }.answer_options.keys + + unless possible_answers.include?(public_send(field)) + errors.add(field, "Value supplied is not one of the permitted values") + end + end + end + + def attributes_for_log + hash = field_mapping.invert + attributes = {} + + hash.map do |k, v| + attributes[k] = public_send(v) + end + + attributes + end + + # def field_4_presence_check + # [1, 3, 5, 7, 9, 11].include?(field_1) + # end +end diff --git a/app/services/csv/lettings_log_csv_service.rb b/app/services/csv/lettings_log_csv_service.rb index c8a2cf41e..09d373b01 100644 --- a/app/services/csv/lettings_log_csv_service.rb +++ b/app/services/csv/lettings_log_csv_service.rb @@ -2,8 +2,9 @@ module Csv class LettingsLogCsvService CSV_FIELDS_TO_OMIT = %w[hhmemb net_income_value_check first_time_property_let_as_social_housing renttype needstype postcode_known is_la_inferred totchild totelder totadult net_income_known is_carehome previous_la_known is_previous_la_inferred age1_known age2_known age3_known age4_known age5_known age6_known age7_known age8_known letting_allocation_unknown details_known_2 details_known_3 details_known_4 details_known_5 details_known_6 details_known_7 details_known_8 rent_type_detail wrent wscharge wpschrge wsupchrg wtcharge wtshortfall rent_value_check old_form_id old_id retirement_value_check tshortfall_known pregnancy_value_check hhtype new_old vacdays la prevloc unresolved updated_by_id bulk_upload_id].freeze - def initialize(user) + def initialize(user, export_type:) @user = user + @export_type = export_type set_csv_attributes end @@ -12,30 +13,126 @@ module Csv csv << @attributes LettingsLog.all.find_each do |record| - csv << @attributes.map do |att| - label_from_value(record, att) - end + csv << @attributes.map { |attribute| get_value(attribute, record) } end end end private - def label_from_value(record, att) - if %w[la prevloc].include? att - label_from_boolean_value(record.send(att)) - elsif %w[mrcdate startdate voiddate].include? att - record.send(att)&.to_formatted_s(:govuk_date) + ATTRIBUTES_OF_RELATED_OBJECTS = { + location_code: { + labels: %i[location id], + codes: %i[location id], + }, + location_postcode: { + labels: %i[location postcode], + codes: %i[location postcode], + }, + location_name: { + labels: %i[location name], + codes: %i[location name], + }, + location_units: { + labels: %i[location units], + codes: %i[location units], + }, + location_type_of_unit: { + labels: %i[location type_of_unit], + codes: %i[location type_of_unit_before_type_cast], + }, + location_mobility_type: { + labels: %i[location mobility_type], + codes: %i[location mobility_type_before_type_cast], + }, + location_admin_district: { + labels: %i[location location_admin_district], + codes: %i[location location_admin_district], + }, + location_startdate: { + labels: %i[location startdate], + codes: %i[location startdate], + }, + scheme_service_name: { + labels: %i[scheme service_name], + codes: %i[scheme service_name], + }, + scheme_sensitive: { + labels: %i[scheme sensitive], + codes: %i[scheme sensitive_before_type_cast], + }, + scheme_type: { + labels: %i[scheme scheme_type], + codes: %i[scheme scheme_type_before_type_cast], + }, + scheme_registered_under_care_act: { + labels: %i[scheme registered_under_care_act], + codes: %i[scheme registered_under_care_act_before_type_cast], + }, + scheme_owning_organisation_name: { + labels: %i[scheme owning_organisation name], + codes: %i[scheme owning_organisation name], + }, + scheme_primary_client_group: { + labels: %i[scheme primary_client_group], + codes: %i[scheme primary_client_group_before_type_cast], + }, + scheme_has_other_client_group: { + labels: %i[scheme has_other_client_group], + codes: %i[scheme has_other_client_group_before_type_cast], + }, + scheme_secondary_client_group: { + labels: %i[scheme secondary_client_group], + codes: %i[scheme secondary_client_group_before_type_cast], + }, + scheme_support_type: { + labels: %i[scheme support_type], + codes: %i[scheme support_type_before_type_cast], + }, + scheme_intended_stay: { + labels: %i[scheme intended_stay], + codes: %i[scheme intended_stay_before_type_cast], + }, + scheme_created_at: { + labels: %i[scheme created_at], + codes: %i[scheme created_at], + }, + }.freeze + + def get_value(attribute, record) + attribute = "rent_type" if attribute == "rent_type_detail" # rent_type_detail is the requested column header for rent_type, so as not to confuse with renttype + if ATTRIBUTES_OF_RELATED_OBJECTS.key? attribute.to_sym + call_chain = ATTRIBUTES_OF_RELATED_OBJECTS[attribute.to_sym][@export_type.to_sym] + call_chain.reduce(record) { |object, next_call| object&.send(next_call) } + elsif %w[la prevloc].include? attribute # for all exports we output both the codes and labels for these location attributes + record.send(attribute) + elsif %w[la_label prevloc_label].include? attribute # as above + attribute = attribute.remove("_label") + field_value = record.send(attribute) + get_label(field_value, attribute, record) + elsif %w[mrcdate startdate voiddate].include? attribute + record.send(attribute)&.to_formatted_s(:govuk_date) else - record.form.get_question(att.remove("_label"), record)&.label_from_value(record.send(att.remove("_label"))) || label_from_boolean_value(record.send(att.remove("_label"))) + field_value = record.send(attribute) + case @export_type + when "codes" + field_value + when "labels" + answer_label = get_label(field_value, attribute, record) + answer_label || label_if_boolean_value(field_value) || field_value + end end end - def label_from_boolean_value(value) + def get_label(value, attribute, record) + record.form + .get_question(attribute, record) + &.label_from_value(value) + end + + def label_if_boolean_value(value) return "Yes" if value == true return "No" if value == false - - value end def set_csv_attributes diff --git a/app/services/imports/local_authorities_service.rb b/app/services/imports/local_authorities_service.rb new file mode 100644 index 000000000..23a4e2375 --- /dev/null +++ b/app/services/imports/local_authorities_service.rb @@ -0,0 +1,25 @@ +require "csv" + +module Imports + class LocalAuthoritiesService + attr_reader :path, :count + + def initialize(path:) + @path = path + @count = 0 + end + + def call + CSV.foreach(path, headers: true) do |row| + LocalAuthority.upsert( + { code: row["code"], + name: row["name"], + start_date: Time.zone.local(row["start_year"], 4, 1), + end_date: (Time.zone.local(row["end_year"], 3, 31) if row["end_year"]) }, + unique_by: %i[code], + ) + @count += 1 + end + end + end +end diff --git a/app/services/imports/local_authority_links_service.rb b/app/services/imports/local_authority_links_service.rb new file mode 100644 index 000000000..bdcf8731c --- /dev/null +++ b/app/services/imports/local_authority_links_service.rb @@ -0,0 +1,22 @@ +require "csv" + +module Imports + class LocalAuthorityLinksService + attr_reader :path, :count + + def initialize(path:) + @path = path + @count = 0 + end + + def call + CSV.foreach(path, headers: true) do |row| + LocalAuthorityLink.upsert( + { local_authority_id: LocalAuthority.find_by(code: row["local_authority_code"]).id, + linked_local_authority_id: LocalAuthority.find_by(code: row["linked_local_authority_code"]).id }, + ) + @count += 1 + end + end + end +end diff --git a/app/services/imports/sales_logs_import_service.rb b/app/services/imports/sales_logs_import_service.rb index ed127bff2..d7a3c8534 100644 --- a/app/services/imports/sales_logs_import_service.rb +++ b/app/services/imports/sales_logs_import_service.rb @@ -54,7 +54,6 @@ module Imports attributes["details_known_#{index}"] = details_known(index, attributes) end attributes["national"] = unsafe_string_as_integer(xml_doc, "P1Nat") - attributes["othernational"] = nil attributes["ethnic"] = unsafe_string_as_integer(xml_doc, "P1Eth") attributes["ethnic_group"] = ethnic_group(attributes["ethnic"]) attributes["buy1livein"] = unsafe_string_as_integer(xml_doc, "LiveInBuyer1") @@ -125,7 +124,7 @@ module Imports attributes["mortgagelenderother"] = mortgage_lender_other(xml_doc, attributes) attributes["postcode_full"] = parse_postcode(string_or_nil(xml_doc, "Q14Postcode")) attributes["pcodenk"] = 0 if attributes["postcode_full"].present? # known if given - attributes["soctenant"] = soctenant(attributes) + attributes["soctenant"] = 0 if attributes["ownershipsch"] == 1 attributes["ethnic_group2"] = nil # 23/24 variable attributes["ethnicbuy2"] = nil # 23/24 variable attributes["prevshared"] = nil # 23/24 variable @@ -153,6 +152,7 @@ module Imports attributes["old_persons_shared_ownership_value_check"] = 0 attributes["income2_value_check"] = 0 attributes["monthly_charges_value_check"] = 0 + attributes["student_not_child_value_check"] = 0 # Sets the log creator owner_id = meta_field_value(xml_doc, "owner-user-id").strip @@ -192,11 +192,22 @@ module Imports attributes.delete(error.attribute.to_s) end @logs_overridden << sales_log.old_id - if sales_log.errors.of_kind?(:postcode_full, :postcodes_not_matching) - @logger.warn("Log #{sales_log.old_id}: Removing postcode known and previous postcode known as the postcodes are invalid") - attributes.delete("pcodenk") - attributes.delete("ppcodenk") - end + save_sales_log(attributes, previous_status) + elsif sales_log.errors.of_kind?(:postcode_full, :postcodes_not_matching) + @logger.warn("Log #{sales_log.old_id}: Removing previous postcode known and previous postcode as the postcode is invalid") + @logs_overridden << sales_log.old_id + attributes.delete("ppcodenk") + attributes.delete("ppostcode_full") + save_sales_log(attributes, previous_status) + elsif sales_log.errors.of_kind?(:exdate, :over_a_year_from_saledate) + @logger.warn("Log #{sales_log.old_id}: Removing exchange date as the exchange date is invalid") + @logs_overridden << sales_log.old_id + attributes.delete("exdate") + save_sales_log(attributes, previous_status) + elsif sales_log.errors.of_kind?(:income1, :over_hard_max_for_outside_london) + @logger.warn("Log #{sales_log.old_id}: Removing income1 as the income1 is invalid") + @logs_overridden << sales_log.old_id + attributes.delete("income1") save_sales_log(attributes, previous_status) else @logger.error("Log #{sales_log.old_id}: Failed to import") @@ -243,7 +254,8 @@ module Imports staircase_bought_value_check monthly_charges_value_check hodate_check - saledate_check] + saledate_check + student_not_child_value_check] end def check_status_completed(sales_log, previous_status) @@ -365,17 +377,6 @@ module Imports end end - def soctenant(attributes) - return nil unless attributes["ownershipsch"] == 1 - - if attributes["frombeds"].blank? && attributes["fromprop"].blank? && attributes["socprevten"].blank? - 2 - else - 1 - end - # NO (2) if FROMBEDS, FROMPROP and socprevten are blank, and YES(1) if they are completed - end - def still_serving(xml_doc) case unsafe_string_as_integer(xml_doc, "LeftArmedF") when 4 @@ -511,6 +512,9 @@ module Imports end attributes["pcodenk"] ||= 1 attributes["prevten"] ||= 0 + attributes["extrabor"] ||= 3 if attributes["mortgageused"] == 1 + attributes["socprevten"] ||= 10 if attributes["ownershipsch"] == 1 + attributes["fromprop"] ||= 0 if attributes["ownershipsch"] == 1 # buyer 1 characteristics attributes["age1_known"] ||= 1 diff --git a/app/services/uprn_client.rb b/app/services/uprn_client.rb new file mode 100644 index 000000000..2e57a6072 --- /dev/null +++ b/app/services/uprn_client.rb @@ -0,0 +1,50 @@ +require "net/http" + +class UprnClient + attr_reader :uprn + attr_accessor :error + + ADDRESS = "api.os.uk".freeze + PATH = "/search/places/v1/uprn".freeze + + def initialize(uprn) + @uprn = uprn + end + + def call + unless response.is_a?(Net::HTTPSuccess) && result.present? + @error = "UPRN is not recognised. Check the number, or enter the address" + end + rescue JSON::ParserError + @error = "UPRN is not recognised. Check the number, or enter the address" + end + + def result + @result ||= JSON.parse(response.body).dig("results", 0, "DPA") + end + +private + + def http_client + client = Net::HTTP.new(ADDRESS, 443) + client.use_ssl = true + client.verify_mode = OpenSSL::SSL::VERIFY_PEER + client.max_retries = 3 + client.read_timeout = 10 # seconds + client + end + + def endpoint_uri + uri = URI(PATH) + params = { + uprn:, + key: ENV["OS_DATA_KEY"], + } + uri.query = URI.encode_www_form(params) + uri.to_s + end + + def response + @response ||= http_client.request_get(endpoint_uri) + end +end diff --git a/app/services/uprn_data_presenter.rb b/app/services/uprn_data_presenter.rb new file mode 100644 index 000000000..5602cbd28 --- /dev/null +++ b/app/services/uprn_data_presenter.rb @@ -0,0 +1,41 @@ +require "net/http" + +class UprnDataPresenter + attr_reader :data + + def initialize(data) + @data = data + end + + def postcode + data["POSTCODE"] + end + + def address_line1 + data.values_at( + "PO_BOX_NUMBER", + "ORGANISATION_NAME", + "DEPARTMENT_NAME", + "SUB_BUILDING_NAME", + "BUILDING_NAME", + "BUILDING_NUMBER", + "DEPENDENT_THOROUGHFARE_NAME", + "THOROUGHFARE_NAME", + ).compact + .join(", ") + .titleize + end + + def address_line2 + data.values_at( + "DOUBLE_DEPENDENT_LOCALITY", "DEPENDENT_LOCALITY" + ).compact + .join(", ") + .titleize + .presence + end + + def town_or_city + data["POST_TOWN"].titleize + end +end diff --git a/app/views/bulk_upload_lettings_results/show.html.erb b/app/views/bulk_upload_lettings_results/show.html.erb index 9a8ccddec..30e0f6890 100644 --- a/app/views/bulk_upload_lettings_results/show.html.erb +++ b/app/views/bulk_upload_lettings_results/show.html.erb @@ -1,9 +1,3 @@ -<% if BulkUploadErrorSummaryTableComponent.new(bulk_upload: @bulk_upload).errors? %> - <% content_for :before_content do %> - <%= govuk_back_link(text: "Back", href: summary_bulk_upload_lettings_result_path(@bulk_upload)) %> - <% end %> -<% end %> -
Bulk upload for lettings (<%= @bulk_upload.year_combo %>) diff --git a/app/views/bulk_upload_lettings_results/summary.html.erb b/app/views/bulk_upload_lettings_results/summary.html.erb index 04d8bdb92..2ea2214b3 100644 --- a/app/views/bulk_upload_lettings_results/summary.html.erb +++ b/app/views/bulk_upload_lettings_results/summary.html.erb @@ -1,22 +1,34 @@
Bulk upload for lettings (<%= @bulk_upload.year_combo %>) -

Correct data export and reupload

+

Fix <%= pluralize(@bulk_upload.bulk_upload_errors.count, "error") %> and upload file again

- We noticed that you have a lot of similar errors for some questions. You can download the specification which we reference below to understand how to correct the data. Once you have fixed these errors you can upload again. + We could not create logs from your bulk upload. Below is a list of everything that you need to fix your spreadsheet. You can download the specification to help you fix the cells in your CSV file. +

+ +

+ Filename: <%= @bulk_upload.filename %>

-<%= render BulkUploadErrorSummaryTableComponent.new(bulk_upload: @bulk_upload) %> -
-
-

- You also have other errors in your file which you can either fix them in the CSV file or you can reupload and fix on CORE. <%= govuk_link_to "View the full report", bulk_upload_lettings_result_path(@bulk_upload) %> -

-
+ <%= govuk_tabs(title: "Error reports") do |c| %> + <% c.with_tab(label: "Summary") do %> +

+ This summary shows questions that have at least <%= BulkUploadErrorSummaryTableComponent::DISPLAY_THRESHOLD %> errors or more. See full error report for more details. +

+ + <%= render BulkUploadErrorSummaryTableComponent.new(bulk_upload: @bulk_upload) %> + <% end %> + + <% c.with_tab(label: "Full error report") do %> + <% @bulk_upload.bulk_upload_errors.group_by(&:row).each do |_row, errors_for_row| %> + <%= render BulkUploadErrorRowComponent.new(bulk_upload_errors: errors_for_row) %> + <% end %> + <% end %> + <% end %>
<%= govuk_button_link_to "Upload your file again", start_bulk_upload_lettings_logs_path %> diff --git a/app/views/form/_check_answers_summary_list.html.erb b/app/views/form/_check_answers_summary_list.html.erb index 56ae87905..71fe9cd97 100644 --- a/app/views/form/_check_answers_summary_list.html.erb +++ b/app/views/form/_check_answers_summary_list.html.erb @@ -1,14 +1,21 @@ <%= govuk_summary_list do |summary_list| %> <% total_applicable_questions(subsection, @log, current_user).each do |question| %> <% summary_list.row do |row| %> - <% row.key { question.check_answer_label.to_s.presence || question.header.to_s } %> + <% row.key { get_question_label(question) } %> <% row.value do %> - <%= get_answer_label(question, @log) %> + <%= simple_format( + get_answer_label(question, @log), + wrapper_tag: "span", + class: "govuk-!-margin-right-4", + ) %> <% extra_value = question.get_extra_check_answer_value(@log) %> - <% if extra_value %> - <%= extra_value %> + <% if extra_value && question.answer_label(lettings_log, current_user).present? %> + <%= simple_format( + extra_value, + wrapper_tag: "span", + class: "govuk-!-font-weight-regular app-!-colour-muted", + ) %> <% end %> -
<% question.get_inferred_answers(@log).each do |inferred_answer| %> <%= inferred_answer %> <% end %> diff --git a/app/views/form/_numeric_output_question.html.erb b/app/views/form/_numeric_output_question.html.erb index b96e7b53d..8892523aa 100644 --- a/app/views/form/_numeric_output_question.html.erb +++ b/app/views/form/_numeric_output_question.html.erb @@ -1,7 +1,7 @@ <%= render partial: "form/guidance/#{question.guidance_partial}" if question.top_guidance? %>
-
diff --git a/app/views/logs/index.html.erb b/app/views/logs/index.html.erb index 0e4cd76df..2d88c9bd6 100644 --- a/app/views/logs/index.html.erb +++ b/app/views/logs/index.html.erb @@ -66,7 +66,17 @@
<%= render SearchComponent.new(current_user:, search_label: search_label_for_controller(controller), value: @searched) %> <%= govuk_section_break(visible: true, size: "m") %> - <%= render partial: "log_list", locals: { logs: @logs, title: "Logs", pagy: @pagy, searched: @searched, item_label:, total_count: @total_count, csv_download_url: csv_download_url_for_controller(controller) } %> + <%= render partial: "log_list", + locals: { + logs: @logs, + title: "Logs", + pagy: @pagy, + searched: @searched, + item_label:, + total_count: @total_count, + csv_download_url: csv_download_url_for_controller(controller_type: controller, search: @search_term, codes_only: false), + csv_codes_only_download_url: csv_download_url_for_controller(controller_type: controller, search: @search_term, codes_only: true), + } %> <%== render partial: "pagy/nav", locals: { pagy: @pagy, item_name: "logs" } %>
diff --git a/app/views/organisations/logs.html.erb b/app/views/organisations/logs.html.erb index 94fe8e9bc..bac737e6c 100644 --- a/app/views/organisations/logs.html.erb +++ b/app/views/organisations/logs.html.erb @@ -26,7 +26,17 @@
<%= render SearchComponent.new(current_user:, search_label: "Search by log ID, tenant code, property reference or postcode", value: @searched) %> <%= govuk_section_break(visible: true, size: "m") %> - <%= render partial: "logs/log_list", locals: { logs: @logs, title: "Logs", pagy: @pagy, searched: @searched, item_label:, total_count: @total_count, csv_download_url: logs_csv_download_organisation_path(@organisation, search: @search_term) } %> + <%= render partial: "logs/log_list", + locals: { + logs: @logs, + title: "Logs", + pagy: @pagy, + searched: @searched, + item_label:, + total_count: @total_count, + csv_download_url: logs_csv_download_organisation_path(@organisation, search: @search_term, codes_only: false), + csv_codes_only_download_url: logs_csv_download_organisation_path(@organisation, search: @search_term, codes_only: true), + } %> <%== render partial: "pagy/nav", locals: { pagy: @pagy, item_name: "logs" } %>
diff --git a/config/forms/2022_2023.json b/config/forms/2022_2023.json index e0ef19198..eeed6c3c7 100644 --- a/config/forms/2022_2023.json +++ b/config/forms/2022_2023.json @@ -1110,9 +1110,6 @@ }, { "tenancy": 6 - }, - { - "tenancy": 3 } ] }, diff --git a/config/initializers/feature_toggle.rb b/config/initializers/feature_toggle.rb index 4fc402212..e00a7190b 100644 --- a/config/initializers/feature_toggle.rb +++ b/config/initializers/feature_toggle.rb @@ -4,11 +4,11 @@ class FeatureToggle Rails.env.production? || Rails.env.test? || Rails.env.staging? end - def self.startdate_two_week_validation_enabled? + def self.startdate_collection_window_validation_enabled? Rails.env.production? || Rails.env.test? || Rails.env.staging? end - def self.startdate_collection_window_validation_enabled? + def self.startdate_two_week_validation_enabled? Rails.env.production? || Rails.env.test? || Rails.env.staging? end @@ -40,6 +40,12 @@ class FeatureToggle !Rails.env.development? end + def self.force_crossover? + return false if Rails.env.test? + + !Rails.env.production? + end + def self.validate_valid_radio_options? !(Rails.env.production? || Rails.env.staging?) end diff --git a/config/local_authorities_data/initial_local_authorities.csv b/config/local_authorities_data/initial_local_authorities.csv new file mode 100644 index 000000000..f80fbb6f5 --- /dev/null +++ b/config/local_authorities_data/initial_local_authorities.csv @@ -0,0 +1,388 @@ +code,name,start_year,end_year +S12000033,Aberdeen City,2021, +S12000034,Aberdeenshire,2021, +E07000223,Adur,2021, +E07000032,Amber Valley,2021, +S12000041,Angus,2021, +N09000001,Antrim and Newtownabbey,2021, +N09000011,Ards and North Down,2021, +S12000035,Argyll and Bute,2021, +N09000002,"Armagh City, Banbridge and Craigavon",2021, +E07000224,Arun,2021, +E07000170,Ashfield,2021, +E07000105,Ashford,2021, +E07000200,Babergh,2021, +E09000002,Barking and Dagenham,2021, +E09000003,Barnet,2021, +E08000016,Barnsley,2021, +E07000066,Basildon,2021, +E07000084,Basingstoke and Deane,2021, +E07000171,Bassetlaw,2021, +E06000022,Bath and North East Somerset,2021, +E06000055,Bedford,2021, +N09000003,Belfast,2021, +E09000004,Bexley,2021, +E08000025,Birmingham,2021, +E07000129,Blaby,2021, +E06000008,Blackburn with Darwen,2021, +E06000009,Blackpool,2021, +W06000019,Blaenau Gwent,2021, +E07000033,Bolsover,2021, +E08000001,Bolton,2021, +E07000136,Boston,2021, +E06000058,"Bournemouth, Christchurch and Poole",2021, +E06000036,Bracknell Forest,2021, +E08000032,Bradford,2021, +E07000067,Braintree,2021, +E07000143,Breckland,2021, +E09000005,Brent,2021, +E07000068,Brentwood,2021, +W06000013,Bridgend,2021, +E06000043,Brighton and Hove,2021, +E06000023,"Bristol, City of",2021, +E07000144,Broadland,2021, +E09000006,Bromley,2021, +E07000234,Bromsgrove,2021, +E07000095,Broxbourne,2021, +E07000172,Broxtowe,2021, +E06000060,Buckinghamshire,2021, +E07000117,Burnley,2021, +E08000002,Bury,2021, +W06000018,Caerphilly,2021, +E08000033,Calderdale,2021, +E07000008,Cambridge,2021, +E09000007,Camden,2021, +E07000192,Cannock Chase,2021, +E07000106,Canterbury,2021, +W06000015,Cardiff,2021, +W06000010,Carmarthenshire,2021, +E07000069,Castle Point,2021, +N09000004,Causeway Coast and Glens,2021, +E06000056,Central Bedfordshire,2021, +W06000008,Ceredigion,2021, +E07000130,Charnwood,2021, +E07000070,Chelmsford,2021, +E07000078,Cheltenham,2021, +E07000177,Cherwell,2021, +E06000049,Cheshire East,2021, +E06000050,Cheshire West and Chester,2021, +E07000034,Chesterfield,2021, +E07000225,Chichester,2021, +E07000118,Chorley,2021, +S12000036,City of Edinburgh,2021, +E09000001,City of London,2021, +S12000005,Clackmannanshire,2021, +E07000071,Colchester,2021, +W06000003,Conwy,2021, +E07000150,Corby,2021, +E06000052,Cornwall,2021, +E07000079,Cotswold,2021, +E06000047,County Durham,2021, +E08000026,Coventry,2021, +E07000226,Crawley,2021, +E09000008,Croydon,2021, +E06000063,Cumberland,2023, +E07000096,Dacorum,2021, +E06000005,Darlington,2021, +E07000107,Dartford,2021, +E07000151,Daventry,2021, +W06000004,Denbighshire,2021, +E06000015,Derby,2021, +E07000035,Derbyshire Dales,2021, +N09000005,Derry City and Strabane,2021, +E08000017,Doncaster,2021, +E06000059,Dorset,2021, +E07000108,Dover,2021, +E08000027,Dudley,2021, +S12000006,Dumfries and Galloway,2021, +S12000042,Dundee City,2021, +E09000009,Ealing,2021, +S12000008,East Ayrshire,2021, +E07000009,East Cambridgeshire,2021, +E07000040,East Devon,2021, +S12000045,East Dunbartonshire,2021, +E07000085,East Hampshire,2021, +E07000242,East Hertfordshire,2021, +E07000137,East Lindsey,2021, +S12000010,East Lothian,2021, +E07000152,East Northamptonshire,2021, +S12000011,East Renfrewshire,2021, +E06000011,East Riding of Yorkshire,2021, +E07000193,East Staffordshire,2021, +E07000244,East Suffolk,2021, +E07000061,Eastbourne,2021, +E07000086,Eastleigh,2021, +E07000207,Elmbridge,2021, +E09000010,Enfield,2021, +E07000072,Epping Forest,2021, +E07000208,Epsom and Ewell,2021, +E07000036,Erewash,2021, +E07000041,Exeter,2021, +S12000014,Falkirk,2021, +E07000087,Fareham,2021, +E07000010,Fenland,2021, +N09000006,Fermanagh and Omagh,2021, +S12000047,Fife,2021, +W06000005,Flintshire,2021, +E07000112,Folkestone and Hythe,2021, +E07000080,Forest of Dean,2021, +E07000119,Fylde,2021, +E08000037,Gateshead,2021, +E07000173,Gedling,2021, +S12000049,Glasgow City,2021, +E07000081,Gloucester,2021, +E07000088,Gosport,2021, +E07000109,Gravesham,2021, +E07000145,Great Yarmouth,2021, +E09000011,Greenwich,2021, +E07000209,Guildford,2021, +W06000002,Gwynedd,2021, +E09000012,Hackney,2021, +E06000006,Halton,2021, +E09000013,Hammersmith and Fulham,2021, +E07000131,Harborough,2021, +E09000014,Haringey,2021, +E07000073,Harlow,2021, +E09000015,Harrow,2021, +E07000089,Hart,2021, +E06000001,Hartlepool,2021, +E07000062,Hastings,2021, +E07000090,Havant,2021, +E09000016,Havering,2021, +E06000019,"Herefordshire, County of",2021, +E07000098,Hertsmere,2021, +E07000037,High Peak,2021, +S12000017,Highland,2021, +E09000017,Hillingdon,2021, +E07000132,Hinckley and Bosworth,2021, +E07000227,Horsham,2021, +E09000018,Hounslow,2021, +E07000011,Huntingdonshire,2021, +E07000120,Hyndburn,2021, +S12000018,Inverclyde,2021, +E07000202,Ipswich,2021, +W06000001,Isle of Anglesey,2021, +E06000046,Isle of Wight,2021, +E06000053,Isles of Scilly,2021, +E09000019,Islington,2021, +E09000020,Kensington and Chelsea,2021, +E07000153,Kettering,2021, +E07000146,King’s Lynn and West Norfolk,2021, +E06000010,"Kingston upon Hull, City of",2021, +E09000021,Kingston upon Thames,2021, +E08000034,Kirklees,2021, +E08000011,Knowsley,2021, +E09000022,Lambeth,2021, +E07000121,Lancaster,2021, +E08000035,Leeds,2021, +E06000016,Leicester,2021, +E07000063,Lewes,2021, +E09000023,Lewisham,2021, +E07000194,Lichfield,2021, +E07000138,Lincoln,2021, +N09000007,Lisburn and Castlereagh,2021, +E08000012,Liverpool,2021, +E06000032,Luton,2021, +E07000110,Maidstone,2021, +E07000074,Maldon,2021, +E07000235,Malvern Hills,2021, +E08000003,Manchester,2021, +E07000174,Mansfield,2021, +E06000035,Medway,2021, +E07000133,Melton,2021, +W06000024,Merthyr Tydfil,2021, +E09000024,Merton,2021, +E07000042,Mid Devon,2021, +E07000203,Mid Suffolk,2021, +E07000228,Mid Sussex,2021, +N09000009,Mid Ulster,2021, +N09000008,Mid and East Antrim,2021, +E06000002,Middlesbrough,2021, +S12000019,Midlothian,2021, +E06000042,Milton Keynes,2021, +E07000210,Mole Valley,2021, +W06000021,Monmouthshire,2021, +S12000020,Moray,2021, +S12000013,Na h-Eileanan Siar,2021, +W06000012,Neath Port Talbot,2021, +E07000091,New Forest,2021, +E07000175,Newark and Sherwood,2021, +E08000021,Newcastle upon Tyne,2021, +E07000195,Newcastle-under-Lyme,2021, +E09000025,Newham,2021, +W06000022,Newport,2021, +N09000010,"Newry, Mourne and Down",2021, +S12000021,North Ayrshire,2021, +E07000043,North Devon,2021, +E07000038,North East Derbyshire,2021, +E06000012,North East Lincolnshire,2021, +E07000099,North Hertfordshire,2021, +E07000139,North Kesteven,2021, +S12000050,North Lanarkshire,2021, +E06000013,North Lincolnshire,2021, +E07000147,North Norfolk,2021, +E06000024,North Somerset,2021, +E08000022,North Tyneside,2021, +E07000218,North Warwickshire,2021, +E07000134,North West Leicestershire,2021, +E07000154,Northampton,2021, +E06000057,Northumberland,2021, +E07000148,Norwich,2021, +E06000018,Nottingham,2021, +E07000219,Nuneaton and Bedworth,2021, +E07000135,Oadby and Wigston,2021, +E08000004,Oldham,2021, +S12000023,Orkney Islands,2021, +E07000178,Oxford,2021, +W06000009,Pembrokeshire,2021, +E07000122,Pendle,2021, +S12000048,Perth and Kinross,2021, +E06000031,Peterborough,2021, +E06000026,Plymouth,2021, +E06000044,Portsmouth,2021, +W06000023,Powys,2021, +E07000123,Preston,2021, +E06000038,Reading,2021, +E09000026,Redbridge,2021, +E06000003,Redcar and Cleveland,2021, +E07000236,Redditch,2021, +E07000211,Reigate and Banstead,2021, +S12000038,Renfrewshire,2021, +W06000016,Rhondda Cynon Taf,2021, +E07000124,Ribble Valley,2021, +E09000027,Richmond upon Thames,2021, +E08000005,Rochdale,2021, +E07000075,Rochford,2021, +E07000125,Rossendale,2021, +E07000064,Rother,2021, +E08000018,Rotherham,2021, +E07000220,Rugby,2021, +E07000212,Runnymede,2021, +E07000176,Rushcliffe,2021, +E07000092,Rushmoor,2021, +E06000017,Rutland,2021, +E08000006,Salford,2021, +E08000028,Sandwell,2021, +S12000026,Scottish Borders,2021, +E08000014,Sefton,2021, +E07000111,Sevenoaks,2021, +E08000019,Sheffield,2021, +S12000027,Shetland Islands,2021, +E06000051,Shropshire,2021, +E06000039,Slough,2021, +E08000029,Solihull,2021, +E06000066,Somerset,2023, +S12000028,South Ayrshire,2021, +E07000012,South Cambridgeshire,2021, +E07000039,South Derbyshire,2021, +E06000025,South Gloucestershire,2021, +E07000044,South Hams,2021, +E07000140,South Holland,2021, +E07000141,South Kesteven,2021, +S12000029,South Lanarkshire,2021, +E07000149,South Norfolk,2021, +E07000155,South Northamptonshire,2021, +E07000179,South Oxfordshire,2021, +E07000126,South Ribble,2021, +E07000196,South Staffordshire,2021, +E08000023,South Tyneside,2021, +E06000045,Southampton,2021, +E06000033,Southend-on-Sea,2021, +E09000028,Southwark,2021, +E07000213,Spelthorne,2021, +E07000240,St Albans,2021, +E08000013,St. Helens,2021, +E07000197,Stafford,2021, +E07000198,Staffordshire Moorlands,2021, +E07000243,Stevenage,2021, +S12000030,Stirling,2021, +E08000007,Stockport,2021, +E06000004,Stockton-on-Tees,2021, +E06000021,Stoke-on-Trent,2021, +E07000221,Stratford-on-Avon,2021, +E07000082,Stroud,2021, +E08000024,Sunderland,2021, +E07000214,Surrey Heath,2021, +E09000029,Sutton,2021, +E07000113,Swale,2021, +W06000011,Swansea,2021, +E06000030,Swindon,2021, +E08000008,Tameside,2021, +E07000199,Tamworth,2021, +E07000215,Tandridge,2021, +E07000045,Teignbridge,2021, +E06000020,Telford and Wrekin,2021, +E07000076,Tendring,2021, +E07000093,Test Valley,2021, +E07000083,Tewkesbury,2021, +E07000114,Thanet,2021, +E07000102,Three Rivers,2021, +E06000034,Thurrock,2021, +E07000115,Tonbridge and Malling,2021, +E06000027,Torbay,2021, +W06000020,Torfaen,2021, +E07000046,Torridge,2021, +E09000030,Tower Hamlets,2021, +E08000009,Trafford,2021, +E07000116,Tunbridge Wells,2021, +E07000077,Uttlesford,2021, +W06000014,Vale of Glamorgan,2021, +E07000180,Vale of White Horse,2021, +E08000036,Wakefield,2021, +E08000030,Walsall,2021, +E09000031,Waltham Forest,2021, +E09000032,Wandsworth,2021, +E06000007,Warrington,2021, +E07000222,Warwick,2021, +E07000103,Watford,2021, +E07000216,Waverley,2021, +E07000065,Wealden,2021, +E07000156,Wellingborough,2021, +E07000241,Welwyn Hatfield,2021, +E06000037,West Berkshire,2021, +E07000047,West Devon,2021, +S12000039,West Dunbartonshire,2021, +E07000127,West Lancashire,2021, +E07000142,West Lindsey,2021, +S12000040,West Lothian,2021, +E07000181,West Oxfordshire,2021, +E07000245,West Suffolk,2021, +E09000033,Westminster,2021, +E06000064,Westmorland and Furness,2023, +E08000010,Wigan,2021, +E06000054,Wiltshire,2021, +E07000094,Winchester,2021, +E06000040,Windsor and Maidenhead,2021, +E08000015,Wirral,2021, +E07000217,Woking,2021, +E06000041,Wokingham,2021, +E08000031,Wolverhampton,2021, +E07000237,Worcester,2021, +E07000229,Worthing,2021, +W06000006,Wrexham,2021, +E07000238,Wychavon,2021, +E07000128,Wyre,2021, +E07000239,Wyre Forest,2021, +E06000014,York,2021, +E06000065,North Yorkshire,2023, +N92000002,Northern Ireland,2021, +S92000003,Scotland,2021, +W92000004,Wales,2021, +9300000XX,Outside UK,2021, +E07000027,Barrow-in-Furness,2021,2023, +E07000030,Eden,2021,2023, +E07000031,South Lakeland,2021,2023, +E07000026,Allerdale,2021,2023, +E07000028,Carlisle,2021,2023, +E07000029,Copeland,2021,2023, +E07000163,Craven,2021,2023, +E07000164,Hambleton,2021,2023, +E07000165,Harrogate,2021,2023, +E07000166,Richmondshire,2021,2023, +E07000167,Ryedale,2021,2023, +E07000168,Scarborough,2021,2023, +E07000169,Selby,2021,2023, +E07000187,Mendip,2021,2023, +E07000188,Sedgemoor,2021,2023, +E07000246,Somerset West and Taunton,2021,2023, +E07000189,South Somerset,2021,2023, diff --git a/config/local_authorities_data/local_authority_links_2023.csv b/config/local_authorities_data/local_authority_links_2023.csv new file mode 100644 index 000000000..d388a36c1 --- /dev/null +++ b/config/local_authorities_data/local_authority_links_2023.csv @@ -0,0 +1,35 @@ +local_authority_code,linked_local_authority_code +E06000064,E07000027 +E06000064,E07000030 +E06000064,E07000031 +E07000027,E06000064 +E07000030,E06000064 +E07000031,E06000064 +E06000063,E07000026 +E06000063,E07000028 +E06000063,E07000029 +E07000026,E06000063 +E07000028,E06000063 +E07000029,E06000063 +E06000065,E07000163 +E06000065,E07000164 +E06000065,E07000165 +E06000065,E07000166 +E06000065,E07000167 +E06000065,E07000168 +E06000065,E07000169 +E07000163,E06000065 +E07000164,E06000065 +E07000165,E06000065 +E07000166,E06000065 +E07000167,E06000065 +E07000168,E06000065 +E07000169,E06000065 +E06000066,E07000187 +E06000066,E07000188 +E06000066,E07000246 +E06000066,E07000189 +E07000187,E06000066 +E07000188,E06000066 +E07000246,E06000066 +E07000189,E06000066 diff --git a/config/locales/en.yml b/config/locales/en.yml index 8665c022a..8c9cd12c1 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -41,6 +41,11 @@ en: activemodel: errors: models: + bulk_upload/lettings/validator: + attributes: + base: + over_max_column_count: "too many columns, please ensure you have used the correct template" + under_min_column_count: "too few columns, please ensure you have used the correct template" forms/bulk_upload_lettings/year: attributes: year: @@ -136,7 +141,7 @@ en: above_min: "%{field} must be at least %{min}" date: invalid_date: "Enter a date in the correct format, for example 31 1 2022" - outside_collection_window: Enter a date within the 22/23 financial year, which is between 1st April 2022 and 31st March 2023 + outside_collection_window: Enter a date within the 22/23 collection year, which is between 1st April 2022 and 31st March 2023 postcode: "Enter a postcode in the correct format, for example AA1 1AA" location_admin_district: "Select a local authority" email: @@ -150,12 +155,18 @@ en: intermediate_rent_product_name: blank: "Enter name of other intermediate rent product" saledate: - current_financial_year: - Enter a date within the %{current_start_year_short}/%{current_end_year_short} financial year, which is between %{current_start_year_long} and %{current_end_year_long} - previous_and_current_financial_year: - "Enter a date within the %{previous_start_year_short}/%{previous_end_year_short} or %{previous_end_year_short}/%{current_end_year_short} financial years, which is between %{previous_start_year_long} and %{current_end_year_long}" + current_collection_year: + Enter a date within the %{current_start_year_short}/%{current_end_year_short} collection year, which is between %{current_start_year_long} and %{current_end_year_long} + previous_and_current_collection_year: + "Enter a date within the %{previous_start_year_short}/%{previous_end_year_short} or %{previous_end_year_short}/%{current_end_year_short} collection years, which is between %{previous_start_year_long} and %{current_end_year_long}" + type: + percentage_bought_must_be_at_least_threshold: "The minimum increase in equity while staircasing is %{threshold}% for this shared ownership type" startdate: + current_collection_year: + Enter a date within the %{current_start_year_short}/%{current_end_year_short} collection year, which is between %{current_start_year_long} and %{current_end_year_long} + previous_and_current_collection_year: + "Enter a date within the %{previous_start_year_short}/%{previous_end_year_short} or %{previous_end_year_short}/%{current_end_year_short} collection years, which is between %{previous_start_year_long} and %{current_end_year_long}" later_than_14_days_after: "The tenancy start date must not be later than 14 days from today’s date" before_scheme_end_date: "The tenancy start date must be before the end date for this supported housing scheme" after_void_date: "Enter a tenancy start date that is after the void date" @@ -180,6 +191,10 @@ en: supported_housing_mismatch: Lettings type must be a supported housing type because you selected supported housing when uploading the file property: + uprn: + invalid: "UPRN must be 12 digits or less" + uprn_known: + invalid: "You must answer UPRN known?" mrcdate: before_tenancy_start: "Enter a major repairs date that is before the tenancy start date" not_first_let: "Major repairs date must not be completed if the tenancy is a first let" @@ -297,6 +312,10 @@ en: staircasing: percentage_bought_must_be_greater_than_percentage_owned: "Total percentage buyer now owns must be more than percentage bought in this transaction" older_person_percentage_owned_maximum_75: "Percentage cannot be above 75% under Older Person's Shared Ownership" + percentage_bought_must_be_at_least_threshold: "The minimum increase in equity while staircasing is %{threshold}%" + equity: + under_min: "The minimum initial equity stake for this type of shared ownership sale is %{min_equity}%" + over_max: "The maximum initial equity stake is %{max_equity}%" household: reasonpref: @@ -325,7 +344,6 @@ en: not_student_16_19: "Answer cannot be between 16 and 19 as person %{person_num} is a child of the lead tenant but is not a full-time student" student_16_19: cannot_be_16_19: - student_not_child: "Person cannot be aged 16-19 if they are a student but don't have relationship ‘child’" child_not_student: "Person cannot be aged 16-19 if they have relationship ‘child’ but are not a student" must_be_16_19: "Person must be aged 16-19 if they are a student and have relationship ‘child’" partner_under_16: "Cannot be under 16 if the relationship is partner" @@ -339,7 +357,6 @@ en: student_16_19: cannot_be_student: child_not_16_19: "Person cannot be a student if they are not aged 16-19 but have relationship ‘child’" - 16_19_not_child: "Person cannot be a student if they are aged 16-19 but don‘t have relationship ‘child’" must_be_student: "Person must be a student if they are aged 16-19 and have relationship ‘child’" retired_male: "Answer cannot be ‘retired’ as the male tenant is under 65" retired_female: "Answer cannot be ‘retired’ as the female tenant is under 60" @@ -353,7 +370,6 @@ en: cannot_be_child: student_not_16_19: "Answer cannot be ‘child’ if the person is a student but not aged 16-19" 16_19_not_student: "Answer cannot be ‘child’ if the person is aged 16-19 but not a student" - must_be_child: "Answer must be ‘child’ if the person is aged 16-19 and a student" housingneeds_a: one_or_two_choices: "You can only select one option or ‘other disabled access needs’ plus ‘wheelchair-accessible housing’, ‘wheelchair access to essential rooms’ or ‘level access housing’" housingneeds_type: @@ -507,6 +523,8 @@ en: staircase_bought_seems_high: "You said %{percentage}% was bought in this staircasing transaction, which seems high. Are you sure?" monthly_charges_over_soft_max: title_text: "The amount of monthly charges is high for this type of property and sale type" + student_not_child: + title_text: "You told us this person is a student aged beween 16 and 19" devise: two_factor_authentication: @@ -538,6 +556,16 @@ en: W: "Suitable for someone who uses a wheelchair and offers the full use of all rooms and facilities." A: "Fitted with stairlifts, ramps, level access showers or grab rails." N: "Not designed to wheelchair-user standards or fitted with any equipment or adaptations." + soctenant: + one: "Was the buyer a private registered provider, housing association or local authority tenant immediately before this sale?" + other: "Were any of the buyers private registered providers, housing association or local authority tenants immediately before this sale?" + prevown: + one: "Has the buyer previously owned a property?" + other: "Have any of the buyers previously owned a property?" + stairowned: + one: "What percentage of the property does the buyer now own in total?" + other: "What percentage of the property do the buyers now own in total?" + offered: "How many times was the property offered between becoming vacant and this letting?" hints: location: @@ -550,6 +578,19 @@ en: toggle_active: "If the date is before %{date}, select ‘From the start of the current collection period’ because the previous period has now closed." bulk_upload: needstype: "General needs housing includes both self-contained and shared housing without support or specific adaptations. Supported housing can include direct access hostels, group homes, residential care and nursing homes." + offered: "Do not include the offer that led to this letting. This is after the last tenancy ended. If the property is being offered for let for the first time, enter 0." + + check_answer_labels: + soctenant: + one: "Buyer was a registered provider, housing association or local authority tenant immediately before this sale?" + other: "Any buyers were registered providers, housing association or local authority tenants immediately before this sale?" + prevown: + one: "Buyer previously owned a property" + other: "Buyers previously owned a property" + stairowned: + one: "Percentage the buyer now owns in total" + other: "Percentage the buyers now own in total" + offered: "Times previously offered since becoming available" warnings: location: diff --git a/config/rent_range_data/2023.csv b/config/rent_range_data/2023.csv new file mode 100644 index 000000000..5a0d9858f --- /dev/null +++ b/config/rent_range_data/2023.csv @@ -0,0 +1,7401 @@ +ranges_rent_id,lettype,la,beds,soft_min,soft_max,hard_min,hard_max +1,1,E07000223,1,57.21,123.09,25.84,176.15 +327,1,E07000223,2,71.06,146.43,25.84,186.77 +653,1,E07000223,3,81.2,161.3,25.84,203.75 +979,1,E07000223,4,89.52,178.28,25.84,221.77 +2609,2,E07000223,0,62.17,268.13,18.64,344.4 +1305,3,E07000223,1,51.68,115.66,25.84,159.17 +1631,3,E07000223,2,62.75,129.46,25.84,145.37 +1957,3,E07000223,3,68.28,149.62,25.84,185.7 +2283,3,E07000223,4,72.9,184.64,25.84,194.19 +2935,4,E07000223,0,48.71,195.45,18.64,204.96 +3983,5,E07000223,1,57.21,130.52,25.84,143.25 +4598,5,E07000223,2,71.06,181.46,25.84,198.45 +5250,5,E07000223,3,81.2,226.01,25.84,246.18 +5935,5,E07000223,4,89.52,426.59,25.84,465.84 +3261,6,E07000223,0,62.17,492.18,18.64,536.27 +4050,7,E07000223,1,51.68,130.52,25.84,143.25 +4745,7,E07000223,2,62.75,181.46,25.84,198.45 +5350,7,E07000223,3,68.28,226.01,25.84,246.18 +6039,7,E07000223,4,72.9,426.59,25.84,465.84 +3587,8,E07000223,0,48.71,492.18,18.64,536.27 +6521,9,E07000223,1,57.21,163.15,25.84,179.06 +6847,9,E07000223,2,71.06,226.84,25.84,248.03 +7173,9,E07000223,3,81.2,282.54,25.84,307.73 +7499,9,E07000223,4,89.52,533.22,25.84,582.31 +7825,10,E07000223,0,62.17,493.08,18.64,537.76 +3,1,E07000032,1,51.68,99.75,25.84,122.03 +329,1,E07000032,2,61.83,114.6,25.84,129.46 +655,1,E07000032,3,68.28,126.28,25.84,137.95 +981,1,E07000032,4,75.67,158.1,25.84,166.61 +2611,2,E07000032,0,51.82,240.72,18.64,361.1 +1307,3,E07000032,1,46.13,90.21,25.84,107.19 +1633,3,E07000032,2,52.6,96.56,25.84,108.24 +1959,3,E07000032,3,58.13,104,25.84,118.85 +2285,3,E07000032,4,63.67,122.03,25.84,122.03 +2937,4,E07000032,0,49.74,114.39,18.64,123.94 +4311,5,E07000032,1,51.68,96.56,25.84,105.06 +5007,5,E07000032,2,61.83,113.53,25.84,123.09 +5650,5,E07000032,3,68.28,134.77,25.84,147.5 +6225,5,E07000032,4,75.67,186.77,25.84,203.75 +3263,6,E07000032,0,51.82,209.73,18.64,228.81 +4411,7,E07000032,1,46.13,96.56,25.84,105.06 +5147,7,E07000032,2,52.6,113.53,25.84,123.09 +5808,7,E07000032,3,58.13,134.77,25.84,147.5 +6469,7,E07000032,4,63.67,186.77,25.84,203.75 +3589,8,E07000032,0,49.74,209.73,18.64,228.81 +6523,9,E07000032,1,51.68,120.73,25.84,131.32 +6849,9,E07000032,2,61.83,141.94,25.84,153.86 +7175,9,E07000032,3,68.28,168.46,25.84,184.37 +7501,9,E07000032,4,75.67,233.46,25.84,254.69 +7827,10,E07000032,0,51.82,269.62,18.64,294.95 +4,1,E07000224,1,57.21,123.09,25.84,176.15 +330,1,E07000224,2,71.06,146.43,25.84,186.77 +656,1,E07000224,3,81.2,161.3,25.84,203.75 +982,1,E07000224,4,89.52,178.28,25.84,221.77 +2612,2,E07000224,0,62.17,268.13,18.64,344.4 +1308,3,E07000224,1,51.68,115.66,25.84,159.17 +1634,3,E07000224,2,62.75,129.46,25.84,145.37 +1960,3,E07000224,3,68.28,149.62,25.84,185.7 +2286,3,E07000224,4,72.9,184.64,25.84,194.19 +2938,4,E07000224,0,48.71,195.45,18.64,204.96 +3984,5,E07000224,1,57.21,125.22,25.84,136.89 +4599,5,E07000224,2,71.06,170.85,25.84,185.7 +5251,5,E07000224,3,81.2,209.06,25.84,228.14 +5936,5,E07000224,4,89.52,337.44,25.84,368.22 +3264,6,E07000224,0,62.17,378.95,18.64,413.53 +4051,7,E07000224,1,51.68,125.22,25.84,136.89 +4746,7,E07000224,2,62.75,170.85,25.84,185.7 +5351,7,E07000224,3,68.28,209.06,25.84,228.14 +6040,7,E07000224,4,72.9,337.44,25.84,368.22 +3590,8,E07000224,0,48.71,378.95,18.64,413.53 +6524,9,E07000224,1,57.21,156.51,25.84,171.11 +6850,9,E07000224,2,71.06,213.57,25.84,232.15 +7176,9,E07000224,3,81.2,261.31,25.84,285.19 +7502,9,E07000224,4,89.52,421.8,25.84,460.26 +7828,10,E07000224,0,62.17,269.62,18.64,294.95 +5,1,E07000170,1,51.68,99.75,25.84,122.03 +331,1,E07000170,2,61.83,114.6,25.84,129.46 +657,1,E07000170,3,68.28,126.28,25.84,137.95 +983,1,E07000170,4,75.67,158.1,25.84,166.61 +2613,2,E07000170,0,51.82,240.72,18.64,361.1 +1309,3,E07000170,1,46.13,90.21,25.84,107.19 +1635,3,E07000170,2,52.6,96.56,25.84,108.24 +1961,3,E07000170,3,58.13,104,25.84,118.85 +2287,3,E07000170,4,63.67,122.03,25.84,122.03 +2939,4,E07000170,0,49.74,114.39,18.64,123.94 +4312,5,E07000170,1,51.68,87.01,25.84,94.47 +5008,5,E07000170,2,61.83,109.29,25.84,118.85 +5651,5,E07000170,3,68.28,125.22,25.84,136.89 +6226,5,E07000170,4,75.67,178.28,25.84,193.13 +3265,6,E07000170,0,51.82,200.21,18.64,216.88 +4412,7,E07000170,1,46.13,87.01,25.84,94.47 +5148,7,E07000170,2,52.6,109.29,25.84,118.85 +5809,7,E07000170,3,58.13,125.22,25.84,136.89 +6470,7,E07000170,4,63.67,178.28,25.84,193.13 +3591,8,E07000170,0,49.74,200.21,18.64,216.88 +6525,9,E07000170,1,51.68,108.78,25.84,118.06 +6851,9,E07000170,2,61.83,136.63,25.84,148.56 +7177,9,E07000170,3,68.28,156.51,25.84,171.11 +7503,9,E07000170,4,75.67,222.85,25.84,241.41 +7829,10,E07000170,0,51.82,348.6,18.64,379.86 +6,1,E07000105,1,57.21,123.09,25.84,176.15 +332,1,E07000105,2,71.06,146.43,25.84,186.77 +658,1,E07000105,3,81.2,161.3,25.84,203.75 +984,1,E07000105,4,89.52,178.28,25.84,221.77 +2614,2,E07000105,0,62.17,268.13,18.64,344.4 +1310,3,E07000105,1,51.68,115.66,25.84,159.17 +1636,3,E07000105,2,62.75,129.46,25.84,145.37 +1962,3,E07000105,3,68.28,149.62,25.84,185.7 +2288,3,E07000105,4,72.9,184.64,25.84,194.19 +2940,4,E07000105,0,48.71,195.45,18.64,204.96 +3985,5,E07000105,1,57.21,125.22,25.84,136.89 +4600,5,E07000105,2,71.06,153.86,25.84,167.67 +5252,5,E07000105,3,81.2,186.77,25.84,203.75 +5937,5,E07000105,4,89.52,275.9,25.84,301.37 +3266,6,E07000105,0,62.17,309.83,18.64,338.45 +4052,7,E07000105,1,51.68,125.22,25.84,136.89 +4747,7,E07000105,2,62.75,153.86,25.84,167.67 +5352,7,E07000105,3,68.28,186.77,25.84,203.75 +6041,7,E07000105,4,72.9,275.9,25.84,301.37 +3592,8,E07000105,0,48.71,309.83,18.64,338.45 +6526,9,E07000105,1,57.21,156.51,25.84,171.11 +6852,9,E07000105,2,71.06,192.33,25.84,209.57 +7178,9,E07000105,3,81.2,233.46,25.84,254.69 +7504,9,E07000105,4,89.52,344.89,25.84,376.72 +7830,10,E07000105,0,62.17,408.19,18.64,445.42 +8,1,E07000200,1,54.44,118.85,25.84,148.56 +334,1,E07000200,2,64.59,142.18,25.84,167.67 +660,1,E07000200,3,71.06,155.98,25.84,180.4 +986,1,E07000200,4,81.2,170.85,25.84,178.28 +2616,2,E07000200,0,36.26,226.42,18.64,423.05 +1312,3,E07000200,1,49.84,99.75,25.84,131.58 +1638,3,E07000200,2,58.13,117.78,25.84,132.64 +1964,3,E07000200,3,63.67,130.52,25.84,143.25 +2290,3,E07000200,4,71.06,148.56,25.84,159.17 +2942,4,E07000200,0,55.97,135.86,18.64,318.19 +4117,5,E07000200,1,54.44,114.6,25.84,124.15 +4698,5,E07000200,2,64.59,142.18,25.84,154.93 +5417,5,E07000200,3,71.06,170.85,25.84,185.7 +6127,5,E07000200,4,81.2,316.23,25.84,344.88 +3268,6,E07000200,0,36.26,355.12,18.64,387.3 +4234,7,E07000200,1,49.84,114.6,25.84,124.15 +4960,7,E07000200,2,58.13,142.18,25.84,154.93 +5603,7,E07000200,3,63.67,170.85,25.84,185.7 +6265,7,E07000200,4,71.06,316.23,25.84,344.88 +3594,8,E07000200,0,55.97,355.12,18.64,387.3 +6528,9,E07000200,1,54.44,143.25,25.84,155.2 +6854,9,E07000200,2,64.59,177.73,25.84,193.64 +7180,9,E07000200,3,71.06,213.57,25.84,232.15 +7506,9,E07000200,4,81.2,395.3,25.84,431.1 +7832,10,E07000200,0,36.26,300.91,18.64,329.21 +9,1,E09000002,1,65.51,145.37,25.84,197.39 +335,1,E09000002,2,77.51,157.04,25.84,192.07 +661,1,E09000002,3,83.97,166.61,25.84,226.01 +987,1,E09000002,4,101.48,186.77,25.84,251.49 +2617,2,E09000002,0,70.47,317,18.64,502.91 +1313,3,E09000002,1,58.13,118.85,25.84,146.43 +1639,3,E09000002,2,63.67,139.02,25.84,175.09 +1965,3,E09000002,3,71.06,159.17,25.84,200.55 +2291,3,E09000002,4,83.05,259.98,25.84,261.04 +2943,4,E09000002,0,60.1,371.82,18.64,402.8 +3950,5,E09000002,1,65.51,160.24,25.84,175.09 +4565,5,E09000002,2,77.51,203.75,25.84,220.72 +5217,5,E09000002,3,83.97,248.31,25.84,270.61 +5902,5,E09000002,4,101.48,304.55,25.84,332.14 +3269,6,E09000002,0,70.47,342.01,18.64,373.01 +4164,7,E09000002,1,58.13,160.24,25.84,175.09 +4665,7,E09000002,2,63.67,203.75,25.84,220.72 +5317,7,E09000002,3,71.06,248.31,25.84,270.61 +5869,7,E09000002,4,83.05,304.55,25.84,332.14 +3595,8,E09000002,0,60.1,342.01,18.64,373.01 +6529,9,E09000002,1,65.51,200.32,25.84,218.87 +6855,9,E09000002,2,77.51,254.69,25.84,275.9 +7181,9,E09000002,3,83.97,310.37,25.84,338.25 +7507,9,E09000002,4,101.48,380.68,25.84,415.17 +7833,10,E09000002,0,70.47,239.85,18.64,260.68 +10,1,E09000003,1,65.51,145.37,25.84,197.39 +336,1,E09000003,2,77.51,157.04,25.84,192.07 +662,1,E09000003,3,83.97,166.61,25.84,226.01 +988,1,E09000003,4,101.48,186.77,25.84,251.49 +2618,2,E09000003,0,70.47,317,18.64,502.91 +1314,3,E09000003,1,58.13,118.85,25.84,146.43 +1640,3,E09000003,2,63.67,139.02,25.84,175.09 +1966,3,E09000003,3,71.06,159.17,25.84,200.55 +2292,3,E09000003,4,83.05,259.98,25.84,261.04 +2944,4,E09000003,0,60.1,371.82,18.64,402.8 +3951,5,E09000003,1,65.51,235.58,25.84,256.8 +4566,5,E09000003,2,77.51,302.42,25.84,330.01 +5218,5,E09000003,3,83.97,414.92,25.84,452.05 +5903,5,E09000003,4,101.48,755.54,25.84,824.52 +3270,6,E09000003,0,70.47,847.34,18.64,925.97 +4165,7,E09000003,1,58.13,235.58,25.84,256.8 +4666,7,E09000003,2,63.67,302.42,25.84,330.01 +5318,7,E09000003,3,71.06,414.92,25.84,452.05 +5870,7,E09000003,4,83.05,755.54,25.84,824.52 +3596,8,E09000003,0,60.1,847.34,18.64,925.97 +6530,9,E09000003,1,65.51,294.49,25.84,320.99 +6856,9,E09000003,2,77.51,378.03,25.84,412.53 +7182,9,E09000003,3,83.97,518.65,25.84,565.05 +7508,9,E09000003,4,101.48,944.43,25.84,1030.66 +7834,10,E09000003,0,70.47,598.84,18.64,653.96 +11,1,E08000016,1,50.76,91.27,25.84,113.53 +337,1,E08000016,2,58.13,108.24,25.84,140.08 +663,1,E08000016,3,62.75,119.9,25.84,161.3 +989,1,E08000016,4,72.9,144.31,25.84,178.28 +2619,2,E08000016,0,52.86,234.75,18.64,322.95 +1315,3,E08000016,1,46.13,81.71,25.84,92.33 +1641,3,E08000016,2,52.6,112.47,25.84,144.31 +1967,3,E08000016,3,56.29,104,25.84,113.53 +2293,3,E08000016,4,63.67,120.97,25.84,175.09 +2945,4,E08000016,0,51.82,160.88,18.64,190.67 +4390,5,E08000016,1,50.76,84.89,25.84,92.33 +4870,5,E08000016,2,58.13,97.63,25.84,107.19 +5501,5,E08000016,3,62.75,114.6,25.84,124.15 +6106,5,E08000016,4,72.9,170.85,25.84,185.7 +3271,6,E08000016,0,52.86,191.88,18.64,208.55 +4544,7,E08000016,1,46.13,84.89,25.84,92.33 +4812,7,E08000016,2,52.6,97.63,25.84,107.19 +5848,7,E08000016,3,56.29,114.6,25.84,124.15 +6204,7,E08000016,4,63.67,170.85,25.84,185.7 +3597,8,E08000016,0,51.82,191.88,18.64,208.55 +6531,9,E08000016,1,50.76,106.13,25.84,115.39 +6857,9,E08000016,2,52.6,122.03,25.84,133.98 +7183,9,E08000016,3,62.75,143.25,25.84,155.2 +7509,9,E08000016,4,72.9,213.57,25.84,232.15 +7835,10,E08000016,0,52.86,945.92,18.64,1030.84 +13,1,E07000066,1,54.44,118.85,25.84,148.56 +339,1,E07000066,2,64.59,142.18,25.84,167.67 +665,1,E07000066,3,71.06,155.98,25.84,180.4 +991,1,E07000066,4,81.2,170.85,25.84,178.28 +2621,2,E07000066,0,36.26,226.42,18.64,423.05 +1317,3,E07000066,1,49.84,99.75,25.84,131.58 +1643,3,E07000066,2,58.13,117.78,25.84,132.64 +1969,3,E07000066,3,63.67,130.52,25.84,143.25 +2295,3,E07000066,4,71.06,148.56,25.84,159.17 +2947,4,E07000066,0,55.97,135.86,18.64,318.19 +4118,5,E07000066,1,54.44,142.18,25.84,154.93 +4699,5,E07000066,2,64.59,180.4,25.84,197.39 +5418,5,E07000066,3,71.06,219.66,25.84,239.83 +6128,5,E07000066,4,81.2,359.73,25.84,392.62 +3273,6,E07000066,0,36.26,403.99,18.64,440.94 +4235,7,E07000066,1,49.84,142.18,25.84,154.93 +4961,7,E07000066,2,58.13,180.4,25.84,197.39 +5604,7,E07000066,3,63.67,219.66,25.84,239.83 +6266,7,E07000066,4,71.06,359.73,25.84,392.62 +3599,8,E07000066,0,55.97,403.99,18.64,440.94 +6533,9,E07000066,1,54.44,177.73,25.84,193.64 +6859,9,E07000066,2,64.59,225.52,25.84,246.73 +7185,9,E07000066,3,71.06,274.57,25.84,299.78 +7511,9,E07000066,4,81.2,449.67,25.84,490.79 +7837,10,E07000066,0,36.26,269.62,18.64,294.95 +14,1,E07000084,1,57.21,123.09,25.84,176.15 +340,1,E07000084,2,71.06,146.43,25.84,186.77 +666,1,E07000084,3,81.2,161.3,25.84,203.75 +992,1,E07000084,4,89.52,178.28,25.84,221.77 +2622,2,E07000084,0,62.17,268.13,18.64,344.4 +1318,3,E07000084,1,51.68,115.66,25.84,159.17 +1644,3,E07000084,2,62.75,129.46,25.84,145.37 +1970,3,E07000084,3,68.28,149.62,25.84,185.7 +2296,3,E07000084,4,72.9,184.64,25.84,194.19 +2948,4,E07000084,0,48.71,195.45,18.64,204.96 +3987,5,E07000084,1,57.21,147.5,25.84,160.24 +4602,5,E07000084,2,71.06,181.46,25.84,198.45 +5254,5,E07000084,3,81.2,209.06,25.84,228.14 +5939,5,E07000084,4,89.52,337.44,25.84,368.22 +3274,6,E07000084,0,62.17,378.95,18.64,413.53 +4054,7,E07000084,1,51.68,147.5,25.84,160.24 +4749,7,E07000084,2,62.75,181.46,25.84,198.45 +5354,7,E07000084,3,68.28,209.06,25.84,228.14 +6043,7,E07000084,4,72.9,337.44,25.84,368.22 +3600,8,E07000084,0,48.71,378.95,18.64,413.53 +6534,9,E07000084,1,57.21,184.37,25.84,200.32 +6860,9,E07000084,2,71.06,226.84,25.84,248.03 +7186,9,E07000084,3,81.2,261.31,25.84,285.19 +7512,9,E07000084,4,89.52,421.8,25.84,460.26 +7838,10,E07000084,0,62.17,1071.07,18.64,1167.89 +15,1,E07000171,1,51.68,99.75,25.84,122.03 +341,1,E07000171,2,61.83,114.6,25.84,129.46 +667,1,E07000171,3,68.28,126.28,25.84,137.95 +993,1,E07000171,4,75.67,158.1,25.84,166.61 +2623,2,E07000171,0,51.82,240.72,18.64,361.1 +1319,3,E07000171,1,46.13,90.21,25.84,107.19 +1645,3,E07000171,2,52.6,96.56,25.84,108.24 +1971,3,E07000171,3,58.13,104,25.84,118.85 +2297,3,E07000171,4,63.67,122.03,25.84,122.03 +2949,4,E07000171,0,49.74,114.39,18.64,123.94 +4313,5,E07000171,1,51.68,84.89,25.84,92.33 +5009,5,E07000171,2,61.83,105.06,25.84,114.6 +5652,5,E07000171,3,68.28,125.22,25.84,136.89 +6227,5,E07000171,4,75.67,180.4,25.84,197.39 +3275,6,E07000171,0,51.82,202.58,18.64,221.66 +4413,7,E07000171,1,46.13,84.89,25.84,92.33 +5149,7,E07000171,2,52.6,105.06,25.84,114.6 +5810,7,E07000171,3,58.13,125.22,25.84,136.89 +6471,7,E07000171,4,63.67,180.4,25.84,197.39 +3601,8,E07000171,0,49.74,202.58,18.64,221.66 +6535,9,E07000171,1,51.68,106.13,25.84,115.39 +6861,9,E07000171,2,61.83,131.32,25.84,143.25 +7187,9,E07000171,3,68.28,156.51,25.84,171.11 +7513,9,E07000171,4,75.67,225.52,25.84,246.73 +7839,10,E07000171,0,51.82,591.38,18.64,645.02 +16,1,E06000022,1,48.92,107.19,25.84,140.08 +342,1,E06000022,2,55.37,120.97,25.84,144.31 +668,1,E06000022,3,61.83,141.13,25.84,161.3 +994,1,E06000022,4,71.06,158.1,25.84,194.19 +2624,2,E06000022,0,54.93,231.2,18.64,358.7 +1320,3,E06000022,1,47.06,89.13,25.84,210.12 +1646,3,E06000022,2,54.44,100.81,25.84,111.41 +1972,3,E06000022,3,61.83,109.29,25.84,126.28 +2298,3,E06000022,4,73.82,130.52,25.84,130.52 +2950,4,E06000022,0,54.93,115.59,18.64,141.81 +4197,5,E06000022,1,48.92,153.86,25.84,167.67 +4833,5,E06000022,2,55.37,192.07,25.84,210.12 +5464,5,E06000022,3,61.83,232.39,25.84,252.55 +6002,5,E06000022,4,71.06,388.39,25.84,423.41 +3276,6,E06000022,0,54.93,436.17,18.64,475.49 +3913,7,E06000022,1,47.06,153.86,25.84,167.67 +5110,7,E06000022,2,54.44,192.07,25.84,210.12 +5690,7,E06000022,3,61.83,232.39,25.84,252.55 +6402,7,E06000022,4,73.82,388.39,25.84,423.41 +3602,8,E06000022,0,54.93,436.17,18.64,475.49 +6536,9,E06000022,1,48.92,192.33,25.84,209.57 +6862,9,E06000022,2,55.37,240.08,25.84,262.64 +7188,9,E06000022,3,61.83,290.5,25.84,315.69 +7514,9,E06000022,4,71.06,485.5,25.84,529.26 +7840,10,E06000022,0,54.93,411.13,18.64,448.39 +17,1,E06000055,1,54.44,118.85,25.84,148.56 +343,1,E06000055,2,64.59,142.18,25.84,167.67 +669,1,E06000055,3,71.06,155.98,25.84,180.4 +995,1,E06000055,4,81.2,170.85,25.84,178.28 +2625,2,E06000055,0,36.26,226.42,18.64,423.05 +1321,3,E06000055,1,49.84,99.75,25.84,131.58 +1647,3,E06000055,2,58.13,117.78,25.84,132.64 +1973,3,E06000055,3,63.67,130.52,25.84,143.25 +2299,3,E06000055,4,71.06,148.56,25.84,159.17 +2951,4,E06000055,0,55.97,135.86,18.64,318.19 +4119,5,E06000055,1,54.44,113.53,25.84,123.09 +4700,5,E06000055,2,64.59,142.18,25.84,154.93 +5419,5,E06000055,3,71.06,170.85,25.84,185.7 +6129,5,E06000055,4,81.2,281.2,25.84,306.68 +3277,6,E06000055,0,36.26,315.82,18.64,344.4 +4236,7,E06000055,1,49.84,113.53,25.84,123.09 +4962,7,E06000055,2,58.13,142.18,25.84,154.93 +5605,7,E06000055,3,63.67,170.85,25.84,185.7 +6267,7,E06000055,4,71.06,281.2,25.84,306.68 +3603,8,E06000055,0,55.97,315.82,18.64,344.4 +6537,9,E06000055,1,54.44,141.94,25.84,153.86 +6863,9,E06000055,2,64.59,177.73,25.84,193.64 +7189,9,E06000055,3,71.06,213.57,25.84,232.15 +7515,9,E06000055,4,81.2,351.51,25.84,383.34 +7841,10,E06000055,0,36.26,254.72,18.64,278.57 +18,1,E09000004,1,65.51,145.37,25.84,197.39 +344,1,E09000004,2,77.51,157.04,25.84,192.07 +670,1,E09000004,3,83.97,166.61,25.84,226.01 +996,1,E09000004,4,101.48,186.77,25.84,251.49 +2626,2,E09000004,0,70.47,317,18.64,502.91 +1322,3,E09000004,1,58.13,118.85,25.84,146.43 +1648,3,E09000004,2,63.67,139.02,25.84,175.09 +1974,3,E09000004,3,71.06,159.17,25.84,200.55 +2300,3,E09000004,4,83.05,259.98,25.84,261.04 +2952,4,E09000004,0,60.1,371.82,18.64,402.8 +3952,5,E09000004,1,65.51,157.04,25.84,172.97 +4567,5,E09000004,2,77.51,192.07,25.84,210.12 +5219,5,E09000004,3,83.97,248.31,25.84,270.61 +5904,5,E09000004,4,101.48,337.44,25.84,368.22 +3278,6,E09000004,0,70.47,378.95,18.64,413.53 +4166,7,E09000004,1,58.13,157.04,25.84,172.97 +4667,7,E09000004,2,63.67,192.07,25.84,210.12 +5319,7,E09000004,3,71.06,248.31,25.84,270.61 +5871,7,E09000004,4,83.05,337.44,25.84,368.22 +3604,8,E09000004,0,60.1,378.95,18.64,413.53 +6538,9,E09000004,1,65.51,196.32,25.84,216.2 +6864,9,E09000004,2,77.51,240.08,25.84,262.64 +7190,9,E09000004,3,83.97,310.37,25.84,338.25 +7516,9,E09000004,4,101.48,421.8,25.84,460.26 +7842,10,E09000004,0,70.47,3164.04,18.64,3451.52 +19,1,E08000025,1,52.6,98.69,25.84,124.15 +345,1,E08000025,2,58.13,116.72,25.84,136.89 +671,1,E08000025,3,69.2,132.64,25.84,160.24 +997,1,E08000025,4,80.28,161.3,25.84,178.28 +2627,2,E08000025,0,39.38,245.49,18.64,382.53 +1323,3,E08000025,1,46.13,88.07,25.84,97.63 +1649,3,E08000025,2,49.84,94.47,25.84,102.94 +1975,3,E08000025,3,59.98,104,25.84,119.9 +2301,3,E08000025,4,68.28,127.34,25.84,127.34 +2953,4,E08000025,0,46.63,107.26,18.64,107.26 +4281,5,E08000025,1,52.6,114.6,25.84,124.15 +4891,5,E08000025,2,58.13,140.08,25.84,151.75 +5522,5,E08000025,3,69.2,147.5,25.84,160.24 +6174,5,E08000025,4,80.28,226.01,25.84,245.12 +3279,6,E08000025,0,39.38,251.45,18.64,275.3 +4502,7,E08000025,1,46.13,114.6,25.84,124.15 +5187,7,E08000025,2,49.84,140.08,25.84,151.75 +5778,7,E08000025,3,59.98,147.5,25.84,160.24 +6439,7,E08000025,4,68.28,226.01,25.84,245.12 +3605,8,E08000025,0,46.63,251.45,18.64,275.3 +6539,9,E08000025,1,52.6,143.25,25.84,155.2 +6865,9,E08000025,2,58.13,175.09,25.84,189.68 +7191,9,E08000025,3,69.2,184.37,25.84,200.32 +7517,9,E08000025,4,80.28,282.54,25.84,306.4 +7843,10,E08000025,0,39.38,466.26,18.64,507.97 +20,1,E07000129,1,51.68,99.75,25.84,122.03 +346,1,E07000129,2,61.83,114.6,25.84,129.46 +672,1,E07000129,3,68.28,126.28,25.84,137.95 +998,1,E07000129,4,75.67,158.1,25.84,166.61 +2628,2,E07000129,0,51.82,240.72,18.64,361.1 +1324,3,E07000129,1,46.13,90.21,25.84,107.19 +1650,3,E07000129,2,52.6,96.56,25.84,108.24 +1976,3,E07000129,3,58.13,104,25.84,118.85 +2302,3,E07000129,4,63.67,122.03,25.84,122.03 +2954,4,E07000129,0,49.74,114.39,18.64,123.94 +4314,5,E07000129,1,51.68,109.29,25.84,118.85 +5010,5,E07000129,2,61.83,125.22,25.84,136.89 +5653,5,E07000129,3,68.28,149.62,25.84,162.37 +6228,5,E07000129,4,75.67,202.69,25.84,220.72 +3280,6,E07000129,0,51.82,227.63,18.64,247.88 +4414,7,E07000129,1,46.13,109.29,25.84,118.85 +5150,7,E07000129,2,52.6,125.22,25.84,136.89 +5811,7,E07000129,3,58.13,149.62,25.84,162.37 +6472,7,E07000129,4,63.67,202.69,25.84,220.72 +3606,8,E07000129,0,49.74,227.63,18.64,247.88 +6540,9,E07000129,1,51.68,136.63,25.84,148.56 +6866,9,E07000129,2,61.83,156.51,25.84,171.11 +7192,9,E07000129,3,68.28,187.02,25.84,202.95 +7518,9,E07000129,4,75.67,253.36,25.84,275.9 +7844,10,E07000129,0,51.82,560.11,18.64,612.24 +21,1,E06000008,1,51.68,93.39,25.84,116.72 +347,1,E06000008,2,59.06,107.19,25.84,134.77 +673,1,E06000008,3,65.51,119.9,25.84,145.37 +999,1,E06000008,4,71.98,133.71,25.84,159.17 +2629,2,E06000008,0,55.97,239.54,18.64,342.01 +1325,3,E06000008,1,43.36,85.94,25.84,100.81 +1651,3,E06000008,2,53.52,94.47,25.84,113.53 +1977,3,E06000008,3,58.13,105.06,25.84,124.15 +2303,3,E06000008,4,55.37,118.85,25.84,133.71 +2955,4,E06000008,0,33.16,469.54,18.64,599.44 +4353,5,E06000008,1,51.68,102.94,25.84,112.47 +4923,5,E06000008,2,59.06,109.29,25.84,118.85 +5566,5,E06000008,3,65.51,130.52,25.84,143.25 +6314,5,E06000008,4,71.98,170.85,25.84,185.7 +3281,6,E06000008,0,55.97,191.88,18.64,208.55 +4465,7,E06000008,1,43.36,102.94,25.84,112.47 +5061,7,E06000008,2,53.52,109.29,25.84,118.85 +5741,7,E06000008,3,58.13,130.52,25.84,143.25 +6365,7,E06000008,4,55.37,170.85,25.84,185.7 +3607,8,E06000008,0,33.16,191.88,18.64,208.55 +6541,9,E06000008,1,51.68,128.67,25.84,140.6 +6867,9,E06000008,2,59.06,136.63,25.84,148.56 +7193,9,E06000008,3,65.51,163.15,25.84,179.06 +7519,9,E06000008,4,71.98,213.57,25.84,232.15 +7845,10,E06000008,0,55.97,269.62,18.64,294.95 +22,1,E06000009,1,51.68,93.39,25.84,116.72 +348,1,E06000009,2,59.06,107.19,25.84,134.77 +674,1,E06000009,3,65.51,119.9,25.84,145.37 +1000,1,E06000009,4,71.98,133.71,25.84,159.17 +2630,2,E06000009,0,55.97,239.54,18.64,342.01 +1326,3,E06000009,1,43.36,85.94,25.84,100.81 +1652,3,E06000009,2,53.52,94.47,25.84,113.53 +1978,3,E06000009,3,58.13,105.06,25.84,124.15 +2304,3,E06000009,4,55.37,118.85,25.84,133.71 +2956,4,E06000009,0,33.16,469.54,18.64,599.44 +4354,5,E06000009,1,51.68,98.69,25.84,109.29 +4924,5,E06000009,2,59.06,125.22,25.84,136.89 +5567,5,E06000009,3,65.51,143.25,25.84,155.98 +6315,5,E06000009,4,71.98,181.46,25.84,198.45 +3282,6,E06000009,0,55.97,203.78,18.64,222.84 +4466,7,E06000009,1,43.36,98.69,25.84,109.29 +5062,7,E06000009,2,53.52,125.22,25.84,136.89 +5742,7,E06000009,3,58.13,143.25,25.84,155.98 +6366,7,E06000009,4,55.37,181.46,25.84,198.45 +3608,8,E06000009,0,33.16,203.78,18.64,222.84 +6542,9,E06000009,1,51.68,123.35,25.84,136.63 +6868,9,E06000009,2,59.06,156.51,25.84,171.11 +7194,9,E06000009,3,65.51,179.06,25.84,194.98 +7520,9,E06000009,4,71.98,226.84,25.84,248.03 +7846,10,E06000009,0,55.97,300.91,18.64,329.21 +23,1,E07000033,1,51.68,99.75,25.84,122.03 +349,1,E07000033,2,61.83,114.6,25.84,129.46 +675,1,E07000033,3,68.28,126.28,25.84,137.95 +1001,1,E07000033,4,75.67,158.1,25.84,166.61 +2631,2,E07000033,0,51.82,240.72,18.64,361.1 +1327,3,E07000033,1,46.13,90.21,25.84,107.19 +1653,3,E07000033,2,52.6,96.56,25.84,108.24 +1979,3,E07000033,3,58.13,104,25.84,118.85 +2305,3,E07000033,4,63.67,122.03,25.84,122.03 +2957,4,E07000033,0,49.74,114.39,18.64,123.94 +4315,5,E07000033,1,51.68,90.21,25.84,97.63 +5011,5,E07000033,2,61.83,102.94,25.84,112.47 +5654,5,E07000033,3,68.28,119.9,25.84,130.52 +6229,5,E07000033,4,75.67,170.85,25.84,185.7 +3283,6,E07000033,0,51.82,191.88,18.64,208.55 +4415,7,E07000033,1,46.13,90.21,25.84,97.63 +5151,7,E07000033,2,52.6,102.94,25.84,112.47 +5812,7,E07000033,3,58.13,119.9,25.84,130.52 +6473,7,E07000033,4,63.67,170.85,25.84,185.7 +3609,8,E07000033,0,49.74,191.88,18.64,208.55 +6543,9,E07000033,1,51.68,112.76,25.84,122.03 +6869,9,E07000033,2,61.83,128.67,25.84,140.6 +7195,9,E07000033,3,68.28,149.9,25.84,163.15 +7521,9,E07000033,4,75.67,213.57,25.84,232.15 +7847,10,E07000033,0,51.82,308.35,18.64,336.65 +24,1,E08000001,1,51.68,93.39,25.84,116.72 +350,1,E08000001,2,59.06,107.19,25.84,134.77 +676,1,E08000001,3,65.51,119.9,25.84,145.37 +1002,1,E08000001,4,71.98,133.71,25.84,159.17 +2632,2,E08000001,0,55.97,239.54,18.64,342.01 +1328,3,E08000001,1,43.36,85.94,25.84,100.81 +1654,3,E08000001,2,53.52,94.47,25.84,113.53 +1980,3,E08000001,3,58.13,105.06,25.84,124.15 +2306,3,E08000001,4,55.37,118.85,25.84,133.71 +2958,4,E08000001,0,33.16,469.54,18.64,599.44 +4355,5,E08000001,1,51.68,92.33,25.84,99.75 +4925,5,E08000001,2,59.06,110.36,25.84,119.9 +5568,5,E08000001,3,65.51,134.77,25.84,147.5 +6316,5,E08000001,4,71.98,192.07,25.84,210.12 +3284,6,E08000001,0,55.97,215.7,18.64,235.95 +4467,7,E08000001,1,43.36,92.33,25.84,99.75 +5063,7,E08000001,2,53.52,110.36,25.84,119.9 +5743,7,E08000001,3,58.13,134.77,25.84,147.5 +6367,7,E08000001,4,55.37,192.07,25.84,210.12 +3610,8,E08000001,0,33.16,215.7,18.64,235.95 +6544,9,E08000001,1,51.68,115.39,25.84,124.69 +6870,9,E08000001,2,59.06,137.95,25.84,149.9 +7196,9,E08000001,3,65.51,168.46,25.84,184.37 +7522,9,E08000001,4,71.98,240.08,25.84,262.64 +7848,10,E08000001,0,55.97,552.67,18.64,601.83 +25,1,E07000136,1,51.68,99.75,25.84,122.03 +351,1,E07000136,2,61.83,114.6,25.84,129.46 +677,1,E07000136,3,68.28,126.28,25.84,137.95 +1003,1,E07000136,4,75.67,158.1,25.84,166.61 +2633,2,E07000136,0,51.82,240.72,18.64,361.1 +1329,3,E07000136,1,46.13,90.21,25.84,107.19 +1655,3,E07000136,2,52.6,96.56,25.84,108.24 +1981,3,E07000136,3,58.13,104,25.84,118.85 +2307,3,E07000136,4,63.67,122.03,25.84,122.03 +2959,4,E07000136,0,49.74,114.39,18.64,123.94 +4316,5,E07000136,1,51.68,97.63,25.84,107.19 +5012,5,E07000136,2,61.83,119.9,25.84,130.52 +5655,5,E07000136,3,68.28,134.77,25.84,147.5 +6230,5,E07000136,4,75.67,177.21,25.84,192.07 +3285,6,E07000136,0,51.82,199.03,18.64,215.7 +4416,7,E07000136,1,46.13,97.63,25.84,107.19 +5152,7,E07000136,2,52.6,119.9,25.84,130.52 +5813,7,E07000136,3,58.13,134.77,25.84,147.5 +6474,7,E07000136,4,63.67,177.21,25.84,192.07 +3611,8,E07000136,0,49.74,199.03,18.64,215.7 +6545,9,E07000136,1,51.68,122.03,25.84,133.98 +6871,9,E07000136,2,61.83,149.9,25.84,163.15 +7197,9,E07000136,3,68.28,168.46,25.84,184.37 +7523,9,E07000136,4,75.67,221.51,25.84,240.08 +7849,10,E07000136,0,51.82,567.58,18.64,618.2 +59,1,E06000058,1,48.92,107.19,25.84,140.08 +385,1,E06000058,2,55.37,120.97,25.84,144.31 +711,1,E06000058,3,61.83,141.13,25.84,161.3 +1037,1,E06000058,4,71.06,158.1,25.84,194.19 +2667,2,E06000058,0,54.93,231.2,18.64,358.7 +1363,3,E06000058,1,47.06,89.13,25.84,210.12 +1689,3,E06000058,2,54.44,100.81,25.84,111.41 +2015,3,E06000058,3,61.83,109.29,25.84,126.28 +2341,3,E06000058,4,73.82,130.52,25.84,130.52 +2993,4,E06000058,0,54.93,115.59,18.64,141.81 +4201,5,E06000058,1,48.92,136.89,25.84,148.56 +4837,5,E06000058,2,55.37,170.85,25.84,185.7 +5468,5,E06000058,3,61.83,226.01,25.84,245.12 +6006,5,E06000058,4,71.06,359.73,25.84,392.62 +3319,6,E06000058,0,54.93,403.99,18.64,440.94 +3917,7,E06000058,1,47.06,136.89,25.84,148.56 +5114,7,E06000058,2,54.44,170.85,25.84,185.7 +5694,7,E06000058,3,61.83,226.01,25.84,245.12 +6406,7,E06000058,4,73.82,359.73,25.84,392.62 +3645,8,E06000058,0,54.93,403.99,18.64,440.94 +6579,9,E06000058,1,48.92,171.11,25.84,185.69 +6905,9,E06000058,2,55.37,213.57,25.84,232.15 +7231,9,E06000058,3,61.83,282.54,25.84,306.4 +7557,9,E06000058,4,71.06,449.67,25.84,490.79 +7883,10,E06000058,0,54.93,530.31,18.64,578 +27,1,E06000036,1,57.21,123.09,25.84,176.15 +353,1,E06000036,2,71.06,146.43,25.84,186.77 +679,1,E06000036,3,81.2,161.3,25.84,203.75 +1005,1,E06000036,4,89.52,178.28,25.84,221.77 +2635,2,E06000036,0,62.17,268.13,18.64,344.4 +1331,3,E06000036,1,51.68,115.66,25.84,159.17 +1657,3,E06000036,2,62.75,129.46,25.84,145.37 +1983,3,E06000036,3,68.28,149.62,25.84,185.7 +2309,3,E06000036,4,72.9,184.64,25.84,194.19 +2961,4,E06000036,0,48.71,195.45,18.64,204.96 +3988,5,E06000036,1,57.21,157.04,25.84,172.97 +4603,5,E06000036,2,71.06,198.45,25.84,215.41 +5255,5,E06000036,3,81.2,269.54,25.84,293.94 +5940,5,E06000036,4,89.52,494.49,25.84,539.06 +3287,6,E06000036,0,62.17,555.35,18.64,605.39 +4055,7,E06000036,1,51.68,157.04,25.84,172.97 +4750,7,E06000036,2,62.75,198.45,25.84,215.41 +5355,7,E06000036,3,68.28,269.54,25.84,293.94 +6044,7,E06000036,4,72.9,494.49,25.84,539.06 +3613,8,E06000036,0,48.71,555.35,18.64,605.39 +6547,9,E06000036,1,57.21,196.32,25.84,216.2 +6873,9,E06000036,2,71.06,248.03,25.84,269.26 +7199,9,E06000036,3,81.2,336.93,25.84,367.42 +7525,9,E06000036,4,89.52,618.12,25.84,673.83 +7851,10,E06000036,0,62.17,788.01,18.64,858.05 +28,1,E08000032,1,50.76,91.27,25.84,113.53 +354,1,E08000032,2,58.13,108.24,25.84,140.08 +680,1,E08000032,3,62.75,119.9,25.84,161.3 +1006,1,E08000032,4,72.9,144.31,25.84,178.28 +2636,2,E08000032,0,52.86,234.75,18.64,322.95 +1332,3,E08000032,1,46.13,81.71,25.84,92.33 +1658,3,E08000032,2,52.6,112.47,25.84,144.31 +1984,3,E08000032,3,56.29,104,25.84,113.53 +2310,3,E08000032,4,63.67,120.97,25.84,175.09 +2962,4,E08000032,0,51.82,160.88,18.64,190.67 +4391,5,E08000032,1,50.76,97.63,25.84,107.19 +4871,5,E08000032,2,58.13,114.6,25.84,124.15 +5502,5,E08000032,3,62.75,134.77,25.84,147.5 +6107,5,E08000032,4,72.9,186.77,25.84,203.75 +3288,6,E08000032,0,52.86,209.73,18.64,228.81 +4545,7,E08000032,1,46.13,97.63,25.84,107.19 +4813,7,E08000032,2,52.6,114.6,25.84,124.15 +5849,7,E08000032,3,56.29,134.77,25.84,147.5 +6205,7,E08000032,4,63.67,186.77,25.84,203.75 +3614,8,E08000032,0,51.82,209.73,18.64,228.81 +6548,9,E08000032,1,50.76,122.03,25.84,133.98 +6874,9,E08000032,2,52.6,143.25,25.84,155.2 +7200,9,E08000032,3,62.75,168.46,25.84,184.37 +7526,9,E08000032,4,72.9,233.46,25.84,254.69 +7852,10,E08000032,0,52.86,788.01,18.64,858.05 +29,1,E07000067,1,54.44,118.85,25.84,148.56 +355,1,E07000067,2,64.59,142.18,25.84,167.67 +681,1,E07000067,3,71.06,155.98,25.84,180.4 +1007,1,E07000067,4,81.2,170.85,25.84,178.28 +2637,2,E07000067,0,36.26,226.42,18.64,423.05 +1333,3,E07000067,1,49.84,99.75,25.84,131.58 +1659,3,E07000067,2,58.13,117.78,25.84,132.64 +1985,3,E07000067,3,63.67,130.52,25.84,143.25 +2311,3,E07000067,4,71.06,148.56,25.84,159.17 +2963,4,E07000067,0,55.97,135.86,18.64,318.19 +4120,5,E07000067,1,54.44,119.9,25.84,130.52 +4701,5,E07000067,2,64.59,147.5,25.84,160.24 +5420,5,E07000067,3,71.06,181.46,25.84,198.45 +6130,5,E07000067,4,81.2,281.2,25.84,306.68 +3289,6,E07000067,0,36.26,315.82,18.64,344.4 +4237,7,E07000067,1,49.84,119.9,25.84,130.52 +4963,7,E07000067,2,58.13,147.5,25.84,160.24 +5606,7,E07000067,3,63.67,181.46,25.84,198.45 +6268,7,E07000067,4,71.06,281.2,25.84,306.68 +3615,8,E07000067,0,55.97,315.82,18.64,344.4 +6549,9,E07000067,1,54.44,149.9,25.84,163.15 +6875,9,E07000067,2,64.59,184.37,25.84,200.32 +7201,9,E07000067,3,71.06,226.84,25.84,248.03 +7527,9,E07000067,4,81.2,351.51,25.84,383.34 +7853,10,E07000067,0,36.26,473.7,18.64,516.92 +30,1,E07000143,1,54.44,118.85,25.84,148.56 +356,1,E07000143,2,64.59,142.18,25.84,167.67 +682,1,E07000143,3,71.06,155.98,25.84,180.4 +1008,1,E07000143,4,81.2,170.85,25.84,178.28 +2638,2,E07000143,0,36.26,226.42,18.64,423.05 +1334,3,E07000143,1,49.84,99.75,25.84,131.58 +1660,3,E07000143,2,58.13,117.78,25.84,132.64 +1986,3,E07000143,3,63.67,130.52,25.84,143.25 +2312,3,E07000143,4,71.06,148.56,25.84,159.17 +2964,4,E07000143,0,55.97,135.86,18.64,318.19 +4121,5,E07000143,1,54.44,100.81,25.84,110.36 +4702,5,E07000143,2,64.59,125.22,25.84,136.89 +5421,5,E07000143,3,71.06,147.5,25.84,160.24 +6131,5,E07000143,4,81.2,237.69,25.84,258.92 +3290,6,E07000143,0,36.26,266.94,18.64,290.78 +4238,7,E07000143,1,49.84,100.81,25.84,110.36 +4964,7,E07000143,2,58.13,125.22,25.84,136.89 +5607,7,E07000143,3,63.67,147.5,25.84,160.24 +6269,7,E07000143,4,71.06,237.69,25.84,258.92 +3616,8,E07000143,0,55.97,266.94,18.64,290.78 +6550,9,E07000143,1,54.44,126.02,25.84,137.95 +6876,9,E07000143,2,64.59,156.51,25.84,171.11 +7202,9,E07000143,3,71.06,184.37,25.84,200.32 +7528,9,E07000143,4,81.2,297.12,25.84,323.65 +7854,10,E07000143,0,36.26,300.91,18.64,329.21 +31,1,E09000005,1,65.51,145.37,25.84,192.07 +357,1,E09000005,2,77.51,157.04,25.84,197.39 +683,1,E09000005,3,83.97,166.61,25.84,226.01 +1009,1,E09000005,4,101.48,186.77,25.84,251.49 +2639,2,E09000005,0,70.47,317,18.64,502.91 +1335,3,E09000005,1,58.13,118.85,25.84,146.43 +1661,3,E09000005,2,63.67,139.02,25.84,175.09 +1987,3,E09000005,3,71.06,159.17,25.84,200.55 +2313,3,E09000005,4,83.05,259.98,25.84,261.04 +2965,4,E09000005,0,60.1,371.82,18.64,402.8 +3953,5,E09000005,1,65.51,273.78,25.84,298.19 +4568,5,E09000005,2,77.51,355.49,25.84,388.39 +5220,5,E09000005,3,83.97,463.73,25.84,504.06 +5905,5,E09000005,4,101.48,564.54,25.84,615.48 +3291,6,E09000005,0,70.47,633.99,18.64,691.2 +4167,7,E09000005,1,58.13,273.78,25.84,298.19 +4668,7,E09000005,2,63.67,355.49,25.84,388.39 +5320,7,E09000005,3,71.06,463.73,25.84,504.06 +5872,7,E09000005,4,83.05,564.54,25.84,615.48 +3617,8,E09000005,0,60.1,633.99,18.64,691.2 +6551,9,E09000005,1,65.51,342.23,25.84,372.74 +6877,9,E09000005,2,77.51,444.36,25.84,485.5 +7203,9,E09000005,3,83.97,579.66,25.84,630.08 +7529,9,E09000005,4,101.48,705.66,25.84,769.35 +7855,10,E09000005,0,70.47,941.46,18.64,1027.87 +32,1,E07000068,1,54.44,118.85,25.84,148.56 +358,1,E07000068,2,64.59,142.18,25.84,167.67 +684,1,E07000068,3,71.06,155.98,25.84,180.4 +1010,1,E07000068,4,81.2,170.85,25.84,178.28 +2640,2,E07000068,0,36.26,226.42,18.64,423.05 +1336,3,E07000068,1,49.84,99.75,25.84,131.58 +1662,3,E07000068,2,58.13,117.78,25.84,132.64 +1988,3,E07000068,3,63.67,130.52,25.84,143.25 +2314,3,E07000068,4,71.06,148.56,25.84,159.17 +2966,4,E07000068,0,55.97,135.86,18.64,318.19 +4122,5,E07000068,1,54.44,180.4,25.84,197.39 +4703,5,E07000068,2,64.59,223.9,25.84,245.12 +5422,5,E07000068,3,71.06,316.23,25.84,344.88 +6132,5,E07000068,4,81.2,539.06,25.84,587.88 +3292,6,E07000068,0,36.26,605.39,18.64,660.22 +4239,7,E07000068,1,49.84,180.4,25.84,197.39 +4965,7,E07000068,2,58.13,223.9,25.84,245.12 +5608,7,E07000068,3,63.67,316.23,25.84,344.88 +6270,7,E07000068,4,71.06,539.06,25.84,587.88 +3618,8,E07000068,0,55.97,605.39,18.64,660.22 +6552,9,E07000068,1,54.44,225.52,25.84,246.73 +6878,9,E07000068,2,64.59,279.88,25.84,306.4 +7204,9,E07000068,3,71.06,395.3,25.84,431.1 +7530,9,E07000068,4,81.2,673.83,25.84,734.87 +7856,10,E07000068,0,36.26,499.04,18.64,545.21 +33,1,E06000043,1,57.21,123.09,25.84,176.15 +359,1,E06000043,2,71.06,146.43,25.84,186.77 +685,1,E06000043,3,81.2,161.3,25.84,203.75 +1011,1,E06000043,4,89.52,178.28,25.84,221.77 +2641,2,E06000043,0,62.17,268.13,18.64,344.4 +1337,3,E06000043,1,51.68,115.66,25.84,159.17 +1663,3,E06000043,2,62.75,129.46,25.84,145.37 +1989,3,E06000043,3,68.28,149.62,25.84,185.7 +2315,3,E06000043,4,72.9,184.64,25.84,194.19 +2967,4,E06000043,0,48.71,195.45,18.64,204.96 +3989,5,E06000043,1,57.21,176.15,25.84,191.01 +4604,5,E06000043,2,71.06,248.31,25.84,270.61 +5256,5,E06000043,3,81.2,304.55,25.84,332.14 +5941,5,E06000043,4,89.52,449.93,25.84,490.26 +3293,6,E06000043,0,62.17,505.29,18.64,550.58 +4056,7,E06000043,1,51.68,176.15,25.84,191.01 +4751,7,E06000043,2,62.75,248.31,25.84,270.61 +5356,7,E06000043,3,68.28,304.55,25.84,332.14 +6045,7,E06000043,4,72.9,449.93,25.84,490.26 +3619,8,E06000043,0,48.71,505.29,18.64,550.58 +6553,9,E06000043,1,57.21,220.21,25.84,238.77 +6879,9,E06000043,2,71.06,310.37,25.84,338.25 +7205,9,E06000043,3,81.2,380.68,25.84,415.17 +7531,9,E06000043,4,89.52,562.41,25.84,612.82 +7857,10,E06000043,0,62.17,269.62,18.64,294.95 +34,1,E06000023,1,48.92,107.19,25.84,140.08 +360,1,E06000023,2,55.37,120.97,25.84,144.31 +686,1,E06000023,3,61.83,141.13,25.84,161.3 +1012,1,E06000023,4,71.06,158.1,25.84,194.19 +2642,2,E06000023,0,54.93,231.2,18.64,358.7 +1338,3,E06000023,1,47.06,89.13,25.84,210.12 +1664,3,E06000023,2,54.44,100.81,25.84,111.41 +1990,3,E06000023,3,61.83,109.29,25.84,126.28 +2316,3,E06000023,4,73.82,130.52,25.84,130.52 +2968,4,E06000023,0,54.93,115.59,18.64,141.81 +4199,5,E06000023,1,48.92,147.5,25.84,160.24 +4835,5,E06000023,2,55.37,181.46,25.84,198.45 +5466,5,E06000023,3,61.83,226.01,25.84,245.12 +6004,5,E06000023,4,71.06,415.98,25.84,453.12 +3294,6,E06000023,0,54.93,467.14,18.64,508.85 +3915,7,E06000023,1,47.06,147.5,25.84,160.24 +5112,7,E06000023,2,54.44,181.46,25.84,198.45 +5692,7,E06000023,3,61.83,226.01,25.84,245.12 +6404,7,E06000023,4,73.82,415.98,25.84,453.12 +3620,8,E06000023,0,54.93,467.14,18.64,508.85 +6554,9,E06000023,1,48.92,184.37,25.84,200.32 +6880,9,E06000023,2,55.37,226.84,25.84,248.03 +7206,9,E06000023,3,61.83,282.54,25.84,306.4 +7532,9,E06000023,4,71.06,519.97,25.84,566.39 +7858,10,E06000023,0,54.93,269.62,18.64,294.95 +35,1,E07000144,1,54.44,118.85,25.84,148.56 +361,1,E07000144,2,64.59,142.18,25.84,167.67 +687,1,E07000144,3,71.06,155.98,25.84,180.4 +1013,1,E07000144,4,81.2,170.85,25.84,178.28 +2643,2,E07000144,0,36.26,226.42,18.64,423.05 +1339,3,E07000144,1,49.84,99.75,25.84,131.58 +1665,3,E07000144,2,58.13,117.78,25.84,132.64 +1991,3,E07000144,3,63.67,130.52,25.84,143.25 +2317,3,E07000144,4,71.06,148.56,25.84,159.17 +2969,4,E07000144,0,55.97,135.86,18.64,318.19 +4123,5,E07000144,1,54.44,108.24,25.84,117.78 +4704,5,E07000144,2,64.59,130.52,25.84,143.25 +5423,5,E07000144,3,71.06,158.1,25.84,172.97 +6133,5,E07000144,4,81.2,214.35,25.84,234.52 +3295,6,E07000144,0,36.26,240.72,18.64,263.37 +4240,7,E07000144,1,49.84,108.24,25.84,117.78 +4966,7,E07000144,2,58.13,130.52,25.84,143.25 +5609,7,E07000144,3,63.67,158.1,25.84,172.97 +6271,7,E07000144,4,71.06,214.35,25.84,234.52 +3621,8,E07000144,0,55.97,240.72,18.64,263.37 +6555,9,E07000144,1,54.44,135.3,25.84,147.23 +6881,9,E07000144,2,64.59,163.15,25.84,179.06 +7207,9,E07000144,3,71.06,197.62,25.84,216.2 +7533,9,E07000144,4,81.2,267.95,25.84,293.15 +7859,10,E07000144,0,36.26,552.67,18.64,601.83 +36,1,E09000006,1,65.51,145.37,25.84,197.39 +362,1,E09000006,2,77.51,157.04,25.84,192.07 +688,1,E09000006,3,83.97,166.61,25.84,226.01 +1014,1,E09000006,4,101.48,186.77,25.84,251.49 +2644,2,E09000006,0,70.47,317,18.64,502.91 +1340,3,E09000006,1,58.13,118.85,25.84,146.43 +1666,3,E09000006,2,63.67,139.02,25.84,175.09 +1992,3,E09000006,3,71.06,159.17,25.84,200.55 +2318,3,E09000006,4,83.05,259.98,25.84,261.04 +2970,4,E09000006,0,60.1,371.82,18.64,402.8 +3954,5,E09000006,1,65.51,181.46,25.84,198.45 +4569,5,E09000006,2,77.51,237.69,25.84,258.92 +5221,5,E09000006,3,83.97,292.87,25.84,319.41 +5906,5,E09000006,4,101.48,449.93,25.84,490.26 +3296,6,E09000006,0,70.47,505.29,18.64,550.58 +4168,7,E09000006,1,58.13,181.46,25.84,198.45 +4669,7,E09000006,2,63.67,237.69,25.84,258.92 +5321,7,E09000006,3,71.06,292.87,25.84,319.41 +5873,7,E09000006,4,83.05,449.93,25.84,490.26 +3622,8,E09000006,0,60.1,505.29,18.64,550.58 +6556,9,E09000006,1,65.51,226.84,25.84,248.03 +6882,9,E09000006,2,77.51,297.12,25.84,323.65 +7208,9,E09000006,3,83.97,366.11,25.84,399.27 +7534,9,E09000006,4,101.48,562.41,25.84,612.82 +7860,10,E09000006,0,70.47,552.67,18.64,601.83 +37,1,E07000234,1,52.6,98.69,25.84,124.15 +363,1,E07000234,2,58.13,116.72,25.84,136.89 +689,1,E07000234,3,69.2,132.64,25.84,160.24 +1015,1,E07000234,4,80.28,161.3,25.84,178.28 +2645,2,E07000234,0,39.38,245.49,18.64,382.53 +1341,3,E07000234,1,46.13,88.07,25.84,97.63 +1667,3,E07000234,2,49.84,94.47,25.84,102.94 +1993,3,E07000234,3,59.98,104,25.84,119.9 +2319,3,E07000234,4,68.28,127.34,25.84,127.34 +2971,4,E07000234,0,46.63,107.26,18.64,107.26 +4282,5,E07000234,1,52.6,116.72,25.84,127.34 +4892,5,E07000234,2,58.13,134.77,25.84,147.5 +5523,5,E07000234,3,69.2,176.15,25.84,191.01 +6175,5,E07000234,4,80.28,281.2,25.84,306.68 +3297,6,E07000234,0,39.38,315.82,18.64,344.4 +4503,7,E07000234,1,46.13,116.72,25.84,127.34 +5188,7,E07000234,2,49.84,134.77,25.84,147.5 +5779,7,E07000234,3,59.98,176.15,25.84,191.01 +6440,7,E07000234,4,68.28,281.2,25.84,306.68 +3623,8,E07000234,0,46.63,315.82,18.64,344.4 +6557,9,E07000234,1,52.6,145.91,25.84,159.17 +6883,9,E07000234,2,58.13,168.46,25.84,184.37 +7209,9,E07000234,3,69.2,220.21,25.84,238.77 +7535,9,E07000234,4,80.28,351.51,25.84,383.34 +7861,10,E07000234,0,39.38,741.86,18.64,807.38 +38,1,E07000095,1,54.44,118.85,25.84,148.56 +364,1,E07000095,2,64.59,142.18,25.84,167.67 +690,1,E07000095,3,71.06,155.98,25.84,180.4 +1016,1,E07000095,4,81.2,170.85,25.84,178.28 +2646,2,E07000095,0,36.26,226.42,18.64,423.05 +1342,3,E07000095,1,49.84,99.75,25.84,131.58 +1668,3,E07000095,2,58.13,117.78,25.84,132.64 +1994,3,E07000095,3,63.67,130.52,25.84,143.25 +2320,3,E07000095,4,71.06,148.56,25.84,159.17 +2972,4,E07000095,0,55.97,135.86,18.64,318.19 +4124,5,E07000095,1,54.44,153.86,25.84,167.67 +4705,5,E07000095,2,64.59,192.07,25.84,210.12 +5424,5,E07000095,3,71.06,259.98,25.84,282.26 +6134,5,E07000095,4,81.2,414.92,25.84,450.99 +3298,6,E07000095,0,36.26,464.76,18.64,506.47 +4241,7,E07000095,1,49.84,153.86,25.84,167.67 +4967,7,E07000095,2,58.13,192.07,25.84,210.12 +5610,7,E07000095,3,63.67,259.98,25.84,282.26 +6272,7,E07000095,4,71.06,414.92,25.84,450.99 +3624,8,E07000095,0,55.97,464.76,18.64,506.47 +6558,9,E07000095,1,54.44,192.33,25.84,209.57 +6884,9,E07000095,2,64.59,240.08,25.84,262.64 +7210,9,E07000095,3,71.06,324.98,25.84,352.84 +7536,9,E07000095,4,81.2,518.65,25.84,563.74 +7862,10,E07000095,0,36.26,503.5,18.64,549.69 +39,1,E07000172,1,51.68,99.75,25.84,122.03 +365,1,E07000172,2,61.83,114.6,25.84,129.46 +691,1,E07000172,3,68.28,126.28,25.84,137.95 +1017,1,E07000172,4,75.67,158.1,25.84,166.61 +2647,2,E07000172,0,51.82,240.72,18.64,361.1 +1343,3,E07000172,1,46.13,90.21,25.84,107.19 +1669,3,E07000172,2,52.6,96.56,25.84,108.24 +1995,3,E07000172,3,58.13,104,25.84,118.85 +2321,3,E07000172,4,63.67,122.03,25.84,122.03 +2973,4,E07000172,0,49.74,114.39,18.64,123.94 +4317,5,E07000172,1,51.68,102.94,25.84,112.47 +5013,5,E07000172,2,61.83,125.22,25.84,136.89 +5656,5,E07000172,3,68.28,136.89,25.84,148.56 +6231,5,E07000172,4,75.67,196.32,25.84,213.29 +3299,6,E07000172,0,51.82,220.48,18.64,239.54 +4417,7,E07000172,1,46.13,102.94,25.84,112.47 +5153,7,E07000172,2,52.6,125.22,25.84,136.89 +5814,7,E07000172,3,58.13,136.89,25.84,148.56 +6475,7,E07000172,4,63.67,196.32,25.84,213.29 +3625,8,E07000172,0,49.74,220.48,18.64,239.54 +6559,9,E07000172,1,51.68,128.67,25.84,140.6 +6885,9,E07000172,2,61.83,156.51,25.84,171.11 +7211,9,E07000172,3,68.28,171.11,25.84,185.69 +7537,9,E07000172,4,75.67,245.4,25.84,266.62 +7863,10,E07000172,0,51.82,750.78,18.64,819.3 +323,1,E06000060,1,58.37,109.21,26.36,156.29 +649,1,E06000060,2,72.5,129.92,26.36,165.71 +975,1,E06000060,3,82.85,143.11,26.36,180.77 +1301,1,E06000060,4,91.33,158.17,26.36,196.76 +2931,2,E06000060,0,61.06,229.01,18.32,294.16 +1627,3,E06000060,1,52.73,102.61,26.36,141.21 +1953,3,E06000060,2,64.02,114.86,26.36,128.98 +2279,3,E06000060,3,69.67,132.75,26.36,164.76 +2605,3,E06000060,4,74.38,163.82,26.36,172.29 +3257,4,E06000060,0,47.84,166.94,18.32,175.06 +4049,5,E06000060,1,58.37,170.41,26.36,186.42 +4664,5,E06000060,2,72.5,230.66,26.36,250.43 +5316,5,E06000060,3,82.85,329.52,26.36,359.65 +6001,5,E06000060,4,91.33,695.75,26.36,759.78 +3583,6,E06000060,0,61.06,752.21,18.32,821.43 +4116,7,E06000060,1,52.73,170.41,26.36,186.42 +4811,7,E06000060,2,64.02,230.66,26.36,250.43 +5416,7,E06000060,3,69.67,329.52,26.36,359.65 +6105,7,E06000060,4,74.38,695.75,26.36,759.78 +3909,8,E06000060,0,47.84,752.21,18.32,821.43 +6843,9,E06000060,1,58.37,213.01,26.36,233.02 +7169,9,E06000060,2,72.5,288.33,26.36,313.05 +7495,9,E06000060,3,82.85,411.9,26.36,449.56 +7821,9,E06000060,4,91.33,869.7,26.36,949.72 +8147,10,E06000060,0,61.06,269.62,18.64,294.95 +40,1,E07000117,1,51.68,93.39,25.84,116.72 +366,1,E07000117,2,59.06,107.19,25.84,134.77 +692,1,E07000117,3,65.51,119.9,25.84,145.37 +1018,1,E07000117,4,71.98,133.71,25.84,159.17 +2648,2,E07000117,0,55.97,239.54,18.64,342.01 +1344,3,E07000117,1,43.36,85.94,25.84,100.81 +1670,3,E07000117,2,53.52,94.47,25.84,113.53 +1996,3,E07000117,3,58.13,105.06,25.84,124.15 +2322,3,E07000117,4,55.37,118.85,25.84,133.71 +2974,4,E07000117,0,33.16,469.54,18.64,599.44 +4356,5,E07000117,1,51.68,81.71,25.84,88.07 +4926,5,E07000117,2,59.06,97.63,25.84,107.19 +5569,5,E07000117,3,65.51,129.46,25.84,141.13 +6317,5,E07000117,4,71.98,185.7,25.84,202.69 +3300,6,E07000117,0,55.97,207.36,18.64,227.63 +4468,7,E07000117,1,43.36,81.71,25.84,88.07 +5064,7,E07000117,2,53.52,97.63,25.84,107.19 +5744,7,E07000117,3,58.13,129.46,25.84,141.13 +6368,7,E07000117,4,55.37,185.7,25.84,202.69 +3626,8,E07000117,0,33.16,207.36,18.64,227.63 +6560,9,E07000117,1,51.68,102.16,25.84,110.1 +6886,9,E07000117,2,59.06,122.03,25.84,133.98 +7212,9,E07000117,3,65.51,161.83,25.84,176.42 +7538,9,E07000117,4,71.98,232.15,25.84,253.36 +7864,10,E07000117,0,55.97,305.36,18.64,333.68 +41,1,E08000002,1,51.68,93.39,25.84,116.72 +367,1,E08000002,2,59.06,107.19,25.84,134.77 +693,1,E08000002,3,65.51,119.9,25.84,145.37 +1019,1,E08000002,4,71.98,133.71,25.84,159.17 +2649,2,E08000002,0,55.97,239.54,18.64,342.01 +1345,3,E08000002,1,43.36,85.94,25.84,100.81 +1671,3,E08000002,2,53.52,94.47,25.84,113.53 +1997,3,E08000002,3,58.13,105.06,25.84,124.15 +2323,3,E08000002,4,55.37,118.85,25.84,133.71 +2975,4,E08000002,0,33.16,469.54,18.64,599.44 +4357,5,E08000002,1,51.68,97.63,25.84,107.19 +4927,5,E08000002,2,59.06,125.22,25.84,136.89 +5570,5,E08000002,3,65.51,147.5,25.84,160.24 +6318,5,E08000002,4,71.98,203.75,25.84,221.77 +3301,6,E08000002,0,55.97,228.81,18.64,249.07 +4469,7,E08000002,1,43.36,97.63,25.84,107.19 +5065,7,E08000002,2,53.52,125.22,25.84,136.89 +5745,7,E08000002,3,58.13,147.5,25.84,160.24 +6369,7,E08000002,4,55.37,203.75,25.84,221.77 +3627,8,E08000002,0,33.16,228.81,18.64,249.07 +6561,9,E08000002,1,51.68,122.03,25.84,133.98 +6887,9,E08000002,2,59.06,156.51,25.84,171.11 +7213,9,E08000002,3,65.51,184.37,25.84,200.32 +7539,9,E08000002,4,71.98,254.69,25.84,277.23 +7865,10,E08000002,0,55.97,615.22,18.64,670.34 +42,1,E08000033,1,50.76,91.27,25.84,113.53 +368,1,E08000033,2,58.13,108.24,25.84,140.08 +694,1,E08000033,3,62.75,119.9,25.84,161.3 +1020,1,E08000033,4,72.9,144.31,25.84,178.28 +2650,2,E08000033,0,52.86,234.75,18.64,322.95 +1346,3,E08000033,1,46.13,81.71,25.84,92.33 +1672,3,E08000033,2,52.6,112.47,25.84,144.31 +1998,3,E08000033,3,56.29,104,25.84,113.53 +2324,3,E08000033,4,63.67,120.97,25.84,175.09 +2976,4,E08000033,0,51.82,160.88,18.64,190.67 +4392,5,E08000033,1,50.76,97.63,25.84,107.19 +4872,5,E08000033,2,58.13,113.53,25.84,123.09 +5503,5,E08000033,3,62.75,136.89,25.84,148.56 +6108,5,E08000033,4,72.9,202.69,25.84,220.72 +3302,6,E08000033,0,52.86,227.63,18.64,247.88 +4546,7,E08000033,1,46.13,97.63,25.84,107.19 +4814,7,E08000033,2,52.6,113.53,25.84,123.09 +5850,7,E08000033,3,56.29,136.89,25.84,148.56 +6206,7,E08000033,4,63.67,202.69,25.84,220.72 +3628,8,E08000033,0,51.82,227.63,18.64,247.88 +6562,9,E08000033,1,50.76,122.03,25.84,133.98 +6888,9,E08000033,2,52.6,141.94,25.84,153.86 +7214,9,E08000033,3,62.75,171.11,25.84,185.69 +7540,9,E08000033,4,72.9,253.36,25.84,275.9 +7866,10,E08000033,0,52.86,411.13,18.64,448.39 +43,1,E07000008,1,54.44,118.85,25.84,148.56 +369,1,E07000008,2,64.59,142.18,25.84,167.67 +695,1,E07000008,3,71.06,155.98,25.84,180.4 +1021,1,E07000008,4,81.2,170.85,25.84,178.28 +2651,2,E07000008,0,36.26,226.42,18.64,423.05 +1347,3,E07000008,1,49.84,99.75,25.84,131.58 +1673,3,E07000008,2,58.13,117.78,25.84,132.64 +1999,3,E07000008,3,63.67,130.52,25.84,143.25 +2325,3,E07000008,4,71.06,148.56,25.84,159.17 +2977,4,E07000008,0,55.97,135.86,18.64,318.19 +4125,5,E07000008,1,54.44,187.82,25.84,204.81 +4706,5,E07000008,2,64.59,223.9,25.84,245.12 +5425,5,E07000008,3,71.06,259.98,25.84,282.26 +6135,5,E07000008,4,81.2,371.41,25.84,405.36 +3303,6,E07000008,0,36.26,417.11,18.64,455.24 +4242,7,E07000008,1,49.84,187.82,25.84,204.81 +4968,7,E07000008,2,58.13,223.9,25.84,245.12 +5611,7,E07000008,3,63.67,259.98,25.84,282.26 +6273,7,E07000008,4,71.06,371.41,25.84,405.36 +3629,8,E07000008,0,55.97,417.11,18.64,455.24 +6563,9,E07000008,1,54.44,234.77,25.84,256 +6889,9,E07000008,2,64.59,279.88,25.84,306.4 +7215,9,E07000008,3,71.06,324.98,25.84,352.84 +7541,9,E07000008,4,81.2,464.26,25.84,506.71 +7867,10,E07000008,0,36.26,788.01,18.64,858.05 +44,1,E09000007,1,65.51,145.37,25.84,197.39 +370,1,E09000007,2,77.51,157.04,25.84,192.07 +696,1,E09000007,3,83.97,166.61,25.84,226.01 +1022,1,E09000007,4,101.48,186.77,25.84,251.49 +2652,2,E09000007,0,70.47,317,18.64,502.91 +1348,3,E09000007,1,58.13,118.85,25.84,146.43 +1674,3,E09000007,2,63.67,139.02,25.84,175.09 +2000,3,E09000007,3,71.06,159.17,25.84,200.55 +2326,3,E09000007,4,83.05,259.98,25.84,261.04 +2978,4,E09000007,0,60.1,371.82,18.64,402.8 +3955,5,E09000007,1,65.51,365.04,25.84,397.93 +4570,5,E09000007,2,77.51,496.61,25.84,541.18 +5222,5,E09000007,3,83.97,727.96,25.84,794.8 +5907,5,E09000007,4,101.48,1213.96,25.84,1323.25 +3304,6,E09000007,0,70.47,1362.14,18.64,1486.07 +4169,7,E09000007,1,58.13,365.04,25.84,397.93 +4670,7,E09000007,2,63.67,496.61,25.84,541.18 +5322,7,E09000007,3,71.06,727.96,25.84,794.8 +5874,7,E09000007,4,83.05,1213.96,25.84,1323.25 +3630,8,E09000007,0,60.1,1362.14,18.64,1486.07 +6564,9,E09000007,1,65.51,456.3,25.84,497.43 +6890,9,E09000007,2,77.51,620.78,25.84,676.49 +7216,9,E09000007,3,83.97,909.95,25.84,993.49 +7542,9,E09000007,4,101.48,1517.44,25.84,1654.07 +7868,10,E09000007,0,70.47,314.32,18.64,344.12 +45,1,E07000192,1,52.6,98.69,25.84,124.15 +371,1,E07000192,2,58.13,116.72,25.84,136.89 +697,1,E07000192,3,69.2,132.64,25.84,160.24 +1023,1,E07000192,4,80.28,161.3,25.84,178.28 +2653,2,E07000192,0,39.38,245.49,18.64,382.53 +1349,3,E07000192,1,46.13,88.07,25.84,97.63 +1675,3,E07000192,2,49.84,94.47,25.84,102.94 +2001,3,E07000192,3,59.98,104,25.84,119.9 +2327,3,E07000192,4,68.28,127.34,25.84,127.34 +2979,4,E07000192,0,46.63,107.26,18.64,107.26 +4283,5,E07000192,1,52.6,91.27,25.84,99.75 +4893,5,E07000192,2,58.13,114.6,25.84,124.15 +5524,5,E07000192,3,69.2,134.77,25.84,147.5 +6176,5,E07000192,4,80.28,196.32,25.84,213.29 +3305,6,E07000192,0,39.38,220.48,18.64,239.54 +4504,7,E07000192,1,46.13,91.27,25.84,99.75 +5189,7,E07000192,2,49.84,114.6,25.84,124.15 +5780,7,E07000192,3,59.98,134.77,25.84,147.5 +6441,7,E07000192,4,68.28,196.32,25.84,213.29 +3631,8,E07000192,0,46.63,220.48,18.64,239.54 +6565,9,E07000192,1,52.6,114.09,25.84,124.69 +6891,9,E07000192,2,58.13,143.25,25.84,155.2 +7217,9,E07000192,3,69.2,168.46,25.84,184.37 +7543,9,E07000192,4,80.28,245.4,25.84,266.62 +7869,10,E07000192,0,39.38,443.93,18.64,484.13 +46,1,E07000106,1,57.21,123.09,25.84,176.15 +372,1,E07000106,2,71.06,146.43,25.84,186.77 +698,1,E07000106,3,81.2,161.3,25.84,203.75 +1024,1,E07000106,4,89.52,178.28,25.84,221.77 +2654,2,E07000106,0,62.17,268.13,18.64,344.4 +1350,3,E07000106,1,51.68,115.66,25.84,159.17 +1676,3,E07000106,2,62.75,129.46,25.84,145.37 +2002,3,E07000106,3,68.28,149.62,25.84,185.7 +2328,3,E07000106,4,72.9,184.64,25.84,194.19 +2980,4,E07000106,0,48.71,195.45,18.64,204.96 +3990,5,E07000106,1,57.21,157.04,25.84,172.97 +4605,5,E07000106,2,71.06,180.4,25.84,197.39 +5257,5,E07000106,3,81.2,228.14,25.84,247.25 +5942,5,E07000106,4,89.52,354.42,25.84,386.26 +3306,6,E07000106,0,62.17,398.03,18.64,433.79 +4057,7,E07000106,1,51.68,157.04,25.84,172.97 +4752,7,E07000106,2,62.75,180.4,25.84,197.39 +5357,7,E07000106,3,68.28,228.14,25.84,247.25 +6046,7,E07000106,4,72.9,354.42,25.84,386.26 +3632,8,E07000106,0,48.71,398.03,18.64,433.79 +6566,9,E07000106,1,57.21,196.32,25.84,216.2 +6892,9,E07000106,2,71.06,225.52,25.84,246.73 +7218,9,E07000106,3,81.2,285.19,25.84,309.06 +7544,9,E07000106,4,89.52,443.03,25.84,482.83 +7870,10,E07000106,0,62.17,536.27,18.64,585.43 +48,1,E07000069,1,54.44,118.85,25.84,148.56 +374,1,E07000069,2,64.59,142.18,25.84,167.67 +700,1,E07000069,3,71.06,155.98,25.84,180.4 +1026,1,E07000069,4,81.2,170.85,25.84,178.28 +2656,2,E07000069,0,36.26,226.42,18.64,423.05 +1352,3,E07000069,1,49.84,99.75,25.84,131.58 +1678,3,E07000069,2,58.13,117.78,25.84,132.64 +2004,3,E07000069,3,63.67,130.52,25.84,143.25 +2330,3,E07000069,4,71.06,148.56,25.84,159.17 +2982,4,E07000069,0,55.97,135.86,18.64,318.19 +4126,5,E07000069,1,54.44,142.18,25.84,154.93 +4707,5,E07000069,2,64.59,176.15,25.84,191.01 +5426,5,E07000069,3,71.06,203.75,25.84,221.77 +6136,5,E07000069,4,81.2,281.2,25.84,306.68 +3308,6,E07000069,0,36.26,315.82,18.64,344.4 +4243,7,E07000069,1,49.84,142.18,25.84,154.93 +4969,7,E07000069,2,58.13,176.15,25.84,191.01 +5612,7,E07000069,3,63.67,203.75,25.84,221.77 +6274,7,E07000069,4,71.06,281.2,25.84,306.68 +3634,8,E07000069,0,55.97,315.82,18.64,344.4 +6568,9,E07000069,1,54.44,177.73,25.84,193.64 +6894,9,E07000069,2,64.59,220.21,25.84,238.77 +7220,9,E07000069,3,71.06,254.69,25.84,277.23 +7546,9,E07000069,4,81.2,351.51,25.84,383.34 +7872,10,E07000069,0,36.26,314.32,18.64,344.12 +49,1,E06000056,1,54.44,118.85,25.84,148.56 +375,1,E06000056,2,64.59,142.18,25.84,167.67 +701,1,E06000056,3,71.06,155.98,25.84,180.4 +1027,1,E06000056,4,81.2,170.85,25.84,178.28 +2657,2,E06000056,0,36.26,226.42,18.64,423.05 +1353,3,E06000056,1,49.84,99.75,25.84,131.58 +1679,3,E06000056,2,58.13,117.78,25.84,132.64 +2005,3,E06000056,3,63.67,130.52,25.84,143.25 +2331,3,E06000056,4,71.06,148.56,25.84,159.17 +2983,4,E06000056,0,55.97,135.86,18.64,318.19 +4127,5,E06000056,1,54.44,119.9,25.84,130.52 +4708,5,E06000056,2,64.59,147.5,25.84,160.24 +5427,5,E06000056,3,71.06,192.07,25.84,210.12 +6137,5,E06000056,4,81.2,270.61,25.84,295.01 +3309,6,E06000056,0,36.26,303.89,18.64,331.29 +4244,7,E06000056,1,49.84,119.9,25.84,130.52 +4970,7,E06000056,2,58.13,147.5,25.84,160.24 +5613,7,E06000056,3,63.67,192.07,25.84,210.12 +6275,7,E06000056,4,71.06,270.61,25.84,295.01 +3635,8,E06000056,0,55.97,303.89,18.64,331.29 +6569,9,E06000056,1,54.44,149.9,25.84,163.15 +6895,9,E06000056,2,64.59,184.37,25.84,200.32 +7221,9,E06000056,3,71.06,240.08,25.84,262.64 +7547,9,E06000056,4,81.2,338.25,25.84,368.76 +7873,10,E06000056,0,36.26,286.02,18.64,311.34 +50,1,E07000130,1,51.68,99.75,25.84,122.03 +376,1,E07000130,2,61.83,114.6,25.84,129.46 +702,1,E07000130,3,68.28,126.28,25.84,137.95 +1028,1,E07000130,4,75.67,158.1,25.84,166.61 +2658,2,E07000130,0,51.82,240.72,18.64,361.1 +1354,3,E07000130,1,46.13,90.21,25.84,107.19 +1680,3,E07000130,2,52.6,96.56,25.84,108.24 +2006,3,E07000130,3,58.13,104,25.84,118.85 +2332,3,E07000130,4,63.67,122.03,25.84,122.03 +2984,4,E07000130,0,49.74,114.39,18.64,123.94 +4318,5,E07000130,1,51.68,102.94,25.84,112.47 +5014,5,E07000130,2,61.83,125.22,25.84,136.89 +5657,5,E07000130,3,68.28,147.5,25.84,160.24 +6232,5,E07000130,4,75.67,226.01,25.84,245.12 +3310,6,E07000130,0,51.82,251.45,18.64,275.3 +4418,7,E07000130,1,46.13,102.94,25.84,112.47 +5154,7,E07000130,2,52.6,125.22,25.84,136.89 +5815,7,E07000130,3,58.13,147.5,25.84,160.24 +6476,7,E07000130,4,63.67,226.01,25.84,245.12 +3636,8,E07000130,0,49.74,251.45,18.64,275.3 +6570,9,E07000130,1,51.68,128.67,25.84,140.6 +6896,9,E07000130,2,61.83,156.51,25.84,171.11 +7222,9,E07000130,3,68.28,184.37,25.84,200.32 +7548,9,E07000130,4,75.67,282.54,25.84,306.4 +7874,10,E07000130,0,51.82,348.6,18.64,379.86 +51,1,E07000070,1,54.44,118.85,25.84,148.56 +377,1,E07000070,2,64.59,142.18,25.84,167.67 +703,1,E07000070,3,71.06,155.98,25.84,180.4 +1029,1,E07000070,4,81.2,170.85,25.84,178.28 +2659,2,E07000070,0,36.26,226.42,18.64,423.05 +1355,3,E07000070,1,49.84,99.75,25.84,131.58 +1681,3,E07000070,2,58.13,117.78,25.84,132.64 +2007,3,E07000070,3,63.67,130.52,25.84,143.25 +2333,3,E07000070,4,71.06,148.56,25.84,159.17 +2985,4,E07000070,0,55.97,135.86,18.64,318.19 +4128,5,E07000070,1,54.44,142.18,25.84,154.93 +4709,5,E07000070,2,64.59,180.4,25.84,197.39 +5428,5,E07000070,3,71.06,214.35,25.84,234.52 +6138,5,E07000070,4,81.2,371.41,25.84,405.36 +3311,6,E07000070,0,36.26,417.11,18.64,455.24 +4245,7,E07000070,1,49.84,142.18,25.84,154.93 +4971,7,E07000070,2,58.13,180.4,25.84,197.39 +5614,7,E07000070,3,63.67,214.35,25.84,234.52 +6276,7,E07000070,4,71.06,371.41,25.84,405.36 +3637,8,E07000070,0,55.97,417.11,18.64,455.24 +6571,9,E07000070,1,54.44,177.73,25.84,193.64 +6897,9,E07000070,2,64.59,225.52,25.84,246.73 +7223,9,E07000070,3,71.06,267.95,25.84,293.15 +7549,9,E07000070,4,81.2,464.26,25.84,506.71 +7875,10,E07000070,0,36.26,929.54,18.64,1012.97 +52,1,E07000078,1,48.92,107.19,25.84,140.08 +378,1,E07000078,2,55.37,120.97,25.84,144.31 +704,1,E07000078,3,61.83,141.13,25.84,161.3 +1030,1,E07000078,4,71.06,158.1,25.84,194.19 +2660,2,E07000078,0,54.93,231.2,18.64,358.7 +1356,3,E07000078,1,47.06,89.13,25.84,210.12 +1682,3,E07000078,2,54.44,100.81,25.84,111.41 +2008,3,E07000078,3,61.83,109.29,25.84,126.28 +2334,3,E07000078,4,73.82,130.52,25.84,130.52 +2986,4,E07000078,0,54.93,115.59,18.64,141.81 +4200,5,E07000078,1,48.92,128.4,25.84,141.13 +4836,5,E07000078,2,55.37,170.85,25.84,185.7 +5467,5,E07000078,3,61.83,214.35,25.84,234.52 +6005,5,E07000078,4,71.06,471.15,25.84,513.6 +3312,6,E07000078,0,54.93,529.13,18.64,576.82 +3916,7,E07000078,1,47.06,128.4,25.84,141.13 +5113,7,E07000078,2,54.44,170.85,25.84,185.7 +5693,7,E07000078,3,61.83,214.35,25.84,234.52 +6405,7,E07000078,4,73.82,471.15,25.84,513.6 +3638,8,E07000078,0,54.93,529.13,18.64,576.82 +6572,9,E07000078,1,48.92,160.51,25.84,176.42 +6898,9,E07000078,2,55.37,213.57,25.84,232.15 +7224,9,E07000078,3,61.83,267.95,25.84,293.15 +7550,9,E07000078,4,71.06,588.93,25.84,642 +7876,10,E07000078,0,54.93,284.53,18.64,309.82 +53,1,E07000177,1,57.21,123.09,25.84,176.15 +379,1,E07000177,2,71.06,146.43,25.84,186.77 +705,1,E07000177,3,81.2,161.3,25.84,203.75 +1031,1,E07000177,4,89.52,178.28,25.84,221.77 +2661,2,E07000177,0,62.17,268.13,18.64,344.4 +1357,3,E07000177,1,51.68,115.66,25.84,159.17 +1683,3,E07000177,2,62.75,129.46,25.84,145.37 +2009,3,E07000177,3,68.28,149.62,25.84,185.7 +2335,3,E07000177,4,72.9,184.64,25.84,194.19 +2987,4,E07000177,0,48.71,195.45,18.64,204.96 +3991,5,E07000177,1,57.21,134.77,25.84,147.5 +4606,5,E07000177,2,71.06,170.85,25.84,185.7 +5258,5,E07000177,3,81.2,209.06,25.84,228.14 +5943,5,E07000177,4,89.52,337.44,25.84,368.22 +3313,6,E07000177,0,62.17,378.95,18.64,413.53 +4058,7,E07000177,1,51.68,134.77,25.84,147.5 +4753,7,E07000177,2,62.75,170.85,25.84,185.7 +5358,7,E07000177,3,68.28,209.06,25.84,228.14 +6047,7,E07000177,4,72.9,337.44,25.84,368.22 +3639,8,E07000177,0,48.71,378.95,18.64,413.53 +6573,9,E07000177,1,57.21,168.46,25.84,184.37 +6899,9,E07000177,2,71.06,213.57,25.84,232.15 +7225,9,E07000177,3,81.2,261.31,25.84,285.19 +7551,9,E07000177,4,89.52,421.8,25.84,460.26 +7877,10,E07000177,0,62.17,254.72,18.64,278.57 +83,1,E06000049,1,51.68,93.39,25.84,116.72 +409,1,E06000049,2,59.06,107.19,25.84,134.77 +735,1,E06000049,3,65.51,119.9,25.84,145.37 +1061,1,E06000049,4,71.98,133.71,25.84,159.17 +2691,2,E06000049,0,55.97,239.54,18.64,342.01 +1387,3,E06000049,1,43.36,85.94,25.84,100.81 +1713,3,E06000049,2,53.52,94.47,25.84,113.53 +2039,3,E06000049,3,58.13,105.06,25.84,124.15 +2365,3,E06000049,4,55.37,118.85,25.84,133.71 +3017,4,E06000049,0,33.16,469.54,18.64,599.44 +4363,5,E06000049,1,51.68,113.53,25.84,123.09 +4933,5,E06000049,2,59.06,147.5,25.84,160.24 +5576,5,E06000049,3,65.51,192.07,25.84,210.12 +6324,5,E06000049,4,71.98,336.37,25.84,367.16 +3343,6,E06000049,0,55.97,377.76,18.64,412.34 +4475,7,E06000049,1,43.36,113.53,25.84,123.09 +5071,7,E06000049,2,53.52,147.5,25.84,160.24 +5751,7,E06000049,3,58.13,192.07,25.84,210.12 +6375,7,E06000049,4,55.37,336.37,25.84,367.16 +3669,8,E06000049,0,33.16,377.76,18.64,412.34 +6603,9,E06000049,1,51.68,141.94,25.84,153.86 +6929,9,E06000049,2,59.06,184.37,25.84,200.32 +7255,9,E06000049,3,65.51,240.08,25.84,262.64 +7581,9,E06000049,4,71.98,420.48,25.84,458.95 +7907,10,E06000049,0,55.97,333.68,18.64,363.48 +54,1,E06000050,1,51.68,93.39,25.84,116.72 +380,1,E06000050,2,59.06,107.19,25.84,134.77 +706,1,E06000050,3,65.51,119.9,25.84,145.37 +1032,1,E06000050,4,71.98,133.71,25.84,159.17 +2662,2,E06000050,0,55.97,239.54,18.64,342.01 +1358,3,E06000050,1,43.36,85.94,25.84,100.81 +1684,3,E06000050,2,53.52,94.47,25.84,113.53 +2010,3,E06000050,3,58.13,105.06,25.84,124.15 +2336,3,E06000050,4,55.37,118.85,25.84,133.71 +2988,4,E06000050,0,33.16,469.54,18.64,599.44 +4359,5,E06000050,1,51.68,119.9,25.84,130.52 +4929,5,E06000050,2,59.06,142.18,25.84,154.93 +5572,5,E06000050,3,65.51,164.48,25.84,179.34 +6320,5,E06000050,4,71.98,259.98,25.84,282.26 +3314,6,E06000050,0,55.97,291.97,18.64,317 +4471,7,E06000050,1,43.36,119.9,25.84,130.52 +5067,7,E06000050,2,53.52,142.18,25.84,154.93 +5747,7,E06000050,3,58.13,164.48,25.84,179.34 +6371,7,E06000050,4,55.37,259.98,25.84,282.26 +3640,8,E06000050,0,33.16,291.97,18.64,317 +6574,9,E06000050,1,51.68,149.9,25.84,163.15 +6900,9,E06000050,2,59.06,177.73,25.84,193.64 +7226,9,E06000050,3,65.51,205.6,25.84,224.18 +7552,9,E06000050,4,71.98,324.98,25.84,352.84 +7878,10,E06000050,0,55.97,317.29,18.64,345.6 +55,1,E07000034,1,51.68,99.75,25.84,122.03 +381,1,E07000034,2,61.83,114.6,25.84,129.46 +707,1,E07000034,3,68.28,126.28,25.84,137.95 +1033,1,E07000034,4,75.67,158.1,25.84,166.61 +2663,2,E07000034,0,51.82,240.72,18.64,361.1 +1359,3,E07000034,1,46.13,90.21,25.84,107.19 +1685,3,E07000034,2,52.6,96.56,25.84,108.24 +2011,3,E07000034,3,58.13,104,25.84,118.85 +2337,3,E07000034,4,63.67,122.03,25.84,122.03 +2989,4,E07000034,0,49.74,114.39,18.64,123.94 +4319,5,E07000034,1,51.68,97.63,25.84,107.19 +5015,5,E07000034,2,61.83,113.53,25.84,123.09 +5658,5,E07000034,3,68.28,134.77,25.84,147.5 +6233,5,E07000034,4,75.67,186.77,25.84,203.75 +3315,6,E07000034,0,51.82,209.73,18.64,228.81 +4419,7,E07000034,1,46.13,97.63,25.84,107.19 +5155,7,E07000034,2,52.6,113.53,25.84,123.09 +5816,7,E07000034,3,58.13,134.77,25.84,147.5 +6477,7,E07000034,4,63.67,186.77,25.84,203.75 +3641,8,E07000034,0,49.74,209.73,18.64,228.81 +6575,9,E07000034,1,51.68,122.03,25.84,133.98 +6901,9,E07000034,2,61.83,141.94,25.84,153.86 +7227,9,E07000034,3,68.28,168.46,25.84,184.37 +7553,9,E07000034,4,75.67,233.46,25.84,254.69 +7879,10,E07000034,0,51.82,662.89,18.64,722.48 +56,1,E07000225,1,57.21,123.09,25.84,176.15 +382,1,E07000225,2,71.06,146.43,25.84,186.77 +708,1,E07000225,3,81.2,161.3,25.84,203.75 +1034,1,E07000225,4,89.52,178.28,25.84,221.77 +2664,2,E07000225,0,62.17,268.13,18.64,344.4 +1360,3,E07000225,1,51.68,115.66,25.84,159.17 +1686,3,E07000225,2,62.75,129.46,25.84,145.37 +2012,3,E07000225,3,68.28,149.62,25.84,185.7 +2338,3,E07000225,4,72.9,184.64,25.84,194.19 +2990,4,E07000225,0,48.71,195.45,18.64,204.96 +3992,5,E07000225,1,57.21,147.5,25.84,160.24 +4607,5,E07000225,2,71.06,192.07,25.84,210.12 +5259,5,E07000225,3,81.2,248.31,25.84,270.61 +5944,5,E07000225,4,89.52,426.59,25.84,465.84 +3316,6,E07000225,0,62.17,479.07,18.64,523.16 +4059,7,E07000225,1,51.68,147.5,25.84,160.24 +4754,7,E07000225,2,62.75,192.07,25.84,210.12 +5359,7,E07000225,3,68.28,248.31,25.84,270.61 +6048,7,E07000225,4,72.9,426.59,25.84,465.84 +3642,8,E07000225,0,48.71,479.07,18.64,523.16 +6576,9,E07000225,1,57.21,184.37,25.84,200.32 +6902,9,E07000225,2,71.06,240.08,25.84,262.64 +7228,9,E07000225,3,81.2,310.37,25.84,338.25 +7554,9,E07000225,4,89.52,533.22,25.84,582.31 +7880,10,E07000225,0,62.17,646.5,18.64,706.09 +58,1,E07000118,1,51.68,93.39,25.84,116.72 +384,1,E07000118,2,59.06,107.19,25.84,134.77 +710,1,E07000118,3,65.51,119.9,25.84,145.37 +1036,1,E07000118,4,71.98,133.71,25.84,159.17 +2666,2,E07000118,0,55.97,239.54,18.64,342.01 +1362,3,E07000118,1,43.36,85.94,25.84,100.81 +1688,3,E07000118,2,53.52,94.47,25.84,113.53 +2014,3,E07000118,3,58.13,105.06,25.84,124.15 +2340,3,E07000118,4,55.37,118.85,25.84,133.71 +2992,4,E07000118,0,33.16,469.54,18.64,599.44 +4360,5,E07000118,1,51.68,96.56,25.84,105.06 +4930,5,E07000118,2,59.06,125.22,25.84,136.89 +5573,5,E07000118,3,65.51,147.5,25.84,160.24 +6321,5,E07000118,4,71.98,202.69,25.84,220.72 +3318,6,E07000118,0,55.97,227.63,18.64,247.88 +4472,7,E07000118,1,43.36,96.56,25.84,105.06 +5068,7,E07000118,2,53.52,125.22,25.84,136.89 +5748,7,E07000118,3,58.13,147.5,25.84,160.24 +6372,7,E07000118,4,55.37,202.69,25.84,220.72 +3644,8,E07000118,0,33.16,227.63,18.64,247.88 +6578,9,E07000118,1,51.68,120.73,25.84,131.32 +6904,9,E07000118,2,59.06,156.51,25.84,171.11 +7230,9,E07000118,3,65.51,184.37,25.84,200.32 +7556,9,E07000118,4,71.98,253.36,25.84,275.9 +7882,10,E07000118,0,55.97,253.23,18.64,277.06 +60,1,E09000001,1,65.51,145.37,25.84,197.39 +386,1,E09000001,2,77.51,157.04,25.84,192.07 +712,1,E09000001,3,83.97,166.61,25.84,226.01 +1038,1,E09000001,4,101.48,186.77,25.84,251.49 +2668,2,E09000001,0,70.47,317,18.64,502.91 +1364,3,E09000001,1,58.13,118.85,25.84,146.43 +1690,3,E09000001,2,63.67,139.02,25.84,175.09 +2016,3,E09000001,3,71.06,159.17,25.84,200.55 +2342,3,E09000001,4,83.05,259.98,25.84,261.04 +2994,4,E09000001,0,60.1,371.82,18.64,402.8 +3956,5,E09000001,1,65.51,385.2,25.84,420.23 +4571,5,E09000001,2,77.51,491.33,25.84,535.89 +5223,5,E09000001,3,83.97,923.2,25.84,1007.03 +5908,5,E09000001,4,101.48,2253.89,25.84,2458.69 +3320,6,E09000001,0,70.47,3210.51,18.64,3502.48 +4170,7,E09000001,1,58.13,385.2,25.84,420.23 +4671,7,E09000001,2,63.67,491.33,25.84,535.89 +5323,7,E09000001,3,71.06,923.2,25.84,1007.03 +5875,7,E09000001,4,83.05,2253.89,25.84,2458.69 +3646,8,E09000001,0,60.1,3210.51,18.64,3502.48 +6580,9,E09000001,1,65.51,481.52,25.84,525.28 +6906,9,E09000001,2,77.51,614.15,25.84,669.87 +7232,9,E09000001,3,83.97,1154.01,25.84,1258.8 +7558,9,E09000001,4,101.48,2817.36,25.84,3073.38 +7884,10,E09000001,0,70.47,443.93,18.64,484.13 +62,1,E07000071,1,54.44,118.85,25.84,148.56 +388,1,E07000071,2,64.59,142.18,25.84,167.67 +714,1,E07000071,3,71.06,155.98,25.84,180.4 +1040,1,E07000071,4,81.2,170.85,25.84,178.28 +2670,2,E07000071,0,36.26,226.42,18.64,423.05 +1366,3,E07000071,1,49.84,99.75,25.84,131.58 +1692,3,E07000071,2,58.13,117.78,25.84,132.64 +2018,3,E07000071,3,63.67,130.52,25.84,143.25 +2344,3,E07000071,4,71.06,148.56,25.84,159.17 +2996,4,E07000071,0,55.97,135.86,18.64,318.19 +4129,5,E07000071,1,54.44,123.09,25.84,133.71 +4710,5,E07000071,2,64.59,147.5,25.84,160.24 +5429,5,E07000071,3,71.06,191.01,25.84,209.06 +6139,5,E07000071,4,81.2,281.2,25.84,306.68 +3322,6,E07000071,0,36.26,315.82,18.64,344.4 +4246,7,E07000071,1,49.84,123.09,25.84,133.71 +4972,7,E07000071,2,58.13,147.5,25.84,160.24 +5615,7,E07000071,3,63.67,191.01,25.84,209.06 +6277,7,E07000071,4,71.06,281.2,25.84,306.68 +3648,8,E07000071,0,55.97,315.82,18.64,344.4 +6582,9,E07000071,1,54.44,153.86,25.84,167.13 +6908,9,E07000071,2,64.59,184.37,25.84,200.32 +7234,9,E07000071,3,71.06,238.77,25.84,261.31 +7560,9,E07000071,4,81.2,351.51,25.84,383.34 +7886,10,E07000071,0,36.26,472.22,18.64,515.43 +65,1,E06000052,1,48.92,107.19,25.84,140.08 +391,1,E06000052,2,55.37,120.97,25.84,144.31 +717,1,E06000052,3,61.83,141.13,25.84,161.3 +1043,1,E06000052,4,71.06,158.1,25.84,194.19 +2673,2,E06000052,0,54.93,231.2,18.64,358.7 +1369,3,E06000052,1,47.06,89.13,25.84,210.12 +1695,3,E06000052,2,54.44,100.81,25.84,111.41 +2021,3,E06000052,3,61.83,109.29,25.84,126.28 +2347,3,E06000052,4,73.82,130.52,25.84,130.52 +2999,4,E06000052,0,54.93,115.59,18.64,141.81 +4202,5,E06000052,1,48.92,114.6,25.84,124.15 +4838,5,E06000052,2,55.37,142.18,25.84,154.93 +5469,5,E06000052,3,61.83,166.61,25.84,180.4 +6007,5,E06000052,4,71.06,219.66,25.84,239.83 +3325,6,E06000052,0,54.93,246.68,18.64,269.32 +3918,7,E06000052,1,47.06,114.6,25.84,124.15 +5115,7,E06000052,2,54.44,142.18,25.84,154.93 +5695,7,E06000052,3,61.83,166.61,25.84,180.4 +6407,7,E06000052,4,73.82,219.66,25.84,239.83 +3651,8,E06000052,0,54.93,246.68,18.64,269.32 +6585,9,E06000052,1,48.92,143.25,25.84,155.2 +6911,9,E06000052,2,55.37,177.73,25.84,193.64 +7237,9,E06000052,3,61.83,208.27,25.84,225.52 +7563,9,E06000052,4,71.06,274.57,25.84,299.78 +7889,10,E06000052,0,54.93,251.74,18.64,275.59 +66,1,E07000079,1,48.92,107.19,25.84,140.08 +392,1,E07000079,2,55.37,120.97,25.84,144.31 +718,1,E07000079,3,61.83,141.13,25.84,161.3 +1044,1,E07000079,4,71.06,158.1,25.84,194.19 +2674,2,E07000079,0,54.93,231.2,18.64,358.7 +1370,3,E07000079,1,47.06,89.13,25.84,210.12 +1696,3,E07000079,2,54.44,100.81,25.84,111.41 +2022,3,E07000079,3,61.83,109.29,25.84,126.28 +2348,3,E07000079,4,73.82,130.52,25.84,130.52 +3000,4,E07000079,0,54.93,115.59,18.64,141.81 +4203,5,E07000079,1,48.92,125.22,25.84,136.89 +4839,5,E07000079,2,55.37,164.48,25.84,179.34 +5470,5,E07000079,3,61.83,203.75,25.84,221.77 +6008,5,E07000079,4,71.06,447.81,25.84,487.08 +3326,6,E07000079,0,54.93,502.91,18.64,547.01 +3919,7,E07000079,1,47.06,125.22,25.84,136.89 +5116,7,E07000079,2,54.44,164.48,25.84,179.34 +5696,7,E07000079,3,61.83,203.75,25.84,221.77 +6408,7,E07000079,4,73.82,447.81,25.84,487.08 +3652,8,E07000079,0,54.93,502.91,18.64,547.01 +6586,9,E07000079,1,48.92,156.51,25.84,171.11 +6912,9,E07000079,2,55.37,205.6,25.84,224.18 +7238,9,E07000079,3,61.83,254.69,25.84,277.23 +7564,9,E07000079,4,71.06,559.76,25.84,608.86 +7890,10,E07000079,0,54.93,269.62,18.64,294.95 +80,1,E06000047,1,50.76,88.07,25.84,97.63 +406,1,E06000047,2,57.21,101.88,25.84,119.9 +732,1,E06000047,3,60.9,113.53,25.84,159.17 +1058,1,E06000047,4,70.13,127.34,25.84,139.02 +2688,2,E06000047,0,55.97,237.14,18.64,340.83 +1384,3,E06000047,1,42.44,99.75,25.84,105.06 +1710,3,E06000047,2,49.84,90.21,25.84,111.41 +2036,3,E06000047,3,53.52,105.06,25.84,124.15 +2362,3,E06000047,4,56.29,115.66,25.84,119.9 +3014,4,E06000047,0,47.67,253.84,18.64,288.39 +4533,5,E06000047,1,50.76,125.22,25.84,136.89 +5048,5,E06000047,2,57.21,102.94,25.84,112.47 +5553,5,E06000047,3,60.9,123.09,25.84,133.71 +6352,5,E06000047,4,70.13,180.4,25.84,197.39 +3340,6,E06000047,0,55.97,202.58,18.64,221.66 +4452,7,E06000047,1,42.44,125.22,25.84,136.89 +5099,7,E06000047,2,49.84,102.94,25.84,112.47 +5728,7,E06000047,3,53.52,123.09,25.84,133.71 +6510,7,E06000047,4,56.29,180.4,25.84,197.39 +3666,8,E06000047,0,47.67,202.58,18.64,221.66 +6600,9,E06000047,1,42.44,156.51,25.84,171.11 +6926,9,E06000047,2,57.21,128.67,25.84,140.6 +7252,9,E06000047,3,60.9,153.86,25.84,167.13 +7578,9,E06000047,4,70.13,225.52,25.84,246.73 +7904,10,E06000047,0,55.97,318.79,18.64,345.6 +67,1,E08000026,1,52.6,98.69,25.84,124.15 +393,1,E08000026,2,58.13,116.72,25.84,136.89 +719,1,E08000026,3,69.2,132.64,25.84,160.24 +1045,1,E08000026,4,80.28,161.3,25.84,178.28 +2675,2,E08000026,0,39.38,245.49,18.64,382.53 +1371,3,E08000026,1,46.13,88.07,25.84,97.63 +1697,3,E08000026,2,49.84,94.47,25.84,102.94 +2023,3,E08000026,3,59.98,104,25.84,119.9 +2349,3,E08000026,4,68.28,127.34,25.84,127.34 +3001,4,E08000026,0,46.63,107.26,18.64,107.26 +4284,5,E08000026,1,52.6,113.53,25.84,123.09 +4894,5,E08000026,2,58.13,130.52,25.84,143.25 +5525,5,E08000026,3,69.2,147.5,25.84,160.24 +6177,5,E08000026,4,80.28,235.58,25.84,256.8 +3327,6,E08000026,0,39.38,264.56,18.64,288.39 +4505,7,E08000026,1,46.13,113.53,25.84,123.09 +5190,7,E08000026,2,49.84,130.52,25.84,143.25 +5781,7,E08000026,3,59.98,147.5,25.84,160.24 +6442,7,E08000026,4,68.28,235.58,25.84,256.8 +3653,8,E08000026,0,46.63,264.56,18.64,288.39 +6587,9,E08000026,1,52.6,141.94,25.84,153.86 +6913,9,E08000026,2,58.13,163.15,25.84,179.06 +7239,9,E08000026,3,69.2,184.37,25.84,200.32 +7565,9,E08000026,4,80.28,294.49,25.84,320.99 +7891,10,E08000026,0,39.38,411.13,18.64,448.39 +69,1,E07000226,1,57.21,123.09,25.84,176.15 +395,1,E07000226,2,71.06,146.43,25.84,186.77 +721,1,E07000226,3,81.2,161.3,25.84,203.75 +1047,1,E07000226,4,89.52,178.28,25.84,221.77 +2677,2,E07000226,0,62.17,268.13,18.64,344.4 +1373,3,E07000226,1,51.68,115.66,25.84,159.17 +1699,3,E07000226,2,62.75,129.46,25.84,145.37 +2025,3,E07000226,3,68.28,149.62,25.84,185.7 +2351,3,E07000226,4,72.9,184.64,25.84,194.19 +3003,4,E07000226,0,48.71,195.45,18.64,204.96 +3994,5,E07000226,1,57.21,153.86,25.84,167.67 +4609,5,E07000226,2,71.06,192.07,25.84,210.12 +5261,5,E07000226,3,81.2,227.08,25.84,246.18 +5946,5,E07000226,4,89.52,315.17,25.84,342.76 +3329,6,E07000226,0,62.17,353.92,18.64,384.93 +4061,7,E07000226,1,51.68,153.86,25.84,167.67 +4756,7,E07000226,2,62.75,192.07,25.84,210.12 +5361,7,E07000226,3,68.28,227.08,25.84,246.18 +6050,7,E07000226,4,72.9,315.17,25.84,342.76 +3655,8,E07000226,0,48.71,353.92,18.64,384.93 +6589,9,E07000226,1,57.21,192.33,25.84,209.57 +6915,9,E07000226,2,71.06,240.08,25.84,262.64 +7241,9,E07000226,3,81.2,283.85,25.84,307.73 +7567,9,E07000226,4,89.52,393.95,25.84,428.42 +7893,10,E07000226,0,62.17,257.69,18.64,281.53 +70,1,E09000008,1,65.51,145.37,25.84,197.39 +396,1,E09000008,2,77.51,157.04,25.84,192.07 +722,1,E09000008,3,83.97,166.61,25.84,226.01 +1048,1,E09000008,4,101.48,186.77,25.84,251.49 +2678,2,E09000008,0,70.47,317,18.64,502.91 +1374,3,E09000008,1,58.13,118.85,25.84,146.43 +1700,3,E09000008,2,63.67,139.02,25.84,175.09 +2026,3,E09000008,3,71.06,159.17,25.84,200.55 +2352,3,E09000008,4,83.05,259.98,25.84,261.04 +3004,4,E09000008,0,60.1,371.82,18.64,402.8 +3957,5,E09000008,1,65.51,176.15,25.84,191.01 +4572,5,E09000008,2,77.51,214.35,25.84,234.52 +5224,5,E09000008,3,83.97,270.61,25.84,295.01 +5909,5,E09000008,4,101.48,390.53,25.84,424.47 +3330,6,E09000008,0,70.47,437.37,18.64,476.69 +4171,7,E09000008,1,58.13,176.15,25.84,191.01 +4672,7,E09000008,2,63.67,214.35,25.84,234.52 +5324,7,E09000008,3,71.06,270.61,25.84,295.01 +5876,7,E09000008,4,83.05,390.53,25.84,424.47 +3656,8,E09000008,0,60.1,437.37,18.64,476.69 +6590,9,E09000008,1,65.51,220.21,25.84,238.77 +6916,9,E09000008,2,77.51,267.95,25.84,293.15 +7242,9,E09000008,3,83.97,338.25,25.84,368.76 +7568,9,E09000008,4,101.48,488.14,25.84,530.59 +7894,10,E09000008,0,70.47,286.02,18.64,311.34 +8151,1,E06000063,1,51.68,93.39,25.84,116.72 +8152,1,E06000063,2,59.06,107.19,25.84,134.77 +8153,1,E06000063,3,65.51,119.9,25.84,145.37 +8154,1,E06000063,4,71.98,133.71,25.84,159.17 +8159,2,E06000063,0,55.97,239.54,18.64,342.01 +8155,3,E06000063,1,43.36,85.94,25.84,100.81 +8156,3,E06000063,2,53.52,94.47,25.84,113.53 +8157,3,E06000063,3,58.13,105.06,25.84,124.15 +8158,3,E06000063,4,55.37,118.85,25.84,133.71 +8160,4,E06000063,0,33.16,469.54,18.64,599.44 +8163,5,E06000063,1,51.68,114.6,25.84,124.15 +8165,5,E06000063,2,59.06,142.18,25.84,154.93 +8167,5,E06000063,3,65.51,170.85,25.84,185.7 +8169,5,E06000063,4,71.98,214.35,25.84,234.52 +8161,6,E06000063,0,55.97,240.72,18.64,263.37 +8164,7,E06000063,1,43.36,114.6,25.84,124.15 +8166,7,E06000063,2,53.52,142.18,25.84,154.93 +8168,7,E06000063,3,58.13,170.85,25.84,185.7 +8170,7,E06000063,4,55.37,214.35,25.84,234.52 +8162,8,E06000063,0,33.16,240.72,18.64,263.37 +8171,9,E06000063,1,51.68,143.25,25.84,155.2 +8172,9,E06000063,2,59.06,177.73,25.84,193.64 +8173,9,E06000063,3,65.51,213.57,25.84,232.15 +8174,9,E06000063,4,71.98,267.95,25.84,293.15 +8175,10,E06000063,0,55.97,269.62,18.64,294.95 +71,1,E07000096,1,54.44,118.85,25.84,148.56 +397,1,E07000096,2,64.59,142.18,25.84,167.67 +723,1,E07000096,3,71.06,155.98,25.84,180.4 +1049,1,E07000096,4,81.2,170.85,25.84,178.28 +2679,2,E07000096,0,36.26,226.42,18.64,423.05 +1375,3,E07000096,1,49.84,99.75,25.84,131.58 +1701,3,E07000096,2,58.13,117.78,25.84,132.64 +2027,3,E07000096,3,63.67,130.52,25.84,143.25 +2353,3,E07000096,4,71.06,148.56,25.84,159.17 +3005,4,E07000096,0,55.97,135.86,18.64,318.19 +4130,5,E07000096,1,54.44,147.5,25.84,160.24 +4711,5,E07000096,2,64.59,192.07,25.84,210.12 +5430,5,E07000096,3,71.06,270.61,25.84,295.01 +6140,5,E07000096,4,81.2,448.87,25.84,489.2 +3331,6,E07000096,0,36.26,504.09,18.64,549.39 +4247,7,E07000096,1,49.84,147.5,25.84,160.24 +4973,7,E07000096,2,58.13,192.07,25.84,210.12 +5616,7,E07000096,3,63.67,270.61,25.84,295.01 +6278,7,E07000096,4,71.06,448.87,25.84,489.2 +3657,8,E07000096,0,55.97,504.09,18.64,549.39 +6591,9,E07000096,1,54.44,184.37,25.84,200.32 +6917,9,E07000096,2,64.59,240.08,25.84,262.64 +7243,9,E07000096,3,71.06,338.25,25.84,368.76 +7569,9,E07000096,4,81.2,561.08,25.84,611.49 +7895,10,E07000096,0,36.26,819.3,18.64,892.3 +72,1,E06000005,1,50.76,88.07,25.84,97.63 +398,1,E06000005,2,57.21,101.88,25.84,119.9 +724,1,E06000005,3,60.9,113.53,25.84,159.17 +1050,1,E06000005,4,70.13,127.34,25.84,139.02 +2680,2,E06000005,0,55.97,237.14,18.64,340.83 +1376,3,E06000005,1,42.44,99.75,25.84,105.06 +1702,3,E06000005,2,49.84,90.21,25.84,111.41 +2028,3,E06000005,3,53.52,105.06,25.84,124.15 +2354,3,E06000005,4,56.29,115.66,25.84,119.9 +3006,4,E06000005,0,47.67,253.84,18.64,288.39 +4532,5,E06000005,1,50.76,90.21,25.84,97.63 +5047,5,E06000005,2,57.21,109.29,25.84,118.85 +5552,5,E06000005,3,60.9,130.52,25.84,143.25 +6351,5,E06000005,4,70.13,186.77,25.84,203.75 +3332,6,E06000005,0,55.97,209.73,18.64,228.81 +4451,7,E06000005,1,42.44,90.21,25.84,97.63 +5098,7,E06000005,2,49.84,109.29,25.84,118.85 +5727,7,E06000005,3,53.52,130.52,25.84,143.25 +6509,7,E06000005,4,56.29,186.77,25.84,203.75 +3658,8,E06000005,0,47.67,209.73,18.64,228.81 +6592,9,E06000005,1,42.44,112.76,25.84,122.03 +6918,9,E06000005,2,57.21,136.63,25.84,148.56 +7244,9,E06000005,3,60.9,163.15,25.84,179.06 +7570,9,E06000005,4,70.13,233.46,25.84,254.69 +7896,10,E06000005,0,55.97,536.27,18.64,583.94 +73,1,E07000107,1,57.21,123.09,25.84,176.15 +399,1,E07000107,2,71.06,146.43,25.84,186.77 +725,1,E07000107,3,81.2,161.3,25.84,203.75 +1051,1,E07000107,4,89.52,178.28,25.84,221.77 +2681,2,E07000107,0,62.17,268.13,18.64,344.4 +1377,3,E07000107,1,51.68,115.66,25.84,159.17 +1703,3,E07000107,2,62.75,129.46,25.84,145.37 +2029,3,E07000107,3,68.28,149.62,25.84,185.7 +2355,3,E07000107,4,72.9,184.64,25.84,194.19 +3007,4,E07000107,0,48.71,195.45,18.64,204.96 +3995,5,E07000107,1,57.21,136.89,25.84,148.56 +4610,5,E07000107,2,71.06,180.4,25.84,197.39 +5262,5,E07000107,3,81.2,209.06,25.84,228.14 +5947,5,E07000107,4,89.52,326.84,25.84,356.55 +3333,6,E07000107,0,62.17,367.04,18.64,400.41 +4062,7,E07000107,1,51.68,136.89,25.84,148.56 +4757,7,E07000107,2,62.75,180.4,25.84,197.39 +5362,7,E07000107,3,68.28,209.06,25.84,228.14 +6051,7,E07000107,4,72.9,326.84,25.84,356.55 +3659,8,E07000107,0,48.71,367.04,18.64,400.41 +6593,9,E07000107,1,57.21,171.11,25.84,185.69 +6919,9,E07000107,2,71.06,225.52,25.84,246.73 +7245,9,E07000107,3,81.2,261.31,25.84,285.19 +7571,9,E07000107,4,89.52,408.54,25.84,445.68 +7897,10,E07000107,0,62.17,750.78,18.64,819.3 +75,1,E06000015,1,51.68,99.75,25.84,122.03 +401,1,E06000015,2,61.83,114.6,25.84,129.46 +727,1,E06000015,3,68.28,126.28,25.84,137.95 +1053,1,E06000015,4,75.67,158.1,25.84,166.61 +2683,2,E06000015,0,51.82,240.72,18.64,361.1 +1379,3,E06000015,1,46.13,90.21,25.84,107.19 +1705,3,E06000015,2,52.6,96.56,25.84,108.24 +2031,3,E06000015,3,58.13,104,25.84,118.85 +2357,3,E06000015,4,63.67,122.03,25.84,122.03 +3009,4,E06000015,0,49.74,114.39,18.64,123.94 +4322,5,E06000015,1,51.68,97.63,25.84,107.19 +5018,5,E06000015,2,61.83,119.9,25.84,130.52 +5661,5,E06000015,3,68.28,142.18,25.84,154.93 +6236,5,E06000015,4,75.67,226.01,25.84,245.12 +3335,6,E06000015,0,51.82,251.45,18.64,275.3 +4422,7,E06000015,1,46.13,97.63,25.84,107.19 +5158,7,E06000015,2,52.6,119.9,25.84,130.52 +5819,7,E06000015,3,58.13,142.18,25.84,154.93 +6480,7,E06000015,4,63.67,226.01,25.84,245.12 +3661,8,E06000015,0,49.74,251.45,18.64,275.3 +6595,9,E06000015,1,51.68,122.03,25.84,133.98 +6921,9,E06000015,2,61.83,149.9,25.84,163.15 +7247,9,E06000015,3,68.28,177.73,25.84,193.64 +7573,9,E06000015,4,75.67,282.54,25.84,306.4 +7899,10,E06000015,0,51.82,379.86,18.64,414.12 +76,1,E07000035,1,51.68,99.75,25.84,122.03 +402,1,E07000035,2,61.83,114.6,25.84,129.46 +728,1,E07000035,3,68.28,126.28,25.84,137.95 +1054,1,E07000035,4,75.67,158.1,25.84,166.61 +2684,2,E07000035,0,51.82,240.72,18.64,361.1 +1380,3,E07000035,1,46.13,90.21,25.84,107.19 +1706,3,E07000035,2,52.6,96.56,25.84,108.24 +2032,3,E07000035,3,58.13,104,25.84,118.85 +2358,3,E07000035,4,63.67,122.03,25.84,122.03 +3010,4,E07000035,0,49.74,114.39,18.64,123.94 +4323,5,E07000035,1,51.68,109.29,25.84,118.85 +5019,5,E07000035,2,61.83,134.77,25.84,147.5 +5662,5,E07000035,3,68.28,158.1,25.84,172.97 +6237,5,E07000035,4,75.67,245.12,25.84,267.41 +3336,6,E07000035,0,51.82,275.3,18.64,300.32 +4423,7,E07000035,1,46.13,109.29,25.84,118.85 +5159,7,E07000035,2,52.6,134.77,25.84,147.5 +5820,7,E07000035,3,58.13,158.1,25.84,172.97 +6481,7,E07000035,4,63.67,245.12,25.84,267.41 +3662,8,E07000035,0,49.74,275.3,18.64,300.32 +6596,9,E07000035,1,51.68,136.63,25.84,148.56 +6922,9,E07000035,2,61.83,168.46,25.84,184.37 +7248,9,E07000035,3,68.28,197.62,25.84,216.2 +7574,9,E07000035,4,75.67,306.4,25.84,334.26 +7900,10,E07000035,0,51.82,443.93,18.64,484.13 +77,1,E08000017,1,50.76,91.27,25.84,113.53 +403,1,E08000017,2,58.13,108.24,25.84,140.08 +729,1,E08000017,3,62.75,119.9,25.84,161.3 +1055,1,E08000017,4,72.9,144.31,25.84,178.28 +2685,2,E08000017,0,52.86,234.75,18.64,322.95 +1381,3,E08000017,1,46.13,81.71,25.84,92.33 +1707,3,E08000017,2,52.6,112.47,25.84,144.31 +2033,3,E08000017,3,56.29,104,25.84,113.53 +2359,3,E08000017,4,63.67,120.97,25.84,175.09 +3011,4,E08000017,0,51.82,160.88,18.64,190.67 +4394,5,E08000017,1,50.76,91.27,25.84,98.69 +4874,5,E08000017,2,58.13,109.29,25.84,118.85 +5505,5,E08000017,3,62.75,125.22,25.84,136.89 +6110,5,E08000017,4,72.9,170.85,25.84,185.7 +3337,6,E08000017,0,52.86,191.88,18.64,208.55 +4548,7,E08000017,1,46.13,91.27,25.84,98.69 +4816,7,E08000017,2,52.6,109.29,25.84,118.85 +5852,7,E08000017,3,56.29,125.22,25.84,136.89 +6208,7,E08000017,4,63.67,170.85,25.84,185.7 +3663,8,E08000017,0,51.82,191.88,18.64,208.55 +6597,9,E08000017,1,50.76,114.09,25.84,123.35 +6923,9,E08000017,2,52.6,136.63,25.84,148.56 +7249,9,E08000017,3,62.75,156.51,25.84,171.11 +7575,9,E08000017,4,72.9,213.57,25.84,232.15 +7901,10,E08000017,0,52.86,239.85,18.64,260.68 +85,1,E06000059,1,48.92,107.19,25.84,140.08 +411,1,E06000059,2,55.37,120.97,25.84,144.31 +737,1,E06000059,3,61.83,141.13,25.84,161.3 +1063,1,E06000059,4,71.06,158.1,25.84,194.19 +2693,2,E06000059,0,54.93,231.2,18.64,358.7 +1389,3,E06000059,1,47.06,89.13,25.84,210.12 +1715,3,E06000059,2,54.44,100.81,25.84,111.41 +2041,3,E06000059,3,61.83,109.29,25.84,126.28 +2367,3,E06000059,4,73.82,130.52,25.84,130.52 +3019,4,E06000059,0,54.93,115.59,18.64,141.81 +4205,5,E06000059,1,48.92,134.77,25.84,147.5 +4841,5,E06000059,2,55.37,170.85,25.84,185.7 +5472,5,E06000059,3,61.83,209.06,25.84,228.14 +6010,5,E06000059,4,71.06,358.66,25.84,391.56 +3345,6,E06000059,0,54.93,402.8,18.64,439.74 +3921,7,E06000059,1,47.06,134.77,25.84,147.5 +5118,7,E06000059,2,54.44,170.85,25.84,185.7 +5698,7,E06000059,3,61.83,209.06,25.84,228.14 +6410,7,E06000059,4,73.82,358.66,25.84,391.56 +3671,8,E06000059,0,54.93,402.8,18.64,439.74 +6605,9,E06000059,1,48.92,168.46,25.84,184.37 +6931,9,E06000059,2,55.37,213.57,25.84,232.15 +7257,9,E06000059,3,61.83,261.31,25.84,285.19 +7583,9,E06000059,4,71.06,448.34,25.84,489.48 +7909,10,E06000059,0,54.93,318.79,18.64,345.6 +78,1,E07000108,1,57.21,123.09,25.84,176.15 +404,1,E07000108,2,71.06,146.43,25.84,186.77 +730,1,E07000108,3,81.2,161.3,25.84,203.75 +1056,1,E07000108,4,89.52,178.28,25.84,221.77 +2686,2,E07000108,0,62.17,268.13,18.64,344.4 +1382,3,E07000108,1,51.68,115.66,25.84,159.17 +1708,3,E07000108,2,62.75,129.46,25.84,145.37 +2034,3,E07000108,3,68.28,149.62,25.84,185.7 +2360,3,E07000108,4,72.9,184.64,25.84,194.19 +3012,4,E07000108,0,48.71,195.45,18.64,204.96 +3996,5,E07000108,1,57.21,105.06,25.84,114.6 +4611,5,E07000108,2,71.06,142.18,25.84,154.93 +5263,5,E07000108,3,81.2,170.85,25.84,185.7 +5948,5,E07000108,4,89.52,237.69,25.84,258.92 +3338,6,E07000108,0,62.17,266.94,18.64,290.78 +4063,7,E07000108,1,51.68,105.06,25.84,114.6 +4758,7,E07000108,2,62.75,142.18,25.84,154.93 +5363,7,E07000108,3,68.28,170.85,25.84,185.7 +6052,7,E07000108,4,72.9,237.69,25.84,258.92 +3664,8,E07000108,0,48.71,266.94,18.64,290.78 +6598,9,E07000108,1,57.21,131.32,25.84,143.25 +6924,9,E07000108,2,71.06,177.73,25.84,193.64 +7250,9,E07000108,3,81.2,213.57,25.84,232.15 +7576,9,E07000108,4,89.52,297.12,25.84,323.65 +7902,10,E07000108,0,62.17,284.53,18.64,309.82 +79,1,E08000027,1,52.6,98.69,25.84,124.15 +405,1,E08000027,2,58.13,116.72,25.84,136.89 +731,1,E08000027,3,69.2,132.64,25.84,160.24 +1057,1,E08000027,4,80.28,161.3,25.84,178.28 +2687,2,E08000027,0,39.38,245.49,18.64,382.53 +1383,3,E08000027,1,46.13,88.07,25.84,97.63 +1709,3,E08000027,2,49.84,94.47,25.84,102.94 +2035,3,E08000027,3,59.98,104,25.84,119.9 +2361,3,E08000027,4,68.28,127.34,25.84,127.34 +3013,4,E08000027,0,46.63,107.26,18.64,107.26 +4285,5,E08000027,1,52.6,97.63,25.84,107.19 +4895,5,E08000027,2,58.13,119.9,25.84,130.52 +5526,5,E08000027,3,69.2,142.18,25.84,154.93 +6178,5,E08000027,4,80.28,192.07,25.84,210.12 +3339,6,E08000027,0,39.38,215.7,18.64,235.95 +4506,7,E08000027,1,46.13,97.63,25.84,107.19 +5191,7,E08000027,2,49.84,119.9,25.84,130.52 +5782,7,E08000027,3,59.98,142.18,25.84,154.93 +6443,7,E08000027,4,68.28,192.07,25.84,210.12 +3665,8,E08000027,0,46.63,215.7,18.64,235.95 +6599,9,E08000027,1,52.6,122.03,25.84,133.98 +6925,9,E08000027,2,58.13,149.9,25.84,163.15 +7251,9,E08000027,3,69.2,177.73,25.84,193.64 +7577,9,E08000027,4,80.28,240.08,25.84,262.64 +7903,10,E08000027,0,39.38,631.61,18.64,688.24 +81,1,E09000009,1,65.51,145.37,25.84,197.39 +407,1,E09000009,2,77.51,157.04,25.84,192.07 +733,1,E09000009,3,83.97,166.61,25.84,226.01 +1059,1,E09000009,4,101.48,186.77,25.84,251.49 +2689,2,E09000009,0,70.47,317,18.64,502.91 +1385,3,E09000009,1,58.13,118.85,25.84,146.43 +1711,3,E09000009,2,63.67,139.02,25.84,175.09 +2037,3,E09000009,3,71.06,159.17,25.84,200.55 +2363,3,E09000009,4,83.05,259.98,25.84,261.04 +3015,4,E09000009,0,60.1,371.82,18.64,402.8 +3958,5,E09000009,1,65.51,237.69,25.84,259.98 +4573,5,E09000009,2,77.51,316.23,25.84,344.88 +5225,5,E09000009,3,83.97,359.73,25.84,392.62 +5910,5,E09000009,4,101.48,608.05,25.84,662.16 +3341,6,E09000009,0,70.47,681.68,18.64,743.63 +4172,7,E09000009,1,58.13,237.69,25.84,259.98 +4673,7,E09000009,2,63.67,316.23,25.84,344.88 +5325,7,E09000009,3,71.06,359.73,25.84,392.62 +5877,7,E09000009,4,83.05,608.05,25.84,662.16 +3667,8,E09000009,0,60.1,681.68,18.64,743.63 +6601,9,E09000009,1,65.51,297.12,25.84,324.98 +6927,9,E09000009,2,77.51,395.3,25.84,431.1 +7253,9,E09000009,3,83.97,449.67,25.84,490.79 +7579,9,E09000009,4,101.48,760.06,25.84,827.71 +7905,10,E09000009,0,70.47,411.13,18.64,448.39 +82,1,E07000009,1,54.44,118.85,25.84,148.56 +408,1,E07000009,2,64.59,142.18,25.84,167.67 +734,1,E07000009,3,71.06,155.98,25.84,180.4 +1060,1,E07000009,4,81.2,170.85,25.84,178.28 +2690,2,E07000009,0,36.26,226.42,18.64,423.05 +1386,3,E07000009,1,49.84,99.75,25.84,131.58 +1712,3,E07000009,2,58.13,117.78,25.84,132.64 +2038,3,E07000009,3,63.67,130.52,25.84,143.25 +2364,3,E07000009,4,71.06,148.56,25.84,159.17 +3016,4,E07000009,0,55.97,135.86,18.64,318.19 +4131,5,E07000009,1,54.44,114.6,25.84,124.15 +4712,5,E07000009,2,64.59,142.18,25.84,154.93 +5431,5,E07000009,3,71.06,181.46,25.84,198.45 +6141,5,E07000009,4,81.2,304.55,25.84,332.14 +3342,6,E07000009,0,36.26,342.01,18.64,373.01 +4248,7,E07000009,1,49.84,114.6,25.84,124.15 +4974,7,E07000009,2,58.13,142.18,25.84,154.93 +5617,7,E07000009,3,63.67,181.46,25.84,198.45 +6279,7,E07000009,4,71.06,304.55,25.84,332.14 +3668,8,E07000009,0,55.97,342.01,18.64,373.01 +6602,9,E07000009,1,54.44,143.25,25.84,155.2 +6928,9,E07000009,2,64.59,177.73,25.84,193.64 +7254,9,E07000009,3,71.06,226.84,25.84,248.03 +7580,9,E07000009,4,81.2,380.68,25.84,415.17 +7906,10,E07000009,0,36.26,300.91,18.64,329.21 +84,1,E07000040,1,48.92,107.19,25.84,140.08 +410,1,E07000040,2,55.37,120.97,25.84,144.31 +736,1,E07000040,3,61.83,141.13,25.84,161.3 +1062,1,E07000040,4,71.06,158.1,25.84,194.19 +2692,2,E07000040,0,54.93,231.2,18.64,358.7 +1388,3,E07000040,1,47.06,89.13,25.84,210.12 +1714,3,E07000040,2,54.44,100.81,25.84,111.41 +2040,3,E07000040,3,61.83,109.29,25.84,126.28 +2366,3,E07000040,4,73.82,130.52,25.84,130.52 +3018,4,E07000040,0,54.93,115.59,18.64,141.81 +4204,5,E07000040,1,48.92,114.6,25.84,124.15 +4840,5,E07000040,2,55.37,147.5,25.84,160.24 +5471,5,E07000040,3,61.83,181.46,25.84,198.45 +6009,5,E07000040,4,71.06,281.2,25.84,306.68 +3344,6,E07000040,0,54.93,315.82,18.64,344.4 +3920,7,E07000040,1,47.06,114.6,25.84,124.15 +5117,7,E07000040,2,54.44,147.5,25.84,160.24 +5697,7,E07000040,3,61.83,181.46,25.84,198.45 +6409,7,E07000040,4,73.82,281.2,25.84,306.68 +3670,8,E07000040,0,54.93,315.82,18.64,344.4 +6604,9,E07000040,1,48.92,143.25,25.84,155.2 +6930,9,E07000040,2,55.37,184.37,25.84,200.32 +7256,9,E07000040,3,61.83,226.84,25.84,248.03 +7582,9,E07000040,4,71.06,351.51,25.84,383.34 +7908,10,E07000040,0,54.93,300.91,18.64,329.21 +86,1,E07000085,1,57.21,123.09,25.84,176.15 +412,1,E07000085,2,71.06,146.43,25.84,186.77 +738,1,E07000085,3,81.2,161.3,25.84,203.75 +1064,1,E07000085,4,89.52,178.28,25.84,221.77 +2694,2,E07000085,0,62.17,268.13,18.64,344.4 +1390,3,E07000085,1,51.68,115.66,25.84,159.17 +1716,3,E07000085,2,62.75,129.46,25.84,145.37 +2042,3,E07000085,3,68.28,149.62,25.84,185.7 +2368,3,E07000085,4,72.9,184.64,25.84,194.19 +3020,4,E07000085,0,48.71,195.45,18.64,204.96 +3997,5,E07000085,1,57.21,136.89,25.84,148.56 +4612,5,E07000085,2,71.06,180.4,25.84,197.39 +5264,5,E07000085,3,81.2,226.01,25.84,245.12 +5949,5,E07000085,4,89.52,404.3,25.84,440.37 +3346,6,E07000085,0,62.17,454.05,18.64,494.54 +4064,7,E07000085,1,51.68,136.89,25.84,148.56 +4759,7,E07000085,2,62.75,180.4,25.84,197.39 +5364,7,E07000085,3,68.28,226.01,25.84,245.12 +6053,7,E07000085,4,72.9,404.3,25.84,440.37 +3672,8,E07000085,0,48.71,454.05,18.64,494.54 +6606,9,E07000085,1,57.21,171.11,25.84,185.69 +6932,9,E07000085,2,71.06,225.52,25.84,246.73 +7258,9,E07000085,3,81.2,282.54,25.84,306.4 +7584,9,E07000085,4,89.52,505.39,25.84,550.49 +7910,10,E07000085,0,62.17,286.02,18.64,311.34 +87,1,E07000242,1,54.44,118.85,25.84,148.56 +413,1,E07000242,2,64.59,142.18,25.84,167.67 +739,1,E07000242,3,71.06,155.98,25.84,180.4 +1065,1,E07000242,4,81.2,170.85,25.84,178.28 +2695,2,E07000242,0,36.26,226.42,18.64,423.05 +1391,3,E07000242,1,49.84,99.75,25.84,131.58 +1717,3,E07000242,2,58.13,117.78,25.84,132.64 +2043,3,E07000242,3,63.67,130.52,25.84,143.25 +2369,3,E07000242,4,71.06,148.56,25.84,159.17 +3021,4,E07000242,0,55.97,135.86,18.64,318.19 +4132,5,E07000242,1,54.44,153.86,25.84,167.67 +4713,5,E07000242,2,64.59,192.07,25.84,210.12 +5432,5,E07000242,3,71.06,269.54,25.84,293.94 +6142,5,E07000242,4,81.2,393.68,25.84,428.71 +3347,6,E07000242,0,36.26,442.13,18.64,481.46 +4249,7,E07000242,1,49.84,153.86,25.84,167.67 +4975,7,E07000242,2,58.13,192.07,25.84,210.12 +5618,7,E07000242,3,63.67,269.54,25.84,293.94 +6280,7,E07000242,4,71.06,393.68,25.84,428.71 +3673,8,E07000242,0,55.97,442.13,18.64,481.46 +6607,9,E07000242,1,54.44,192.33,25.84,209.57 +6933,9,E07000242,2,64.59,240.08,25.84,262.64 +7259,9,E07000242,3,71.06,336.93,25.84,367.42 +7585,9,E07000242,4,81.2,492.12,25.84,535.89 +7911,10,E07000242,0,36.26,253.23,18.64,277.06 +88,1,E07000137,1,51.68,99.75,25.84,122.03 +414,1,E07000137,2,61.83,114.6,25.84,129.46 +740,1,E07000137,3,68.28,126.28,25.84,137.95 +1066,1,E07000137,4,75.67,158.1,25.84,166.61 +2696,2,E07000137,0,51.82,240.72,18.64,361.1 +1392,3,E07000137,1,46.13,90.21,25.84,107.19 +1718,3,E07000137,2,52.6,96.56,25.84,108.24 +2044,3,E07000137,3,58.13,104,25.84,118.85 +2370,3,E07000137,4,63.67,122.03,25.84,122.03 +3022,4,E07000137,0,49.74,114.39,18.64,123.94 +4324,5,E07000137,1,51.68,87.01,25.84,94.47 +5020,5,E07000137,2,61.83,109.29,25.84,118.85 +5663,5,E07000137,3,68.28,125.22,25.84,137.95 +6238,5,E07000137,4,75.67,159.17,25.84,174.02 +3348,6,E07000137,0,51.82,178.77,18.64,195.45 +4424,7,E07000137,1,46.13,87.01,25.84,94.47 +5160,7,E07000137,2,52.6,109.29,25.84,118.85 +5821,7,E07000137,3,58.13,125.22,25.84,137.95 +6482,7,E07000137,4,63.67,159.17,25.84,174.02 +3674,8,E07000137,0,49.74,178.77,18.64,195.45 +6608,9,E07000137,1,51.68,108.78,25.84,118.06 +6934,9,E07000137,2,61.83,136.63,25.84,148.56 +7260,9,E07000137,3,68.28,156.51,25.84,172.43 +7586,9,E07000137,4,75.67,198.96,25.84,217.54 +7912,10,E07000137,0,51.82,348.6,18.64,379.86 +90,1,E06000011,1,50.76,91.27,25.84,113.53 +416,1,E06000011,2,58.13,108.24,25.84,140.08 +742,1,E06000011,3,62.75,119.9,25.84,161.3 +1068,1,E06000011,4,72.9,144.31,25.84,178.28 +2698,2,E06000011,0,52.86,234.75,18.64,322.95 +1394,3,E06000011,1,46.13,81.71,25.84,92.33 +1720,3,E06000011,2,52.6,112.47,25.84,144.31 +2046,3,E06000011,3,56.29,104,25.84,113.53 +2372,3,E06000011,4,63.67,120.97,25.84,175.09 +3024,4,E06000011,0,51.82,160.88,18.64,190.67 +4395,5,E06000011,1,50.76,89.13,25.84,96.56 +4875,5,E06000011,2,58.13,112.47,25.84,122.03 +5506,5,E06000011,3,62.75,134.77,25.84,147.5 +6111,5,E06000011,4,72.9,186.77,25.84,203.75 +3350,6,E06000011,0,52.86,209.73,18.64,228.81 +4549,7,E06000011,1,46.13,89.13,25.84,96.56 +4817,7,E06000011,2,52.6,112.47,25.84,122.03 +5853,7,E06000011,3,56.29,134.77,25.84,147.5 +6209,7,E06000011,4,63.67,186.77,25.84,203.75 +3676,8,E06000011,0,51.82,209.73,18.64,228.81 +6610,9,E06000011,1,50.76,111.41,25.84,120.73 +6936,9,E06000011,2,52.6,140.6,25.84,152.55 +7262,9,E06000011,3,62.75,168.46,25.84,184.37 +7588,9,E06000011,4,72.9,233.46,25.84,254.69 +7914,10,E06000011,0,52.86,378.39,18.64,412.63 +91,1,E07000193,1,52.6,98.69,25.84,124.15 +417,1,E07000193,2,58.13,116.72,25.84,136.89 +743,1,E07000193,3,69.2,132.64,25.84,160.24 +1069,1,E07000193,4,80.28,161.3,25.84,178.28 +2699,2,E07000193,0,39.38,245.49,18.64,382.53 +1395,3,E07000193,1,46.13,88.07,25.84,97.63 +1721,3,E07000193,2,49.84,94.47,25.84,102.94 +2047,3,E07000193,3,59.98,104,25.84,119.9 +2373,3,E07000193,4,68.28,127.34,25.84,127.34 +3025,4,E07000193,0,46.63,107.26,18.64,107.26 +4286,5,E07000193,1,52.6,91.27,25.84,99.75 +4896,5,E07000193,2,58.13,114.6,25.84,124.15 +5527,5,E07000193,3,69.2,147.5,25.84,160.24 +6179,5,E07000193,4,80.28,203.75,25.84,221.77 +3351,6,E07000193,0,39.38,228.81,18.64,249.07 +4507,7,E07000193,1,46.13,91.27,25.84,99.75 +5192,7,E07000193,2,49.84,114.6,25.84,124.15 +5783,7,E07000193,3,59.98,147.5,25.84,160.24 +6444,7,E07000193,4,68.28,203.75,25.84,221.77 +3677,8,E07000193,0,46.63,228.81,18.64,249.07 +6611,9,E07000193,1,52.6,114.09,25.84,124.69 +6937,9,E07000193,2,58.13,143.25,25.84,155.2 +7263,9,E07000193,3,69.2,184.37,25.84,200.32 +7589,9,E07000193,4,80.28,254.69,25.84,277.23 +7915,10,E07000193,0,39.38,347.11,18.64,379.86 +264,1,E07000244,1,54.44,118.85,25.84,148.56 +590,1,E07000244,2,64.59,142.18,25.84,167.67 +916,1,E07000244,3,71.06,155.98,25.84,180.4 +1242,1,E07000244,4,81.2,170.85,25.84,178.28 +2872,2,E07000244,0,36.26,226.42,18.64,423.05 +1568,3,E07000244,1,49.84,99.75,25.84,131.58 +1894,3,E07000244,2,58.13,117.78,25.84,132.64 +2220,3,E07000244,3,63.67,130.52,25.84,143.25 +2546,3,E07000244,4,71.06,148.56,25.84,159.17 +3198,4,E07000244,0,55.97,135.86,18.64,318.19 +4156,5,E07000244,1,54.44,105.06,25.84,114.6 +4737,5,E07000244,2,64.59,125.22,25.84,136.89 +5456,5,E07000244,3,71.06,153.86,25.84,167.67 +6166,5,E07000244,4,81.2,227.08,25.84,246.18 +3524,6,E07000244,0,36.26,255.02,18.64,276.48 +4273,7,E07000244,1,49.84,105.06,25.84,114.6 +4999,7,E07000244,2,58.13,125.22,25.84,136.89 +5642,7,E07000244,3,63.67,153.86,25.84,167.67 +6304,7,E07000244,4,71.06,227.08,25.84,246.18 +3850,8,E07000244,0,55.97,255.02,18.64,276.48 +6784,9,E07000244,1,54.44,131.32,25.84,143.25 +7110,9,E07000244,2,64.59,156.51,25.84,171.11 +7436,9,E07000244,3,71.06,192.33,25.84,209.57 +7762,9,E07000244,4,81.2,283.85,25.84,307.73 +8088,10,E07000244,0,36.26,443.93,18.64,484.13 +92,1,E07000061,1,57.21,123.09,25.84,176.15 +418,1,E07000061,2,71.06,146.43,25.84,186.77 +744,1,E07000061,3,81.2,161.3,25.84,203.75 +1070,1,E07000061,4,89.52,178.28,25.84,221.77 +2700,2,E07000061,0,62.17,268.13,18.64,344.4 +1396,3,E07000061,1,51.68,115.66,25.84,159.17 +1722,3,E07000061,2,62.75,129.46,25.84,145.37 +2048,3,E07000061,3,68.28,149.62,25.84,185.7 +2374,3,E07000061,4,72.9,184.64,25.84,194.19 +3026,4,E07000061,0,48.71,195.45,18.64,204.96 +3998,5,E07000061,1,57.21,130.52,25.84,143.25 +4613,5,E07000061,2,71.06,170.85,25.84,185.7 +5265,5,E07000061,3,81.2,209.06,25.84,228.14 +5950,5,E07000061,4,89.52,472.21,25.84,514.66 +3352,6,E07000061,0,62.17,530.31,18.64,578 +4065,7,E07000061,1,51.68,130.52,25.84,143.25 +4760,7,E07000061,2,62.75,170.85,25.84,185.7 +5365,7,E07000061,3,68.28,209.06,25.84,228.14 +6054,7,E07000061,4,72.9,472.21,25.84,514.66 +3678,8,E07000061,0,48.71,530.31,18.64,578 +6612,9,E07000061,1,57.21,163.15,25.84,179.06 +6938,9,E07000061,2,71.06,213.57,25.84,232.15 +7264,9,E07000061,3,81.2,261.31,25.84,285.19 +7590,9,E07000061,4,89.52,590.27,25.84,643.34 +7916,10,E07000061,0,62.17,379.86,18.64,414.12 +93,1,E07000086,1,57.21,123.09,25.84,176.15 +419,1,E07000086,2,71.06,146.43,25.84,186.77 +745,1,E07000086,3,81.2,161.3,25.84,203.75 +1071,1,E07000086,4,89.52,178.28,25.84,221.77 +2701,2,E07000086,0,62.17,268.13,18.64,344.4 +1397,3,E07000086,1,51.68,115.66,25.84,159.17 +1723,3,E07000086,2,62.75,129.46,25.84,145.37 +2049,3,E07000086,3,68.28,149.62,25.84,185.7 +2375,3,E07000086,4,72.9,184.64,25.84,194.19 +3027,4,E07000086,0,48.71,195.45,18.64,204.96 +3999,5,E07000086,1,57.21,134.77,25.84,147.5 +4614,5,E07000086,2,71.06,164.48,25.84,179.34 +5266,5,E07000086,3,81.2,202.69,25.84,220.72 +5951,5,E07000086,4,89.52,306.68,25.84,334.25 +3353,6,E07000086,0,62.17,343.2,18.64,375.37 +4066,7,E07000086,1,51.68,134.77,25.84,147.5 +4761,7,E07000086,2,62.75,164.48,25.84,179.34 +5366,7,E07000086,3,68.28,202.69,25.84,220.72 +6055,7,E07000086,4,72.9,306.68,25.84,334.25 +3679,8,E07000086,0,48.71,343.2,18.64,375.37 +6613,9,E07000086,1,57.21,168.46,25.84,184.37 +6939,9,E07000086,2,71.06,205.6,25.84,224.18 +7265,9,E07000086,3,81.2,253.36,25.84,275.9 +7591,9,E07000086,4,89.52,383.34,25.84,417.83 +7917,10,E07000086,0,62.17,503.5,18.64,549.69 +95,1,E07000207,1,57.21,123.09,25.84,176.15 +421,1,E07000207,2,71.06,146.43,25.84,186.77 +747,1,E07000207,3,81.2,161.3,25.84,203.75 +1073,1,E07000207,4,89.52,178.28,25.84,221.77 +2703,2,E07000207,0,62.17,268.13,18.64,344.4 +1399,3,E07000207,1,51.68,115.66,25.84,159.17 +1725,3,E07000207,2,62.75,129.46,25.84,145.37 +2051,3,E07000207,3,68.28,149.62,25.84,185.7 +2377,3,E07000207,4,72.9,184.64,25.84,194.19 +3029,4,E07000207,0,48.71,195.45,18.64,204.96 +4000,5,E07000207,1,57.21,186.77,25.84,203.75 +4615,5,E07000207,2,71.06,270.61,25.84,295.01 +5267,5,E07000207,3,81.2,326.84,25.84,356.55 +5952,5,E07000207,4,89.52,751.3,25.84,819.21 +3355,6,E07000207,0,62.17,843.74,18.64,920.01 +4067,7,E07000207,1,51.68,186.77,25.84,203.75 +4762,7,E07000207,2,62.75,270.61,25.84,295.01 +5367,7,E07000207,3,68.28,326.84,25.84,356.55 +6056,7,E07000207,4,72.9,751.3,25.84,819.21 +3681,8,E07000207,0,48.71,843.74,18.64,920.01 +6615,9,E07000207,1,57.21,233.46,25.84,254.69 +6941,9,E07000207,2,71.06,338.25,25.84,368.76 +7267,9,E07000207,3,81.2,408.54,25.84,445.68 +7593,9,E07000207,4,89.52,939.12,25.84,1024.03 +7919,10,E07000207,0,62.17,473.7,18.64,516.92 +96,1,E09000010,1,65.51,145.37,25.84,197.39 +422,1,E09000010,2,77.51,157.04,25.84,192.07 +748,1,E09000010,3,83.97,166.61,25.84,226.01 +1074,1,E09000010,4,101.48,186.77,25.84,251.49 +2704,2,E09000010,0,70.47,317,18.64,502.91 +1400,3,E09000010,1,58.13,118.85,25.84,146.43 +1726,3,E09000010,2,63.67,139.02,25.84,175.09 +2052,3,E09000010,3,71.06,159.17,25.84,200.55 +2378,3,E09000010,4,83.05,259.98,25.84,261.04 +3030,4,E09000010,0,60.1,371.82,18.64,402.8 +3959,5,E09000010,1,65.51,186.77,25.84,203.75 +4574,5,E09000010,2,77.51,259.98,25.84,282.26 +5226,5,E09000010,3,83.97,304.55,25.84,332.14 +5911,5,E09000010,4,101.48,426.59,25.84,465.84 +3356,6,E09000010,0,70.47,479.07,18.64,523.16 +4173,7,E09000010,1,58.13,186.77,25.84,203.75 +4674,7,E09000010,2,63.67,259.98,25.84,282.26 +5326,7,E09000010,3,71.06,304.55,25.84,332.14 +5878,7,E09000010,4,83.05,426.59,25.84,465.84 +3682,8,E09000010,0,60.1,479.07,18.64,523.16 +6616,9,E09000010,1,65.51,233.46,25.84,254.69 +6942,9,E09000010,2,77.51,324.98,25.84,352.84 +7268,9,E09000010,3,83.97,380.68,25.84,415.17 +7594,9,E09000010,4,101.48,533.22,25.84,582.31 +7920,10,E09000010,0,70.47,308.35,18.64,336.65 +97,1,E07000072,1,54.44,118.85,25.84,148.56 +423,1,E07000072,2,64.59,142.18,25.84,167.67 +749,1,E07000072,3,71.06,155.98,25.84,180.4 +1075,1,E07000072,4,81.2,170.85,25.84,178.28 +2705,2,E07000072,0,36.26,226.42,18.64,423.05 +1401,3,E07000072,1,49.84,99.75,25.84,131.58 +1727,3,E07000072,2,58.13,117.78,25.84,132.64 +2053,3,E07000072,3,63.67,130.52,25.84,143.25 +2379,3,E07000072,4,71.06,148.56,25.84,159.17 +3031,4,E07000072,0,55.97,135.86,18.64,318.19 +4133,5,E07000072,1,54.44,170.85,25.84,185.7 +4714,5,E07000072,2,64.59,227.08,25.84,246.18 +5433,5,E07000072,3,71.06,292.87,25.84,319.41 +6143,5,E07000072,4,81.2,494.49,25.84,539.06 +3357,6,E07000072,0,36.26,555.35,18.64,605.39 +4250,7,E07000072,1,49.84,170.85,25.84,185.7 +4976,7,E07000072,2,58.13,227.08,25.84,246.18 +5619,7,E07000072,3,63.67,292.87,25.84,319.41 +6281,7,E07000072,4,71.06,494.49,25.84,539.06 +3683,8,E07000072,0,55.97,555.35,18.64,605.39 +6617,9,E07000072,1,54.44,213.57,25.84,232.15 +6943,9,E07000072,2,64.59,283.85,25.84,307.73 +7269,9,E07000072,3,71.06,366.11,25.84,399.27 +7595,9,E07000072,4,81.2,618.12,25.84,673.83 +7921,10,E07000072,0,36.26,372.42,18.64,406.69 +98,1,E07000208,1,57.21,123.09,25.84,176.15 +424,1,E07000208,2,71.06,146.43,25.84,186.77 +750,1,E07000208,3,81.2,161.3,25.84,203.75 +1076,1,E07000208,4,89.52,178.28,25.84,221.77 +2706,2,E07000208,0,62.17,268.13,18.64,344.4 +1402,3,E07000208,1,51.68,115.66,25.84,159.17 +1728,3,E07000208,2,62.75,129.46,25.84,145.37 +2054,3,E07000208,3,68.28,149.62,25.84,185.7 +2380,3,E07000208,4,72.9,184.64,25.84,194.19 +3032,4,E07000208,0,48.71,195.45,18.64,204.96 +4001,5,E07000208,1,57.21,186.77,25.84,203.75 +4616,5,E07000208,2,71.06,248.31,25.84,270.61 +5268,5,E07000208,3,81.2,337.44,25.84,368.22 +5953,5,E07000208,4,89.52,523.16,25.84,569.84 +3358,6,E07000208,0,62.17,587.54,18.64,639.96 +4068,7,E07000208,1,51.68,186.77,25.84,203.75 +4763,7,E07000208,2,62.75,248.31,25.84,270.61 +5368,7,E07000208,3,68.28,337.44,25.84,368.22 +6057,7,E07000208,4,72.9,523.16,25.84,569.84 +3684,8,E07000208,0,48.71,587.54,18.64,639.96 +6618,9,E07000208,1,57.21,233.46,25.84,254.69 +6944,9,E07000208,2,71.06,310.37,25.84,338.25 +7270,9,E07000208,3,81.2,421.8,25.84,460.26 +7596,9,E07000208,4,89.52,653.94,25.84,712.3 +7922,10,E07000208,0,62.17,293.46,18.64,320.27 +99,1,E07000036,1,51.68,99.75,25.84,122.03 +425,1,E07000036,2,61.83,114.6,25.84,129.46 +751,1,E07000036,3,68.28,126.28,25.84,137.95 +1077,1,E07000036,4,75.67,158.1,25.84,166.61 +2707,2,E07000036,0,51.82,240.72,18.64,361.1 +1403,3,E07000036,1,46.13,90.21,25.84,107.19 +1729,3,E07000036,2,52.6,96.56,25.84,108.24 +2055,3,E07000036,3,58.13,104,25.84,118.85 +2381,3,E07000036,4,63.67,122.03,25.84,122.03 +3033,4,E07000036,0,49.74,114.39,18.64,123.94 +4326,5,E07000036,1,51.68,91.27,25.84,98.69 +5022,5,E07000036,2,61.83,113.53,25.84,123.09 +5665,5,E07000036,3,68.28,130.52,25.84,143.25 +6240,5,E07000036,4,75.67,203.75,25.84,221.77 +3359,6,E07000036,0,51.82,228.81,18.64,249.07 +4426,7,E07000036,1,46.13,91.27,25.84,98.69 +5162,7,E07000036,2,52.6,113.53,25.84,123.09 +5823,7,E07000036,3,58.13,130.52,25.84,143.25 +6484,7,E07000036,4,63.67,203.75,25.84,221.77 +3685,8,E07000036,0,49.74,228.81,18.64,249.07 +6619,9,E07000036,1,51.68,114.09,25.84,123.35 +6945,9,E07000036,2,61.83,141.94,25.84,153.86 +7271,9,E07000036,3,68.28,163.15,25.84,179.06 +7597,9,E07000036,4,75.67,254.69,25.84,277.23 +7923,10,E07000036,0,51.82,881.9,18.64,962.3 +100,1,E07000041,1,48.92,107.19,25.84,140.08 +426,1,E07000041,2,55.37,120.97,25.84,144.31 +752,1,E07000041,3,61.83,141.13,25.84,161.3 +1078,1,E07000041,4,71.06,158.1,25.84,194.19 +2708,2,E07000041,0,54.93,231.2,18.64,358.7 +1404,3,E07000041,1,47.06,89.13,25.84,210.12 +1730,3,E07000041,2,54.44,100.81,25.84,111.41 +2056,3,E07000041,3,61.83,109.29,25.84,126.28 +2382,3,E07000041,4,73.82,130.52,25.84,130.52 +3034,4,E07000041,0,54.93,115.59,18.64,141.81 +4206,5,E07000041,1,48.92,134.77,25.84,147.5 +4842,5,E07000041,2,55.37,164.48,25.84,179.34 +5473,5,E07000041,3,61.83,203.75,25.84,220.72 +6011,5,E07000041,4,71.06,481.75,25.84,526.35 +3360,6,E07000041,0,54.93,541.04,18.64,591.1 +3922,7,E07000041,1,47.06,134.77,25.84,147.5 +5119,7,E07000041,2,54.44,164.48,25.84,179.34 +5699,7,E07000041,3,61.83,203.75,25.84,220.72 +6411,7,E07000041,4,73.82,481.75,25.84,526.35 +3686,8,E07000041,0,54.93,541.04,18.64,591.1 +6620,9,E07000041,1,48.92,168.46,25.84,184.37 +6946,9,E07000041,2,55.37,205.6,25.84,224.18 +7272,9,E07000041,3,61.83,254.69,25.84,275.9 +7598,9,E07000041,4,71.06,602.21,25.84,657.9 +7924,10,E07000041,0,54.93,308.35,18.64,336.65 +101,1,E07000087,1,57.21,123.09,25.84,176.15 +427,1,E07000087,2,71.06,146.43,25.84,186.77 +753,1,E07000087,3,81.2,161.3,25.84,203.75 +1079,1,E07000087,4,89.52,178.28,25.84,221.77 +2709,2,E07000087,0,62.17,268.13,18.64,344.4 +1405,3,E07000087,1,51.68,115.66,25.84,159.17 +1731,3,E07000087,2,62.75,129.46,25.84,145.37 +2057,3,E07000087,3,68.28,149.62,25.84,185.7 +2383,3,E07000087,4,72.9,184.64,25.84,194.19 +3035,4,E07000087,0,48.71,195.45,18.64,204.96 +4002,5,E07000087,1,57.21,134.77,25.84,147.5 +4617,5,E07000087,2,71.06,164.48,25.84,179.34 +5269,5,E07000087,3,81.2,202.69,25.84,220.72 +5954,5,E07000087,4,89.52,315.17,25.84,342.76 +3361,6,E07000087,0,62.17,353.92,18.64,384.93 +4069,7,E07000087,1,51.68,134.77,25.84,147.5 +4764,7,E07000087,2,62.75,164.48,25.84,179.34 +5369,7,E07000087,3,68.28,202.69,25.84,220.72 +6058,7,E07000087,4,72.9,315.17,25.84,342.76 +3687,8,E07000087,0,48.71,353.92,18.64,384.93 +6621,9,E07000087,1,57.21,168.46,25.84,184.37 +6947,9,E07000087,2,71.06,205.6,25.84,224.18 +7273,9,E07000087,3,81.2,253.36,25.84,275.9 +7599,9,E07000087,4,89.52,393.95,25.84,428.42 +7925,10,E07000087,0,62.17,254.72,18.64,278.57 +102,1,E07000010,1,54.44,118.85,25.84,148.56 +428,1,E07000010,2,64.59,142.18,25.84,167.67 +754,1,E07000010,3,71.06,155.98,25.84,180.4 +1080,1,E07000010,4,81.2,170.85,25.84,178.28 +2710,2,E07000010,0,36.26,226.42,18.64,423.05 +1406,3,E07000010,1,49.84,99.75,25.84,131.58 +1732,3,E07000010,2,58.13,117.78,25.84,132.64 +2058,3,E07000010,3,63.67,130.52,25.84,143.25 +2384,3,E07000010,4,71.06,148.56,25.84,159.17 +3036,4,E07000010,0,55.97,135.86,18.64,318.19 +4134,5,E07000010,1,54.44,95.53,25.84,104 +4715,5,E07000010,2,64.59,125.22,25.84,136.89 +5434,5,E07000010,3,71.06,147.5,25.84,160.24 +6144,5,E07000010,4,81.2,192.07,25.84,210.12 +3362,6,E07000010,0,36.26,215.7,18.64,235.95 +4251,7,E07000010,1,49.84,95.53,25.84,104 +4977,7,E07000010,2,58.13,125.22,25.84,136.89 +5620,7,E07000010,3,63.67,147.5,25.84,160.24 +6282,7,E07000010,4,71.06,192.07,25.84,210.12 +3688,8,E07000010,0,55.97,215.7,18.64,235.95 +6622,9,E07000010,1,54.44,119.38,25.84,129.98 +6948,9,E07000010,2,64.59,156.51,25.84,171.11 +7274,9,E07000010,3,71.06,184.37,25.84,200.32 +7600,9,E07000010,4,81.2,240.08,25.84,262.64 +7926,10,E07000010,0,36.26,341.13,18.64,372.42 +104,1,E07000080,1,48.92,107.19,25.84,140.08 +430,1,E07000080,2,55.37,120.97,25.84,144.31 +756,1,E07000080,3,61.83,141.13,25.84,161.3 +1082,1,E07000080,4,71.06,158.1,25.84,194.19 +2712,2,E07000080,0,54.93,231.2,18.64,358.7 +1408,3,E07000080,1,47.06,89.13,25.84,210.12 +1734,3,E07000080,2,54.44,100.81,25.84,111.41 +2060,3,E07000080,3,61.83,109.29,25.84,126.28 +2386,3,E07000080,4,73.82,130.52,25.84,130.52 +3038,4,E07000080,0,54.93,115.59,18.64,141.81 +4207,5,E07000080,1,48.92,97.63,25.84,107.19 +4843,5,E07000080,2,55.37,126.28,25.84,137.95 +5474,5,E07000080,3,61.83,147.5,25.84,160.24 +6012,5,E07000080,4,71.06,203.75,25.84,221.77 +3364,6,E07000080,0,54.93,228.81,18.64,249.07 +3923,7,E07000080,1,47.06,97.63,25.84,107.19 +5120,7,E07000080,2,54.44,126.28,25.84,137.95 +5700,7,E07000080,3,61.83,147.5,25.84,160.24 +6412,7,E07000080,4,73.82,203.75,25.84,221.77 +3690,8,E07000080,0,54.93,228.81,18.64,249.07 +6624,9,E07000080,1,48.92,122.03,25.84,133.98 +6950,9,E07000080,2,55.37,157.85,25.84,172.43 +7276,9,E07000080,3,61.83,184.37,25.84,200.32 +7602,9,E07000080,4,71.06,254.69,25.84,277.23 +7928,10,E07000080,0,54.93,403.71,18.64,437.96 +105,1,E07000119,1,51.68,93.39,25.84,116.72 +431,1,E07000119,2,59.06,107.19,25.84,134.77 +757,1,E07000119,3,65.51,119.9,25.84,145.37 +1083,1,E07000119,4,71.98,133.71,25.84,159.17 +2713,2,E07000119,0,55.97,239.54,18.64,342.01 +1409,3,E07000119,1,43.36,85.94,25.84,100.81 +1735,3,E07000119,2,53.52,94.47,25.84,113.53 +2061,3,E07000119,3,58.13,105.06,25.84,124.15 +2387,3,E07000119,4,55.37,118.85,25.84,133.71 +3039,4,E07000119,0,33.16,469.54,18.64,599.44 +4365,5,E07000119,1,51.68,102.94,25.84,112.47 +4935,5,E07000119,2,59.06,136.89,25.84,148.56 +5578,5,E07000119,3,65.51,170.85,25.84,185.7 +6326,5,E07000119,4,71.98,248.31,25.84,270.61 +3365,6,E07000119,0,55.97,278.86,18.64,303.89 +4477,7,E07000119,1,43.36,102.94,25.84,112.47 +5073,7,E07000119,2,53.52,136.89,25.84,148.56 +5753,7,E07000119,3,58.13,170.85,25.84,185.7 +6377,7,E07000119,4,55.37,248.31,25.84,270.61 +3691,8,E07000119,0,33.16,278.86,18.64,303.89 +6625,9,E07000119,1,51.68,128.67,25.84,140.6 +6951,9,E07000119,2,59.06,171.11,25.84,185.69 +7277,9,E07000119,3,65.51,213.57,25.84,232.15 +7603,9,E07000119,4,71.98,310.37,25.84,338.25 +7929,10,E07000119,0,55.97,473.7,18.64,516.92 +106,1,E08000037,1,50.76,88.07,25.84,97.63 +432,1,E08000037,2,57.21,101.88,25.84,119.9 +758,1,E08000037,3,60.9,113.53,25.84,159.17 +1084,1,E08000037,4,70.13,127.34,25.84,139.02 +2714,2,E08000037,0,55.97,237.14,18.64,340.83 +1410,3,E08000037,1,42.44,99.75,25.84,105.06 +1736,3,E08000037,2,49.84,90.21,25.84,111.41 +2062,3,E08000037,3,53.52,105.06,25.84,124.15 +2388,3,E08000037,4,56.29,115.66,25.84,119.9 +3040,4,E08000037,0,47.67,253.84,18.64,288.39 +4534,5,E08000037,1,50.76,113.53,25.84,123.09 +5049,5,E08000037,2,57.21,119.9,25.84,130.52 +5554,5,E08000037,3,60.9,142.18,25.84,154.93 +6353,5,E08000037,4,70.13,192.07,25.84,210.12 +3366,6,E08000037,0,55.97,215.7,18.64,235.95 +4453,7,E08000037,1,42.44,113.53,25.84,123.09 +5100,7,E08000037,2,49.84,119.9,25.84,130.52 +5729,7,E08000037,3,53.52,142.18,25.84,154.93 +6511,7,E08000037,4,56.29,192.07,25.84,210.12 +3692,8,E08000037,0,47.67,215.7,18.64,235.95 +6626,9,E08000037,1,42.44,141.94,25.84,153.86 +6952,9,E08000037,2,57.21,149.9,25.84,163.15 +7278,9,E08000037,3,60.9,177.73,25.84,193.64 +7604,9,E08000037,4,70.13,240.08,25.84,262.64 +7930,10,E08000037,0,55.97,379.86,18.64,414.12 +107,1,E07000173,1,51.68,99.75,25.84,122.03 +433,1,E07000173,2,61.83,114.6,25.84,129.46 +759,1,E07000173,3,68.28,126.28,25.84,137.95 +1085,1,E07000173,4,75.67,158.1,25.84,166.61 +2715,2,E07000173,0,51.82,240.72,18.64,361.1 +1411,3,E07000173,1,46.13,90.21,25.84,107.19 +1737,3,E07000173,2,52.6,96.56,25.84,108.24 +2063,3,E07000173,3,58.13,104,25.84,118.85 +2389,3,E07000173,4,63.67,122.03,25.84,122.03 +3041,4,E07000173,0,49.74,114.39,18.64,123.94 +4327,5,E07000173,1,51.68,102.94,25.84,112.47 +5023,5,E07000173,2,61.83,119.9,25.84,130.52 +5666,5,E07000173,3,68.28,146.43,25.84,158.1 +6241,5,E07000173,4,75.67,202.69,25.84,220.72 +3367,6,E07000173,0,51.82,227.63,18.64,247.88 +4427,7,E07000173,1,46.13,102.94,25.84,112.47 +5163,7,E07000173,2,52.6,119.9,25.84,130.52 +5824,7,E07000173,3,58.13,146.43,25.84,158.1 +6485,7,E07000173,4,63.67,202.69,25.84,220.72 +3693,8,E07000173,0,49.74,227.63,18.64,247.88 +6627,9,E07000173,1,51.68,128.67,25.84,140.6 +6953,9,E07000173,2,61.83,149.9,25.84,163.15 +7279,9,E07000173,3,68.28,183.04,25.84,197.62 +7605,9,E07000173,4,75.67,253.36,25.84,275.9 +7931,10,E07000173,0,51.82,756.74,18.64,825.27 +108,1,E07000081,1,48.92,107.19,25.84,140.08 +434,1,E07000081,2,55.37,120.97,25.84,144.31 +760,1,E07000081,3,61.83,141.13,25.84,161.3 +1086,1,E07000081,4,71.06,158.1,25.84,194.19 +2716,2,E07000081,0,54.93,231.2,18.64,358.7 +1412,3,E07000081,1,47.06,89.13,25.84,210.12 +1738,3,E07000081,2,54.44,100.81,25.84,111.41 +2064,3,E07000081,3,61.83,109.29,25.84,126.28 +2390,3,E07000081,4,73.82,130.52,25.84,130.52 +3042,4,E07000081,0,54.93,115.59,18.64,141.81 +4208,5,E07000081,1,48.92,109.29,25.84,118.85 +4844,5,E07000081,2,55.37,130.52,25.84,143.25 +5475,5,E07000081,3,61.83,164.48,25.84,179.34 +6013,5,E07000081,4,71.06,248.31,25.84,270.61 +3368,6,E07000081,0,54.93,278.86,18.64,303.89 +3924,7,E07000081,1,47.06,109.29,25.84,118.85 +5121,7,E07000081,2,54.44,130.52,25.84,143.25 +5701,7,E07000081,3,61.83,164.48,25.84,179.34 +6413,7,E07000081,4,73.82,248.31,25.84,270.61 +3694,8,E07000081,0,54.93,278.86,18.64,303.89 +6628,9,E07000081,1,48.92,136.63,25.84,148.56 +6954,9,E07000081,2,55.37,163.15,25.84,179.06 +7280,9,E07000081,3,61.83,205.6,25.84,224.18 +7606,9,E07000081,4,71.06,310.37,25.84,338.25 +7932,10,E07000081,0,54.93,372.42,18.64,406.69 +109,1,E07000088,1,57.21,123.09,25.84,176.15 +435,1,E07000088,2,71.06,146.43,25.84,186.77 +761,1,E07000088,3,81.2,161.3,25.84,203.75 +1087,1,E07000088,4,89.52,178.28,25.84,221.77 +2717,2,E07000088,0,62.17,268.13,18.64,344.4 +1413,3,E07000088,1,51.68,115.66,25.84,159.17 +1739,3,E07000088,2,62.75,129.46,25.84,145.37 +2065,3,E07000088,3,68.28,149.62,25.84,185.7 +2391,3,E07000088,4,72.9,184.64,25.84,194.19 +3043,4,E07000088,0,48.71,195.45,18.64,204.96 +4003,5,E07000088,1,57.21,125.22,25.84,136.89 +4618,5,E07000088,2,71.06,147.5,25.84,160.24 +5270,5,E07000088,3,81.2,176.15,25.84,191.01 +5955,5,E07000088,4,89.52,281.2,25.84,306.68 +3369,6,E07000088,0,62.17,315.82,18.64,344.4 +4070,7,E07000088,1,51.68,125.22,25.84,136.89 +4765,7,E07000088,2,62.75,147.5,25.84,160.24 +5370,7,E07000088,3,68.28,176.15,25.84,191.01 +6059,7,E07000088,4,72.9,281.2,25.84,306.68 +3695,8,E07000088,0,48.71,315.82,18.64,344.4 +6629,9,E07000088,1,57.21,156.51,25.84,171.11 +6955,9,E07000088,2,71.06,184.37,25.84,200.32 +7281,9,E07000088,3,81.2,220.21,25.84,238.77 +7607,9,E07000088,4,89.52,351.51,25.84,383.34 +7933,10,E07000088,0,62.17,239.85,18.64,260.68 +110,1,E07000109,1,57.21,123.09,25.84,176.15 +436,1,E07000109,2,71.06,146.43,25.84,186.77 +762,1,E07000109,3,81.2,161.3,25.84,203.75 +1088,1,E07000109,4,89.52,178.28,25.84,221.77 +2718,2,E07000109,0,62.17,268.13,18.64,344.4 +1414,3,E07000109,1,51.68,115.66,25.84,159.17 +1740,3,E07000109,2,62.75,129.46,25.84,145.37 +2066,3,E07000109,3,68.28,149.62,25.84,185.7 +2392,3,E07000109,4,72.9,184.64,25.84,194.19 +3044,4,E07000109,0,48.71,195.45,18.64,204.96 +4004,5,E07000109,1,57.21,125.22,25.84,136.89 +4619,5,E07000109,2,71.06,159.17,25.84,174.02 +5271,5,E07000109,3,81.2,186.77,25.84,203.75 +5956,5,E07000109,4,89.52,270.61,25.84,295.01 +3370,6,E07000109,0,62.17,303.89,18.64,331.29 +4071,7,E07000109,1,51.68,125.22,25.84,136.89 +4766,7,E07000109,2,62.75,159.17,25.84,174.02 +5371,7,E07000109,3,68.28,186.77,25.84,203.75 +6060,7,E07000109,4,72.9,270.61,25.84,295.01 +3696,8,E07000109,0,48.71,303.89,18.64,331.29 +6630,9,E07000109,1,57.21,156.51,25.84,171.11 +6956,9,E07000109,2,71.06,198.96,25.84,217.54 +7282,9,E07000109,3,81.2,233.46,25.84,254.69 +7608,9,E07000109,4,89.52,338.25,25.84,368.76 +7934,10,E07000109,0,62.17,394.77,18.64,430.5 +111,1,E07000145,1,54.44,118.85,25.84,148.56 +437,1,E07000145,2,64.59,142.18,25.84,167.67 +763,1,E07000145,3,71.06,155.98,25.84,180.4 +1089,1,E07000145,4,81.2,170.85,25.84,178.28 +2719,2,E07000145,0,36.26,226.42,18.64,423.05 +1415,3,E07000145,1,49.84,99.75,25.84,131.58 +1741,3,E07000145,2,58.13,117.78,25.84,132.64 +2067,3,E07000145,3,63.67,130.52,25.84,143.25 +2393,3,E07000145,4,71.06,148.56,25.84,159.17 +3045,4,E07000145,0,55.97,135.86,18.64,318.19 +4136,5,E07000145,1,54.44,98.69,25.84,108.24 +4717,5,E07000145,2,64.59,119.9,25.84,130.52 +5436,5,E07000145,3,71.06,130.52,25.84,142.18 +6146,5,E07000145,4,81.2,171.91,25.84,186.77 +3371,6,E07000145,0,36.26,193.06,18.64,209.73 +4253,7,E07000145,1,49.84,98.69,25.84,108.24 +4979,7,E07000145,2,58.13,119.9,25.84,130.52 +5622,7,E07000145,3,63.67,130.52,25.84,142.18 +6284,7,E07000145,4,71.06,171.91,25.84,186.77 +3697,8,E07000145,0,55.97,193.06,18.64,209.73 +6631,9,E07000145,1,54.44,123.35,25.84,135.3 +6957,9,E07000145,2,64.59,149.9,25.84,163.15 +7283,9,E07000145,3,71.06,163.15,25.84,177.73 +7609,9,E07000145,4,81.2,214.91,25.84,233.46 +7935,10,E07000145,0,36.26,254.72,18.64,278.57 +112,1,E09000011,1,65.51,145.37,25.84,197.39 +438,1,E09000011,2,77.51,157.04,25.84,192.07 +764,1,E09000011,3,83.97,166.61,25.84,226.01 +1090,1,E09000011,4,101.48,186.77,25.84,251.49 +2720,2,E09000011,0,70.47,317,18.64,502.91 +1416,3,E09000011,1,58.13,118.85,25.84,146.43 +1742,3,E09000011,2,63.67,139.02,25.84,175.09 +2068,3,E09000011,3,71.06,159.17,25.84,200.55 +2394,3,E09000011,4,83.05,259.98,25.84,261.04 +3046,4,E09000011,0,60.1,371.82,18.64,402.8 +3960,5,E09000011,1,65.51,198.45,25.84,215.41 +4575,5,E09000011,2,77.51,281.2,25.84,306.68 +5227,5,E09000011,3,83.97,292.87,25.84,319.41 +5912,5,E09000011,4,101.48,383.08,25.84,417.04 +3372,6,E09000011,0,70.47,430.21,18.64,468.35 +4174,7,E09000011,1,58.13,198.45,25.84,215.41 +4675,7,E09000011,2,63.67,281.2,25.84,306.68 +5327,7,E09000011,3,71.06,292.87,25.84,319.41 +5879,7,E09000011,4,83.05,383.08,25.84,417.04 +3698,8,E09000011,0,60.1,430.21,18.64,468.35 +6632,9,E09000011,1,65.51,248.03,25.84,269.26 +6958,9,E09000011,2,77.51,351.51,25.84,383.34 +7284,9,E09000011,3,83.97,366.11,25.84,399.27 +7610,9,E09000011,4,101.48,478.85,25.84,521.29 +7936,10,E09000011,0,70.47,411.13,18.64,448.39 +113,1,E07000209,1,57.21,123.09,25.84,176.15 +439,1,E07000209,2,71.06,146.43,25.84,186.77 +765,1,E07000209,3,81.2,161.3,25.84,203.75 +1091,1,E07000209,4,89.52,178.28,25.84,221.77 +2721,2,E07000209,0,62.17,268.13,18.64,344.4 +1417,3,E07000209,1,51.68,115.66,25.84,159.17 +1743,3,E07000209,2,62.75,129.46,25.84,145.37 +2069,3,E07000209,3,68.28,149.62,25.84,185.7 +2395,3,E07000209,4,72.9,184.64,25.84,194.19 +3047,4,E07000209,0,48.71,195.45,18.64,204.96 +4005,5,E07000209,1,57.21,192.07,25.84,210.12 +4620,5,E07000209,2,71.06,269.54,25.84,293.94 +5272,5,E07000209,3,81.2,326.84,25.84,356.55 +5957,5,E07000209,4,89.52,561.35,25.84,611.23 +3373,6,E07000209,0,62.17,630.42,18.64,686.44 +4072,7,E07000209,1,51.68,192.07,25.84,210.12 +4767,7,E07000209,2,62.75,269.54,25.84,293.94 +5372,7,E07000209,3,68.28,326.84,25.84,356.55 +6061,7,E07000209,4,72.9,561.35,25.84,611.23 +3699,8,E07000209,0,48.71,630.42,18.64,686.44 +6633,9,E07000209,1,57.21,240.08,25.84,262.64 +6959,9,E07000209,2,71.06,336.93,25.84,367.42 +7285,9,E07000209,3,81.2,408.54,25.84,445.68 +7611,9,E07000209,4,89.52,701.69,25.84,764.03 +7937,10,E07000209,0,62.17,269.62,18.64,294.95 +114,1,E09000012,1,65.51,145.37,25.84,197.39 +440,1,E09000012,2,77.51,157.04,25.84,192.07 +766,1,E09000012,3,83.97,166.61,25.84,226.01 +1092,1,E09000012,4,101.48,186.77,25.84,251.49 +2722,2,E09000012,0,70.47,317,18.64,502.91 +1418,3,E09000012,1,58.13,118.85,25.84,146.43 +1744,3,E09000012,2,63.67,139.02,25.84,175.09 +2070,3,E09000012,3,71.06,159.17,25.84,200.55 +2396,3,E09000012,4,83.05,259.98,25.84,261.04 +3048,4,E09000012,0,60.1,371.82,18.64,402.8 +3961,5,E09000012,1,65.51,307.74,25.84,335.31 +4576,5,E09000012,2,77.51,370.33,25.84,404.3 +5228,5,E09000012,3,83.97,438.24,25.84,477.53 +5913,5,E09000012,4,101.48,583.64,25.84,635.64 +3374,6,E09000012,0,70.47,655.45,18.64,713.85 +4175,7,E09000012,1,58.13,307.74,25.84,335.31 +4676,7,E09000012,2,63.67,370.33,25.84,404.3 +5328,7,E09000012,3,71.06,438.24,25.84,477.53 +5880,7,E09000012,4,83.05,583.64,25.84,635.64 +3700,8,E09000012,0,60.1,655.45,18.64,713.85 +6634,9,E09000012,1,65.51,384.68,25.84,419.17 +6960,9,E09000012,2,77.51,462.92,25.84,505.39 +7286,9,E09000012,3,83.97,547.82,25.84,596.91 +7612,9,E09000012,4,101.48,729.54,25.84,794.53 +7938,10,E09000012,0,70.47,1257.26,18.64,1371.98 +115,1,E06000006,1,51.68,93.39,25.84,116.72 +441,1,E06000006,2,59.06,107.19,25.84,134.77 +767,1,E06000006,3,65.51,119.9,25.84,145.37 +1093,1,E06000006,4,71.98,133.71,25.84,159.17 +2723,2,E06000006,0,55.97,239.54,18.64,342.01 +1419,3,E06000006,1,43.36,85.94,25.84,100.81 +1745,3,E06000006,2,53.52,94.47,25.84,113.53 +2071,3,E06000006,3,58.13,105.06,25.84,124.15 +2397,3,E06000006,4,55.37,118.85,25.84,133.71 +3049,4,E06000006,0,33.16,469.54,18.64,599.44 +4366,5,E06000006,1,51.68,102.94,25.84,112.47 +4936,5,E06000006,2,59.06,114.6,25.84,124.15 +5579,5,E06000006,3,65.51,134.77,25.84,147.5 +6327,5,E06000006,4,71.98,203.75,25.84,221.77 +3375,6,E06000006,0,55.97,228.81,18.64,249.07 +4478,7,E06000006,1,43.36,102.94,25.84,112.47 +5074,7,E06000006,2,53.52,114.6,25.84,124.15 +5754,7,E06000006,3,58.13,134.77,25.84,147.5 +6378,7,E06000006,4,55.37,203.75,25.84,221.77 +3701,8,E06000006,0,33.16,228.81,18.64,249.07 +6635,9,E06000006,1,51.68,128.67,25.84,140.6 +6961,9,E06000006,2,59.06,143.25,25.84,155.2 +7287,9,E06000006,3,65.51,168.46,25.84,184.37 +7613,9,E06000006,4,71.98,254.69,25.84,277.23 +7939,10,E06000006,0,55.97,348.6,18.64,379.86 +117,1,E09000013,1,65.51,145.37,25.84,197.39 +443,1,E09000013,2,77.51,157.04,25.84,192.07 +769,1,E09000013,3,83.97,166.61,25.84,226.01 +1095,1,E09000013,4,101.48,186.77,25.84,251.49 +2725,2,E09000013,0,70.47,317,18.64,502.91 +1421,3,E09000013,1,58.13,118.85,25.84,146.43 +1747,3,E09000013,2,63.67,139.02,25.84,175.09 +2073,3,E09000013,3,71.06,159.17,25.84,200.55 +2399,3,E09000013,4,83.05,259.98,25.84,261.04 +3051,4,E09000013,0,60.1,371.82,18.64,402.8 +3962,5,E09000013,1,65.51,317.29,25.84,345.93 +4577,5,E09000013,2,77.51,423.41,25.84,461.6 +5229,5,E09000013,3,83.97,608.05,25.84,662.16 +5914,5,E09000013,4,101.48,972.01,25.84,1059.03 +3377,6,E09000013,0,70.47,1090.41,18.64,1189.33 +4176,7,E09000013,1,58.13,317.29,25.84,345.93 +4677,7,E09000013,2,63.67,423.41,25.84,461.6 +5329,7,E09000013,3,71.06,608.05,25.84,662.16 +5881,7,E09000013,4,83.05,972.01,25.84,1059.03 +3703,8,E09000013,0,60.1,1090.41,18.64,1189.33 +6637,9,E09000013,1,65.51,396.59,25.84,432.43 +6963,9,E09000013,2,77.51,529.26,25.84,576.98 +7289,9,E09000013,3,83.97,760.06,25.84,827.71 +7615,9,E09000013,4,101.48,1215.02,25.84,1323.81 +7941,10,E09000013,0,70.47,615.22,18.64,670.34 +118,1,E07000131,1,51.68,99.75,25.84,122.03 +444,1,E07000131,2,61.83,114.6,25.84,129.46 +770,1,E07000131,3,68.28,126.28,25.84,137.95 +1096,1,E07000131,4,75.67,158.1,25.84,166.61 +2726,2,E07000131,0,51.82,240.72,18.64,361.1 +1422,3,E07000131,1,46.13,90.21,25.84,107.19 +1748,3,E07000131,2,52.6,96.56,25.84,108.24 +2074,3,E07000131,3,58.13,104,25.84,118.85 +2400,3,E07000131,4,63.67,122.03,25.84,122.03 +3052,4,E07000131,0,49.74,114.39,18.64,123.94 +4328,5,E07000131,1,51.68,107.19,25.84,116.72 +5024,5,E07000131,2,61.83,125.22,25.84,136.89 +5667,5,E07000131,3,68.28,158.1,25.84,172.97 +6242,5,E07000131,4,75.67,248.31,25.84,270.61 +3378,6,E07000131,0,51.82,278.86,18.64,303.89 +4428,7,E07000131,1,46.13,107.19,25.84,116.72 +5164,7,E07000131,2,52.6,125.22,25.84,136.89 +5825,7,E07000131,3,58.13,158.1,25.84,172.97 +6486,7,E07000131,4,63.67,248.31,25.84,270.61 +3704,8,E07000131,0,49.74,278.86,18.64,303.89 +6638,9,E07000131,1,51.68,133.98,25.84,145.91 +6964,9,E07000131,2,61.83,156.51,25.84,171.11 +7290,9,E07000131,3,68.28,197.62,25.84,216.2 +7616,9,E07000131,4,75.67,310.37,25.84,338.25 +7942,10,E07000131,0,51.82,269.62,18.64,294.95 +119,1,E09000014,1,65.51,145.37,25.84,197.39 +445,1,E09000014,2,77.51,157.04,25.84,192.07 +771,1,E09000014,3,83.97,166.61,25.84,226.01 +1097,1,E09000014,4,101.48,186.77,25.84,251.49 +2727,2,E09000014,0,70.47,317,18.64,502.91 +1423,3,E09000014,1,58.13,118.85,25.84,146.43 +1749,3,E09000014,2,63.67,139.02,25.84,175.09 +2075,3,E09000014,3,71.06,159.17,25.84,200.55 +2401,3,E09000014,4,83.05,259.98,25.84,261.04 +3053,4,E09000014,0,60.1,371.82,18.64,402.8 +3963,5,E09000014,1,65.51,259.98,25.84,282.26 +4578,5,E09000014,2,77.51,332.14,25.84,361.84 +5230,5,E09000014,3,83.97,414.92,25.84,452.05 +5915,5,E09000014,4,101.48,632.45,25.84,689.74 +3379,6,E09000014,0,70.47,709.09,18.64,774.62 +4177,7,E09000014,1,58.13,259.98,25.84,282.26 +4678,7,E09000014,2,63.67,332.14,25.84,361.84 +5330,7,E09000014,3,71.06,414.92,25.84,452.05 +5882,7,E09000014,4,83.05,632.45,25.84,689.74 +3705,8,E09000014,0,60.1,709.09,18.64,774.62 +6639,9,E09000014,1,65.51,324.98,25.84,352.84 +6965,9,E09000014,2,77.51,415.17,25.84,452.31 +7291,9,E09000014,3,83.97,518.65,25.84,565.05 +7617,9,E09000014,4,101.48,790.55,25.84,862.19 +7943,10,E09000014,0,70.47,239.85,18.64,260.68 +120,1,E07000073,1,54.44,118.85,25.84,148.56 +446,1,E07000073,2,64.59,142.18,25.84,167.67 +772,1,E07000073,3,71.06,155.98,25.84,180.4 +1098,1,E07000073,4,81.2,170.85,25.84,178.28 +2728,2,E07000073,0,36.26,226.42,18.64,423.05 +1424,3,E07000073,1,49.84,99.75,25.84,131.58 +1750,3,E07000073,2,58.13,117.78,25.84,132.64 +2076,3,E07000073,3,63.67,130.52,25.84,143.25 +2402,3,E07000073,4,71.06,148.56,25.84,159.17 +3054,4,E07000073,0,55.97,135.86,18.64,318.19 +4137,5,E07000073,1,54.44,132.64,25.84,145.37 +4718,5,E07000073,2,64.59,179.34,25.84,196.32 +5437,5,E07000073,3,71.06,214.35,25.84,234.52 +6147,5,E07000073,4,81.2,316.23,25.84,344.88 +3380,6,E07000073,0,36.26,355.12,18.64,387.3 +4254,7,E07000073,1,49.84,132.64,25.84,145.37 +4980,7,E07000073,2,58.13,179.34,25.84,196.32 +5623,7,E07000073,3,63.67,214.35,25.84,234.52 +6285,7,E07000073,4,71.06,316.23,25.84,344.88 +3706,8,E07000073,0,55.97,355.12,18.64,387.3 +6640,9,E07000073,1,54.44,165.81,25.84,181.72 +6966,9,E07000073,2,64.59,224.18,25.84,245.4 +7292,9,E07000073,3,71.06,267.95,25.84,293.15 +7618,9,E07000073,4,81.2,395.3,25.84,431.1 +7944,10,E07000073,0,36.26,521.38,18.64,569.06 +122,1,E09000015,1,65.51,145.37,25.84,197.39 +448,1,E09000015,2,77.51,157.04,25.84,192.07 +774,1,E09000015,3,83.97,166.61,25.84,226.01 +1100,1,E09000015,4,101.48,186.77,25.84,251.49 +2730,2,E09000015,0,70.47,317,18.64,502.91 +1426,3,E09000015,1,58.13,118.85,25.84,146.43 +1752,3,E09000015,2,63.67,139.02,25.84,175.09 +2078,3,E09000015,3,71.06,159.17,25.84,200.55 +2404,3,E09000015,4,83.05,259.98,25.84,261.04 +3056,4,E09000015,0,60.1,371.82,18.64,402.8 +3964,5,E09000015,1,65.51,198.45,25.84,215.41 +4579,5,E09000015,2,77.51,259.98,25.84,282.26 +5231,5,E09000015,3,83.97,316.23,25.84,344.88 +5916,5,E09000015,4,101.48,449.93,25.84,490.26 +3382,6,E09000015,0,70.47,505.29,18.64,550.58 +4178,7,E09000015,1,58.13,198.45,25.84,215.41 +4679,7,E09000015,2,63.67,259.98,25.84,282.26 +5331,7,E09000015,3,71.06,316.23,25.84,344.88 +5883,7,E09000015,4,83.05,449.93,25.84,490.26 +3708,8,E09000015,0,60.1,505.29,18.64,550.58 +6642,9,E09000015,1,65.51,248.03,25.84,269.26 +6968,9,E09000015,2,77.51,324.98,25.84,352.84 +7294,9,E09000015,3,83.97,395.3,25.84,431.1 +7620,9,E09000015,4,101.48,562.41,25.84,612.82 +7946,10,E09000015,0,70.47,624.16,18.64,680.77 +123,1,E07000089,1,57.21,123.09,25.84,176.15 +449,1,E07000089,2,71.06,146.43,25.84,186.77 +775,1,E07000089,3,81.2,161.3,25.84,203.75 +1101,1,E07000089,4,89.52,178.28,25.84,221.77 +2731,2,E07000089,0,62.17,268.13,18.64,344.4 +1427,3,E07000089,1,51.68,115.66,25.84,159.17 +1753,3,E07000089,2,62.75,129.46,25.84,145.37 +2079,3,E07000089,3,68.28,149.62,25.84,185.7 +2405,3,E07000089,4,72.9,184.64,25.84,194.19 +3057,4,E07000089,0,48.71,195.45,18.64,204.96 +4006,5,E07000089,1,57.21,164.48,25.84,179.34 +4621,5,E07000089,2,71.06,198.45,25.84,215.41 +5273,5,E07000089,3,81.2,270.61,25.84,295.01 +5958,5,E07000089,4,89.52,415.98,25.84,453.12 +3383,6,E07000089,0,62.17,467.14,18.64,508.85 +4073,7,E07000089,1,51.68,164.48,25.84,179.34 +4768,7,E07000089,2,62.75,198.45,25.84,215.41 +5373,7,E07000089,3,68.28,270.61,25.84,295.01 +6062,7,E07000089,4,72.9,415.98,25.84,453.12 +3709,8,E07000089,0,48.71,467.14,18.64,508.85 +6643,9,E07000089,1,57.21,205.6,25.84,224.18 +6969,9,E07000089,2,71.06,248.03,25.84,269.26 +7295,9,E07000089,3,81.2,338.25,25.84,368.76 +7621,9,E07000089,4,89.52,519.97,25.84,566.39 +7947,10,E07000089,0,62.17,286.02,18.64,311.34 +124,1,E06000001,1,50.76,88.07,25.84,97.63 +450,1,E06000001,2,57.21,101.88,25.84,119.9 +776,1,E06000001,3,60.9,113.53,25.84,159.17 +1102,1,E06000001,4,70.13,127.34,25.84,139.02 +2732,2,E06000001,0,55.97,237.14,18.64,340.83 +1428,3,E06000001,1,42.44,99.75,25.84,105.06 +1754,3,E06000001,2,49.84,90.21,25.84,111.41 +2080,3,E06000001,3,53.52,105.06,25.84,124.15 +2406,3,E06000001,4,56.29,115.66,25.84,119.9 +3058,4,E06000001,0,47.67,253.84,18.64,288.39 +4535,5,E06000001,1,50.76,92.33,25.84,100.81 +5050,5,E06000001,2,57.21,104,25.84,114.6 +5555,5,E06000001,3,60.9,134.77,25.84,147.5 +6354,5,E06000001,4,70.13,170.85,25.84,185.7 +3384,6,E06000001,0,55.97,191.88,18.64,208.55 +4454,7,E06000001,1,42.44,92.33,25.84,100.81 +5101,7,E06000001,2,49.84,104,25.84,114.6 +5730,7,E06000001,3,53.52,134.77,25.84,147.5 +6512,7,E06000001,4,56.29,170.85,25.84,185.7 +3710,8,E06000001,0,47.67,191.88,18.64,208.55 +6644,9,E06000001,1,42.44,115.39,25.84,126.02 +6970,9,E06000001,2,57.21,129.98,25.84,143.25 +7296,9,E06000001,3,60.9,168.46,25.84,184.37 +7622,9,E06000001,4,70.13,213.57,25.84,232.15 +7948,10,E06000001,0,55.97,443.93,18.64,484.13 +125,1,E07000062,1,57.21,123.09,25.84,176.15 +451,1,E07000062,2,71.06,146.43,25.84,186.77 +777,1,E07000062,3,81.2,161.3,25.84,203.75 +1103,1,E07000062,4,89.52,178.28,25.84,221.77 +2733,2,E07000062,0,62.17,268.13,18.64,344.4 +1429,3,E07000062,1,51.68,115.66,25.84,159.17 +1755,3,E07000062,2,62.75,129.46,25.84,145.37 +2081,3,E07000062,3,68.28,149.62,25.84,185.7 +2407,3,E07000062,4,72.9,184.64,25.84,194.19 +3059,4,E07000062,0,48.71,195.45,18.64,204.96 +4007,5,E07000062,1,57.21,99.75,25.84,109.29 +4622,5,E07000062,2,71.06,134.77,25.84,147.5 +5274,5,E07000062,3,81.2,170.85,25.84,185.7 +5959,5,E07000062,4,89.52,248.31,25.84,270.61 +3385,6,E07000062,0,62.17,278.86,18.64,303.89 +4074,7,E07000062,1,51.68,99.75,25.84,109.29 +4769,7,E07000062,2,62.75,134.77,25.84,147.5 +5374,7,E07000062,3,68.28,170.85,25.84,185.7 +6063,7,E07000062,4,72.9,248.31,25.84,270.61 +3711,8,E07000062,0,48.71,278.86,18.64,303.89 +6645,9,E07000062,1,57.21,124.69,25.84,136.63 +6971,9,E07000062,2,71.06,168.46,25.84,184.37 +7297,9,E07000062,3,81.2,213.57,25.84,232.15 +7623,9,E07000062,4,89.52,310.37,25.84,338.25 +7949,10,E07000062,0,62.17,381.34,18.64,415.6 +126,1,E07000090,1,57.21,123.09,25.84,176.15 +452,1,E07000090,2,71.06,146.43,25.84,186.77 +778,1,E07000090,3,81.2,161.3,25.84,203.75 +1104,1,E07000090,4,89.52,178.28,25.84,221.77 +2734,2,E07000090,0,62.17,268.13,18.64,344.4 +1430,3,E07000090,1,51.68,115.66,25.84,159.17 +1756,3,E07000090,2,62.75,129.46,25.84,145.37 +2082,3,E07000090,3,68.28,149.62,25.84,185.7 +2408,3,E07000090,4,72.9,184.64,25.84,194.19 +3060,4,E07000090,0,48.71,195.45,18.64,204.96 +4008,5,E07000090,1,57.21,130.52,25.84,143.25 +4623,5,E07000090,2,71.06,159.17,25.84,174.02 +5275,5,E07000090,3,81.2,192.07,25.84,210.12 +5960,5,E07000090,4,89.52,281.2,25.84,306.68 +3386,6,E07000090,0,62.17,315.82,18.64,344.4 +4075,7,E07000090,1,51.68,130.52,25.84,143.25 +4770,7,E07000090,2,62.75,159.17,25.84,174.02 +5375,7,E07000090,3,68.28,192.07,25.84,210.12 +6064,7,E07000090,4,72.9,281.2,25.84,306.68 +3712,8,E07000090,0,48.71,315.82,18.64,344.4 +6646,9,E07000090,1,57.21,163.15,25.84,179.06 +6972,9,E07000090,2,71.06,198.96,25.84,217.54 +7298,9,E07000090,3,81.2,240.08,25.84,262.64 +7624,9,E07000090,4,89.52,351.51,25.84,383.34 +7950,10,E07000090,0,62.17,286.02,18.64,311.34 +127,1,E09000016,1,65.51,145.37,25.84,197.39 +453,1,E09000016,2,77.51,157.04,25.84,192.07 +779,1,E09000016,3,83.97,166.61,25.84,226.01 +1105,1,E09000016,4,101.48,186.77,25.84,251.49 +2735,2,E09000016,0,70.47,317,18.64,502.91 +1431,3,E09000016,1,58.13,118.85,25.84,146.43 +1757,3,E09000016,2,63.67,139.02,25.84,175.09 +2083,3,E09000016,3,71.06,159.17,25.84,200.55 +2409,3,E09000016,4,83.05,259.98,25.84,261.04 +3061,4,E09000016,0,60.1,371.82,18.64,402.8 +3965,5,E09000016,1,65.51,161.3,25.84,176.15 +4580,5,E09000016,2,77.51,203.75,25.84,221.77 +5232,5,E09000016,3,83.97,248.31,25.84,270.61 +5917,5,E09000016,4,101.48,405.36,25.84,441.43 +3387,6,E09000016,0,70.47,455.24,18.64,495.73 +4179,7,E09000016,1,58.13,161.3,25.84,176.15 +4680,7,E09000016,2,63.67,203.75,25.84,221.77 +5332,7,E09000016,3,71.06,248.31,25.84,270.61 +5884,7,E09000016,4,83.05,405.36,25.84,441.43 +3713,8,E09000016,0,60.1,455.24,18.64,495.73 +6647,9,E09000016,1,65.51,201.61,25.84,220.21 +6973,9,E09000016,2,77.51,254.69,25.84,277.23 +7299,9,E09000016,3,83.97,310.37,25.84,338.25 +7625,9,E09000016,4,101.48,506.71,25.84,551.8 +7951,10,E09000016,0,70.47,253.23,18.64,277.06 +128,1,E06000019,1,52.6,98.69,25.84,124.15 +454,1,E06000019,2,58.13,116.72,25.84,136.89 +780,1,E06000019,3,69.2,132.64,25.84,160.24 +1106,1,E06000019,4,80.28,161.3,25.84,178.28 +2736,2,E06000019,0,39.38,245.49,18.64,382.53 +1432,3,E06000019,1,46.13,88.07,25.84,97.63 +1758,3,E06000019,2,49.84,94.47,25.84,102.94 +2084,3,E06000019,3,59.98,104,25.84,119.9 +2410,3,E06000019,4,68.28,127.34,25.84,127.34 +3062,4,E06000019,0,46.63,107.26,18.64,107.26 +4287,5,E06000019,1,52.6,109.29,25.84,118.85 +4897,5,E06000019,2,58.13,130.52,25.84,143.25 +5528,5,E06000019,3,69.2,158.1,25.84,172.97 +6180,5,E06000019,4,80.28,214.35,25.84,234.52 +3388,6,E06000019,0,39.38,240.72,18.64,263.37 +4508,7,E06000019,1,46.13,109.29,25.84,118.85 +5193,7,E06000019,2,49.84,130.52,25.84,143.25 +5784,7,E06000019,3,59.98,158.1,25.84,172.97 +6445,7,E06000019,4,68.28,214.35,25.84,234.52 +3714,8,E06000019,0,46.63,240.72,18.64,263.37 +6648,9,E06000019,1,52.6,136.63,25.84,148.56 +6974,9,E06000019,2,58.13,163.15,25.84,179.06 +7300,9,E06000019,3,69.2,197.62,25.84,216.2 +7626,9,E06000019,4,80.28,267.95,25.84,293.15 +7952,10,E06000019,0,39.38,613.74,18.64,668.86 +129,1,E07000098,1,54.44,118.85,25.84,148.56 +455,1,E07000098,2,64.59,142.18,25.84,167.67 +781,1,E07000098,3,71.06,155.98,25.84,180.4 +1107,1,E07000098,4,81.2,170.85,25.84,178.28 +2737,2,E07000098,0,36.26,226.42,18.64,423.05 +1433,3,E07000098,1,49.84,99.75,25.84,131.58 +1759,3,E07000098,2,58.13,117.78,25.84,132.64 +2085,3,E07000098,3,63.67,130.52,25.84,143.25 +2411,3,E07000098,4,71.06,148.56,25.84,159.17 +3063,4,E07000098,0,55.97,135.86,18.64,318.19 +4138,5,E07000098,1,54.44,176.15,25.84,191.01 +4719,5,E07000098,2,64.59,227.08,25.84,246.18 +5438,5,E07000098,3,71.06,316.23,25.84,344.88 +6148,5,E07000098,4,81.2,526.35,25.84,573.01 +3389,6,E07000098,0,36.26,591.1,18.64,643.54 +4255,7,E07000098,1,49.84,176.15,25.84,191.01 +4981,7,E07000098,2,58.13,227.08,25.84,246.18 +5624,7,E07000098,3,63.67,316.23,25.84,344.88 +6286,7,E07000098,4,71.06,526.35,25.84,573.01 +3715,8,E07000098,0,55.97,591.1,18.64,643.54 +6649,9,E07000098,1,54.44,220.21,25.84,238.77 +6975,9,E07000098,2,64.59,283.85,25.84,307.73 +7301,9,E07000098,3,71.06,395.3,25.84,431.1 +7627,9,E07000098,4,81.2,657.9,25.84,716.27 +7953,10,E07000098,0,36.26,269.62,18.64,294.95 +130,1,E07000037,1,51.68,99.75,25.84,122.03 +456,1,E07000037,2,61.83,114.6,25.84,129.46 +782,1,E07000037,3,68.28,126.28,25.84,137.95 +1108,1,E07000037,4,75.67,158.1,25.84,166.61 +2738,2,E07000037,0,51.82,240.72,18.64,361.1 +1434,3,E07000037,1,46.13,90.21,25.84,107.19 +1760,3,E07000037,2,52.6,96.56,25.84,108.24 +2086,3,E07000037,3,58.13,104,25.84,118.85 +2412,3,E07000037,4,63.67,122.03,25.84,122.03 +3064,4,E07000037,0,49.74,114.39,18.64,123.94 +4329,5,E07000037,1,51.68,102.94,25.84,112.47 +5025,5,E07000037,2,61.83,125.22,25.84,136.89 +5668,5,E07000037,3,68.28,153.86,25.84,167.67 +6243,5,E07000037,4,75.67,192.07,25.84,210.12 +3390,6,E07000037,0,51.82,215.7,18.64,235.95 +4429,7,E07000037,1,46.13,102.94,25.84,112.47 +5165,7,E07000037,2,52.6,125.22,25.84,136.89 +5826,7,E07000037,3,58.13,153.86,25.84,167.67 +6487,7,E07000037,4,63.67,192.07,25.84,210.12 +3716,8,E07000037,0,49.74,215.7,18.64,235.95 +6650,9,E07000037,1,51.68,128.67,25.84,140.6 +6976,9,E07000037,2,61.83,156.51,25.84,171.11 +7302,9,E07000037,3,68.28,192.33,25.84,209.57 +7628,9,E07000037,4,75.67,240.08,25.84,262.64 +7954,10,E07000037,0,51.82,318.79,18.64,345.6 +131,1,E09000017,1,65.51,145.37,25.84,197.39 +457,1,E09000017,2,77.51,157.04,25.84,192.07 +783,1,E09000017,3,83.97,166.61,25.84,226.01 +1109,1,E09000017,4,101.48,186.77,25.84,251.49 +2739,2,E09000017,0,70.47,317,18.64,502.91 +1435,3,E09000017,1,58.13,118.85,25.84,146.43 +1761,3,E09000017,2,63.67,139.02,25.84,175.09 +2087,3,E09000017,3,71.06,159.17,25.84,200.55 +2413,3,E09000017,4,83.05,259.98,25.84,261.04 +3065,4,E09000017,0,60.1,371.82,18.64,402.8 +3966,5,E09000017,1,65.51,181.46,25.84,198.45 +4581,5,E09000017,2,77.51,248.31,25.84,270.61 +5233,5,E09000017,3,83.97,292.87,25.84,319.41 +5918,5,E09000017,4,101.48,426.59,25.84,465.84 +3391,6,E09000017,0,70.47,479.07,18.64,523.16 +4180,7,E09000017,1,58.13,181.46,25.84,198.45 +4681,7,E09000017,2,63.67,248.31,25.84,270.61 +5333,7,E09000017,3,71.06,292.87,25.84,319.41 +5885,7,E09000017,4,83.05,426.59,25.84,465.84 +3717,8,E09000017,0,60.1,479.07,18.64,523.16 +6651,9,E09000017,1,65.51,226.84,25.84,248.03 +6977,9,E09000017,2,77.51,310.37,25.84,338.25 +7303,9,E09000017,3,83.97,366.11,25.84,399.27 +7629,9,E09000017,4,101.48,533.22,25.84,582.31 +7955,10,E09000017,0,70.47,278.57,18.64,302.41 +132,1,E07000132,1,51.68,99.75,25.84,122.03 +458,1,E07000132,2,61.83,114.6,25.84,129.46 +784,1,E07000132,3,68.28,126.28,25.84,137.95 +1110,1,E07000132,4,75.67,158.1,25.84,166.61 +2740,2,E07000132,0,51.82,240.72,18.64,361.1 +1436,3,E07000132,1,46.13,90.21,25.84,107.19 +1762,3,E07000132,2,52.6,96.56,25.84,108.24 +2088,3,E07000132,3,58.13,104,25.84,118.85 +2414,3,E07000132,4,63.67,122.03,25.84,122.03 +3066,4,E07000132,0,49.74,114.39,18.64,123.94 +4330,5,E07000132,1,51.68,92.33,25.84,99.75 +5026,5,E07000132,2,61.83,119.9,25.84,130.52 +5669,5,E07000132,3,68.28,141.13,25.84,153.86 +6244,5,E07000132,4,75.67,214.35,25.84,234.52 +3392,6,E07000132,0,51.82,240.72,18.64,263.37 +4430,7,E07000132,1,46.13,92.33,25.84,99.75 +5166,7,E07000132,2,52.6,119.9,25.84,130.52 +5827,7,E07000132,3,58.13,141.13,25.84,153.86 +6488,7,E07000132,4,63.67,214.35,25.84,234.52 +3718,8,E07000132,0,49.74,240.72,18.64,263.37 +6652,9,E07000132,1,51.68,115.39,25.84,124.69 +6978,9,E07000132,2,61.83,149.9,25.84,163.15 +7304,9,E07000132,3,68.28,176.42,25.84,192.33 +7630,9,E07000132,4,75.67,267.95,25.84,293.15 +7956,10,E07000132,0,51.82,443.93,18.64,484.13 +133,1,E07000227,1,57.21,123.09,25.84,176.15 +459,1,E07000227,2,71.06,146.43,25.84,186.77 +785,1,E07000227,3,81.2,161.3,25.84,203.75 +1111,1,E07000227,4,89.52,178.28,25.84,221.77 +2741,2,E07000227,0,62.17,268.13,18.64,344.4 +1437,3,E07000227,1,51.68,115.66,25.84,159.17 +1763,3,E07000227,2,62.75,129.46,25.84,145.37 +2089,3,E07000227,3,68.28,149.62,25.84,185.7 +2415,3,E07000227,4,72.9,184.64,25.84,194.19 +3067,4,E07000227,0,48.71,195.45,18.64,204.96 +4009,5,E07000227,1,57.21,147.5,25.84,160.24 +4624,5,E07000227,2,71.06,186.77,25.84,203.75 +5276,5,E07000227,3,81.2,259.98,25.84,282.26 +5961,5,E07000227,4,89.52,426.59,25.84,465.84 +3393,6,E07000227,0,62.17,479.07,18.64,523.16 +4076,7,E07000227,1,51.68,147.5,25.84,160.24 +4771,7,E07000227,2,62.75,186.77,25.84,203.75 +5376,7,E07000227,3,68.28,259.98,25.84,282.26 +6065,7,E07000227,4,72.9,426.59,25.84,465.84 +3719,8,E07000227,0,48.71,479.07,18.64,523.16 +6653,9,E07000227,1,57.21,184.37,25.84,200.32 +6979,9,E07000227,2,71.06,233.46,25.84,254.69 +7305,9,E07000227,3,81.2,324.98,25.84,352.84 +7631,9,E07000227,4,89.52,533.22,25.84,582.31 +7957,10,E07000227,0,62.17,342.63,18.64,373.91 +134,1,E09000018,1,65.51,145.37,25.84,197.39 +460,1,E09000018,2,77.51,157.04,25.84,192.07 +786,1,E09000018,3,83.97,166.61,25.84,226.01 +1112,1,E09000018,4,101.48,186.77,25.84,251.49 +2742,2,E09000018,0,70.47,317,18.64,502.91 +1438,3,E09000018,1,58.13,118.85,25.84,146.43 +1764,3,E09000018,2,63.67,139.02,25.84,175.09 +2090,3,E09000018,3,71.06,159.17,25.84,200.55 +2416,3,E09000018,4,83.05,259.98,25.84,261.04 +3068,4,E09000018,0,60.1,371.82,18.64,402.8 +3967,5,E09000018,1,65.51,215.41,25.84,235.58 +4582,5,E09000018,2,77.51,292.87,25.84,319.41 +5234,5,E09000018,3,83.97,316.23,25.84,344.88 +5919,5,E09000018,4,101.48,727.96,25.84,794.8 +3394,6,E09000018,0,70.47,817.52,18.64,892.61 +4181,7,E09000018,1,58.13,215.41,25.84,235.58 +4682,7,E09000018,2,63.67,292.87,25.84,319.41 +5334,7,E09000018,3,71.06,316.23,25.84,344.88 +5886,7,E09000018,4,83.05,727.96,25.84,794.8 +3720,8,E09000018,0,60.1,817.52,18.64,892.61 +6654,9,E09000018,1,65.51,269.26,25.84,294.49 +6980,9,E09000018,2,77.51,366.11,25.84,399.27 +7306,9,E09000018,3,83.97,395.3,25.84,431.1 +7632,9,E09000018,4,101.48,909.95,25.84,993.49 +7958,10,E09000018,0,70.47,284.53,18.64,309.82 +135,1,E07000011,1,54.44,118.85,25.84,148.56 +461,1,E07000011,2,64.59,142.18,25.84,167.67 +787,1,E07000011,3,71.06,155.98,25.84,180.4 +1113,1,E07000011,4,81.2,170.85,25.84,178.28 +2743,2,E07000011,0,36.26,226.42,18.64,423.05 +1439,3,E07000011,1,49.84,99.75,25.84,131.58 +1765,3,E07000011,2,58.13,117.78,25.84,132.64 +2091,3,E07000011,3,63.67,130.52,25.84,143.25 +2417,3,E07000011,4,71.06,148.56,25.84,159.17 +3069,4,E07000011,0,55.97,135.86,18.64,318.19 +4139,5,E07000011,1,54.44,113.53,25.84,123.09 +4720,5,E07000011,2,64.59,143.25,25.84,155.98 +5439,5,E07000011,3,71.06,170.85,25.84,185.7 +6149,5,E07000011,4,81.2,281.2,25.84,306.68 +3395,6,E07000011,0,36.26,315.82,18.64,344.4 +4256,7,E07000011,1,49.84,113.53,25.84,123.09 +4982,7,E07000011,2,58.13,143.25,25.84,155.98 +5625,7,E07000011,3,63.67,170.85,25.84,185.7 +6287,7,E07000011,4,71.06,281.2,25.84,306.68 +3721,8,E07000011,0,55.97,315.82,18.64,344.4 +6655,9,E07000011,1,54.44,141.94,25.84,153.86 +6981,9,E07000011,2,64.59,179.06,25.84,194.98 +7307,9,E07000011,3,71.06,213.57,25.84,232.15 +7633,9,E07000011,4,81.2,351.51,25.84,383.34 +7959,10,E07000011,0,36.26,284.53,18.64,309.82 +136,1,E07000120,1,51.68,93.39,25.84,116.72 +462,1,E07000120,2,59.06,107.19,25.84,134.77 +788,1,E07000120,3,65.51,119.9,25.84,145.37 +1114,1,E07000120,4,71.98,133.71,25.84,159.17 +2744,2,E07000120,0,55.97,239.54,18.64,342.01 +1440,3,E07000120,1,43.36,85.94,25.84,100.81 +1766,3,E07000120,2,53.52,94.47,25.84,113.53 +2092,3,E07000120,3,58.13,105.06,25.84,124.15 +2418,3,E07000120,4,55.37,118.85,25.84,133.71 +3070,4,E07000120,0,33.16,469.54,18.64,599.44 +4367,5,E07000120,1,51.68,90.21,25.84,97.63 +4937,5,E07000120,2,59.06,98.69,25.84,108.24 +5580,5,E07000120,3,65.51,125.22,25.84,136.89 +6328,5,E07000120,4,71.98,170.85,25.84,185.7 +3396,6,E07000120,0,55.97,191.88,18.64,208.55 +4479,7,E07000120,1,43.36,90.21,25.84,97.63 +5075,7,E07000120,2,53.52,98.69,25.84,108.24 +5755,7,E07000120,3,58.13,125.22,25.84,136.89 +6379,7,E07000120,4,55.37,170.85,25.84,185.7 +3722,8,E07000120,0,33.16,191.88,18.64,208.55 +6656,9,E07000120,1,51.68,112.76,25.84,122.03 +6982,9,E07000120,2,59.06,123.35,25.84,135.3 +7308,9,E07000120,3,65.51,156.51,25.84,171.11 +7634,9,E07000120,4,71.98,213.57,25.84,232.15 +7960,10,E07000120,0,55.97,269.62,18.64,294.95 +137,1,E07000202,1,54.44,118.85,25.84,148.56 +463,1,E07000202,2,64.59,142.18,25.84,167.67 +789,1,E07000202,3,71.06,155.98,25.84,180.4 +1115,1,E07000202,4,81.2,170.85,25.84,178.28 +2745,2,E07000202,0,36.26,226.42,18.64,423.05 +1441,3,E07000202,1,49.84,99.75,25.84,131.58 +1767,3,E07000202,2,58.13,117.78,25.84,132.64 +2093,3,E07000202,3,63.67,130.52,25.84,143.25 +2419,3,E07000202,4,71.06,148.56,25.84,159.17 +3071,4,E07000202,0,55.97,135.86,18.64,318.19 +4140,5,E07000202,1,54.44,102.94,25.84,112.47 +4721,5,E07000202,2,64.59,125.22,25.84,136.89 +5440,5,E07000202,3,71.06,146.43,25.84,158.1 +6150,5,E07000202,4,81.2,245.12,25.84,266.35 +3397,6,E07000202,0,36.26,274.11,18.64,299.12 +4257,7,E07000202,1,49.84,102.94,25.84,112.47 +4983,7,E07000202,2,58.13,125.22,25.84,136.89 +5626,7,E07000202,3,63.67,146.43,25.84,158.1 +6288,7,E07000202,4,71.06,245.12,25.84,266.35 +3723,8,E07000202,0,55.97,274.11,18.64,299.12 +6657,9,E07000202,1,54.44,128.67,25.84,140.6 +6983,9,E07000202,2,64.59,156.51,25.84,171.11 +7309,9,E07000202,3,71.06,183.04,25.84,197.62 +7635,9,E07000202,4,81.2,306.4,25.84,332.95 +7961,10,E07000202,0,36.26,318.79,18.64,345.6 +138,1,E06000046,1,57.21,123.09,25.84,176.15 +464,1,E06000046,2,71.06,146.43,25.84,186.77 +790,1,E06000046,3,81.2,161.3,25.84,203.75 +1116,1,E06000046,4,89.52,178.28,25.84,221.77 +2746,2,E06000046,0,62.17,268.13,18.64,344.4 +1442,3,E06000046,1,51.68,115.66,25.84,159.17 +1768,3,E06000046,2,62.75,129.46,25.84,145.37 +2094,3,E06000046,3,68.28,149.62,25.84,185.7 +2420,3,E06000046,4,72.9,184.64,25.84,194.19 +3072,4,E06000046,0,48.71,195.45,18.64,204.96 +4010,5,E06000046,1,57.21,107.19,25.84,116.72 +4625,5,E06000046,2,71.06,136.89,25.84,148.56 +5277,5,E06000046,3,81.2,170.85,25.84,185.7 +5962,5,E06000046,4,89.52,237.69,25.84,258.92 +3398,6,E06000046,0,62.17,266.94,18.64,290.78 +4077,7,E06000046,1,51.68,107.19,25.84,116.72 +4772,7,E06000046,2,62.75,136.89,25.84,148.56 +5377,7,E06000046,3,68.28,170.85,25.84,185.7 +6066,7,E06000046,4,72.9,237.69,25.84,258.92 +3724,8,E06000046,0,48.71,266.94,18.64,290.78 +6658,9,E06000046,1,57.21,133.98,25.84,145.91 +6984,9,E06000046,2,71.06,171.11,25.84,185.69 +7310,9,E06000046,3,81.2,213.57,25.84,232.15 +7636,9,E06000046,4,89.52,297.12,25.84,323.65 +7962,10,E06000046,0,62.17,348.6,18.64,379.86 +139,1,E06000053,1,48.92,107.19,25.84,140.08 +465,1,E06000053,2,55.37,120.97,25.84,144.31 +791,1,E06000053,3,61.83,141.13,25.84,161.3 +1117,1,E06000053,4,71.06,158.1,25.84,194.19 +2747,2,E06000053,0,54.93,231.2,18.64,358.7 +1443,3,E06000053,1,47.06,89.13,25.84,210.12 +1769,3,E06000053,2,54.44,100.81,25.84,111.41 +2095,3,E06000053,3,61.83,109.29,25.84,126.28 +2421,3,E06000053,4,73.82,130.52,25.84,130.52 +3073,4,E06000053,0,54.93,115.59,18.64,141.81 +4209,5,E06000053,1,48.92,129.46,25.84,142.18 +4845,5,E06000053,2,55.37,164.48,25.84,179.34 +5476,5,E06000053,3,61.83,192.07,25.84,210.12 +6014,5,E06000053,4,71.06,292.87,25.84,319.41 +3399,6,E06000053,0,54.93,215.7,18.64,235.95 +3925,7,E06000053,1,47.06,129.46,25.84,142.18 +5122,7,E06000053,2,54.44,164.48,25.84,179.34 +5702,7,E06000053,3,61.83,192.07,25.84,210.12 +6414,7,E06000053,4,73.82,292.87,25.84,319.41 +3725,8,E06000053,0,54.93,215.7,18.64,235.95 +6659,9,E06000053,1,48.92,161.83,25.84,177.73 +6985,9,E06000053,2,55.37,205.6,25.84,224.18 +7311,9,E06000053,3,61.83,240.08,25.84,262.64 +7637,9,E06000053,4,71.06,366.11,25.84,399.27 +7963,10,E06000053,0,54.93,379.86,18.64,414.12 +140,1,E09000019,1,65.51,145.37,25.84,197.39 +466,1,E09000019,2,77.51,157.04,25.84,192.07 +792,1,E09000019,3,83.97,166.61,25.84,226.01 +1118,1,E09000019,4,101.48,186.77,25.84,251.49 +2748,2,E09000019,0,70.47,317,18.64,502.91 +1444,3,E09000019,1,58.13,118.85,25.84,146.43 +1770,3,E09000019,2,63.67,139.02,25.84,175.09 +2096,3,E09000019,3,71.06,159.17,25.84,200.55 +2422,3,E09000019,4,83.05,259.98,25.84,261.04 +3074,4,E09000019,0,60.1,371.82,18.64,402.8 +3968,5,E09000019,1,65.51,332.14,25.84,361.84 +4583,5,E09000019,2,77.51,447.81,25.84,488.14 +5235,5,E09000019,3,83.97,524.21,25.84,570.9 +5920,5,E09000019,4,101.48,651.55,25.84,710.97 +3400,6,E09000019,0,70.47,731.72,18.64,798.45 +4182,7,E09000019,1,58.13,332.14,25.84,361.84 +4683,7,E09000019,2,63.67,447.81,25.84,488.14 +5335,7,E09000019,3,71.06,524.21,25.84,570.9 +5887,7,E09000019,4,83.05,651.55,25.84,710.97 +3726,8,E09000019,0,60.1,731.72,18.64,798.45 +6660,9,E09000019,1,65.51,415.17,25.84,452.31 +6986,9,E09000019,2,77.51,559.76,25.84,610.16 +7312,9,E09000019,3,83.97,655.27,25.84,713.62 +7638,9,E09000019,4,101.48,814.43,25.84,888.72 +7964,10,E09000019,0,70.47,253.23,18.64,277.06 +141,1,E09000020,1,65.51,145.37,25.84,197.39 +467,1,E09000020,2,77.51,157.04,25.84,192.07 +793,1,E09000020,3,83.97,166.61,25.84,226.01 +1119,1,E09000020,4,101.48,186.77,25.84,251.49 +2749,2,E09000020,0,70.47,317,18.64,502.91 +1445,3,E09000020,1,58.13,118.85,25.84,146.43 +1771,3,E09000020,2,63.67,139.02,25.84,175.09 +2097,3,E09000020,3,71.06,159.17,25.84,200.55 +2423,3,E09000020,4,83.05,259.98,25.84,261.04 +3075,4,E09000020,0,60.1,371.82,18.64,402.8 +3969,5,E09000020,1,65.51,481.75,25.84,526.35 +4584,5,E09000020,2,77.51,727.96,25.84,794.8 +5236,5,E09000020,3,83.97,1552.48,25.84,1692.54 +5921,5,E09000020,4,101.48,2859.82,25.84,3118.73 +3401,6,E09000020,0,70.47,3210.51,18.64,3502.48 +4183,7,E09000020,1,58.13,481.75,25.84,526.35 +4684,7,E09000020,2,63.67,727.96,25.84,794.8 +5336,7,E09000020,3,71.06,1552.48,25.84,1692.54 +5888,7,E09000020,4,83.05,2859.82,25.84,3118.73 +3727,8,E09000020,0,60.1,3210.51,18.64,3502.48 +6661,9,E09000020,1,65.51,602.21,25.84,657.9 +6987,9,E09000020,2,77.51,909.95,25.84,993.49 +7313,9,E09000020,3,83.97,1940.6,25.84,2115.67 +7639,9,E09000020,4,101.48,3574.77,25.84,3898.4 +7965,10,E09000020,0,70.47,269.62,18.64,294.95 +143,1,E07000146,1,54.44,118.85,25.84,148.56 +469,1,E07000146,2,64.59,142.18,25.84,167.67 +795,1,E07000146,3,71.06,155.98,25.84,180.4 +1121,1,E07000146,4,81.2,170.85,25.84,178.28 +2751,2,E07000146,0,36.26,226.42,18.64,423.05 +1447,3,E07000146,1,49.84,99.75,25.84,131.58 +1773,3,E07000146,2,58.13,117.78,25.84,132.64 +2099,3,E07000146,3,63.67,130.52,25.84,143.25 +2425,3,E07000146,4,71.06,148.56,25.84,159.17 +3077,4,E07000146,0,55.97,135.86,18.64,318.19 +4141,5,E07000146,1,54.44,99.75,25.84,109.29 +4722,5,E07000146,2,64.59,125.22,25.84,136.89 +5441,5,E07000146,3,71.06,147.5,25.84,160.24 +6151,5,E07000146,4,81.2,243.02,25.84,265.29 +3403,6,E07000146,0,36.26,272.91,18.64,297.95 +4258,7,E07000146,1,49.84,99.75,25.84,109.29 +4984,7,E07000146,2,58.13,125.22,25.84,136.89 +5627,7,E07000146,3,63.67,147.5,25.84,160.24 +6289,7,E07000146,4,71.06,243.02,25.84,265.29 +3729,8,E07000146,0,55.97,272.91,18.64,297.95 +6663,9,E07000146,1,54.44,124.69,25.84,136.63 +6989,9,E07000146,2,64.59,156.51,25.84,171.11 +7315,9,E07000146,3,71.06,184.37,25.84,200.32 +7641,9,E07000146,4,81.2,303.74,25.84,331.63 +7967,10,E07000146,0,36.26,591.38,18.64,645.02 +144,1,E06000010,1,50.76,91.27,25.84,113.53 +470,1,E06000010,2,58.13,108.24,25.84,140.08 +796,1,E06000010,3,62.75,119.9,25.84,161.3 +1122,1,E06000010,4,72.9,144.31,25.84,178.28 +2752,2,E06000010,0,52.86,234.75,18.64,322.95 +1448,3,E06000010,1,46.13,81.71,25.84,92.33 +1774,3,E06000010,2,52.6,112.47,25.84,144.31 +2100,3,E06000010,3,56.29,104,25.84,113.53 +2426,3,E06000010,4,63.67,120.97,25.84,175.09 +3078,4,E06000010,0,51.82,160.88,18.64,190.67 +4398,5,E06000010,1,50.76,81.71,25.84,88.07 +4878,5,E06000010,2,58.13,102.94,25.84,112.47 +5509,5,E06000010,3,62.75,125.22,25.84,136.89 +6114,5,E06000010,4,72.9,170.85,25.84,185.7 +3404,6,E06000010,0,52.86,191.88,18.64,208.55 +4552,7,E06000010,1,46.13,81.71,25.84,88.07 +4820,7,E06000010,2,52.6,102.94,25.84,112.47 +5856,7,E06000010,3,56.29,125.22,25.84,136.89 +6212,7,E06000010,4,63.67,170.85,25.84,185.7 +3730,8,E06000010,0,51.82,191.88,18.64,208.55 +6664,9,E06000010,1,50.76,102.16,25.84,110.1 +6990,9,E06000010,2,52.6,128.67,25.84,140.6 +7316,9,E06000010,3,62.75,156.51,25.84,171.11 +7642,9,E06000010,4,72.9,213.57,25.84,232.15 +7968,10,E06000010,0,52.86,223.45,18.64,244.32 +145,1,E09000021,1,65.51,145.37,25.84,197.39 +471,1,E09000021,2,77.51,157.04,25.84,192.07 +797,1,E09000021,3,83.97,166.61,25.84,226.01 +1123,1,E09000021,4,101.48,186.77,25.84,251.49 +2753,2,E09000021,0,70.47,317,18.64,502.91 +1449,3,E09000021,1,58.13,118.85,25.84,146.43 +1775,3,E09000021,2,63.67,139.02,25.84,175.09 +2101,3,E09000021,3,71.06,159.17,25.84,200.55 +2427,3,E09000021,4,83.05,259.98,25.84,261.04 +3079,4,E09000021,0,60.1,371.82,18.64,402.8 +3970,5,E09000021,1,65.51,209.06,25.84,228.14 +4585,5,E09000021,2,77.51,270.61,25.84,295.01 +5237,5,E09000021,3,83.97,336.37,25.84,367.16 +5922,5,E09000021,4,101.48,561.35,25.84,611.23 +3405,6,E09000021,0,70.47,630.42,18.64,686.44 +4184,7,E09000021,1,58.13,209.06,25.84,228.14 +4685,7,E09000021,2,63.67,270.61,25.84,295.01 +5337,7,E09000021,3,71.06,336.37,25.84,367.16 +5889,7,E09000021,4,83.05,561.35,25.84,611.23 +3731,8,E09000021,0,60.1,630.42,18.64,686.44 +6665,9,E09000021,1,65.51,261.31,25.84,285.19 +6991,9,E09000021,2,77.51,338.25,25.84,368.76 +7317,9,E09000021,3,83.97,420.48,25.84,458.95 +7643,9,E09000021,4,101.48,701.69,25.84,764.03 +7969,10,E09000021,0,70.47,284.53,18.64,309.82 +146,1,E08000034,1,50.76,91.27,25.84,113.53 +472,1,E08000034,2,58.13,108.24,25.84,140.08 +798,1,E08000034,3,62.75,119.9,25.84,161.3 +1124,1,E08000034,4,72.9,144.31,25.84,178.28 +2754,2,E08000034,0,52.86,234.75,18.64,322.95 +1450,3,E08000034,1,46.13,81.71,25.84,92.33 +1776,3,E08000034,2,52.6,112.47,25.84,144.31 +2102,3,E08000034,3,56.29,104,25.84,113.53 +2428,3,E08000034,4,63.67,120.97,25.84,175.09 +3080,4,E08000034,0,51.82,160.88,18.64,190.67 +4399,5,E08000034,1,50.76,96.56,25.84,105.06 +4879,5,E08000034,2,58.13,113.53,25.84,123.09 +5510,5,E08000034,3,62.75,134.77,25.84,147.5 +6115,5,E08000034,4,72.9,192.07,25.84,210.12 +3406,6,E08000034,0,52.86,215.7,18.64,235.95 +4553,7,E08000034,1,46.13,96.56,25.84,105.06 +4821,7,E08000034,2,52.6,113.53,25.84,123.09 +5857,7,E08000034,3,56.29,134.77,25.84,147.5 +6213,7,E08000034,4,63.67,192.07,25.84,210.12 +3732,8,E08000034,0,51.82,215.7,18.64,235.95 +6666,9,E08000034,1,50.76,120.73,25.84,131.32 +6992,9,E08000034,2,52.6,141.94,25.84,153.86 +7318,9,E08000034,3,62.75,168.46,25.84,184.37 +7644,9,E08000034,4,72.9,240.08,25.84,262.64 +7970,10,E08000034,0,52.86,308.35,18.64,336.65 +147,1,E08000011,1,51.68,93.39,25.84,116.72 +473,1,E08000011,2,59.06,107.19,25.84,134.77 +799,1,E08000011,3,65.51,119.9,25.84,145.37 +1125,1,E08000011,4,71.98,133.71,25.84,159.17 +2755,2,E08000011,0,55.97,239.54,18.64,342.01 +1451,3,E08000011,1,43.36,85.94,25.84,100.81 +1777,3,E08000011,2,53.52,94.47,25.84,113.53 +2103,3,E08000011,3,58.13,105.06,25.84,124.15 +2429,3,E08000011,4,55.37,118.85,25.84,133.71 +3081,4,E08000011,0,33.16,469.54,18.64,599.44 +4368,5,E08000011,1,51.68,109.29,25.84,118.85 +4938,5,E08000011,2,59.06,125.22,25.84,136.89 +5581,5,E08000011,3,65.51,142.18,25.84,154.93 +6329,5,E08000011,4,71.98,203.75,25.84,221.77 +3407,6,E08000011,0,55.97,228.81,18.64,249.07 +4480,7,E08000011,1,43.36,109.29,25.84,118.85 +5076,7,E08000011,2,53.52,125.22,25.84,136.89 +5756,7,E08000011,3,58.13,142.18,25.84,154.93 +6380,7,E08000011,4,55.37,203.75,25.84,221.77 +3733,8,E08000011,0,33.16,228.81,18.64,249.07 +6667,9,E08000011,1,51.68,136.63,25.84,148.56 +6993,9,E08000011,2,59.06,156.51,25.84,171.11 +7319,9,E08000011,3,65.51,177.73,25.84,193.64 +7645,9,E08000011,4,71.98,254.69,25.84,277.23 +7971,10,E08000011,0,55.97,516.92,18.64,563.1 +148,1,E09000022,1,65.51,145.37,25.84,197.39 +474,1,E09000022,2,77.51,157.04,25.84,192.07 +800,1,E09000022,3,83.97,166.61,25.84,226.01 +1126,1,E09000022,4,101.48,186.77,25.84,251.49 +2756,2,E09000022,0,70.47,317,18.64,502.91 +1452,3,E09000022,1,58.13,118.85,25.84,146.43 +1778,3,E09000022,2,63.67,139.02,25.84,175.09 +2104,3,E09000022,3,71.06,159.17,25.84,200.55 +2430,3,E09000022,4,83.05,259.98,25.84,261.04 +3082,4,E09000022,0,60.1,371.82,18.64,402.8 +3971,5,E09000022,1,65.51,273.78,25.84,298.19 +4586,5,E09000022,2,77.51,326.84,25.84,356.55 +5238,5,E09000022,3,83.97,428.71,25.84,467.97 +5923,5,E09000022,4,101.48,613.35,25.84,667.48 +3408,6,E09000022,0,70.47,686.44,18.64,749.59 +4185,7,E09000022,1,58.13,273.78,25.84,298.19 +4686,7,E09000022,2,63.67,326.84,25.84,356.55 +5338,7,E09000022,3,71.06,428.71,25.84,467.97 +5890,7,E09000022,4,83.05,613.35,25.84,667.48 +3734,8,E09000022,0,60.1,686.44,18.64,749.59 +6668,9,E09000022,1,65.51,342.23,25.84,372.74 +6994,9,E09000022,2,77.51,408.54,25.84,445.68 +7320,9,E09000022,3,83.97,535.89,25.84,584.95 +7646,9,E09000022,4,101.48,766.71,25.84,834.33 +7972,10,E09000022,0,70.47,278.57,18.64,302.41 +149,1,E07000121,1,51.68,93.39,25.84,116.72 +475,1,E07000121,2,59.06,107.19,25.84,134.77 +801,1,E07000121,3,65.51,119.9,25.84,145.37 +1127,1,E07000121,4,71.98,133.71,25.84,159.17 +2757,2,E07000121,0,55.97,239.54,18.64,342.01 +1453,3,E07000121,1,43.36,85.94,25.84,100.81 +1779,3,E07000121,2,53.52,94.47,25.84,113.53 +2105,3,E07000121,3,58.13,105.06,25.84,124.15 +2431,3,E07000121,4,55.37,118.85,25.84,133.71 +3083,4,E07000121,0,33.16,469.54,18.64,599.44 +4369,5,E07000121,1,51.68,109.29,25.84,118.85 +4939,5,E07000121,2,59.06,130.52,25.84,143.25 +5582,5,E07000121,3,65.51,147.5,25.84,160.24 +6330,5,E07000121,4,71.98,180.4,25.84,197.39 +3409,6,E07000121,0,55.97,202.58,18.64,221.66 +4481,7,E07000121,1,43.36,109.29,25.84,118.85 +5077,7,E07000121,2,53.52,130.52,25.84,143.25 +5757,7,E07000121,3,58.13,147.5,25.84,160.24 +6381,7,E07000121,4,55.37,180.4,25.84,197.39 +3735,8,E07000121,0,33.16,202.58,18.64,221.66 +6669,9,E07000121,1,51.68,136.63,25.84,148.56 +6995,9,E07000121,2,59.06,163.15,25.84,179.06 +7321,9,E07000121,3,65.51,184.37,25.84,200.32 +7647,9,E07000121,4,71.98,225.52,25.84,246.73 +7973,10,E07000121,0,55.97,302.41,18.64,330.71 +150,1,E08000035,1,50.76,91.27,25.84,113.53 +476,1,E08000035,2,58.13,108.24,25.84,140.08 +802,1,E08000035,3,62.75,119.9,25.84,161.3 +1128,1,E08000035,4,72.9,144.31,25.84,178.28 +2758,2,E08000035,0,52.86,234.75,18.64,322.95 +1454,3,E08000035,1,46.13,81.71,25.84,92.33 +1780,3,E08000035,2,52.6,112.47,25.84,144.31 +2106,3,E08000035,3,56.29,104,25.84,113.53 +2432,3,E08000035,4,63.67,120.97,25.84,175.09 +3084,4,E08000035,0,51.82,160.88,18.64,190.67 +4400,5,E08000035,1,50.76,125.22,25.84,136.89 +4880,5,E08000035,2,58.13,153.86,25.84,167.67 +5511,5,E08000035,3,62.75,188.88,25.84,205.88 +6116,5,E08000035,4,72.9,409.6,25.84,446.76 +3410,6,E08000035,0,52.86,460,18.64,501.72 +4554,7,E08000035,1,46.13,125.22,25.84,136.89 +4822,7,E08000035,2,52.6,153.86,25.84,167.67 +5858,7,E08000035,3,56.29,188.88,25.84,205.88 +6214,7,E08000035,4,63.67,409.6,25.84,446.76 +3736,8,E08000035,0,51.82,460,18.64,501.72 +6670,9,E08000035,1,50.76,156.51,25.84,171.11 +6996,9,E08000035,2,52.6,192.33,25.84,209.57 +7322,9,E08000035,3,62.75,236.12,25.84,257.33 +7648,9,E08000035,4,72.9,512.02,25.84,558.42 +7974,10,E08000035,0,52.86,284.53,18.64,309.82 +151,1,E06000016,1,51.68,99.75,25.84,122.03 +477,1,E06000016,2,61.83,114.6,25.84,129.46 +803,1,E06000016,3,68.28,126.28,25.84,137.95 +1129,1,E06000016,4,75.67,158.1,25.84,166.61 +2759,2,E06000016,0,51.82,240.72,18.64,361.1 +1455,3,E06000016,1,46.13,90.21,25.84,107.19 +1781,3,E06000016,2,52.6,96.56,25.84,108.24 +2107,3,E06000016,3,58.13,104,25.84,118.85 +2433,3,E06000016,4,63.67,122.03,25.84,122.03 +3085,4,E06000016,0,49.74,114.39,18.64,123.94 +4332,5,E06000016,1,51.68,107.19,25.84,116.72 +5028,5,E06000016,2,61.83,125.22,25.84,136.89 +5671,5,E06000016,3,68.28,136.89,25.84,148.56 +6246,5,E06000016,4,75.67,197.39,25.84,214.35 +3411,6,E06000016,0,51.82,220.48,18.64,240.72 +4432,7,E06000016,1,46.13,107.19,25.84,116.72 +5168,7,E06000016,2,52.6,125.22,25.84,136.89 +5829,7,E06000016,3,58.13,136.89,25.84,148.56 +6490,7,E06000016,4,63.67,197.39,25.84,214.35 +3737,8,E06000016,0,49.74,220.48,18.64,240.72 +6671,9,E06000016,1,51.68,133.98,25.84,145.91 +6997,9,E06000016,2,61.83,156.51,25.84,171.11 +7323,9,E06000016,3,68.28,171.11,25.84,185.69 +7649,9,E06000016,4,75.67,246.73,25.84,267.95 +7975,10,E06000016,0,51.82,473.7,18.64,516.92 +152,1,E07000063,1,57.21,123.09,25.84,176.15 +478,1,E07000063,2,71.06,146.43,25.84,186.77 +804,1,E07000063,3,81.2,161.3,25.84,203.75 +1130,1,E07000063,4,89.52,178.28,25.84,221.77 +2760,2,E07000063,0,62.17,268.13,18.64,344.4 +1456,3,E07000063,1,51.68,115.66,25.84,159.17 +1782,3,E07000063,2,62.75,129.46,25.84,145.37 +2108,3,E07000063,3,68.28,149.62,25.84,185.7 +2434,3,E07000063,4,72.9,184.64,25.84,194.19 +3086,4,E07000063,0,48.71,195.45,18.64,204.96 +4011,5,E07000063,1,57.21,142.18,25.84,154.93 +4626,5,E07000063,2,71.06,186.77,25.84,203.75 +5278,5,E07000063,3,81.2,226.01,25.84,245.12 +5963,5,E07000063,4,89.52,337.44,25.84,368.22 +3412,6,E07000063,0,62.17,378.95,18.64,413.53 +4078,7,E07000063,1,51.68,142.18,25.84,154.93 +4773,7,E07000063,2,62.75,186.77,25.84,203.75 +5378,7,E07000063,3,68.28,226.01,25.84,245.12 +6067,7,E07000063,4,72.9,337.44,25.84,368.22 +3738,8,E07000063,0,48.71,378.95,18.64,413.53 +6672,9,E07000063,1,57.21,177.73,25.84,193.64 +6998,9,E07000063,2,71.06,233.46,25.84,254.69 +7324,9,E07000063,3,81.2,282.54,25.84,306.4 +7650,9,E07000063,4,89.52,421.8,25.84,460.26 +7976,10,E07000063,0,62.17,788.01,18.64,858.05 +153,1,E09000023,1,65.51,145.37,25.84,197.39 +479,1,E09000023,2,77.51,157.04,25.84,192.07 +805,1,E09000023,3,83.97,166.61,25.84,226.01 +1131,1,E09000023,4,101.48,186.77,25.84,251.49 +2761,2,E09000023,0,70.47,317,18.64,502.91 +1457,3,E09000023,1,58.13,118.85,25.84,146.43 +1783,3,E09000023,2,63.67,139.02,25.84,175.09 +2109,3,E09000023,3,71.06,159.17,25.84,200.55 +2435,3,E09000023,4,83.05,259.98,25.84,261.04 +3087,4,E09000023,0,60.1,371.82,18.64,402.8 +3972,5,E09000023,1,65.51,192.07,25.84,210.12 +4587,5,E09000023,2,77.51,248.31,25.84,270.61 +5239,5,E09000023,3,83.97,316.23,25.84,344.88 +5924,5,E09000023,4,101.48,467.97,25.84,509.36 +3413,6,E09000023,0,70.47,525.55,18.64,572.03 +4186,7,E09000023,1,58.13,192.07,25.84,210.12 +4687,7,E09000023,2,63.67,248.31,25.84,270.61 +5339,7,E09000023,3,71.06,316.23,25.84,344.88 +5891,7,E09000023,4,83.05,467.97,25.84,509.36 +3739,8,E09000023,0,60.1,525.55,18.64,572.03 +6673,9,E09000023,1,65.51,240.08,25.84,262.64 +6999,9,E09000023,2,77.51,310.37,25.84,338.25 +7325,9,E09000023,3,83.97,395.3,25.84,431.1 +7651,9,E09000023,4,101.48,584.95,25.84,636.7 +7977,10,E09000023,0,70.47,458.81,18.64,500.53 +154,1,E07000194,1,52.6,98.69,25.84,124.15 +480,1,E07000194,2,58.13,116.72,25.84,136.89 +806,1,E07000194,3,69.2,132.64,25.84,160.24 +1132,1,E07000194,4,80.28,161.3,25.84,178.28 +2762,2,E07000194,0,39.38,245.49,18.64,382.53 +1458,3,E07000194,1,46.13,88.07,25.84,97.63 +1784,3,E07000194,2,49.84,94.47,25.84,102.94 +2110,3,E07000194,3,59.98,104,25.84,119.9 +2436,3,E07000194,4,68.28,127.34,25.84,127.34 +3088,4,E07000194,0,46.63,107.26,18.64,107.26 +4288,5,E07000194,1,52.6,113.53,25.84,123.09 +4898,5,E07000194,2,58.13,134.77,25.84,147.5 +5529,5,E07000194,3,69.2,170.85,25.84,185.7 +6181,5,E07000194,4,80.28,269.54,25.84,293.94 +3414,6,E07000194,0,39.38,302.7,18.64,330.11 +4509,7,E07000194,1,46.13,113.53,25.84,123.09 +5194,7,E07000194,2,49.84,134.77,25.84,147.5 +5785,7,E07000194,3,59.98,170.85,25.84,185.7 +6446,7,E07000194,4,68.28,269.54,25.84,293.94 +3740,8,E07000194,0,46.63,302.7,18.64,330.11 +6674,9,E07000194,1,52.6,141.94,25.84,153.86 +7000,9,E07000194,2,58.13,168.46,25.84,184.37 +7326,9,E07000194,3,69.2,213.57,25.84,232.15 +7652,9,E07000194,4,80.28,336.93,25.84,367.42 +7978,10,E07000194,0,39.38,269.62,18.64,294.95 +155,1,E07000138,1,51.68,99.75,25.84,122.03 +481,1,E07000138,2,61.83,114.6,25.84,129.46 +807,1,E07000138,3,68.28,126.28,25.84,137.95 +1133,1,E07000138,4,75.67,158.1,25.84,166.61 +2763,2,E07000138,0,51.82,240.72,18.64,361.1 +1459,3,E07000138,1,46.13,90.21,25.84,107.19 +1785,3,E07000138,2,52.6,96.56,25.84,108.24 +2111,3,E07000138,3,58.13,104,25.84,118.85 +2437,3,E07000138,4,63.67,122.03,25.84,122.03 +3089,4,E07000138,0,49.74,114.39,18.64,123.94 +4333,5,E07000138,1,51.68,102.94,25.84,112.47 +5029,5,E07000138,2,61.83,117.78,25.84,128.4 +5672,5,E07000138,3,68.28,134.77,25.84,147.5 +6247,5,E07000138,4,75.67,175.09,25.84,189.94 +3415,6,E07000138,0,51.82,196.63,18.64,213.31 +4433,7,E07000138,1,46.13,102.94,25.84,112.47 +5169,7,E07000138,2,52.6,117.78,25.84,128.4 +5830,7,E07000138,3,58.13,134.77,25.84,147.5 +6491,7,E07000138,4,63.67,175.09,25.84,189.94 +3741,8,E07000138,0,49.74,196.63,18.64,213.31 +6675,9,E07000138,1,51.68,128.67,25.84,140.6 +7001,9,E07000138,2,61.83,147.23,25.84,160.51 +7327,9,E07000138,3,68.28,168.46,25.84,184.37 +7653,9,E07000138,4,75.67,218.87,25.84,237.44 +7979,10,E07000138,0,51.82,628.63,18.64,686.73 +156,1,E08000012,1,51.68,93.39,25.84,116.72 +482,1,E08000012,2,59.06,107.19,25.84,134.77 +808,1,E08000012,3,65.51,119.9,25.84,145.37 +1134,1,E08000012,4,71.98,133.71,25.84,159.17 +2764,2,E08000012,0,55.97,239.54,18.64,342.01 +1460,3,E08000012,1,43.36,85.94,25.84,100.81 +1786,3,E08000012,2,53.52,94.47,25.84,113.53 +2112,3,E08000012,3,58.13,105.06,25.84,124.15 +2438,3,E08000012,4,55.37,118.85,25.84,133.71 +3090,4,E08000012,0,33.16,469.54,18.64,599.44 +4370,5,E08000012,1,51.68,113.53,25.84,123.09 +4940,5,E08000012,2,59.06,147.5,25.84,160.24 +5583,5,E08000012,3,65.51,142.18,25.84,154.93 +6331,5,E08000012,4,71.98,227.08,25.84,246.18 +3416,6,E08000012,0,55.97,255.02,18.64,276.48 +4482,7,E08000012,1,43.36,113.53,25.84,123.09 +5078,7,E08000012,2,53.52,147.5,25.84,160.24 +5758,7,E08000012,3,58.13,142.18,25.84,154.93 +6382,7,E08000012,4,55.37,227.08,25.84,246.18 +3742,8,E08000012,0,33.16,255.02,18.64,276.48 +6676,9,E08000012,1,51.68,141.94,25.84,153.86 +7002,9,E08000012,2,59.06,184.37,25.84,200.32 +7328,9,E08000012,3,65.51,177.73,25.84,193.64 +7654,9,E08000012,4,71.98,283.85,25.84,307.73 +7980,10,E08000012,0,55.97,403.71,18.64,439.44 +157,1,E06000032,1,54.44,118.85,25.84,148.56 +483,1,E06000032,2,64.59,142.18,25.84,167.67 +809,1,E06000032,3,71.06,155.98,25.84,180.4 +1135,1,E06000032,4,81.2,170.85,25.84,178.28 +2765,2,E06000032,0,36.26,226.42,18.64,423.05 +1461,3,E06000032,1,49.84,99.75,25.84,131.58 +1787,3,E06000032,2,58.13,117.78,25.84,132.64 +2113,3,E06000032,3,63.67,130.52,25.84,143.25 +2439,3,E06000032,4,71.06,148.56,25.84,159.17 +3091,4,E06000032,0,55.97,135.86,18.64,318.19 +4142,5,E06000032,1,54.44,119.9,25.84,130.52 +4723,5,E06000032,2,64.59,147.5,25.84,160.24 +5442,5,E06000032,3,71.06,180.4,25.84,197.39 +6152,5,E06000032,4,81.2,248.31,25.84,270.61 +3417,6,E06000032,0,36.26,278.86,18.64,303.89 +4259,7,E06000032,1,49.84,119.9,25.84,130.52 +4985,7,E06000032,2,58.13,147.5,25.84,160.24 +5628,7,E06000032,3,63.67,180.4,25.84,197.39 +6290,7,E06000032,4,71.06,248.31,25.84,270.61 +3743,8,E06000032,0,55.97,278.86,18.64,303.89 +6677,9,E06000032,1,54.44,149.9,25.84,163.15 +7003,9,E06000032,2,64.59,184.37,25.84,200.32 +7329,9,E06000032,3,71.06,225.52,25.84,246.73 +7655,9,E06000032,4,81.2,310.37,25.84,338.25 +7981,10,E06000032,0,36.26,348.6,18.64,379.86 +158,1,E07000110,1,57.21,123.09,25.84,176.15 +484,1,E07000110,2,71.06,146.43,25.84,186.77 +810,1,E07000110,3,81.2,161.3,25.84,203.75 +1136,1,E07000110,4,89.52,178.28,25.84,221.77 +2766,2,E07000110,0,62.17,268.13,18.64,344.4 +1462,3,E07000110,1,51.68,115.66,25.84,159.17 +1788,3,E07000110,2,62.75,129.46,25.84,145.37 +2114,3,E07000110,3,68.28,149.62,25.84,185.7 +2440,3,E07000110,4,72.9,184.64,25.84,194.19 +3092,4,E07000110,0,48.71,195.45,18.64,204.96 +4012,5,E07000110,1,57.21,134.77,25.84,147.5 +4627,5,E07000110,2,71.06,164.48,25.84,179.34 +5279,5,E07000110,3,81.2,192.07,25.84,210.12 +5964,5,E07000110,4,89.52,281.2,25.84,306.68 +3418,6,E07000110,0,62.17,315.82,18.64,344.4 +4079,7,E07000110,1,51.68,134.77,25.84,147.5 +4774,7,E07000110,2,62.75,164.48,25.84,179.34 +5379,7,E07000110,3,68.28,192.07,25.84,210.12 +6068,7,E07000110,4,72.9,281.2,25.84,306.68 +3744,8,E07000110,0,48.71,315.82,18.64,344.4 +6678,9,E07000110,1,57.21,168.46,25.84,184.37 +7004,9,E07000110,2,71.06,205.6,25.84,224.18 +7330,9,E07000110,3,81.2,240.08,25.84,262.64 +7656,9,E07000110,4,89.52,351.51,25.84,383.34 +7982,10,E07000110,0,62.17,819.3,18.64,892.3 +159,1,E07000074,1,54.44,118.85,25.84,148.56 +485,1,E07000074,2,64.59,142.18,25.84,167.67 +811,1,E07000074,3,71.06,155.98,25.84,180.4 +1137,1,E07000074,4,81.2,170.85,25.84,178.28 +2767,2,E07000074,0,36.26,226.42,18.64,423.05 +1463,3,E07000074,1,49.84,99.75,25.84,131.58 +1789,3,E07000074,2,58.13,117.78,25.84,132.64 +2115,3,E07000074,3,63.67,130.52,25.84,143.25 +2441,3,E07000074,4,71.06,148.56,25.84,159.17 +3093,4,E07000074,0,55.97,135.86,18.64,318.19 +4143,5,E07000074,1,54.44,125.22,25.84,136.89 +4724,5,E07000074,2,64.59,164.48,25.84,179.34 +5443,5,E07000074,3,71.06,192.07,25.84,210.12 +6153,5,E07000074,4,81.2,292.87,25.84,319.41 +3419,6,E07000074,0,36.26,328.92,18.64,358.7 +4260,7,E07000074,1,49.84,125.22,25.84,136.89 +4986,7,E07000074,2,58.13,164.48,25.84,179.34 +5629,7,E07000074,3,63.67,192.07,25.84,210.12 +6291,7,E07000074,4,71.06,292.87,25.84,319.41 +3745,8,E07000074,0,55.97,328.92,18.64,358.7 +6679,9,E07000074,1,54.44,156.51,25.84,171.11 +7005,9,E07000074,2,64.59,205.6,25.84,224.18 +7331,9,E07000074,3,71.06,240.08,25.84,262.64 +7657,9,E07000074,4,81.2,366.11,25.84,399.27 +7983,10,E07000074,0,36.26,394.77,18.64,430.5 +160,1,E07000235,1,52.6,98.69,25.84,124.15 +486,1,E07000235,2,58.13,116.72,25.84,136.89 +812,1,E07000235,3,69.2,132.64,25.84,160.24 +1138,1,E07000235,4,80.28,161.3,25.84,178.28 +2768,2,E07000235,0,39.38,245.49,18.64,382.53 +1464,3,E07000235,1,46.13,88.07,25.84,97.63 +1790,3,E07000235,2,49.84,94.47,25.84,102.94 +2116,3,E07000235,3,59.98,104,25.84,119.9 +2442,3,E07000235,4,68.28,127.34,25.84,127.34 +3094,4,E07000235,0,46.63,107.26,18.64,107.26 +4289,5,E07000235,1,52.6,113.53,25.84,123.09 +4899,5,E07000235,2,58.13,134.77,25.84,147.5 +5530,5,E07000235,3,69.2,164.48,25.84,179.34 +6182,5,E07000235,4,80.28,270.61,25.84,295.01 +3420,6,E07000235,0,39.38,303.89,18.64,331.29 +4510,7,E07000235,1,46.13,113.53,25.84,123.09 +5195,7,E07000235,2,49.84,134.77,25.84,147.5 +5786,7,E07000235,3,59.98,164.48,25.84,179.34 +6447,7,E07000235,4,68.28,270.61,25.84,295.01 +3746,8,E07000235,0,46.63,303.89,18.64,331.29 +6680,9,E07000235,1,52.6,141.94,25.84,153.86 +7006,9,E07000235,2,58.13,168.46,25.84,184.37 +7332,9,E07000235,3,69.2,205.6,25.84,224.18 +7658,9,E07000235,4,80.28,338.25,25.84,368.76 +7984,10,E07000235,0,39.38,379.86,18.64,414.12 +61,1,E08000003,1,51.68,93.39,25.84,116.72 +387,1,E08000003,2,59.06,107.19,25.84,134.77 +713,1,E08000003,3,65.51,119.9,25.84,145.37 +1039,1,E08000003,4,71.98,133.71,25.84,159.17 +2669,2,E08000003,0,55.97,239.54,18.64,342.01 +1365,3,E08000003,1,43.36,85.94,25.84,100.81 +1691,3,E08000003,2,53.52,94.47,25.84,113.53 +2017,3,E08000003,3,58.13,105.06,25.84,124.15 +2343,3,E08000003,4,55.37,118.85,25.84,133.71 +2995,4,E08000003,0,33.16,469.54,18.64,599.44 +4361,5,E08000003,1,51.68,130.52,25.84,143.25 +4931,5,E08000003,2,59.06,153.86,25.84,167.67 +5574,5,E08000003,3,65.51,174.02,25.84,189.94 +6322,5,E08000003,4,71.98,270.61,25.84,295.01 +3321,6,E08000003,0,55.97,303.89,18.64,331.29 +4473,7,E08000003,1,43.36,130.52,25.84,143.25 +5069,7,E08000003,2,53.52,153.86,25.84,167.67 +5749,7,E08000003,3,58.13,174.02,25.84,189.94 +6373,7,E08000003,4,55.37,270.61,25.84,295.01 +3647,8,E08000003,0,33.16,303.89,18.64,331.29 +6581,9,E08000003,1,51.68,163.15,25.84,179.06 +6907,9,E08000003,2,59.06,192.33,25.84,209.57 +7233,9,E08000003,3,65.51,217.54,25.84,237.44 +7559,9,E08000003,4,71.98,338.25,25.84,368.76 +7885,10,E08000003,0,55.97,253.23,18.64,277.06 +161,1,E07000174,1,51.68,99.75,25.84,122.03 +487,1,E07000174,2,61.83,114.6,25.84,129.46 +813,1,E07000174,3,68.28,126.28,25.84,137.95 +1139,1,E07000174,4,75.67,158.1,25.84,166.61 +2769,2,E07000174,0,51.82,240.72,18.64,361.1 +1465,3,E07000174,1,46.13,90.21,25.84,107.19 +1791,3,E07000174,2,52.6,96.56,25.84,108.24 +2117,3,E07000174,3,58.13,104,25.84,118.85 +2443,3,E07000174,4,63.67,122.03,25.84,122.03 +3095,4,E07000174,0,49.74,114.39,18.64,123.94 +4334,5,E07000174,1,51.68,88.07,25.84,96.56 +5030,5,E07000174,2,61.83,109.29,25.84,118.85 +5673,5,E07000174,3,68.28,125.22,25.84,136.89 +6248,5,E07000174,4,75.67,180.4,25.84,197.39 +3421,6,E07000174,0,51.82,202.58,18.64,221.66 +4434,7,E07000174,1,46.13,88.07,25.84,96.56 +5170,7,E07000174,2,52.6,109.29,25.84,118.85 +5831,7,E07000174,3,58.13,125.22,25.84,136.89 +6492,7,E07000174,4,63.67,180.4,25.84,197.39 +3747,8,E07000174,0,49.74,202.58,18.64,221.66 +6681,9,E07000174,1,51.68,110.1,25.84,120.73 +7007,9,E07000174,2,61.83,136.63,25.84,148.56 +7333,9,E07000174,3,68.28,156.51,25.84,171.11 +7659,9,E07000174,4,75.67,225.52,25.84,246.73 +7985,10,E07000174,0,51.82,379.86,18.64,414.12 +280,1,E06000035,1,57.21,123.09,25.84,176.15 +606,1,E06000035,2,71.06,146.43,25.84,186.77 +932,1,E06000035,3,81.2,161.3,25.84,203.75 +1258,1,E06000035,4,89.52,178.28,25.84,221.77 +2888,2,E06000035,0,62.17,268.13,18.64,344.4 +1584,3,E06000035,1,51.68,115.66,25.84,159.17 +1910,3,E06000035,2,62.75,129.46,25.84,145.37 +2236,3,E06000035,3,68.28,149.62,25.84,185.7 +2562,3,E06000035,4,72.9,184.64,25.84,194.19 +3214,4,E06000035,0,48.71,195.45,18.64,204.96 +4036,5,E06000035,1,57.21,125.22,25.84,136.89 +4651,5,E06000035,2,71.06,147.5,25.84,160.24 +5303,5,E06000035,3,81.2,170.85,25.84,185.7 +5988,5,E06000035,4,89.52,270.61,25.84,295.01 +3540,6,E06000035,0,62.17,303.89,18.64,331.29 +4103,7,E06000035,1,51.68,125.22,25.84,136.89 +4798,7,E06000035,2,62.75,147.5,25.84,160.24 +5403,7,E06000035,3,68.28,170.85,25.84,185.7 +6092,7,E06000035,4,72.9,270.61,25.84,295.01 +3866,8,E06000035,0,48.71,303.89,18.64,331.29 +6800,9,E06000035,1,57.21,156.51,25.84,171.11 +7126,9,E06000035,2,71.06,184.37,25.84,200.32 +7452,9,E06000035,3,81.2,213.57,25.84,232.15 +7778,9,E06000035,4,89.52,338.25,25.84,368.76 +8104,10,E06000035,0,62.17,379.86,18.64,414.12 +162,1,E07000133,1,51.68,99.75,25.84,122.03 +488,1,E07000133,2,61.83,114.6,25.84,129.46 +814,1,E07000133,3,68.28,126.28,25.84,137.95 +1140,1,E07000133,4,75.67,158.1,25.84,166.61 +2770,2,E07000133,0,51.82,240.72,18.64,361.1 +1466,3,E07000133,1,46.13,90.21,25.84,107.19 +1792,3,E07000133,2,52.6,96.56,25.84,108.24 +2118,3,E07000133,3,58.13,104,25.84,118.85 +2444,3,E07000133,4,63.67,122.03,25.84,122.03 +3096,4,E07000133,0,49.74,114.39,18.64,123.94 +4335,5,E07000133,1,51.68,97.63,25.84,107.19 +5031,5,E07000133,2,61.83,119.9,25.84,130.52 +5674,5,E07000133,3,68.28,136.89,25.84,148.56 +6249,5,E07000133,4,75.67,281.2,25.84,306.68 +3422,6,E07000133,0,51.82,315.82,18.64,344.4 +4435,7,E07000133,1,46.13,97.63,25.84,107.19 +5171,7,E07000133,2,52.6,119.9,25.84,130.52 +5832,7,E07000133,3,58.13,136.89,25.84,148.56 +6493,7,E07000133,4,63.67,281.2,25.84,306.68 +3748,8,E07000133,0,49.74,315.82,18.64,344.4 +6682,9,E07000133,1,51.68,122.03,25.84,133.98 +7008,9,E07000133,2,61.83,149.9,25.84,163.15 +7334,9,E07000133,3,68.28,171.11,25.84,185.69 +7660,9,E07000133,4,75.67,351.51,25.84,383.34 +7986,10,E07000133,0,51.82,411.13,18.64,448.39 +164,1,E09000024,1,65.51,145.37,25.84,197.39 +490,1,E09000024,2,77.51,157.04,25.84,192.07 +816,1,E09000024,3,83.97,166.61,25.84,226.01 +1142,1,E09000024,4,101.48,186.77,25.84,251.49 +2772,2,E09000024,0,70.47,317,18.64,502.91 +1468,3,E09000024,1,58.13,118.85,25.84,146.43 +1794,3,E09000024,2,63.67,139.02,25.84,175.09 +2120,3,E09000024,3,71.06,159.17,25.84,200.55 +2446,3,E09000024,4,83.05,259.98,25.84,261.04 +3098,4,E09000024,0,60.1,371.82,18.64,402.8 +3973,5,E09000024,1,65.51,237.69,25.84,258.92 +4588,5,E09000024,2,77.51,304.55,25.84,332.14 +5240,5,E09000024,3,83.97,371.41,25.84,405.36 +5925,5,E09000024,4,101.48,583.64,25.84,635.64 +3424,6,E09000024,0,70.47,655.45,18.64,713.85 +4187,7,E09000024,1,58.13,237.69,25.84,258.92 +4688,7,E09000024,2,63.67,304.55,25.84,332.14 +5340,7,E09000024,3,71.06,371.41,25.84,405.36 +5892,7,E09000024,4,83.05,583.64,25.84,635.64 +3750,8,E09000024,0,60.1,655.45,18.64,713.85 +6684,9,E09000024,1,65.51,297.12,25.84,323.65 +7010,9,E09000024,2,77.51,380.68,25.84,415.17 +7336,9,E09000024,3,83.97,464.26,25.84,506.71 +7662,9,E09000024,4,101.48,729.54,25.84,794.53 +7988,10,E09000024,0,70.47,394.77,18.64,430.5 +165,1,E07000042,1,48.92,107.19,25.84,140.08 +491,1,E07000042,2,55.37,120.97,25.84,144.31 +817,1,E07000042,3,61.83,141.13,25.84,161.3 +1143,1,E07000042,4,71.06,158.1,25.84,194.19 +2773,2,E07000042,0,54.93,231.2,18.64,358.7 +1469,3,E07000042,1,47.06,89.13,25.84,210.12 +1795,3,E07000042,2,54.44,100.81,25.84,111.41 +2121,3,E07000042,3,61.83,109.29,25.84,126.28 +2447,3,E07000042,4,73.82,130.52,25.84,130.52 +3099,4,E07000042,0,54.93,115.59,18.64,141.81 +4211,5,E07000042,1,48.92,102.94,25.84,112.47 +4847,5,E07000042,2,55.37,130.52,25.84,143.25 +5478,5,E07000042,3,61.83,164.48,25.84,180.4 +6016,5,E07000042,4,71.06,248.31,25.84,270.61 +3425,6,E07000042,0,54.93,278.86,18.64,303.89 +3927,7,E07000042,1,47.06,102.94,25.84,112.47 +5124,7,E07000042,2,54.44,130.52,25.84,143.25 +5704,7,E07000042,3,61.83,164.48,25.84,180.4 +6416,7,E07000042,4,73.82,248.31,25.84,270.61 +3751,8,E07000042,0,54.93,278.86,18.64,303.89 +6685,9,E07000042,1,48.92,128.67,25.84,140.6 +7011,9,E07000042,2,55.37,163.15,25.84,179.06 +7337,9,E07000042,3,61.83,205.6,25.84,225.52 +7663,9,E07000042,4,71.06,310.37,25.84,338.25 +7989,10,E07000042,0,54.93,348.6,18.64,379.86 +166,1,E07000203,1,54.44,118.85,25.84,148.56 +492,1,E07000203,2,64.59,142.18,25.84,167.67 +818,1,E07000203,3,71.06,155.98,25.84,180.4 +1144,1,E07000203,4,81.2,170.85,25.84,178.28 +2774,2,E07000203,0,36.26,226.42,18.64,423.05 +1470,3,E07000203,1,49.84,99.75,25.84,131.58 +1796,3,E07000203,2,58.13,117.78,25.84,132.64 +2122,3,E07000203,3,63.67,130.52,25.84,143.25 +2448,3,E07000203,4,71.06,148.56,25.84,159.17 +3100,4,E07000203,0,55.97,135.86,18.64,318.19 +4144,5,E07000203,1,54.44,100.81,25.84,110.36 +4725,5,E07000203,2,64.59,125.22,25.84,136.89 +5444,5,E07000203,3,71.06,159.17,25.84,174.02 +6154,5,E07000203,4,81.2,287.59,25.84,313.05 +3426,6,E07000203,0,36.26,322.95,18.64,351.54 +4261,7,E07000203,1,49.84,100.81,25.84,110.36 +4987,7,E07000203,2,58.13,125.22,25.84,136.89 +5630,7,E07000203,3,63.67,159.17,25.84,174.02 +6292,7,E07000203,4,71.06,287.59,25.84,313.05 +3752,8,E07000203,0,55.97,322.95,18.64,351.54 +6686,9,E07000203,1,54.44,126.02,25.84,137.95 +7012,9,E07000203,2,64.59,156.51,25.84,171.11 +7338,9,E07000203,3,71.06,198.96,25.84,217.54 +7664,9,E07000203,4,81.2,359.47,25.84,391.31 +7990,10,E07000203,0,36.26,318.79,18.64,345.6 +167,1,E07000228,1,57.21,123.09,25.84,176.15 +493,1,E07000228,2,71.06,146.43,25.84,186.77 +819,1,E07000228,3,81.2,161.3,25.84,203.75 +1145,1,E07000228,4,89.52,178.28,25.84,221.77 +2775,2,E07000228,0,62.17,268.13,18.64,344.4 +1471,3,E07000228,1,51.68,115.66,25.84,159.17 +1797,3,E07000228,2,62.75,129.46,25.84,145.37 +2123,3,E07000228,3,68.28,149.62,25.84,185.7 +2449,3,E07000228,4,72.9,184.64,25.84,194.19 +3101,4,E07000228,0,48.71,195.45,18.64,204.96 +4013,5,E07000228,1,57.21,153.86,25.84,167.67 +4628,5,E07000228,2,71.06,192.07,25.84,210.12 +5280,5,E07000228,3,81.2,268.48,25.84,292.87 +5965,5,E07000228,4,89.52,448.87,25.84,489.2 +3427,6,E07000228,0,62.17,502.91,18.64,549.39 +4080,7,E07000228,1,51.68,153.86,25.84,167.67 +4775,7,E07000228,2,62.75,192.07,25.84,210.12 +5380,7,E07000228,3,68.28,268.48,25.84,292.87 +6069,7,E07000228,4,72.9,448.87,25.84,489.2 +3753,8,E07000228,0,48.71,502.91,18.64,549.39 +6687,9,E07000228,1,57.21,192.33,25.84,209.57 +7013,9,E07000228,2,71.06,240.08,25.84,262.64 +7339,9,E07000228,3,81.2,335.59,25.84,366.11 +7665,9,E07000228,4,89.52,561.08,25.84,611.49 +7991,10,E07000228,0,62.17,245.79,18.64,266.63 +168,1,E06000002,1,50.76,88.07,25.84,97.63 +494,1,E06000002,2,57.21,101.88,25.84,119.9 +820,1,E06000002,3,60.9,113.53,25.84,159.17 +1146,1,E06000002,4,70.13,127.34,25.84,139.02 +2776,2,E06000002,0,55.97,237.14,18.64,340.83 +1472,3,E06000002,1,42.44,99.75,25.84,105.06 +1798,3,E06000002,2,49.84,90.21,25.84,111.41 +2124,3,E06000002,3,53.52,105.06,25.84,124.15 +2450,3,E06000002,4,56.29,115.66,25.84,119.9 +3102,4,E06000002,0,47.67,253.84,18.64,288.39 +4536,5,E06000002,1,50.76,97.63,25.84,107.19 +5051,5,E06000002,2,57.21,114.6,25.84,124.15 +5556,5,E06000002,3,60.9,132.64,25.84,145.37 +6355,5,E06000002,4,70.13,192.07,25.84,210.12 +3428,6,E06000002,0,55.97,215.7,18.64,235.95 +4455,7,E06000002,1,42.44,97.63,25.84,107.19 +5102,7,E06000002,2,49.84,114.6,25.84,124.15 +5731,7,E06000002,3,53.52,132.64,25.84,145.37 +6513,7,E06000002,4,56.29,192.07,25.84,210.12 +3754,8,E06000002,0,47.67,215.7,18.64,235.95 +6688,9,E06000002,1,42.44,122.03,25.84,133.98 +7014,9,E06000002,2,57.21,143.25,25.84,155.2 +7340,9,E06000002,3,60.9,165.81,25.84,181.72 +7666,9,E06000002,4,70.13,240.08,25.84,262.64 +7992,10,E06000002,0,55.97,378.39,18.64,412.63 +169,1,E06000042,1,57.21,123.09,25.84,176.15 +495,1,E06000042,2,71.06,146.43,25.84,186.77 +821,1,E06000042,3,81.2,161.3,25.84,203.75 +1147,1,E06000042,4,89.52,178.28,25.84,221.77 +2777,2,E06000042,0,62.17,268.13,18.64,344.4 +1473,3,E06000042,1,51.68,115.66,25.84,159.17 +1799,3,E06000042,2,62.75,129.46,25.84,145.37 +2125,3,E06000042,3,68.28,149.62,25.84,185.7 +2451,3,E06000042,4,72.9,184.64,25.84,194.19 +3103,4,E06000042,0,48.71,195.45,18.64,204.96 +4014,5,E06000042,1,57.21,134.77,25.84,147.5 +4629,5,E06000042,2,71.06,164.48,25.84,179.34 +5281,5,E06000042,3,81.2,186.77,25.84,203.75 +5966,5,E06000042,4,89.52,326.84,25.84,356.55 +3429,6,E06000042,0,62.17,367.04,18.64,400.41 +4081,7,E06000042,1,51.68,134.77,25.84,147.5 +4776,7,E06000042,2,62.75,164.48,25.84,179.34 +5381,7,E06000042,3,68.28,186.77,25.84,203.75 +6070,7,E06000042,4,72.9,326.84,25.84,356.55 +3755,8,E06000042,0,48.71,367.04,18.64,400.41 +6689,9,E06000042,1,57.21,168.46,25.84,184.37 +7015,9,E06000042,2,71.06,205.6,25.84,224.18 +7341,9,E06000042,3,81.2,233.46,25.84,254.69 +7667,9,E06000042,4,89.52,408.54,25.84,445.68 +7993,10,E06000042,0,62.17,656.94,18.64,715.04 +170,1,E07000210,1,57.21,123.09,25.84,176.15 +496,1,E07000210,2,71.06,146.43,25.84,186.77 +822,1,E07000210,3,81.2,161.3,25.84,203.75 +1148,1,E07000210,4,89.52,178.28,25.84,221.77 +2778,2,E07000210,0,62.17,268.13,18.64,344.4 +1474,3,E07000210,1,51.68,115.66,25.84,159.17 +1800,3,E07000210,2,62.75,129.46,25.84,145.37 +2126,3,E07000210,3,68.28,149.62,25.84,185.7 +2452,3,E07000210,4,72.9,184.64,25.84,194.19 +3104,4,E07000210,0,48.71,195.45,18.64,204.96 +4015,5,E07000210,1,57.21,164.48,25.84,179.34 +4630,5,E07000210,2,71.06,237.69,25.84,258.92 +5282,5,E07000210,3,81.2,326.84,25.84,356.55 +5967,5,E07000210,4,89.52,561.35,25.84,611.23 +3430,6,E07000210,0,62.17,630.42,18.64,686.44 +4082,7,E07000210,1,51.68,164.48,25.84,179.34 +4777,7,E07000210,2,62.75,237.69,25.84,258.92 +5382,7,E07000210,3,68.28,326.84,25.84,356.55 +6071,7,E07000210,4,72.9,561.35,25.84,611.23 +3756,8,E07000210,0,48.71,630.42,18.64,686.44 +6690,9,E07000210,1,57.21,205.6,25.84,224.18 +7016,9,E07000210,2,71.06,297.12,25.84,323.65 +7342,9,E07000210,3,81.2,408.54,25.84,445.68 +7668,9,E07000210,4,89.52,701.69,25.84,764.03 +7994,10,E07000210,0,62.17,473.7,18.64,516.92 +171,1,E07000091,1,57.21,123.09,25.84,176.15 +497,1,E07000091,2,71.06,146.43,25.84,186.77 +823,1,E07000091,3,81.2,161.3,25.84,203.75 +1149,1,E07000091,4,89.52,178.28,25.84,221.77 +2779,2,E07000091,0,62.17,268.13,18.64,344.4 +1475,3,E07000091,1,51.68,115.66,25.84,159.17 +1801,3,E07000091,2,62.75,129.46,25.84,145.37 +2127,3,E07000091,3,68.28,149.62,25.84,185.7 +2453,3,E07000091,4,72.9,184.64,25.84,194.19 +3105,4,E07000091,0,48.71,195.45,18.64,204.96 +4016,5,E07000091,1,57.21,134.77,25.84,147.5 +4631,5,E07000091,2,71.06,174.02,25.84,188.88 +5283,5,E07000091,3,81.2,214.35,25.84,234.52 +5968,5,E07000091,4,89.52,337.44,25.84,368.22 +3431,6,E07000091,0,62.17,378.95,18.64,413.53 +4083,7,E07000091,1,51.68,134.77,25.84,147.5 +4778,7,E07000091,2,62.75,174.02,25.84,188.88 +5383,7,E07000091,3,68.28,214.35,25.84,234.52 +6072,7,E07000091,4,72.9,337.44,25.84,368.22 +3757,8,E07000091,0,48.71,378.95,18.64,413.53 +6691,9,E07000091,1,57.21,168.46,25.84,184.37 +7017,9,E07000091,2,71.06,217.54,25.84,236.12 +7343,9,E07000091,3,81.2,267.95,25.84,293.15 +7669,9,E07000091,4,89.52,421.8,25.84,460.26 +7995,10,E07000091,0,62.17,275.59,18.64,300.91 +172,1,E07000175,1,51.68,99.75,25.84,122.03 +498,1,E07000175,2,61.83,114.6,25.84,129.46 +824,1,E07000175,3,68.28,126.28,25.84,137.95 +1150,1,E07000175,4,75.67,158.1,25.84,166.61 +2780,2,E07000175,0,51.82,240.72,18.64,361.1 +1476,3,E07000175,1,46.13,90.21,25.84,107.19 +1802,3,E07000175,2,52.6,96.56,25.84,108.24 +2128,3,E07000175,3,58.13,104,25.84,118.85 +2454,3,E07000175,4,63.67,122.03,25.84,122.03 +3106,4,E07000175,0,49.74,114.39,18.64,123.94 +4336,5,E07000175,1,51.68,92.33,25.84,99.75 +5032,5,E07000175,2,61.83,113.53,25.84,123.09 +5675,5,E07000175,3,68.28,132.64,25.84,145.37 +6250,5,E07000175,4,75.67,202.69,25.84,220.72 +3432,6,E07000175,0,51.82,227.63,18.64,247.88 +4436,7,E07000175,1,46.13,92.33,25.84,99.75 +5172,7,E07000175,2,52.6,113.53,25.84,123.09 +5833,7,E07000175,3,58.13,132.64,25.84,145.37 +6494,7,E07000175,4,63.67,202.69,25.84,220.72 +3758,8,E07000175,0,49.74,227.63,18.64,247.88 +6692,9,E07000175,1,51.68,115.39,25.84,124.69 +7018,9,E07000175,2,61.83,141.94,25.84,153.86 +7344,9,E07000175,3,68.28,165.81,25.84,181.72 +7670,9,E07000175,4,75.67,253.36,25.84,275.9 +7996,10,E07000175,0,51.82,575,18.64,627.12 +174,1,E08000021,1,50.76,88.07,25.84,97.63 +500,1,E08000021,2,57.21,101.88,25.84,119.9 +826,1,E08000021,3,60.9,113.53,25.84,159.17 +1152,1,E08000021,4,70.13,127.34,25.84,139.02 +2782,2,E08000021,0,55.97,237.14,18.64,340.83 +1478,3,E08000021,1,42.44,99.75,25.84,105.06 +1804,3,E08000021,2,49.84,90.21,25.84,111.41 +2130,3,E08000021,3,53.52,105.06,25.84,124.15 +2456,3,E08000021,4,56.29,115.66,25.84,119.9 +3108,4,E08000021,0,47.67,253.84,18.64,288.39 +4537,5,E08000021,1,50.76,113.53,25.84,123.09 +5052,5,E08000021,2,57.21,134.77,25.84,147.5 +5557,5,E08000021,3,60.9,142.18,25.84,154.93 +6356,5,E08000021,4,70.13,215.41,25.84,235.58 +3434,6,E08000021,0,55.97,241.92,18.64,264.56 +4456,7,E08000021,1,42.44,113.53,25.84,123.09 +5103,7,E08000021,2,49.84,134.77,25.84,147.5 +5732,7,E08000021,3,53.52,142.18,25.84,154.93 +6514,7,E08000021,4,56.29,215.41,25.84,235.58 +3760,8,E08000021,0,47.67,241.92,18.64,264.56 +6694,9,E08000021,1,42.44,141.94,25.84,153.86 +7020,9,E08000021,2,57.21,168.46,25.84,184.37 +7346,9,E08000021,3,60.9,177.73,25.84,193.64 +7672,9,E08000021,4,70.13,269.26,25.84,294.49 +7998,10,E08000021,0,55.97,253.23,18.64,277.06 +173,1,E07000195,1,52.6,98.69,25.84,124.15 +499,1,E07000195,2,58.13,116.72,25.84,136.89 +825,1,E07000195,3,69.2,132.64,25.84,160.24 +1151,1,E07000195,4,80.28,161.3,25.84,178.28 +2781,2,E07000195,0,39.38,245.49,18.64,382.53 +1477,3,E07000195,1,46.13,88.07,25.84,97.63 +1803,3,E07000195,2,49.84,94.47,25.84,102.94 +2129,3,E07000195,3,59.98,104,25.84,119.9 +2455,3,E07000195,4,68.28,127.34,25.84,127.34 +3107,4,E07000195,0,46.63,107.26,18.64,107.26 +4290,5,E07000195,1,52.6,97.63,25.84,107.19 +4900,5,E07000195,2,58.13,113.53,25.84,123.09 +5531,5,E07000195,3,69.2,134.77,25.84,147.5 +6183,5,E07000195,4,80.28,198.45,25.84,215.41 +3433,6,E07000195,0,39.38,222.84,18.64,241.92 +4511,7,E07000195,1,46.13,97.63,25.84,107.19 +5196,7,E07000195,2,49.84,113.53,25.84,123.09 +5787,7,E07000195,3,59.98,134.77,25.84,147.5 +6448,7,E07000195,4,68.28,198.45,25.84,215.41 +3759,8,E07000195,0,46.63,222.84,18.64,241.92 +6693,9,E07000195,1,52.6,122.03,25.84,133.98 +7019,9,E07000195,2,58.13,141.94,25.84,153.86 +7345,9,E07000195,3,69.2,168.46,25.84,184.37 +7671,9,E07000195,4,80.28,248.03,25.84,269.26 +7997,10,E07000195,0,39.38,858.05,18.64,936.99 +175,1,E09000025,1,65.51,145.37,25.84,197.39 +501,1,E09000025,2,77.51,157.04,25.84,192.07 +827,1,E09000025,3,83.97,166.61,25.84,226.01 +1153,1,E09000025,4,101.48,186.77,25.84,251.49 +2783,2,E09000025,0,70.47,317,18.64,502.91 +1479,3,E09000025,1,58.13,118.85,25.84,146.43 +1805,3,E09000025,2,63.67,139.02,25.84,175.09 +2131,3,E09000025,3,71.06,159.17,25.84,200.55 +2457,3,E09000025,4,83.05,259.98,25.84,261.04 +3109,4,E09000025,0,60.1,371.82,18.64,402.8 +3974,5,E09000025,1,65.51,208,25.84,227.08 +4589,5,E09000025,2,77.51,253.61,25.84,276.96 +5241,5,E09000025,3,83.97,292.87,25.84,319.41 +5926,5,E09000025,4,101.48,368.22,25.84,401.13 +3435,6,E09000025,0,70.47,413.53,18.64,450.45 +4188,7,E09000025,1,58.13,208,25.84,227.08 +4689,7,E09000025,2,63.67,253.61,25.84,276.96 +5341,7,E09000025,3,71.06,292.87,25.84,319.41 +5893,7,E09000025,4,83.05,368.22,25.84,401.13 +3761,8,E09000025,0,60.1,413.53,18.64,450.45 +6695,9,E09000025,1,65.51,259.98,25.84,283.85 +7021,9,E09000025,2,77.51,317.02,25.84,346.2 +7347,9,E09000025,3,83.97,366.11,25.84,399.27 +7673,9,E09000025,4,101.48,460.26,25.84,501.4 +7999,10,E09000025,0,70.47,286.02,18.64,311.34 +176,1,E07000043,1,48.92,107.19,25.84,140.08 +502,1,E07000043,2,55.37,120.97,25.84,144.31 +828,1,E07000043,3,61.83,141.13,25.84,161.3 +1154,1,E07000043,4,71.06,158.1,25.84,194.19 +2784,2,E07000043,0,54.93,231.2,18.64,358.7 +1480,3,E07000043,1,47.06,89.13,25.84,210.12 +1806,3,E07000043,2,54.44,100.81,25.84,111.41 +2132,3,E07000043,3,61.83,109.29,25.84,126.28 +2458,3,E07000043,4,73.82,130.52,25.84,130.52 +3110,4,E07000043,0,54.93,115.59,18.64,141.81 +4212,5,E07000043,1,48.92,102.94,25.84,112.47 +4848,5,E07000043,2,55.37,134.77,25.84,147.5 +5479,5,E07000043,3,61.83,159.17,25.84,174.02 +6017,5,E07000043,4,71.06,219.66,25.84,239.83 +3436,6,E07000043,0,54.93,246.68,18.64,269.32 +3928,7,E07000043,1,47.06,102.94,25.84,112.47 +5125,7,E07000043,2,54.44,134.77,25.84,147.5 +5705,7,E07000043,3,61.83,159.17,25.84,174.02 +6417,7,E07000043,4,73.82,219.66,25.84,239.83 +3762,8,E07000043,0,54.93,246.68,18.64,269.32 +6696,9,E07000043,1,48.92,128.67,25.84,140.6 +7022,9,E07000043,2,55.37,168.46,25.84,184.37 +7348,9,E07000043,3,61.83,198.96,25.84,217.54 +7674,9,E07000043,4,71.06,274.57,25.84,299.78 +8000,10,E07000043,0,54.93,269.62,18.64,294.95 +178,1,E07000038,1,51.68,99.75,25.84,122.03 +504,1,E07000038,2,61.83,114.6,25.84,129.46 +830,1,E07000038,3,68.28,126.28,25.84,137.95 +1156,1,E07000038,4,75.67,158.1,25.84,166.61 +2786,2,E07000038,0,51.82,240.72,18.64,361.1 +1482,3,E07000038,1,46.13,90.21,25.84,107.19 +1808,3,E07000038,2,52.6,96.56,25.84,108.24 +2134,3,E07000038,3,58.13,104,25.84,118.85 +2460,3,E07000038,4,63.67,122.03,25.84,122.03 +3112,4,E07000038,0,49.74,114.39,18.64,123.94 +4337,5,E07000038,1,51.68,91.27,25.84,98.69 +5033,5,E07000038,2,61.83,114.6,25.84,124.15 +5676,5,E07000038,3,68.28,147.5,25.84,160.24 +6251,5,E07000038,4,75.67,202.69,25.84,220.72 +3438,6,E07000038,0,51.82,227.63,18.64,247.88 +4437,7,E07000038,1,46.13,91.27,25.84,98.69 +5173,7,E07000038,2,52.6,114.6,25.84,124.15 +5834,7,E07000038,3,58.13,147.5,25.84,160.24 +6495,7,E07000038,4,63.67,202.69,25.84,220.72 +3764,8,E07000038,0,49.74,227.63,18.64,247.88 +6698,9,E07000038,1,51.68,114.09,25.84,123.35 +7024,9,E07000038,2,61.83,143.25,25.84,155.2 +7350,9,E07000038,3,68.28,184.37,25.84,200.32 +7676,9,E07000038,4,75.67,253.36,25.84,275.9 +8002,10,E07000038,0,51.82,788.01,18.64,858.05 +179,1,E06000012,1,50.76,91.27,25.84,113.53 +505,1,E06000012,2,58.13,108.24,25.84,140.08 +831,1,E06000012,3,62.75,119.9,25.84,161.3 +1157,1,E06000012,4,72.9,144.31,25.84,178.28 +2787,2,E06000012,0,52.86,234.75,18.64,322.95 +1483,3,E06000012,1,46.13,81.71,25.84,92.33 +1809,3,E06000012,2,52.6,112.47,25.84,144.31 +2135,3,E06000012,3,56.29,104,25.84,113.53 +2461,3,E06000012,4,63.67,120.97,25.84,175.09 +3113,4,E06000012,0,51.82,160.88,18.64,190.67 +4401,5,E06000012,1,50.76,84.89,25.84,92.33 +4881,5,E06000012,2,58.13,107.19,25.84,116.72 +5512,5,E06000012,3,62.75,113.53,25.84,123.09 +6117,5,E06000012,4,72.9,159.17,25.84,174.02 +3439,6,E06000012,0,52.86,178.77,18.64,195.45 +4555,7,E06000012,1,46.13,84.89,25.84,92.33 +4823,7,E06000012,2,52.6,107.19,25.84,116.72 +5859,7,E06000012,3,56.29,113.53,25.84,123.09 +6215,7,E06000012,4,63.67,159.17,25.84,174.02 +3765,8,E06000012,0,51.82,178.77,18.64,195.45 +6699,9,E06000012,1,50.76,106.13,25.84,115.39 +7025,9,E06000012,2,52.6,133.98,25.84,145.91 +7351,9,E06000012,3,62.75,141.94,25.84,153.86 +7677,9,E06000012,4,72.9,198.96,25.84,217.54 +8003,10,E06000012,0,52.86,239.85,18.64,260.68 +180,1,E07000099,1,54.44,118.85,25.84,148.56 +506,1,E07000099,2,64.59,142.18,25.84,167.67 +832,1,E07000099,3,71.06,155.98,25.84,180.4 +1158,1,E07000099,4,81.2,170.85,25.84,178.28 +2788,2,E07000099,0,36.26,226.42,18.64,423.05 +1484,3,E07000099,1,49.84,99.75,25.84,131.58 +1810,3,E07000099,2,58.13,117.78,25.84,132.64 +2136,3,E07000099,3,63.67,130.52,25.84,143.25 +2462,3,E07000099,4,71.06,148.56,25.84,159.17 +3114,4,E07000099,0,55.97,135.86,18.64,318.19 +4145,5,E07000099,1,54.44,130.52,25.84,143.25 +4726,5,E07000099,2,64.59,169.79,25.84,184.64 +5445,5,E07000099,3,71.06,217.53,25.84,237.69 +6155,5,E07000099,4,81.2,421.28,25.84,459.48 +3440,6,E07000099,0,36.26,473.1,18.64,516 +4262,7,E07000099,1,49.84,130.52,25.84,143.25 +4988,7,E07000099,2,58.13,169.79,25.84,184.64 +5631,7,E07000099,3,63.67,217.53,25.84,237.69 +6293,7,E07000099,4,71.06,421.28,25.84,459.48 +3766,8,E07000099,0,55.97,473.1,18.64,516 +6700,9,E07000099,1,54.44,163.15,25.84,179.06 +7026,9,E07000099,2,64.59,212.23,25.84,230.81 +7352,9,E07000099,3,71.06,271.92,25.84,297.12 +7678,9,E07000099,4,81.2,526.6,25.84,574.35 +8004,10,E07000099,0,36.26,341.13,18.64,372.42 +181,1,E07000139,1,51.68,99.75,25.84,122.03 +507,1,E07000139,2,61.83,114.6,25.84,129.46 +833,1,E07000139,3,68.28,126.28,25.84,137.95 +1159,1,E07000139,4,75.67,158.1,25.84,166.61 +2789,2,E07000139,0,51.82,240.72,18.64,361.1 +1485,3,E07000139,1,46.13,90.21,25.84,107.19 +1811,3,E07000139,2,52.6,96.56,25.84,108.24 +2137,3,E07000139,3,58.13,104,25.84,118.85 +2463,3,E07000139,4,63.67,122.03,25.84,122.03 +3115,4,E07000139,0,49.74,114.39,18.64,123.94 +4338,5,E07000139,1,51.68,102.94,25.84,112.47 +5034,5,E07000139,2,61.83,113.53,25.84,123.09 +5677,5,E07000139,3,68.28,136.89,25.84,148.56 +6252,5,E07000139,4,75.67,192.07,25.84,210.12 +3441,6,E07000139,0,51.82,215.7,18.64,235.95 +4438,7,E07000139,1,46.13,102.94,25.84,112.47 +5174,7,E07000139,2,52.6,113.53,25.84,123.09 +5835,7,E07000139,3,58.13,136.89,25.84,148.56 +6496,7,E07000139,4,63.67,192.07,25.84,210.12 +3767,8,E07000139,0,49.74,215.7,18.64,235.95 +6701,9,E07000139,1,51.68,128.67,25.84,140.6 +7027,9,E07000139,2,61.83,141.94,25.84,153.86 +7353,9,E07000139,3,68.28,171.11,25.84,185.69 +7679,9,E07000139,4,75.67,240.08,25.84,262.64 +8005,10,E07000139,0,51.82,4013.13,18.64,4378.1 +182,1,E06000013,1,50.76,91.27,25.84,113.53 +508,1,E06000013,2,58.13,108.24,25.84,140.08 +834,1,E06000013,3,62.75,119.9,25.84,161.3 +1160,1,E06000013,4,72.9,144.31,25.84,178.28 +2790,2,E06000013,0,52.86,234.75,18.64,322.95 +1486,3,E06000013,1,46.13,81.71,25.84,92.33 +1812,3,E06000013,2,52.6,112.47,25.84,144.31 +2138,3,E06000013,3,56.29,104,25.84,113.53 +2464,3,E06000013,4,63.67,120.97,25.84,175.09 +3116,4,E06000013,0,51.82,160.88,18.64,190.67 +4402,5,E06000013,1,50.76,81.71,25.84,88.07 +4882,5,E06000013,2,58.13,102.94,25.84,112.47 +5513,5,E06000013,3,62.75,114.6,25.84,124.15 +6118,5,E06000013,4,72.9,180.4,25.84,197.39 +3442,6,E06000013,0,52.86,202.58,18.64,221.66 +4556,7,E06000013,1,46.13,81.71,25.84,88.07 +4824,7,E06000013,2,52.6,102.94,25.84,112.47 +5860,7,E06000013,3,56.29,114.6,25.84,124.15 +6216,7,E06000013,4,63.67,180.4,25.84,197.39 +3768,8,E06000013,0,51.82,202.58,18.64,221.66 +6702,9,E06000013,1,50.76,102.16,25.84,110.1 +7028,9,E06000013,2,52.6,128.67,25.84,140.6 +7354,9,E06000013,3,62.75,143.25,25.84,155.2 +7680,9,E06000013,4,72.9,225.52,25.84,246.73 +8006,10,E06000013,0,52.86,914.64,18.64,998.07 +183,1,E07000147,1,54.44,118.85,25.84,148.56 +509,1,E07000147,2,64.59,142.18,25.84,167.67 +835,1,E07000147,3,71.06,155.98,25.84,180.4 +1161,1,E07000147,4,81.2,170.85,25.84,178.28 +2791,2,E07000147,0,36.26,226.42,18.64,423.05 +1487,3,E07000147,1,49.84,99.75,25.84,131.58 +1813,3,E07000147,2,58.13,117.78,25.84,132.64 +2139,3,E07000147,3,63.67,130.52,25.84,143.25 +2465,3,E07000147,4,71.06,148.56,25.84,159.17 +3117,4,E07000147,0,55.97,135.86,18.64,318.19 +4146,5,E07000147,1,54.44,99.75,25.84,109.29 +4727,5,E07000147,2,64.59,125.22,25.84,136.89 +5446,5,E07000147,3,71.06,164.48,25.84,179.34 +6156,5,E07000147,4,81.2,270.61,25.84,295.01 +3443,6,E07000147,0,36.26,303.89,18.64,331.29 +4263,7,E07000147,1,49.84,99.75,25.84,109.29 +4989,7,E07000147,2,58.13,125.22,25.84,136.89 +5632,7,E07000147,3,63.67,164.48,25.84,179.34 +6294,7,E07000147,4,71.06,270.61,25.84,295.01 +3769,8,E07000147,0,55.97,303.89,18.64,331.29 +6703,9,E07000147,1,54.44,124.69,25.84,136.63 +7029,9,E07000147,2,64.59,156.51,25.84,171.11 +7355,9,E07000147,3,71.06,205.6,25.84,224.18 +7681,9,E07000147,4,81.2,338.25,25.84,368.76 +8007,10,E07000147,0,36.26,269.62,18.64,294.95 +89,1,E06000061,1,51.68,99.75,25.84,122.03 +415,1,E06000061,2,61.83,114.6,25.84,129.46 +741,1,E06000061,3,68.28,126.28,25.84,137.95 +1067,1,E06000061,4,75.67,158.1,25.84,166.61 +2697,2,E06000061,0,51.82,240.72,18.64,361.1 +1393,3,E06000061,1,46.13,90.21,25.84,107.19 +1719,3,E06000061,2,52.6,96.56,25.84,108.24 +2045,3,E06000061,3,58.13,104,25.84,118.85 +2371,3,E06000061,4,63.67,122.03,25.84,122.03 +3023,4,E06000061,0,49.74,114.39,18.64,123.94 +4320,5,E06000061,1,51.68,97.63,25.84,107.19 +5021,5,E06000061,2,61.83,125.22,25.84,136.89 +5664,5,E06000061,3,68.28,147.5,25.84,160.24 +6239,5,E06000061,4,75.67,248.31,25.84,270.61 +3349,6,E06000061,0,51.82,278.86,18.64,303.89 +4425,7,E06000061,1,46.13,97.63,25.84,107.19 +5161,7,E06000061,2,52.6,125.22,25.84,136.89 +5822,7,E06000061,3,58.13,147.5,25.84,160.24 +6483,7,E06000061,4,63.67,248.31,25.84,270.61 +3675,8,E06000061,0,49.74,278.86,18.64,303.89 +6609,9,E06000061,1,51.68,122.03,25.84,133.98 +6935,9,E06000061,2,61.83,156.51,25.84,171.11 +7261,9,E06000061,3,68.28,184.37,25.84,200.32 +7587,9,E06000061,4,75.67,310.37,25.84,338.25 +7913,10,E06000061,0,51.82,333.68,18.64,363.48 +184,1,E06000024,1,48.92,107.19,25.84,140.08 +510,1,E06000024,2,55.37,120.97,25.84,144.31 +836,1,E06000024,3,61.83,141.13,25.84,161.3 +1162,1,E06000024,4,71.06,158.1,25.84,194.19 +2792,2,E06000024,0,54.93,231.2,18.64,358.7 +1488,3,E06000024,1,47.06,89.13,25.84,210.12 +1814,3,E06000024,2,54.44,100.81,25.84,111.41 +2140,3,E06000024,3,61.83,109.29,25.84,126.28 +2466,3,E06000024,4,73.82,130.52,25.84,130.52 +3118,4,E06000024,0,54.93,115.59,18.64,141.81 +4214,5,E06000024,1,48.92,113.53,25.84,123.09 +4850,5,E06000024,2,55.37,136.89,25.84,148.56 +5481,5,E06000024,3,61.83,164.48,25.84,179.34 +6019,5,E06000024,4,71.06,248.31,25.84,270.61 +3444,6,E06000024,0,54.93,278.86,18.64,303.89 +3930,7,E06000024,1,47.06,113.53,25.84,123.09 +5127,7,E06000024,2,54.44,136.89,25.84,148.56 +5707,7,E06000024,3,61.83,164.48,25.84,179.34 +6419,7,E06000024,4,73.82,248.31,25.84,270.61 +3770,8,E06000024,0,54.93,278.86,18.64,303.89 +6704,9,E06000024,1,48.92,141.94,25.84,153.86 +7030,9,E06000024,2,55.37,171.11,25.84,185.69 +7356,9,E06000024,3,61.83,205.6,25.84,224.18 +7682,9,E06000024,4,71.06,310.37,25.84,338.25 +8008,10,E06000024,0,54.93,342.63,18.64,373.91 +185,1,E08000022,1,50.76,88.07,25.84,97.63 +511,1,E08000022,2,57.21,101.88,25.84,119.9 +837,1,E08000022,3,60.9,113.53,25.84,159.17 +1163,1,E08000022,4,70.13,127.34,25.84,139.02 +2793,2,E08000022,0,55.97,237.14,18.64,340.83 +1489,3,E08000022,1,42.44,99.75,25.84,105.06 +1815,3,E08000022,2,49.84,90.21,25.84,111.41 +2141,3,E08000022,3,53.52,105.06,25.84,124.15 +2467,3,E08000022,4,56.29,115.66,25.84,119.9 +3119,4,E08000022,0,47.67,253.84,18.64,288.39 +4538,5,E08000022,1,50.76,98.69,25.84,108.24 +5053,5,E08000022,2,57.21,125.22,25.84,136.89 +5558,5,E08000022,3,60.9,147.5,25.84,160.24 +6357,5,E08000022,4,70.13,227.08,25.84,246.18 +3445,6,E08000022,0,55.97,255.02,18.64,276.48 +4457,7,E08000022,1,42.44,98.69,25.84,108.24 +5104,7,E08000022,2,49.84,125.22,25.84,136.89 +5733,7,E08000022,3,53.52,147.5,25.84,160.24 +6515,7,E08000022,4,56.29,227.08,25.84,246.18 +3771,8,E08000022,0,47.67,255.02,18.64,276.48 +6705,9,E08000022,1,42.44,123.35,25.84,135.3 +7031,9,E08000022,2,57.21,156.51,25.84,171.11 +7357,9,E08000022,3,60.9,184.37,25.84,200.32 +7683,9,E08000022,4,70.13,283.85,25.84,307.73 +8009,10,E08000022,0,55.97,239.85,18.64,260.68 +186,1,E07000218,1,52.6,98.69,25.84,124.15 +512,1,E07000218,2,58.13,116.72,25.84,136.89 +838,1,E07000218,3,69.2,132.64,25.84,160.24 +1164,1,E07000218,4,80.28,161.3,25.84,178.28 +2794,2,E07000218,0,39.38,245.49,18.64,382.53 +1490,3,E07000218,1,46.13,88.07,25.84,97.63 +1816,3,E07000218,2,49.84,94.47,25.84,102.94 +2142,3,E07000218,3,59.98,104,25.84,119.9 +2468,3,E07000218,4,68.28,127.34,25.84,127.34 +3120,4,E07000218,0,46.63,107.26,18.64,107.26 +4291,5,E07000218,1,52.6,102.94,25.84,112.47 +4901,5,E07000218,2,58.13,125.22,25.84,136.89 +5532,5,E07000218,3,69.2,147.5,25.84,160.24 +6184,5,E07000218,4,80.28,192.07,25.84,210.12 +3446,6,E07000218,0,39.38,215.7,18.64,235.95 +4512,7,E07000218,1,46.13,102.94,25.84,112.47 +5197,7,E07000218,2,49.84,125.22,25.84,136.89 +5788,7,E07000218,3,59.98,147.5,25.84,160.24 +6449,7,E07000218,4,68.28,192.07,25.84,210.12 +3772,8,E07000218,0,46.63,215.7,18.64,235.95 +6706,9,E07000218,1,52.6,128.67,25.84,140.6 +7032,9,E07000218,2,58.13,156.51,25.84,171.11 +7358,9,E07000218,3,69.2,184.37,25.84,200.32 +7684,9,E07000218,4,80.28,240.08,25.84,262.64 +8010,10,E07000218,0,39.38,394.77,18.64,430.5 +187,1,E07000134,1,51.68,99.75,25.84,122.03 +513,1,E07000134,2,61.83,114.6,25.84,129.46 +839,1,E07000134,3,68.28,126.28,25.84,137.95 +1165,1,E07000134,4,75.67,158.1,25.84,166.61 +2795,2,E07000134,0,51.82,240.72,18.64,361.1 +1491,3,E07000134,1,46.13,90.21,25.84,107.19 +1817,3,E07000134,2,52.6,96.56,25.84,108.24 +2143,3,E07000134,3,58.13,104,25.84,118.85 +2469,3,E07000134,4,63.67,122.03,25.84,122.03 +3121,4,E07000134,0,49.74,114.39,18.64,123.94 +4339,5,E07000134,1,51.68,97.63,25.84,107.19 +5035,5,E07000134,2,61.83,119.9,25.84,130.52 +5678,5,E07000134,3,68.28,136.89,25.84,148.56 +6253,5,E07000134,4,75.67,202.69,25.84,220.72 +3447,6,E07000134,0,51.82,227.63,18.64,247.88 +4439,7,E07000134,1,46.13,97.63,25.84,107.19 +5175,7,E07000134,2,52.6,119.9,25.84,130.52 +5836,7,E07000134,3,58.13,136.89,25.84,148.56 +6497,7,E07000134,4,63.67,202.69,25.84,220.72 +3773,8,E07000134,0,49.74,227.63,18.64,247.88 +6707,9,E07000134,1,51.68,122.03,25.84,133.98 +7033,9,E07000134,2,61.83,149.9,25.84,163.15 +7359,9,E07000134,3,68.28,171.11,25.84,185.69 +7685,9,E07000134,4,75.67,253.36,25.84,275.9 +8011,10,E07000134,0,51.82,1021.9,18.64,1115.75 +8201,1,E06000065,1,50.76,91.27,25.84,113.53 +8202,1,E06000065,2,58.13,108.24,25.84,140.08 +8203,1,E06000065,3,62.75,119.9,25.84,161.3 +8204,1,E06000065,4,72.9,144.31,25.84,178.28 +8209,2,E06000065,0,52.86,234.75,18.64,322.95 +8205,3,E06000065,1,46.13,81.71,25.84,92.33 +8206,3,E06000065,2,52.6,112.47,25.84,144.31 +8207,3,E06000065,3,56.29,104,25.84,113.53 +8208,3,E06000065,4,63.67,120.97,25.84,175.09 +8210,4,E06000065,0,51.82,160.88,18.64,190.67 +8213,5,E06000065,1,50.76,125.22,25.84,136.89 +8216,5,E06000065,2,58.13,157.04,25.84,172.97 +8217,5,E06000065,3,62.75,192.07,25.84,210.12 +8219,5,E06000065,4,72.9,371.41,25.84,405.36 +8211,6,E06000065,0,52.86,417.11,18.64,455.24 +8214,7,E06000065,1,46.13,125.22,25.84,136.89 +8215,7,E06000065,2,52.6,157.04,25.84,172.97 +8218,7,E06000065,3,56.29,192.07,25.84,210.12 +8220,7,E06000065,4,63.67,371.41,25.84,405.36 +8212,8,E06000065,0,51.82,417.11,18.64,455.24 +8221,9,E06000065,1,50.76,156.51,25.84,171.11 +8222,9,E06000065,2,52.6,196.32,25.84,216.2 +8223,9,E06000065,3,62.75,240.08,25.84,262.64 +8224,9,E06000065,4,72.9,464.26,25.84,506.71 +8225,10,E06000065,0,52.86,598.84,18.64,653.96 +189,1,E06000057,1,50.76,88.07,25.84,97.63 +515,1,E06000057,2,57.21,101.88,25.84,119.9 +841,1,E06000057,3,60.9,113.53,25.84,159.17 +1167,1,E06000057,4,70.13,127.34,25.84,139.02 +2797,2,E06000057,0,55.97,237.14,18.64,340.83 +1493,3,E06000057,1,42.44,99.75,25.84,105.06 +1819,3,E06000057,2,49.84,90.21,25.84,111.41 +2145,3,E06000057,3,53.52,105.06,25.84,124.15 +2471,3,E06000057,4,56.29,115.66,25.84,119.9 +3123,4,E06000057,0,47.67,253.84,18.64,288.39 +4539,5,E06000057,1,50.76,91.27,25.84,98.69 +5054,5,E06000057,2,57.21,109.29,25.84,118.85 +5559,5,E06000057,3,60.9,125.22,25.84,136.89 +6358,5,E06000057,4,70.13,202.69,25.84,220.72 +3449,6,E06000057,0,55.97,227.63,18.64,247.88 +4458,7,E06000057,1,42.44,91.27,25.84,98.69 +5105,7,E06000057,2,49.84,109.29,25.84,118.85 +5734,7,E06000057,3,53.52,125.22,25.84,136.89 +6516,7,E06000057,4,56.29,202.69,25.84,220.72 +3775,8,E06000057,0,47.67,227.63,18.64,247.88 +6709,9,E06000057,1,42.44,114.09,25.84,123.35 +7035,9,E06000057,2,57.21,136.63,25.84,148.56 +7361,9,E06000057,3,60.9,156.51,25.84,171.11 +7687,9,E06000057,4,70.13,253.36,25.84,275.9 +8013,10,E06000057,0,55.97,300.91,18.64,329.21 +190,1,E07000148,1,54.44,118.85,25.84,148.56 +516,1,E07000148,2,64.59,142.18,25.84,167.67 +842,1,E07000148,3,71.06,155.98,25.84,180.4 +1168,1,E07000148,4,81.2,170.85,25.84,178.28 +2798,2,E07000148,0,36.26,226.42,18.64,423.05 +1494,3,E07000148,1,49.84,99.75,25.84,131.58 +1820,3,E07000148,2,58.13,117.78,25.84,132.64 +2146,3,E07000148,3,63.67,130.52,25.84,143.25 +2472,3,E07000148,4,71.06,148.56,25.84,159.17 +3124,4,E07000148,0,55.97,135.86,18.64,318.19 +4147,5,E07000148,1,54.44,113.53,25.84,123.09 +4728,5,E07000148,2,64.59,134.77,25.84,147.5 +5447,5,E07000148,3,71.06,170.85,25.84,185.7 +6157,5,E07000148,4,81.2,244.06,25.84,266.35 +3450,6,E07000148,0,36.26,274.11,18.64,299.12 +4264,7,E07000148,1,49.84,113.53,25.84,123.09 +4990,7,E07000148,2,58.13,134.77,25.84,147.5 +5633,7,E07000148,3,63.67,170.85,25.84,185.7 +6295,7,E07000148,4,71.06,244.06,25.84,266.35 +3776,8,E07000148,0,55.97,274.11,18.64,299.12 +6710,9,E07000148,1,54.44,141.94,25.84,153.86 +7036,9,E07000148,2,64.59,168.46,25.84,184.37 +7362,9,E07000148,3,71.06,213.57,25.84,232.15 +7688,9,E07000148,4,81.2,305.08,25.84,332.95 +8014,10,E07000148,0,36.26,598.84,18.64,653.96 +191,1,E06000018,1,51.68,99.75,25.84,122.03 +517,1,E06000018,2,61.83,114.6,25.84,129.46 +843,1,E06000018,3,68.28,126.28,25.84,137.95 +1169,1,E06000018,4,75.67,158.1,25.84,166.61 +2799,2,E06000018,0,51.82,240.72,18.64,361.1 +1495,3,E06000018,1,46.13,90.21,25.84,107.19 +1821,3,E06000018,2,52.6,96.56,25.84,108.24 +2147,3,E06000018,3,58.13,104,25.84,118.85 +2473,3,E06000018,4,63.67,122.03,25.84,122.03 +3125,4,E06000018,0,49.74,114.39,18.64,123.94 +4341,5,E06000018,1,51.68,119.9,25.84,130.52 +5037,5,E06000018,2,61.83,147.5,25.84,160.24 +5680,5,E06000018,3,68.28,147.5,25.84,160.24 +6255,5,E06000018,4,75.67,316.23,25.84,344.88 +3451,6,E06000018,0,51.82,355.12,18.64,387.3 +4441,7,E06000018,1,46.13,119.9,25.84,130.52 +5177,7,E06000018,2,52.6,147.5,25.84,160.24 +5838,7,E06000018,3,58.13,147.5,25.84,160.24 +6499,7,E06000018,4,63.67,316.23,25.84,344.88 +3777,8,E06000018,0,49.74,355.12,18.64,387.3 +6711,9,E06000018,1,51.68,149.9,25.84,163.15 +7037,9,E06000018,2,61.83,184.37,25.84,200.32 +7363,9,E06000018,3,68.28,184.37,25.84,200.32 +7689,9,E06000018,4,75.67,395.3,25.84,431.1 +8015,10,E06000018,0,51.82,269.62,18.64,294.95 +192,1,E07000219,1,52.6,98.69,25.84,124.15 +518,1,E07000219,2,58.13,116.72,25.84,136.89 +844,1,E07000219,3,69.2,132.64,25.84,160.24 +1170,1,E07000219,4,80.28,161.3,25.84,178.28 +2800,2,E07000219,0,39.38,245.49,18.64,382.53 +1496,3,E07000219,1,46.13,88.07,25.84,97.63 +1822,3,E07000219,2,49.84,94.47,25.84,102.94 +2148,3,E07000219,3,59.98,104,25.84,119.9 +2474,3,E07000219,4,68.28,127.34,25.84,127.34 +3126,4,E07000219,0,46.63,107.26,18.64,107.26 +4292,5,E07000219,1,52.6,97.63,25.84,107.19 +4902,5,E07000219,2,58.13,118.85,25.84,129.46 +5533,5,E07000219,3,69.2,142.18,25.84,154.93 +6185,5,E07000219,4,80.28,198.45,25.84,215.41 +3452,6,E07000219,0,39.38,222.84,18.64,241.92 +4513,7,E07000219,1,46.13,97.63,25.84,107.19 +5198,7,E07000219,2,49.84,118.85,25.84,129.46 +5789,7,E07000219,3,59.98,142.18,25.84,154.93 +6450,7,E07000219,4,68.28,198.45,25.84,215.41 +3778,8,E07000219,0,46.63,222.84,18.64,241.92 +6712,9,E07000219,1,52.6,122.03,25.84,133.98 +7038,9,E07000219,2,58.13,148.56,25.84,161.83 +7364,9,E07000219,3,69.2,177.73,25.84,193.64 +7690,9,E07000219,4,80.28,248.03,25.84,269.26 +8016,10,E07000219,0,39.38,738.88,18.64,804.41 +193,1,E07000135,1,51.68,99.75,25.84,122.03 +519,1,E07000135,2,61.83,114.6,25.84,129.46 +845,1,E07000135,3,68.28,126.28,25.84,137.95 +1171,1,E07000135,4,75.67,158.1,25.84,166.61 +2801,2,E07000135,0,51.82,240.72,18.64,361.1 +1497,3,E07000135,1,46.13,90.21,25.84,107.19 +1823,3,E07000135,2,52.6,96.56,25.84,108.24 +2149,3,E07000135,3,58.13,104,25.84,118.85 +2475,3,E07000135,4,63.67,122.03,25.84,122.03 +3127,4,E07000135,0,49.74,114.39,18.64,123.94 +4342,5,E07000135,1,51.68,102.94,25.84,112.47 +5038,5,E07000135,2,61.83,125.22,25.84,136.89 +5681,5,E07000135,3,68.28,147.5,25.84,160.24 +6256,5,E07000135,4,75.67,227.08,25.84,246.18 +3453,6,E07000135,0,51.82,255.02,18.64,276.48 +4442,7,E07000135,1,46.13,102.94,25.84,112.47 +5178,7,E07000135,2,52.6,125.22,25.84,136.89 +5839,7,E07000135,3,58.13,147.5,25.84,160.24 +6500,7,E07000135,4,63.67,227.08,25.84,246.18 +3779,8,E07000135,0,49.74,255.02,18.64,276.48 +6713,9,E07000135,1,51.68,128.67,25.84,140.6 +7039,9,E07000135,2,61.83,156.51,25.84,171.11 +7365,9,E07000135,3,68.28,184.37,25.84,200.32 +7691,9,E07000135,4,75.67,283.85,25.84,307.73 +8017,10,E07000135,0,51.82,300.91,18.64,329.21 +194,1,E08000004,1,51.68,93.39,25.84,116.72 +520,1,E08000004,2,59.06,107.19,25.84,134.77 +846,1,E08000004,3,65.51,119.9,25.84,145.37 +1172,1,E08000004,4,71.98,133.71,25.84,159.17 +2802,2,E08000004,0,55.97,239.54,18.64,342.01 +1498,3,E08000004,1,43.36,85.94,25.84,100.81 +1824,3,E08000004,2,53.52,94.47,25.84,113.53 +2150,3,E08000004,3,58.13,105.06,25.84,124.15 +2476,3,E08000004,4,55.37,118.85,25.84,133.71 +3128,4,E08000004,0,33.16,469.54,18.64,599.44 +4371,5,E08000004,1,51.68,102.94,25.84,112.47 +4941,5,E08000004,2,59.06,113.53,25.84,123.09 +5584,5,E08000004,3,65.51,136.89,25.84,148.56 +6332,5,E08000004,4,71.98,192.07,25.84,210.12 +3454,6,E08000004,0,55.97,215.7,18.64,235.95 +4483,7,E08000004,1,43.36,102.94,25.84,112.47 +5079,7,E08000004,2,53.52,113.53,25.84,123.09 +5759,7,E08000004,3,58.13,136.89,25.84,148.56 +6383,7,E08000004,4,55.37,192.07,25.84,210.12 +3780,8,E08000004,0,33.16,215.7,18.64,235.95 +6714,9,E08000004,1,51.68,128.67,25.84,140.6 +7040,9,E08000004,2,59.06,141.94,25.84,153.86 +7366,9,E08000004,3,65.51,171.11,25.84,185.69 +7692,9,E08000004,4,71.98,240.08,25.84,262.64 +8018,10,E08000004,0,55.97,569.06,18.64,619.69 +195,1,E07000178,1,57.21,123.09,25.84,176.15 +521,1,E07000178,2,71.06,146.43,25.84,186.77 +847,1,E07000178,3,81.2,161.3,25.84,203.75 +1173,1,E07000178,4,89.52,178.28,25.84,221.77 +2803,2,E07000178,0,62.17,268.13,18.64,344.4 +1499,3,E07000178,1,51.68,115.66,25.84,159.17 +1825,3,E07000178,2,62.75,129.46,25.84,145.37 +2151,3,E07000178,3,68.28,149.62,25.84,185.7 +2477,3,E07000178,4,72.9,184.64,25.84,194.19 +3129,4,E07000178,0,48.71,195.45,18.64,204.96 +4017,5,E07000178,1,57.21,189.94,25.84,208 +4632,5,E07000178,2,71.06,237.69,25.84,258.92 +5284,5,E07000178,3,81.2,292.87,25.84,319.41 +5969,5,E07000178,4,89.52,437.18,25.84,476.46 +3455,6,E07000178,0,62.17,490.98,18.64,535.08 +4084,7,E07000178,1,51.68,189.94,25.84,208 +4779,7,E07000178,2,62.75,237.69,25.84,258.92 +5384,7,E07000178,3,68.28,292.87,25.84,319.41 +6073,7,E07000178,4,72.9,437.18,25.84,476.46 +3781,8,E07000178,0,48.71,490.98,18.64,535.08 +6715,9,E07000178,1,57.21,237.44,25.84,259.98 +7041,9,E07000178,2,71.06,297.12,25.84,323.65 +7367,9,E07000178,3,81.2,366.11,25.84,399.27 +7693,9,E07000178,4,89.52,546.48,25.84,595.55 +8019,10,E07000178,0,62.17,394.77,18.64,430.5 +196,1,E07000122,1,51.68,93.39,25.84,116.72 +522,1,E07000122,2,59.06,107.19,25.84,134.77 +848,1,E07000122,3,65.51,119.9,25.84,145.37 +1174,1,E07000122,4,71.98,133.71,25.84,159.17 +2804,2,E07000122,0,55.97,239.54,18.64,342.01 +1500,3,E07000122,1,43.36,85.94,25.84,100.81 +1826,3,E07000122,2,53.52,94.47,25.84,113.53 +2152,3,E07000122,3,58.13,105.06,25.84,124.15 +2478,3,E07000122,4,55.37,118.85,25.84,133.71 +3130,4,E07000122,0,33.16,469.54,18.64,599.44 +4372,5,E07000122,1,51.68,90.21,25.84,97.63 +4942,5,E07000122,2,59.06,97.63,25.84,108.24 +5585,5,E07000122,3,65.51,125.22,25.84,136.89 +6333,5,E07000122,4,71.98,180.4,25.84,197.39 +3456,6,E07000122,0,55.97,202.58,18.64,221.66 +4484,7,E07000122,1,43.36,90.21,25.84,97.63 +5080,7,E07000122,2,53.52,97.63,25.84,108.24 +5760,7,E07000122,3,58.13,125.22,25.84,136.89 +6384,7,E07000122,4,55.37,180.4,25.84,197.39 +3782,8,E07000122,0,33.16,202.58,18.64,221.66 +6716,9,E07000122,1,51.68,112.76,25.84,122.03 +7042,9,E07000122,2,59.06,122.03,25.84,135.3 +7368,9,E07000122,3,65.51,156.51,25.84,171.11 +7694,9,E07000122,4,71.98,225.52,25.84,246.73 +8020,10,E07000122,0,55.97,348.6,18.64,379.86 +197,1,E06000031,1,54.44,118.85,25.84,148.56 +523,1,E06000031,2,64.59,142.18,25.84,167.67 +849,1,E06000031,3,71.06,155.98,25.84,180.4 +1175,1,E06000031,4,81.2,170.85,25.84,178.28 +2805,2,E06000031,0,36.26,226.42,18.64,423.05 +1501,3,E06000031,1,49.84,99.75,25.84,131.58 +1827,3,E06000031,2,58.13,117.78,25.84,132.64 +2153,3,E06000031,3,63.67,130.52,25.84,143.25 +2479,3,E06000031,4,71.06,148.56,25.84,159.17 +3131,4,E06000031,0,55.97,135.86,18.64,318.19 +4148,5,E06000031,1,54.44,102.94,25.84,112.47 +4729,5,E06000031,2,64.59,125.22,25.84,136.89 +5448,5,E06000031,3,71.06,147.5,25.84,160.24 +6158,5,E06000031,4,81.2,203.75,25.84,221.77 +3457,6,E06000031,0,36.26,228.81,18.64,249.07 +4265,7,E06000031,1,49.84,102.94,25.84,112.47 +4991,7,E06000031,2,58.13,125.22,25.84,136.89 +5634,7,E06000031,3,63.67,147.5,25.84,160.24 +6296,7,E06000031,4,71.06,203.75,25.84,221.77 +3783,8,E06000031,0,55.97,228.81,18.64,249.07 +6717,9,E06000031,1,54.44,128.67,25.84,140.6 +7043,9,E06000031,2,64.59,156.51,25.84,171.11 +7369,9,E06000031,3,71.06,184.37,25.84,200.32 +7695,9,E06000031,4,81.2,254.69,25.84,277.23 +8021,10,E06000031,0,36.26,239.85,18.64,260.68 +198,1,E06000026,1,48.92,107.19,25.84,140.08 +524,1,E06000026,2,55.37,120.97,25.84,144.31 +850,1,E06000026,3,61.83,141.13,25.84,161.3 +1176,1,E06000026,4,71.06,158.1,25.84,194.19 +2806,2,E06000026,0,54.93,231.2,18.64,358.7 +1502,3,E06000026,1,47.06,89.13,25.84,210.12 +1828,3,E06000026,2,54.44,100.81,25.84,111.41 +2154,3,E06000026,3,61.83,109.29,25.84,126.28 +2480,3,E06000026,4,73.82,130.52,25.84,130.52 +3132,4,E06000026,0,54.93,115.59,18.64,141.81 +4215,5,E06000026,1,48.92,110.36,25.84,119.9 +4851,5,E06000026,2,55.37,136.89,25.84,148.56 +5482,5,E06000026,3,61.83,159.17,25.84,174.02 +6020,5,E06000026,4,71.06,271.67,25.84,296.07 +3458,6,E06000026,0,54.93,305.08,18.64,332.48 +3931,7,E06000026,1,47.06,110.36,25.84,119.9 +5128,7,E06000026,2,54.44,136.89,25.84,148.56 +5708,7,E06000026,3,61.83,159.17,25.84,174.02 +6420,7,E06000026,4,73.82,271.67,25.84,296.07 +3784,8,E06000026,0,54.93,305.08,18.64,332.48 +6718,9,E06000026,1,48.92,137.95,25.84,149.9 +7044,9,E06000026,2,55.37,171.11,25.84,185.69 +7370,9,E06000026,3,61.83,198.96,25.84,217.54 +7696,9,E06000026,4,71.06,339.58,25.84,370.08 +8022,10,E06000026,0,54.93,583.94,18.64,636.07 +200,1,E06000044,1,57.21,123.09,25.84,176.15 +526,1,E06000044,2,71.06,146.43,25.84,186.77 +852,1,E06000044,3,81.2,161.3,25.84,203.75 +1178,1,E06000044,4,89.52,178.28,25.84,221.77 +2808,2,E06000044,0,62.17,268.13,18.64,344.4 +1504,3,E06000044,1,51.68,115.66,25.84,159.17 +1830,3,E06000044,2,62.75,129.46,25.84,145.37 +2156,3,E06000044,3,68.28,149.62,25.84,185.7 +2482,3,E06000044,4,72.9,184.64,25.84,194.19 +3134,4,E06000044,0,48.71,195.45,18.64,204.96 +4018,5,E06000044,1,57.21,125.22,25.84,136.89 +4633,5,E06000044,2,71.06,153.86,25.84,167.67 +5285,5,E06000044,3,81.2,192.07,25.84,210.12 +5970,5,E06000044,4,89.52,316.23,25.84,344.88 +3460,6,E06000044,0,62.17,355.12,18.64,387.3 +4085,7,E06000044,1,51.68,125.22,25.84,136.89 +4780,7,E06000044,2,62.75,153.86,25.84,167.67 +5385,7,E06000044,3,68.28,192.07,25.84,210.12 +6074,7,E06000044,4,72.9,316.23,25.84,344.88 +3786,8,E06000044,0,48.71,355.12,18.64,387.3 +6720,9,E06000044,1,57.21,156.51,25.84,171.11 +7046,9,E06000044,2,71.06,192.33,25.84,209.57 +7372,9,E06000044,3,81.2,240.08,25.84,262.64 +7698,9,E06000044,4,89.52,395.3,25.84,431.1 +8024,10,E06000044,0,62.17,631.61,18.64,688.24 +201,1,E07000123,1,51.68,93.39,25.84,116.72 +527,1,E07000123,2,59.06,107.19,25.84,134.77 +853,1,E07000123,3,65.51,119.9,25.84,145.37 +1179,1,E07000123,4,71.98,133.71,25.84,159.17 +2809,2,E07000123,0,55.97,239.54,18.64,342.01 +1505,3,E07000123,1,43.36,85.94,25.84,100.81 +1831,3,E07000123,2,53.52,94.47,25.84,113.53 +2157,3,E07000123,3,58.13,105.06,25.84,124.15 +2483,3,E07000123,4,55.37,118.85,25.84,133.71 +3135,4,E07000123,0,33.16,469.54,18.64,599.44 +4373,5,E07000123,1,51.68,102.94,25.84,112.47 +4943,5,E07000123,2,59.06,130.52,25.84,143.25 +5586,5,E07000123,3,65.51,147.5,25.84,160.24 +6334,5,E07000123,4,71.98,203.75,25.84,221.77 +3461,6,E07000123,0,55.97,228.81,18.64,249.07 +4485,7,E07000123,1,43.36,102.94,25.84,112.47 +5081,7,E07000123,2,53.52,130.52,25.84,143.25 +5761,7,E07000123,3,58.13,147.5,25.84,160.24 +6385,7,E07000123,4,55.37,203.75,25.84,221.77 +3787,8,E07000123,0,33.16,228.81,18.64,249.07 +6721,9,E07000123,1,51.68,128.67,25.84,140.6 +7047,9,E07000123,2,59.06,163.15,25.84,179.06 +7373,9,E07000123,3,65.51,184.37,25.84,200.32 +7699,9,E07000123,4,71.98,254.69,25.84,277.23 +8025,10,E07000123,0,55.97,521.38,18.64,569.06 +203,1,E06000038,1,57.21,123.09,25.84,176.15 +529,1,E06000038,2,71.06,146.43,25.84,186.77 +855,1,E06000038,3,81.2,161.3,25.84,203.75 +1181,1,E06000038,4,89.52,178.28,25.84,221.77 +2811,2,E06000038,0,62.17,268.13,18.64,344.4 +1507,3,E06000038,1,51.68,115.66,25.84,159.17 +1833,3,E06000038,2,62.75,129.46,25.84,145.37 +2159,3,E06000038,3,68.28,149.62,25.84,185.7 +2485,3,E06000038,4,72.9,184.64,25.84,194.19 +3137,4,E06000038,0,48.71,195.45,18.64,204.96 +4019,5,E06000038,1,57.21,159.17,25.84,174.02 +4634,5,E06000038,2,71.06,202.69,25.84,220.72 +5286,5,E06000038,3,81.2,219.66,25.84,239.83 +5971,5,E06000038,4,89.52,445.68,25.84,484.95 +3463,6,E06000038,0,62.17,499.33,18.64,544.63 +4086,7,E06000038,1,51.68,159.17,25.84,174.02 +4781,7,E06000038,2,62.75,202.69,25.84,220.72 +5386,7,E06000038,3,68.28,219.66,25.84,239.83 +6075,7,E06000038,4,72.9,445.68,25.84,484.95 +3789,8,E06000038,0,48.71,499.33,18.64,544.63 +6723,9,E06000038,1,57.21,198.96,25.84,217.54 +7049,9,E06000038,2,71.06,253.36,25.84,275.9 +7375,9,E06000038,3,81.2,274.57,25.84,299.78 +7701,9,E06000038,4,89.52,557.11,25.84,606.19 +8027,10,E06000038,0,62.17,443.93,18.64,484.13 +204,1,E09000026,1,65.51,145.37,25.84,197.39 +530,1,E09000026,2,77.51,157.04,25.84,192.07 +856,1,E09000026,3,83.97,166.61,25.84,226.01 +1182,1,E09000026,4,101.48,186.77,25.84,251.49 +2812,2,E09000026,0,70.47,317,18.64,502.91 +1508,3,E09000026,1,58.13,118.85,25.84,146.43 +1834,3,E09000026,2,63.67,139.02,25.84,175.09 +2160,3,E09000026,3,71.06,159.17,25.84,200.55 +2486,3,E09000026,4,83.05,259.98,25.84,261.04 +3138,4,E09000026,0,60.1,371.82,18.64,402.8 +3975,5,E09000026,1,65.51,181.46,25.84,198.45 +4590,5,E09000026,2,77.51,237.69,25.84,258.92 +5242,5,E09000026,3,83.97,292.87,25.84,319.41 +5927,5,E09000026,4,101.48,371.41,25.84,405.36 +3464,6,E09000026,0,70.47,417.11,18.64,455.24 +4189,7,E09000026,1,58.13,181.46,25.84,198.45 +4690,7,E09000026,2,63.67,237.69,25.84,258.92 +5342,7,E09000026,3,71.06,292.87,25.84,319.41 +5894,7,E09000026,4,83.05,371.41,25.84,405.36 +3790,8,E09000026,0,60.1,417.11,18.64,455.24 +6724,9,E09000026,1,65.51,226.84,25.84,248.03 +7050,9,E09000026,2,77.51,297.12,25.84,323.65 +7376,9,E09000026,3,83.97,366.11,25.84,399.27 +7702,9,E09000026,4,101.48,464.26,25.84,506.71 +8028,10,E09000026,0,70.47,886.34,18.64,968.27 +205,1,E06000003,1,50.76,88.07,25.84,97.63 +531,1,E06000003,2,57.21,101.88,25.84,119.9 +857,1,E06000003,3,60.9,113.53,25.84,159.17 +1183,1,E06000003,4,70.13,127.34,25.84,139.02 +2813,2,E06000003,0,55.97,237.14,18.64,340.83 +1509,3,E06000003,1,42.44,99.75,25.84,105.06 +1835,3,E06000003,2,49.84,90.21,25.84,111.41 +2161,3,E06000003,3,53.52,105.06,25.84,124.15 +2487,3,E06000003,4,56.29,115.66,25.84,119.9 +3139,4,E06000003,0,47.67,253.84,18.64,288.39 +4540,5,E06000003,1,50.76,97.63,25.84,107.19 +5055,5,E06000003,2,57.21,114.6,25.84,124.15 +5560,5,E06000003,3,60.9,132.64,25.84,145.37 +6359,5,E06000003,4,70.13,170.85,25.84,185.7 +3465,6,E06000003,0,55.97,191.88,18.64,208.55 +4459,7,E06000003,1,42.44,97.63,25.84,107.19 +5106,7,E06000003,2,49.84,114.6,25.84,124.15 +5735,7,E06000003,3,53.52,132.64,25.84,145.37 +6517,7,E06000003,4,56.29,170.85,25.84,185.7 +3791,8,E06000003,0,47.67,191.88,18.64,208.55 +6725,9,E06000003,1,42.44,122.03,25.84,133.98 +7051,9,E06000003,2,57.21,143.25,25.84,155.2 +7377,9,E06000003,3,60.9,165.81,25.84,181.72 +7703,9,E06000003,4,70.13,213.57,25.84,232.15 +8029,10,E06000003,0,55.97,348.6,18.64,379.86 +206,1,E07000236,1,52.6,98.69,25.84,124.15 +532,1,E07000236,2,58.13,116.72,25.84,136.89 +858,1,E07000236,3,69.2,132.64,25.84,160.24 +1184,1,E07000236,4,80.28,161.3,25.84,178.28 +2814,2,E07000236,0,39.38,245.49,18.64,382.53 +1510,3,E07000236,1,46.13,88.07,25.84,97.63 +1836,3,E07000236,2,49.84,94.47,25.84,102.94 +2162,3,E07000236,3,59.98,104,25.84,119.9 +2488,3,E07000236,4,68.28,127.34,25.84,127.34 +3140,4,E07000236,0,46.63,107.26,18.64,107.26 +4293,5,E07000236,1,52.6,109.29,25.84,118.85 +4903,5,E07000236,2,58.13,130.52,25.84,143.25 +5534,5,E07000236,3,69.2,147.5,25.84,160.24 +6186,5,E07000236,4,80.28,192.07,25.84,210.12 +3466,6,E07000236,0,39.38,215.7,18.64,235.95 +4514,7,E07000236,1,46.13,109.29,25.84,118.85 +5199,7,E07000236,2,49.84,130.52,25.84,143.25 +5790,7,E07000236,3,59.98,147.5,25.84,160.24 +6451,7,E07000236,4,68.28,192.07,25.84,210.12 +3792,8,E07000236,0,46.63,215.7,18.64,235.95 +6726,9,E07000236,1,52.6,136.63,25.84,148.56 +7052,9,E07000236,2,58.13,163.15,25.84,179.06 +7378,9,E07000236,3,69.2,184.37,25.84,200.32 +7704,9,E07000236,4,80.28,240.08,25.84,262.64 +8030,10,E07000236,0,39.38,1363.04,18.64,1486.68 +207,1,E07000211,1,57.21,123.09,25.84,176.15 +533,1,E07000211,2,71.06,146.43,25.84,186.77 +859,1,E07000211,3,81.2,161.3,25.84,203.75 +1185,1,E07000211,4,89.52,178.28,25.84,221.77 +2815,2,E07000211,0,62.17,268.13,18.64,344.4 +1511,3,E07000211,1,51.68,115.66,25.84,159.17 +1837,3,E07000211,2,62.75,129.46,25.84,145.37 +2163,3,E07000211,3,68.28,149.62,25.84,185.7 +2489,3,E07000211,4,72.9,184.64,25.84,194.19 +3141,4,E07000211,0,48.71,195.45,18.64,204.96 +4020,5,E07000211,1,57.21,159.17,25.84,174.02 +4635,5,E07000211,2,71.06,209.06,25.84,228.14 +5287,5,E07000211,3,81.2,269.54,25.84,293.94 +5972,5,E07000211,4,89.52,438.24,25.84,477.53 +3467,6,E07000211,0,62.17,492.18,18.64,536.27 +4087,7,E07000211,1,51.68,159.17,25.84,174.02 +4782,7,E07000211,2,62.75,209.06,25.84,228.14 +5387,7,E07000211,3,68.28,269.54,25.84,293.94 +6076,7,E07000211,4,72.9,438.24,25.84,477.53 +3793,8,E07000211,0,48.71,492.18,18.64,536.27 +6727,9,E07000211,1,57.21,198.96,25.84,217.54 +7053,9,E07000211,2,71.06,261.31,25.84,285.19 +7379,9,E07000211,3,81.2,336.93,25.84,367.42 +7705,9,E07000211,4,89.52,547.82,25.84,596.91 +8031,10,E07000211,0,62.17,286.02,18.64,311.34 +208,1,E07000124,1,51.68,93.39,25.84,116.72 +534,1,E07000124,2,59.06,107.19,25.84,134.77 +860,1,E07000124,3,65.51,119.9,25.84,145.37 +1186,1,E07000124,4,71.98,133.71,25.84,159.17 +2816,2,E07000124,0,55.97,239.54,18.64,342.01 +1512,3,E07000124,1,43.36,85.94,25.84,100.81 +1838,3,E07000124,2,53.52,94.47,25.84,113.53 +2164,3,E07000124,3,58.13,105.06,25.84,124.15 +2490,3,E07000124,4,55.37,118.85,25.84,133.71 +3142,4,E07000124,0,33.16,469.54,18.64,599.44 +4374,5,E07000124,1,51.68,102.94,25.84,112.47 +4944,5,E07000124,2,59.06,130.52,25.84,143.25 +5587,5,E07000124,3,65.51,158.1,25.84,172.97 +6335,5,E07000124,4,71.98,248.31,25.84,270.61 +3468,6,E07000124,0,55.97,278.86,18.64,303.89 +4486,7,E07000124,1,43.36,102.94,25.84,112.47 +5082,7,E07000124,2,53.52,130.52,25.84,143.25 +5762,7,E07000124,3,58.13,158.1,25.84,172.97 +6386,7,E07000124,4,55.37,248.31,25.84,270.61 +3794,8,E07000124,0,33.16,278.86,18.64,303.89 +6728,9,E07000124,1,51.68,128.67,25.84,140.6 +7054,9,E07000124,2,59.06,163.15,25.84,179.06 +7380,9,E07000124,3,65.51,197.62,25.84,216.2 +7706,9,E07000124,4,71.98,310.37,25.84,338.25 +8032,10,E07000124,0,55.97,819.3,18.64,892.3 +210,1,E09000027,1,65.51,145.37,25.84,197.39 +536,1,E09000027,2,77.51,157.04,25.84,192.07 +862,1,E09000027,3,83.97,166.61,25.84,226.01 +1188,1,E09000027,4,101.48,186.77,25.84,251.49 +2818,2,E09000027,0,70.47,317,18.64,502.91 +1514,3,E09000027,1,58.13,118.85,25.84,146.43 +1840,3,E09000027,2,63.67,139.02,25.84,175.09 +2166,3,E09000027,3,71.06,159.17,25.84,200.55 +2492,3,E09000027,4,83.05,259.98,25.84,261.04 +3144,4,E09000027,0,60.1,371.82,18.64,402.8 +3976,5,E09000027,1,65.51,248.31,25.84,270.61 +4591,5,E09000027,2,77.51,336.37,25.84,367.16 +5243,5,E09000027,3,83.97,472.21,25.84,514.66 +5928,5,E09000027,4,101.48,895.6,25.84,977.32 +3470,6,E09000027,0,70.47,1005.8,18.64,1097.58 +4190,7,E09000027,1,58.13,248.31,25.84,270.61 +4691,7,E09000027,2,63.67,336.37,25.84,367.16 +5343,7,E09000027,3,71.06,472.21,25.84,514.66 +5895,7,E09000027,4,83.05,895.6,25.84,977.32 +3796,8,E09000027,0,60.1,1005.8,18.64,1097.58 +6730,9,E09000027,1,65.51,310.37,25.84,338.25 +7056,9,E09000027,2,77.51,420.48,25.84,458.95 +7382,9,E09000027,3,83.97,590.27,25.84,643.34 +7708,9,E09000027,4,101.48,1119.51,25.84,1221.66 +8034,10,E09000027,0,70.47,788.01,18.64,858.05 +211,1,E08000005,1,51.68,93.39,25.84,116.72 +537,1,E08000005,2,59.06,107.19,25.84,134.77 +863,1,E08000005,3,65.51,119.9,25.84,145.37 +1189,1,E08000005,4,71.98,133.71,25.84,159.17 +2819,2,E08000005,0,55.97,239.54,18.64,342.01 +1515,3,E08000005,1,43.36,85.94,25.84,100.81 +1841,3,E08000005,2,53.52,94.47,25.84,113.53 +2167,3,E08000005,3,58.13,105.06,25.84,124.15 +2493,3,E08000005,4,55.37,118.85,25.84,133.71 +3145,4,E08000005,0,33.16,469.54,18.64,599.44 +4375,5,E08000005,1,51.68,95.53,25.84,104 +4945,5,E08000005,2,59.06,109.29,25.84,118.85 +5588,5,E08000005,3,65.51,130.52,25.84,143.25 +6336,5,E08000005,4,71.98,192.07,25.84,210.12 +3471,6,E08000005,0,55.97,215.7,18.64,235.95 +4487,7,E08000005,1,43.36,95.53,25.84,104 +5083,7,E08000005,2,53.52,109.29,25.84,118.85 +5763,7,E08000005,3,58.13,130.52,25.84,143.25 +6387,7,E08000005,4,55.37,192.07,25.84,210.12 +3797,8,E08000005,0,33.16,215.7,18.64,235.95 +6731,9,E08000005,1,51.68,119.38,25.84,129.98 +7057,9,E08000005,2,59.06,136.63,25.84,148.56 +7383,9,E08000005,3,65.51,163.15,25.84,179.06 +7709,9,E08000005,4,71.98,240.08,25.84,262.64 +8035,10,E08000005,0,55.97,537.76,18.64,585.43 +212,1,E07000075,1,54.44,118.85,25.84,148.56 +538,1,E07000075,2,64.59,142.18,25.84,167.67 +864,1,E07000075,3,71.06,155.98,25.84,180.4 +1190,1,E07000075,4,81.2,170.85,25.84,178.28 +2820,2,E07000075,0,36.26,226.42,18.64,423.05 +1516,3,E07000075,1,49.84,99.75,25.84,131.58 +1842,3,E07000075,2,58.13,117.78,25.84,132.64 +2168,3,E07000075,3,63.67,130.52,25.84,143.25 +2494,3,E07000075,4,71.06,148.56,25.84,159.17 +3146,4,E07000075,0,55.97,135.86,18.64,318.19 +4149,5,E07000075,1,54.44,134.77,25.84,147.5 +4730,5,E07000075,2,64.59,180.4,25.84,197.39 +5449,5,E07000075,3,71.06,214.35,25.84,234.52 +6159,5,E07000075,4,81.2,292.87,25.84,319.41 +3472,6,E07000075,0,36.26,328.92,18.64,358.7 +4266,7,E07000075,1,49.84,134.77,25.84,147.5 +4992,7,E07000075,2,58.13,180.4,25.84,197.39 +5635,7,E07000075,3,63.67,214.35,25.84,234.52 +6297,7,E07000075,4,71.06,292.87,25.84,319.41 +3798,8,E07000075,0,55.97,328.92,18.64,358.7 +6732,9,E07000075,1,54.44,168.46,25.84,184.37 +7058,9,E07000075,2,64.59,225.52,25.84,246.73 +7384,9,E07000075,3,71.06,267.95,25.84,293.15 +7710,9,E07000075,4,81.2,366.11,25.84,399.27 +8036,10,E07000075,0,36.26,241.34,18.64,262.16 +213,1,E07000125,1,51.68,93.39,25.84,116.72 +539,1,E07000125,2,59.06,107.19,25.84,134.77 +865,1,E07000125,3,65.51,119.9,25.84,145.37 +1191,1,E07000125,4,71.98,133.71,25.84,159.17 +2821,2,E07000125,0,55.97,239.54,18.64,342.01 +1517,3,E07000125,1,43.36,85.94,25.84,100.81 +1843,3,E07000125,2,53.52,94.47,25.84,113.53 +2169,3,E07000125,3,58.13,105.06,25.84,124.15 +2495,3,E07000125,4,55.37,118.85,25.84,133.71 +3147,4,E07000125,0,33.16,469.54,18.64,599.44 +4376,5,E07000125,1,51.68,91.27,25.84,98.69 +4946,5,E07000125,2,59.06,109.29,25.84,118.85 +5589,5,E07000125,3,65.51,125.22,25.84,136.89 +6337,5,E07000125,4,71.98,181.46,25.84,198.45 +3473,6,E07000125,0,55.97,203.78,18.64,222.84 +4488,7,E07000125,1,43.36,91.27,25.84,98.69 +5084,7,E07000125,2,53.52,109.29,25.84,118.85 +5764,7,E07000125,3,58.13,125.22,25.84,136.89 +6388,7,E07000125,4,55.37,181.46,25.84,198.45 +3799,8,E07000125,0,33.16,203.78,18.64,222.84 +6733,9,E07000125,1,51.68,114.09,25.84,123.35 +7059,9,E07000125,2,59.06,136.63,25.84,148.56 +7385,9,E07000125,3,65.51,156.51,25.84,171.11 +7711,9,E07000125,4,71.98,226.84,25.84,248.03 +8037,10,E07000125,0,55.97,379.86,18.64,414.12 +214,1,E07000064,1,57.21,123.09,25.84,176.15 +540,1,E07000064,2,71.06,146.43,25.84,186.77 +866,1,E07000064,3,81.2,161.3,25.84,203.75 +1192,1,E07000064,4,89.52,178.28,25.84,221.77 +2822,2,E07000064,0,62.17,268.13,18.64,344.4 +1518,3,E07000064,1,51.68,115.66,25.84,159.17 +1844,3,E07000064,2,62.75,129.46,25.84,145.37 +2170,3,E07000064,3,68.28,149.62,25.84,185.7 +2496,3,E07000064,4,72.9,184.64,25.84,194.19 +3148,4,E07000064,0,48.71,195.45,18.64,204.96 +4021,5,E07000064,1,57.21,116.72,25.84,127.34 +4636,5,E07000064,2,71.06,147.5,25.84,160.24 +5288,5,E07000064,3,81.2,198.45,25.84,215.41 +5973,5,E07000064,4,89.52,281.2,25.84,306.68 +3474,6,E07000064,0,62.17,315.82,18.64,344.4 +4088,7,E07000064,1,51.68,116.72,25.84,127.34 +4783,7,E07000064,2,62.75,147.5,25.84,160.24 +5388,7,E07000064,3,68.28,198.45,25.84,215.41 +6077,7,E07000064,4,72.9,281.2,25.84,306.68 +3800,8,E07000064,0,48.71,315.82,18.64,344.4 +6734,9,E07000064,1,57.21,145.91,25.84,159.17 +7060,9,E07000064,2,71.06,184.37,25.84,200.32 +7386,9,E07000064,3,81.2,248.03,25.84,269.26 +7712,9,E07000064,4,89.52,351.51,25.84,383.34 +8038,10,E07000064,0,62.17,394.77,18.64,430.5 +215,1,E08000018,1,50.76,91.27,25.84,113.53 +541,1,E08000018,2,58.13,108.24,25.84,140.08 +867,1,E08000018,3,62.75,119.9,25.84,161.3 +1193,1,E08000018,4,72.9,144.31,25.84,178.28 +2823,2,E08000018,0,52.86,234.75,18.64,322.95 +1519,3,E08000018,1,46.13,81.71,25.84,92.33 +1845,3,E08000018,2,52.6,112.47,25.84,144.31 +2171,3,E08000018,3,56.29,104,25.84,113.53 +2497,3,E08000018,4,63.67,120.97,25.84,175.09 +3149,4,E08000018,0,51.82,160.88,18.64,190.67 +4404,5,E08000018,1,50.76,87.01,25.84,94.47 +4884,5,E08000018,2,58.13,113.53,25.84,123.09 +5515,5,E08000018,3,62.75,125.22,25.84,136.89 +6120,5,E08000018,4,72.9,170.85,25.84,185.7 +3475,6,E08000018,0,52.86,191.88,18.64,208.55 +4558,7,E08000018,1,46.13,87.01,25.84,94.47 +4826,7,E08000018,2,52.6,113.53,25.84,123.09 +5862,7,E08000018,3,56.29,125.22,25.84,136.89 +6218,7,E08000018,4,63.67,170.85,25.84,185.7 +3801,8,E08000018,0,51.82,191.88,18.64,208.55 +6735,9,E08000018,1,50.76,108.78,25.84,118.06 +7061,9,E08000018,2,52.6,141.94,25.84,153.86 +7387,9,E08000018,3,62.75,156.51,25.84,171.11 +7713,9,E08000018,4,72.9,213.57,25.84,232.15 +8039,10,E08000018,0,52.86,348.6,18.64,379.86 +216,1,E07000220,1,52.6,98.69,25.84,124.15 +542,1,E07000220,2,58.13,116.72,25.84,136.89 +868,1,E07000220,3,69.2,132.64,25.84,160.24 +1194,1,E07000220,4,80.28,161.3,25.84,178.28 +2824,2,E07000220,0,39.38,245.49,18.64,382.53 +1520,3,E07000220,1,46.13,88.07,25.84,97.63 +1846,3,E07000220,2,49.84,94.47,25.84,102.94 +2172,3,E07000220,3,59.98,104,25.84,119.9 +2498,3,E07000220,4,68.28,127.34,25.84,127.34 +3150,4,E07000220,0,46.63,107.26,18.64,107.26 +4294,5,E07000220,1,52.6,102.94,25.84,112.47 +4904,5,E07000220,2,58.13,125.22,25.84,136.89 +5535,5,E07000220,3,69.2,153.86,25.84,167.67 +6187,5,E07000220,4,80.28,265.29,25.84,289.68 +3476,6,E07000220,0,39.38,297.95,18.64,325.34 +4515,7,E07000220,1,46.13,102.94,25.84,112.47 +5200,7,E07000220,2,49.84,125.22,25.84,136.89 +5791,7,E07000220,3,59.98,153.86,25.84,167.67 +6452,7,E07000220,4,68.28,265.29,25.84,289.68 +3802,8,E07000220,0,46.63,297.95,18.64,325.34 +6736,9,E07000220,1,52.6,128.67,25.84,140.6 +7062,9,E07000220,2,58.13,156.51,25.84,171.11 +7388,9,E07000220,3,69.2,192.33,25.84,209.57 +7714,9,E07000220,4,80.28,331.63,25.84,362.13 +8040,10,E07000220,0,39.38,284.53,18.64,309.82 +217,1,E07000212,1,57.21,123.09,25.84,176.15 +543,1,E07000212,2,71.06,146.43,25.84,186.77 +869,1,E07000212,3,81.2,161.3,25.84,203.75 +1195,1,E07000212,4,89.52,178.28,25.84,221.77 +2825,2,E07000212,0,62.17,268.13,18.64,344.4 +1521,3,E07000212,1,51.68,115.66,25.84,159.17 +1847,3,E07000212,2,62.75,129.46,25.84,145.37 +2173,3,E07000212,3,68.28,149.62,25.84,185.7 +2499,3,E07000212,4,72.9,184.64,25.84,194.19 +3151,4,E07000212,0,48.71,195.45,18.64,204.96 +4022,5,E07000212,1,57.21,181.46,25.84,198.45 +4637,5,E07000212,2,71.06,248.31,25.84,270.61 +5289,5,E07000212,3,81.2,304.55,25.84,332.14 +5974,5,E07000212,4,89.52,539.06,25.84,587.88 +3477,6,E07000212,0,62.17,605.39,18.64,660.22 +4089,7,E07000212,1,51.68,181.46,25.84,198.45 +4784,7,E07000212,2,62.75,248.31,25.84,270.61 +5389,7,E07000212,3,68.28,304.55,25.84,332.14 +6078,7,E07000212,4,72.9,539.06,25.84,587.88 +3803,8,E07000212,0,48.71,605.39,18.64,660.22 +6737,9,E07000212,1,57.21,226.84,25.84,248.03 +7063,9,E07000212,2,71.06,310.37,25.84,338.25 +7389,9,E07000212,3,81.2,380.68,25.84,415.17 +7715,9,E07000212,4,89.52,673.83,25.84,734.87 +8041,10,E07000212,0,62.17,269.62,18.64,294.95 +218,1,E07000176,1,51.68,99.75,25.84,122.03 +544,1,E07000176,2,61.83,114.6,25.84,129.46 +870,1,E07000176,3,68.28,126.28,25.84,137.95 +1196,1,E07000176,4,75.67,158.1,25.84,166.61 +2826,2,E07000176,0,51.82,240.72,18.64,361.1 +1522,3,E07000176,1,46.13,90.21,25.84,107.19 +1848,3,E07000176,2,52.6,96.56,25.84,108.24 +2174,3,E07000176,3,58.13,104,25.84,118.85 +2500,3,E07000176,4,63.67,122.03,25.84,122.03 +3152,4,E07000176,0,49.74,114.39,18.64,123.94 +4343,5,E07000176,1,51.68,109.29,25.84,118.85 +5039,5,E07000176,2,61.83,134.77,25.84,147.5 +5682,5,E07000176,3,68.28,170.85,25.84,185.7 +6257,5,E07000176,4,75.67,270.61,25.84,295.01 +3478,6,E07000176,0,51.82,303.89,18.64,331.29 +4443,7,E07000176,1,46.13,109.29,25.84,118.85 +5179,7,E07000176,2,52.6,134.77,25.84,147.5 +5840,7,E07000176,3,58.13,170.85,25.84,185.7 +6501,7,E07000176,4,63.67,270.61,25.84,295.01 +3804,8,E07000176,0,49.74,303.89,18.64,331.29 +6738,9,E07000176,1,51.68,136.63,25.84,148.56 +7064,9,E07000176,2,61.83,168.46,25.84,184.37 +7390,9,E07000176,3,68.28,213.57,25.84,232.15 +7716,9,E07000176,4,75.67,338.25,25.84,368.76 +8042,10,E07000176,0,51.82,348.6,18.64,379.86 +219,1,E07000092,1,57.21,123.09,25.84,176.15 +545,1,E07000092,2,71.06,146.43,25.84,186.77 +871,1,E07000092,3,81.2,161.3,25.84,203.75 +1197,1,E07000092,4,89.52,178.28,25.84,221.77 +2827,2,E07000092,0,62.17,268.13,18.64,344.4 +1523,3,E07000092,1,51.68,115.66,25.84,159.17 +1849,3,E07000092,2,62.75,129.46,25.84,145.37 +2175,3,E07000092,3,68.28,149.62,25.84,185.7 +2501,3,E07000092,4,72.9,184.64,25.84,194.19 +3153,4,E07000092,0,48.71,195.45,18.64,204.96 +4023,5,E07000092,1,57.21,147.5,25.84,160.24 +4638,5,E07000092,2,71.06,181.46,25.84,198.45 +5290,5,E07000092,3,81.2,237.69,25.84,258.92 +5975,5,E07000092,4,89.52,337.44,25.84,368.22 +3479,6,E07000092,0,62.17,378.95,18.64,413.53 +4090,7,E07000092,1,51.68,147.5,25.84,160.24 +4785,7,E07000092,2,62.75,181.46,25.84,198.45 +5390,7,E07000092,3,68.28,237.69,25.84,258.92 +6079,7,E07000092,4,72.9,337.44,25.84,368.22 +3805,8,E07000092,0,48.71,378.95,18.64,413.53 +6739,9,E07000092,1,57.21,184.37,25.84,200.32 +7065,9,E07000092,2,71.06,226.84,25.84,248.03 +7391,9,E07000092,3,81.2,297.12,25.84,323.65 +7717,9,E07000092,4,89.52,421.8,25.84,460.26 +8043,10,E07000092,0,62.17,286.02,18.64,311.34 +220,1,E06000017,1,51.68,99.75,25.84,122.03 +546,1,E06000017,2,61.83,114.6,25.84,129.46 +872,1,E06000017,3,68.28,126.28,25.84,137.95 +1198,1,E06000017,4,75.67,158.1,25.84,166.61 +2828,2,E06000017,0,51.82,240.72,18.64,361.1 +1524,3,E06000017,1,46.13,90.21,25.84,107.19 +1850,3,E06000017,2,52.6,96.56,25.84,108.24 +2176,3,E06000017,3,58.13,104,25.84,118.85 +2502,3,E06000017,4,63.67,122.03,25.84,122.03 +3154,4,E06000017,0,49.74,114.39,18.64,123.94 +4344,5,E06000017,1,51.68,109.29,25.84,118.85 +5040,5,E06000017,2,61.83,130.52,25.84,143.25 +5683,5,E06000017,3,68.28,164.48,25.84,179.34 +6258,5,E06000017,4,75.67,287.59,25.84,311.99 +3480,6,E06000017,0,51.82,322.95,18.64,350.36 +4444,7,E06000017,1,46.13,109.29,25.84,118.85 +5180,7,E06000017,2,52.6,130.52,25.84,143.25 +5841,7,E06000017,3,58.13,164.48,25.84,179.34 +6502,7,E06000017,4,63.67,287.59,25.84,311.99 +3806,8,E06000017,0,49.74,322.95,18.64,350.36 +6740,9,E06000017,1,51.68,136.63,25.84,148.56 +7066,9,E06000017,2,61.83,163.15,25.84,179.06 +7392,9,E06000017,3,68.28,205.6,25.84,224.18 +7718,9,E06000017,4,75.67,359.47,25.84,389.97 +8044,10,E06000017,0,51.82,269.62,18.64,294.95 +222,1,E08000006,1,51.68,93.39,25.84,116.72 +548,1,E08000006,2,59.06,107.19,25.84,134.77 +874,1,E08000006,3,65.51,119.9,25.84,145.37 +1200,1,E08000006,4,71.98,133.71,25.84,159.17 +2830,2,E08000006,0,55.97,239.54,18.64,342.01 +1526,3,E08000006,1,43.36,85.94,25.84,100.81 +1852,3,E08000006,2,53.52,94.47,25.84,113.53 +2178,3,E08000006,3,58.13,105.06,25.84,124.15 +2504,3,E08000006,4,55.37,118.85,25.84,133.71 +3156,4,E08000006,0,33.16,469.54,18.64,599.44 +4377,5,E08000006,1,51.68,113.53,25.84,123.09 +4947,5,E08000006,2,59.06,130.52,25.84,143.25 +5590,5,E08000006,3,65.51,147.5,25.84,160.24 +6338,5,E08000006,4,71.98,243.02,25.84,265.29 +3482,6,E08000006,0,55.97,272.91,18.64,297.95 +4489,7,E08000006,1,43.36,113.53,25.84,123.09 +5085,7,E08000006,2,53.52,130.52,25.84,143.25 +5765,7,E08000006,3,58.13,147.5,25.84,160.24 +6389,7,E08000006,4,55.37,243.02,25.84,265.29 +3808,8,E08000006,0,33.16,272.91,18.64,297.95 +6742,9,E08000006,1,51.68,141.94,25.84,153.86 +7068,9,E08000006,2,59.06,163.15,25.84,179.06 +7394,9,E08000006,3,65.51,184.37,25.84,200.32 +7720,9,E08000006,4,71.98,303.74,25.84,331.63 +8046,10,E08000006,0,55.97,442.4,18.64,481.18 +223,1,E08000028,1,52.6,98.69,25.84,124.15 +549,1,E08000028,2,58.13,116.72,25.84,136.89 +875,1,E08000028,3,69.2,132.64,25.84,160.24 +1201,1,E08000028,4,80.28,161.3,25.84,178.28 +2831,2,E08000028,0,39.38,245.49,18.64,382.53 +1527,3,E08000028,1,46.13,88.07,25.84,97.63 +1853,3,E08000028,2,49.84,94.47,25.84,102.94 +2179,3,E08000028,3,59.98,104,25.84,119.9 +2505,3,E08000028,4,68.28,127.34,25.84,127.34 +3157,4,E08000028,0,46.63,107.26,18.64,107.26 +4295,5,E08000028,1,52.6,99.75,25.84,109.29 +4905,5,E08000028,2,58.13,119.9,25.84,130.52 +5536,5,E08000028,3,69.2,134.77,25.84,147.5 +6188,5,E08000028,4,80.28,181.46,25.84,198.45 +3483,6,E08000028,0,39.38,203.78,18.64,222.84 +4516,7,E08000028,1,46.13,99.75,25.84,109.29 +5201,7,E08000028,2,49.84,119.9,25.84,130.52 +5792,7,E08000028,3,59.98,134.77,25.84,147.5 +6453,7,E08000028,4,68.28,181.46,25.84,198.45 +3809,8,E08000028,0,46.63,203.78,18.64,222.84 +6743,9,E08000028,1,52.6,124.69,25.84,136.63 +7069,9,E08000028,2,58.13,149.9,25.84,163.15 +7395,9,E08000028,3,69.2,168.46,25.84,184.37 +7721,9,E08000028,4,80.28,226.84,25.84,248.03 +8047,10,E08000028,0,39.38,676.32,18.64,738.88 +226,1,E08000014,1,51.68,93.39,25.84,116.72 +552,1,E08000014,2,59.06,107.19,25.84,134.77 +878,1,E08000014,3,65.51,119.9,25.84,145.37 +1204,1,E08000014,4,71.98,133.71,25.84,159.17 +2834,2,E08000014,0,55.97,239.54,18.64,342.01 +1530,3,E08000014,1,43.36,85.94,25.84,100.81 +1856,3,E08000014,2,53.52,94.47,25.84,113.53 +2182,3,E08000014,3,58.13,105.06,25.84,124.15 +2508,3,E08000014,4,55.37,118.85,25.84,133.71 +3160,4,E08000014,0,33.16,469.54,18.64,599.44 +4378,5,E08000014,1,51.68,102.94,25.84,112.47 +4948,5,E08000014,2,59.06,131.58,25.84,144.31 +5591,5,E08000014,3,65.51,153.86,25.84,167.67 +6339,5,E08000014,4,71.98,219.66,25.84,239.83 +3486,6,E08000014,0,55.97,246.68,18.64,269.32 +4490,7,E08000014,1,43.36,102.94,25.84,112.47 +5086,7,E08000014,2,53.52,131.58,25.84,144.31 +5766,7,E08000014,3,58.13,153.86,25.84,167.67 +6390,7,E08000014,4,55.37,219.66,25.84,239.83 +3812,8,E08000014,0,33.16,246.68,18.64,269.32 +6746,9,E08000014,1,51.68,128.67,25.84,140.6 +7072,9,E08000014,2,59.06,164.47,25.84,180.39 +7398,9,E08000014,3,65.51,192.33,25.84,209.57 +7724,9,E08000014,4,71.98,274.57,25.84,299.78 +8050,10,E08000014,0,55.97,286.02,18.64,311.34 +228,1,E07000111,1,57.21,123.09,25.84,176.15 +554,1,E07000111,2,71.06,146.43,25.84,186.77 +880,1,E07000111,3,81.2,161.3,25.84,203.75 +1206,1,E07000111,4,89.52,178.28,25.84,221.77 +2836,2,E07000111,0,62.17,268.13,18.64,344.4 +1532,3,E07000111,1,51.68,115.66,25.84,159.17 +1858,3,E07000111,2,62.75,129.46,25.84,145.37 +2184,3,E07000111,3,68.28,149.62,25.84,185.7 +2510,3,E07000111,4,72.9,184.64,25.84,194.19 +3162,4,E07000111,0,48.71,195.45,18.64,204.96 +4024,5,E07000111,1,57.21,159.17,25.84,174.02 +4639,5,E07000111,2,71.06,214.35,25.84,234.52 +5291,5,E07000111,3,81.2,315.17,25.84,342.76 +5976,5,E07000111,4,89.52,628.21,25.84,685.51 +3488,6,E07000111,0,62.17,705.52,18.64,769.85 +4091,7,E07000111,1,51.68,159.17,25.84,174.02 +4786,7,E07000111,2,62.75,214.35,25.84,234.52 +5391,7,E07000111,3,68.28,315.17,25.84,342.76 +6080,7,E07000111,4,72.9,628.21,25.84,685.51 +3814,8,E07000111,0,48.71,705.52,18.64,769.85 +6748,9,E07000111,1,57.21,198.96,25.84,217.54 +7074,9,E07000111,2,71.06,267.95,25.84,293.15 +7400,9,E07000111,3,81.2,393.95,25.84,428.42 +7726,9,E07000111,4,89.52,785.27,25.84,856.88 +8052,10,E07000111,0,62.17,734.4,18.64,799.92 +229,1,E08000019,1,50.76,91.27,25.84,113.53 +555,1,E08000019,2,58.13,108.24,25.84,140.08 +881,1,E08000019,3,62.75,119.9,25.84,161.3 +1207,1,E08000019,4,72.9,144.31,25.84,178.28 +2837,2,E08000019,0,52.86,234.75,18.64,322.95 +1533,3,E08000019,1,46.13,81.71,25.84,92.33 +1859,3,E08000019,2,52.6,112.47,25.84,144.31 +2185,3,E08000019,3,56.29,104,25.84,113.53 +2511,3,E08000019,4,63.67,120.97,25.84,175.09 +3163,4,E08000019,0,51.82,160.88,18.64,190.67 +4408,5,E08000019,1,50.76,114.6,25.84,124.15 +4888,5,E08000019,2,58.13,130.52,25.84,143.25 +5519,5,E08000019,3,62.75,136.89,25.84,148.56 +6124,5,E08000019,4,72.9,209.06,25.84,228.14 +3489,6,E08000019,0,52.86,234.75,18.64,256.21 +4562,7,E08000019,1,46.13,114.6,25.84,124.15 +4830,7,E08000019,2,52.6,130.52,25.84,143.25 +5866,7,E08000019,3,56.29,136.89,25.84,148.56 +6222,7,E08000019,4,63.67,209.06,25.84,228.14 +3815,8,E08000019,0,51.82,234.75,18.64,256.21 +6749,9,E08000019,1,50.76,143.25,25.84,155.2 +7075,9,E08000019,2,52.6,163.15,25.84,179.06 +7401,9,E08000019,3,62.75,171.11,25.84,185.69 +7727,9,E08000019,4,72.9,261.31,25.84,285.19 +8053,10,E08000019,0,52.86,694.16,18.64,756.74 +230,1,E07000112,1,57.21,123.09,25.84,176.15 +556,1,E07000112,2,71.06,146.43,25.84,186.77 +882,1,E07000112,3,81.2,161.3,25.84,203.75 +1208,1,E07000112,4,89.52,178.28,25.84,221.77 +2838,2,E07000112,0,62.17,268.13,18.64,344.4 +1534,3,E07000112,1,51.68,115.66,25.84,159.17 +1860,3,E07000112,2,62.75,129.46,25.84,145.37 +2186,3,E07000112,3,68.28,149.62,25.84,185.7 +2512,3,E07000112,4,72.9,184.64,25.84,194.19 +3164,4,E07000112,0,48.71,195.45,18.64,204.96 +4025,5,E07000112,1,57.21,102.94,25.84,112.47 +4640,5,E07000112,2,71.06,141.13,25.84,153.86 +5292,5,E07000112,3,81.2,170.85,25.84,185.7 +5977,5,E07000112,4,89.52,265.29,25.84,289.68 +3490,6,E07000112,0,62.17,297.95,18.64,325.34 +4092,7,E07000112,1,51.68,102.94,25.84,112.47 +4787,7,E07000112,2,62.75,141.13,25.84,153.86 +5392,7,E07000112,3,68.28,170.85,25.84,185.7 +6081,7,E07000112,4,72.9,265.29,25.84,289.68 +3816,8,E07000112,0,48.71,297.95,18.64,325.34 +6750,9,E07000112,1,57.21,128.67,25.84,140.6 +7076,9,E07000112,2,71.06,176.42,25.84,192.33 +7402,9,E07000112,3,81.2,213.57,25.84,232.15 +7728,9,E07000112,4,89.52,331.63,25.84,362.13 +8054,10,E07000112,0,62.17,598.84,18.64,653.96 +231,1,E06000051,1,52.6,98.69,25.84,124.15 +557,1,E06000051,2,58.13,116.72,25.84,136.89 +883,1,E06000051,3,69.2,132.64,25.84,160.24 +1209,1,E06000051,4,80.28,161.3,25.84,178.28 +2839,2,E06000051,0,39.38,245.49,18.64,382.53 +1535,3,E06000051,1,46.13,88.07,25.84,97.63 +1861,3,E06000051,2,49.84,94.47,25.84,102.94 +2187,3,E06000051,3,59.98,104,25.84,119.9 +2513,3,E06000051,4,68.28,127.34,25.84,127.34 +3165,4,E06000051,0,46.63,107.26,18.64,107.26 +4296,5,E06000051,1,52.6,102.94,25.84,112.47 +4906,5,E06000051,2,58.13,125.22,25.84,136.89 +5537,5,E06000051,3,69.2,147.5,25.84,160.24 +6189,5,E06000051,4,80.28,219.66,25.84,239.83 +3491,6,E06000051,0,39.38,246.68,18.64,269.32 +4517,7,E06000051,1,46.13,102.94,25.84,112.47 +5202,7,E06000051,2,49.84,125.22,25.84,136.89 +5793,7,E06000051,3,59.98,147.5,25.84,160.24 +6454,7,E06000051,4,68.28,219.66,25.84,239.83 +3817,8,E06000051,0,46.63,246.68,18.64,269.32 +6751,9,E06000051,1,52.6,128.67,25.84,140.6 +7077,9,E06000051,2,58.13,156.51,25.84,171.11 +7403,9,E06000051,3,69.2,184.37,25.84,200.32 +7729,9,E06000051,4,80.28,274.57,25.84,299.78 +8055,10,E06000051,0,39.38,1054.69,18.64,1150.03 +232,1,E06000039,1,57.21,123.09,25.84,176.15 +558,1,E06000039,2,71.06,146.43,25.84,186.77 +884,1,E06000039,3,81.2,161.3,25.84,203.75 +1210,1,E06000039,4,89.52,178.28,25.84,221.77 +2840,2,E06000039,0,62.17,268.13,18.64,344.4 +1536,3,E06000039,1,51.68,115.66,25.84,159.17 +1862,3,E06000039,2,62.75,129.46,25.84,145.37 +2188,3,E06000039,3,68.28,149.62,25.84,185.7 +2514,3,E06000039,4,72.9,184.64,25.84,194.19 +3166,4,E06000039,0,48.71,195.45,18.64,204.96 +4026,5,E06000039,1,57.21,153.86,25.84,167.67 +4641,5,E06000039,2,71.06,192.07,25.84,210.12 +5293,5,E06000039,3,81.2,237.69,25.84,258.92 +5978,5,E06000039,4,89.52,337.44,25.84,368.22 +3492,6,E06000039,0,62.17,378.95,18.64,413.53 +4093,7,E06000039,1,51.68,153.86,25.84,167.67 +4788,7,E06000039,2,62.75,192.07,25.84,210.12 +5393,7,E06000039,3,68.28,237.69,25.84,258.92 +6082,7,E06000039,4,72.9,337.44,25.84,368.22 +3818,8,E06000039,0,48.71,378.95,18.64,413.53 +6752,9,E06000039,1,57.21,192.33,25.84,209.57 +7078,9,E06000039,2,71.06,240.08,25.84,262.64 +7404,9,E06000039,3,81.2,297.12,25.84,323.65 +7730,9,E06000039,4,89.52,421.8,25.84,460.26 +8056,10,E06000039,0,62.17,428.99,18.64,469.23 +233,1,E08000029,1,52.6,98.69,25.84,124.15 +559,1,E08000029,2,58.13,116.72,25.84,136.89 +885,1,E08000029,3,69.2,132.64,25.84,160.24 +1211,1,E08000029,4,80.28,161.3,25.84,178.28 +2841,2,E08000029,0,39.38,245.49,18.64,382.53 +1537,3,E08000029,1,46.13,88.07,25.84,97.63 +1863,3,E08000029,2,49.84,94.47,25.84,102.94 +2189,3,E08000029,3,59.98,104,25.84,119.9 +2515,3,E08000029,4,68.28,127.34,25.84,127.34 +3167,4,E08000029,0,46.63,107.26,18.64,107.26 +4297,5,E08000029,1,52.6,125.22,25.84,136.89 +4907,5,E08000029,2,58.13,159.17,25.84,174.02 +5538,5,E08000029,3,69.2,192.07,25.84,210.12 +6190,5,E08000029,4,80.28,358.66,25.84,391.56 +3493,6,E08000029,0,39.38,402.8,18.64,439.74 +4518,7,E08000029,1,46.13,125.22,25.84,136.89 +5203,7,E08000029,2,49.84,159.17,25.84,174.02 +5794,7,E08000029,3,59.98,192.07,25.84,210.12 +6455,7,E08000029,4,68.28,358.66,25.84,391.56 +3819,8,E08000029,0,46.63,402.8,18.64,439.74 +6753,9,E08000029,1,52.6,156.51,25.84,171.11 +7079,9,E08000029,2,58.13,198.96,25.84,217.54 +7405,9,E08000029,3,69.2,240.08,25.84,262.64 +7731,9,E08000029,4,80.28,448.34,25.84,489.48 +8057,10,E08000029,0,39.38,662.89,18.64,722.48 +8226,1,E06000066,1,48.92,107.19,25.84,140.08 +8227,1,E06000066,2,55.37,120.97,25.84,144.31 +8228,1,E06000066,3,61.83,141.13,25.84,161.3 +8229,1,E06000066,4,71.06,158.1,25.84,194.19 +8234,2,E06000066,0,54.93,231.2,18.64,358.7 +8230,3,E06000066,1,47.06,89.13,25.84,210.12 +8231,3,E06000066,2,54.44,100.81,25.84,111.41 +8232,3,E06000066,3,61.83,109.29,25.84,126.28 +8233,3,E06000066,4,73.82,130.52,25.84,130.52 +8235,4,E06000066,0,54.93,115.59,18.64,141.81 +8239,5,E06000066,1,48.92,113.53,25.84,123.09 +8240,5,E06000066,2,55.37,136.89,25.84,148.56 +8242,5,E06000066,3,61.83,164.48,25.84,179.34 +8244,5,E06000066,4,71.06,248.31,25.84,270.61 +8236,6,E06000066,0,54.93,303.89,18.64,331.29 +8238,7,E06000066,1,47.06,113.53,25.84,123.09 +8241,7,E06000066,2,54.44,136.89,25.84,148.56 +8243,7,E06000066,3,61.83,164.48,25.84,179.34 +8245,7,E06000066,4,73.82,248.31,25.84,270.61 +8237,8,E06000066,0,54.93,303.89,18.64,331.29 +8246,9,E06000066,1,48.92,141.94,25.84,153.86 +8247,9,E06000066,2,55.37,171.11,25.84,185.69 +8248,9,E06000066,3,61.83,205.6,25.84,224.18 +8249,9,E06000066,4,71.06,310.37,25.84,338.25 +8250,10,E06000066,0,54.93,318.79,18.64,345.6 +235,1,E07000012,1,54.44,118.85,25.84,148.56 +561,1,E07000012,2,64.59,142.18,25.84,167.67 +887,1,E07000012,3,71.06,155.98,25.84,180.4 +1213,1,E07000012,4,81.2,170.85,25.84,178.28 +2843,2,E07000012,0,36.26,226.42,18.64,423.05 +1539,3,E07000012,1,49.84,99.75,25.84,131.58 +1865,3,E07000012,2,58.13,117.78,25.84,132.64 +2191,3,E07000012,3,63.67,130.52,25.84,143.25 +2517,3,E07000012,4,71.06,148.56,25.84,159.17 +3169,4,E07000012,0,55.97,135.86,18.64,318.19 +4150,5,E07000012,1,54.44,147.5,25.84,160.24 +4731,5,E07000012,2,64.59,170.85,25.84,185.7 +5450,5,E07000012,3,71.06,202.69,25.84,220.72 +6160,5,E07000012,4,81.2,316.23,25.84,344.88 +3495,6,E07000012,0,36.26,355.12,18.64,387.3 +4267,7,E07000012,1,49.84,147.5,25.84,160.24 +4993,7,E07000012,2,58.13,170.85,25.84,185.7 +5636,7,E07000012,3,63.67,202.69,25.84,220.72 +6298,7,E07000012,4,71.06,316.23,25.84,344.88 +3821,8,E07000012,0,55.97,355.12,18.64,387.3 +6755,9,E07000012,1,54.44,184.37,25.84,200.32 +7081,9,E07000012,2,64.59,213.57,25.84,232.15 +7407,9,E07000012,3,71.06,253.36,25.84,275.9 +7733,9,E07000012,4,81.2,395.3,25.84,431.1 +8059,10,E07000012,0,36.26,286.02,18.64,311.34 +236,1,E07000039,1,51.68,99.75,25.84,122.03 +562,1,E07000039,2,61.83,114.6,25.84,129.46 +888,1,E07000039,3,68.28,126.28,25.84,137.95 +1214,1,E07000039,4,75.67,158.1,25.84,166.61 +2844,2,E07000039,0,51.82,240.72,18.64,361.1 +1540,3,E07000039,1,46.13,90.21,25.84,107.19 +1866,3,E07000039,2,52.6,96.56,25.84,108.24 +2192,3,E07000039,3,58.13,104,25.84,118.85 +2518,3,E07000039,4,63.67,122.03,25.84,122.03 +3170,4,E07000039,0,49.74,114.39,18.64,123.94 +4345,5,E07000039,1,51.68,102.94,25.84,112.47 +5041,5,E07000039,2,61.83,125.22,25.84,136.89 +5684,5,E07000039,3,68.28,147.5,25.84,160.24 +6259,5,E07000039,4,75.67,247.25,25.84,270.61 +3496,6,E07000039,0,51.82,277.67,18.64,303.89 +4445,7,E07000039,1,46.13,102.94,25.84,112.47 +5181,7,E07000039,2,52.6,125.22,25.84,136.89 +5842,7,E07000039,3,58.13,147.5,25.84,160.24 +6503,7,E07000039,4,63.67,247.25,25.84,270.61 +3822,8,E07000039,0,49.74,277.67,18.64,303.89 +6756,9,E07000039,1,51.68,128.67,25.84,140.6 +7082,9,E07000039,2,61.83,156.51,25.84,171.11 +7408,9,E07000039,3,68.28,184.37,25.84,200.32 +7734,9,E07000039,4,75.67,309.06,25.84,338.25 +8060,10,E07000039,0,51.82,262.16,18.64,286.02 +237,1,E06000025,1,48.92,107.19,25.84,140.08 +563,1,E06000025,2,55.37,120.97,25.84,144.31 +889,1,E06000025,3,61.83,141.13,25.84,161.3 +1215,1,E06000025,4,71.06,158.1,25.84,194.19 +2845,2,E06000025,0,54.93,231.2,18.64,358.7 +1541,3,E06000025,1,47.06,89.13,25.84,210.12 +1867,3,E06000025,2,54.44,100.81,25.84,111.41 +2193,3,E06000025,3,61.83,109.29,25.84,126.28 +2519,3,E06000025,4,73.82,130.52,25.84,130.52 +3171,4,E06000025,0,54.93,115.59,18.64,141.81 +4219,5,E06000025,1,48.92,125.22,25.84,136.89 +4855,5,E06000025,2,55.37,150.69,25.84,164.48 +5486,5,E06000025,3,61.83,186.77,25.84,203.75 +6024,5,E06000025,4,71.06,269.54,25.84,293.94 +3497,6,E06000025,0,54.93,302.7,18.64,330.11 +3935,7,E06000025,1,47.06,125.22,25.84,136.89 +5132,7,E06000025,2,54.44,150.69,25.84,164.48 +5712,7,E06000025,3,61.83,186.77,25.84,203.75 +6424,7,E06000025,4,73.82,269.54,25.84,293.94 +3823,8,E06000025,0,54.93,302.7,18.64,330.11 +6757,9,E06000025,1,48.92,156.51,25.84,171.11 +7083,9,E06000025,2,55.37,188.36,25.84,205.6 +7409,9,E06000025,3,61.83,233.46,25.84,254.69 +7735,9,E06000025,4,71.06,336.93,25.84,367.42 +8061,10,E06000025,0,54.93,348.6,18.64,379.86 +238,1,E07000044,1,48.92,107.19,25.84,140.08 +564,1,E07000044,2,55.37,120.97,25.84,144.31 +890,1,E07000044,3,61.83,141.13,25.84,161.3 +1216,1,E07000044,4,71.06,158.1,25.84,194.19 +2846,2,E07000044,0,54.93,231.2,18.64,358.7 +1542,3,E07000044,1,47.06,89.13,25.84,210.12 +1868,3,E07000044,2,54.44,100.81,25.84,111.41 +2194,3,E07000044,3,61.83,109.29,25.84,126.28 +2520,3,E07000044,4,73.82,130.52,25.84,130.52 +3172,4,E07000044,0,54.93,115.59,18.64,141.81 +4220,5,E07000044,1,48.92,113.53,25.84,124.15 +4856,5,E07000044,2,55.37,142.18,25.84,154.93 +5487,5,E07000044,3,61.83,180.4,25.84,197.39 +6025,5,E07000044,4,71.06,248.31,25.84,270.61 +3498,6,E07000044,0,54.93,278.86,18.64,303.89 +3936,7,E07000044,1,47.06,113.53,25.84,124.15 +5133,7,E07000044,2,54.44,142.18,25.84,154.93 +5713,7,E07000044,3,61.83,180.4,25.84,197.39 +6425,7,E07000044,4,73.82,248.31,25.84,270.61 +3824,8,E07000044,0,54.93,278.86,18.64,303.89 +6758,9,E07000044,1,48.92,141.94,25.84,155.2 +7084,9,E07000044,2,55.37,177.73,25.84,193.64 +7410,9,E07000044,3,61.83,225.52,25.84,246.73 +7736,9,E07000044,4,71.06,310.37,25.84,338.25 +8062,10,E07000044,0,54.93,223.45,18.64,244.32 +239,1,E07000140,1,51.68,99.75,25.84,122.03 +565,1,E07000140,2,61.83,114.6,25.84,129.46 +891,1,E07000140,3,68.28,126.28,25.84,137.95 +1217,1,E07000140,4,75.67,158.1,25.84,166.61 +2847,2,E07000140,0,51.82,240.72,18.64,361.1 +1543,3,E07000140,1,46.13,90.21,25.84,107.19 +1869,3,E07000140,2,52.6,96.56,25.84,108.24 +2195,3,E07000140,3,58.13,104,25.84,118.85 +2521,3,E07000140,4,63.67,122.03,25.84,122.03 +3173,4,E07000140,0,49.74,114.39,18.64,123.94 +4346,5,E07000140,1,51.68,99.75,25.84,109.29 +5042,5,E07000140,2,61.83,119.9,25.84,130.52 +5685,5,E07000140,3,68.28,136.89,25.84,148.56 +6260,5,E07000140,4,75.67,180.4,25.84,197.39 +3499,6,E07000140,0,51.82,202.58,18.64,221.66 +4446,7,E07000140,1,46.13,99.75,25.84,109.29 +5182,7,E07000140,2,52.6,119.9,25.84,130.52 +5843,7,E07000140,3,58.13,136.89,25.84,148.56 +6504,7,E07000140,4,63.67,180.4,25.84,197.39 +3825,8,E07000140,0,49.74,202.58,18.64,221.66 +6759,9,E07000140,1,51.68,124.69,25.84,136.63 +7085,9,E07000140,2,61.83,149.9,25.84,163.15 +7411,9,E07000140,3,68.28,171.11,25.84,185.69 +7737,9,E07000140,4,75.67,225.52,25.84,246.73 +8063,10,E07000140,0,51.82,552.67,18.64,601.83 +240,1,E07000141,1,51.68,99.75,25.84,122.03 +566,1,E07000141,2,61.83,114.6,25.84,129.46 +892,1,E07000141,3,68.28,126.28,25.84,137.95 +1218,1,E07000141,4,75.67,158.1,25.84,166.61 +2848,2,E07000141,0,51.82,240.72,18.64,361.1 +1544,3,E07000141,1,46.13,90.21,25.84,107.19 +1870,3,E07000141,2,52.6,96.56,25.84,108.24 +2196,3,E07000141,3,58.13,104,25.84,118.85 +2522,3,E07000141,4,63.67,122.03,25.84,122.03 +3174,4,E07000141,0,49.74,114.39,18.64,123.94 +4347,5,E07000141,1,51.68,97.63,25.84,107.19 +5043,5,E07000141,2,61.83,125.22,25.84,136.89 +5686,5,E07000141,3,68.28,147.5,25.84,160.24 +6261,5,E07000141,4,75.67,203.75,25.84,221.77 +3500,6,E07000141,0,51.82,228.81,18.64,249.07 +4447,7,E07000141,1,46.13,97.63,25.84,107.19 +5183,7,E07000141,2,52.6,125.22,25.84,136.89 +5844,7,E07000141,3,58.13,147.5,25.84,160.24 +6505,7,E07000141,4,63.67,203.75,25.84,221.77 +3826,8,E07000141,0,49.74,228.81,18.64,249.07 +6760,9,E07000141,1,51.68,122.03,25.84,133.98 +7086,9,E07000141,2,61.83,156.51,25.84,171.11 +7412,9,E07000141,3,68.28,184.37,25.84,200.32 +7738,9,E07000141,4,75.67,254.69,25.84,277.23 +8064,10,E07000141,0,51.82,567.58,18.64,618.2 +242,1,E07000149,1,54.44,118.85,25.84,148.56 +568,1,E07000149,2,64.59,142.18,25.84,167.67 +894,1,E07000149,3,71.06,155.98,25.84,180.4 +1220,1,E07000149,4,81.2,170.85,25.84,178.28 +2850,2,E07000149,0,36.26,226.42,18.64,423.05 +1546,3,E07000149,1,49.84,99.75,25.84,131.58 +1872,3,E07000149,2,58.13,117.78,25.84,132.64 +2198,3,E07000149,3,63.67,130.52,25.84,143.25 +2524,3,E07000149,4,71.06,148.56,25.84,159.17 +3176,4,E07000149,0,55.97,135.86,18.64,318.19 +4151,5,E07000149,1,54.44,102.94,25.84,112.47 +4732,5,E07000149,2,64.59,125.22,25.84,136.89 +5451,5,E07000149,3,71.06,147.5,25.84,160.24 +6161,5,E07000149,4,81.2,214.35,25.84,234.52 +3502,6,E07000149,0,36.26,240.72,18.64,263.37 +4268,7,E07000149,1,49.84,102.94,25.84,112.47 +4994,7,E07000149,2,58.13,125.22,25.84,136.89 +5637,7,E07000149,3,63.67,147.5,25.84,160.24 +6299,7,E07000149,4,71.06,214.35,25.84,234.52 +3828,8,E07000149,0,55.97,240.72,18.64,263.37 +6762,9,E07000149,1,54.44,128.67,25.84,140.6 +7088,9,E07000149,2,64.59,156.51,25.84,171.11 +7414,9,E07000149,3,71.06,184.37,25.84,200.32 +7740,9,E07000149,4,81.2,267.95,25.84,293.15 +8066,10,E07000149,0,36.26,394.77,18.64,430.5 +244,1,E07000179,1,57.21,123.09,25.84,176.15 +570,1,E07000179,2,71.06,146.43,25.84,186.77 +896,1,E07000179,3,81.2,161.3,25.84,203.75 +1222,1,E07000179,4,89.52,178.28,25.84,221.77 +2852,2,E07000179,0,62.17,268.13,18.64,344.4 +1548,3,E07000179,1,51.68,115.66,25.84,159.17 +1874,3,E07000179,2,62.75,129.46,25.84,145.37 +2200,3,E07000179,3,68.28,149.62,25.84,185.7 +2526,3,E07000179,4,72.9,184.64,25.84,194.19 +3178,4,E07000179,0,48.71,195.45,18.64,204.96 +4028,5,E07000179,1,57.21,157.04,25.84,170.85 +4643,5,E07000179,2,71.06,192.07,25.84,210.12 +5295,5,E07000179,3,81.2,281.2,25.84,306.68 +5980,5,E07000179,4,89.52,449.93,25.84,490.26 +3504,6,E07000179,0,62.17,505.29,18.64,550.58 +4095,7,E07000179,1,51.68,157.04,25.84,170.85 +4790,7,E07000179,2,62.75,192.07,25.84,210.12 +5395,7,E07000179,3,68.28,281.2,25.84,306.68 +6084,7,E07000179,4,72.9,449.93,25.84,490.26 +3830,8,E07000179,0,48.71,505.29,18.64,550.58 +6764,9,E07000179,1,57.21,196.32,25.84,213.57 +7090,9,E07000179,2,71.06,240.08,25.84,262.64 +7416,9,E07000179,3,81.2,351.51,25.84,383.34 +7742,9,E07000179,4,89.52,562.41,25.84,612.82 +8068,10,E07000179,0,62.17,427.52,18.64,466.26 +245,1,E07000126,1,51.68,93.39,25.84,116.72 +571,1,E07000126,2,59.06,107.19,25.84,134.77 +897,1,E07000126,3,65.51,119.9,25.84,145.37 +1223,1,E07000126,4,71.98,133.71,25.84,159.17 +2853,2,E07000126,0,55.97,239.54,18.64,342.01 +1549,3,E07000126,1,43.36,85.94,25.84,100.81 +1875,3,E07000126,2,53.52,94.47,25.84,113.53 +2201,3,E07000126,3,58.13,105.06,25.84,124.15 +2527,3,E07000126,4,55.37,118.85,25.84,133.71 +3179,4,E07000126,0,33.16,469.54,18.64,599.44 +4380,5,E07000126,1,51.68,101.88,25.84,112.47 +4950,5,E07000126,2,59.06,125.22,25.84,136.89 +5593,5,E07000126,3,65.51,142.18,25.84,154.93 +6341,5,E07000126,4,71.98,202.69,25.84,220.72 +3505,6,E07000126,0,55.97,227.63,18.64,247.88 +4492,7,E07000126,1,43.36,101.88,25.84,112.47 +5088,7,E07000126,2,53.52,125.22,25.84,136.89 +5768,7,E07000126,3,58.13,142.18,25.84,154.93 +6392,7,E07000126,4,55.37,202.69,25.84,220.72 +3831,8,E07000126,0,33.16,227.63,18.64,247.88 +6765,9,E07000126,1,51.68,127.34,25.84,140.6 +7091,9,E07000126,2,59.06,156.51,25.84,171.11 +7417,9,E07000126,3,65.51,177.73,25.84,193.64 +7743,9,E07000126,4,71.98,253.36,25.84,275.9 +8069,10,E07000126,0,55.97,852.08,18.64,929.54 +247,1,E07000196,1,52.6,98.69,25.84,124.15 +573,1,E07000196,2,58.13,116.72,25.84,136.89 +899,1,E07000196,3,69.2,132.64,25.84,160.24 +1225,1,E07000196,4,80.28,161.3,25.84,178.28 +2855,2,E07000196,0,39.38,245.49,18.64,382.53 +1551,3,E07000196,1,46.13,88.07,25.84,97.63 +1877,3,E07000196,2,49.84,94.47,25.84,102.94 +2203,3,E07000196,3,59.98,104,25.84,119.9 +2529,3,E07000196,4,68.28,127.34,25.84,127.34 +3181,4,E07000196,0,46.63,107.26,18.64,107.26 +4298,5,E07000196,1,52.6,102.94,25.84,112.47 +4908,5,E07000196,2,58.13,125.22,25.84,136.89 +5539,5,E07000196,3,69.2,147.5,25.84,160.24 +6191,5,E07000196,4,80.28,227.08,25.84,246.18 +3507,6,E07000196,0,39.38,255.02,18.64,276.48 +4519,7,E07000196,1,46.13,102.94,25.84,112.47 +5204,7,E07000196,2,49.84,125.22,25.84,136.89 +5795,7,E07000196,3,59.98,147.5,25.84,160.24 +6456,7,E07000196,4,68.28,227.08,25.84,246.18 +3833,8,E07000196,0,46.63,255.02,18.64,276.48 +6767,9,E07000196,1,52.6,128.67,25.84,140.6 +7093,9,E07000196,2,58.13,156.51,25.84,171.11 +7419,9,E07000196,3,69.2,184.37,25.84,200.32 +7745,9,E07000196,4,80.28,283.85,25.84,307.73 +8071,10,E07000196,0,39.38,269.62,18.64,294.95 +248,1,E08000023,1,50.76,88.07,25.84,97.63 +574,1,E08000023,2,57.21,101.88,25.84,119.9 +900,1,E08000023,3,60.9,113.53,25.84,159.17 +1226,1,E08000023,4,70.13,127.34,25.84,139.02 +2856,2,E08000023,0,55.97,237.14,18.64,340.83 +1552,3,E08000023,1,42.44,99.75,25.84,105.06 +1878,3,E08000023,2,49.84,90.21,25.84,111.41 +2204,3,E08000023,3,53.52,105.06,25.84,124.15 +2530,3,E08000023,4,56.29,115.66,25.84,119.9 +3182,4,E08000023,0,47.67,253.84,18.64,288.39 +4541,5,E08000023,1,50.76,92.33,25.84,99.75 +5056,5,E08000023,2,57.21,114.6,25.84,124.15 +5561,5,E08000023,3,60.9,130.52,25.84,143.25 +6360,5,E08000023,4,70.13,170.85,25.84,185.7 +3508,6,E08000023,0,55.97,191.88,18.64,208.55 +4460,7,E08000023,1,42.44,92.33,25.84,99.75 +5107,7,E08000023,2,49.84,114.6,25.84,124.15 +5736,7,E08000023,3,53.52,130.52,25.84,143.25 +6518,7,E08000023,4,56.29,170.85,25.84,185.7 +3834,8,E08000023,0,47.67,191.88,18.64,208.55 +6768,9,E08000023,1,42.44,115.39,25.84,124.69 +7094,9,E08000023,2,57.21,143.25,25.84,155.2 +7420,9,E08000023,3,60.9,163.15,25.84,179.06 +7746,9,E08000023,4,70.13,213.57,25.84,232.15 +8072,10,E08000023,0,55.97,333.68,18.64,363.48 +249,1,E06000045,1,57.21,123.09,25.84,176.15 +575,1,E06000045,2,71.06,146.43,25.84,186.77 +901,1,E06000045,3,81.2,161.3,25.84,203.75 +1227,1,E06000045,4,89.52,178.28,25.84,221.77 +2857,2,E06000045,0,62.17,268.13,18.64,344.4 +1553,3,E06000045,1,51.68,115.66,25.84,159.17 +1879,3,E06000045,2,62.75,129.46,25.84,145.37 +2205,3,E06000045,3,68.28,149.62,25.84,185.7 +2531,3,E06000045,4,72.9,184.64,25.84,194.19 +3183,4,E06000045,0,48.71,195.45,18.64,204.96 +4029,5,E06000045,1,57.21,125.22,25.84,136.89 +4644,5,E06000045,2,71.06,170.85,25.84,185.7 +5296,5,E06000045,3,81.2,202.69,25.84,220.72 +5981,5,E06000045,4,89.52,316.23,25.84,344.88 +3509,6,E06000045,0,62.17,355.12,18.64,387.3 +4096,7,E06000045,1,51.68,125.22,25.84,136.89 +4791,7,E06000045,2,62.75,170.85,25.84,185.7 +5396,7,E06000045,3,68.28,202.69,25.84,220.72 +6085,7,E06000045,4,72.9,316.23,25.84,344.88 +3835,8,E06000045,0,48.71,355.12,18.64,387.3 +6769,9,E06000045,1,57.21,156.51,25.84,171.11 +7095,9,E06000045,2,71.06,213.57,25.84,232.15 +7421,9,E06000045,3,81.2,253.36,25.84,275.9 +7747,9,E06000045,4,89.52,395.3,25.84,431.1 +8073,10,E06000045,0,62.17,503.5,18.64,549.69 +250,1,E06000033,1,54.44,118.85,25.84,148.56 +576,1,E06000033,2,64.59,142.18,25.84,167.67 +902,1,E06000033,3,71.06,155.98,25.84,180.4 +1228,1,E06000033,4,81.2,170.85,25.84,178.28 +2858,2,E06000033,0,36.26,226.42,18.64,423.05 +1554,3,E06000033,1,49.84,99.75,25.84,131.58 +1880,3,E06000033,2,58.13,117.78,25.84,132.64 +2206,3,E06000033,3,63.67,130.52,25.84,143.25 +2532,3,E06000033,4,71.06,148.56,25.84,159.17 +3184,4,E06000033,0,55.97,135.86,18.64,318.19 +4152,5,E06000033,1,54.44,125.22,25.84,136.89 +4733,5,E06000033,2,64.59,159.17,25.84,174.02 +5452,5,E06000033,3,71.06,202.69,25.84,220.72 +6162,5,E06000033,4,81.2,270.61,25.84,295.01 +3510,6,E06000033,0,36.26,303.89,18.64,331.29 +4269,7,E06000033,1,49.84,125.22,25.84,136.89 +4995,7,E06000033,2,58.13,159.17,25.84,174.02 +5638,7,E06000033,3,63.67,202.69,25.84,220.72 +6300,7,E06000033,4,71.06,270.61,25.84,295.01 +3836,8,E06000033,0,55.97,303.89,18.64,331.29 +6770,9,E06000033,1,54.44,156.51,25.84,171.11 +7096,9,E06000033,2,64.59,198.96,25.84,217.54 +7422,9,E06000033,3,71.06,253.36,25.84,275.9 +7748,9,E06000033,4,81.2,338.25,25.84,368.76 +8074,10,E06000033,0,36.26,239.85,18.64,260.68 +251,1,E09000028,1,65.51,145.37,25.84,197.39 +577,1,E09000028,2,77.51,157.04,25.84,192.07 +903,1,E09000028,3,83.97,166.61,25.84,226.01 +1229,1,E09000028,4,101.48,186.77,25.84,251.49 +2859,2,E09000028,0,70.47,317,18.64,502.91 +1555,3,E09000028,1,58.13,118.85,25.84,146.43 +1881,3,E09000028,2,63.67,139.02,25.84,175.09 +2207,3,E09000028,3,71.06,159.17,25.84,200.55 +2533,3,E09000028,4,83.05,259.98,25.84,261.04 +3185,4,E09000028,0,60.1,371.82,18.64,402.8 +3977,5,E09000028,1,65.51,292.87,25.84,319.41 +4592,5,E09000028,2,77.51,385.2,25.84,420.23 +5244,5,E09000028,3,83.97,393.68,25.84,428.71 +5929,5,E09000028,4,101.48,535.89,25.84,583.64 +3511,6,E09000028,0,70.47,600.65,18.64,655.45 +4191,7,E09000028,1,58.13,292.87,25.84,319.41 +4692,7,E09000028,2,63.67,385.2,25.84,420.23 +5344,7,E09000028,3,71.06,393.68,25.84,428.71 +5896,7,E09000028,4,83.05,535.89,25.84,583.64 +3837,8,E09000028,0,60.1,600.65,18.64,655.45 +6771,9,E09000028,1,65.51,366.11,25.84,399.27 +7097,9,E09000028,2,77.51,481.52,25.84,525.28 +7423,9,E09000028,3,83.97,492.12,25.84,535.89 +7749,9,E09000028,4,101.48,669.87,25.84,729.54 +8075,10,E09000028,0,70.47,344.12,18.64,375.38 +252,1,E07000213,1,57.21,123.09,25.84,176.15 +578,1,E07000213,2,71.06,146.43,25.84,186.77 +904,1,E07000213,3,81.2,161.3,25.84,203.75 +1230,1,E07000213,4,89.52,178.28,25.84,221.77 +2860,2,E07000213,0,62.17,268.13,18.64,344.4 +1556,3,E07000213,1,51.68,115.66,25.84,159.17 +1882,3,E07000213,2,62.75,129.46,25.84,145.37 +2208,3,E07000213,3,68.28,149.62,25.84,185.7 +2534,3,E07000213,4,72.9,184.64,25.84,194.19 +3186,4,E07000213,0,48.71,195.45,18.64,204.96 +4030,5,E07000213,1,57.21,180.4,25.84,197.39 +4645,5,E07000213,2,71.06,214.35,25.84,234.52 +5297,5,E07000213,3,81.2,281.2,25.84,306.68 +5982,5,E07000213,4,89.52,382.01,25.84,415.98 +3512,6,E07000213,0,62.17,429.02,18.64,467.14 +4097,7,E07000213,1,51.68,180.4,25.84,197.39 +4792,7,E07000213,2,62.75,214.35,25.84,234.52 +5397,7,E07000213,3,68.28,281.2,25.84,306.68 +6086,7,E07000213,4,72.9,382.01,25.84,415.98 +3838,8,E07000213,0,48.71,429.02,18.64,467.14 +6772,9,E07000213,1,57.21,225.52,25.84,246.73 +7098,9,E07000213,2,71.06,267.95,25.84,293.15 +7424,9,E07000213,3,81.2,351.51,25.84,383.34 +7750,9,E07000213,4,89.52,477.53,25.84,519.97 +8076,10,E07000213,0,62.17,314.32,18.64,344.12 +253,1,E07000240,1,54.44,118.85,25.84,148.56 +579,1,E07000240,2,64.59,142.18,25.84,167.67 +905,1,E07000240,3,71.06,155.98,25.84,180.4 +1231,1,E07000240,4,81.2,170.85,25.84,178.28 +2861,2,E07000240,0,36.26,226.42,18.64,423.05 +1557,3,E07000240,1,49.84,99.75,25.84,131.58 +1883,3,E07000240,2,58.13,117.78,25.84,132.64 +2209,3,E07000240,3,63.67,130.52,25.84,143.25 +2535,3,E07000240,4,71.06,148.56,25.84,159.17 +3187,4,E07000240,0,55.97,135.86,18.64,318.19 +4153,5,E07000240,1,54.44,170.85,25.84,185.7 +4734,5,E07000240,2,64.59,259.98,25.84,282.26 +5453,5,E07000240,3,71.06,316.23,25.84,344.88 +6163,5,E07000240,4,81.2,583.64,25.84,635.64 +3513,6,E07000240,0,36.26,655.45,18.64,713.85 +4270,7,E07000240,1,49.84,170.85,25.84,185.7 +4996,7,E07000240,2,58.13,259.98,25.84,282.26 +5639,7,E07000240,3,63.67,316.23,25.84,344.88 +6301,7,E07000240,4,71.06,583.64,25.84,635.64 +3839,8,E07000240,0,55.97,655.45,18.64,713.85 +6773,9,E07000240,1,54.44,213.57,25.84,232.15 +7099,9,E07000240,2,64.59,324.98,25.84,352.84 +7425,9,E07000240,3,71.06,395.3,25.84,431.1 +7751,9,E07000240,4,81.2,729.54,25.84,794.53 +8077,10,E07000240,0,36.26,458.81,18.64,500.53 +255,1,E08000013,1,51.68,93.39,25.84,116.72 +581,1,E08000013,2,59.06,107.19,25.84,134.77 +907,1,E08000013,3,65.51,119.9,25.84,145.37 +1233,1,E08000013,4,71.98,133.71,25.84,159.17 +2863,2,E08000013,0,55.97,239.54,18.64,342.01 +1559,3,E08000013,1,43.36,85.94,25.84,100.81 +1885,3,E08000013,2,53.52,94.47,25.84,113.53 +2211,3,E08000013,3,58.13,105.06,25.84,124.15 +2537,3,E08000013,4,55.37,118.85,25.84,133.71 +3189,4,E08000013,0,33.16,469.54,18.64,599.44 +4381,5,E08000013,1,51.68,97.63,25.84,107.19 +4951,5,E08000013,2,59.06,111.41,25.84,120.97 +5594,5,E08000013,3,65.51,134.77,25.84,147.5 +6342,5,E08000013,4,71.98,192.07,25.84,210.12 +3515,6,E08000013,0,55.97,215.7,18.64,235.95 +4493,7,E08000013,1,43.36,97.63,25.84,107.19 +5089,7,E08000013,2,53.52,111.41,25.84,120.97 +5769,7,E08000013,3,58.13,134.77,25.84,147.5 +6393,7,E08000013,4,55.37,192.07,25.84,210.12 +3841,8,E08000013,0,33.16,215.7,18.64,235.95 +6775,9,E08000013,1,51.68,122.03,25.84,133.98 +7101,9,E08000013,2,59.06,139.27,25.84,151.21 +7427,9,E08000013,3,65.51,168.46,25.84,184.37 +7753,9,E08000013,4,71.98,240.08,25.84,262.64 +8079,10,E08000013,0,55.97,262.16,18.64,286.02 +256,1,E07000197,1,52.6,98.69,25.84,124.15 +582,1,E07000197,2,58.13,116.72,25.84,136.89 +908,1,E07000197,3,69.2,132.64,25.84,160.24 +1234,1,E07000197,4,80.28,161.3,25.84,178.28 +2864,2,E07000197,0,39.38,245.49,18.64,382.53 +1560,3,E07000197,1,46.13,88.07,25.84,97.63 +1886,3,E07000197,2,49.84,94.47,25.84,102.94 +2212,3,E07000197,3,59.98,104,25.84,119.9 +2538,3,E07000197,4,68.28,127.34,25.84,127.34 +3190,4,E07000197,0,46.63,107.26,18.64,107.26 +4299,5,E07000197,1,52.6,102.94,25.84,112.47 +4909,5,E07000197,2,58.13,125.22,25.84,136.89 +5540,5,E07000197,3,69.2,147.5,25.84,160.24 +6192,5,E07000197,4,80.28,203.75,25.84,221.77 +3516,6,E07000197,0,39.38,228.81,18.64,249.07 +4520,7,E07000197,1,46.13,102.94,25.84,112.47 +5205,7,E07000197,2,49.84,125.22,25.84,136.89 +5796,7,E07000197,3,59.98,147.5,25.84,160.24 +6457,7,E07000197,4,68.28,203.75,25.84,221.77 +3842,8,E07000197,0,46.63,228.81,18.64,249.07 +6776,9,E07000197,1,52.6,128.67,25.84,140.6 +7102,9,E07000197,2,58.13,156.51,25.84,171.11 +7428,9,E07000197,3,69.2,184.37,25.84,200.32 +7754,9,E07000197,4,80.28,254.69,25.84,277.23 +8080,10,E07000197,0,39.38,630.13,18.64,686.73 +257,1,E07000198,1,52.6,98.69,25.84,124.15 +583,1,E07000198,2,58.13,116.72,25.84,136.89 +909,1,E07000198,3,69.2,132.64,25.84,160.24 +1235,1,E07000198,4,80.28,161.3,25.84,178.28 +2865,2,E07000198,0,39.38,245.49,18.64,382.53 +1561,3,E07000198,1,46.13,88.07,25.84,97.63 +1887,3,E07000198,2,49.84,94.47,25.84,102.94 +2213,3,E07000198,3,59.98,104,25.84,119.9 +2539,3,E07000198,4,68.28,127.34,25.84,127.34 +3191,4,E07000198,0,46.63,107.26,18.64,107.26 +4300,5,E07000198,1,52.6,91.27,25.84,98.69 +4910,5,E07000198,2,58.13,109.29,25.84,118.85 +5541,5,E07000198,3,69.2,134.77,25.84,147.5 +6193,5,E07000198,4,80.28,183.59,25.84,200.55 +3517,6,E07000198,0,39.38,206.16,18.64,225.23 +4521,7,E07000198,1,46.13,91.27,25.84,98.69 +5206,7,E07000198,2,49.84,109.29,25.84,118.85 +5797,7,E07000198,3,59.98,134.77,25.84,147.5 +6458,7,E07000198,4,68.28,183.59,25.84,200.55 +3843,8,E07000198,0,46.63,206.16,18.64,225.23 +6777,9,E07000198,1,52.6,114.09,25.84,123.35 +7103,9,E07000198,2,58.13,136.63,25.84,148.56 +7429,9,E07000198,3,69.2,168.46,25.84,184.37 +7755,9,E07000198,4,80.28,229.48,25.84,250.7 +8081,10,E07000198,0,39.38,546.7,18.64,595.86 +258,1,E07000243,1,54.44,118.85,25.84,148.56 +584,1,E07000243,2,64.59,142.18,25.84,167.67 +910,1,E07000243,3,71.06,155.98,25.84,180.4 +1236,1,E07000243,4,81.2,170.85,25.84,178.28 +2866,2,E07000243,0,36.26,226.42,18.64,423.05 +1562,3,E07000243,1,49.84,99.75,25.84,131.58 +1888,3,E07000243,2,58.13,117.78,25.84,132.64 +2214,3,E07000243,3,63.67,130.52,25.84,143.25 +2540,3,E07000243,4,71.06,148.56,25.84,159.17 +3192,4,E07000243,0,55.97,135.86,18.64,318.19 +4155,5,E07000243,1,54.44,131.58,25.84,144.31 +4736,5,E07000243,2,64.59,170.85,25.84,185.7 +5455,5,E07000243,3,71.06,181.46,25.84,198.45 +6165,5,E07000243,4,81.2,292.87,25.84,319.41 +3518,6,E07000243,0,36.26,328.92,18.64,358.7 +4272,7,E07000243,1,49.84,131.58,25.84,144.31 +4998,7,E07000243,2,58.13,170.85,25.84,185.7 +5641,7,E07000243,3,63.67,181.46,25.84,198.45 +6303,7,E07000243,4,71.06,292.87,25.84,319.41 +3844,8,E07000243,0,55.97,328.92,18.64,358.7 +6778,9,E07000243,1,54.44,164.47,25.84,180.39 +7104,9,E07000243,2,64.59,213.57,25.84,232.15 +7430,9,E07000243,3,71.06,226.84,25.84,248.03 +7756,9,E07000243,4,81.2,366.11,25.84,399.27 +8082,10,E07000243,0,36.26,442.4,18.64,481.18 +259,1,E08000007,1,51.68,93.39,25.84,116.72 +585,1,E08000007,2,59.06,107.19,25.84,134.77 +911,1,E08000007,3,65.51,119.9,25.84,145.37 +1237,1,E08000007,4,71.98,133.71,25.84,159.17 +2867,2,E08000007,0,55.97,239.54,18.64,342.01 +1563,3,E08000007,1,43.36,85.94,25.84,100.81 +1889,3,E08000007,2,53.52,94.47,25.84,113.53 +2215,3,E08000007,3,58.13,105.06,25.84,124.15 +2541,3,E08000007,4,55.37,118.85,25.84,133.71 +3193,4,E08000007,0,33.16,469.54,18.64,599.44 +4382,5,E08000007,1,51.68,113.53,25.84,123.09 +4952,5,E08000007,2,59.06,134.77,25.84,147.5 +5595,5,E08000007,3,65.51,159.17,25.84,174.02 +6343,5,E08000007,4,71.98,227.08,25.84,246.18 +3519,6,E08000007,0,55.97,255.02,18.64,276.48 +4494,7,E08000007,1,43.36,113.53,25.84,123.09 +5090,7,E08000007,2,53.52,134.77,25.84,147.5 +5770,7,E08000007,3,58.13,159.17,25.84,174.02 +6394,7,E08000007,4,55.37,227.08,25.84,246.18 +3845,8,E08000007,0,33.16,255.02,18.64,276.48 +6779,9,E08000007,1,51.68,141.94,25.84,153.86 +7105,9,E08000007,2,59.06,168.46,25.84,184.37 +7431,9,E08000007,3,65.51,198.96,25.84,217.54 +7757,9,E08000007,4,71.98,283.85,25.84,307.73 +8083,10,E08000007,0,55.97,330.71,18.64,360.51 +260,1,E06000004,1,50.76,88.07,25.84,97.63 +586,1,E06000004,2,57.21,101.88,25.84,119.9 +912,1,E06000004,3,60.9,113.53,25.84,159.17 +1238,1,E06000004,4,70.13,127.34,25.84,139.02 +2868,2,E06000004,0,55.97,237.14,18.64,340.83 +1564,3,E06000004,1,42.44,99.75,25.84,105.06 +1890,3,E06000004,2,49.84,90.21,25.84,111.41 +2216,3,E06000004,3,53.52,105.06,25.84,124.15 +2542,3,E06000004,4,56.29,115.66,25.84,119.9 +3194,4,E06000004,0,47.67,253.84,18.64,288.39 +4542,5,E06000004,1,50.76,94.47,25.84,102.94 +5057,5,E06000004,2,57.21,125.22,25.84,136.89 +5562,5,E06000004,3,60.9,136.89,25.84,148.56 +6361,5,E06000004,4,70.13,192.07,25.84,210.12 +3520,6,E06000004,0,55.97,215.7,18.64,235.95 +4461,7,E06000004,1,42.44,94.47,25.84,102.94 +5108,7,E06000004,2,49.84,125.22,25.84,136.89 +5737,7,E06000004,3,53.52,136.89,25.84,148.56 +6519,7,E06000004,4,56.29,192.07,25.84,210.12 +3846,8,E06000004,0,47.67,215.7,18.64,235.95 +6780,9,E06000004,1,42.44,118.06,25.84,128.67 +7106,9,E06000004,2,57.21,156.51,25.84,171.11 +7432,9,E06000004,3,60.9,171.11,25.84,185.69 +7758,9,E06000004,4,70.13,240.08,25.84,262.64 +8084,10,E06000004,0,55.97,253.23,18.64,277.06 +261,1,E06000021,1,52.6,98.69,25.84,124.15 +587,1,E06000021,2,58.13,116.72,25.84,136.89 +913,1,E06000021,3,69.2,132.64,25.84,160.24 +1239,1,E06000021,4,80.28,161.3,25.84,178.28 +2869,2,E06000021,0,39.38,245.49,18.64,382.53 +1565,3,E06000021,1,46.13,88.07,25.84,97.63 +1891,3,E06000021,2,49.84,94.47,25.84,102.94 +2217,3,E06000021,3,59.98,104,25.84,119.9 +2543,3,E06000021,4,68.28,127.34,25.84,127.34 +3195,4,E06000021,0,46.63,107.26,18.64,107.26 +4301,5,E06000021,1,52.6,91.27,25.84,98.69 +4911,5,E06000021,2,58.13,102.94,25.84,112.47 +5542,5,E06000021,3,69.2,130.52,25.84,143.25 +6194,5,E06000021,4,80.28,180.4,25.84,196.32 +3521,6,E06000021,0,39.38,201.39,18.64,220.48 +4522,7,E06000021,1,46.13,91.27,25.84,98.69 +5207,7,E06000021,2,49.84,102.94,25.84,112.47 +5798,7,E06000021,3,59.98,130.52,25.84,143.25 +6459,7,E06000021,4,68.28,180.4,25.84,196.32 +3847,8,E06000021,0,46.63,201.39,18.64,220.48 +6781,9,E06000021,1,52.6,114.09,25.84,123.35 +7107,9,E06000021,2,58.13,128.67,25.84,140.6 +7433,9,E06000021,3,69.2,163.15,25.84,179.06 +7759,9,E06000021,4,80.28,225.52,25.84,245.4 +8085,10,E06000021,0,39.38,628.63,18.64,683.76 +262,1,E07000221,1,52.6,98.69,25.84,124.15 +588,1,E07000221,2,58.13,116.72,25.84,136.89 +914,1,E07000221,3,69.2,132.64,25.84,160.24 +1240,1,E07000221,4,80.28,161.3,25.84,178.28 +2870,2,E07000221,0,39.38,245.49,18.64,382.53 +1566,3,E07000221,1,46.13,88.07,25.84,97.63 +1892,3,E07000221,2,49.84,94.47,25.84,102.94 +2218,3,E07000221,3,59.98,104,25.84,119.9 +2544,3,E07000221,4,68.28,127.34,25.84,127.34 +3196,4,E07000221,0,46.63,107.26,18.64,107.26 +4302,5,E07000221,1,52.6,127.34,25.84,140.08 +4912,5,E07000221,2,58.13,157.04,25.84,172.97 +5543,5,E07000221,3,69.2,202.69,25.84,220.72 +6195,5,E07000221,4,80.28,336.37,25.84,367.16 +3522,6,E07000221,0,39.38,377.76,18.64,412.34 +4523,7,E07000221,1,46.13,127.34,25.84,140.08 +5208,7,E07000221,2,49.84,157.04,25.84,172.97 +5799,7,E07000221,3,59.98,202.69,25.84,220.72 +6460,7,E07000221,4,68.28,336.37,25.84,367.16 +3848,8,E07000221,0,46.63,377.76,18.64,412.34 +6782,9,E07000221,1,52.6,159.17,25.84,175.09 +7108,9,E07000221,2,58.13,196.32,25.84,216.2 +7434,9,E07000221,3,69.2,253.36,25.84,275.9 +7760,9,E07000221,4,80.28,420.48,25.84,458.95 +8086,10,E07000221,0,39.38,308.35,18.64,336.65 +263,1,E07000082,1,48.92,107.19,25.84,140.08 +589,1,E07000082,2,55.37,120.97,25.84,144.31 +915,1,E07000082,3,61.83,141.13,25.84,161.3 +1241,1,E07000082,4,71.06,158.1,25.84,194.19 +2871,2,E07000082,0,54.93,231.2,18.64,358.7 +1567,3,E07000082,1,47.06,89.13,25.84,210.12 +1893,3,E07000082,2,54.44,100.81,25.84,111.41 +2219,3,E07000082,3,61.83,109.29,25.84,126.28 +2545,3,E07000082,4,73.82,130.52,25.84,130.52 +3197,4,E07000082,0,54.93,115.59,18.64,141.81 +4222,5,E07000082,1,48.92,112.47,25.84,122.03 +4858,5,E07000082,2,55.37,147.5,25.84,160.24 +5489,5,E07000082,3,61.83,181.46,25.84,198.45 +6027,5,E07000082,4,71.06,316.23,25.84,344.88 +3523,6,E07000082,0,54.93,355.12,18.64,387.3 +3938,7,E07000082,1,47.06,112.47,25.84,122.03 +5135,7,E07000082,2,54.44,147.5,25.84,160.24 +5715,7,E07000082,3,61.83,181.46,25.84,198.45 +6427,7,E07000082,4,73.82,316.23,25.84,344.88 +3849,8,E07000082,0,54.93,355.12,18.64,387.3 +6783,9,E07000082,1,48.92,140.6,25.84,152.55 +7109,9,E07000082,2,55.37,184.37,25.84,200.32 +7435,9,E07000082,3,61.83,226.84,25.84,248.03 +7761,9,E07000082,4,71.06,395.3,25.84,431.1 +8087,10,E07000082,0,54.93,284.53,18.64,309.82 +265,1,E08000024,1,50.76,88.07,25.84,97.63 +591,1,E08000024,2,57.21,101.88,25.84,119.9 +917,1,E08000024,3,60.9,113.53,25.84,159.17 +1243,1,E08000024,4,70.13,127.34,25.84,139.02 +2873,2,E08000024,0,55.97,237.14,18.64,340.83 +1569,3,E08000024,1,42.44,99.75,25.84,105.06 +1895,3,E08000024,2,49.84,90.21,25.84,111.41 +2221,3,E08000024,3,53.52,105.06,25.84,124.15 +2547,3,E08000024,4,56.29,115.66,25.84,119.9 +3199,4,E08000024,0,47.67,253.84,18.64,288.39 +4543,5,E08000024,1,50.76,102.94,25.84,112.47 +5058,5,E08000024,2,57.21,125.22,25.84,136.89 +5563,5,E08000024,3,60.9,134.77,25.84,147.5 +6362,5,E08000024,4,70.13,180.4,25.84,197.39 +3525,6,E08000024,0,55.97,202.58,18.64,221.66 +4462,7,E08000024,1,42.44,102.94,25.84,112.47 +5109,7,E08000024,2,49.84,125.22,25.84,136.89 +5738,7,E08000024,3,53.52,134.77,25.84,147.5 +6520,7,E08000024,4,56.29,180.4,25.84,197.39 +3851,8,E08000024,0,47.67,202.58,18.64,221.66 +6785,9,E08000024,1,42.44,128.67,25.84,140.6 +7111,9,E08000024,2,57.21,156.51,25.84,171.11 +7437,9,E08000024,3,60.9,168.46,25.84,184.37 +7763,9,E08000024,4,70.13,225.52,25.84,246.73 +8089,10,E08000024,0,55.97,394.77,18.64,430.5 +266,1,E07000214,1,57.21,123.09,25.84,176.15 +592,1,E07000214,2,71.06,146.43,25.84,186.77 +918,1,E07000214,3,81.2,161.3,25.84,203.75 +1244,1,E07000214,4,89.52,178.28,25.84,221.77 +2874,2,E07000214,0,62.17,268.13,18.64,344.4 +1570,3,E07000214,1,51.68,115.66,25.84,159.17 +1896,3,E07000214,2,62.75,129.46,25.84,145.37 +2222,3,E07000214,3,68.28,149.62,25.84,185.7 +2548,3,E07000214,4,72.9,184.64,25.84,194.19 +3200,4,E07000214,0,48.71,195.45,18.64,204.96 +4031,5,E07000214,1,57.21,159.17,25.84,174.02 +4646,5,E07000214,2,71.06,209.06,25.84,228.14 +5298,5,E07000214,3,81.2,281.2,25.84,306.68 +5983,5,E07000214,4,89.52,460.54,25.84,503 +3526,6,E07000214,0,62.17,517.2,18.64,564.9 +4098,7,E07000214,1,51.68,159.17,25.84,174.02 +4793,7,E07000214,2,62.75,209.06,25.84,228.14 +5398,7,E07000214,3,68.28,281.2,25.84,306.68 +6087,7,E07000214,4,72.9,460.54,25.84,503 +3852,8,E07000214,0,48.71,517.2,18.64,564.9 +6786,9,E07000214,1,57.21,198.96,25.84,217.54 +7112,9,E07000214,2,71.06,261.31,25.84,285.19 +7438,9,E07000214,3,81.2,351.51,25.84,383.34 +7764,9,E07000214,4,89.52,575.68,25.84,628.74 +8090,10,E07000214,0,62.17,4013.13,18.64,4378.1 +267,1,E09000029,1,65.51,145.37,25.84,197.39 +593,1,E09000029,2,77.51,157.04,25.84,192.07 +919,1,E09000029,3,83.97,166.61,25.84,226.01 +1245,1,E09000029,4,101.48,186.77,25.84,251.49 +2875,2,E09000029,0,70.47,317,18.64,502.91 +1571,3,E09000029,1,58.13,118.85,25.84,146.43 +1897,3,E09000029,2,63.67,139.02,25.84,175.09 +2223,3,E09000029,3,71.06,159.17,25.84,200.55 +2549,3,E09000029,4,83.05,259.98,25.84,261.04 +3201,4,E09000029,0,60.1,371.82,18.64,402.8 +3978,5,E09000029,1,65.51,170.85,25.84,185.7 +4593,5,E09000029,2,77.51,214.35,25.84,234.52 +5245,5,E09000029,3,83.97,292.87,25.84,319.41 +5930,5,E09000029,4,101.48,472.21,25.84,514.66 +3527,6,E09000029,0,70.47,530.31,18.64,578 +4192,7,E09000029,1,58.13,170.85,25.84,185.7 +4693,7,E09000029,2,63.67,214.35,25.84,234.52 +5345,7,E09000029,3,71.06,292.87,25.84,319.41 +5897,7,E09000029,4,83.05,472.21,25.84,514.66 +3853,8,E09000029,0,60.1,530.31,18.64,578 +6787,9,E09000029,1,65.51,213.57,25.84,232.15 +7113,9,E09000029,2,77.51,267.95,25.84,293.15 +7439,9,E09000029,3,83.97,366.11,25.84,399.27 +7765,9,E09000029,4,101.48,590.27,25.84,643.34 +8091,10,E09000029,0,70.47,284.53,18.64,309.82 +268,1,E07000113,1,57.21,123.09,25.84,176.15 +594,1,E07000113,2,71.06,146.43,25.84,186.77 +920,1,E07000113,3,81.2,161.3,25.84,203.75 +1246,1,E07000113,4,89.52,178.28,25.84,221.77 +2876,2,E07000113,0,62.17,268.13,18.64,344.4 +1572,3,E07000113,1,51.68,115.66,25.84,159.17 +1898,3,E07000113,2,62.75,129.46,25.84,145.37 +2224,3,E07000113,3,68.28,149.62,25.84,185.7 +2550,3,E07000113,4,72.9,184.64,25.84,194.19 +3202,4,E07000113,0,48.71,195.45,18.64,204.96 +4032,5,E07000113,1,57.21,122.03,25.84,132.64 +4647,5,E07000113,2,71.06,147.5,25.84,160.24 +5299,5,E07000113,3,81.2,170.85,25.84,185.7 +5984,5,E07000113,4,89.52,226.01,25.84,246.18 +3528,6,E07000113,0,62.17,253.84,18.64,276.48 +4099,7,E07000113,1,51.68,122.03,25.84,132.64 +4794,7,E07000113,2,62.75,147.5,25.84,160.24 +5399,7,E07000113,3,68.28,170.85,25.84,185.7 +6088,7,E07000113,4,72.9,226.01,25.84,246.18 +3854,8,E07000113,0,48.71,253.84,18.64,276.48 +6788,9,E07000113,1,57.21,152.55,25.84,165.81 +7114,9,E07000113,2,71.06,184.37,25.84,200.32 +7440,9,E07000113,3,81.2,213.57,25.84,232.15 +7766,9,E07000113,4,89.52,282.54,25.84,307.73 +8092,10,E07000113,0,62.17,598.84,18.64,653.96 +269,1,E06000030,1,48.92,107.19,25.84,140.08 +595,1,E06000030,2,55.37,120.97,25.84,144.31 +921,1,E06000030,3,61.83,141.13,25.84,161.3 +1247,1,E06000030,4,71.06,158.1,25.84,194.19 +2877,2,E06000030,0,54.93,231.2,18.64,358.7 +1573,3,E06000030,1,47.06,89.13,25.84,210.12 +1899,3,E06000030,2,54.44,100.81,25.84,111.41 +2225,3,E06000030,3,61.83,109.29,25.84,126.28 +2551,3,E06000030,4,73.82,130.52,25.84,130.52 +3203,4,E06000030,0,54.93,115.59,18.64,141.81 +4223,5,E06000030,1,48.92,113.53,25.84,123.09 +4859,5,E06000030,2,55.37,134.77,25.84,147.5 +5490,5,E06000030,3,61.83,170.85,25.84,185.7 +6028,5,E06000030,4,71.06,237.69,25.84,258.92 +3529,6,E06000030,0,54.93,266.94,18.64,290.78 +3939,7,E06000030,1,47.06,113.53,25.84,123.09 +5136,7,E06000030,2,54.44,134.77,25.84,147.5 +5716,7,E06000030,3,61.83,170.85,25.84,185.7 +6428,7,E06000030,4,73.82,237.69,25.84,258.92 +3855,8,E06000030,0,54.93,266.94,18.64,290.78 +6789,9,E06000030,1,48.92,141.94,25.84,153.86 +7115,9,E06000030,2,55.37,168.46,25.84,184.37 +7441,9,E06000030,3,61.83,213.57,25.84,232.15 +7767,9,E06000030,4,71.06,297.12,25.84,323.65 +8093,10,E06000030,0,54.93,262.16,18.64,286.02 +270,1,E08000008,1,51.68,93.39,25.84,116.72 +596,1,E08000008,2,59.06,107.19,25.84,134.77 +922,1,E08000008,3,65.51,119.9,25.84,145.37 +1248,1,E08000008,4,71.98,133.71,25.84,159.17 +2878,2,E08000008,0,55.97,239.54,18.64,342.01 +1574,3,E08000008,1,43.36,85.94,25.84,100.81 +1900,3,E08000008,2,53.52,94.47,25.84,113.53 +2226,3,E08000008,3,58.13,105.06,25.84,124.15 +2552,3,E08000008,4,55.37,118.85,25.84,133.71 +3204,4,E08000008,0,33.16,469.54,18.64,599.44 +4383,5,E08000008,1,51.68,102.94,25.84,112.47 +4953,5,E08000008,2,59.06,113.53,25.84,123.09 +5596,5,E08000008,3,65.51,136.89,25.84,148.56 +6344,5,E08000008,4,71.98,181.46,25.84,198.45 +3530,6,E08000008,0,55.97,203.78,18.64,222.84 +4495,7,E08000008,1,43.36,102.94,25.84,112.47 +5091,7,E08000008,2,53.52,113.53,25.84,123.09 +5771,7,E08000008,3,58.13,136.89,25.84,148.56 +6395,7,E08000008,4,55.37,181.46,25.84,198.45 +3856,8,E08000008,0,33.16,203.78,18.64,222.84 +6790,9,E08000008,1,51.68,128.67,25.84,140.6 +7116,9,E08000008,2,59.06,141.94,25.84,153.86 +7442,9,E08000008,3,65.51,171.11,25.84,185.69 +7768,9,E08000008,4,71.98,226.84,25.84,248.03 +8094,10,E08000008,0,55.97,364.96,18.64,396.26 +271,1,E07000199,1,52.6,98.69,25.84,124.15 +597,1,E07000199,2,58.13,116.72,25.84,136.89 +923,1,E07000199,3,69.2,132.64,25.84,160.24 +1249,1,E07000199,4,80.28,161.3,25.84,178.28 +2879,2,E07000199,0,39.38,245.49,18.64,382.53 +1575,3,E07000199,1,46.13,88.07,25.84,97.63 +1901,3,E07000199,2,49.84,94.47,25.84,102.94 +2227,3,E07000199,3,59.98,104,25.84,119.9 +2553,3,E07000199,4,68.28,127.34,25.84,127.34 +3205,4,E07000199,0,46.63,107.26,18.64,107.26 +4303,5,E07000199,1,52.6,102.94,25.84,112.47 +4913,5,E07000199,2,58.13,125.22,25.84,136.89 +5544,5,E07000199,3,69.2,147.5,25.84,160.24 +6196,5,E07000199,4,80.28,202.69,25.84,220.72 +3531,6,E07000199,0,39.38,227.63,18.64,247.88 +4524,7,E07000199,1,46.13,102.94,25.84,112.47 +5209,7,E07000199,2,49.84,125.22,25.84,136.89 +5800,7,E07000199,3,59.98,147.5,25.84,160.24 +6461,7,E07000199,4,68.28,202.69,25.84,220.72 +3857,8,E07000199,0,46.63,227.63,18.64,247.88 +6791,9,E07000199,1,52.6,128.67,25.84,140.6 +7117,9,E07000199,2,58.13,156.51,25.84,171.11 +7443,9,E07000199,3,69.2,184.37,25.84,200.32 +7769,9,E07000199,4,80.28,253.36,25.84,275.9 +8095,10,E07000199,0,39.38,472.22,18.64,515.43 +272,1,E07000215,1,57.21,123.09,25.84,176.15 +598,1,E07000215,2,71.06,146.43,25.84,186.77 +924,1,E07000215,3,81.2,161.3,25.84,203.75 +1250,1,E07000215,4,89.52,178.28,25.84,221.77 +2880,2,E07000215,0,62.17,268.13,18.64,344.4 +1576,3,E07000215,1,51.68,115.66,25.84,159.17 +1902,3,E07000215,2,62.75,129.46,25.84,145.37 +2228,3,E07000215,3,68.28,149.62,25.84,185.7 +2554,3,E07000215,4,72.9,184.64,25.84,194.19 +3206,4,E07000215,0,48.71,195.45,18.64,204.96 +4033,5,E07000215,1,57.21,164.48,25.84,179.34 +4648,5,E07000215,2,71.06,209.06,25.84,228.14 +5300,5,E07000215,3,81.2,304.55,25.84,332.14 +5985,5,E07000215,4,89.52,662.16,25.84,721.59 +3532,6,E07000215,0,62.17,743.63,18.64,810.38 +4100,7,E07000215,1,51.68,164.48,25.84,179.34 +4795,7,E07000215,2,62.75,209.06,25.84,228.14 +5400,7,E07000215,3,68.28,304.55,25.84,332.14 +6089,7,E07000215,4,72.9,662.16,25.84,721.59 +3858,8,E07000215,0,48.71,743.63,18.64,810.38 +6792,9,E07000215,1,57.21,205.6,25.84,224.18 +7118,9,E07000215,2,71.06,261.31,25.84,285.19 +7444,9,E07000215,3,81.2,380.68,25.84,415.17 +7770,9,E07000215,4,89.52,827.71,25.84,901.98 +8096,10,E07000215,0,62.17,473.7,18.64,516.92 +274,1,E07000045,1,48.92,107.19,25.84,140.08 +600,1,E07000045,2,55.37,120.97,25.84,144.31 +926,1,E07000045,3,61.83,141.13,25.84,161.3 +1252,1,E07000045,4,71.06,158.1,25.84,194.19 +2882,2,E07000045,0,54.93,231.2,18.64,358.7 +1578,3,E07000045,1,47.06,89.13,25.84,210.12 +1904,3,E07000045,2,54.44,100.81,25.84,111.41 +2230,3,E07000045,3,61.83,109.29,25.84,126.28 +2556,3,E07000045,4,73.82,130.52,25.84,130.52 +3208,4,E07000045,0,54.93,115.59,18.64,141.81 +4225,5,E07000045,1,48.92,113.53,25.84,123.09 +4861,5,E07000045,2,55.37,147.5,25.84,160.24 +5492,5,E07000045,3,61.83,176.15,25.84,191.01 +6030,5,E07000045,4,71.06,248.31,25.84,270.61 +3534,6,E07000045,0,54.93,278.86,18.64,303.89 +3941,7,E07000045,1,47.06,113.53,25.84,123.09 +5138,7,E07000045,2,54.44,147.5,25.84,160.24 +5718,7,E07000045,3,61.83,176.15,25.84,191.01 +6430,7,E07000045,4,73.82,248.31,25.84,270.61 +3860,8,E07000045,0,54.93,278.86,18.64,303.89 +6794,9,E07000045,1,48.92,141.94,25.84,153.86 +7120,9,E07000045,2,55.37,184.37,25.84,200.32 +7446,9,E07000045,3,61.83,220.21,25.84,238.77 +7772,9,E07000045,4,71.06,310.37,25.84,338.25 +8098,10,E07000045,0,54.93,661.42,18.64,720.99 +275,1,E06000020,1,52.6,98.69,25.84,124.15 +601,1,E06000020,2,58.13,116.72,25.84,136.89 +927,1,E06000020,3,69.2,132.64,25.84,160.24 +1253,1,E06000020,4,80.28,161.3,25.84,178.28 +2883,2,E06000020,0,39.38,245.49,18.64,382.53 +1579,3,E06000020,1,46.13,88.07,25.84,97.63 +1905,3,E06000020,2,49.84,94.47,25.84,102.94 +2231,3,E06000020,3,59.98,104,25.84,119.9 +2557,3,E06000020,4,68.28,127.34,25.84,127.34 +3209,4,E06000020,0,46.63,107.26,18.64,107.26 +4304,5,E06000020,1,52.6,102.94,25.84,112.47 +4914,5,E06000020,2,58.13,125.22,25.84,136.89 +5545,5,E06000020,3,69.2,142.18,25.84,154.93 +6197,5,E06000020,4,80.28,203.75,25.84,221.77 +3535,6,E06000020,0,39.38,228.81,18.64,249.07 +4525,7,E06000020,1,46.13,102.94,25.84,112.47 +5210,7,E06000020,2,49.84,125.22,25.84,136.89 +5801,7,E06000020,3,59.98,142.18,25.84,154.93 +6462,7,E06000020,4,68.28,203.75,25.84,221.77 +3861,8,E06000020,0,46.63,228.81,18.64,249.07 +6795,9,E06000020,1,52.6,128.67,25.84,140.6 +7121,9,E06000020,2,58.13,156.51,25.84,171.11 +7447,9,E06000020,3,69.2,177.73,25.84,193.64 +7773,9,E06000020,4,80.28,254.69,25.84,277.23 +8099,10,E06000020,0,39.38,521.38,18.64,569.06 +276,1,E07000076,1,54.44,118.85,25.84,148.56 +602,1,E07000076,2,64.59,142.18,25.84,167.67 +928,1,E07000076,3,71.06,155.98,25.84,180.4 +1254,1,E07000076,4,81.2,170.85,25.84,178.28 +2884,2,E07000076,0,36.26,226.42,18.64,423.05 +1580,3,E07000076,1,49.84,99.75,25.84,131.58 +1906,3,E07000076,2,58.13,117.78,25.84,132.64 +2232,3,E07000076,3,63.67,130.52,25.84,143.25 +2558,3,E07000076,4,71.06,148.56,25.84,159.17 +3210,4,E07000076,0,55.97,135.86,18.64,318.19 +4157,5,E07000076,1,54.44,111.41,25.84,120.97 +4738,5,E07000076,2,64.59,144.31,25.84,155.98 +5457,5,E07000076,3,71.06,170.85,25.84,185.7 +6167,5,E07000076,4,81.2,226.01,25.84,245.12 +3536,6,E07000076,0,36.26,251.45,18.64,275.3 +4274,7,E07000076,1,49.84,111.41,25.84,120.97 +5000,7,E07000076,2,58.13,144.31,25.84,155.98 +5643,7,E07000076,3,63.67,170.85,25.84,185.7 +6305,7,E07000076,4,71.06,226.01,25.84,245.12 +3862,8,E07000076,0,55.97,251.45,18.64,275.3 +6796,9,E07000076,1,54.44,139.27,25.84,151.21 +7122,9,E07000076,2,64.59,180.39,25.84,194.98 +7448,9,E07000076,3,71.06,213.57,25.84,232.15 +7774,9,E07000076,4,81.2,282.54,25.84,306.4 +8100,10,E07000076,0,36.26,314.32,18.64,344.12 +277,1,E07000093,1,57.21,123.09,25.84,176.15 +603,1,E07000093,2,71.06,146.43,25.84,186.77 +929,1,E07000093,3,81.2,161.3,25.84,203.75 +1255,1,E07000093,4,89.52,178.28,25.84,221.77 +2885,2,E07000093,0,62.17,268.13,18.64,344.4 +1581,3,E07000093,1,51.68,115.66,25.84,159.17 +1907,3,E07000093,2,62.75,129.46,25.84,145.37 +2233,3,E07000093,3,68.28,149.62,25.84,185.7 +2559,3,E07000093,4,72.9,184.64,25.84,194.19 +3211,4,E07000093,0,48.71,195.45,18.64,204.96 +4034,5,E07000093,1,57.21,136.89,25.84,148.56 +4649,5,E07000093,2,71.06,180.4,25.84,197.39 +5301,5,E07000093,3,81.2,214.35,25.84,234.52 +5986,5,E07000093,4,89.52,382.01,25.84,417.04 +3537,6,E07000093,0,62.17,429.02,18.64,468.35 +4101,7,E07000093,1,51.68,136.89,25.84,148.56 +4796,7,E07000093,2,62.75,180.4,25.84,197.39 +5401,7,E07000093,3,68.28,214.35,25.84,234.52 +6090,7,E07000093,4,72.9,382.01,25.84,417.04 +3863,8,E07000093,0,48.71,429.02,18.64,468.35 +6797,9,E07000093,1,57.21,171.11,25.84,185.69 +7123,9,E07000093,2,71.06,225.52,25.84,246.73 +7449,9,E07000093,3,81.2,267.95,25.84,293.15 +7775,9,E07000093,4,89.52,477.53,25.84,521.29 +8101,10,E07000093,0,62.17,379.86,18.64,414.12 +278,1,E07000083,1,48.92,107.19,25.84,140.08 +604,1,E07000083,2,55.37,120.97,25.84,144.31 +930,1,E07000083,3,61.83,141.13,25.84,161.3 +1256,1,E07000083,4,71.06,158.1,25.84,194.19 +2886,2,E07000083,0,54.93,231.2,18.64,358.7 +1582,3,E07000083,1,47.06,89.13,25.84,210.12 +1908,3,E07000083,2,54.44,100.81,25.84,111.41 +2234,3,E07000083,3,61.83,109.29,25.84,126.28 +2560,3,E07000083,4,73.82,130.52,25.84,130.52 +3212,4,E07000083,0,54.93,115.59,18.64,141.81 +4226,5,E07000083,1,48.92,113.53,25.84,123.09 +4862,5,E07000083,2,55.37,147.5,25.84,160.24 +5493,5,E07000083,3,61.83,176.15,25.84,191.01 +6031,5,E07000083,4,71.06,316.23,25.84,344.88 +3538,6,E07000083,0,54.93,355.12,18.64,387.3 +3942,7,E07000083,1,47.06,113.53,25.84,123.09 +5139,7,E07000083,2,54.44,147.5,25.84,160.24 +5719,7,E07000083,3,61.83,176.15,25.84,191.01 +6431,7,E07000083,4,73.82,316.23,25.84,344.88 +3864,8,E07000083,0,54.93,355.12,18.64,387.3 +6798,9,E07000083,1,48.92,141.94,25.84,153.86 +7124,9,E07000083,2,55.37,184.37,25.84,200.32 +7450,9,E07000083,3,61.83,220.21,25.84,238.77 +7776,9,E07000083,4,71.06,395.3,25.84,431.1 +8102,10,E07000083,0,54.93,394.77,18.64,430.5 +279,1,E07000114,1,57.21,123.09,25.84,176.15 +605,1,E07000114,2,71.06,146.43,25.84,186.77 +931,1,E07000114,3,81.2,161.3,25.84,203.75 +1257,1,E07000114,4,89.52,178.28,25.84,221.77 +2887,2,E07000114,0,62.17,268.13,18.64,344.4 +1583,3,E07000114,1,51.68,115.66,25.84,159.17 +1909,3,E07000114,2,62.75,129.46,25.84,145.37 +2235,3,E07000114,3,68.28,149.62,25.84,185.7 +2561,3,E07000114,4,72.9,184.64,25.84,194.19 +3213,4,E07000114,0,48.71,195.45,18.64,204.96 +4035,5,E07000114,1,57.21,97.63,25.84,107.19 +4650,5,E07000114,2,71.06,131.58,25.84,144.31 +5302,5,E07000114,3,81.2,164.48,25.84,179.34 +5987,5,E07000114,4,89.52,226.01,25.84,245.12 +3539,6,E07000114,0,62.17,251.45,18.64,275.3 +4102,7,E07000114,1,51.68,97.63,25.84,107.19 +4797,7,E07000114,2,62.75,131.58,25.84,144.31 +5402,7,E07000114,3,68.28,164.48,25.84,179.34 +6091,7,E07000114,4,72.9,226.01,25.84,245.12 +3865,8,E07000114,0,48.71,251.45,18.64,275.3 +6799,9,E07000114,1,57.21,122.03,25.84,133.98 +7125,9,E07000114,2,71.06,164.47,25.84,180.39 +7451,9,E07000114,3,81.2,205.6,25.84,224.18 +7777,9,E07000114,4,89.52,282.54,25.84,306.4 +8103,10,E07000114,0,62.17,497.55,18.64,542.24 +281,1,E07000102,1,54.44,118.85,25.84,148.56 +607,1,E07000102,2,64.59,142.18,25.84,167.67 +933,1,E07000102,3,71.06,155.98,25.84,180.4 +1259,1,E07000102,4,81.2,170.85,25.84,178.28 +2889,2,E07000102,0,36.26,226.42,18.64,423.05 +1585,3,E07000102,1,49.84,99.75,25.84,131.58 +1911,3,E07000102,2,58.13,117.78,25.84,132.64 +2237,3,E07000102,3,63.67,130.52,25.84,143.25 +2563,3,E07000102,4,71.06,148.56,25.84,159.17 +3215,4,E07000102,0,55.97,135.86,18.64,318.19 +4158,5,E07000102,1,54.44,170.85,25.84,185.7 +4739,5,E07000102,2,64.59,259.98,25.84,282.26 +5458,5,E07000102,3,71.06,383.08,25.84,417.04 +6168,5,E07000102,4,81.2,561.35,25.84,611.23 +3541,6,E07000102,0,36.26,630.42,18.64,686.44 +4275,7,E07000102,1,49.84,170.85,25.84,185.7 +5001,7,E07000102,2,58.13,259.98,25.84,282.26 +5644,7,E07000102,3,63.67,383.08,25.84,417.04 +6306,7,E07000102,4,71.06,561.35,25.84,611.23 +3867,8,E07000102,0,55.97,630.42,18.64,686.44 +6801,9,E07000102,1,54.44,213.57,25.84,232.15 +7127,9,E07000102,2,64.59,324.98,25.84,352.84 +7453,9,E07000102,3,71.06,478.85,25.84,521.29 +7779,9,E07000102,4,81.2,701.69,25.84,764.03 +8105,10,E07000102,0,36.26,275.59,18.64,299.44 +282,1,E06000034,1,54.44,118.85,25.84,148.56 +608,1,E06000034,2,64.59,142.18,25.84,167.67 +934,1,E06000034,3,71.06,155.98,25.84,180.4 +1260,1,E06000034,4,81.2,170.85,25.84,178.28 +2890,2,E06000034,0,36.26,226.42,18.64,423.05 +1586,3,E06000034,1,49.84,99.75,25.84,131.58 +1912,3,E06000034,2,58.13,117.78,25.84,132.64 +2238,3,E06000034,3,63.67,130.52,25.84,143.25 +2564,3,E06000034,4,71.06,148.56,25.84,159.17 +3216,4,E06000034,0,55.97,135.86,18.64,318.19 +4159,5,E06000034,1,54.44,134.77,25.84,147.5 +4740,5,E06000034,2,64.59,170.85,25.84,185.7 +5459,5,E06000034,3,71.06,203.75,25.84,221.77 +6169,5,E06000034,4,81.2,292.87,25.84,319.41 +3542,6,E06000034,0,36.26,328.92,18.64,358.7 +4276,7,E06000034,1,49.84,134.77,25.84,147.5 +5002,7,E06000034,2,58.13,170.85,25.84,185.7 +5645,7,E06000034,3,63.67,203.75,25.84,221.77 +6307,7,E06000034,4,71.06,292.87,25.84,319.41 +3868,8,E06000034,0,55.97,328.92,18.64,358.7 +6802,9,E06000034,1,54.44,168.46,25.84,184.37 +7128,9,E06000034,2,64.59,213.57,25.84,232.15 +7454,9,E06000034,3,71.06,254.69,25.84,277.23 +7780,9,E06000034,4,81.2,366.11,25.84,399.27 +8106,10,E06000034,0,36.26,1702.69,18.64,1857.59 +283,1,E07000115,1,57.21,123.09,25.84,176.15 +609,1,E07000115,2,71.06,146.43,25.84,186.77 +935,1,E07000115,3,81.2,161.3,25.84,203.75 +1261,1,E07000115,4,89.52,178.28,25.84,221.77 +2891,2,E07000115,0,62.17,268.13,18.64,344.4 +1587,3,E07000115,1,51.68,115.66,25.84,159.17 +1913,3,E07000115,2,62.75,129.46,25.84,145.37 +2239,3,E07000115,3,68.28,149.62,25.84,185.7 +2565,3,E07000115,4,72.9,184.64,25.84,194.19 +3217,4,E07000115,0,48.71,195.45,18.64,204.96 +4037,5,E07000115,1,57.21,136.89,25.84,148.56 +4652,5,E07000115,2,71.06,180.4,25.84,197.39 +5304,5,E07000115,3,81.2,206.94,25.84,226.01 +5989,5,E07000115,4,89.52,438.24,25.84,477.53 +3543,6,E07000115,0,62.17,492.18,18.64,536.27 +4104,7,E07000115,1,51.68,136.89,25.84,148.56 +4799,7,E07000115,2,62.75,180.4,25.84,197.39 +5404,7,E07000115,3,68.28,206.94,25.84,226.01 +6093,7,E07000115,4,72.9,438.24,25.84,477.53 +3869,8,E07000115,0,48.71,492.18,18.64,536.27 +6803,9,E07000115,1,57.21,171.11,25.84,185.69 +7129,9,E07000115,2,71.06,225.52,25.84,246.73 +7455,9,E07000115,3,81.2,258.65,25.84,282.54 +7781,9,E07000115,4,89.52,547.82,25.84,596.91 +8107,10,E07000115,0,62.17,521.38,18.64,569.06 +284,1,E06000027,1,48.92,107.19,25.84,140.08 +610,1,E06000027,2,55.37,120.97,25.84,144.31 +936,1,E06000027,3,61.83,141.13,25.84,161.3 +1262,1,E06000027,4,71.06,158.1,25.84,194.19 +2892,2,E06000027,0,54.93,231.2,18.64,358.7 +1588,3,E06000027,1,47.06,89.13,25.84,210.12 +1914,3,E06000027,2,54.44,100.81,25.84,111.41 +2240,3,E06000027,3,61.83,109.29,25.84,126.28 +2566,3,E06000027,4,73.82,130.52,25.84,130.52 +3218,4,E06000027,0,54.93,115.59,18.64,141.81 +4227,5,E06000027,1,48.92,109.29,25.84,118.85 +4863,5,E06000027,2,55.37,140.08,25.84,152.81 +5494,5,E06000027,3,61.83,164.48,25.84,179.34 +6032,5,E06000027,4,71.06,217.53,25.84,237.69 +3544,6,E06000027,0,54.93,244.3,18.64,266.94 +3943,7,E06000027,1,47.06,109.29,25.84,118.85 +5140,7,E06000027,2,54.44,140.08,25.84,152.81 +5720,7,E06000027,3,61.83,164.48,25.84,179.34 +6432,7,E06000027,4,73.82,217.53,25.84,237.69 +3870,8,E06000027,0,54.93,244.3,18.64,266.94 +6804,9,E06000027,1,48.92,136.63,25.84,148.56 +7130,9,E06000027,2,55.37,175.09,25.84,191 +7456,9,E06000027,3,61.83,205.6,25.84,224.18 +7782,9,E06000027,4,71.06,271.92,25.84,297.12 +8108,10,E06000027,0,54.93,284.53,18.64,309.82 +285,1,E07000046,1,48.92,107.19,25.84,140.08 +611,1,E07000046,2,55.37,120.97,25.84,144.31 +937,1,E07000046,3,61.83,141.13,25.84,161.3 +1263,1,E07000046,4,71.06,158.1,25.84,194.19 +2893,2,E07000046,0,54.93,231.2,18.64,358.7 +1589,3,E07000046,1,47.06,89.13,25.84,210.12 +1915,3,E07000046,2,54.44,100.81,25.84,111.41 +2241,3,E07000046,3,61.83,109.29,25.84,126.28 +2567,3,E07000046,4,73.82,130.52,25.84,130.52 +3219,4,E07000046,0,54.93,115.59,18.64,141.81 +4228,5,E07000046,1,48.92,97.63,25.84,107.19 +4864,5,E07000046,2,55.37,123.09,25.84,133.71 +5495,5,E07000046,3,61.83,147.5,25.84,160.24 +6033,5,E07000046,4,71.06,192.07,25.84,210.12 +3545,6,E07000046,0,54.93,215.7,18.64,235.95 +3944,7,E07000046,1,47.06,97.63,25.84,107.19 +5141,7,E07000046,2,54.44,123.09,25.84,133.71 +5721,7,E07000046,3,61.83,147.5,25.84,160.24 +6433,7,E07000046,4,73.82,192.07,25.84,210.12 +3871,8,E07000046,0,54.93,215.7,18.64,235.95 +6805,9,E07000046,1,48.92,122.03,25.84,133.98 +7131,9,E07000046,2,55.37,153.86,25.84,167.13 +7457,9,E07000046,3,61.83,184.37,25.84,200.32 +7783,9,E07000046,4,71.06,240.08,25.84,262.64 +8109,10,E07000046,0,54.93,286.02,18.64,311.34 +286,1,E09000030,1,65.51,145.37,25.84,197.39 +612,1,E09000030,2,77.51,157.04,25.84,192.07 +938,1,E09000030,3,83.97,166.61,25.84,226.01 +1264,1,E09000030,4,101.48,186.77,25.84,251.49 +2894,2,E09000030,0,70.47,317,18.64,502.91 +1590,3,E09000030,1,58.13,118.85,25.84,146.43 +1916,3,E09000030,2,63.67,139.02,25.84,175.09 +2242,3,E09000030,3,71.06,159.17,25.84,200.55 +2568,3,E09000030,4,83.05,259.98,25.84,261.04 +3220,4,E09000030,0,60.1,371.82,18.64,402.8 +3979,5,E09000030,1,65.51,317.29,25.84,345.93 +4594,5,E09000030,2,77.51,389.45,25.84,424.47 +5246,5,E09000030,3,83.97,472.21,25.84,514.66 +5931,5,E09000030,4,101.48,535.89,25.84,583.64 +3546,6,E09000030,0,70.47,600.65,18.64,655.45 +4193,7,E09000030,1,58.13,317.29,25.84,345.93 +4694,7,E09000030,2,63.67,389.45,25.84,424.47 +5346,7,E09000030,3,71.06,472.21,25.84,514.66 +5898,7,E09000030,4,83.05,535.89,25.84,583.64 +3872,8,E09000030,0,60.1,600.65,18.64,655.45 +6806,9,E09000030,1,65.51,396.59,25.84,432.43 +7132,9,E09000030,2,77.51,486.79,25.84,530.59 +7458,9,E09000030,3,83.97,590.27,25.84,643.34 +7784,9,E09000030,4,101.48,669.87,25.84,729.54 +8110,10,E09000030,0,70.47,259.21,18.64,284.53 +287,1,E08000009,1,51.68,93.39,25.84,116.72 +613,1,E08000009,2,59.06,107.19,25.84,134.77 +939,1,E08000009,3,65.51,119.9,25.84,145.37 +1265,1,E08000009,4,71.98,133.71,25.84,159.17 +2895,2,E08000009,0,55.97,239.54,18.64,342.01 +1591,3,E08000009,1,43.36,85.94,25.84,100.81 +1917,3,E08000009,2,53.52,94.47,25.84,113.53 +2243,3,E08000009,3,58.13,105.06,25.84,124.15 +2569,3,E08000009,4,55.37,118.85,25.84,133.71 +3221,4,E08000009,0,33.16,469.54,18.64,599.44 +4384,5,E08000009,1,51.68,124.15,25.84,134.77 +4954,5,E08000009,2,59.06,157.04,25.84,172.97 +5597,5,E08000009,3,65.51,192.07,25.84,210.12 +6345,5,E08000009,4,71.98,358.66,25.84,391.56 +3547,6,E08000009,0,55.97,402.8,18.64,439.74 +4496,7,E08000009,1,43.36,124.15,25.84,134.77 +5092,7,E08000009,2,53.52,157.04,25.84,172.97 +5772,7,E08000009,3,58.13,192.07,25.84,210.12 +6396,7,E08000009,4,55.37,358.66,25.84,391.56 +3873,8,E08000009,0,33.16,402.8,18.64,439.74 +6807,9,E08000009,1,51.68,155.2,25.84,168.46 +7133,9,E08000009,2,59.06,196.32,25.84,216.2 +7459,9,E08000009,3,65.51,240.08,25.84,262.64 +7785,9,E08000009,4,71.98,448.34,25.84,489.48 +8111,10,E08000009,0,55.97,940.26,18.32,1026.78 +288,1,E07000116,1,57.21,123.09,25.84,176.15 +614,1,E07000116,2,71.06,146.43,25.84,186.77 +940,1,E07000116,3,81.2,161.3,25.84,203.75 +1266,1,E07000116,4,89.52,178.28,25.84,221.77 +2896,2,E07000116,0,62.17,268.13,18.64,344.4 +1592,3,E07000116,1,51.68,115.66,25.84,159.17 +1918,3,E07000116,2,62.75,129.46,25.84,145.37 +2244,3,E07000116,3,68.28,149.62,25.84,185.7 +2570,3,E07000116,4,72.9,184.64,25.84,194.19 +3222,4,E07000116,0,48.71,195.45,18.64,204.96 +4038,5,E07000116,1,57.21,151.75,25.84,166.61 +4653,5,E07000116,2,71.06,202.69,25.84,220.72 +5305,5,E07000116,3,81.2,281.2,25.84,306.68 +5990,5,E07000116,4,89.52,528.46,25.84,575.13 +3548,6,E07000116,0,62.17,593.49,18.64,645.92 +4105,7,E07000116,1,51.68,151.75,25.84,166.61 +4800,7,E07000116,2,62.75,202.69,25.84,220.72 +5405,7,E07000116,3,68.28,281.2,25.84,306.68 +6094,7,E07000116,4,72.9,528.46,25.84,575.13 +3874,8,E07000116,0,48.71,593.49,18.64,645.92 +6808,9,E07000116,1,57.21,189.68,25.84,208.27 +7134,9,E07000116,2,71.06,253.36,25.84,275.9 +7460,9,E07000116,3,81.2,351.51,25.84,383.34 +7786,9,E07000116,4,89.52,660.57,25.84,718.92 +8112,10,E07000116,0,62.17,275.59,18.64,299.44 +289,1,E07000077,1,54.44,118.85,25.84,148.56 +615,1,E07000077,2,64.59,142.18,25.84,167.67 +941,1,E07000077,3,71.06,155.98,25.84,180.4 +1267,1,E07000077,4,81.2,170.85,25.84,178.28 +2897,2,E07000077,0,36.26,226.42,18.64,423.05 +1593,3,E07000077,1,49.84,99.75,25.84,131.58 +1919,3,E07000077,2,58.13,117.78,25.84,132.64 +2245,3,E07000077,3,63.67,130.52,25.84,143.25 +2571,3,E07000077,4,71.06,148.56,25.84,159.17 +3223,4,E07000077,0,55.97,135.86,18.64,318.19 +4160,5,E07000077,1,54.44,134.77,25.84,147.5 +4741,5,E07000077,2,64.59,176.15,25.84,191.01 +5460,5,E07000077,3,71.06,219.66,25.84,239.83 +6170,5,E07000077,4,81.2,393.68,25.84,428.71 +3549,6,E07000077,0,36.26,442.13,18.64,481.46 +4277,7,E07000077,1,49.84,134.77,25.84,147.5 +5003,7,E07000077,2,58.13,176.15,25.84,191.01 +5646,7,E07000077,3,63.67,219.66,25.84,239.83 +6308,7,E07000077,4,71.06,393.68,25.84,428.71 +3875,8,E07000077,0,55.97,442.13,18.64,481.46 +6809,9,E07000077,1,54.44,168.46,25.84,184.37 +7135,9,E07000077,2,64.59,220.21,25.84,238.77 +7461,9,E07000077,3,71.06,274.57,25.84,299.78 +7787,9,E07000077,4,81.2,492.12,25.84,535.89 +8113,10,E07000077,0,36.26,580.96,18.64,633.1 +290,1,E07000180,1,57.21,123.09,25.84,176.15 +616,1,E07000180,2,71.06,146.43,25.84,186.77 +942,1,E07000180,3,81.2,161.3,25.84,203.75 +1268,1,E07000180,4,89.52,178.28,25.84,221.77 +2898,2,E07000180,0,62.17,268.13,18.64,344.4 +1594,3,E07000180,1,51.68,115.66,25.84,159.17 +1920,3,E07000180,2,62.75,129.46,25.84,145.37 +2246,3,E07000180,3,68.28,149.62,25.84,185.7 +2572,3,E07000180,4,72.9,184.64,25.84,194.19 +3224,4,E07000180,0,48.71,195.45,18.64,204.96 +4039,5,E07000180,1,57.21,159.17,25.84,174.02 +4654,5,E07000180,2,71.06,192.07,25.84,210.12 +5306,5,E07000180,3,81.2,237.69,25.84,258.92 +5991,5,E07000180,4,89.52,393.68,25.84,428.71 +3550,6,E07000180,0,62.17,442.13,18.64,481.46 +4106,7,E07000180,1,51.68,159.17,25.84,174.02 +4801,7,E07000180,2,62.75,192.07,25.84,210.12 +5406,7,E07000180,3,68.28,237.69,25.84,258.92 +6095,7,E07000180,4,72.9,393.68,25.84,428.71 +3876,8,E07000180,0,48.71,442.13,18.64,481.46 +6810,9,E07000180,1,57.21,198.96,25.84,217.54 +7136,9,E07000180,2,71.06,240.08,25.84,262.64 +7462,9,E07000180,3,81.2,297.12,25.84,323.65 +7788,9,E07000180,4,89.52,492.12,25.84,535.89 +8114,10,E07000180,0,62.17,394.77,18.64,430.5 +291,1,E08000036,1,50.76,91.27,25.84,113.53 +617,1,E08000036,2,58.13,108.24,25.84,140.08 +943,1,E08000036,3,62.75,119.9,25.84,161.3 +1269,1,E08000036,4,72.9,144.31,25.84,178.28 +2899,2,E08000036,0,52.86,234.75,18.64,322.95 +1595,3,E08000036,1,46.13,81.71,25.84,92.33 +1921,3,E08000036,2,52.6,112.47,25.84,144.31 +2247,3,E08000036,3,56.29,104,25.84,113.53 +2573,3,E08000036,4,63.67,120.97,25.84,175.09 +3225,4,E08000036,0,51.82,160.88,18.64,190.67 +4409,5,E08000036,1,50.76,109.29,25.84,118.85 +4889,5,E08000036,2,58.13,125.22,25.84,136.89 +5520,5,E08000036,3,62.75,136.89,25.84,148.56 +6125,5,E08000036,4,72.9,192.07,25.84,210.12 +3551,6,E08000036,0,52.86,215.7,18.64,235.95 +4563,7,E08000036,1,46.13,109.29,25.84,118.85 +4831,7,E08000036,2,52.6,125.22,25.84,136.89 +5867,7,E08000036,3,56.29,136.89,25.84,148.56 +6223,7,E08000036,4,63.67,192.07,25.84,210.12 +3877,8,E08000036,0,51.82,215.7,18.64,235.95 +6811,9,E08000036,1,50.76,136.63,25.84,148.56 +7137,9,E08000036,2,52.6,156.51,25.84,171.11 +7463,9,E08000036,3,62.75,171.11,25.84,185.69 +7789,9,E08000036,4,72.9,240.08,25.84,262.64 +8115,10,E08000036,0,52.86,631.61,18.64,688.24 +292,1,E08000030,1,52.6,98.69,25.84,124.15 +618,1,E08000030,2,58.13,116.72,25.84,136.89 +944,1,E08000030,3,69.2,132.64,25.84,160.24 +1270,1,E08000030,4,80.28,161.3,25.84,178.28 +2900,2,E08000030,0,39.38,245.49,18.64,382.53 +1596,3,E08000030,1,46.13,88.07,25.84,97.63 +1922,3,E08000030,2,49.84,94.47,25.84,102.94 +2248,3,E08000030,3,59.98,104,25.84,119.9 +2574,3,E08000030,4,68.28,127.34,25.84,127.34 +3226,4,E08000030,0,46.63,107.26,18.64,107.26 +4305,5,E08000030,1,52.6,97.63,25.84,107.19 +4915,5,E08000030,2,58.13,119.9,25.84,130.52 +5546,5,E08000030,3,69.2,130.52,25.84,143.25 +6198,5,E08000030,4,80.28,192.07,25.84,210.12 +3552,6,E08000030,0,39.38,215.7,18.64,235.95 +4526,7,E08000030,1,46.13,97.63,25.84,107.19 +5211,7,E08000030,2,49.84,119.9,25.84,130.52 +5802,7,E08000030,3,59.98,130.52,25.84,143.25 +6463,7,E08000030,4,68.28,192.07,25.84,210.12 +3878,8,E08000030,0,46.63,215.7,18.64,235.95 +6812,9,E08000030,1,52.6,122.03,25.84,133.98 +7138,9,E08000030,2,58.13,149.9,25.84,163.15 +7464,9,E08000030,3,69.2,163.15,25.84,179.06 +7790,9,E08000030,4,80.28,240.08,25.84,262.64 +8116,10,E08000030,0,39.38,300.91,18.64,329.21 +293,1,E09000031,1,65.51,145.37,25.84,197.39 +619,1,E09000031,2,77.51,157.04,25.84,192.07 +945,1,E09000031,3,83.97,166.61,25.84,226.01 +1271,1,E09000031,4,101.48,186.77,25.84,251.49 +2901,2,E09000031,0,70.47,317,18.64,502.91 +1597,3,E09000031,1,58.13,118.85,25.84,146.43 +1923,3,E09000031,2,63.67,139.02,25.84,175.09 +2249,3,E09000031,3,71.06,159.17,25.84,200.55 +2575,3,E09000031,4,83.05,259.98,25.84,261.04 +3227,4,E09000031,0,60.1,371.82,18.64,402.8 +3980,5,E09000031,1,65.51,186.77,25.84,203.75 +4595,5,E09000031,2,77.51,237.69,25.84,258.92 +5247,5,E09000031,3,83.97,292.87,25.84,319.41 +5932,5,E09000031,4,101.48,356.55,25.84,388.39 +3553,6,E09000031,0,70.47,399.22,18.64,436.17 +4194,7,E09000031,1,58.13,186.77,25.84,203.75 +4695,7,E09000031,2,63.67,237.69,25.84,258.92 +5347,7,E09000031,3,71.06,292.87,25.84,319.41 +5899,7,E09000031,4,83.05,356.55,25.84,388.39 +3879,8,E09000031,0,60.1,399.22,18.64,436.17 +6813,9,E09000031,1,65.51,233.46,25.84,254.69 +7139,9,E09000031,2,77.51,297.12,25.84,323.65 +7465,9,E09000031,3,83.97,366.11,25.84,399.27 +7791,9,E09000031,4,101.48,445.68,25.84,485.5 +8117,10,E09000031,0,70.47,583.94,18.64,636.07 +294,1,E09000032,1,65.51,145.37,25.84,197.39 +620,1,E09000032,2,77.51,157.04,25.84,192.07 +946,1,E09000032,3,83.97,166.61,25.84,226.01 +1272,1,E09000032,4,101.48,186.77,25.84,251.49 +2902,2,E09000032,0,70.47,317,18.64,502.91 +1598,3,E09000032,1,58.13,118.85,25.84,146.43 +1924,3,E09000032,2,63.67,139.02,25.84,175.09 +2250,3,E09000032,3,71.06,159.17,25.84,200.55 +2576,3,E09000032,4,83.05,259.98,25.84,261.04 +3228,4,E09000032,0,60.1,371.82,18.64,402.8 +3981,5,E09000032,1,65.51,292.87,25.84,319.41 +4596,5,E09000032,2,77.51,365.04,25.84,397.93 +5248,5,E09000032,3,83.97,453.12,25.84,494.49 +5933,5,E09000032,4,101.48,670.66,25.84,732.19 +3554,6,E09000032,0,70.47,753.18,18.64,822.3 +4195,7,E09000032,1,58.13,292.87,25.84,319.41 +4696,7,E09000032,2,63.67,365.04,25.84,397.93 +5348,7,E09000032,3,71.06,453.12,25.84,494.49 +5900,7,E09000032,4,83.05,670.66,25.84,732.19 +3880,8,E09000032,0,60.1,753.18,18.64,822.3 +6814,9,E09000032,1,65.51,366.11,25.84,399.27 +7140,9,E09000032,2,77.51,456.3,25.84,497.43 +7466,9,E09000032,3,83.97,566.39,25.84,618.12 +7792,9,E09000032,4,101.48,838.3,25.84,915.25 +8118,10,E09000032,0,70.47,631.61,18.64,688.24 +295,1,E06000007,1,51.68,93.39,25.84,116.72 +621,1,E06000007,2,59.06,107.19,25.84,134.77 +947,1,E06000007,3,65.51,119.9,25.84,145.37 +1273,1,E06000007,4,71.98,133.71,25.84,159.17 +2903,2,E06000007,0,55.97,239.54,18.64,342.01 +1599,3,E06000007,1,43.36,85.94,25.84,100.81 +1925,3,E06000007,2,53.52,94.47,25.84,113.53 +2251,3,E06000007,3,58.13,105.06,25.84,124.15 +2577,3,E06000007,4,55.37,118.85,25.84,133.71 +3229,4,E06000007,0,33.16,469.54,18.64,599.44 +4385,5,E06000007,1,51.68,102.94,25.84,112.47 +4955,5,E06000007,2,59.06,125.22,25.84,136.89 +5598,5,E06000007,3,65.51,153.86,25.84,167.67 +6346,5,E06000007,4,71.98,214.35,25.84,234.52 +3555,6,E06000007,0,55.97,240.72,18.64,263.37 +4497,7,E06000007,1,43.36,102.94,25.84,112.47 +5093,7,E06000007,2,53.52,125.22,25.84,136.89 +5773,7,E06000007,3,58.13,153.86,25.84,167.67 +6397,7,E06000007,4,55.37,214.35,25.84,234.52 +3881,8,E06000007,0,33.16,240.72,18.64,263.37 +6815,9,E06000007,1,51.68,128.67,25.84,140.6 +7141,9,E06000007,2,59.06,156.51,25.84,171.11 +7467,9,E06000007,3,65.51,192.33,25.84,209.57 +7793,9,E06000007,4,71.98,267.95,25.84,293.15 +8119,10,E06000007,0,55.97,756.74,18.64,825.27 +296,1,E07000222,1,52.6,98.69,25.84,124.15 +622,1,E07000222,2,58.13,116.72,25.84,136.89 +948,1,E07000222,3,69.2,132.64,25.84,160.24 +1274,1,E07000222,4,80.28,161.3,25.84,178.28 +2904,2,E07000222,0,39.38,245.49,18.64,382.53 +1600,3,E07000222,1,46.13,88.07,25.84,97.63 +1926,3,E07000222,2,49.84,94.47,25.84,102.94 +2252,3,E07000222,3,59.98,104,25.84,119.9 +2578,3,E07000222,4,68.28,127.34,25.84,127.34 +3230,4,E07000222,0,46.63,107.26,18.64,107.26 +4306,5,E07000222,1,52.6,130.52,25.84,143.25 +4916,5,E07000222,2,58.13,164.48,25.84,179.34 +5547,5,E07000222,3,69.2,192.07,25.84,210.12 +6199,5,E07000222,4,80.28,337.44,25.84,368.22 +3556,6,E07000222,0,39.38,378.95,18.64,413.53 +4527,7,E07000222,1,46.13,130.52,25.84,143.25 +5212,7,E07000222,2,49.84,164.48,25.84,179.34 +5803,7,E07000222,3,59.98,192.07,25.84,210.12 +6464,7,E07000222,4,68.28,337.44,25.84,368.22 +3882,8,E07000222,0,46.63,378.95,18.64,413.53 +6816,9,E07000222,1,52.6,163.15,25.84,179.06 +7142,9,E07000222,2,58.13,205.6,25.84,224.18 +7468,9,E07000222,3,69.2,240.08,25.84,262.64 +7794,9,E07000222,4,80.28,421.8,25.84,460.26 +8120,10,E07000222,0,39.38,792.49,18.64,863.99 +297,1,E07000103,1,54.44,118.85,25.84,148.56 +623,1,E07000103,2,64.59,142.18,25.84,167.67 +949,1,E07000103,3,71.06,155.98,25.84,180.4 +1275,1,E07000103,4,81.2,170.85,25.84,178.28 +2905,2,E07000103,0,36.26,226.42,18.64,423.05 +1601,3,E07000103,1,49.84,99.75,25.84,131.58 +1927,3,E07000103,2,58.13,117.78,25.84,132.64 +2253,3,E07000103,3,63.67,130.52,25.84,143.25 +2579,3,E07000103,4,71.06,148.56,25.84,159.17 +3231,4,E07000103,0,55.97,135.86,18.64,318.19 +4161,5,E07000103,1,54.44,170.85,25.84,185.7 +4742,5,E07000103,2,64.59,227.08,25.84,246.18 +5461,5,E07000103,3,71.06,281.2,25.84,306.68 +6171,5,E07000103,4,81.2,561.35,25.84,611.23 +3557,6,E07000103,0,36.26,630.42,18.64,686.44 +4278,7,E07000103,1,49.84,170.85,25.84,185.7 +5004,7,E07000103,2,58.13,227.08,25.84,246.18 +5647,7,E07000103,3,63.67,281.2,25.84,306.68 +6309,7,E07000103,4,71.06,561.35,25.84,611.23 +3883,8,E07000103,0,55.97,630.42,18.64,686.44 +6817,9,E07000103,1,54.44,213.57,25.84,232.15 +7143,9,E07000103,2,64.59,283.85,25.84,307.73 +7469,9,E07000103,3,71.06,351.51,25.84,383.34 +7795,9,E07000103,4,81.2,701.69,25.84,764.03 +8121,10,E07000103,0,36.26,333.68,18.64,363.48 +299,1,E07000216,1,57.21,123.09,25.84,176.15 +625,1,E07000216,2,71.06,146.43,25.84,186.77 +951,1,E07000216,3,81.2,161.3,25.84,203.75 +1277,1,E07000216,4,89.52,178.28,25.84,221.77 +2907,2,E07000216,0,62.17,268.13,18.64,344.4 +1603,3,E07000216,1,51.68,115.66,25.84,159.17 +1929,3,E07000216,2,62.75,129.46,25.84,145.37 +2255,3,E07000216,3,68.28,149.62,25.84,185.7 +2581,3,E07000216,4,72.9,184.64,25.84,194.19 +3233,4,E07000216,0,48.71,195.45,18.64,204.96 +4040,5,E07000216,1,57.21,174.02,25.84,188.88 +4655,5,E07000216,2,71.06,223.9,25.84,245.12 +5307,5,E07000216,3,81.2,304.55,25.84,332.14 +5992,5,E07000216,4,89.52,561.35,25.84,611.23 +3559,6,E07000216,0,62.17,630.42,18.64,686.44 +4107,7,E07000216,1,51.68,174.02,25.84,188.88 +4802,7,E07000216,2,62.75,223.9,25.84,245.12 +5407,7,E07000216,3,68.28,304.55,25.84,332.14 +6096,7,E07000216,4,72.9,561.35,25.84,611.23 +3885,8,E07000216,0,48.71,630.42,18.64,686.44 +6819,9,E07000216,1,57.21,217.54,25.84,236.12 +7145,9,E07000216,2,71.06,279.88,25.84,306.4 +7471,9,E07000216,3,81.2,380.68,25.84,415.17 +7797,9,E07000216,4,89.52,701.69,25.84,764.03 +8123,10,E07000216,0,62.17,394.77,18.64,430.5 +300,1,E07000065,1,57.21,123.09,25.84,176.15 +626,1,E07000065,2,71.06,146.43,25.84,186.77 +952,1,E07000065,3,81.2,161.3,25.84,203.75 +1278,1,E07000065,4,89.52,178.28,25.84,221.77 +2908,2,E07000065,0,62.17,268.13,18.64,344.4 +1604,3,E07000065,1,51.68,115.66,25.84,159.17 +1930,3,E07000065,2,62.75,129.46,25.84,145.37 +2256,3,E07000065,3,68.28,149.62,25.84,185.7 +2582,3,E07000065,4,72.9,184.64,25.84,194.19 +3234,4,E07000065,0,48.71,195.45,18.64,204.96 +4041,5,E07000065,1,57.21,134.77,25.84,147.5 +4656,5,E07000065,2,71.06,176.15,25.84,191.01 +5308,5,E07000065,3,81.2,209.06,25.84,228.14 +5993,5,E07000065,4,89.52,377.78,25.84,411.74 +3560,6,E07000065,0,62.17,424.25,18.64,462.37 +4108,7,E07000065,1,51.68,134.77,25.84,147.5 +4803,7,E07000065,2,62.75,176.15,25.84,191.01 +5408,7,E07000065,3,68.28,209.06,25.84,228.14 +6097,7,E07000065,4,72.9,377.78,25.84,411.74 +3886,8,E07000065,0,48.71,424.25,18.64,462.37 +6820,9,E07000065,1,57.21,168.46,25.84,184.37 +7146,9,E07000065,2,71.06,220.21,25.84,238.77 +7472,9,E07000065,3,81.2,261.31,25.84,285.19 +7798,9,E07000065,4,89.52,472.22,25.84,514.66 +8124,10,E07000065,0,62.17,262.16,18.64,286.02 +302,1,E07000241,1,54.44,118.85,25.84,148.56 +628,1,E07000241,2,64.59,142.18,25.84,167.67 +954,1,E07000241,3,71.06,155.98,25.84,180.4 +1280,1,E07000241,4,81.2,170.85,25.84,178.28 +2910,2,E07000241,0,36.26,226.42,18.64,423.05 +1606,3,E07000241,1,49.84,99.75,25.84,131.58 +1932,3,E07000241,2,58.13,117.78,25.84,132.64 +2258,3,E07000241,3,63.67,130.52,25.84,143.25 +2584,3,E07000241,4,71.06,148.56,25.84,159.17 +3236,4,E07000241,0,55.97,135.86,18.64,318.19 +4163,5,E07000241,1,54.44,153.86,25.84,168.73 +4744,5,E07000241,2,64.59,192.07,25.84,210.12 +5463,5,E07000241,3,71.06,270.61,25.84,295.01 +6173,5,E07000241,4,81.2,404.3,25.84,440.37 +3562,6,E07000241,0,36.26,454.05,18.64,494.54 +4280,7,E07000241,1,49.84,153.86,25.84,168.73 +5006,7,E07000241,2,58.13,192.07,25.84,210.12 +5649,7,E07000241,3,63.67,270.61,25.84,295.01 +6311,7,E07000241,4,71.06,404.3,25.84,440.37 +3888,8,E07000241,0,55.97,454.05,18.64,494.54 +6822,9,E07000241,1,54.44,192.33,25.84,210.91 +7148,9,E07000241,2,64.59,240.08,25.84,262.64 +7474,9,E07000241,3,71.06,338.25,25.84,368.76 +7800,9,E07000241,4,81.2,505.39,25.84,550.49 +8126,10,E07000241,0,36.26,694.16,18.64,756.74 +303,1,E06000037,1,57.21,123.09,25.84,176.15 +629,1,E06000037,2,71.06,146.43,25.84,186.77 +955,1,E06000037,3,81.2,161.3,25.84,203.75 +1281,1,E06000037,4,89.52,178.28,25.84,221.77 +2911,2,E06000037,0,62.17,268.13,18.64,344.4 +1607,3,E06000037,1,51.68,115.66,25.84,159.17 +1933,3,E06000037,2,62.75,129.46,25.84,145.37 +2259,3,E06000037,3,68.28,149.62,25.84,185.7 +2585,3,E06000037,4,72.9,184.64,25.84,194.19 +3237,4,E06000037,0,48.71,195.45,18.64,204.96 +4042,5,E06000037,1,57.21,142.18,25.84,154.93 +4657,5,E06000037,2,71.06,180.4,25.84,197.39 +5309,5,E06000037,3,81.2,214.35,25.84,234.52 +5994,5,E06000037,4,89.52,393.68,25.84,428.71 +3563,6,E06000037,0,62.17,442.13,18.64,481.46 +4109,7,E06000037,1,51.68,142.18,25.84,154.93 +4804,7,E06000037,2,62.75,180.4,25.84,197.39 +5409,7,E06000037,3,68.28,214.35,25.84,234.52 +6098,7,E06000037,4,72.9,393.68,25.84,428.71 +3889,8,E06000037,0,48.71,442.13,18.64,481.46 +6823,9,E06000037,1,57.21,177.73,25.84,193.64 +7149,9,E06000037,2,71.06,225.52,25.84,246.73 +7475,9,E06000037,3,81.2,267.95,25.84,293.15 +7801,9,E06000037,4,89.52,492.12,25.84,535.89 +8127,10,E06000037,0,62.17,505.01,18.64,551.18 +304,1,E07000047,1,48.92,107.19,25.84,140.08 +630,1,E07000047,2,55.37,120.97,25.84,144.31 +956,1,E07000047,3,61.83,141.13,25.84,161.3 +1282,1,E07000047,4,71.06,158.1,25.84,194.19 +2912,2,E07000047,0,54.93,231.2,18.64,358.7 +1608,3,E07000047,1,47.06,89.13,25.84,210.12 +1934,3,E07000047,2,54.44,100.81,25.84,111.41 +2260,3,E07000047,3,61.83,109.29,25.84,126.28 +2586,3,E07000047,4,73.82,130.52,25.84,130.52 +3238,4,E07000047,0,54.93,115.59,18.64,141.81 +4229,5,E07000047,1,48.92,102.94,25.84,112.47 +4865,5,E07000047,2,55.37,127.34,25.84,140.08 +5496,5,E07000047,3,61.83,158.1,25.84,172.97 +6034,5,E07000047,4,71.06,219.66,25.84,239.83 +3564,6,E07000047,0,54.93,246.68,18.64,269.32 +3945,7,E07000047,1,47.06,102.94,25.84,112.47 +5142,7,E07000047,2,54.44,127.34,25.84,140.08 +5722,7,E07000047,3,61.83,158.1,25.84,172.97 +6434,7,E07000047,4,73.82,219.66,25.84,239.83 +3890,8,E07000047,0,54.93,246.68,18.64,269.32 +6824,9,E07000047,1,48.92,128.67,25.84,140.6 +7150,9,E07000047,2,55.37,159.17,25.84,175.09 +7476,9,E07000047,3,61.83,197.62,25.84,216.2 +7802,9,E07000047,4,71.06,274.57,25.84,299.78 +8128,10,E07000047,0,54.93,248.76,18.64,269.62 +306,1,E07000127,1,51.68,93.39,25.84,116.72 +632,1,E07000127,2,59.06,107.19,25.84,134.77 +958,1,E07000127,3,65.51,119.9,25.84,145.37 +1284,1,E07000127,4,71.98,133.71,25.84,159.17 +2914,2,E07000127,0,55.97,239.54,18.64,342.01 +1610,3,E07000127,1,43.36,85.94,25.84,100.81 +1936,3,E07000127,2,53.52,94.47,25.84,113.53 +2262,3,E07000127,3,58.13,105.06,25.84,124.15 +2588,3,E07000127,4,55.37,118.85,25.84,133.71 +3240,4,E07000127,0,33.16,469.54,18.64,599.44 +4386,5,E07000127,1,51.68,102.94,25.84,112.47 +4956,5,E07000127,2,59.06,134.77,25.84,147.5 +5599,5,E07000127,3,65.51,147.5,25.84,160.24 +6347,5,E07000127,4,71.98,214.35,25.84,234.52 +3566,6,E07000127,0,55.97,240.72,18.64,263.37 +4498,7,E07000127,1,43.36,102.94,25.84,112.47 +5094,7,E07000127,2,53.52,134.77,25.84,147.5 +5774,7,E07000127,3,58.13,147.5,25.84,160.24 +6398,7,E07000127,4,55.37,214.35,25.84,234.52 +3892,8,E07000127,0,33.16,240.72,18.64,263.37 +6826,9,E07000127,1,51.68,128.67,25.84,140.6 +7152,9,E07000127,2,59.06,168.46,25.84,184.37 +7478,9,E07000127,3,65.51,184.37,25.84,200.32 +7804,9,E07000127,4,71.98,267.95,25.84,293.15 +8130,10,E07000127,0,55.97,269.62,18.64,294.95 +307,1,E07000142,1,51.68,99.75,25.84,122.03 +633,1,E07000142,2,61.83,114.6,25.84,129.46 +959,1,E07000142,3,68.28,126.28,25.84,137.95 +1285,1,E07000142,4,75.67,158.1,25.84,166.61 +2915,2,E07000142,0,51.82,240.72,18.64,361.1 +1611,3,E07000142,1,46.13,90.21,25.84,107.19 +1937,3,E07000142,2,52.6,96.56,25.84,108.24 +2263,3,E07000142,3,58.13,104,25.84,118.85 +2589,3,E07000142,4,63.67,122.03,25.84,122.03 +3241,4,E07000142,0,49.74,114.39,18.64,123.94 +4350,5,E07000142,1,51.68,84.89,25.84,92.33 +5046,5,E07000142,2,61.83,109.29,25.84,118.85 +5689,5,E07000142,3,68.28,129.46,25.84,142.18 +6264,5,E07000142,4,75.67,192.07,25.84,210.12 +3567,6,E07000142,0,51.82,215.7,18.64,235.95 +4450,7,E07000142,1,46.13,84.89,25.84,92.33 +5186,7,E07000142,2,52.6,109.29,25.84,118.85 +5847,7,E07000142,3,58.13,129.46,25.84,142.18 +6508,7,E07000142,4,63.67,192.07,25.84,210.12 +3893,8,E07000142,0,49.74,215.7,18.64,235.95 +6827,9,E07000142,1,51.68,106.13,25.84,115.39 +7153,9,E07000142,2,61.83,136.63,25.84,148.56 +7479,9,E07000142,3,68.28,161.83,25.84,177.73 +7805,9,E07000142,4,75.67,240.08,25.84,262.64 +8131,10,E07000142,0,51.82,239.85,18.64,260.68 +243,1,E06000062,1,51.68,99.75,25.84,122.03 +569,1,E06000062,2,61.83,114.6,25.84,129.46 +895,1,E06000062,3,68.28,126.28,25.84,137.95 +1221,1,E06000062,4,75.67,158.1,25.84,166.61 +2851,2,E06000062,0,51.82,240.72,18.64,361.1 +1547,3,E06000062,1,46.13,90.21,25.84,107.19 +1873,3,E06000062,2,52.6,96.56,25.84,108.24 +2199,3,E06000062,3,58.13,104,25.84,118.85 +2525,3,E06000062,4,63.67,122.03,25.84,122.03 +3177,4,E06000062,0,49.74,114.39,18.64,123.94 +4348,5,E06000062,1,51.68,125.22,25.84,136.89 +5044,5,E06000062,2,61.83,153.86,25.84,168.73 +5687,5,E06000062,3,68.28,184.64,25.84,201.61 +6262,5,E06000062,4,75.67,292.87,25.84,319.41 +3503,6,E06000062,0,51.82,328.92,18.64,358.7 +4448,7,E06000062,1,46.13,125.22,25.84,136.89 +5184,7,E06000062,2,52.6,153.86,25.84,168.73 +5845,7,E06000062,3,58.13,184.64,25.84,201.61 +6506,7,E06000062,4,63.67,292.87,25.84,319.41 +3829,8,E06000062,0,49.74,328.92,18.64,358.7 +6763,9,E06000062,1,51.68,156.51,25.84,171.11 +7089,9,E06000062,2,61.83,192.33,25.84,210.91 +7415,9,E06000062,3,68.28,230.81,25.84,252.02 +7741,9,E06000062,4,75.67,366.11,25.84,399.27 +8067,10,E06000062,0,51.82,254.72,18.64,278.57 +308,1,E07000181,1,57.21,123.09,25.84,176.15 +634,1,E07000181,2,71.06,146.43,25.84,186.77 +960,1,E07000181,3,81.2,161.3,25.84,203.75 +1286,1,E07000181,4,89.52,178.28,25.84,221.77 +2916,2,E07000181,0,62.17,268.13,18.64,344.4 +1612,3,E07000181,1,51.68,115.66,25.84,159.17 +1938,3,E07000181,2,62.75,129.46,25.84,145.37 +2264,3,E07000181,3,68.28,149.62,25.84,185.7 +2590,3,E07000181,4,72.9,184.64,25.84,194.19 +3242,4,E07000181,0,48.71,195.45,18.64,204.96 +4043,5,E07000181,1,57.21,147.5,25.84,160.24 +4658,5,E07000181,2,71.06,181.46,25.84,198.45 +5310,5,E07000181,3,81.2,226.01,25.84,245.12 +5995,5,E07000181,4,89.52,399,25.84,436.13 +3568,6,E07000181,0,62.17,448.09,18.64,489.79 +4110,7,E07000181,1,51.68,147.5,25.84,160.24 +4805,7,E07000181,2,62.75,181.46,25.84,198.45 +5410,7,E07000181,3,68.28,226.01,25.84,245.12 +6099,7,E07000181,4,72.9,399,25.84,436.13 +3894,8,E07000181,0,48.71,448.09,18.64,489.79 +6828,9,E07000181,1,57.21,184.37,25.84,200.32 +7154,9,E07000181,2,71.06,226.84,25.84,248.03 +7480,9,E07000181,3,81.2,282.54,25.84,306.4 +7806,9,E07000181,4,89.52,498.75,25.84,545.17 +8132,10,E07000181,0,62.17,239.85,18.64,260.68 +254,1,E07000245,1,54.44,118.85,25.84,148.56 +580,1,E07000245,2,64.59,142.18,25.84,167.67 +906,1,E07000245,3,71.06,155.98,25.84,180.4 +1232,1,E07000245,4,81.2,170.85,25.84,178.28 +2862,2,E07000245,0,36.26,226.42,18.64,423.05 +1558,3,E07000245,1,49.84,99.75,25.84,131.58 +1884,3,E07000245,2,58.13,117.78,25.84,132.64 +2210,3,E07000245,3,63.67,130.52,25.84,143.25 +2536,3,E07000245,4,71.06,148.56,25.84,159.17 +3188,4,E07000245,0,55.97,135.86,18.64,318.19 +4154,5,E07000245,1,54.44,125.22,25.84,136.89 +4735,5,E07000245,2,64.59,147.5,25.84,160.24 +5454,5,E07000245,3,71.06,181.46,25.84,198.45 +6164,5,E07000245,4,81.2,332.14,25.84,361.84 +3514,6,E07000245,0,36.26,373.01,18.64,406.37 +4271,7,E07000245,1,49.84,125.22,25.84,136.89 +4997,7,E07000245,2,58.13,147.5,25.84,160.24 +5640,7,E07000245,3,63.67,181.46,25.84,198.45 +6302,7,E07000245,4,71.06,332.14,25.84,361.84 +3840,8,E07000245,0,55.97,373.01,18.64,406.37 +6774,9,E07000245,1,54.44,156.51,25.84,171.11 +7100,9,E07000245,2,64.59,184.37,25.84,200.32 +7426,9,E07000245,3,71.06,226.84,25.84,248.03 +7752,9,E07000245,4,81.2,415.17,25.84,452.31 +8078,10,E07000245,0,36.26,284.53,18.64,309.82 +310,1,E09000033,1,65.51,145.37,25.84,197.39 +636,1,E09000033,2,77.51,157.04,25.84,192.07 +962,1,E09000033,3,83.97,166.61,25.84,226.01 +1288,1,E09000033,4,101.48,186.77,25.84,251.49 +2918,2,E09000033,0,70.47,317,18.64,502.91 +1614,3,E09000033,1,58.13,118.85,25.84,146.43 +1940,3,E09000033,2,63.67,139.02,25.84,175.09 +2266,3,E09000033,3,71.06,159.17,25.84,200.55 +2592,3,E09000033,4,83.05,259.98,25.84,261.04 +3244,4,E09000033,0,60.1,371.82,18.64,402.8 +3982,5,E09000033,1,65.51,438.24,25.84,477.53 +4597,5,E09000033,2,77.51,631.39,25.84,689.74 +5249,5,E09000033,3,83.97,923.2,25.84,1007.03 +5934,5,E09000033,4,101.48,2253.89,25.84,2458.69 +3570,6,E09000033,0,70.47,2531.21,18.64,2761.21 +4196,7,E09000033,1,58.13,438.24,25.84,477.53 +4697,7,E09000033,2,63.67,631.39,25.84,689.74 +5349,7,E09000033,3,71.06,923.2,25.84,1007.03 +5901,7,E09000033,4,83.05,2253.89,25.84,2458.69 +3896,8,E09000033,0,60.1,2531.21,18.64,2761.21 +6830,9,E09000033,1,65.51,547.82,25.84,596.91 +7156,9,E09000033,2,77.51,789.25,25.84,862.19 +7482,9,E09000033,3,83.97,1154.01,25.84,1258.8 +7808,9,E09000033,4,101.48,2817.36,25.84,3073.38 +8134,10,E09000033,0,70.47,314.32,18.64,344.12 +8176,1,E06000064,1,51.68,93.39,25.84,116.72 +8177,1,E06000064,2,59.06,107.19,25.84,134.77 +8178,1,E06000064,3,65.51,119.9,25.84,145.37 +8179,1,E06000064,4,71.98,133.71,25.84,159.17 +8184,2,E06000064,0,55.97,239.54,18.64,342.01 +8180,3,E06000064,1,43.36,85.94,25.84,100.81 +8181,3,E06000064,2,53.52,94.47,25.84,113.53 +8182,3,E06000064,3,58.13,105.06,25.84,124.15 +8183,3,E06000064,4,55.37,118.85,25.84,133.71 +8185,4,E06000064,0,33.16,469.54,18.64,599.44 +8188,5,E06000064,1,51.68,94.47,25.84,101.88 +8190,5,E06000064,2,59.06,114.6,25.84,124.15 +8192,5,E06000064,3,65.51,130.52,25.84,143.25 +8194,5,E06000064,4,71.98,202.69,25.84,220.72 +8186,6,E06000064,0,55.97,227.63,18.64,247.88 +8189,7,E06000064,1,43.36,94.47,25.84,101.88 +8191,7,E06000064,2,53.52,114.6,25.84,124.15 +8193,7,E06000064,3,58.13,130.52,25.84,143.25 +8195,7,E06000064,4,55.37,202.69,25.84,220.72 +8187,8,E06000064,0,33.16,227.63,18.64,247.88 +8196,9,E06000064,1,51.68,118.06,25.84,127.34 +8197,9,E06000064,2,59.06,143.25,25.84,155.2 +8198,9,E06000064,3,65.51,163.15,25.84,179.06 +8199,9,E06000064,4,71.98,253.36,25.84,275.9 +8200,10,E06000064,0,55.97,473.7,18.64,516.92 +312,1,E08000010,1,51.68,93.39,25.84,116.72 +638,1,E08000010,2,59.06,107.19,25.84,134.77 +964,1,E08000010,3,65.51,119.9,25.84,145.37 +1290,1,E08000010,4,71.98,133.71,25.84,159.17 +2920,2,E08000010,0,55.97,239.54,18.64,342.01 +1616,3,E08000010,1,43.36,85.94,25.84,100.81 +1942,3,E08000010,2,53.52,94.47,25.84,113.53 +2268,3,E08000010,3,58.13,105.06,25.84,124.15 +2594,3,E08000010,4,55.37,118.85,25.84,133.71 +3246,4,E08000010,0,33.16,469.54,18.64,599.44 +4387,5,E08000010,1,51.68,92.33,25.84,99.75 +4957,5,E08000010,2,59.06,109.29,25.84,118.85 +5600,5,E08000010,3,65.51,130.52,25.84,143.25 +6348,5,E08000010,4,71.98,181.46,25.84,198.45 +3572,6,E08000010,0,55.97,203.78,18.64,222.84 +4499,7,E08000010,1,43.36,92.33,25.84,99.75 +5095,7,E08000010,2,53.52,109.29,25.84,118.85 +5775,7,E08000010,3,58.13,130.52,25.84,143.25 +6399,7,E08000010,4,55.37,181.46,25.84,198.45 +3898,8,E08000010,0,33.16,203.78,18.64,222.84 +6832,9,E08000010,1,51.68,115.39,25.84,124.69 +7158,9,E08000010,2,59.06,136.63,25.84,148.56 +7484,9,E08000010,3,65.51,163.15,25.84,179.06 +7810,9,E08000010,4,71.98,226.84,25.84,248.03 +8136,10,E08000010,0,55.97,394.77,18.64,430.5 +313,1,E06000054,1,48.92,107.19,25.84,140.08 +639,1,E06000054,2,55.37,120.97,25.84,144.31 +965,1,E06000054,3,61.83,141.13,25.84,161.3 +1291,1,E06000054,4,71.06,158.1,25.84,194.19 +2921,2,E06000054,0,54.93,231.2,18.64,358.7 +1617,3,E06000054,1,47.06,89.13,25.84,210.12 +1943,3,E06000054,2,54.44,100.81,25.84,111.41 +2269,3,E06000054,3,61.83,109.29,25.84,126.28 +2595,3,E06000054,4,73.82,130.52,25.84,130.52 +3247,4,E06000054,0,54.93,115.59,18.64,141.81 +4233,5,E06000054,1,48.92,125.22,25.84,136.89 +4869,5,E06000054,2,55.37,154.93,25.84,169.79 +5500,5,E06000054,3,61.83,192.07,25.84,210.12 +6038,5,E06000054,4,71.06,292.87,25.84,319.41 +3573,6,E06000054,0,54.93,328.92,18.64,358.7 +3949,7,E06000054,1,47.06,125.22,25.84,136.89 +5146,7,E06000054,2,54.44,154.93,25.84,169.79 +5726,7,E06000054,3,61.83,192.07,25.84,210.12 +6438,7,E06000054,4,73.82,292.87,25.84,319.41 +3899,8,E06000054,0,54.93,328.92,18.64,358.7 +6833,9,E06000054,1,48.92,156.51,25.84,171.11 +7159,9,E06000054,2,55.37,193.64,25.84,212.23 +7485,9,E06000054,3,61.83,240.08,25.84,262.64 +7811,9,E06000054,4,71.06,366.11,25.84,399.27 +8137,10,E06000054,0,54.93,545.21,18.64,594.37 +314,1,E07000094,1,57.21,123.09,25.84,176.15 +640,1,E07000094,2,71.06,146.43,25.84,186.77 +966,1,E07000094,3,81.2,161.3,25.84,203.75 +1292,1,E07000094,4,89.52,178.28,25.84,221.77 +2922,2,E07000094,0,62.17,268.13,18.64,344.4 +1618,3,E07000094,1,51.68,115.66,25.84,159.17 +1944,3,E07000094,2,62.75,129.46,25.84,145.37 +2270,3,E07000094,3,68.28,149.62,25.84,185.7 +2596,3,E07000094,4,72.9,184.64,25.84,194.19 +3248,4,E07000094,0,48.71,195.45,18.64,204.96 +4044,5,E07000094,1,57.21,170.85,25.84,185.7 +4659,5,E07000094,2,71.06,214.35,25.84,234.52 +5311,5,E07000094,3,81.2,281.2,25.84,306.68 +5996,5,E07000094,4,89.52,421.28,25.84,459.48 +3574,6,E07000094,0,62.17,473.1,18.64,516 +4111,7,E07000094,1,51.68,170.85,25.84,185.7 +4806,7,E07000094,2,62.75,214.35,25.84,234.52 +5411,7,E07000094,3,68.28,281.2,25.84,306.68 +6100,7,E07000094,4,72.9,421.28,25.84,459.48 +3900,8,E07000094,0,48.71,473.1,18.64,516 +6834,9,E07000094,1,57.21,213.57,25.84,232.15 +7160,9,E07000094,2,71.06,267.95,25.84,293.15 +7486,9,E07000094,3,81.2,351.51,25.84,383.34 +7812,9,E07000094,4,89.52,526.6,25.84,574.35 +8138,10,E07000094,0,62.17,253.23,18.64,277.06 +315,1,E06000040,1,57.21,123.09,25.84,176.15 +641,1,E06000040,2,71.06,146.43,25.84,186.77 +967,1,E06000040,3,81.2,161.3,25.84,203.75 +1293,1,E06000040,4,89.52,178.28,25.84,221.77 +2923,2,E06000040,0,62.17,268.13,18.64,344.4 +1619,3,E06000040,1,51.68,115.66,25.84,159.17 +1945,3,E06000040,2,62.75,129.46,25.84,145.37 +2271,3,E06000040,3,68.28,149.62,25.84,185.7 +2597,3,E06000040,4,72.9,184.64,25.84,194.19 +3249,4,E06000040,0,48.71,195.45,18.64,204.96 +4045,5,E06000040,1,57.21,198.45,25.84,215.41 +4660,5,E06000040,2,71.06,281.2,25.84,306.68 +5312,5,E06000040,3,81.2,342.76,25.84,374.6 +5997,5,E06000040,4,89.52,762.96,25.84,831.96 +3575,6,E06000040,0,62.17,856.86,18.64,934.32 +4112,7,E06000040,1,51.68,198.45,25.84,215.41 +4807,7,E06000040,2,62.75,281.2,25.84,306.68 +5412,7,E06000040,3,68.28,342.76,25.84,374.6 +6101,7,E06000040,4,72.9,762.96,25.84,831.96 +3901,8,E06000040,0,48.71,856.86,18.64,934.32 +6835,9,E06000040,1,57.21,248.03,25.84,269.26 +7161,9,E06000040,2,71.06,351.51,25.84,383.34 +7487,9,E06000040,3,81.2,428.42,25.84,468.25 +7813,9,E06000040,4,89.52,953.72,25.84,1039.95 +8139,10,E06000040,0,62.17,473.7,18.64,516.92 +316,1,E08000015,1,51.68,93.39,25.84,116.72 +642,1,E08000015,2,59.06,107.19,25.84,134.77 +968,1,E08000015,3,65.51,119.9,25.84,145.37 +1294,1,E08000015,4,71.98,133.71,25.84,159.17 +2924,2,E08000015,0,55.97,239.54,18.64,342.01 +1620,3,E08000015,1,43.36,85.94,25.84,100.81 +1946,3,E08000015,2,53.52,94.47,25.84,113.53 +2272,3,E08000015,3,58.13,105.06,25.84,124.15 +2598,3,E08000015,4,55.37,118.85,25.84,133.71 +3250,4,E08000015,0,33.16,469.54,18.64,599.44 +4388,5,E08000015,1,51.68,102.94,25.84,112.47 +4958,5,E08000015,2,59.06,125.22,25.84,136.89 +5601,5,E08000015,3,65.51,147.5,25.84,160.24 +6349,5,E08000015,4,71.98,192.07,25.84,210.12 +3576,6,E08000015,0,55.97,215.7,18.64,235.95 +4500,7,E08000015,1,43.36,102.94,25.84,112.47 +5096,7,E08000015,2,53.52,125.22,25.84,136.89 +5776,7,E08000015,3,58.13,147.5,25.84,160.24 +6400,7,E08000015,4,55.37,192.07,25.84,210.12 +3902,8,E08000015,0,33.16,215.7,18.64,235.95 +6836,9,E08000015,1,51.68,128.67,25.84,140.6 +7162,9,E08000015,2,59.06,156.51,25.84,171.11 +7488,9,E08000015,3,65.51,184.37,25.84,200.32 +7814,9,E08000015,4,71.98,240.08,25.84,262.64 +8140,10,E08000015,0,55.97,505.01,18.64,551.18 +317,1,E07000217,1,57.21,123.09,25.84,176.15 +643,1,E07000217,2,71.06,146.43,25.84,186.77 +969,1,E07000217,3,81.2,161.3,25.84,203.75 +1295,1,E07000217,4,89.52,178.28,25.84,221.77 +2925,2,E07000217,0,62.17,268.13,18.64,344.4 +1621,3,E07000217,1,51.68,115.66,25.84,159.17 +1947,3,E07000217,2,62.75,129.46,25.84,145.37 +2273,3,E07000217,3,68.28,149.62,25.84,185.7 +2599,3,E07000217,4,72.9,184.64,25.84,194.19 +3251,4,E07000217,0,48.71,195.45,18.64,204.96 +4046,5,E07000217,1,57.21,176.15,25.84,191.01 +4661,5,E07000217,2,71.06,248.31,25.84,270.61 +5313,5,E07000217,3,81.2,299.26,25.84,325.77 +5998,5,E07000217,4,89.52,673.83,25.84,734.32 +3577,6,E07000217,0,62.17,756.74,18.64,824.68 +4113,7,E07000217,1,51.68,176.15,25.84,191.01 +4808,7,E07000217,2,62.75,248.31,25.84,270.61 +5413,7,E07000217,3,68.28,299.26,25.84,325.77 +6102,7,E07000217,4,72.9,673.83,25.84,734.32 +3903,8,E07000217,0,48.71,756.74,18.64,824.68 +6837,9,E07000217,1,57.21,220.21,25.84,238.77 +7163,9,E07000217,2,71.06,310.37,25.84,338.25 +7489,9,E07000217,3,81.2,374.05,25.84,407.22 +7815,9,E07000217,4,89.52,842.3,25.84,917.9 +8141,10,E07000217,0,62.17,239.85,18.64,260.68 +318,1,E06000041,1,57.21,123.09,25.84,176.15 +644,1,E06000041,2,71.06,146.43,25.84,186.77 +970,1,E06000041,3,81.2,161.3,25.84,203.75 +1296,1,E06000041,4,89.52,178.28,25.84,221.77 +2926,2,E06000041,0,62.17,268.13,18.64,344.4 +1622,3,E06000041,1,51.68,115.66,25.84,159.17 +1948,3,E06000041,2,62.75,129.46,25.84,145.37 +2274,3,E06000041,3,68.28,149.62,25.84,185.7 +2600,3,E06000041,4,72.9,184.64,25.84,194.19 +3252,4,E06000041,0,48.71,195.45,18.64,204.96 +4047,5,E06000041,1,57.21,164.48,25.84,179.34 +4662,5,E06000041,2,71.06,205.88,25.84,223.9 +5314,5,E06000041,3,81.2,269.54,25.84,293.94 +5999,5,E06000041,4,89.52,426.59,25.84,465.84 +3578,6,E06000041,0,62.17,479.07,18.64,523.16 +4114,7,E06000041,1,51.68,164.48,25.84,179.34 +4809,7,E06000041,2,62.75,205.88,25.84,223.9 +5414,7,E06000041,3,68.28,269.54,25.84,293.94 +6103,7,E06000041,4,72.9,426.59,25.84,465.84 +3904,8,E06000041,0,48.71,479.07,18.64,523.16 +6838,9,E06000041,1,57.21,205.6,25.84,224.18 +7164,9,E06000041,2,71.06,257.33,25.84,279.88 +7490,9,E06000041,3,81.2,336.93,25.84,367.42 +7816,9,E06000041,4,89.52,533.22,25.84,582.31 +8142,10,E06000041,0,62.17,1059.14,18.64,1157.45 +319,1,E08000031,1,52.6,98.69,25.84,124.15 +645,1,E08000031,2,58.13,116.72,25.84,136.89 +971,1,E08000031,3,69.2,132.64,25.84,160.24 +1297,1,E08000031,4,80.28,161.3,25.84,178.28 +2927,2,E08000031,0,39.38,245.49,18.64,382.53 +1623,3,E08000031,1,46.13,88.07,25.84,97.63 +1949,3,E08000031,2,49.84,94.47,25.84,102.94 +2275,3,E08000031,3,59.98,104,25.84,119.9 +2601,3,E08000031,4,68.28,127.34,25.84,127.34 +3253,4,E08000031,0,46.63,107.26,18.64,107.26 +4307,5,E08000031,1,52.6,97.63,25.84,107.19 +4917,5,E08000031,2,58.13,119.9,25.84,130.52 +5548,5,E08000031,3,69.2,134.77,25.84,147.5 +6200,5,E08000031,4,80.28,170.85,25.84,185.7 +3579,6,E08000031,0,39.38,191.88,18.64,208.55 +4528,7,E08000031,1,46.13,97.63,25.84,107.19 +5213,7,E08000031,2,49.84,119.9,25.84,130.52 +5804,7,E08000031,3,59.98,134.77,25.84,147.5 +6465,7,E08000031,4,68.28,170.85,25.84,185.7 +3905,8,E08000031,0,46.63,191.88,18.64,208.55 +6839,9,E08000031,1,52.6,122.03,25.84,133.98 +7165,9,E08000031,2,58.13,149.9,25.84,163.15 +7491,9,E08000031,3,69.2,168.46,25.84,184.37 +7817,9,E08000031,4,80.28,213.57,25.84,232.15 +8143,10,E08000031,0,39.38,427.52,18.64,466.26 +320,1,E07000237,1,52.6,98.69,25.84,124.15 +646,1,E07000237,2,58.13,116.72,25.84,136.89 +972,1,E07000237,3,69.2,132.64,25.84,160.24 +1298,1,E07000237,4,80.28,161.3,25.84,178.28 +2928,2,E07000237,0,39.38,245.49,18.64,382.53 +1624,3,E07000237,1,46.13,88.07,25.84,97.63 +1950,3,E07000237,2,49.84,94.47,25.84,102.94 +2276,3,E07000237,3,59.98,104,25.84,119.9 +2602,3,E07000237,4,68.28,127.34,25.84,127.34 +3254,4,E07000237,0,46.63,107.26,18.64,107.26 +4308,5,E07000237,1,52.6,114.6,25.84,124.15 +4918,5,E07000237,2,58.13,142.18,25.84,154.93 +5549,5,E07000237,3,69.2,164.48,25.84,179.34 +6201,5,E07000237,4,80.28,214.35,25.84,234.52 +3580,6,E07000237,0,39.38,240.72,18.64,263.37 +4529,7,E07000237,1,46.13,114.6,25.84,124.15 +5214,7,E07000237,2,49.84,142.18,25.84,154.93 +5805,7,E07000237,3,59.98,164.48,25.84,179.34 +6466,7,E07000237,4,68.28,214.35,25.84,234.52 +3906,8,E07000237,0,46.63,240.72,18.64,263.37 +6840,9,E07000237,1,52.6,143.25,25.84,155.2 +7166,9,E07000237,2,58.13,177.73,25.84,193.64 +7492,9,E07000237,3,69.2,205.6,25.84,224.18 +7818,9,E07000237,4,80.28,267.95,25.84,293.15 +8144,10,E07000237,0,39.38,443.93,18.64,484.13 +321,1,E07000229,1,57.21,123.09,25.84,176.15 +647,1,E07000229,2,71.06,146.43,25.84,186.77 +973,1,E07000229,3,81.2,161.3,25.84,203.75 +1299,1,E07000229,4,89.52,178.28,25.84,221.77 +2929,2,E07000229,0,62.17,268.13,18.64,344.4 +1625,3,E07000229,1,51.68,115.66,25.84,159.17 +1951,3,E07000229,2,62.75,129.46,25.84,145.37 +2277,3,E07000229,3,68.28,149.62,25.84,185.7 +2603,3,E07000229,4,72.9,184.64,25.84,194.19 +3255,4,E07000229,0,48.71,195.45,18.64,204.96 +4048,5,E07000229,1,57.21,130.52,25.84,143.25 +4663,5,E07000229,2,71.06,170.85,25.84,185.7 +5315,5,E07000229,3,81.2,214.35,25.84,234.52 +6000,5,E07000229,4,89.52,291.81,25.84,317.29 +3581,6,E07000229,0,62.17,326.54,18.64,356.32 +4115,7,E07000229,1,51.68,130.52,25.84,143.25 +4810,7,E07000229,2,62.75,170.85,25.84,185.7 +5415,7,E07000229,3,68.28,214.35,25.84,234.52 +6104,7,E07000229,4,72.9,291.81,25.84,317.29 +3907,8,E07000229,0,48.71,326.54,18.64,356.32 +6841,9,E07000229,1,57.21,163.15,25.84,179.06 +7167,9,E07000229,2,71.06,213.57,25.84,232.15 +7493,9,E07000229,3,81.2,267.95,25.84,293.15 +7819,9,E07000229,4,89.52,364.78,25.84,396.59 +8145,10,E07000229,0,62.17,387.31,18.64,423.05 +322,1,E07000238,1,52.6,98.69,25.84,124.15 +648,1,E07000238,2,58.13,116.72,25.84,136.89 +974,1,E07000238,3,69.2,132.64,25.84,160.24 +1300,1,E07000238,4,80.28,161.3,25.84,178.28 +2930,2,E07000238,0,39.38,245.49,18.64,382.53 +1626,3,E07000238,1,46.13,88.07,25.84,97.63 +1952,3,E07000238,2,49.84,94.47,25.84,102.94 +2278,3,E07000238,3,59.98,104,25.84,119.9 +2604,3,E07000238,4,68.28,127.34,25.84,127.34 +3256,4,E07000238,0,46.63,107.26,18.64,107.26 +4309,5,E07000238,1,52.6,113.53,25.84,123.09 +4919,5,E07000238,2,58.13,137.95,25.84,150.69 +5550,5,E07000238,3,69.2,170.85,25.84,185.7 +6202,5,E07000238,4,80.28,248.31,25.84,270.61 +3582,6,E07000238,0,39.38,278.86,18.64,303.89 +4530,7,E07000238,1,46.13,113.53,25.84,123.09 +5215,7,E07000238,2,49.84,137.95,25.84,150.69 +5806,7,E07000238,3,59.98,170.85,25.84,185.7 +6467,7,E07000238,4,68.28,248.31,25.84,270.61 +3908,8,E07000238,0,46.63,278.86,18.64,303.89 +6842,9,E07000238,1,52.6,141.94,25.84,153.86 +7168,9,E07000238,2,58.13,172.43,25.84,188.36 +7494,9,E07000238,3,69.2,213.57,25.84,232.15 +7820,9,E07000238,4,80.28,310.37,25.84,338.25 +8146,10,E07000238,0,39.38,250.25,18.64,271.11 +324,1,E07000128,1,51.68,93.39,25.84,116.72 +650,1,E07000128,2,59.06,107.19,25.84,134.77 +976,1,E07000128,3,65.51,119.9,25.84,145.37 +1302,1,E07000128,4,71.98,133.71,25.84,159.17 +2932,2,E07000128,0,55.97,239.54,18.64,342.01 +1628,3,E07000128,1,43.36,85.94,25.84,100.81 +1954,3,E07000128,2,53.52,94.47,25.84,113.53 +2280,3,E07000128,3,58.13,105.06,25.84,124.15 +2606,3,E07000128,4,55.37,118.85,25.84,133.71 +3258,4,E07000128,0,33.16,469.54,18.64,599.44 +4389,5,E07000128,1,51.68,102.94,25.84,113.53 +4959,5,E07000128,2,59.06,132.64,25.84,145.37 +5602,5,E07000128,3,65.51,147.5,25.84,160.24 +6350,5,E07000128,4,71.98,192.07,25.84,210.12 +3584,6,E07000128,0,55.97,215.7,18.64,235.95 +4501,7,E07000128,1,43.36,102.94,25.84,113.53 +5097,7,E07000128,2,53.52,132.64,25.84,145.37 +5777,7,E07000128,3,58.13,147.5,25.84,160.24 +6401,7,E07000128,4,55.37,192.07,25.84,210.12 +3910,8,E07000128,0,33.16,215.7,18.64,235.95 +6844,9,E07000128,1,51.68,128.67,25.84,141.94 +7170,9,E07000128,2,59.06,165.81,25.84,181.72 +7496,9,E07000128,3,65.51,184.37,25.84,200.32 +7822,9,E07000128,4,71.98,240.08,25.84,262.64 +8148,10,E07000128,0,55.97,473.7,18.64,516.92 +325,1,E07000239,1,52.6,98.69,25.84,124.15 +651,1,E07000239,2,58.13,116.72,25.84,136.89 +977,1,E07000239,3,69.2,132.64,25.84,160.24 +1303,1,E07000239,4,80.28,161.3,25.84,178.28 +2933,2,E07000239,0,39.38,245.49,18.64,382.53 +1629,3,E07000239,1,46.13,88.07,25.84,97.63 +1955,3,E07000239,2,49.84,94.47,25.84,102.94 +2281,3,E07000239,3,59.98,104,25.84,119.9 +2607,3,E07000239,4,68.28,127.34,25.84,127.34 +3259,4,E07000239,0,46.63,107.26,18.64,107.26 +4310,5,E07000239,1,52.6,97.63,25.84,107.19 +4920,5,E07000239,2,58.13,125.22,25.84,136.89 +5551,5,E07000239,3,69.2,142.18,25.84,154.93 +6203,5,E07000239,4,80.28,192.07,25.84,210.12 +3585,6,E07000239,0,39.38,215.7,18.64,235.95 +4531,7,E07000239,1,46.13,97.63,25.84,107.19 +5216,7,E07000239,2,49.84,125.22,25.84,136.89 +5807,7,E07000239,3,59.98,142.18,25.84,154.93 +6468,7,E07000239,4,68.28,192.07,25.84,210.12 +3911,8,E07000239,0,46.63,215.7,18.64,235.95 +6845,9,E07000239,1,52.6,122.03,25.84,133.98 +7171,9,E07000239,2,58.13,156.51,25.84,171.11 +7497,9,E07000239,3,69.2,177.73,25.84,193.64 +7823,9,E07000239,4,80.28,240.08,25.84,262.64 +8149,10,E07000239,0,39.38,262.16,18.64,286.02 +326,1,E06000014,1,50.76,91.27,25.84,113.53 +652,1,E06000014,2,58.13,108.24,25.84,140.08 +978,1,E06000014,3,62.75,119.9,25.84,161.3 +1304,1,E06000014,4,72.9,144.31,25.84,178.28 +2934,2,E06000014,0,52.86,234.75,18.64,322.95 +1630,3,E06000014,1,46.13,81.71,25.84,92.33 +1956,3,E06000014,2,52.6,112.47,25.84,144.31 +2282,3,E06000014,3,56.29,104,25.84,113.53 +2608,3,E06000014,4,63.67,120.97,25.84,175.09 +3260,4,E06000014,0,51.82,160.88,18.64,190.67 +4410,5,E06000014,1,50.76,134.77,25.84,147.5 +4890,5,E06000014,2,58.13,157.04,25.84,172.97 +5521,5,E06000014,3,62.75,202.69,25.84,220.72 +6126,5,E06000014,4,72.9,351.25,25.84,383.08 +3586,6,E06000014,0,52.86,394.46,18.64,430.21 +4564,7,E06000014,1,46.13,134.77,25.84,147.5 +4832,7,E06000014,2,52.6,157.04,25.84,172.97 +5868,7,E06000014,3,56.29,202.69,25.84,220.72 +6224,7,E06000014,4,63.67,351.25,25.84,383.08 +3912,8,E06000014,0,51.82,394.46,18.64,430.21 +6846,9,E06000014,1,50.76,168.46,25.84,184.37 +7172,9,E06000014,2,52.6,196.32,25.84,216.2 +7498,9,E06000014,3,62.75,253.36,25.84,275.9 +7824,9,E06000014,4,72.9,439.06,25.84,478.85 +8150,10,E06000014,0,52.86,615.22,18.64,670.34 \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 02a9cb707..9c66098d7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -35,6 +35,9 @@ Rails.application.routes.draw do get "/accessibility-statement", to: "content#accessibility_statement" get "/privacy-notice", to: "content#privacy_notice" get "/data-sharing-agreement", to: "content#data_sharing_agreement" + get "/download-23-24-sales-form", to: "start#download_23_24_sales_form" + get "/download-22-23-sales-form", to: "start#download_22_23_sales_form" + get "/download-23-24-lettings-form", to: "start#download_23_24_lettings_form" resource :account, only: %i[show edit], controller: "users" do get "edit/password", to: "users#edit_password" diff --git a/config/sidekiq_cron_schedule.yml b/config/sidekiq_cron_schedule.yml index 46cb10ff2..7c91706ab 100644 --- a/config/sidekiq_cron_schedule.yml +++ b/config/sidekiq_cron_schedule.yml @@ -1,5 +1,5 @@ data_export_csv: - cron: "every day at 5am" + cron: "every day at 4am" class: "DataExportCsvJob" queue: default data_export_xml: diff --git a/db/migrate/20230224083552_add_columns_to_sales_log.rb b/db/migrate/20230224083552_add_columns_to_sales_log.rb new file mode 100644 index 000000000..f4fbc91df --- /dev/null +++ b/db/migrate/20230224083552_add_columns_to_sales_log.rb @@ -0,0 +1,8 @@ +class AddColumnsToSalesLog < ActiveRecord::Migration[7.0] + def change + change_table :sales_logs, bulk: true do |t| + t.column :buy2living, :integer + t.column :prevtenbuy2, :integer + end + end +end diff --git a/db/migrate/20230301170338_add_uprn_to_logs.rb b/db/migrate/20230301170338_add_uprn_to_logs.rb new file mode 100644 index 000000000..ba354c619 --- /dev/null +++ b/db/migrate/20230301170338_add_uprn_to_logs.rb @@ -0,0 +1,15 @@ +class AddUprnToLogs < ActiveRecord::Migration[7.0] + def change + change_table :sales_logs, bulk: true do |t| + t.column :uprn, :string + t.column :uprn_known, :integer + t.column :uprn_confirmed, :integer + end + + change_table :lettings_logs, bulk: true do |t| + t.column :uprn, :string + t.column :uprn_known, :integer + t.column :uprn_confirmed, :integer + end + end +end diff --git a/db/migrate/20230306110210_add_address_to_logs.rb b/db/migrate/20230306110210_add_address_to_logs.rb new file mode 100644 index 000000000..6562aa742 --- /dev/null +++ b/db/migrate/20230306110210_add_address_to_logs.rb @@ -0,0 +1,15 @@ +class AddAddressToLogs < ActiveRecord::Migration[7.0] + change_table :sales_logs, bulk: true do |t| + t.column :address_line1, :string + t.column :address_line2, :string + t.column :town_or_city, :string + t.column :county, :string + end + + change_table :lettings_logs, bulk: true do |t| + t.column :address_line1, :string + t.column :address_line2, :string + t.column :town_or_city, :string + t.column :county, :string + end +end diff --git a/db/migrate/20230307111943_remove_othernational_from_sales_logs.rb b/db/migrate/20230307111943_remove_othernational_from_sales_logs.rb new file mode 100644 index 000000000..534962773 --- /dev/null +++ b/db/migrate/20230307111943_remove_othernational_from_sales_logs.rb @@ -0,0 +1,5 @@ +class RemoveOthernationalFromSalesLogs < ActiveRecord::Migration[7.0] + def change + remove_column :sales_logs, :othernational, :string + end +end diff --git a/db/migrate/20230307140937_add_nationalbuy2_to_sales_logs.rb b/db/migrate/20230307140937_add_nationalbuy2_to_sales_logs.rb new file mode 100644 index 000000000..f49f2c493 --- /dev/null +++ b/db/migrate/20230307140937_add_nationalbuy2_to_sales_logs.rb @@ -0,0 +1,5 @@ +class AddNationalbuy2ToSalesLogs < ActiveRecord::Migration[7.0] + def change + add_column :sales_logs, :nationalbuy2, :integer + end +end diff --git a/db/migrate/20230308101826_create_local_authorities.rb b/db/migrate/20230308101826_create_local_authorities.rb new file mode 100644 index 000000000..f64964455 --- /dev/null +++ b/db/migrate/20230308101826_create_local_authorities.rb @@ -0,0 +1,13 @@ +class CreateLocalAuthorities < ActiveRecord::Migration[7.0] + def change + create_table :local_authorities do |t| + t.string :code, null: false + t.string :name, null: false + t.datetime :start_date, null: false + t.datetime :end_date + t.index %w[code], name: "index_local_authority_code", unique: true + + t.timestamps + end + end +end diff --git a/db/migrate/20230309145740_add_local_authority_link.rb b/db/migrate/20230309145740_add_local_authority_link.rb new file mode 100644 index 000000000..6c1b0a079 --- /dev/null +++ b/db/migrate/20230309145740_add_local_authority_link.rb @@ -0,0 +1,12 @@ +class AddLocalAuthorityLink < ActiveRecord::Migration[7.0] + def change + create_table :local_authority_links do |t| + t.references :local_authority + t.references :linked_local_authority + + t.timestamps + end + add_foreign_key :local_authority_links, :local_authorities, column: :local_authority_id + add_foreign_key :local_authority_links, :local_authorities, column: :linked_local_authority_id + end +end diff --git a/db/migrate/20230320084057_add_student_not_child_value_check.rb b/db/migrate/20230320084057_add_student_not_child_value_check.rb new file mode 100644 index 000000000..ecd037368 --- /dev/null +++ b/db/migrate/20230320084057_add_student_not_child_value_check.rb @@ -0,0 +1,5 @@ +class AddStudentNotChildValueCheck < ActiveRecord::Migration[7.0] + def change + add_column :sales_logs, :student_not_child_value_check, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 6acaba1f5..32d71dfeb 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[7.0].define(version: 2023_03_01_144555) do +ActiveRecord::Schema[7.0].define(version: 2023_03_20_084057) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -279,6 +279,13 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_01_144555) do t.boolean "unresolved" t.bigint "updated_by_id" t.bigint "bulk_upload_id" + t.string "uprn" + t.integer "uprn_known" + t.integer "uprn_confirmed" + t.string "address_line1" + t.string "address_line2" + t.string "town_or_city" + t.string "county" t.index ["bulk_upload_id"], name: "index_lettings_logs_on_bulk_upload_id" t.index ["created_by_id"], name: "index_lettings_logs_on_created_by_id" t.index ["location_id"], name: "index_lettings_logs_on_location_id" @@ -289,6 +296,25 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_01_144555) do t.index ["updated_by_id"], name: "index_lettings_logs_on_updated_by_id" end + create_table "local_authorities", force: :cascade do |t| + t.string "code", null: false + t.string "name", null: false + t.datetime "start_date", null: false + t.datetime "end_date" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["code"], name: "index_local_authority_code", unique: true + end + + create_table "local_authority_links", force: :cascade do |t| + t.bigint "local_authority_id" + t.bigint "linked_local_authority_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["linked_local_authority_id"], name: "index_local_authority_links_on_linked_local_authority_id" + t.index ["local_authority_id"], name: "index_local_authority_links_on_local_authority_id" + end + create_table "location_deactivation_periods", force: :cascade do |t| t.datetime "deactivation_date" t.datetime "reactivation_date" @@ -393,7 +419,6 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_01_144555) do t.integer "age1_known" t.string "sex1" t.integer "national" - t.string "othernational" t.integer "ethnic" t.integer "ethnic_group" t.integer "buy1livein" @@ -532,7 +557,18 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_01_144555) do t.integer "ethnicbuy2" t.integer "proplen_asked" t.string "old_id" + t.integer "buy2living" + t.integer "prevtenbuy2" t.integer "pregblank" + t.string "uprn" + t.integer "uprn_known" + t.integer "uprn_confirmed" + t.string "address_line1" + t.string "address_line2" + t.string "town_or_city" + t.string "county" + t.integer "nationalbuy2" + t.integer "student_not_child_value_check" t.index ["bulk_upload_id"], name: "index_sales_logs_on_bulk_upload_id" t.index ["created_by_id"], name: "index_sales_logs_on_created_by_id" t.index ["old_id"], name: "index_sales_logs_on_old_id", unique: true @@ -629,6 +665,8 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_01_144555) do add_foreign_key "lettings_logs", "locations" add_foreign_key "lettings_logs", "organisations", column: "owning_organisation_id", on_delete: :cascade add_foreign_key "lettings_logs", "schemes" + add_foreign_key "local_authority_links", "local_authorities" + add_foreign_key "local_authority_links", "local_authorities", column: "linked_local_authority_id" add_foreign_key "locations", "schemes" add_foreign_key "organisation_relationships", "organisations", column: "child_organisation_id" add_foreign_key "organisation_relationships", "organisations", column: "parent_organisation_id" diff --git a/db/seeds.rb b/db/seeds.rb index 341677b27..bf43d47b1 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -309,6 +309,20 @@ unless Rails.env.test? pp "Seeded 3 dummy schemes" end + if LocalAuthority.count.zero? + la_path = "config/local_authorities_data/initial_local_authorities.csv" + service = Imports::LocalAuthoritiesService.new(path: la_path) + service.call + end + + if (Rails.env.development? || Rails.env.review?) && LocalAuthorityLink.count.zero? + links_data_path = "config/local_authorities_data/local_authority_links_2023.csv" + service = Imports::LocalAuthorityLinksService.new(path: links_data_path) + service.call + + pp "Seeded local authority links" + end + if LaRentRange.count.zero? Dir.glob("config/rent_range_data/*.csv").each do |path| start_year = File.basename(path, ".csv") @@ -325,4 +339,10 @@ unless Rails.env.test? end end end + +if LocalAuthority.count.zero? + path = "config/local_authorities_data/initial_local_authorities.csv" + service = Imports::LocalAuthoritiesService.new(path:) + service.call +end # rubocop:enable Rails/Output diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index c8a433b8f..52a7b091a 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: https://rubygems.org/ specs: - activesupport (7.0.4.2) + activesupport (7.0.4.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -14,7 +14,7 @@ GEM coffee-script-source (1.11.1) colorator (1.1.0) commonmarker (0.23.8) - concurrent-ruby (1.2.0) + concurrent-ruby (1.2.2) dnsruby (1.61.9) simpleidn (~> 0.1) em-websocket (0.5.3) @@ -209,7 +209,7 @@ GEM jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) - minitest (5.17.0) + minitest (5.18.0) nokogiri (1.14.2-arm64-darwin) racc (~> 1.4) nokogiri (1.14.2-x86_64-darwin) diff --git a/lib/tasks/local_authorities.rake b/lib/tasks/local_authorities.rake new file mode 100644 index 000000000..b812bbc94 --- /dev/null +++ b/lib/tasks/local_authorities.rake @@ -0,0 +1,13 @@ +namespace :data_import do + desc "Import local authorities data" + task :local_authorities, %i[path] => :environment do |_task, args| + path = args[:path] + + raise "Usage: rake data_import:local_authorities['path/to/csv_file']" if path.blank? + + service = Imports::LocalAuthoritiesService.new(path:) + service.call + + pp "Created/updated #{service.count} local authority records" unless Rails.env.test? + end +end diff --git a/lib/tasks/local_authority_links.rake b/lib/tasks/local_authority_links.rake new file mode 100644 index 000000000..0345d3dd2 --- /dev/null +++ b/lib/tasks/local_authority_links.rake @@ -0,0 +1,13 @@ +namespace :data_import do + desc "Import local authority links data" + task :local_authority_links, %i[path] => :environment do |_task, args| + path = args[:path] + + raise "Usage: rake data_import:local_authority_links['path/to/csv_file']" if path.blank? + + service = Imports::LocalAuthorityLinksService.new(path:) + service.call + + pp "Created/updated #{service.count} local authority link records" unless Rails.env.test? + end +end diff --git a/public/files/2022_23_sales_paper_form.pdf b/public/files/2022_23_sales_paper_form.pdf new file mode 100644 index 000000000..961350f37 Binary files /dev/null and b/public/files/2022_23_sales_paper_form.pdf differ diff --git a/public/files/2023_24_lettings_paper_form.pdf b/public/files/2023_24_lettings_paper_form.pdf new file mode 100644 index 000000000..787e3b3b8 Binary files /dev/null and b/public/files/2023_24_lettings_paper_form.pdf differ diff --git a/public/files/2023_24_sales_paper_form.pdf b/public/files/2023_24_sales_paper_form.pdf new file mode 100644 index 000000000..327c90ab8 Binary files /dev/null and b/public/files/2023_24_sales_paper_form.pdf differ diff --git a/spec/components/bulk_upload_error_summary_table_component_spec.rb b/spec/components/bulk_upload_error_summary_table_component_spec.rb index a7468d70a..4c307515c 100644 --- a/spec/components/bulk_upload_error_summary_table_component_spec.rb +++ b/spec/components/bulk_upload_error_summary_table_component_spec.rb @@ -3,16 +3,16 @@ require "rails_helper" RSpec.describe BulkUploadErrorSummaryTableComponent, type: :component do subject(:component) { described_class.new(bulk_upload:) } - let(:bulk_upload) { create(:bulk_upload) } + let(:bulk_upload) { create(:bulk_upload, :lettings) } before do stub_const("BulkUploadErrorSummaryTableComponent::DISPLAY_THRESHOLD", 0) end context "when no errors" do - it "does not renders any rows" do + it "does not renders any tables" do result = render_inline(component) - expect(result).not_to have_selector("tbody tr") + expect(result).not_to have_selector("table") end end @@ -23,9 +23,9 @@ RSpec.describe BulkUploadErrorSummaryTableComponent, type: :component do create(:bulk_upload_error, bulk_upload:, col: "A", row: 1) end - it "does not render rows" do + it "does not render tables" do result = render_inline(component) - expect(result).to have_selector("tbody tr", count: 0) + expect(result).to have_selector("table", count: 0) end end @@ -33,38 +33,36 @@ RSpec.describe BulkUploadErrorSummaryTableComponent, type: :component do let!(:error_2) { create(:bulk_upload_error, bulk_upload:, col: "B", row: 2) } let!(:error_1) { create(:bulk_upload_error, bulk_upload:, col: "A", row: 1) } - it "renders rows for each error" do + it "renders table for each error" do result = render_inline(component) - expect(result).to have_selector("tbody tr", count: 2) + expect(result).to have_selector("table", count: 2) end - it "renders rows by col order" do + it "renders by col order" do result = render_inline(component) - order = result.css("tbody tr td:nth-of-type(1)").map(&:content) - expect(order).to eql(%w[A B]) + order = result.css("table thead th:nth-of-type(2)").map(&:content) + expect(order).to eql(["Column A", "Column B"]) end it "render correct data" do result = render_inline(component) - row_1 = result.css("tbody tr:nth-of-type(1) td").map(&:content) + table_1 = result.css("table").first.css("th, td").map(&:content) - expect(row_1).to eql([ - "A", - "1", - BulkUpload::Lettings::Validator.question_for_field(error_1.field.to_sym), + expect(table_1).to eql([ + bulk_upload.prefix_namespace::RowParser.question_for_field(error_1.field.to_sym).to_s, + "Column A", error_1.error, - error_1.field, + "1 error", ]) - row_2 = result.css("tbody tr:nth-of-type(2) td").map(&:content) + table_2 = result.css("table")[1].css("th, td").map(&:content) - expect(row_2).to eql([ - "B", - "1", - BulkUpload::Lettings::Validator.question_for_field(error_2.field.to_sym), + expect(table_2).to eql([ + bulk_upload.prefix_namespace::RowParser.question_for_field(error_2.field.to_sym).to_s, + "Column B", error_2.error, - error_2.field, + "1 error", ]) end end @@ -76,22 +74,21 @@ RSpec.describe BulkUploadErrorSummaryTableComponent, type: :component do create(:bulk_upload_error, bulk_upload:, col: "A", row: 2, field: "field_1") end - it "renders 1 row combining the errors" do + it "renders 1 table combining the errors" do result = render_inline(component) - expect(result).to have_selector("tbody tr", count: 1) + expect(result).to have_selector("table", count: 1) end it "render correct data" do result = render_inline(component) - row_1 = result.css("tbody tr:nth-of-type(1) td").map(&:content) + table_1 = result.css("table").css("th, td").map(&:content) - expect(row_1).to eql([ - "A", - "2", - BulkUpload::Lettings::Validator.question_for_field(error_1.field.to_sym), + expect(table_1).to eql([ + bulk_upload.prefix_namespace::RowParser.question_for_field(error_1.field.to_sym).to_s, + "Column A", error_1.error, - error_1.field, + "2 errors", ]) end end diff --git a/spec/components/check_answers_summary_list_card_component_spec.rb b/spec/components/check_answers_summary_list_card_component_spec.rb index f9b8f6667..41bf32e28 100644 --- a/spec/components/check_answers_summary_list_card_component_spec.rb +++ b/spec/components/check_answers_summary_list_card_component_spec.rb @@ -5,44 +5,63 @@ RSpec.describe CheckAnswersSummaryListCardComponent, type: :component do let(:rendered) { render_inline(component) } - context "when given a set of questions" do - let(:user) { build(:user) } - let(:log) { build(:lettings_log, :completed, age2: 99, startdate: Time.zone.local(2021, 5, 1)) } - let(:subsection_id) { "household_characteristics" } - let(:subsection) { log.form.get_subsection(subsection_id) } - let(:questions) { subsection.applicable_questions(log) } - - it "renders a summary list card for the answers to those questions" do - expect(rendered).to have_content(questions.first.answer_label(log)) - end + context "when before 23/24 collection" do + context "when given a set of questions" do + let(:user) { build(:user) } + let(:log) { build(:lettings_log, :completed, age2: 99, startdate: Time.zone.local(2021, 5, 1)) } + let(:subsection_id) { "household_characteristics" } + let(:subsection) { log.form.get_subsection(subsection_id) } + let(:questions) { subsection.applicable_questions(log) } - it "applicable questions doesn't return questions that are hidden in check answers" do - expect(component.applicable_questions.map(&:id).include?("retirement_value_check")).to eq(false) - end + it "renders a summary list card without question numbers for the answers to those questions" do + expect(rendered).to have_content(questions.first.answer_label(log)) + expect(rendered).to have_content("Lead tenant’s age") + expect(rendered).not_to have_content("Q32 - Lead tenant’s age") + end - it "has the correct answer label for a question" do - sex1_question = questions[2] - expect(component.get_answer_label(sex1_question)).to eq("Female") - end + it "applicable questions doesn't return questions that are hidden in check answers" do + expect(component.applicable_questions.map(&:id).include?("retirement_value_check")).to eq(false) + end + + it "has the correct answer label for a question" do + sex1_question = questions[2] + expect(component.get_answer_label(sex1_question)).to eq("Female") + end - context "when log was created via a bulk upload and has an unanswered question" do - subject(:component) { described_class.new(questions:, log:, user:) } + context "when log was created via a bulk upload and has an unanswered question" do + subject(:component) { described_class.new(questions:, log:, user:) } - let(:bulk_upload) { build(:bulk_upload, :lettings) } - let(:log) { build(:lettings_log, :in_progress, bulk_upload:, age2: 99, startdate: Time.zone.local(2021, 5, 1)) } + let(:bulk_upload) { build(:bulk_upload, :lettings) } + let(:log) { build(:lettings_log, :in_progress, bulk_upload:, age2: 99, startdate: Time.zone.local(2021, 5, 1)) } - it "displays tweaked copy in red" do - expect(rendered).to have_selector("span", class: "app-!-colour-red", text: "You still need to answer this question") + it "displays tweaked copy in red" do + expect(rendered).to have_selector("span", class: "app-!-colour-red", text: "You still need to answer this question") + end end - end - context "when log was not created via a bulk upload and has an unanswered question" do - subject(:component) { described_class.new(questions:, log:, user:) } + context "when log was not created via a bulk upload and has an unanswered question" do + subject(:component) { described_class.new(questions:, log:, user:) } + + let(:log) { build(:lettings_log, :in_progress, age2: 99, startdate: Time.zone.local(2021, 5, 1)) } + + it "displays normal copy with muted colour " do + expect(rendered).to have_selector("span", class: "app-!-colour-muted", text: "You didn’t answer this question") + end + end + end + end - let(:log) { build(:lettings_log, :in_progress, age2: 99, startdate: Time.zone.local(2021, 5, 1)) } + context "when in 23/24 collection" do + context "when given a set of questions" do + let(:user) { build(:user) } + let(:log) { build(:lettings_log, :completed, age2: 99, startdate: Time.zone.local(2023, 5, 1)) } + let(:subsection_id) { "household_characteristics" } + let(:subsection) { log.form.get_subsection(subsection_id) } + let(:questions) { subsection.applicable_questions(log) } - it "displays normal copy with muted colour " do - expect(rendered).to have_selector("span", class: "app-!-colour-muted", text: "You didn’t answer this question") + it "renders a summary list card includinq question numbers for the answers to those questions" do + expect(rendered).to have_content(questions.first.answer_label(log)) + expect(rendered).to have_content("Q32 - Lead tenant’s age") end end end diff --git a/spec/components/log_summary_component_spec.rb b/spec/components/log_summary_component_spec.rb index f8edfb948..99015b6d6 100644 --- a/spec/components/log_summary_component_spec.rb +++ b/spec/components/log_summary_component_spec.rb @@ -5,7 +5,7 @@ RSpec.describe LogSummaryComponent, type: :component do let(:coordinator_user) { FactoryBot.create(:user) } let(:propcode) { "P3647" } let(:tenancycode) { "T62863" } - let(:lettings_log) { FactoryBot.create(:lettings_log, needstype: 1, startdate: Time.utc(2022, 1, 1), tenancycode:, propcode:) } + let(:lettings_log) { FactoryBot.create(:lettings_log, needstype: 1, tenancycode:, propcode:, startdate: Time.zone.today) } let(:sales_log) { FactoryBot.create(:sales_log) } context "when rendering lettings log for a support user" do @@ -16,8 +16,8 @@ RSpec.describe LogSummaryComponent, type: :component do expect(result).to have_text(lettings_log.tenancycode) expect(result).to have_text(lettings_log.propcode) expect(result).to have_text("General needs") - expect(result).to have_text("Tenancy starts 1 January 2022") - expect(result).to have_text("Created 8 February 2022") + expect(result).to have_text("Tenancy starts #{Time.zone.today.strftime('%e %B %Y')}") + expect(result).to have_text("Created #{Time.zone.today.strftime('%e %B %Y')}") expect(result).to have_text("by Danny Rojas") expect(result).to have_content("Owned by\n DLUHC") expect(result).to have_content("Managed by\n DLUHC") diff --git a/spec/db/seeds_spec.rb b/spec/db/seeds_spec.rb index 15891b2da..fb41ccf36 100644 --- a/spec/db/seeds_spec.rb +++ b/spec/db/seeds_spec.rb @@ -29,7 +29,7 @@ RSpec.describe "seeding process", type: task do .and change(OrganisationRelationship, :count).by(4) .and change(Scheme, :count).by(3) .and change(Location, :count).by(3) - .and change(LaRentRange, :count).by(15_450) + .and change(LaRentRange, :count).by(22_850) end it "is idempotent" do diff --git a/spec/factories/lettings_log.rb b/spec/factories/lettings_log.rb index cb97eed68..b0667b817 100644 --- a/spec/factories/lettings_log.rb +++ b/spec/factories/lettings_log.rb @@ -7,7 +7,6 @@ FactoryBot.define do renewal { 0 } needstype { 1 } rent_type { 1 } - startdate { Time.zone.local(2022, 5, 1) } end trait :in_progress do status { 1 } @@ -18,7 +17,7 @@ FactoryBot.define do age2 { 19 } renewal { 1 } rent_type { 1 } - startdate { Time.zone.local(2021, 5, 1) } + startdate { Time.zone.today } end trait :soft_validations_triggered do status { 1 } @@ -36,6 +35,7 @@ FactoryBot.define do hhmemb { 1 } end trait :completed do + startdate { Time.zone.today } status { 2 } tenancycode { Faker::Name.initials(number: 10) } age1_known { 0 } @@ -66,7 +66,7 @@ FactoryBot.define do rsnvac { 6 } unittype_gn { 7 } beds { 3 } - voiddate { "03/11/2019" } + voiddate { 2.days.ago } offered { 2 } wchair { 1 } earnings { 68 } @@ -132,9 +132,8 @@ FactoryBot.define do hbrentshortfall { 1 } tshortfall { 12 } property_relet { 0 } - mrcdate { Time.zone.local(2020, 5, 5, 10, 36, 49) } + mrcdate { 1.day.ago } incref { 0 } - startdate { Time.zone.today } armedforces { 1 } builtype { 1 } unitletas { 2 } @@ -155,7 +154,7 @@ FactoryBot.define do sheltered { 0 } household_charge { 0 } end - created_at { Time.utc(2022, 2, 8, 16, 52, 15) } - updated_at { Time.utc(2022, 2, 8, 16, 52, 15) } + created_at { Time.zone.today } + updated_at { Time.zone.today } end end diff --git a/spec/factories/sales_log.rb b/spec/factories/sales_log.rb index f1da841a4..b2d6f37a5 100644 --- a/spec/factories/sales_log.rb +++ b/spec/factories/sales_log.rb @@ -14,7 +14,6 @@ FactoryBot.define do ownershipsch { 2 } type { 8 } saledate { Time.utc(2023, 2, 2, 10, 36, 49) } - companybuy { 1 } jointpur { 1 } beds { 2 } jointmore { 1 } diff --git a/spec/features/bulk_upload_sales_logs_spec.rb b/spec/features/bulk_upload_sales_logs_spec.rb index b69b6e237..e92b98a68 100644 --- a/spec/features/bulk_upload_sales_logs_spec.rb +++ b/spec/features/bulk_upload_sales_logs_spec.rb @@ -75,7 +75,7 @@ RSpec.describe "Bulk upload sales log" do expect(page).to have_link("Upload sales logs in bulk") click_link("Upload sales logs in bulk") - expect(page).to have_content("Upload sales logs in bulk (2022/23)") + expect(page).to have_content("Upload sales logs in bulk (2023/24)") click_button("Continue") expect(page).to have_content("Upload your file") diff --git a/spec/features/form/accessible_autocomplete_spec.rb b/spec/features/form/accessible_autocomplete_spec.rb index fd8102dcc..15d23fe32 100644 --- a/spec/features/form/accessible_autocomplete_spec.rb +++ b/spec/features/form/accessible_autocomplete_spec.rb @@ -1,7 +1,16 @@ require "rails_helper" require_relative "helpers" -RSpec.describe "Accessible Automcomplete" do +RSpec.describe "Accessible Autocomplete" do + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + include Helpers let(:user) { FactoryBot.create(:user) } let(:lettings_log) do @@ -64,8 +73,8 @@ RSpec.describe "Accessible Automcomplete" do let(:scheme) { FactoryBot.create(:scheme, owning_organisation_id: lettings_log.created_by.organisation_id, primary_client_group: "Q", secondary_client_group: "P") } before do - FactoryBot.create(:location, scheme:, postcode: "W6 0ST") - FactoryBot.create(:location, scheme:, postcode: "SE6 1LB") + FactoryBot.create(:location, scheme:, postcode: "W6 0ST", startdate: Time.zone.local(2022, 1, 1)) + FactoryBot.create(:location, scheme:, postcode: "SE6 1LB", startdate: Time.zone.local(2022, 1, 1)) lettings_log.update!(needstype: 2) visit("/lettings-logs/#{lettings_log.id}/scheme") end diff --git a/spec/features/form/check_answers_page_lettings_logs_spec.rb b/spec/features/form/check_answers_page_lettings_logs_spec.rb index 9062e1abc..97a9ccbec 100644 --- a/spec/features/form/check_answers_page_lettings_logs_spec.rb +++ b/spec/features/form/check_answers_page_lettings_logs_spec.rb @@ -2,6 +2,15 @@ require "rails_helper" require_relative "helpers" RSpec.describe "Lettings Log Check Answers Page" do + around do |example| + Timecop.freeze(Time.zone.local(2021, 5, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + include Helpers let(:user) { FactoryBot.create(:user) } let(:subsection) { "household-characteristics" } @@ -152,7 +161,7 @@ RSpec.describe "Lettings Log Check Answers Page" do context "when viewing setup section answers" do before do - FactoryBot.create(:location, scheme:) + FactoryBot.create(:location, scheme:, startdate: Time.zone.local(2021, 1, 1)) end it "displays inferred postcode with the location id" do diff --git a/spec/features/form/checkboxes_spec.rb b/spec/features/form/checkboxes_spec.rb index 056ff93cf..dae505bcf 100644 --- a/spec/features/form/checkboxes_spec.rb +++ b/spec/features/form/checkboxes_spec.rb @@ -14,6 +14,15 @@ RSpec.describe "Checkboxes" do end let(:id) { lettings_log.id } + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + before do allow(lettings_log.form).to receive(:end_date).and_return(Time.zone.today + 1.day) RequestHelper.stub_http_requests diff --git a/spec/features/form/conditional_questions_spec.rb b/spec/features/form/conditional_questions_spec.rb index 4fc9387da..f79b33191 100644 --- a/spec/features/form/conditional_questions_spec.rb +++ b/spec/features/form/conditional_questions_spec.rb @@ -2,6 +2,15 @@ require "rails_helper" require_relative "helpers" RSpec.describe "Form Conditional Questions" do + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + include Helpers let(:user) { FactoryBot.create(:user) } let(:lettings_log) do @@ -16,6 +25,7 @@ RSpec.describe "Form Conditional Questions" do :sales_log, :completed, created_by: user, + saledate: Time.zone.local(2022, 1, 1), ) end let(:id) { lettings_log.id } @@ -54,13 +64,13 @@ RSpec.describe "Form Conditional Questions" do end it "gets cleared if the conditional question is hidden after editing the answer" do - sales_log.update!(national: 12, othernational: "other") - visit("/sales-logs/#{sales_log.id}/buyer-1-nationality") - expect(page).to have_field("sales-log-othernational-field", with: "other") + sales_log.update!(age1_known: 0, age1: 50) + visit("/sales-logs/#{sales_log.id}/buyer-1-age") + expect(page).to have_field("sales-log-age1-field", with: 50) - choose("sales-log-national-18-field", allow_label_click: true) - choose("sales-log-national-12-field", allow_label_click: true) - expect(page).to have_field("sales-log-othernational-field", with: "") + choose("sales-log-age1-known-1-field", allow_label_click: true) + choose("sales-log-age1-known-0-field", allow_label_click: true) + expect(page).to have_field("sales-log-age1-field", with: "") end end end diff --git a/spec/features/form/form_navigation_spec.rb b/spec/features/form/form_navigation_spec.rb index 351675804..aa0223616 100644 --- a/spec/features/form/form_navigation_spec.rb +++ b/spec/features/form/form_navigation_spec.rb @@ -2,6 +2,15 @@ require "rails_helper" require_relative "helpers" RSpec.describe "Form Navigation" do + around do |example| + Timecop.travel(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + include Helpers let(:user) { FactoryBot.create(:user) } let(:lettings_log) do diff --git a/spec/features/form/page_routing_spec.rb b/spec/features/form/page_routing_spec.rb index eb4f6acc2..312e0752b 100644 --- a/spec/features/form/page_routing_spec.rb +++ b/spec/features/form/page_routing_spec.rb @@ -20,95 +20,106 @@ RSpec.describe "Form Page Routing" do sign_in user end - it "can route the user to a different page based on their answer on the current page", js: true do - visit("/lettings-logs/#{id}/conditional-question") - # using a question name that is already in the db to avoid - # having to add a new column to the db for this test - choose("lettings-log-preg-occ-1-field", allow_label_click: true) - click_button("Save and continue") - expect(page).to have_current_path("/lettings-logs/#{id}/conditional-question-yes-page") - click_link(text: "Back") - expect(page).to have_current_path("/lettings-logs/#{id}/conditional-question") - choose("lettings-log-preg-occ-2-field", allow_label_click: true) - click_button("Save and continue") - expect(page).to have_current_path("/lettings-logs/#{id}/conditional-question-no-page") - end - - it "can route based on multiple conditions", js: true do - visit("/lettings-logs/#{id}/person-1-gender") - choose("lettings-log-sex1-f-field", allow_label_click: true) - click_button("Save and continue") - expect(page).to have_current_path("/lettings-logs/#{id}/person-1-working-situation") - visit("/lettings-logs/#{id}/conditional-question") - choose("lettings-log-preg-occ-2-field", allow_label_click: true) - click_button("Save and continue") - expect(page).to have_current_path("/lettings-logs/#{id}/conditional-question-no-page") - choose("lettings-log-cbl-0-field", allow_label_click: true) - click_button("Save and continue") - expect(page).to have_current_path("/lettings-logs/#{id}/conditional-question/check-answers") - end + context "with 21/22 logs" do + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end - context "when the answers are inferred", js: true do - it "shows question if the answer could not be inferred" do - visit("/lettings-logs/#{id}/property-postcode") - fill_in("lettings-log-postcode-full-field", with: "PO5 3TE") + it "can route the user to a different page based on their answer on the current page", js: true do + visit("/lettings-logs/#{id}/conditional-question") + # using a question name that is already in the db to avoid + # having to add a new column to the db for this test + choose("lettings-log-preg-occ-1-field", allow_label_click: true) + click_button("Save and continue") + expect(page).to have_current_path("/lettings-logs/#{id}/conditional-question-yes-page") + click_link(text: "Back") + expect(page).to have_current_path("/lettings-logs/#{id}/conditional-question") + choose("lettings-log-preg-occ-2-field", allow_label_click: true) click_button("Save and continue") - expect(page).to have_current_path("/lettings-logs/#{id}/do-you-know-the-local-authority") + expect(page).to have_current_path("/lettings-logs/#{id}/conditional-question-no-page") end - it "shows question if the answer could not be inferred from an empty input" do - visit("/lettings-logs/#{id}/property-postcode") + it "can route based on multiple conditions", js: true do + visit("/lettings-logs/#{id}/person-1-gender") + choose("lettings-log-sex1-f-field", allow_label_click: true) click_button("Save and continue") - expect(page).to have_current_path("/lettings-logs/#{id}/do-you-know-the-local-authority") + expect(page).to have_current_path("/lettings-logs/#{id}/person-1-working-situation") + visit("/lettings-logs/#{id}/conditional-question") + choose("lettings-log-preg-occ-2-field", allow_label_click: true) + click_button("Save and continue") + expect(page).to have_current_path("/lettings-logs/#{id}/conditional-question-no-page") + choose("lettings-log-cbl-0-field", allow_label_click: true) + click_button("Save and continue") + expect(page).to have_current_path("/lettings-logs/#{id}/conditional-question/check-answers") end - it "does not show question if the answer could be inferred" do - stub_request(:get, /api.postcodes.io/) - .to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\", \"codes\":{\"admin_district\": \"E08000003\"}}}", headers: {}) + context "when the answers are inferred", js: true do + it "shows question if the answer could not be inferred" do + visit("/lettings-logs/#{id}/property-postcode") + fill_in("lettings-log-postcode-full-field", with: "PO5 3TE") + click_button("Save and continue") + expect(page).to have_current_path("/lettings-logs/#{id}/do-you-know-the-local-authority") + end - visit("/lettings-logs/#{id}/property-postcode") - fill_in("lettings-log-postcode-full-field", with: "P0 5ST") - click_button("Save and continue") - expect(page).to have_current_path("/lettings-logs/#{id}/property-wheelchair-accessible") - end - end + it "shows question if the answer could not be inferred from an empty input" do + visit("/lettings-logs/#{id}/property-postcode") + click_button("Save and continue") + expect(page).to have_current_path("/lettings-logs/#{id}/do-you-know-the-local-authority") + end - context "when answer is invalid" do - it "shows error with invalid value in the field" do - visit("/lettings-logs/#{id}/property-postcode") - fill_in("lettings-log-postcode-full-field", with: "fake_postcode") - click_button("Save and continue") + it "does not show question if the answer could be inferred" do + stub_request(:get, /api.postcodes.io/) + .to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\", \"codes\":{\"admin_district\": \"E08000003\"}}}", headers: {}) - expect(page).to have_current_path("/lettings-logs/#{id}/property-postcode") - expect(find("#lettings-log-postcode-full-field-error").value).to eq("fake_postcode") + visit("/lettings-logs/#{id}/property-postcode") + fill_in("lettings-log-postcode-full-field", with: "P0 5ST") + click_button("Save and continue") + expect(page).to have_current_path("/lettings-logs/#{id}/property-wheelchair-accessible") + end end - it "does not reset the displayed date" do - lettings_log.update!(startdate: "2021/10/13") - visit("/lettings-logs/#{id}/tenancy-start-date") - fill_in("lettings_log[startdate(1i)]", with: "202") - fill_in("lettings_log[startdate(2i)]", with: "32") - fill_in("lettings_log[startdate(3i)]", with: "0") - click_button("Save and continue") + context "when answer is invalid" do + it "shows error with invalid value in the field" do + visit("/lettings-logs/#{id}/property-postcode") + fill_in("lettings-log-postcode-full-field", with: "fake_postcode") + click_button("Save and continue") - expect(page).to have_current_path("/lettings-logs/#{id}/tenancy-start-date") - expect(find_field("lettings_log[startdate(3i)]").value).to eq("13") - expect(find_field("lettings_log[startdate(2i)]").value).to eq("10") - expect(find_field("lettings_log[startdate(1i)]").value).to eq("2021") - end + expect(page).to have_current_path("/lettings-logs/#{id}/property-postcode") + expect(find("#lettings-log-postcode-full-field-error").value).to eq("fake_postcode") + end - it "does not reset the displayed date if it's empty" do - lettings_log.update!(startdate: nil) - visit("/lettings-logs/#{id}/tenancy-start-date") - fill_in("lettings_log[startdate(1i)]", with: "202") - fill_in("lettings_log[startdate(2i)]", with: "32") - fill_in("lettings_log[startdate(3i)]", with: "0") - click_button("Save and continue") + it "does not reset the displayed date" do + lettings_log.update!(startdate: "2021/10/13") + visit("/lettings-logs/#{id}/tenancy-start-date") + fill_in("lettings_log[startdate(1i)]", with: "202") + fill_in("lettings_log[startdate(2i)]", with: "32") + fill_in("lettings_log[startdate(3i)]", with: "0") + click_button("Save and continue") + + expect(page).to have_current_path("/lettings-logs/#{id}/tenancy-start-date") + expect(find_field("lettings_log[startdate(3i)]").value).to eq("13") + expect(find_field("lettings_log[startdate(2i)]").value).to eq("10") + expect(find_field("lettings_log[startdate(1i)]").value).to eq("2021") + end - expect(page).to have_current_path("/lettings-logs/#{id}/tenancy-start-date") - expect(find_field("lettings_log[startdate(3i)]").value).to eq(nil) - expect(find_field("lettings_log[startdate(2i)]").value).to eq(nil) - expect(find_field("lettings_log[startdate(1i)]").value).to eq(nil) + it "does not reset the displayed date if it's empty" do + lettings_log.update!(startdate: nil) + visit("/lettings-logs/#{id}/tenancy-start-date") + fill_in("lettings_log[startdate(1i)]", with: "202") + fill_in("lettings_log[startdate(2i)]", with: "32") + fill_in("lettings_log[startdate(3i)]", with: "0") + click_button("Save and continue") + + expect(page).to have_current_path("/lettings-logs/#{id}/tenancy-start-date") + expect(find_field("lettings_log[startdate(3i)]").value).to eq(nil) + expect(find_field("lettings_log[startdate(2i)]").value).to eq(nil) + expect(find_field("lettings_log[startdate(1i)]").value).to eq(nil) + end end end diff --git a/spec/features/form/progressive_total_field_spec.rb b/spec/features/form/progressive_total_field_spec.rb index e5959d16d..cbf50f206 100644 --- a/spec/features/form/progressive_total_field_spec.rb +++ b/spec/features/form/progressive_total_field_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" require_relative "helpers" -RSpec.describe "Accessible Automcomplete" do +RSpec.describe "Accessible Autocomplete" do include Helpers let(:user) { FactoryBot.create(:user) } let(:lettings_log) do @@ -12,6 +12,15 @@ RSpec.describe "Accessible Automcomplete" do ) end + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + before do allow(lettings_log.form).to receive(:end_date).and_return(Time.zone.today + 1.day) sign_in user diff --git a/spec/features/form/saving_data_spec.rb b/spec/features/form/saving_data_spec.rb index 7a7996457..0c7397511 100644 --- a/spec/features/form/saving_data_spec.rb +++ b/spec/features/form/saving_data_spec.rb @@ -2,6 +2,15 @@ require "rails_helper" require_relative "helpers" RSpec.describe "Form Saving Data" do + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + include Helpers let(:user) { FactoryBot.create(:user) } let(:lettings_log) do diff --git a/spec/features/form/tasklist_page_spec.rb b/spec/features/form/tasklist_page_spec.rb index 09d332583..ba06a4051 100644 --- a/spec/features/form/tasklist_page_spec.rb +++ b/spec/features/form/tasklist_page_spec.rb @@ -36,18 +36,32 @@ RSpec.describe "Task List" do :about_completed, owning_organisation: user.organisation, managing_organisation: user.organisation, - startdate: Time.zone.local(2021, 5, 1), created_by: user, ) end let(:id) { lettings_log.id } let(:status) { lettings_log.status } + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + before do + Timecop.freeze(Time.zone.local(2021, 5, 1)) + setup_completed_log.update!(startdate: Time.zone.local(2021, 5, 1)) allow(lettings_log.form).to receive(:end_date).and_return(Time.zone.today + 1.day) sign_in user end + after do + Timecop.unfreeze + end + it "shows if the section has not been started" do visit("/lettings-logs/#{empty_lettings_log.id}") expect(page).to have_content("This log has not been started.") diff --git a/spec/features/form/validations_spec.rb b/spec/features/form/validations_spec.rb index 24b2816ce..12e5bb657 100644 --- a/spec/features/form/validations_spec.rb +++ b/spec/features/form/validations_spec.rb @@ -2,6 +2,15 @@ require "rails_helper" require_relative "helpers" RSpec.describe "validations" do + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + let(:fake_2021_2022_form) { Form.new("spec/fixtures/forms/2021_2022.json") } let(:user) { FactoryBot.create(:user) } let(:lettings_log) do @@ -26,6 +35,8 @@ RSpec.describe "validations" do status: 1, declaration: nil, startdate: Time.zone.local(2021, 5, 1), + voiddate: Time.zone.local(2021, 5, 1), + mrcdate: Time.zone.local(2021, 5, 1), ) end let(:id) { lettings_log.id } diff --git a/spec/features/lettings_log_spec.rb b/spec/features/lettings_log_spec.rb index f145f9e7c..483924f0f 100644 --- a/spec/features/lettings_log_spec.rb +++ b/spec/features/lettings_log_spec.rb @@ -89,7 +89,7 @@ RSpec.describe "Lettings Log Features" do click_button("Save and continue") log_id = page.current_path.scan(/\d/).join visit("lettings-logs/#{log_id}/setup/check-answers") - expect(page).to have_content("Stock owner User org") + expect(page).to have_content("Stock owner User org", normalize_ws: true) expect(page).to have_content("You have answered 2 of 8 questions") end end @@ -125,7 +125,7 @@ RSpec.describe "Lettings Log Features" do select(managing_org.name, from: "lettings-log-managing-organisation-id-field") click_button("Save and continue") visit("lettings-logs/#{log_id}/setup/check-answers") - expect(page).to have_content("Managing agent Managing org") + expect(page).to have_content("Managing agent Managing org", normalize_ws: true) expect(support_user.organisation.managing_agents).to eq([org_rel.child_organisation]) end end @@ -164,7 +164,7 @@ RSpec.describe "Lettings Log Features" do select(managing_org1.name, from: "lettings-log-managing-organisation-id-field") click_button("Save and continue") visit("lettings-logs/#{log_id}/setup/check-answers") - expect(page).to have_content("Managing agent Managing org 1") + expect(page).to have_content("Managing agent Managing org 1", normalize_ws: true) end context "and the owning organisation has 2 or more managing agents" do @@ -183,10 +183,10 @@ RSpec.describe "Lettings Log Features" do select(managing_org1.name, from: "lettings-log-managing-organisation-id-field") click_button("Save and continue") visit("lettings-logs/#{log_id}/setup/check-answers") - expect(page).to have_content("Managing agent Managing org 1") + expect(page).to have_content("Managing agent Managing org 1", normalize_ws: true) org_rel1.destroy! visit("lettings-logs/#{log_id}/setup/check-answers") - expect(page).to have_content("Managing agent Managing org 1") + expect(page).to have_content("Managing agent Managing org 1", normalize_ws: true) expect(support_user.organisation.managing_agents).to eq([org_rel2.child_organisation]) end end @@ -237,7 +237,7 @@ RSpec.describe "Lettings Log Features" do log_id = page.current_path.scan(/\d/).join expect(page).to have_current_path("/lettings-logs/#{log_id}/stock-owner") visit("lettings-logs/#{log_id}/setup/check-answers") - expect(page).to have_content("Stock owner User org") + expect(page).to have_content("Stock owner User org", normalize_ws: true) end context "and there are 3 or more potential stock owners" do @@ -254,10 +254,10 @@ RSpec.describe "Lettings Log Features" do select(owning_org1.name, from: "lettings-log-owning-organisation-id-field") click_button("Save and continue") visit("lettings-logs/#{log_id}/setup/check-answers") - expect(page).to have_content("Stock owner Owning org 1") + expect(page).to have_content("Stock owner Owning org 1", normalize_ws: true) org_rel1.destroy! visit("lettings-logs/#{log_id}/setup/check-answers") - expect(page).to have_content("Stock owner Owning org 1") + expect(page).to have_content("Stock owner Owning org 1", normalize_ws: true) expect(user.organisation.stock_owners).to eq([org_rel2.parent_organisation]) end end @@ -283,7 +283,8 @@ RSpec.describe "Lettings Log Features" do select(user.organisation.name, from: "lettings-log-managing-organisation-id-field") click_button("Save and continue") visit("lettings-logs/#{log_id}/setup/check-answers") - expect(page).to have_content("Managing agent User org") + + expect(page).to have_content("Managing agent User org", normalize_ws: true) expect(user.organisation.stock_owners).to eq([org_rel1.parent_organisation, org_rel2.parent_organisation]) end end @@ -328,7 +329,7 @@ RSpec.describe "Lettings Log Features" do select(managing_org.name, from: "lettings-log-managing-organisation-id-field") click_button("Save and continue") visit("lettings-logs/#{log_id}/setup/check-answers") - expect(page).to have_content("Managing agent Managing org") + expect(page).to have_content("Managing agent Managing org", normalize_ws: true) expect(user.organisation.managing_agents).to eq([org_rel2.child_organisation]) end end diff --git a/spec/features/schemes_helpers.rb b/spec/features/schemes_helpers.rb index 4ce1063c1..d5e5a8e22 100644 --- a/spec/features/schemes_helpers.rb +++ b/spec/features/schemes_helpers.rb @@ -64,7 +64,8 @@ module SchemesHelpers click_button "Add a location" fill_in with: "AA11AA" click_button "Save and continue" - fill_in with: "Adur" + select "Adur" + click_button "Save and continue" fill_in with: "Some name" click_button "Save and continue" fill_in with: 5 @@ -84,7 +85,8 @@ module SchemesHelpers click_button "Add a location" fill_in with: "AA12AA" click_button "Save and continue" - fill_in with: "Adur" + select "Adur" + click_button "Save and continue" fill_in with: "Other name" click_button "Save and continue" fill_in with: 2 diff --git a/spec/features/schemes_spec.rb b/spec/features/schemes_spec.rb index fefa3ea56..15487fc53 100644 --- a/spec/features/schemes_spec.rb +++ b/spec/features/schemes_spec.rb @@ -284,7 +284,8 @@ RSpec.describe "Schemes scheme Features" do before do fill_in with: "AA12AA" click_button "Save and continue" - fill_in with: "Adur" + select "Adur" + click_button "Save and continue" fill_in with: location_name click_button "Save and continue" fill_in with: 1 @@ -904,7 +905,8 @@ RSpec.describe "Schemes scheme Features" do before do fill_in with: "AA12AA" click_button "Save and continue" - fill_in with: "Adur" + select "Adur" + click_button "Save and continue" fill_in with: location_name click_button "Save and continue" fill_in with: 1 diff --git a/spec/fixtures/exports/general_needs_log.csv b/spec/fixtures/exports/general_needs_log.csv index 8cc656f19..0185f54e0 100644 --- a/spec/fixtures/exports/general_needs_log.csv +++ b/spec/fixtures/exports/general_needs_log.csv @@ -1,2 +1,2 @@ status,tenancycode,age1,sex1,ethnic,national,prevten,ecstat1,hhmemb,age2,sex2,ecstat2,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,leftreg,reservist,illness,preg_occ,startertenancy,tenancylength,tenancy,ppostcode_full,rsnvac,unittype_gn,beds,offered,wchair,earnings,incfreq,benefits,period,layear,waityear,postcode_full,reasonpref,cbl,chr,cap,reasonother,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,illness_type_1,illness_type_2,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,irproduct_other,reason,propcode,la,prevloc,hb,hbrentshortfall,mrcdate,incref,startdate,armedforces,unitletas,builtype,voiddate,renttype,needstype,lettype,totchild,totelder,totadult,nocharge,referral,brent,scharge,pscharge,supcharg,tcharge,tshortfall,chcharge,ppcodenk,has_benefits,renewal,wrent,wscharge,wpschrge,wsupchrg,wtcharge,wtshortfall,refused,housingneeds,wchchrg,newprop,relat2,relat3,relat4,relat5,relat6,relat7,relat8,lar,irproduct,joint,sheltered,hhtype,new_old,vacdays,formid,owningorgid,owningorgname,hcnum,maningorgid,maningorgname,manhcnum,createddate,uploaddate -2,BZ737,35,F,2,4,6,0,2,32,M,6,,,,,,,,,,,,,,,,,,,1,4,1,1,1,2,1,5,1,SE2 6RT,6,7,3,2,1,68,1,1,2,2,1,NW1 5TY,1,2,1,2,,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,,,4,123,E09000003,E07000105,6,1,2020-05-05T10:36:49+01:00,0,2022-02-02T10:36:49+00:00,1,2,1,2019-11-03T00:00:00+00:00,2,1,7,0,0,2,0,2,200.0,50.0,40.0,35.0,325.0,12.0,,1,1,0,100.0,25.0,20.0,17.5,162.5,6.0,0,1,,2,P,,,,,,,,,,,4,2,638,{id},{owning_org_id},DLUHC,1234,{managing_org_id},DLUHC,1234,2022-02-08T16:52:15+00:00,2022-02-08T16:52:15+00:00 +2,BZ737,35,F,2,4,6,0,2,32,M,6,,,,,,,,,,,,,,,,,,,1,4,1,1,1,2,1,5,1,SE2 6RT,6,7,3,2,1,68,1,1,2,2,1,NW1 5TY,1,2,1,2,,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,,,4,123,E09000003,E07000105,6,1,2020-05-05T10:36:49+01:00,0,2022-02-02T10:36:49+00:00,1,2,1,2019-11-03T00:00:00+00:00,2,1,7,0,0,2,0,2,200.0,50.0,40.0,35.0,325.0,12.0,,1,1,0,100.0,25.0,20.0,17.5,162.5,6.0,0,1,,2,P,,,,,,,,,,,4,2,638,{id},{owning_org_id},DLUHC,1234,{managing_org_id},DLUHC,1234,2022-05-01T00:00:00+01:00,2022-05-01T00:00:00+01:00 diff --git a/spec/fixtures/exports/general_needs_log.xml b/spec/fixtures/exports/general_needs_log.xml index 62542af54..f05de09e3 100644 --- a/spec/fixtures/exports/general_needs_log.xml +++ b/spec/fixtures/exports/general_needs_log.xml @@ -142,8 +142,8 @@ {managing_org_id} DLUHC 1234 - 2022-02-08T16:52:15+00:00 - 2022-02-08T16:52:15+00:00 + 2022-05-01T00:00:00+01:00 + 2022-05-01T00:00:00+01:00 1 diff --git a/spec/fixtures/exports/supported_housing_logs.xml b/spec/fixtures/exports/supported_housing_logs.xml index 69f52161c..0a0ed0981 100644 --- a/spec/fixtures/exports/supported_housing_logs.xml +++ b/spec/fixtures/exports/supported_housing_logs.xml @@ -141,8 +141,8 @@ {managing_org_id} DLUHC 1234 - 2022-02-08T16:52:15+00:00 - 2022-02-08T16:52:15+00:00 + 2022-05-01T00:00:00+01:00 + 2022-05-01T00:00:00+01:00 7 1 G diff --git a/spec/fixtures/files/lettings_logs_download.csv b/spec/fixtures/files/lettings_logs_download.csv index ecd41667d..394c3b920 100644 --- a/spec/fixtures/files/lettings_logs_download.csv +++ b/spec/fixtures/files/lettings_logs_download.csv @@ -1,2 +1,2 @@ -id,status,created_at,updated_at,created_by_name,is_dpo,owning_organisation_name,managing_organisation_name,collection_start_year,needstype,renewal,startdate,rent_type_detail,irproduct_other,tenancycode,propcode,age1,sex1,ecstat1,hhmemb,relat2,age2,sex2,retirement_value_check,ecstat2,armedforces,leftreg,illness,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_h,is_previous_la_inferred,prevloc_label,prevloc,illness_type_1,illness_type_2,is_la_inferred,la_label,la,postcode_known,postcode_full,previous_la_known,wchair,preg_occ,cbl,earnings,incfreq,net_income_value_check,benefits,hb,period,brent,scharge,pscharge,supcharg,tcharge,offered,layear,ppostcode_full,mrcdate,declaration,ethnic,national,prevten,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,reservist,startertenancy,tenancylength,tenancy,rsnvac,unittype_gn,beds,waityear,reasonpref,chr,cap,reasonother,housingneeds_f,housingneeds_g,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,property_owner_organisation,property_manager_organisation,purchaser_code,reason,majorrepairs,hbrentshortfall,property_relet,incref,first_time_property_let_as_social_housing,unitletas,builtype,voiddate,renttype,lettype,totchild,totelder,totadult,net_income_known,nocharge,is_carehome,household_charge,referral,tshortfall,chcharge,ppcodenk,age1_known,age2_known,age3_known,age4_known,age5_known,age6_known,age7_known,age8_known,ethnic_group,letting_allocation_unknown,details_known_2,details_known_3,details_known_4,details_known_5,details_known_6,details_known_7,details_known_8,has_benefits,wrent,wscharge,wpschrge,wsupchrg,wtcharge,wtshortfall,refused,housingneeds,wchchrg,newprop,relat3,relat4,relat5,relat6,relat7,relat8,rent_value_check,old_form_id,lar,irproduct,old_id,joint,tshortfall_known,sheltered,pregnancy_value_check,hhtype,new_old,vacdays,major_repairs_date_value_check,void_date_value_check,housingneeds_type,housingneeds_other,unresolved,updated_by_id,unittype_sh,scheme_code,scheme_service_name,scheme_sensitive,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate -{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,No,DLUHC,DLUHC,2021,Supported housing,,2 October 2021,London Affordable Rent,,,,,,,,,,,,,,,,,,,,No,,,,,No,Westminster,E09000033,,SE1 1TE,,No,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,8,0,0,0,,0,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,0,,,,,,,,,,,,,,,,,,,9,1,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},Missing,No,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,Bungalow,Fitted with equipment and adaptations,Westminster,{location_startdate} +id,status,created_at,updated_at,created_by_name,is_dpo,owning_organisation_name,managing_organisation_name,collection_start_year,needstype,renewal,startdate,rent_type_detail,irproduct_other,tenancycode,propcode,age1,sex1,ecstat1,hhmemb,relat2,age2,sex2,retirement_value_check,ecstat2,armedforces,leftreg,illness,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_h,is_previous_la_inferred,prevloc_label,prevloc,illness_type_1,illness_type_2,is_la_inferred,la_label,la,postcode_known,postcode_full,previous_la_known,wchair,preg_occ,cbl,earnings,incfreq,net_income_value_check,benefits,hb,period,brent,scharge,pscharge,supcharg,tcharge,offered,layear,ppostcode_full,mrcdate,declaration,ethnic,national,prevten,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,reservist,startertenancy,tenancylength,tenancy,rsnvac,unittype_gn,beds,waityear,reasonpref,chr,cap,reasonother,housingneeds_f,housingneeds_g,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,property_owner_organisation,property_manager_organisation,purchaser_code,reason,majorrepairs,hbrentshortfall,property_relet,incref,first_time_property_let_as_social_housing,unitletas,builtype,voiddate,renttype,lettype,totchild,totelder,totadult,net_income_known,nocharge,is_carehome,household_charge,referral,tshortfall,chcharge,ppcodenk,age1_known,age2_known,age3_known,age4_known,age5_known,age6_known,age7_known,age8_known,ethnic_group,letting_allocation_unknown,details_known_2,details_known_3,details_known_4,details_known_5,details_known_6,details_known_7,details_known_8,has_benefits,wrent,wscharge,wpschrge,wsupchrg,wtcharge,wtshortfall,refused,housingneeds,wchchrg,newprop,relat3,relat4,relat5,relat6,relat7,relat8,rent_value_check,old_form_id,lar,irproduct,old_id,joint,tshortfall_known,sheltered,pregnancy_value_check,hhtype,new_old,vacdays,major_repairs_date_value_check,void_date_value_check,housingneeds_type,housingneeds_other,unresolved,updated_by_id,uprn,uprn_known,uprn_confirmed,address_line1,address_line2,town_or_city,county,unittype_sh,scheme_code,scheme_service_name,scheme_sensitive,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate +{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,No,DLUHC,DLUHC,2021,Supported housing,,2 October 2021,London Affordable Rent,,,,,,,,,,,,,,,,,,,,No,,,,,No,Westminster,E09000033,,SE1 1TE,,No,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,8,0,0,0,,0,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,0,,,,,,,,,,,,,,,,,,,9,1,,,,,,,,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},Missing,No,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,Bungalow,Fitted with equipment and adaptations,Westminster,{location_startdate} diff --git a/spec/fixtures/files/lettings_logs_download_codes_only.csv b/spec/fixtures/files/lettings_logs_download_codes_only.csv new file mode 100644 index 000000000..423675c5b --- /dev/null +++ b/spec/fixtures/files/lettings_logs_download_codes_only.csv @@ -0,0 +1,2 @@ +id,status,created_at,updated_at,created_by_name,is_dpo,owning_organisation_name,managing_organisation_name,collection_start_year,needstype,renewal,startdate,rent_type_detail,irproduct_other,tenancycode,propcode,age1,sex1,ecstat1,hhmemb,relat2,age2,sex2,retirement_value_check,ecstat2,armedforces,leftreg,illness,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_h,is_previous_la_inferred,prevloc_label,prevloc,illness_type_1,illness_type_2,is_la_inferred,la_label,la,postcode_known,postcode_full,previous_la_known,wchair,preg_occ,cbl,earnings,incfreq,net_income_value_check,benefits,hb,period,brent,scharge,pscharge,supcharg,tcharge,offered,layear,ppostcode_full,mrcdate,declaration,ethnic,national,prevten,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,reservist,startertenancy,tenancylength,tenancy,rsnvac,unittype_gn,beds,waityear,reasonpref,chr,cap,reasonother,housingneeds_f,housingneeds_g,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,property_owner_organisation,property_manager_organisation,purchaser_code,reason,majorrepairs,hbrentshortfall,property_relet,incref,first_time_property_let_as_social_housing,unitletas,builtype,voiddate,renttype,lettype,totchild,totelder,totadult,net_income_known,nocharge,is_carehome,household_charge,referral,tshortfall,chcharge,ppcodenk,age1_known,age2_known,age3_known,age4_known,age5_known,age6_known,age7_known,age8_known,ethnic_group,letting_allocation_unknown,details_known_2,details_known_3,details_known_4,details_known_5,details_known_6,details_known_7,details_known_8,has_benefits,wrent,wscharge,wpschrge,wsupchrg,wtcharge,wtshortfall,refused,housingneeds,wchchrg,newprop,relat3,relat4,relat5,relat6,relat7,relat8,rent_value_check,old_form_id,lar,irproduct,old_id,joint,tshortfall_known,sheltered,pregnancy_value_check,hhtype,new_old,vacdays,major_repairs_date_value_check,void_date_value_check,housingneeds_type,housingneeds_other,unresolved,updated_by_id,uprn,uprn_known,uprn_confirmed,address_line1,address_line2,town_or_city,county,unittype_sh,scheme_code,scheme_service_name,scheme_sensitive,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate +{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,false,DLUHC,DLUHC,2021,2,,2 October 2021,2,,,,,,,,,,,,,,,,,,,,false,,,,,false,Westminster,E09000033,,SE1 1TE,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,8,0,0,0,,0,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,0,,,,,,,,,,,,,,,,,,,9,1,,,,,,,,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},0,1,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,6,A,Westminster,{location_startdate} diff --git a/spec/fixtures/files/lettings_logs_download_non_support.csv b/spec/fixtures/files/lettings_logs_download_non_support.csv index 2db794f49..a2fa80f4f 100644 --- a/spec/fixtures/files/lettings_logs_download_non_support.csv +++ b/spec/fixtures/files/lettings_logs_download_non_support.csv @@ -1,2 +1,2 @@ -id,status,created_at,updated_at,created_by_name,is_dpo,owning_organisation_name,managing_organisation_name,collection_start_year,renewal,startdate,irproduct_other,tenancycode,propcode,age1,sex1,ecstat1,relat2,age2,sex2,ecstat2,armedforces,leftreg,illness,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_h,prevloc_label,illness_type_1,illness_type_2,la_label,postcode_full,wchair,preg_occ,cbl,earnings,incfreq,benefits,hb,period,brent,scharge,pscharge,supcharg,tcharge,offered,layear,ppostcode_full,mrcdate,declaration,ethnic,national,prevten,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,reservist,startertenancy,tenancylength,tenancy,rsnvac,unittype_gn,beds,waityear,reasonpref,chr,cap,reasonother,housingneeds_f,housingneeds_g,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,property_owner_organisation,property_manager_organisation,purchaser_code,reason,majorrepairs,hbrentshortfall,property_relet,incref,unitletas,builtype,voiddate,lettype,nocharge,household_charge,referral,tshortfall,chcharge,ppcodenk,ethnic_group,has_benefits,refused,housingneeds,wchchrg,newprop,relat3,relat4,relat5,relat6,relat7,relat8,lar,irproduct,joint,sheltered,major_repairs_date_value_check,void_date_value_check,housingneeds_type,housingneeds_other,unittype_sh,scheme_code,scheme_service_name,scheme_sensitive,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate -{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,No,DLUHC,DLUHC,2021,,2 October 2021,,,,,,,,,,,,,,,,,,,,,Westminster,SE1 1TE,No,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},Missing,No,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,Bungalow,Fitted with equipment and adaptations,Westminster,{location_startdate} +id,status,created_at,updated_at,created_by_name,is_dpo,owning_organisation_name,managing_organisation_name,collection_start_year,renewal,startdate,irproduct_other,tenancycode,propcode,age1,sex1,ecstat1,relat2,age2,sex2,ecstat2,armedforces,leftreg,illness,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_h,prevloc_label,illness_type_1,illness_type_2,la_label,postcode_full,wchair,preg_occ,cbl,earnings,incfreq,benefits,hb,period,brent,scharge,pscharge,supcharg,tcharge,offered,layear,ppostcode_full,mrcdate,declaration,ethnic,national,prevten,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,reservist,startertenancy,tenancylength,tenancy,rsnvac,unittype_gn,beds,waityear,reasonpref,chr,cap,reasonother,housingneeds_f,housingneeds_g,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,property_owner_organisation,property_manager_organisation,purchaser_code,reason,majorrepairs,hbrentshortfall,property_relet,incref,unitletas,builtype,voiddate,lettype,nocharge,household_charge,referral,tshortfall,chcharge,ppcodenk,ethnic_group,has_benefits,refused,housingneeds,wchchrg,newprop,relat3,relat4,relat5,relat6,relat7,relat8,lar,irproduct,joint,sheltered,major_repairs_date_value_check,void_date_value_check,housingneeds_type,housingneeds_other,uprn,uprn_known,uprn_confirmed,address_line1,address_line2,town_or_city,county,unittype_sh,scheme_code,scheme_service_name,scheme_sensitive,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate +{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,No,DLUHC,DLUHC,2021,,2 October 2021,,,,,,,,,,,,,,,,,,,,,Westminster,SE1 1TE,No,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},Missing,No,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,Bungalow,Fitted with equipment and adaptations,Westminster,{location_startdate} diff --git a/spec/fixtures/files/local_authorities.csv b/spec/fixtures/files/local_authorities.csv new file mode 100644 index 000000000..d1cebba6b --- /dev/null +++ b/spec/fixtures/files/local_authorities.csv @@ -0,0 +1,6 @@ +code,name,start_year,end_year +S12000033,Aberdeen City,2021, +S12000034,Aberdeenshire,2021, +E07000223,Adur,2021, +E07000032,Amber Valley,2021, +S12000041,Angus,2021, \ No newline at end of file diff --git a/spec/fixtures/files/local_authority_links_2023.csv b/spec/fixtures/files/local_authority_links_2023.csv new file mode 100644 index 000000000..5cf6f4798 --- /dev/null +++ b/spec/fixtures/files/local_authority_links_2023.csv @@ -0,0 +1,6 @@ +local_authority_code,linked_local_authority_code +E06000063,E07000027 +E06000063,E07000030 +E06000063,E07000031 +E07000027,E06000063 +E07000030,E06000063 diff --git a/spec/helpers/check_answers_helper_spec.rb b/spec/helpers/check_answers_helper_spec.rb index d60c79f51..716c93827 100644 --- a/spec/helpers/check_answers_helper_spec.rb +++ b/spec/helpers/check_answers_helper_spec.rb @@ -6,6 +6,15 @@ RSpec.describe CheckAnswersHelper do let(:lettings_log) { FactoryBot.build(:lettings_log, :in_progress) } let(:current_user) { FactoryBot.build(:user) } + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + describe "display_answered_questions_summary" do context "when a section hasn't been completed yet" do it "returns that you have unanswered questions" do diff --git a/spec/helpers/collection_time_helper_spec.rb b/spec/helpers/collection_time_helper_spec.rb index 0c187020e..43a14025e 100644 --- a/spec/helpers/collection_time_helper_spec.rb +++ b/spec/helpers/collection_time_helper_spec.rb @@ -9,6 +9,7 @@ RSpec.describe CollectionTimeHelper do Timecop.freeze(now) do example.run end + Timecop.return end context "when the date is after 1st of April" do diff --git a/spec/helpers/form_page_error_helper_spec.rb b/spec/helpers/form_page_error_helper_spec.rb index e2b342a40..ae9d22494 100644 --- a/spec/helpers/form_page_error_helper_spec.rb +++ b/spec/helpers/form_page_error_helper_spec.rb @@ -3,6 +3,15 @@ require "rails_helper" RSpec.describe FormPageErrorHelper do describe "#remove_other_page_errors" do context "when non base other questions are removed" do + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + let!(:lettings_log) { FactoryBot.create(:lettings_log, :in_progress) } let!(:form) { lettings_log.form } diff --git a/spec/helpers/interruption_screen_helper_spec.rb b/spec/helpers/interruption_screen_helper_spec.rb index f46aca9ae..fba8782da 100644 --- a/spec/helpers/interruption_screen_helper_spec.rb +++ b/spec/helpers/interruption_screen_helper_spec.rb @@ -17,6 +17,15 @@ RSpec.describe InterruptionScreenHelper do ) end + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + describe "display_informative_text" do context "when 2 out of 2 arguments are given" do it "returns correct informative text" do diff --git a/spec/helpers/locations_helper_spec.rb b/spec/helpers/locations_helper_spec.rb index 4d58a7e8f..ae63c2e84 100644 --- a/spec/helpers/locations_helper_spec.rb +++ b/spec/helpers/locations_helper_spec.rb @@ -152,6 +152,52 @@ RSpec.describe LocationsHelper do expect(display_location_attributes(location)).to eq(attributes) end + context "when location has different local authorities for different years" do + before do + LocalAuthorityLink.create!(local_authority_id: LocalAuthority.find_by(code: "E07000030").id, linked_local_authority_id: LocalAuthority.find_by(code: "E06000063").id) + location.update!(location_code: "E07000030") + end + + it "returns correct display attributes" do + attributes = [ + { attribute: "postcode", name: "Postcode", value: location.postcode }, + { attribute: "name", name: "Location name", value: location.name }, + { attribute: "local_authority", name: "Local authority", value: "Eden (until 31 March 2023)\nCumberland (1 April 2023 - present)" }, + { attribute: "units", name: "Number of units", value: location.units }, + { attribute: "type_of_unit", name: "Most common unit", value: location.type_of_unit }, + { attribute: "mobility_standards", name: "Mobility standards", value: location.mobility_type }, + { attribute: "location_code", name: "Location code", value: "E07000030 (until 31 March 2023)\nE06000063 (1 April 2023 - present)" }, + { attribute: "availability", name: "Availability", value: "Active from 1 April 2022" }, + { attribute: "status", name: "Status", value: :active }, + ] + + expect(display_location_attributes(location)).to eq(attributes) + end + end + + context "when location has no local authority" do + before do + LocalAuthorityLink.create!(local_authority_id: LocalAuthority.find_by(code: "E07000030").id, linked_local_authority_id: LocalAuthority.find_by(code: "E06000063").id) + location.update!(location_code: nil) + end + + it "returns correct display attributes" do + attributes = [ + { attribute: "postcode", name: "Postcode", value: location.postcode }, + { attribute: "name", name: "Location name", value: location.name }, + { attribute: "local_authority", name: "Local authority", value: "" }, + { attribute: "units", name: "Number of units", value: location.units }, + { attribute: "type_of_unit", name: "Most common unit", value: location.type_of_unit }, + { attribute: "mobility_standards", name: "Mobility standards", value: location.mobility_type }, + { attribute: "location_code", name: "Location code", value: "" }, + { attribute: "availability", name: "Availability", value: "Active from 1 April 2022" }, + { attribute: "status", name: "Status", value: :incomplete }, + ] + + expect(display_location_attributes(location)).to eq(attributes) + end + end + context "when viewing availability" do context "with no deactivations" do it "displays previous collection start date as availability date if created_at is earlier than collection start date" do diff --git a/spec/helpers/question_view_helper_spec.rb b/spec/helpers/question_view_helper_spec.rb index 82f6d0b08..c24540709 100644 --- a/spec/helpers/question_view_helper_spec.rb +++ b/spec/helpers/question_view_helper_spec.rb @@ -44,7 +44,19 @@ RSpec.describe QuestionViewHelper do describe "legend" do subject(:question_view_helper) { legend(question, page_header, conditional) } - let(:question) { OpenStruct.new(header: "Some question header") } + let(:question_stub) do + Struct.new(:header) do + def question_number_string(_conditional) + nil + end + + def plain_label + nil + end + end + end + + let(:question) { question_stub.new("Some question header") } let(:size) { "m" } let(:tag) { "div" } let(:legend_options_hash) do @@ -67,7 +79,7 @@ RSpec.describe QuestionViewHelper do end end - context "when viewinng a conditional question" do + context "when viewing a conditional question" do let(:conditional) { true } let(:tag) { "" } @@ -75,5 +87,23 @@ RSpec.describe QuestionViewHelper do expect(question_view_helper).to eq(legend_options_hash) end end + + context "when viewing a question with a plain label" do + let(:question_stub) do + Struct.new(:header) do + def question_number_string(_conditional) + nil + end + + def plain_label + true + end + end + end + + it "returns an options hash with nil size" do + expect(question_view_helper).to eq({ size: nil, tag: "div", text: "Some question header" }) + end + end end end diff --git a/spec/helpers/tasklist_helper_spec.rb b/spec/helpers/tasklist_helper_spec.rb index b5bfe89f5..5d75616ec 100644 --- a/spec/helpers/tasklist_helper_spec.rb +++ b/spec/helpers/tasklist_helper_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe TasklistHelper do - let(:now) { Time.utc(2022, 6, 1) } + let(:now) { Time.utc(2022, 1, 1) } around do |example| Timecop.freeze(now) do @@ -9,12 +9,11 @@ RSpec.describe TasklistHelper do example.run end Timecop.return - Singleton.__init__(FormHandler) end describe "with lettings" do let(:empty_lettings_log) { create(:lettings_log) } - let(:lettings_log) { build(:lettings_log, :in_progress, needstype: 1) } + let(:lettings_log) { build(:lettings_log, :in_progress, needstype: 1, startdate: now) } describe "get next incomplete section" do it "returns the first subsection name if it is not completed" do @@ -28,8 +27,14 @@ RSpec.describe TasklistHelper do end describe "get sections count" do + let(:fake_2021_2022_form) { Form.new("spec/fixtures/forms/2021_2022.json") } + + before do + allow(FormHandler.instance).to receive(:get_form).and_return(fake_2021_2022_form) + end + it "returns the total of sections if no status is given" do - expect(get_subsections_count(empty_lettings_log)).to eq(1) + expect(get_subsections_count(empty_lettings_log)).to eq(8) end it "returns 0 sections for completed sections if no sections are completed" do @@ -37,7 +42,7 @@ RSpec.describe TasklistHelper do end it "returns the number of not started sections" do - expect(get_subsections_count(empty_lettings_log, :not_started)).to eq(1) + expect(get_subsections_count(empty_lettings_log, :not_started)).to eq(8) end it "returns the number of sections in progress" do @@ -49,41 +54,6 @@ RSpec.describe TasklistHelper do end end - describe "review_log_text" do - context "when collection_period_open? == true" do - context "with 2023 deadline" do - let(:now) { Time.utc(2022, 6, 1) } - let(:lettings_log) { create(:lettings_log, :completed) } - - it "returns relevant text" do - expect(review_log_text(lettings_log)).to eq( - "You can #{govuk_link_to 'review and make changes to this log', review_lettings_log_path(lettings_log)} until 1 July 2023.".html_safe, - ) - end - end - - context "with 2024 deadline" do - let(:now) { Time.utc(2023, 6, 20) } - let(:lettings_log) { create(:lettings_log, :completed, national: 18, waityear: 2) } - - it "returns relevant text" do - expect(review_log_text(lettings_log)).to eq( - "You can #{govuk_link_to 'review and make changes to this log', review_lettings_log_path(lettings_log)} until 9 July 2024.".html_safe, - ) - end - end - end - - context "when collection_period_open? == false" do - let(:now) { Time.utc(2023, 7, 8) } - let(:lettings_log) { create(:lettings_log, :completed, startdate: Time.utc(2023, 2, 8)) } - - it "returns relevant text" do - expect(review_log_text(lettings_log)).to eq("This log is from the 2022/2023 collection window, which is now closed.") - end - end - end - describe "subsection link" do let(:lettings_log) { create(:lettings_log, :completed) } let(:subsection) { lettings_log.form.get_subsection("household_characteristics") } @@ -131,5 +101,42 @@ RSpec.describe TasklistHelper do end end end + + context "with lettings log" do + context "when collection_period_open? == true" do + context "with 2023 deadline" do + let(:now) { Time.utc(2022, 6, 1) } + let(:lettings_log) { create(:lettings_log, :completed) } + + it "returns relevant text" do + expect(review_log_text(lettings_log)).to eq( + "You can #{govuk_link_to 'review and make changes to this log', review_lettings_log_path(lettings_log)} until 1 July 2023.".html_safe, + ) + end + end + + context "with 2024 deadline" do + let(:now) { Time.utc(2023, 6, 20) } + let(:lettings_log) { create(:lettings_log, :completed, national: 18, waityear: 2) } + + it "returns relevant text" do + expect(review_log_text(lettings_log)).to eq( + "You can #{govuk_link_to 'review and make changes to this log', review_lettings_log_path(lettings_log)} until 9 July 2024.".html_safe, + ) + end + end + end + + context "when collection_period_open? == false" do + let(:now) { Time.utc(2022, 6, 1) } + let!(:sales_log) { create(:lettings_log, :completed) } + + it "returns relevant text" do + Timecop.freeze(now + 1.year) do + expect(review_log_text(sales_log)).to eq("This log is from the 2021/2022 collection window, which is now closed.") + end + end + end + end end end diff --git a/spec/jobs/email_csv_job_spec.rb b/spec/jobs/email_csv_job_spec.rb index 5ff0b3355..04776aac7 100644 --- a/spec/jobs/email_csv_job_spec.rb +++ b/spec/jobs/email_csv_job_spec.rb @@ -31,7 +31,9 @@ describe EmailCsvJob do FactoryBot.create(:lettings_log, :completed, created_by: user, - startdate: Time.zone.local(2021, 5, 1)) + startdate: Time.zone.local(2022, 5, 1), + voiddate: Time.zone.local(2022, 5, 1), + mrcdate: Time.zone.local(2022, 5, 1)) allow(Storage::S3Service).to receive(:new).and_return(storage_service) allow(storage_service).to receive(:write_file) @@ -104,7 +106,7 @@ describe EmailCsvJob do it "writes answer labels rather than values" do expect_csv do |csv| - expect(csv.second[16]).to eq("Full-time – 30 hours or more") + expect(csv.second[19]).to eq("Full-time – 30 hours or more") end job.perform(user) diff --git a/spec/lib/tasks/local_authorities_import_spec.rb b/spec/lib/tasks/local_authorities_import_spec.rb new file mode 100644 index 000000000..67d952767 --- /dev/null +++ b/spec/lib/tasks/local_authorities_import_spec.rb @@ -0,0 +1,43 @@ +require "rails_helper" +require "rake" + +RSpec.describe "data_import" do + describe ":local_authorities", type: :task do + subject(:task) { Rake::Task["data_import:local_authorities"] } + + before do + LocalAuthority.destroy_all + Rake.application.rake_require("tasks/local_authorities") + Rake::Task.define_task(:environment) + task.reenable + end + + context "when the rake task is run" do + let(:local_authorities_file_path) { "./spec/fixtures/files/local_authorities.csv" } + let(:wrong_file_path) { "/test/no_csv_here.csv" } + + it "creates new local authorities records" do + expect { task.invoke(local_authorities_file_path) }.to change(LocalAuthority, :count).by(5) + expect(LocalAuthority.where(code: "S12000041").exists?).to be true + end + + it "raises an error when no path is given" do + expect { task.invoke(nil) }.to raise_error(RuntimeError, "Usage: rake data_import:local_authorities['path/to/csv_file']") + end + + it "raises an error when no file exists at the given path" do + expect { task.invoke(wrong_file_path) }.to raise_error(Errno::ENOENT) + end + + context "when a record already exists with a matching code index" do + let!(:local_authority) { LocalAuthority.create(code: "S12000041", name: "Something else", start_date: Time.zone.local(2021, 4, 1)) } + + it "updates local authority if the record is matched on code" do + task.invoke(local_authorities_file_path) + local_authority.reload + expect(local_authority.name).to eq("Angus") + end + end + end + end +end diff --git a/spec/lib/tasks/local_authority_links_import_spec.rb b/spec/lib/tasks/local_authority_links_import_spec.rb new file mode 100644 index 000000000..443a622cf --- /dev/null +++ b/spec/lib/tasks/local_authority_links_import_spec.rb @@ -0,0 +1,40 @@ +require "rails_helper" +require "rake" + +RSpec.describe "data_import" do + describe ":local_authority_links", type: :task do + subject(:task) { Rake::Task["data_import:local_authority_links"] } + + before do + LocalAuthorityLink.destroy_all + Rake.application.rake_require("tasks/local_authority_links") + Rake::Task.define_task(:environment) + task.reenable + end + + context "when the rake task is run" do + let(:local_authority_links_file_path) { "./spec/fixtures/files/local_authority_links_2023.csv" } + let(:wrong_file_path) { "/test/no_csv_here.csv" } + + it "creates new local authority links records" do + expect { task.invoke(local_authority_links_file_path) }.to change(LocalAuthorityLink, :count).by(5) + expect(LocalAuthorityLink.where(local_authority_id: LocalAuthority.find_by(code: "E06000063").id).exists?).to be true + end + + it "raises an error when no path is given" do + expect { task.invoke(nil) }.to raise_error(RuntimeError, "Usage: rake data_import:local_authority_links['path/to/csv_file']") + end + + it "raises an error when no file exists at the given path" do + expect { task.invoke(wrong_file_path) }.to raise_error(Errno::ENOENT) + end + + context "when a record already exists with a matching ids" do + it "does not create a new link" do + task.invoke(local_authority_links_file_path) + expect { task.invoke(local_authority_links_file_path) }.to change(LocalAuthorityLink, :count).by(0) + end + end + end + end +end diff --git a/spec/mailers/bulk_upload_mailer_spec.rb b/spec/mailers/bulk_upload_mailer_spec.rb index 0e38617a3..9f59de365 100644 --- a/spec/mailers/bulk_upload_mailer_spec.rb +++ b/spec/mailers/bulk_upload_mailer_spec.rb @@ -21,8 +21,8 @@ RSpec.describe BulkUploadMailer do let(:expected_errors) do [ - "- Column A (What is the letting type?)", - "- Column E (Management group code)", + "- What is the letting type? (Column A)", + "- Management group code (Column E)", ] end @@ -52,7 +52,7 @@ RSpec.describe BulkUploadMailer do personalisation: { title: "You’ve successfully uploaded 0 logs", filename: bulk_upload.filename, - upload_timestamp: bulk_upload.created_at, + upload_timestamp: bulk_upload.created_at.to_fs(:govuk_date_and_time), success_description: "The lettings 2022/23 data you uploaded has been checked. The 0 logs you uploaded are now complete.", logs_link: lettings_logs_url, }, @@ -69,14 +69,15 @@ RSpec.describe BulkUploadMailer do template_id: described_class::BULK_UPLOAD_FAILED_SERVICE_ERROR_TEMPLATE_ID, personalisation: { filename: bulk_upload.filename, - upload_timestamp: bulk_upload.created_at, + upload_timestamp: bulk_upload.created_at.to_fs(:govuk_date_and_time), lettings_or_sales: bulk_upload.log_type, year_combo: bulk_upload.year_combo, + errors: "- foo\n- bar", bulk_upload_link: start_bulk_upload_lettings_logs_url, }, ) - mailer.send_bulk_upload_failed_service_error_mail(bulk_upload:) + mailer.send_bulk_upload_failed_service_error_mail(bulk_upload:, errors: %w[foo bar]) end end diff --git a/spec/models/form/lettings/pages/person_age_spec.rb b/spec/models/form/lettings/pages/person_age_spec.rb index ca39ef2c9..3a5ee1655 100644 --- a/spec/models/form/lettings/pages/person_age_spec.rb +++ b/spec/models/form/lettings/pages/person_age_spec.rb @@ -1,11 +1,12 @@ require "rails_helper" RSpec.describe Form::Lettings::Pages::PersonAge, type: :model do - subject(:page) { described_class.new(nil, page_definition, subsection, person_index:) } + subject(:page) { described_class.new(nil, page_definition, subsection, person_index:, person_type:) } let(:page_definition) { nil } let(:subsection) { instance_double(Form::Subsection) } let(:person_index) { 2 } + let(:person_type) { "non_child" } it "has correct subsection" do expect(page.subsection).to eq(subsection) @@ -24,14 +25,30 @@ RSpec.describe Form::Lettings::Pages::PersonAge, type: :model do expect(page.questions.map(&:id)).to eq(%w[age2_known age2]) end - it "has the correct id" do - expect(page.id).to eq("person_2_age") + context "when child" do + let(:person_type) { "child" } + + it "has the correct id" do + expect(page.id).to eq("person_2_age_child") + end + + it "has correct depends_on" do + expect(page.depends_on).to eq( + [{ "details_known_2" => 0, "person_2_child_relation?" => true }], + ) + end end - it "has correct depends_on" do - expect(page.depends_on).to eq( - [{ "details_known_2" => 0 }], - ) + context "when not child" do + it "has the correct id" do + expect(page.id).to eq("person_2_age_non_child") + end + + it "has correct depends_on" do + expect(page.depends_on).to eq( + [{ "details_known_2" => 0, "person_2_child_relation?" => false }], + ) + end end end @@ -43,12 +60,12 @@ RSpec.describe Form::Lettings::Pages::PersonAge, type: :model do end it "has the correct id" do - expect(page.id).to eq("person_3_age") + expect(page.id).to eq("person_3_age_non_child") end it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "details_known_3" => 0 }], + [{ "details_known_3" => 0, "person_3_child_relation?" => false }], ) end end diff --git a/spec/models/form/lettings/pages/previous_housing_situation_renewal_spec.rb b/spec/models/form/lettings/pages/previous_housing_situation_renewal_spec.rb new file mode 100644 index 000000000..4bdc2d8a3 --- /dev/null +++ b/spec/models/form/lettings/pages/previous_housing_situation_renewal_spec.rb @@ -0,0 +1,31 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::PreviousHousingSituationRenewal, type: :model do + subject(:page) { described_class.new(nil, nil, subsection) } + + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[prevten]) + end + + it "has the correct id" do + expect(page.id).to eq("previous_housing_situation_renewal") + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has the correct depends_on" do + expect(page.depends_on).to eq([{ "is_renewal?" => true, "is_supported_housing?" => true }]) + end +end diff --git a/spec/models/form/lettings/pages/previous_housing_situation_spec.rb b/spec/models/form/lettings/pages/previous_housing_situation_spec.rb new file mode 100644 index 000000000..c891996c9 --- /dev/null +++ b/spec/models/form/lettings/pages/previous_housing_situation_spec.rb @@ -0,0 +1,31 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::PreviousHousingSituation, type: :model do + subject(:page) { described_class.new(nil, nil, subsection) } + + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[prevten]) + end + + it "has the correct id" do + expect(page.id).to eq("previous_housing_situation") + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has the correct depends_on" do + expect(page.depends_on).to eq([{ "is_renewal?" => false }]) + end +end diff --git a/spec/models/form/lettings/pages/sheltered_accommodation_spec.rb b/spec/models/form/lettings/pages/sheltered_accommodation_spec.rb new file mode 100644 index 000000000..7d403f9e3 --- /dev/null +++ b/spec/models/form/lettings/pages/sheltered_accommodation_spec.rb @@ -0,0 +1,31 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::ShelteredAccommodation, type: :model do + subject(:page) { described_class.new(nil, nil, subsection) } + + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[sheltered]) + end + + it "has the correct id" do + expect(page.id).to eq("sheltered_accommodation") + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has the correct depends_on" do + expect(page.depends_on).to eq([{ "is_supported_housing?" => true }]) + end +end diff --git a/spec/models/form/lettings/pages/starter_tenancy_type_spec.rb b/spec/models/form/lettings/pages/starter_tenancy_type_spec.rb new file mode 100644 index 000000000..795dee561 --- /dev/null +++ b/spec/models/form/lettings/pages/starter_tenancy_type_spec.rb @@ -0,0 +1,31 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::StarterTenancyType, type: :model do + subject(:page) { described_class.new(nil, nil, subsection) } + + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[tenancy tenancyother]) + end + + it "has the correct id" do + expect(page.id).to eq("starter_tenancy_type") + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has the correct depends_on" do + expect(page.depends_on).to eq([{ "starter_tenancy?" => true }]) + end +end diff --git a/spec/models/form/lettings/pages/tenancy_length_spec.rb b/spec/models/form/lettings/pages/tenancy_length_spec.rb new file mode 100644 index 000000000..d4ea920ae --- /dev/null +++ b/spec/models/form/lettings/pages/tenancy_length_spec.rb @@ -0,0 +1,31 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::TenancyLength, type: :model do + subject(:page) { described_class.new(nil, nil, subsection) } + + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq subsection + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq %w[tenancylength] + end + + it "has the correct id" do + expect(page.id).to eq "tenancy_length" + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has the correct depends_on" do + expect(page.depends_on).to eq [{ "tenancy_type_fixed_term?" => true }] + end +end diff --git a/spec/models/form/lettings/pages/tenancy_type_spec.rb b/spec/models/form/lettings/pages/tenancy_type_spec.rb new file mode 100644 index 000000000..ef772e85e --- /dev/null +++ b/spec/models/form/lettings/pages/tenancy_type_spec.rb @@ -0,0 +1,31 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::TenancyType, type: :model do + subject(:page) { described_class.new(nil, nil, subsection) } + + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq %w[tenancy tenancyother] + end + + it "has the correct id" do + expect(page.id).to eq "tenancy_type" + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has the correct depends_on" do + expect(page.depends_on).to eq [{ "starter_tenancy?" => false }] + end +end diff --git a/spec/models/form/lettings/questions/age_spec.rb b/spec/models/form/lettings/questions/age_spec.rb index 87c3dce22..40a6356fd 100644 --- a/spec/models/form/lettings/questions/age_spec.rb +++ b/spec/models/form/lettings/questions/age_spec.rb @@ -1,11 +1,12 @@ require "rails_helper" RSpec.describe Form::Lettings::Questions::Age, type: :model do - subject(:question) { described_class.new(nil, question_definition, page, person_index:) } + subject(:question) { described_class.new(nil, question_definition, page, person_index:, person_type:) } let(:question_definition) { nil } let(:page) { instance_double(Form::Page) } let(:person_index) { 2 } + let(:person_type) { "non_child" } it "has correct page" do expect(question.page).to eq(page) @@ -23,12 +24,22 @@ RSpec.describe Form::Lettings::Questions::Age, type: :model do expect(question.derived?).to be false end - it "has the correct hint" do - expect(question.hint_text).to be_nil + context "when child" do + let(:person_type) { "child" } + + it "has the correct hint" do + expect(question.hint_text).to eq("For a child under 1, enter 1") + end + end + + context "when not child" do + it "has no hint" do + expect(question.hint_text).to be nil + end end it "has the correct min" do - expect(question.min).to eq(0) + expect(question.min).to eq(1) end it "has the correct max" do diff --git a/spec/models/form/lettings/questions/la_spec.rb b/spec/models/form/lettings/questions/la_spec.rb new file mode 100644 index 000000000..f73a29660 --- /dev/null +++ b/spec/models/form/lettings/questions/la_spec.rb @@ -0,0 +1,318 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::La, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date:)) } + let(:page) { instance_double(Form::Page, subsection:) } + let(:start_date) { Time.utc(2023, 4, 1) } + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "" => "Select an option", + "E06000001" => "Hartlepool", + "E06000002" => "Middlesbrough", + "E06000003" => "Redcar and Cleveland", + "E06000004" => "Stockton-on-Tees", + "E06000005" => "Darlington", + "E06000006" => "Halton", + "E06000007" => "Warrington", + "E06000008" => "Blackburn with Darwen", + "E06000009" => "Blackpool", + "E06000010" => "Kingston upon Hull, City of", + "E06000011" => "East Riding of Yorkshire", + "E06000012" => "North East Lincolnshire", + "E06000013" => "North Lincolnshire", + "E06000014" => "York", + "E06000015" => "Derby", + "E06000016" => "Leicester", + "E06000017" => "Rutland", + "E06000018" => "Nottingham", + "E06000019" => "Herefordshire, County of", + "E06000020" => "Telford and Wrekin", + "E06000021" => "Stoke-on-Trent", + "E06000022" => "Bath and North East Somerset", + "E06000023" => "Bristol, City of", + "E06000024" => "North Somerset", + "E06000025" => "South Gloucestershire", + "E06000026" => "Plymouth", + "E06000027" => "Torbay", + "E06000030" => "Swindon", + "E06000031" => "Peterborough", + "E06000032" => "Luton", + "E06000033" => "Southend-on-Sea", + "E06000034" => "Thurrock", + "E06000035" => "Medway", + "E06000036" => "Bracknell Forest", + "E06000037" => "West Berkshire", + "E06000038" => "Reading", + "E06000039" => "Slough", + "E06000040" => "Windsor and Maidenhead", + "E06000041" => "Wokingham", + "E06000042" => "Milton Keynes", + "E06000043" => "Brighton and Hove", + "E06000044" => "Portsmouth", + "E06000045" => "Southampton", + "E06000046" => "Isle of Wight", + "E06000047" => "County Durham", + "E06000049" => "Cheshire East", + "E06000050" => "Cheshire West and Chester", + "E06000051" => "Shropshire", + "E06000052" => "Cornwall", + "E06000053" => "Isles of Scilly", + "E06000054" => "Wiltshire", + "E06000055" => "Bedford", + "E06000056" => "Central Bedfordshire", + "E06000057" => "Northumberland", + "E06000058" => "Bournemouth, Christchurch and Poole", + "E06000059" => "Dorset", + "E06000060" => "Buckinghamshire", + "E07000008" => "Cambridge", + "E07000009" => "East Cambridgeshire", + "E07000010" => "Fenland", + "E07000011" => "Huntingdonshire", + "E07000012" => "South Cambridgeshire", + "E07000032" => "Amber Valley", + "E07000033" => "Bolsover", + "E07000034" => "Chesterfield", + "E07000035" => "Derbyshire Dales", + "E07000036" => "Erewash", + "E07000037" => "High Peak", + "E07000038" => "North East Derbyshire", + "E07000039" => "South Derbyshire", + "E07000040" => "East Devon", + "E07000041" => "Exeter", + "E07000042" => "Mid Devon", + "E07000043" => "North Devon", + "E07000044" => "South Hams", + "E07000045" => "Teignbridge", + "E07000046" => "Torridge", + "E07000047" => "West Devon", + "E07000061" => "Eastbourne", + "E07000062" => "Hastings", + "E07000063" => "Lewes", + "E07000064" => "Rother", + "E07000065" => "Wealden", + "E07000066" => "Basildon", + "E07000067" => "Braintree", + "E07000068" => "Brentwood", + "E07000069" => "Castle Point", + "E07000070" => "Chelmsford", + "E07000071" => "Colchester", + "E07000072" => "Epping Forest", + "E07000073" => "Harlow", + "E07000074" => "Maldon", + "E07000075" => "Rochford", + "E07000076" => "Tendring", + "E07000077" => "Uttlesford", + "E07000078" => "Cheltenham", + "E07000079" => "Cotswold", + "E07000080" => "Forest of Dean", + "E07000081" => "Gloucester", + "E07000082" => "Stroud", + "E07000083" => "Tewkesbury", + "E07000084" => "Basingstoke and Deane", + "E07000085" => "East Hampshire", + "E07000086" => "Eastleigh", + "E07000087" => "Fareham", + "E07000088" => "Gosport", + "E07000089" => "Hart", + "E07000090" => "Havant", + "E07000091" => "New Forest", + "E07000092" => "Rushmoor", + "E07000093" => "Test Valley", + "E07000094" => "Winchester", + "E07000095" => "Broxbourne", + "E07000096" => "Dacorum", + "E07000098" => "Hertsmere", + "E07000099" => "North Hertfordshire", + "E07000102" => "Three Rivers", + "E07000103" => "Watford", + "E07000105" => "Ashford", + "E07000106" => "Canterbury", + "E07000107" => "Dartford", + "E07000108" => "Dover", + "E07000109" => "Gravesham", + "E07000110" => "Maidstone", + "E07000111" => "Sevenoaks", + "E07000112" => "Folkestone and Hythe", + "E07000113" => "Swale", + "E07000114" => "Thanet", + "E07000115" => "Tonbridge and Malling", + "E07000116" => "Tunbridge Wells", + "E07000117" => "Burnley", + "E07000118" => "Chorley", + "E07000119" => "Fylde", + "E07000120" => "Hyndburn", + "E07000121" => "Lancaster", + "E07000122" => "Pendle", + "E07000123" => "Preston", + "E07000124" => "Ribble Valley", + "E07000125" => "Rossendale", + "E07000126" => "South Ribble", + "E07000127" => "West Lancashire", + "E07000128" => "Wyre", + "E07000129" => "Blaby", + "E07000130" => "Charnwood", + "E07000131" => "Harborough", + "E07000132" => "Hinckley and Bosworth", + "E07000133" => "Melton", + "E07000134" => "North West Leicestershire", + "E07000135" => "Oadby and Wigston", + "E07000136" => "Boston", + "E07000137" => "East Lindsey", + "E07000138" => "Lincoln", + "E07000139" => "North Kesteven", + "E07000140" => "South Holland", + "E07000141" => "South Kesteven", + "E07000142" => "West Lindsey", + "E07000143" => "Breckland", + "E07000144" => "Broadland", + "E07000145" => "Great Yarmouth", + "E07000146" => "King’s Lynn and West Norfolk", + "E07000147" => "North Norfolk", + "E07000148" => "Norwich", + "E07000149" => "South Norfolk", + "E07000150" => "Corby", + "E07000151" => "Daventry", + "E07000152" => "East Northamptonshire", + "E07000153" => "Kettering", + "E07000154" => "Northampton", + "E07000155" => "South Northamptonshire", + "E07000156" => "Wellingborough", + "E07000170" => "Ashfield", + "E07000171" => "Bassetlaw", + "E07000172" => "Broxtowe", + "E07000173" => "Gedling", + "E07000174" => "Mansfield", + "E07000175" => "Newark and Sherwood", + "E07000176" => "Rushcliffe", + "E07000177" => "Cherwell", + "E07000178" => "Oxford", + "E07000179" => "South Oxfordshire", + "E07000180" => "Vale of White Horse", + "E07000181" => "West Oxfordshire", + "E07000192" => "Cannock Chase", + "E07000193" => "East Staffordshire", + "E07000194" => "Lichfield", + "E07000195" => "Newcastle-under-Lyme", + "E07000196" => "South Staffordshire", + "E07000197" => "Stafford", + "E07000198" => "Staffordshire Moorlands", + "E07000199" => "Tamworth", + "E07000200" => "Babergh", + "E07000202" => "Ipswich", + "E07000203" => "Mid Suffolk", + "E07000207" => "Elmbridge", + "E07000208" => "Epsom and Ewell", + "E07000209" => "Guildford", + "E07000210" => "Mole Valley", + "E07000211" => "Reigate and Banstead", + "E07000212" => "Runnymede", + "E07000213" => "Spelthorne", + "E07000214" => "Surrey Heath", + "E07000215" => "Tandridge", + "E07000216" => "Waverley", + "E07000217" => "Woking", + "E07000218" => "North Warwickshire", + "E07000219" => "Nuneaton and Bedworth", + "E07000220" => "Rugby", + "E07000221" => "Stratford-on-Avon", + "E07000222" => "Warwick", + "E07000223" => "Adur", + "E07000224" => "Arun", + "E07000225" => "Chichester", + "E07000226" => "Crawley", + "E07000227" => "Horsham", + "E07000228" => "Mid Sussex", + "E07000229" => "Worthing", + "E07000234" => "Bromsgrove", + "E07000235" => "Malvern Hills", + "E07000236" => "Redditch", + "E07000237" => "Worcester", + "E07000238" => "Wychavon", + "E07000239" => "Wyre Forest", + "E07000240" => "St Albans", + "E07000241" => "Welwyn Hatfield", + "E07000242" => "East Hertfordshire", + "E07000243" => "Stevenage", + "E07000244" => "East Suffolk", + "E07000245" => "West Suffolk", + "E08000001" => "Bolton", + "E08000002" => "Bury", + "E08000003" => "Manchester", + "E08000004" => "Oldham", + "E08000005" => "Rochdale", + "E08000006" => "Salford", + "E08000007" => "Stockport", + "E08000008" => "Tameside", + "E08000009" => "Trafford", + "E08000010" => "Wigan", + "E08000011" => "Knowsley", + "E08000012" => "Liverpool", + "E08000013" => "St. Helens", + "E08000014" => "Sefton", + "E08000015" => "Wirral", + "E08000016" => "Barnsley", + "E08000017" => "Doncaster", + "E08000018" => "Rotherham", + "E08000019" => "Sheffield", + "E08000021" => "Newcastle upon Tyne", + "E08000022" => "North Tyneside", + "E08000023" => "South Tyneside", + "E08000024" => "Sunderland", + "E08000025" => "Birmingham", + "E08000026" => "Coventry", + "E08000027" => "Dudley", + "E08000028" => "Sandwell", + "E08000029" => "Solihull", + "E06000066" => "Somerset", + "E08000030" => "Walsall", + "E08000031" => "Wolverhampton", + "E08000032" => "Bradford", + "E08000033" => "Calderdale", + "E08000034" => "Kirklees", + "E08000035" => "Leeds", + "E08000036" => "Wakefield", + "E08000037" => "Gateshead", + "E09000001" => "City of London", + "E09000002" => "Barking and Dagenham", + "E09000003" => "Barnet", + "E09000004" => "Bexley", + "E09000005" => "Brent", + "E09000006" => "Bromley", + "E09000007" => "Camden", + "E09000008" => "Croydon", + "E06000063" => "Cumberland", + "E09000009" => "Ealing", + "E09000010" => "Enfield", + "E09000011" => "Greenwich", + "E09000012" => "Hackney", + "E09000013" => "Hammersmith and Fulham", + "E09000014" => "Haringey", + "E09000015" => "Harrow", + "E09000016" => "Havering", + "E09000017" => "Hillingdon", + "E09000018" => "Hounslow", + "E09000019" => "Islington", + "E09000020" => "Kensington and Chelsea", + "E09000021" => "Kingston upon Thames", + "E09000022" => "Lambeth", + "E09000023" => "Lewisham", + "E09000024" => "Merton", + "E09000025" => "Newham", + "E09000026" => "Redbridge", + "E09000027" => "Richmond upon Thames", + "E09000028" => "Southwark", + "E09000029" => "Sutton", + "E09000030" => "Tower Hamlets", + "E09000031" => "Waltham Forest", + "E09000032" => "Wandsworth", + "E09000033" => "Westminster", + "E06000064" => "Westmorland and Furness", + "E06000065" => "North Yorkshire", + }) + end +end diff --git a/spec/models/form/lettings/questions/nationality_spec.rb b/spec/models/form/lettings/questions/nationality_spec.rb new file mode 100644 index 000000000..d0eaeb69b --- /dev/null +++ b/spec/models/form/lettings/questions/nationality_spec.rb @@ -0,0 +1,48 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::Nationality, type: :model do + subject(:question) { described_class.new(nil, nil, page) } + + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("national") + end + + it "has the correct header" do + expect(question.header).to eq("What is the nationality of the lead tenant?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Lead tenant’s nationality") + end + + it "has the correct type" do + expect(question.type).to eq("radio") + end + + it "has the correct hint_text" do + expect(question.hint_text).to eq("The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest.") + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "18" => { "value" => "United Kingdom" }, + "17" => { "value" => "Republic of Ireland" }, + "19" => { "value" => "European Economic Area (EEA) country, excluding Ireland" }, + "20" => { "value" => "Afghanistan" }, + "21" => { "value" => "Ukraine" }, + "12" => { "value" => "Other" }, + "divider" => true, + "13" => { "value" => "Tenant prefers not to say" }, + }) + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end +end diff --git a/spec/models/form/lettings/questions/offered_social_let_spec.rb b/spec/models/form/lettings/questions/offered_social_let_spec.rb index 8a3622e02..6516c661b 100644 --- a/spec/models/form/lettings/questions/offered_social_let_spec.rb +++ b/spec/models/form/lettings/questions/offered_social_let_spec.rb @@ -39,6 +39,6 @@ RSpec.describe Form::Lettings::Questions::OfferedSocialLet, type: :model do end it "has the correct hint_text" do - expect(question.hint_text).to eq "Do not include the offer that led to this letting.This is after the last tenancy ended. If the property is being offered for let for the first time, enter 0." + expect(question.hint_text).to eq "Do not include the offer that led to this letting. This is after the last tenancy ended. If the property is being offered for let for the first time, enter 0." end end diff --git a/spec/models/form/lettings/questions/person_relationship_spec.rb b/spec/models/form/lettings/questions/person_relationship_spec.rb index 04f071b9b..dca3d82a3 100644 --- a/spec/models/form/lettings/questions/person_relationship_spec.rb +++ b/spec/models/form/lettings/questions/person_relationship_spec.rb @@ -20,7 +20,7 @@ RSpec.describe Form::Lettings::Questions::PersonRelationship, type: :model do end it "has the correct answer_options" do - expect(question.answer_options).to eq("C" => { "hint" => "Must be eligible for child benefit, aged under 16 or under 20 if still in full-time education.", "value" => "Child" }, + expect(question.answer_options).to eq("C" => { "hint" => "Must be eligible for child benefit: under age 16 or under 20 if still in full-time education.", "value" => "Child" }, "P" => { "value" => "Partner" }, "R" => { "value" => "Person prefers not to say" }, "X" => { "value" => "Other" }, diff --git a/spec/models/form/lettings/questions/previous_let_type_spec.rb b/spec/models/form/lettings/questions/previous_let_type_spec.rb new file mode 100644 index 000000000..b18bbc88a --- /dev/null +++ b/spec/models/form/lettings/questions/previous_let_type_spec.rb @@ -0,0 +1,48 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::PreviousLetType, type: :model do + subject(:question) { described_class.new(nil, nil, page) } + + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq page + end + + it "has the correct id" do + expect(question.id).to eq "unitletas" + end + + it "has the correct header" do + expect(question.header).to eq "What type was the property most recently let as?" + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq "Most recent let type" + end + + it "has the correct type" do + expect(question.type).to eq "radio" + end + + it "has the correct hint_text" do + expect(question.hint_text).to eq "" + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct answer options" do + expect(question.answer_options).to eq({ + "1" => { "value" => "Social rent basis" }, + "2" => { "value" => "Affordable rent basis" }, + "5" => { "value" => "A London Affordable Rent basis" }, + "6" => { "value" => "A Rent to Buy basis" }, + "7" => { "value" => "A London Living Rent basis" }, + "8" => { "value" => "Another Intermediate Rent basis" }, + "divider" => { "value" => true }, + "3" => { "value" => "Don’t know" }, + }) + end +end diff --git a/spec/models/form/lettings/questions/previous_tenure_renewal_spec.rb b/spec/models/form/lettings/questions/previous_tenure_renewal_spec.rb new file mode 100644 index 000000000..91f1ec158 --- /dev/null +++ b/spec/models/form/lettings/questions/previous_tenure_renewal_spec.rb @@ -0,0 +1,44 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::PreviousTenureRenewal, type: :model do + subject(:question) { described_class.new(nil, nil, page) } + + let(:page) { instance_double(Form::Page) } + + it "has the correct id" do + expect(question.id).to eq("prevten") + end + + it "has the correct header" do + expect(question.header).to eq("Where was the household immediately before this letting?") + end + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Where was the household immediately before this letting?") + end + + it "has the correct type" do + expect(question.type).to eq("radio") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint" do + expect(question.hint_text).to eq("") + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "34" => { "value" => "Specialist retirement housing" }, + "35" => { "value" => "Extra care housing" }, + "36" => { "value" => "Sheltered housing for adults aged under 55 years" }, + "6" => { "value" => "Other supported housing" }, + }) + end +end diff --git a/spec/models/form/lettings/questions/previous_tenure_spec.rb b/spec/models/form/lettings/questions/previous_tenure_spec.rb new file mode 100644 index 000000000..4b106601e --- /dev/null +++ b/spec/models/form/lettings/questions/previous_tenure_spec.rb @@ -0,0 +1,66 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::PreviousTenure, type: :model do + subject(:question) { described_class.new(nil, nil, page) } + + let(:page) { instance_double(Form::Page) } + + it "has the correct id" do + expect(question.id).to eq("prevten") + end + + it "has the correct header" do + expect(question.header).to eq("Where was the household immediately before this letting?") + end + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Where was the household immediately before this letting?") + end + + it "has the correct type" do + expect(question.type).to eq("radio") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint" do + expect(question.hint_text).to eq("This is where the household was the night before they moved.") + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "30" => { "value" => "Fixed-term local authority general needs tenancy" }, + "32" => { "value" => "Fixed-term private registered provider (PRP) general needs tenancy" }, + "31" => { "value" => "Lifetime local authority general needs tenancy" }, + "33" => { "value" => "Lifetime private registered provider (PRP) general needs tenancy" }, + "34" => { "value" => "Specialist retirement housing" }, + "35" => { "value" => "Extra care housing" }, + "6" => { "value" => "Other supported housing" }, + "3" => { "value" => "Private sector tenancy" }, + "27" => { "value" => "Owner occupation (low-cost home ownership)" }, + "26" => { "value" => "Owner occupation (private)" }, + "28" => { "value" => "Living with friends or family" }, + "14" => { "value" => "Bed and breakfast" }, + "7" => { "value" => "Direct access hostel" }, + "10" => { "value" => "Hospital" }, + "29" => { "value" => "Prison or approved probation hostel" }, + "19" => { "value" => "Rough sleeping" }, + "18" => { "value" => "Any other temporary accommodation" }, + "13" => { "value" => "Children’s home or foster care" }, + "24" => { "value" => "Home Office Asylum Support" }, + "23" => { "value" => "Mobile home or caravan" }, + "21" => { "value" => "Refuge" }, + "9" => { "value" => "Residential care home" }, + "4" => { "value" => "Tied housing or rented with job" }, + "36" => { "value" => "Sheltered housing for adults aged under 55 years" }, + "37" => { "value" => "Host family or similar refugee accommodation" }, + "25" => { "value" => "Any other accommodation" }, + }) + end +end diff --git a/spec/models/form/lettings/questions/prevloc_spec.rb b/spec/models/form/lettings/questions/prevloc_spec.rb new file mode 100644 index 000000000..7d2b141a2 --- /dev/null +++ b/spec/models/form/lettings/questions/prevloc_spec.rb @@ -0,0 +1,387 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::Prevloc, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date:)) } + let(:page) { instance_double(Form::Page, subsection:) } + let(:start_date) { Time.utc(2023, 4, 1) } + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "" => "Select an option", + "S12000033" => "Aberdeen City", + "S12000034" => "Aberdeenshire", + "E07000223" => "Adur", + "E07000032" => "Amber Valley", + "S12000041" => "Angus", + "N09000001" => "Antrim and Newtownabbey", + "N09000011" => "Ards and North Down", + "S12000035" => "Argyll and Bute", + "N09000002" => "Armagh City, Banbridge and Craigavon", + "E07000224" => "Arun", + "E07000170" => "Ashfield", + "E07000105" => "Ashford", + "E07000200" => "Babergh", + "E09000002" => "Barking and Dagenham", + "E09000003" => "Barnet", + "E08000016" => "Barnsley", + "E07000066" => "Basildon", + "E07000084" => "Basingstoke and Deane", + "E07000171" => "Bassetlaw", + "E06000022" => "Bath and North East Somerset", + "E06000055" => "Bedford", + "N09000003" => "Belfast", + "E09000004" => "Bexley", + "E08000025" => "Birmingham", + "E07000129" => "Blaby", + "E06000008" => "Blackburn with Darwen", + "E06000009" => "Blackpool", + "W06000019" => "Blaenau Gwent", + "E07000033" => "Bolsover", + "E08000001" => "Bolton", + "E07000136" => "Boston", + "E06000058" => "Bournemouth, Christchurch and Poole", + "E06000036" => "Bracknell Forest", + "E08000032" => "Bradford", + "E07000067" => "Braintree", + "E07000143" => "Breckland", + "E09000005" => "Brent", + "E07000068" => "Brentwood", + "W06000013" => "Bridgend", + "E06000043" => "Brighton and Hove", + "E06000023" => "Bristol, City of", + "E07000144" => "Broadland", + "E09000006" => "Bromley", + "E07000234" => "Bromsgrove", + "E07000095" => "Broxbourne", + "E07000172" => "Broxtowe", + "E06000060" => "Buckinghamshire", + "E07000117" => "Burnley", + "E08000002" => "Bury", + "W06000018" => "Caerphilly", + "E08000033" => "Calderdale", + "E07000008" => "Cambridge", + "E09000007" => "Camden", + "E07000192" => "Cannock Chase", + "E07000106" => "Canterbury", + "W06000015" => "Cardiff", + "W06000010" => "Carmarthenshire", + "E07000069" => "Castle Point", + "N09000004" => "Causeway Coast and Glens", + "E06000056" => "Central Bedfordshire", + "W06000008" => "Ceredigion", + "E07000130" => "Charnwood", + "E07000070" => "Chelmsford", + "E07000078" => "Cheltenham", + "E07000177" => "Cherwell", + "E06000049" => "Cheshire East", + "E06000050" => "Cheshire West and Chester", + "E07000034" => "Chesterfield", + "E07000225" => "Chichester", + "E07000118" => "Chorley", + "S12000036" => "City of Edinburgh", + "E09000001" => "City of London", + "S12000005" => "Clackmannanshire", + "E07000071" => "Colchester", + "W06000003" => "Conwy", + "E07000150" => "Corby", + "E06000052" => "Cornwall", + "E07000079" => "Cotswold", + "E06000047" => "County Durham", + "E08000026" => "Coventry", + "E07000226" => "Crawley", + "E09000008" => "Croydon", + "E06000063" => "Cumberland", + "E07000096" => "Dacorum", + "E06000005" => "Darlington", + "E07000107" => "Dartford", + "E07000151" => "Daventry", + "W06000004" => "Denbighshire", + "E06000015" => "Derby", + "E07000035" => "Derbyshire Dales", + "N09000005" => "Derry City and Strabane", + "E08000017" => "Doncaster", + "E06000059" => "Dorset", + "E07000108" => "Dover", + "E08000027" => "Dudley", + "S12000006" => "Dumfries and Galloway", + "S12000042" => "Dundee City", + "E09000009" => "Ealing", + "S12000008" => "East Ayrshire", + "E07000009" => "East Cambridgeshire", + "E07000040" => "East Devon", + "S12000045" => "East Dunbartonshire", + "E07000085" => "East Hampshire", + "E07000242" => "East Hertfordshire", + "E07000137" => "East Lindsey", + "S12000010" => "East Lothian", + "E07000152" => "East Northamptonshire", + "S12000011" => "East Renfrewshire", + "E06000011" => "East Riding of Yorkshire", + "E07000193" => "East Staffordshire", + "E07000244" => "East Suffolk", + "E07000061" => "Eastbourne", + "E07000086" => "Eastleigh", + "E07000207" => "Elmbridge", + "E09000010" => "Enfield", + "E07000072" => "Epping Forest", + "E07000208" => "Epsom and Ewell", + "E07000036" => "Erewash", + "E07000041" => "Exeter", + "S12000014" => "Falkirk", + "E07000087" => "Fareham", + "E07000010" => "Fenland", + "N09000006" => "Fermanagh and Omagh", + "S12000047" => "Fife", + "W06000005" => "Flintshire", + "E07000112" => "Folkestone and Hythe", + "E07000080" => "Forest of Dean", + "E07000119" => "Fylde", + "E08000037" => "Gateshead", + "E07000173" => "Gedling", + "S12000049" => "Glasgow City", + "E07000081" => "Gloucester", + "E07000088" => "Gosport", + "E07000109" => "Gravesham", + "E07000145" => "Great Yarmouth", + "E09000011" => "Greenwich", + "E07000209" => "Guildford", + "W06000002" => "Gwynedd", + "E09000012" => "Hackney", + "E06000006" => "Halton", + "E09000013" => "Hammersmith and Fulham", + "E07000131" => "Harborough", + "E09000014" => "Haringey", + "E07000073" => "Harlow", + "E09000015" => "Harrow", + "E07000089" => "Hart", + "E06000001" => "Hartlepool", + "E07000062" => "Hastings", + "E07000090" => "Havant", + "E09000016" => "Havering", + "E06000019" => "Herefordshire, County of", + "E07000098" => "Hertsmere", + "E07000037" => "High Peak", + "S12000017" => "Highland", + "E09000017" => "Hillingdon", + "E07000132" => "Hinckley and Bosworth", + "E07000227" => "Horsham", + "E09000018" => "Hounslow", + "E07000011" => "Huntingdonshire", + "E07000120" => "Hyndburn", + "S12000018" => "Inverclyde", + "E07000202" => "Ipswich", + "W06000001" => "Isle of Anglesey", + "E06000046" => "Isle of Wight", + "E06000053" => "Isles of Scilly", + "E09000019" => "Islington", + "E09000020" => "Kensington and Chelsea", + "E07000153" => "Kettering", + "E07000146" => "King’s Lynn and West Norfolk", + "E06000010" => "Kingston upon Hull, City of", + "E09000021" => "Kingston upon Thames", + "E08000034" => "Kirklees", + "E08000011" => "Knowsley", + "E09000022" => "Lambeth", + "E07000121" => "Lancaster", + "E08000035" => "Leeds", + "E06000016" => "Leicester", + "E07000063" => "Lewes", + "E09000023" => "Lewisham", + "E07000194" => "Lichfield", + "E07000138" => "Lincoln", + "N09000007" => "Lisburn and Castlereagh", + "E08000012" => "Liverpool", + "E06000032" => "Luton", + "E07000110" => "Maidstone", + "E07000074" => "Maldon", + "E07000235" => "Malvern Hills", + "E08000003" => "Manchester", + "E07000174" => "Mansfield", + "E06000035" => "Medway", + "E07000133" => "Melton", + "W06000024" => "Merthyr Tydfil", + "E09000024" => "Merton", + "E07000042" => "Mid Devon", + "E07000203" => "Mid Suffolk", + "E07000228" => "Mid Sussex", + "N09000009" => "Mid Ulster", + "N09000008" => "Mid and East Antrim", + "E06000002" => "Middlesbrough", + "S12000019" => "Midlothian", + "E06000042" => "Milton Keynes", + "E07000210" => "Mole Valley", + "W06000021" => "Monmouthshire", + "S12000020" => "Moray", + "S12000013" => "Na h-Eileanan Siar", + "W06000012" => "Neath Port Talbot", + "E07000091" => "New Forest", + "E07000175" => "Newark and Sherwood", + "E08000021" => "Newcastle upon Tyne", + "E07000195" => "Newcastle-under-Lyme", + "E09000025" => "Newham", + "W06000022" => "Newport", + "N09000010" => "Newry, Mourne and Down", + "S12000021" => "North Ayrshire", + "E07000043" => "North Devon", + "E07000038" => "North East Derbyshire", + "E06000012" => "North East Lincolnshire", + "E07000099" => "North Hertfordshire", + "E07000139" => "North Kesteven", + "S12000050" => "North Lanarkshire", + "E06000013" => "North Lincolnshire", + "E07000147" => "North Norfolk", + "E06000024" => "North Somerset", + "E08000022" => "North Tyneside", + "E07000218" => "North Warwickshire", + "E06000065" => "North Yorkshire", + "E07000134" => "North West Leicestershire", + "E07000154" => "Northampton", + "E06000057" => "Northumberland", + "E07000148" => "Norwich", + "E06000018" => "Nottingham", + "E07000219" => "Nuneaton and Bedworth", + "E07000135" => "Oadby and Wigston", + "E08000004" => "Oldham", + "S12000023" => "Orkney Islands", + "E07000178" => "Oxford", + "W06000009" => "Pembrokeshire", + "E07000122" => "Pendle", + "S12000048" => "Perth and Kinross", + "E06000031" => "Peterborough", + "E06000026" => "Plymouth", + "E06000044" => "Portsmouth", + "W06000023" => "Powys", + "E07000123" => "Preston", + "E06000038" => "Reading", + "E09000026" => "Redbridge", + "E06000003" => "Redcar and Cleveland", + "E07000236" => "Redditch", + "E07000211" => "Reigate and Banstead", + "S12000038" => "Renfrewshire", + "W06000016" => "Rhondda Cynon Taf", + "E07000124" => "Ribble Valley", + "E09000027" => "Richmond upon Thames", + "E08000005" => "Rochdale", + "E07000075" => "Rochford", + "E07000125" => "Rossendale", + "E07000064" => "Rother", + "E08000018" => "Rotherham", + "E07000220" => "Rugby", + "E07000212" => "Runnymede", + "E07000176" => "Rushcliffe", + "E07000092" => "Rushmoor", + "E06000017" => "Rutland", + "E08000006" => "Salford", + "E08000028" => "Sandwell", + "S12000026" => "Scottish Borders", + "E08000014" => "Sefton", + "E07000111" => "Sevenoaks", + "E08000019" => "Sheffield", + "S12000027" => "Shetland Islands", + "E06000051" => "Shropshire", + "E06000039" => "Slough", + "E08000029" => "Solihull", + "E06000066" => "Somerset", + "S12000028" => "South Ayrshire", + "E07000012" => "South Cambridgeshire", + "E07000039" => "South Derbyshire", + "E06000025" => "South Gloucestershire", + "E07000044" => "South Hams", + "E07000140" => "South Holland", + "E07000141" => "South Kesteven", + "S12000029" => "South Lanarkshire", + "E07000149" => "South Norfolk", + "E07000155" => "South Northamptonshire", + "E07000179" => "South Oxfordshire", + "E07000126" => "South Ribble", + "E07000196" => "South Staffordshire", + "E08000023" => "South Tyneside", + "E06000045" => "Southampton", + "E06000033" => "Southend-on-Sea", + "E09000028" => "Southwark", + "E07000213" => "Spelthorne", + "E07000240" => "St Albans", + "E08000013" => "St. Helens", + "E07000197" => "Stafford", + "E07000198" => "Staffordshire Moorlands", + "E07000243" => "Stevenage", + "S12000030" => "Stirling", + "E08000007" => "Stockport", + "E06000004" => "Stockton-on-Tees", + "E06000021" => "Stoke-on-Trent", + "E07000221" => "Stratford-on-Avon", + "E07000082" => "Stroud", + "E08000024" => "Sunderland", + "E07000214" => "Surrey Heath", + "E09000029" => "Sutton", + "E07000113" => "Swale", + "W06000011" => "Swansea", + "E06000030" => "Swindon", + "E08000008" => "Tameside", + "E07000199" => "Tamworth", + "E07000215" => "Tandridge", + "E07000045" => "Teignbridge", + "E06000020" => "Telford and Wrekin", + "E07000076" => "Tendring", + "E07000093" => "Test Valley", + "E07000083" => "Tewkesbury", + "E07000114" => "Thanet", + "E07000102" => "Three Rivers", + "E06000034" => "Thurrock", + "E07000115" => "Tonbridge and Malling", + "E06000027" => "Torbay", + "W06000020" => "Torfaen", + "E07000046" => "Torridge", + "E09000030" => "Tower Hamlets", + "E08000009" => "Trafford", + "E07000116" => "Tunbridge Wells", + "E07000077" => "Uttlesford", + "W06000014" => "Vale of Glamorgan", + "E07000180" => "Vale of White Horse", + "E08000036" => "Wakefield", + "E08000030" => "Walsall", + "E09000031" => "Waltham Forest", + "E09000032" => "Wandsworth", + "E06000007" => "Warrington", + "E07000222" => "Warwick", + "E07000103" => "Watford", + "E07000216" => "Waverley", + "E07000065" => "Wealden", + "E07000156" => "Wellingborough", + "E07000241" => "Welwyn Hatfield", + "E06000037" => "West Berkshire", + "E07000047" => "West Devon", + "S12000039" => "West Dunbartonshire", + "E07000127" => "West Lancashire", + "E07000142" => "West Lindsey", + "S12000040" => "West Lothian", + "E07000181" => "West Oxfordshire", + "E07000245" => "West Suffolk", + "E09000033" => "Westminster", + "E06000064" => "Westmorland and Furness", + "E08000010" => "Wigan", + "E06000054" => "Wiltshire", + "E07000094" => "Winchester", + "E06000040" => "Windsor and Maidenhead", + "E08000015" => "Wirral", + "E07000217" => "Woking", + "E06000041" => "Wokingham", + "E08000031" => "Wolverhampton", + "E07000237" => "Worcester", + "E07000229" => "Worthing", + "W06000006" => "Wrexham", + "E07000238" => "Wychavon", + "E07000128" => "Wyre", + "E07000239" => "Wyre Forest", + "E06000014" => "York", + "N92000002" => "Northern Ireland", + "S92000003" => "Scotland", + "W92000004" => "Wales", + "9300000XX" => "Outside UK", + }) + end +end diff --git a/spec/models/form/lettings/questions/reason_spec.rb b/spec/models/form/lettings/questions/reason_spec.rb new file mode 100644 index 000000000..24d28fd4b --- /dev/null +++ b/spec/models/form/lettings/questions/reason_spec.rb @@ -0,0 +1,158 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::Reason, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("reason") + end + + it "has the correct header" do + expect(question.header).to eq("What is the tenant’s main reason for the household leaving their last settled home?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Reason for leaving last settled home") + end + + it "has the correct type" do + expect(question.type).to eq("radio") + end + + it "has the correct check_answers_card_number" do + expect(question.check_answers_card_number).to eq(0) + end + + it "has the correct hint" do + expect(question.hint_text).to eq("The tenant’s ‘last settled home’ is their last long-standing home. For tenants who were in temporary accommodation or sleeping rough, their last settled home is where they were living previously.") + end + + it "has the correct conditional_for" do + expect(question.conditional_for).to eq({ "reasonother" => [20] }) + end + + it "is not marked as derived" do + expect(question).not_to be_derived + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "40" => { + "value" => "End of assured shorthold tenancy (no fault)", + }, + "41" => { + "value" => "End of assured shorthold tenancy (eviction or tenant at fault)", + }, + "42" => { + "value" => "End of fixed term tenancy (no fault)", + }, + "43" => { + "value" => "End of fixed term tenancy (eviction or tenant at fault)", + }, + "1" => { + "value" => "Permanently decanted from another property owned by this landlord", + }, + "46" => { + "value" => "Discharged from long-stay hospital or similar institution", + }, + "45" => { + "value" => "Discharged from prison", + }, + "2" => { + "value" => "Left home country as a refugee", + }, + "4" => { + "value" => "Loss of tied accommodation", + }, + "9" => { + "value" => "Asked to leave by family or friends", + }, + "44" => { + "value" => "Death of household member in last settled accommodation", + }, + "8" => { + "value" => "Relationship breakdown (non-violent) with partner", + }, + "16" => { + "value" => "To move nearer to family, friends or school", + }, + "17" => { + "value" => "To move nearer to work", + }, + "48" => { + "value" => "Domestic abuse - previously joint tenancy with partner", + }, + "49" => { + "value" => "Domestic abuse - other", + }, + "31" => { + "value" => "Hate crime", + }, + "10" => { + "value" => "Racial harassment", + }, + "11" => { + "value" => "Other problems with neighbours", + }, + "35" => { + "value" => "Couldn’t afford fees attached to renewing the tenancy", + }, + "36" => { + "value" => "Couldn’t afford increase in rent", + }, + "38" => { + "value" => "Couldn’t afford rent or mortgage (employment)", + }, + "37" => { + "value" => "Couldn’t afford rent or mortgage (welfare reforms)", + }, + "39" => { + "value" => "Couldn’t afford rent or mortgage (other)", + }, + "34" => { + "value" => "Repossession", + }, + "12" => { + "value" => "Property unsuitable because of overcrowding", + }, + "13" => { + "value" => "Property unsuitable because of ill health or disability", + }, + "14" => { + "value" => "Property unsuitable because of poor condition", + }, + "18" => { + "value" => "To move to accommodation with support", + }, + "19" => { + "value" => "To move to independent accommodation", + }, + "30" => { + "value" => "Under occupation (no incentive)", + }, + "29" => { + "value" => "Under occupation (offered incentive to downsize)", + }, + "20" => { + "value" => "Other", + }, + "47" => { + "value" => "Tenant prefers not to say", + }, + "divider" => { + "value" => true, + }, + "28" => { + "value" => "Don’t know", + }, + }) + end +end diff --git a/spec/models/form/lettings/questions/sheltered_spec.rb b/spec/models/form/lettings/questions/sheltered_spec.rb new file mode 100644 index 000000000..5b9b3c743 --- /dev/null +++ b/spec/models/form/lettings/questions/sheltered_spec.rb @@ -0,0 +1,46 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::Sheltered, type: :model do + subject(:question) { described_class.new(nil, nil, page) } + + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq page + end + + it "has the correct id" do + expect(question.id).to eq "sheltered" + end + + it "has the correct header" do + expect(question.header).to eq "Is this letting in sheltered accommodation?" + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq "Is this letting in sheltered accommodation?" + end + + it "has the correct type" do + expect(question.type).to eq "radio" + end + + it "has the correct hint_text" do + expect(question.hint_text).to eq "" + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "2" => { "value" => "Yes – extra care housing" }, + "1" => { "value" => "Yes – specialist retirement housing" }, + "5" => { "value" => "Yes – sheltered housing for adults aged under 55 years" }, + "3" => { "value" => "No" }, + "divider" => { "value" => true }, + "4" => { "value" => "Don’t know" }, + }) + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end +end diff --git a/spec/models/form/lettings/questions/tenancy_length_spec.rb b/spec/models/form/lettings/questions/tenancy_length_spec.rb new file mode 100644 index 000000000..8eea52a81 --- /dev/null +++ b/spec/models/form/lettings/questions/tenancy_length_spec.rb @@ -0,0 +1,44 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::TenancyLength, type: :model do + subject(:question) { described_class.new(nil, nil, page) } + + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("tenancylength") + end + + it "has the correct header" do + expect(question.header).to eq("What is the length of the fixed-term tenancy to the nearest year?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Length of fixed-term tenancy") + end + + it "has the correct type" do + expect(question.type).to eq("numeric") + end + + it "has the correct hint_text" do + expect(question.hint_text).to eq("Don’t include the starter or introductory period.") + end + + it "has the correct minimum and maximum" do + expect(question.min).to eq 0 + expect(question.max).to eq 150 + end + + it "has the correct step" do + expect(question.step).to eq 1 + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end +end diff --git a/spec/models/form/lettings/questions/tenancy_other_spec.rb b/spec/models/form/lettings/questions/tenancy_other_spec.rb new file mode 100644 index 000000000..58a656e57 --- /dev/null +++ b/spec/models/form/lettings/questions/tenancy_other_spec.rb @@ -0,0 +1,35 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::TenancyOther, type: :model do + subject(:question) { described_class.new(nil, nil, page) } + + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("tenancyother") + end + + it "has the correct header" do + expect(question.header).to eq("Please state the tenancy type") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("") + end + + it "has the correct type" do + expect(question.type).to eq("text") + end + + it "has the correct hint_text" do + expect(question.hint_text).to eq("") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end +end diff --git a/spec/models/form/lettings/questions/tenancy_type_spec.rb b/spec/models/form/lettings/questions/tenancy_type_spec.rb new file mode 100644 index 000000000..8fd8a50f0 --- /dev/null +++ b/spec/models/form/lettings/questions/tenancy_type_spec.rb @@ -0,0 +1,65 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::TenancyType, type: :model do + subject(:question) { described_class.new(nil, nil, page) } + + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("tenancy") + end + + it "has the correct header" do + expect(question.header).to eq("What is the type of tenancy?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Type of main tenancy") + end + + it "has the correct type" do + expect(question.type).to eq("radio") + end + + it "has the correct hint_text" do + expect(question.hint_text).to eq("") + end + + it "has the correct conditional_for" do + expect(question.conditional_for).to eq({ "tenancyother" => [3] }) + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "4" => { + "value" => "Assured Shorthold Tenancy (AST) – Fixed term", + "hint" => "Mostly housing associations provide these. Fixed term tenancies are intended to be for a set amount of time up to 20 years.", + }, + "6" => { + "value" => "Secure – fixed term", + "hint" => "Mostly local authorities provide these. Fixed term tenancies are intended to be for a set amount of time up to 20 years.", + }, + "2" => { + "value" => "Assured – lifetime", + }, + "7" => { + "value" => "Secure – lifetime", + }, + "5" => { + "value" => "Licence agreement", + "hint" => "Licence agreements are mostly used for Supported Housing and work on a rolling basis.", + }, + "3" => { + "value" => "Other", + }, + }) + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end +end diff --git a/spec/models/form/lettings/subsections/household_characteristics_spec.rb b/spec/models/form/lettings/subsections/household_characteristics_spec.rb index 96d722a2b..d0d55b8bf 100644 --- a/spec/models/form/lettings/subsections/household_characteristics_spec.rb +++ b/spec/models/form/lettings/subsections/household_characteristics_spec.rb @@ -36,7 +36,8 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod lead_tenant_over_retirement_value_check person_2_known person_2_relationship_to_lead - person_2_age + person_2_age_child + person_2_age_non_child no_females_pregnant_household_person_2_age_value_check females_in_soft_age_range_in_pregnant_household_person_2_age_value_check person_2_gender_identity @@ -47,7 +48,8 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod person_2_over_retirement_value_check person_3_known person_3_relationship_to_lead - person_3_age + person_3_age_child + person_3_age_non_child no_females_pregnant_household_person_3_age_value_check females_in_soft_age_range_in_pregnant_household_person_3_age_value_check person_3_gender_identity @@ -58,7 +60,8 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod person_3_over_retirement_value_check person_4_known person_4_relationship_to_lead - person_4_age + person_4_age_child + person_4_age_non_child no_females_pregnant_household_person_4_age_value_check females_in_soft_age_range_in_pregnant_household_person_4_age_value_check person_4_gender_identity @@ -69,7 +72,8 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod person_4_over_retirement_value_check person_5_known person_5_relationship_to_lead - person_5_age + person_5_age_child + person_5_age_non_child no_females_pregnant_household_person_5_age_value_check females_in_soft_age_range_in_pregnant_household_person_5_age_value_check person_5_gender_identity @@ -80,7 +84,8 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod person_5_over_retirement_value_check person_6_known person_6_relationship_to_lead - person_6_age + person_6_age_child + person_6_age_non_child no_females_pregnant_household_person_6_age_value_check females_in_soft_age_range_in_pregnant_household_person_6_age_value_check person_6_gender_identity @@ -91,7 +96,8 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod person_6_over_retirement_value_check person_7_known person_7_relationship_to_lead - person_7_age + person_7_age_child + person_7_age_non_child no_females_pregnant_household_person_7_age_value_check females_in_soft_age_range_in_pregnant_household_person_7_age_value_check person_7_gender_identity @@ -102,7 +108,8 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod person_7_over_retirement_value_check person_8_known person_8_relationship_to_lead - person_8_age + person_8_age_child + person_8_age_non_child no_females_pregnant_household_person_8_age_value_check females_in_soft_age_range_in_pregnant_household_person_8_age_value_check person_8_gender_identity diff --git a/spec/models/form/lettings/subsections/tenancy_information_spec.rb b/spec/models/form/lettings/subsections/tenancy_information_spec.rb index 7dd3e3a10..475ea209c 100644 --- a/spec/models/form/lettings/subsections/tenancy_information_spec.rb +++ b/spec/models/form/lettings/subsections/tenancy_information_spec.rb @@ -13,7 +13,7 @@ RSpec.describe Form::Lettings::Subsections::TenancyInformation, type: :model do it "has correct pages" do expect(tenancy_information.pages.map(&:id)).to eq( - %w[joint starter_tenancy tenancy_type starter_tenancy_type tenancy_length shelteredaccom], + %w[joint starter_tenancy tenancy_type starter_tenancy_type tenancy_length sheltered_accommodation], ) end diff --git a/spec/models/form/page_spec.rb b/spec/models/form/page_spec.rb index 4a870fe46..17bd7dcc9 100644 --- a/spec/models/form/page_spec.rb +++ b/spec/models/form/page_spec.rb @@ -3,6 +3,15 @@ require "rails_helper" RSpec.describe Form::Page, type: :model do subject(:page) { described_class.new(page_id, page_definition, subsection) } + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + let(:user) { FactoryBot.create(:user) } let(:lettings_log) { FactoryBot.build(:lettings_log) } let(:form) { lettings_log.form } diff --git a/spec/models/form/question_spec.rb b/spec/models/form/question_spec.rb index 48e71c76b..ede6636f7 100644 --- a/spec/models/form/question_spec.rb +++ b/spec/models/form/question_spec.rb @@ -3,6 +3,15 @@ require "rails_helper" RSpec.describe Form::Question, type: :model do subject(:question) { described_class.new(question_id, question_definition, page) } + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + let(:lettings_log) { FactoryBot.build(:lettings_log) } let(:form) { lettings_log.form } let(:section_id) { "rent_and_charges" } @@ -367,7 +376,7 @@ RSpec.describe Form::Question, type: :model do end context "when Sales form" do - let(:sales_log) { FactoryBot.create(:sales_log, :completed, ethnic_group: 17) } + let(:sales_log) { FactoryBot.create(:sales_log, :completed, ethnic_group: 17, saledate: Time.zone.local(2022, 1, 1)) } let(:question) { sales_log.form.get_question("ethnic_group", sales_log) } it "returns the inferred label value" do diff --git a/spec/models/form/sales/pages/about_deposit_without_discount_spec.rb b/spec/models/form/sales/pages/about_deposit_without_discount_spec.rb index 62212e011..1a0b5ef4d 100644 --- a/spec/models/form/sales/pages/about_deposit_without_discount_spec.rb +++ b/spec/models/form/sales/pages/about_deposit_without_discount_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do - subject(:page) { described_class.new(page_id, page_definition, subsection) } + subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1) } let(:page_id) { nil } let(:page_definition) { nil } diff --git a/spec/models/form/sales/pages/about_staircase_spec.rb b/spec/models/form/sales/pages/about_staircase_spec.rb index 3828f52e4..48aa82acf 100644 --- a/spec/models/form/sales/pages/about_staircase_spec.rb +++ b/spec/models/form/sales/pages/about_staircase_spec.rb @@ -1,11 +1,12 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::AboutStaircase, type: :model do - subject(:page) { described_class.new(page_id, page_definition, subsection) } + subject(:page) { described_class.new(page_id, page_definition, subsection, joint_purchase:) } - let(:page_id) { nil } + let(:page_id) { "an_id" } let(:page_definition) { nil } let(:subsection) { instance_double(Form::Subsection) } + let(:joint_purchase) { false } it "has correct subsection" do expect(page.subsection).to eq(subsection) @@ -32,7 +33,7 @@ RSpec.describe Form::Sales::Pages::AboutStaircase, type: :model do end it "has the correct id" do - expect(page.id).to eq("about_staircasing") + expect(page.id).to eq("an_id") end it "has the correct header" do @@ -43,9 +44,23 @@ RSpec.describe Form::Sales::Pages::AboutStaircase, type: :model do expect(page.description).to be_nil end - it "has correct depends_on" do - expect(page.depends_on).to eq([{ - "staircase" => 1, - }]) + context "when not a joint purchase" do + it "has correct depends_on" do + expect(page.depends_on).to eq([{ + "staircase" => 1, + "joint_purchase?" => false, + }]) + end + end + + context "when a joint purchase" do + let(:joint_purchase) { true } + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ + "staircase" => 1, + "joint_purchase?" => true, + }]) + end end end diff --git a/spec/models/form/sales/pages/address_spec.rb b/spec/models/form/sales/pages/address_spec.rb new file mode 100644 index 000000000..d6979b6b4 --- /dev/null +++ b/spec/models/form/sales/pages/address_spec.rb @@ -0,0 +1,73 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Pages::Address, type: :model do + subject(:page) { described_class.new(page_id, page_definition, subsection) } + + let(:page_id) { nil } + let(:page_definition) { nil } + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[address_line1 address_line2 town_or_city county postcode_full]) + end + + it "has the correct id" do + expect(page.id).to eq("address") + end + + it "has the correct header" do + expect(page.header).to eq("What is the property's address?") + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has correct depends_on" do + expect(page.depends_on).to be_nil + end + + describe "has correct routed_to?" do + context "when uprn_known == nil" do + let(:log) { create(:sales_log, uprn_known: nil) } + + it "returns false" do + expect(page.routed_to?(log)).to eq(false) + end + end + + context "when uprn_confirmed != 1" do + let(:log) do + create(:sales_log, uprn_known: 1, uprn_confirmed: 0) + end + + it "returns true" do + expect(page.routed_to?(log)).to eq(true) + end + end + + context "when uprn_known == 0" do + let(:log) do + create(:sales_log, uprn_known: 0, uprn_confirmed: 0) + end + + it "returns true" do + expect(page.routed_to?(log)).to eq(true) + end + end + + context "when uprn_confirmed == 1 && uprn_known != 0" do + let(:log) do + create(:sales_log, uprn_known: 1, uprn_confirmed: 1) + end + + it "returns true" do + expect(page.routed_to?(log)).to eq(false) + end + end + end +end diff --git a/spec/models/form/sales/pages/buyer2_live_in_property_spec.rb b/spec/models/form/sales/pages/buyer2_live_in_property_spec.rb index 258e37462..555e78927 100644 --- a/spec/models/form/sales/pages/buyer2_live_in_property_spec.rb +++ b/spec/models/form/sales/pages/buyer2_live_in_property_spec.rb @@ -30,12 +30,12 @@ RSpec.describe Form::Sales::Pages::Buyer2LiveInProperty, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq([ { - "jointpur" => 1, + "joint_purchase?" => true, "privacynotice" => 1, }, { - "jointpur" => 1, - "noint" => 1, + "joint_purchase?" => true, + "buyer_not_interviewed?" => true, }, ]) end diff --git a/spec/models/form/sales/pages/buyer2_living_in_spec.rb b/spec/models/form/sales/pages/buyer2_living_in_spec.rb new file mode 100644 index 000000000..9bfef1ff4 --- /dev/null +++ b/spec/models/form/sales/pages/buyer2_living_in_spec.rb @@ -0,0 +1,31 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Pages::Buyer2LivingIn, type: :model do + subject(:page) { described_class.new(nil, nil, subsection) } + + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[buy2living]) + end + + it "has the correct id" do + expect(page.id).to eq("buyer_2_living_in") + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "buyer_two_will_live_in_property?" => true }]) + end +end diff --git a/spec/models/form/sales/pages/buyer2_nationality_spec.rb b/spec/models/form/sales/pages/buyer2_nationality_spec.rb new file mode 100644 index 000000000..92c891f88 --- /dev/null +++ b/spec/models/form/sales/pages/buyer2_nationality_spec.rb @@ -0,0 +1,31 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Pages::Buyer2Nationality, type: :model do + subject(:page) { described_class.new(nil, nil, subsection) } + + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to be subsection + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq %w[nationalbuy2] + end + + it "has the correct id" do + expect(page.id).to eq "buyer_2_nationality" + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has correct depends_on" do + expect(page.depends_on).to eq [{ "joint_purchase?" => true }] + end +end diff --git a/spec/models/form/sales/pages/buyer2_previous_housing_situation_spec.rb b/spec/models/form/sales/pages/buyer2_previous_housing_situation_spec.rb new file mode 100644 index 000000000..ac5611a8f --- /dev/null +++ b/spec/models/form/sales/pages/buyer2_previous_housing_situation_spec.rb @@ -0,0 +1,31 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Pages::Buyer2PreviousHousingSituation, type: :model do + subject(:page) { described_class.new(nil, nil, subsection) } + + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[prevtenbuy2]) + end + + it "has the correct id" do + expect(page.id).to eq("buyer_2_previous_housing_situation") + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "buyer_two_not_already_living_in_property?" => true }]) + end +end diff --git a/spec/models/form/sales/pages/buyer_previous_spec.rb b/spec/models/form/sales/pages/buyer_previous_spec.rb index a3355c137..e6dda073e 100644 --- a/spec/models/form/sales/pages/buyer_previous_spec.rb +++ b/spec/models/form/sales/pages/buyer_previous_spec.rb @@ -1,11 +1,12 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::BuyerPrevious, type: :model do - subject(:page) { described_class.new(page_id, page_definition, subsection) } + subject(:page) { described_class.new(page_id, page_definition, subsection, joint_purchase:) } - let(:page_id) { nil } + let(:page_id) { "example" } let(:page_definition) { nil } let(:subsection) { instance_double(Form::Subsection) } + let(:joint_purchase) { false } it "has correct subsection" do expect(page.subsection).to eq(subsection) @@ -16,7 +17,7 @@ RSpec.describe Form::Sales::Pages::BuyerPrevious, type: :model do end it "has the correct id" do - expect(page.id).to eq("buyer_previous") + expect(page.id).to eq("example") end it "has the correct header" do @@ -26,4 +27,18 @@ RSpec.describe Form::Sales::Pages::BuyerPrevious, type: :model do it "has the correct description" do expect(page.description).to be_nil end + + context "when sales is a joint purchase" do + let(:joint_purchase) { true } + + it "has the correct depends on" do + expect(page.depends_on).to eq([{ "joint_purchase?" => true }]) + end + end + + context "when sales is not a joint purchase" do + it "has the correct depends on" do + expect(page.depends_on).to eq([{ "joint_purchase?" => false }]) + end + end end diff --git a/spec/models/form/sales/pages/extra_borrowing_spec.rb b/spec/models/form/sales/pages/extra_borrowing_spec.rb index 5540f89cf..a0c148c9f 100644 --- a/spec/models/form/sales/pages/extra_borrowing_spec.rb +++ b/spec/models/form/sales/pages/extra_borrowing_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::ExtraBorrowing, type: :model do - subject(:page) { described_class.new(page_id, page_definition, subsection) } + subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1) } let(:page_id) { nil } let(:page_definition) { nil } diff --git a/spec/models/form/sales/pages/last_accommodation_la_spec.rb b/spec/models/form/sales/pages/last_accommodation_la_spec.rb index fb3890cc6..20daf0525 100644 --- a/spec/models/form/sales/pages/last_accommodation_la_spec.rb +++ b/spec/models/form/sales/pages/last_accommodation_la_spec.rb @@ -5,7 +5,8 @@ RSpec.describe Form::Sales::Pages::LastAccommodationLa, type: :model do let(:page_id) { nil } let(:page_definition) { nil } - let(:subsection) { instance_double(Form::Subsection) } + let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date:)) } + let(:start_date) { Time.utc(2022, 4, 1) } it "has correct subsection" do expect(page.subsection).to eq(subsection) diff --git a/spec/models/form/sales/pages/leasehold_charges_spec.rb b/spec/models/form/sales/pages/leasehold_charges_spec.rb index c729bc82e..d58b965c3 100644 --- a/spec/models/form/sales/pages/leasehold_charges_spec.rb +++ b/spec/models/form/sales/pages/leasehold_charges_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::LeaseholdCharges, type: :model do - subject(:page) { described_class.new(page_id, page_definition, subsection) } + subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1) } let(:page_id) { nil } let(:page_definition) { nil } diff --git a/spec/models/form/sales/pages/living_before_purchase_spec.rb b/spec/models/form/sales/pages/living_before_purchase_spec.rb index 76dbd7609..939910583 100644 --- a/spec/models/form/sales/pages/living_before_purchase_spec.rb +++ b/spec/models/form/sales/pages/living_before_purchase_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::LivingBeforePurchase, type: :model do - subject(:page) { described_class.new(page_id, page_definition, subsection) } + subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1) } let(:page_id) { nil } let(:page_definition) { nil } diff --git a/spec/models/form/sales/pages/mortgage_amount_spec.rb b/spec/models/form/sales/pages/mortgage_amount_spec.rb index 1aa563d9b..551788fbb 100644 --- a/spec/models/form/sales/pages/mortgage_amount_spec.rb +++ b/spec/models/form/sales/pages/mortgage_amount_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::MortgageAmount, type: :model do - subject(:page) { described_class.new(page_id, page_definition, subsection) } + subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1) } let(:page_id) { nil } let(:page_definition) { nil } diff --git a/spec/models/form/sales/pages/mortgage_lender_other_spec.rb b/spec/models/form/sales/pages/mortgage_lender_other_spec.rb index 32ad5bb6b..93ef4d342 100644 --- a/spec/models/form/sales/pages/mortgage_lender_other_spec.rb +++ b/spec/models/form/sales/pages/mortgage_lender_other_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::MortgageLenderOther, type: :model do - subject(:page) { described_class.new(page_id, page_definition, subsection) } + subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1) } let(:page_id) { "mortgage_lender_other" } let(:page_definition) { nil } diff --git a/spec/models/form/sales/pages/mortgage_lender_spec.rb b/spec/models/form/sales/pages/mortgage_lender_spec.rb index fafa8e043..ad195b8a1 100644 --- a/spec/models/form/sales/pages/mortgage_lender_spec.rb +++ b/spec/models/form/sales/pages/mortgage_lender_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::MortgageLender, type: :model do - subject(:page) { described_class.new(page_id, page_definition, subsection) } + subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1) } let(:page_id) { "mortgage_lender" } let(:page_definition) { nil } diff --git a/spec/models/form/sales/pages/mortgage_length_spec.rb b/spec/models/form/sales/pages/mortgage_length_spec.rb index ef2573e57..5b04503a0 100644 --- a/spec/models/form/sales/pages/mortgage_length_spec.rb +++ b/spec/models/form/sales/pages/mortgage_length_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::MortgageLength, type: :model do - subject(:page) { described_class.new(page_id, page_definition, subsection) } + subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1) } let(:page_id) { nil } let(:page_definition) { nil } diff --git a/spec/models/form/sales/pages/mortgageused_spec.rb b/spec/models/form/sales/pages/mortgageused_spec.rb index 963814074..71fe94128 100644 --- a/spec/models/form/sales/pages/mortgageused_spec.rb +++ b/spec/models/form/sales/pages/mortgageused_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::Mortgageused, type: :model do - subject(:page) { described_class.new(page_id, page_definition, subsection) } + subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1) } let(:page_id) { "mortgage_used" } let(:page_definition) { nil } diff --git a/spec/models/form/sales/pages/nationality1_spec.rb b/spec/models/form/sales/pages/nationality1_spec.rb index da5a5f802..37b58a89f 100644 --- a/spec/models/form/sales/pages/nationality1_spec.rb +++ b/spec/models/form/sales/pages/nationality1_spec.rb @@ -1,22 +1,20 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::Nationality1, type: :model do - subject(:page) { described_class.new(page_id, page_definition, subsection) } + subject(:page) { described_class.new(nil, nil, subsection) } - let(:page_id) { nil } - let(:page_definition) { nil } let(:subsection) { instance_double(Form::Subsection) } it "has correct subsection" do - expect(page.subsection).to eq(subsection) + expect(page.subsection).to be subsection end it "has correct questions" do - expect(page.questions.map(&:id)).to eq(%w[national othernational]) + expect(page.questions.map(&:id)).to eq %w[national] end it "has the correct id" do - expect(page.id).to eq("buyer_1_nationality") + expect(page.id).to eq "buyer_1_nationality" end it "has the correct header" do @@ -28,6 +26,6 @@ RSpec.describe Form::Sales::Pages::Nationality1, type: :model do end it "has correct depends_on" do - expect(page.depends_on).to eq([{ "privacynotice" => 1 }, { "noint" => 1 }]) + expect(page.depends_on).to eq [{ "privacynotice" => 1 }, { "buyer_not_interviewed?" => true }] end end diff --git a/spec/models/form/sales/pages/person_student_not_child_value_check_spec.rb b/spec/models/form/sales/pages/person_student_not_child_value_check_spec.rb new file mode 100644 index 000000000..3499cda9f --- /dev/null +++ b/spec/models/form/sales/pages/person_student_not_child_value_check_spec.rb @@ -0,0 +1,106 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Pages::PersonStudentNotChildValueCheck, type: :model do + subject(:page) { described_class.new(page_id, page_definition, subsection, person_index:) } + + let(:page_definition) { nil } + let(:subsection) { instance_double(Form::Subsection) } + let(:person_index) { 2 } + + let(:page_id) { "person_2_student_not_child_value_check" } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "is interruption screen page" do + expect(page.interruption_screen?).to eq(true) + end + + it "has correct title_text" do + expect(page.title_text).to eq({ + "translation" => "soft_validations.student_not_child.title_text", + }) + end + + it "has correct informative_text" do + expect(page.informative_text).to eq({}) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[student_not_child_value_check]) + end + + context "with person 2" do + let(:person_index) { 2 } + let(:page_id) { "person_2_student_not_child_value_check" } + + it "has the correct id" do + expect(page.id).to eq(page_id) + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "person_2_student_not_child?" => true }]) + end + end + + context "with person 3" do + let(:person_index) { 3 } + let(:page_id) { "person_3_student_not_child_value_check" } + + it "has the correct id" do + expect(page.id).to eq(page_id) + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "person_3_student_not_child?" => true }]) + end + end + + context "with person 4" do + let(:person_index) { 4 } + let(:page_id) { "person_4_student_not_child_value_check" } + + it "has the correct id" do + expect(page.id).to eq(page_id) + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "person_4_student_not_child?" => true }]) + end + end + + context "with person 5" do + let(:person_index) { 5 } + let(:page_id) { "person_5_student_not_child_value_check" } + + it "has the correct id" do + expect(page.id).to eq(page_id) + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "person_5_student_not_child?" => true }]) + end + end + + context "with person 6" do + let(:person_index) { 6 } + let(:page_id) { "person_6_student_not_child_value_check" } + + it "has the correct id" do + expect(page.id).to eq(page_id) + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "person_6_student_not_child?" => true }]) + end + end +end diff --git a/spec/models/form/sales/pages/previous_bedrooms_spec.rb b/spec/models/form/sales/pages/previous_bedrooms_spec.rb index 5e1e18a52..8e2d03a20 100644 --- a/spec/models/form/sales/pages/previous_bedrooms_spec.rb +++ b/spec/models/form/sales/pages/previous_bedrooms_spec.rb @@ -28,8 +28,13 @@ RSpec.describe Form::Sales::Pages::PreviousBedrooms, type: :model do end it "has correct depends_on" do - expect(page.depends_on).to eq([{ - "soctenant" => 1, - }]) + expect(page.depends_on).to eq([ + { + "soctenant" => 1, + }, + { + "soctenant" => 0, + }, + ]) end end diff --git a/spec/models/form/sales/pages/previous_ownership_spec.rb b/spec/models/form/sales/pages/previous_ownership_spec.rb index 7fe0d2795..69c93fefa 100644 --- a/spec/models/form/sales/pages/previous_ownership_spec.rb +++ b/spec/models/form/sales/pages/previous_ownership_spec.rb @@ -1,11 +1,12 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::PreviousOwnership, type: :model do - subject(:page) { described_class.new(page_id, page_definition, subsection) } + subject(:page) { described_class.new(page_id, page_definition, subsection, joint_purchase:) } - let(:page_id) { nil } + let(:page_id) { "example_id" } let(:page_definition) { nil } let(:subsection) { instance_double(Form::Subsection) } + let(:joint_purchase) { true } it "has correct subsection" do expect(page.subsection).to eq(subsection) @@ -16,7 +17,7 @@ RSpec.describe Form::Sales::Pages::PreviousOwnership, type: :model do end it "has the correct id" do - expect(page.id).to eq("previous_ownership") + expect(page.id).to eq("example_id") end it "has the correct header" do @@ -26,4 +27,16 @@ RSpec.describe Form::Sales::Pages::PreviousOwnership, type: :model do it "has the correct description" do expect(page.description).to be_nil end + + it "when sale is a joint purchase has the correct depends on" do + expect(page.depends_on).to eq([{ "joint_purchase?" => true }]) + end + + context "when sale is not a joint purchase" do + let(:joint_purchase) { false } + + it "has the correct depends on" do + expect(page.depends_on).to eq([{ "joint_purchase?" => false }]) + end + end end diff --git a/spec/models/form/sales/pages/previous_property_type_spec.rb b/spec/models/form/sales/pages/previous_property_type_spec.rb index 4cfae3b1c..21b3b3c0b 100644 --- a/spec/models/form/sales/pages/previous_property_type_spec.rb +++ b/spec/models/form/sales/pages/previous_property_type_spec.rb @@ -28,8 +28,13 @@ RSpec.describe Form::Sales::Pages::PreviousPropertyType, type: :model do end it "has correct depends_on" do - expect(page.depends_on).to eq([{ - "soctenant" => 1, - }]) + expect(page.depends_on).to eq([ + { + "soctenant" => 1, + }, + { + "soctenant" => 0, + }, + ]) end end diff --git a/spec/models/form/sales/pages/previous_tenure_spec.rb b/spec/models/form/sales/pages/previous_tenure_spec.rb index a4892d567..2ee7d5c02 100644 --- a/spec/models/form/sales/pages/previous_tenure_spec.rb +++ b/spec/models/form/sales/pages/previous_tenure_spec.rb @@ -28,8 +28,13 @@ RSpec.describe Form::Sales::Pages::PreviousTenure, type: :model do end it "has correct depends_on" do - expect(page.depends_on).to eq([{ - "soctenant" => 1, - }]) + expect(page.depends_on).to eq([ + { + "soctenant" => 1, + }, + { + "soctenant" => 0, + }, + ]) end end diff --git a/spec/models/form/sales/pages/property_local_authority_spec.rb b/spec/models/form/sales/pages/property_local_authority_spec.rb index 3c88a0cd6..8ac3aaa03 100644 --- a/spec/models/form/sales/pages/property_local_authority_spec.rb +++ b/spec/models/form/sales/pages/property_local_authority_spec.rb @@ -5,19 +5,38 @@ RSpec.describe Form::Sales::Pages::PropertyLocalAuthority, type: :model do let(:page_id) { nil } let(:page_definition) { nil } - let(:subsection) { instance_double(Form::Subsection) } + let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date:)) } + let(:start_date) { Time.utc(2022, 4, 1) } it "has correct subsection" do expect(page.subsection).to eq(subsection) end - it "has correct questions" do - expect(page.questions.map(&:id)).to eq( - %w[ - la_known - la - ], - ) + describe "has correct questions" do + context "when 2022" do + let(:start_date) { Time.utc(2022, 2, 8) } + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq( + %w[ + la_known + la + ], + ) + end + end + + context "when 2023" do + let(:start_date) { Time.utc(2023, 2, 8) } + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq( + %w[ + la + ], + ) + end + end end it "has the correct id" do @@ -37,4 +56,33 @@ RSpec.describe Form::Sales::Pages::PropertyLocalAuthority, type: :model do "is_la_inferred" => false, }]) end + + describe "has correct routed_to?" do + context "when start_date < 2023" do + let(:log) { create(:sales_log, uprn_known: 1) } + let(:start_date) { Time.utc(2022, 2, 8) } + + it "returns false" do + expect(page.routed_to?(log)).to eq(true) + end + end + + context "when start_date >= 2023" do + let(:log) { create(:sales_log, uprn_known: 1) } + let(:start_date) { Time.utc(2023, 2, 8) } + + it "returns true" do + expect(page.routed_to?(log)).to eq(true) + end + end + + context "when start_date < 2023 and uprn_known: nil" do + let(:log) { create(:sales_log, uprn_known: nil) } + let(:start_date) { Time.utc(2023, 2, 8) } + + it "returns true" do + expect(page.routed_to?(log)).to eq(false) + end + end + end end diff --git a/spec/models/form/sales/pages/purchase_price_outright_ownership_spec.rb b/spec/models/form/sales/pages/purchase_price_outright_ownership_spec.rb index 88c357034..11b84baa6 100644 --- a/spec/models/form/sales/pages/purchase_price_outright_ownership_spec.rb +++ b/spec/models/form/sales/pages/purchase_price_outright_ownership_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::PurchasePriceOutrightOwnership, type: :model do - subject(:page) { described_class.new(page_id, page_definition, subsection) } + subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1) } let(:page_id) { "purchase_price" } let(:page_definition) { nil } diff --git a/spec/models/form/sales/pages/uprn_confirmation_spec.rb b/spec/models/form/sales/pages/uprn_confirmation_spec.rb new file mode 100644 index 000000000..9deb50f02 --- /dev/null +++ b/spec/models/form/sales/pages/uprn_confirmation_spec.rb @@ -0,0 +1,59 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Pages::UprnConfirmation, type: :model do + subject(:page) { described_class.new(page_id, page_definition, subsection) } + + let(:page_id) { nil } + let(:page_definition) { nil } + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[uprn_confirmed]) + end + + it "has the correct id" do + expect(page.id).to eq("uprn_confirmation") + end + + it "has the correct header" do + expect(page.header).to eq("We found an address that might be this property") + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has correct depends_on" do + expect(page.depends_on).to be_nil + end + + describe "has correct routed_to?" do + context "when uprn present && uprn_known == 1 " do + let(:log) { create(:sales_log, uprn_known: 1, uprn: "123456789") } + + it "returns true" do + expect(page.routed_to?(log)).to eq(true) + end + end + + context "when uprn = nil" do + let(:log) { create(:sales_log, uprn_known: 1, uprn: nil) } + + it "returns false" do + expect(page.routed_to?(log)).to eq(false) + end + end + + context "when uprn_known == 0" do + let(:log) { create(:sales_log, uprn_known: 0, uprn: "123456789") } + + it "returns false" do + expect(page.routed_to?(log)).to eq(false) + end + end + end +end diff --git a/spec/models/form/sales/pages/uprn_known_spec.rb b/spec/models/form/sales/pages/uprn_known_spec.rb new file mode 100644 index 000000000..9c18cfa21 --- /dev/null +++ b/spec/models/form/sales/pages/uprn_known_spec.rb @@ -0,0 +1,33 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Pages::UprnKnown, type: :model do + subject(:page) { described_class.new(page_id, page_definition, subsection) } + + let(:page_id) { nil } + let(:page_definition) { nil } + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[uprn_known]) + end + + it "has the correct id" do + expect(page.id).to eq("uprn_known") + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has correct depends_on" do + expect(page.depends_on).to be_nil + end +end diff --git a/spec/models/form/sales/pages/uprn_spec.rb b/spec/models/form/sales/pages/uprn_spec.rb new file mode 100644 index 000000000..37fa0f329 --- /dev/null +++ b/spec/models/form/sales/pages/uprn_spec.rb @@ -0,0 +1,73 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Pages::Uprn, type: :model do + subject(:page) { described_class.new(page_id, page_definition, subsection) } + + let(:page_id) { nil } + let(:page_definition) { nil } + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[uprn]) + end + + it "has the correct id" do + expect(page.id).to eq("uprn") + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has correct depends_on" do + expect(page.depends_on).to be_nil + end + + it "has correct skip_text" do + expect(page.skip_text).to eq("Enter address instead") + end + + describe "has correct routed_to?" do + context "when uprn_known != 1" do + let(:log) { create(:sales_log, uprn_known: 0) } + + it "returns false" do + expect(page.routed_to?(log)).to eq(false) + end + end + + context "when uprn_known == 1" do + let(:log) { create(:sales_log, uprn_known: 1) } + + it "returns true" do + expect(page.routed_to?(log)).to eq(true) + end + end + end + + describe "has correct skip_href" do + context "when log is nil" do + it "is nil" do + expect(page.skip_href).to be_nil + end + end + + context "when log is present" do + let(:log) { create(:sales_log) } + + it "points to address page" do + expect(page.skip_href(log)).to eq( + "/sales-logs/#{log.id}/address", + ) + end + end + end +end diff --git a/spec/models/form/sales/questions/address_line1_spec.rb b/spec/models/form/sales/questions/address_line1_spec.rb new file mode 100644 index 000000000..bc65c0646 --- /dev/null +++ b/spec/models/form/sales/questions/address_line1_spec.rb @@ -0,0 +1,75 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::AddressLine1, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("address_line1") + end + + it "has the correct header" do + expect(question.header).to eq("Address line 1") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Address") + end + + it "has the correct type" do + expect(question.type).to eq("text") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint" do + expect(question.hint_text).to be_nil + end + + it "has the correct inferred check answers value" do + expect(question.inferred_check_answers_value).to be_nil + end + + it "has the correct check_answers_card_number" do + expect(question.check_answers_card_number).to be_nil + end + + describe "has the correct get_extra_check_answer_value" do + context "when la is not present" do + let(:log) { create(:sales_log, la: nil) } + + it "returns nil" do + expect(question.get_extra_check_answer_value(log)).to be_nil + end + end + + context "when la is present but not inferred" do + let(:log) { create(:sales_log, la: "E09000003", is_la_inferred: false) } + + it "returns nil" do + expect(question.get_extra_check_answer_value(log)).to be_nil + end + end + + context "when la is present but inferred" do + let(:log) { create(:sales_log, la: "E09000003") } + + before do + allow(log).to receive(:is_la_inferred?).and_return(true) + end + + it "returns the la" do + expect(question.get_extra_check_answer_value(log)).to eq("Barnet") + end + end + end +end diff --git a/spec/models/form/sales/questions/address_line2_spec.rb b/spec/models/form/sales/questions/address_line2_spec.rb new file mode 100644 index 000000000..06c93da80 --- /dev/null +++ b/spec/models/form/sales/questions/address_line2_spec.rb @@ -0,0 +1,49 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::AddressLine2, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("address_line2") + end + + it "has the correct header" do + expect(question.header).to eq("Address line 2 (optional)") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to be_nil + end + + it "has the correct type" do + expect(question.type).to eq("text") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint" do + expect(question.hint_text).to be_nil + end + + it "has the correct inferred check answers value" do + expect(question.inferred_check_answers_value).to be_nil + end + + it "has the correct check_answers_card_number" do + expect(question.check_answers_card_number).to be_nil + end + + it "has the correct hidden_in_check_answers" do + expect(question.hidden_in_check_answers?).to eq(true) + end +end diff --git a/spec/models/form/sales/questions/buyer1_ethnic_background_arab_spec.rb b/spec/models/form/sales/questions/buyer1_ethnic_background_arab_spec.rb index fd62707bd..31df4708c 100644 --- a/spec/models/form/sales/questions/buyer1_ethnic_background_arab_spec.rb +++ b/spec/models/form/sales/questions/buyer1_ethnic_background_arab_spec.rb @@ -16,7 +16,7 @@ RSpec.describe Form::Sales::Questions::Buyer1EthnicBackgroundArab, type: :model end it "has the correct header" do - expect(question.header).to eq("Which of the following best describes the buyer 1’s Arab background?") + expect(question.header).to eq("Which of the following best describes buyer 1’s Arab background?") end it "has the correct check_answer_label" do diff --git a/spec/models/form/sales/questions/buyer1_ethnic_background_asian_spec.rb b/spec/models/form/sales/questions/buyer1_ethnic_background_asian_spec.rb index 1b7c99988..931802fe5 100644 --- a/spec/models/form/sales/questions/buyer1_ethnic_background_asian_spec.rb +++ b/spec/models/form/sales/questions/buyer1_ethnic_background_asian_spec.rb @@ -16,7 +16,7 @@ RSpec.describe Form::Sales::Questions::Buyer1EthnicBackgroundAsian, type: :model end it "has the correct header" do - expect(question.header).to eq("Which of the following best describes the buyer 1’s Asian or Asian British background?") + expect(question.header).to eq("Which of the following best describes buyer 1’s Asian or Asian British background?") end it "has the correct check_answer_label" do diff --git a/spec/models/form/sales/questions/buyer1_ethnic_background_black_spec.rb b/spec/models/form/sales/questions/buyer1_ethnic_background_black_spec.rb index c324556f7..c4b7919c8 100644 --- a/spec/models/form/sales/questions/buyer1_ethnic_background_black_spec.rb +++ b/spec/models/form/sales/questions/buyer1_ethnic_background_black_spec.rb @@ -16,7 +16,7 @@ RSpec.describe Form::Sales::Questions::Buyer1EthnicBackgroundBlack, type: :model end it "has the correct header" do - expect(question.header).to eq("Which of the following best describes the buyer 1’s Black, African, Caribbean or Black British background?") + expect(question.header).to eq("Which of the following best describes buyer 1’s Black, African, Caribbean or Black British background?") end it "has the correct check_answer_label" do diff --git a/spec/models/form/sales/questions/buyer1_ethnic_background_mixed_spec.rb b/spec/models/form/sales/questions/buyer1_ethnic_background_mixed_spec.rb index efbb928d4..f6fbdf3b0 100644 --- a/spec/models/form/sales/questions/buyer1_ethnic_background_mixed_spec.rb +++ b/spec/models/form/sales/questions/buyer1_ethnic_background_mixed_spec.rb @@ -16,7 +16,7 @@ RSpec.describe Form::Sales::Questions::Buyer1EthnicBackgroundMixed, type: :model end it "has the correct header" do - expect(question.header).to eq("Which of the following best describes the buyer 1’s Mixed or Multiple ethnic groups background?") + expect(question.header).to eq("Which of the following best describes buyer 1’s Mixed or Multiple ethnic groups background?") end it "has the correct check_answer_label" do diff --git a/spec/models/form/sales/questions/buyer1_ethnic_background_white_spec.rb b/spec/models/form/sales/questions/buyer1_ethnic_background_white_spec.rb index e155378a3..684477542 100644 --- a/spec/models/form/sales/questions/buyer1_ethnic_background_white_spec.rb +++ b/spec/models/form/sales/questions/buyer1_ethnic_background_white_spec.rb @@ -16,7 +16,7 @@ RSpec.describe Form::Sales::Questions::Buyer1EthnicBackgroundWhite, type: :model end it "has the correct header" do - expect(question.header).to eq("Which of the following best describes the buyer 1’s White background?") + expect(question.header).to eq("Which of the following best describes buyer 1’s White background?") end it "has the correct check_answer_label" do diff --git a/spec/models/form/sales/questions/buyer1_income_known_spec.rb b/spec/models/form/sales/questions/buyer1_income_known_spec.rb index aafe16c2d..2abd58d3a 100644 --- a/spec/models/form/sales/questions/buyer1_income_known_spec.rb +++ b/spec/models/form/sales/questions/buyer1_income_known_spec.rb @@ -20,7 +20,7 @@ RSpec.describe Form::Sales::Questions::Buyer1IncomeKnown, type: :model do end it "has the correct check_answer_label" do - expect(question.check_answer_label).to eq("Buyer 1’s gross annual income") + expect(question.check_answer_label).to eq("Buyer 1’s gross annual income known?") end it "has the correct type" do diff --git a/spec/models/form/sales/questions/buyer1_previous_tenure_spec.rb b/spec/models/form/sales/questions/buyer1_previous_tenure_spec.rb index 4321700b4..f99b1c01f 100644 --- a/spec/models/form/sales/questions/buyer1_previous_tenure_spec.rb +++ b/spec/models/form/sales/questions/buyer1_previous_tenure_spec.rb @@ -32,13 +32,13 @@ RSpec.describe Form::Sales::Questions::Buyer1PreviousTenure, type: :model do it "has the correct answer_options" do expect(question.answer_options).to eq({ - "1" => { "value" => "Local Authority" }, + "1" => { "value" => "Local authority tenant" }, "2" => { "value" => "Private registered provider or housing association tenant" }, "3" => { "value" => "Private tenant" }, "4" => { "value" => "Tied home or renting with job" }, "5" => { "value" => "Owner occupier" }, "6" => { "value" => "Living with family or friends" }, - "7" => { "value" => "Temporary accomodation" }, + "7" => { "value" => "Temporary accommodation" }, "9" => { "value" => "Other" }, "0" => { "value" => "Don’t know" }, }) diff --git a/spec/models/form/sales/questions/buyer2_ethnic_background_arab_spec.rb b/spec/models/form/sales/questions/buyer2_ethnic_background_arab_spec.rb index 9fd408db9..0ec22b6bf 100644 --- a/spec/models/form/sales/questions/buyer2_ethnic_background_arab_spec.rb +++ b/spec/models/form/sales/questions/buyer2_ethnic_background_arab_spec.rb @@ -16,7 +16,7 @@ RSpec.describe Form::Sales::Questions::Buyer2EthnicBackgroundArab, type: :model end it "has the correct header" do - expect(question.header).to eq("Which of the following best describes the buyer 2’s Arab background?") + expect(question.header).to eq("Which of the following best describes buyer 2’s Arab background?") end it "has the correct check_answer_label" do diff --git a/spec/models/form/sales/questions/buyer2_ethnic_background_asian_spec.rb b/spec/models/form/sales/questions/buyer2_ethnic_background_asian_spec.rb index 67ce60e43..86a59b65f 100644 --- a/spec/models/form/sales/questions/buyer2_ethnic_background_asian_spec.rb +++ b/spec/models/form/sales/questions/buyer2_ethnic_background_asian_spec.rb @@ -16,7 +16,7 @@ RSpec.describe Form::Sales::Questions::Buyer2EthnicBackgroundAsian, type: :model end it "has the correct header" do - expect(question.header).to eq("Which of the following best describes the buyer 2’s Asian or Asian British background?") + expect(question.header).to eq("Which of the following best describes buyer 2’s Asian or Asian British background?") end it "has the correct check_answer_label" do diff --git a/spec/models/form/sales/questions/buyer2_ethnic_background_black_spec.rb b/spec/models/form/sales/questions/buyer2_ethnic_background_black_spec.rb index 8e772f870..db5cbba0d 100644 --- a/spec/models/form/sales/questions/buyer2_ethnic_background_black_spec.rb +++ b/spec/models/form/sales/questions/buyer2_ethnic_background_black_spec.rb @@ -16,7 +16,7 @@ RSpec.describe Form::Sales::Questions::Buyer2EthnicBackgroundBlack, type: :model end it "has the correct header" do - expect(question.header).to eq("Which of the following best describes the buyer 2’s Black, African, Caribbean or Black British background?") + expect(question.header).to eq("Which of the following best describes buyer 2’s Black, African, Caribbean or Black British background?") end it "has the correct check_answer_label" do diff --git a/spec/models/form/sales/questions/buyer2_ethnic_background_mixed_spec.rb b/spec/models/form/sales/questions/buyer2_ethnic_background_mixed_spec.rb index 6c1b12865..255251e90 100644 --- a/spec/models/form/sales/questions/buyer2_ethnic_background_mixed_spec.rb +++ b/spec/models/form/sales/questions/buyer2_ethnic_background_mixed_spec.rb @@ -16,7 +16,7 @@ RSpec.describe Form::Sales::Questions::Buyer2EthnicBackgroundMixed, type: :model end it "has the correct header" do - expect(question.header).to eq("Which of the following best describes the buyer 2’s Mixed or Multiple ethnic groups background?") + expect(question.header).to eq("Which of the following best describes buyer 2’s Mixed or Multiple ethnic groups background?") end it "has the correct check_answer_label" do diff --git a/spec/models/form/sales/questions/buyer2_ethnic_background_white_spec.rb b/spec/models/form/sales/questions/buyer2_ethnic_background_white_spec.rb index d3f2da508..d8aaa0292 100644 --- a/spec/models/form/sales/questions/buyer2_ethnic_background_white_spec.rb +++ b/spec/models/form/sales/questions/buyer2_ethnic_background_white_spec.rb @@ -16,7 +16,7 @@ RSpec.describe Form::Sales::Questions::Buyer2EthnicBackgroundWhite, type: :model end it "has the correct header" do - expect(question.header).to eq("Which of the following best describes the buyer 2’s White background?") + expect(question.header).to eq("Which of the following best describes buyer 2’s White background?") end it "has the correct check_answer_label" do diff --git a/spec/models/form/sales/questions/buyer2_income_known_spec.rb b/spec/models/form/sales/questions/buyer2_income_known_spec.rb index a1be51ad4..6724b9b0d 100644 --- a/spec/models/form/sales/questions/buyer2_income_known_spec.rb +++ b/spec/models/form/sales/questions/buyer2_income_known_spec.rb @@ -20,7 +20,7 @@ RSpec.describe Form::Sales::Questions::Buyer2IncomeKnown, type: :model do end it "has the correct check_answer_label" do - expect(question.check_answer_label).to eq("Buyer 2’s gross annual income") + expect(question.check_answer_label).to eq("Buyer 2’s gross annual income known?") end it "has the correct type" do diff --git a/spec/models/form/sales/questions/buyer2_living_in_spec.rb b/spec/models/form/sales/questions/buyer2_living_in_spec.rb new file mode 100644 index 000000000..4fca65f3f --- /dev/null +++ b/spec/models/form/sales/questions/buyer2_living_in_spec.rb @@ -0,0 +1,43 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::Buyer2LivingIn, type: :model do + subject(:question) { described_class.new(nil, nil, page) } + + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq page + end + + it "has the correct id" do + expect(question.id).to eq "buy2living" + end + + it "has the correct header" do + expect(question.header).to eq "At the time of purchase, was buyer 2 living at the same address as buyer 1?" + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq "Buyer 2 living at the same address" + end + + it "has the correct type" do + expect(question.type).to eq "radio" + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint_text" do + expect(question.hint_text).to eq "" + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "1" => { "value" => "Yes" }, + "2" => { "value" => "No" }, + "3" => { "value" => "Don't know" }, + }) + end +end diff --git a/spec/models/form/sales/questions/buyer2_nationality_spec.rb b/spec/models/form/sales/questions/buyer2_nationality_spec.rb new file mode 100644 index 000000000..ed1f96c28 --- /dev/null +++ b/spec/models/form/sales/questions/buyer2_nationality_spec.rb @@ -0,0 +1,63 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::Buyer2Nationality, type: :model do + subject(:question) { described_class.new(nil, nil, page) } + + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to be page + end + + it "has the correct id" do + expect(question.id).to eq "nationalbuy2" + end + + it "has the correct header" do + expect(question.header).to eq "What is buyer 2’s nationality?" + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq "Buyer 2’s nationality" + end + + it "has the correct type" do + expect(question.type).to eq "radio" + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint" do + expect(question.hint_text).to be nil + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "18" => { "value" => "United Kingdom" }, + "17" => { "value" => "Republic of Ireland" }, + "19" => { "value" => "European Economic Area (EEA), excluding ROI" }, + "12" => { "value" => "Other" }, + "13" => { "value" => "Buyer prefers not to say" }, + }) + end + + it "has correct conditional for" do + expect(question.conditional_for).to be_nil + end + + it "has correct hidden in check answers" do + expect(question.hidden_in_check_answers).to be_nil + end + + it "has the correct check_answers_card_number" do + expect(question.check_answers_card_number).to be 2 + end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([ + { "condition" => { "national" => 13 }, "value" => "Prefers not to say" }, + ]) + end +end diff --git a/spec/models/form/sales/questions/buyer_previous_spec.rb b/spec/models/form/sales/questions/buyer_previous_spec.rb index 07d3685f8..06aaca38f 100644 --- a/spec/models/form/sales/questions/buyer_previous_spec.rb +++ b/spec/models/form/sales/questions/buyer_previous_spec.rb @@ -1,11 +1,12 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::BuyerPrevious, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } + subject(:question) { described_class.new(question_id, question_definition, page, joint_purchase:) } let(:question_id) { nil } let(:question_definition) { nil } let(:page) { instance_double(Form::Page) } + let(:joint_purchase) { true } it "has correct page" do expect(question.page).to eq(page) @@ -15,12 +16,26 @@ RSpec.describe Form::Sales::Questions::BuyerPrevious, type: :model do expect(question.id).to eq("soctenant") end - it "has the correct header" do - expect(question.header).to eq("Was the buyer a private registered provider, housing association or local authority tenant immediately before this sale?") + context "when a joint purchase" do + it "has the correct header" do + expect(question.header).to eq("Were any of the buyers private registered providers, housing association or local authority tenants immediately before this sale?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Any buyers were registered providers, housing association or local authority tenants immediately before this sale?") + end end - it "has the correct check_answer_label" do - expect(question.check_answer_label).to eq("Buyer was a registered provider, housing association or local authority tenant immediately before this sale?") + context "when not a joint purchase" do + let(:joint_purchase) { false } + + it "has the correct header" do + expect(question.header).to eq("Was the buyer a private registered provider, housing association or local authority tenant immediately before this sale?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Buyer was a registered provider, housing association or local authority tenant immediately before this sale?") + end end it "has the correct type" do @@ -31,10 +46,18 @@ RSpec.describe Form::Sales::Questions::BuyerPrevious, type: :model do expect(question.derived?).to be false end + it "has the correct displayed_answer_options" do + expect(question.displayed_answer_options(nil)).to eq({ + "1" => { "value" => "Yes" }, + "2" => { "value" => "No" }, + }) + end + it "has the correct answer_options" do expect(question.answer_options).to eq({ "1" => { "value" => "Yes" }, "2" => { "value" => "No" }, + "0" => { "value" => "Don’t know" }, }) end diff --git a/spec/models/form/sales/questions/other_nationality1_spec.rb b/spec/models/form/sales/questions/county_spec.rb similarity index 59% rename from spec/models/form/sales/questions/other_nationality1_spec.rb rename to spec/models/form/sales/questions/county_spec.rb index c3faa73dc..d5800b260 100644 --- a/spec/models/form/sales/questions/other_nationality1_spec.rb +++ b/spec/models/form/sales/questions/county_spec.rb @@ -1,6 +1,6 @@ require "rails_helper" -RSpec.describe Form::Sales::Questions::OtherNationality1, type: :model do +RSpec.describe Form::Sales::Questions::County, type: :model do subject(:question) { described_class.new(question_id, question_definition, page) } let(:question_id) { nil } @@ -12,15 +12,15 @@ RSpec.describe Form::Sales::Questions::OtherNationality1, type: :model do end it "has the correct id" do - expect(question.id).to eq("othernational") + expect(question.id).to eq("county") end it "has the correct header" do - expect(question.header).to eq("Nationality") + expect(question.header).to eq("County (optional)") end it "has the correct check_answer_label" do - expect(question.check_answer_label).to eq("Buyer 1’s nationality") + expect(question.check_answer_label).to be_nil end it "has the correct type" do @@ -35,7 +35,15 @@ RSpec.describe Form::Sales::Questions::OtherNationality1, type: :model do expect(question.hint_text).to be_nil end + it "has the correct inferred check answers value" do + expect(question.inferred_check_answers_value).to be_nil + end + it "has the correct check_answers_card_number" do - expect(question.check_answers_card_number).to eq(1) + expect(question.check_answers_card_number).to be_nil + end + + it "has the correct hidden_in_check_answers" do + expect(question.hidden_in_check_answers?).to eq(true) end end diff --git a/spec/models/form/sales/questions/deposit_amount_spec.rb b/spec/models/form/sales/questions/deposit_amount_spec.rb index 33a5dcf1d..e0a77b7fc 100644 --- a/spec/models/form/sales/questions/deposit_amount_spec.rb +++ b/spec/models/form/sales/questions/deposit_amount_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::DepositAmount, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } + subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1) } let(:question_id) { nil } let(:question_definition) { nil } diff --git a/spec/models/form/sales/questions/extra_borrowing_spec.rb b/spec/models/form/sales/questions/extra_borrowing_spec.rb index b9149c27d..cc0656031 100644 --- a/spec/models/form/sales/questions/extra_borrowing_spec.rb +++ b/spec/models/form/sales/questions/extra_borrowing_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::ExtraBorrowing, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } + subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1) } let(:question_id) { nil } let(:question_definition) { nil } diff --git a/spec/models/form/sales/questions/fromprop_spec.rb b/spec/models/form/sales/questions/fromprop_spec.rb index ebfa218c5..c9aaa60b9 100644 --- a/spec/models/form/sales/questions/fromprop_spec.rb +++ b/spec/models/form/sales/questions/fromprop_spec.rb @@ -35,6 +35,16 @@ RSpec.describe Form::Sales::Questions::Fromprop, type: :model do expect(question.hint_text).to eq("") end + it "has the correct displayed_answer_options" do + expect(question.displayed_answer_options(nil)).to eq({ + "1" => { "value" => "Flat or maisonette" }, + "2" => { "value" => "Bedsit" }, + "3" => { "value" => "House" }, + "4" => { "value" => "Bungalow" }, + "9" => { "value" => "Other" }, + }) + end + it "has the correct answer_options" do expect(question.answer_options).to eq({ "1" => { "value" => "Flat or maisonette" }, @@ -42,6 +52,7 @@ RSpec.describe Form::Sales::Questions::Fromprop, type: :model do "3" => { "value" => "House" }, "4" => { "value" => "Bungalow" }, "9" => { "value" => "Other" }, + "0" => { "value" => "Don’t know" }, }) end end diff --git a/spec/models/form/sales/questions/grant_spec.rb b/spec/models/form/sales/questions/grant_spec.rb index d4e92f703..cd74ee704 100644 --- a/spec/models/form/sales/questions/grant_spec.rb +++ b/spec/models/form/sales/questions/grant_spec.rb @@ -32,7 +32,7 @@ RSpec.describe Form::Sales::Questions::Grant, type: :model do end it "has the correct hint" do - expect(question.hint_text).to eq("For all schemes except Right to Buy (RTB), Preserved Right to Buy (PRTB), Voluntary Right to Buy (VRTB)") + expect(question.hint_text).to eq("For all schemes except Right to Buy (RTB), Preserved Right to Buy (PRTB), Voluntary Right to Buy (VRTB) and Rent to Buy") end it "has correct width" do diff --git a/spec/models/form/sales/questions/leasehold_charges_known_spec.rb b/spec/models/form/sales/questions/leasehold_charges_known_spec.rb index d47b535eb..64cd08f33 100644 --- a/spec/models/form/sales/questions/leasehold_charges_known_spec.rb +++ b/spec/models/form/sales/questions/leasehold_charges_known_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::LeaseholdChargesKnown, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } + subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1) } let(:question_id) { nil } let(:question_definition) { nil } diff --git a/spec/models/form/sales/questions/leasehold_charges_spec.rb b/spec/models/form/sales/questions/leasehold_charges_spec.rb index a06fc9975..a9be62ef5 100644 --- a/spec/models/form/sales/questions/leasehold_charges_spec.rb +++ b/spec/models/form/sales/questions/leasehold_charges_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::LeaseholdCharges, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } + subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1) } let(:question_id) { nil } let(:question_definition) { nil } diff --git a/spec/models/form/sales/questions/living_before_purchase_spec.rb b/spec/models/form/sales/questions/living_before_purchase_spec.rb index 530bb151a..624865aac 100644 --- a/spec/models/form/sales/questions/living_before_purchase_spec.rb +++ b/spec/models/form/sales/questions/living_before_purchase_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::LivingBeforePurchase, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } + subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1) } let(:question_id) { nil } let(:question_definition) { nil } diff --git a/spec/models/form/sales/questions/living_before_purchase_years_spec.rb b/spec/models/form/sales/questions/living_before_purchase_years_spec.rb index 5fdb5ccba..52ea05a4f 100644 --- a/spec/models/form/sales/questions/living_before_purchase_years_spec.rb +++ b/spec/models/form/sales/questions/living_before_purchase_years_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::LivingBeforePurchaseYears, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } + subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1) } let(:question_id) { nil } let(:question_definition) { nil } diff --git a/spec/models/form/sales/questions/mortgage_amount_spec.rb b/spec/models/form/sales/questions/mortgage_amount_spec.rb index 832b47d37..328406ecd 100644 --- a/spec/models/form/sales/questions/mortgage_amount_spec.rb +++ b/spec/models/form/sales/questions/mortgage_amount_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::MortgageAmount, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } + subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1) } let(:question_id) { nil } let(:question_definition) { nil } diff --git a/spec/models/form/sales/questions/mortgage_lender_other_spec.rb b/spec/models/form/sales/questions/mortgage_lender_other_spec.rb index e5a8a3869..8150c1088 100644 --- a/spec/models/form/sales/questions/mortgage_lender_other_spec.rb +++ b/spec/models/form/sales/questions/mortgage_lender_other_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::MortgageLenderOther, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } + subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1) } let(:question_id) { nil } let(:question_definition) { nil } diff --git a/spec/models/form/sales/questions/mortgage_lender_spec.rb b/spec/models/form/sales/questions/mortgage_lender_spec.rb index 659cf7070..84caef701 100644 --- a/spec/models/form/sales/questions/mortgage_lender_spec.rb +++ b/spec/models/form/sales/questions/mortgage_lender_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::MortgageLender, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } + subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1) } let(:question_id) { nil } let(:question_definition) { nil } diff --git a/spec/models/form/sales/questions/mortgage_length_spec.rb b/spec/models/form/sales/questions/mortgage_length_spec.rb index 0f3193244..bb77c16e6 100644 --- a/spec/models/form/sales/questions/mortgage_length_spec.rb +++ b/spec/models/form/sales/questions/mortgage_length_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::MortgageLength, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } + subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1) } let(:question_id) { nil } let(:question_definition) { nil } diff --git a/spec/models/form/sales/questions/mortgageused_spec.rb b/spec/models/form/sales/questions/mortgageused_spec.rb index a31f063c9..32fdfde72 100644 --- a/spec/models/form/sales/questions/mortgageused_spec.rb +++ b/spec/models/form/sales/questions/mortgageused_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::Mortgageused, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } + subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1) } let(:question_id) { nil } let(:question_definition) { nil } diff --git a/spec/models/form/sales/questions/nationality1_spec.rb b/spec/models/form/sales/questions/nationality1_spec.rb index 18f659e86..4b8816dbf 100644 --- a/spec/models/form/sales/questions/nationality1_spec.rb +++ b/spec/models/form/sales/questions/nationality1_spec.rb @@ -1,30 +1,28 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::Nationality1, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } + subject(:question) { described_class.new(nil, nil, page) } - let(:question_id) { nil } - let(:question_definition) { nil } let(:page) { instance_double(Form::Page) } it "has correct page" do - expect(question.page).to eq(page) + expect(question.page).to be page end it "has the correct id" do - expect(question.id).to eq("national") + expect(question.id).to eq "national" end it "has the correct header" do - expect(question.header).to eq("What is buyer 1’s nationality?") + expect(question.header).to eq "What is buyer 1’s nationality?" end it "has the correct check_answer_label" do - expect(question.check_answer_label).to eq("Buyer 1’s nationality") + expect(question.check_answer_label).to eq "Buyer 1’s nationality" end it "has the correct type" do - expect(question.type).to eq("radio") + expect(question.type).to eq "radio" end it "is not marked as derived" do @@ -32,7 +30,7 @@ RSpec.describe Form::Sales::Questions::Nationality1, type: :model do end it "has the correct hint" do - expect(question.hint_text).to eq("Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest.") + expect(question.hint_text).to eq "Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest." end it "has the correct answer_options" do @@ -46,23 +44,15 @@ RSpec.describe Form::Sales::Questions::Nationality1, type: :model do end it "has correct conditional for" do - expect(question.conditional_for).to eq({ - "othernational" => [12], - }) + expect(question.conditional_for).to be_nil end it "has correct hidden in check answers" do - expect(question.hidden_in_check_answers).to eq({ - "depends_on" => [ - { - "national" => 12, - }, - ], - }) + expect(question.hidden_in_check_answers).to be_nil end it "has the correct check_answers_card_number" do - expect(question.check_answers_card_number).to eq(1) + expect(question.check_answers_card_number).to be 1 end it "has the correct inferred_check_answers_value" do diff --git a/spec/models/form/sales/questions/person_student_not_child_value_check_spec.rb b/spec/models/form/sales/questions/person_student_not_child_value_check_spec.rb new file mode 100644 index 000000000..f36e7ad57 --- /dev/null +++ b/spec/models/form/sales/questions/person_student_not_child_value_check_spec.rb @@ -0,0 +1,61 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::PersonStudentNotChildValueCheck, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page, person_index: 1) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("student_not_child_value_check") + end + + it "has the correct header" do + expect(question.header).to eq("Are you sure this person is not a child?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Student not a child confirmation") + end + + it "has the correct type" do + expect(question.type).to eq("interruption_screen") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint" do + expect(question.hint_text).to be_nil + end + + it "has a correct check_answers_card_number" do + expect(question.check_answers_card_number).to eq(1) + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "0" => { "value" => "Yes" }, + "1" => { "value" => "No" }, + }) + end + + it "has the correct hidden_in_check_answers" do + expect(question.hidden_in_check_answers).to eq({ + "depends_on" => [ + { + "student_not_child_value_check" => 0, + }, + { + "student_not_child_value_check" => 1, + }, + ], + }) + end +end diff --git a/spec/models/form/sales/questions/postcode_for_full_address_spec.rb b/spec/models/form/sales/questions/postcode_for_full_address_spec.rb new file mode 100644 index 000000000..a655172ec --- /dev/null +++ b/spec/models/form/sales/questions/postcode_for_full_address_spec.rb @@ -0,0 +1,62 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::PostcodeForFullAddress, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("postcode_full") + end + + it "has the correct header" do + expect(question.header).to eq("Postcode") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to be_nil + end + + it "has the correct type" do + expect(question.type).to eq("text") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint" do + expect(question.hint_text).to be_nil + end + + it "has the correct width" do + expect(question.width).to eq(5) + end + + it "has the correct inferred_answers" do + expect(question.inferred_answers).to eq({ + "la" => { + "is_la_inferred" => true, + }, + }) + end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([{ + "condition" => { + "pcodenk" => 1, + }, + "value" => "Not known", + }]) + end + + it "has the correct hidden_in_check_answers" do + expect(question.hidden_in_check_answers?).to eq(true) + end +end diff --git a/spec/models/form/sales/questions/previous_tenure_buyer2_spec.rb b/spec/models/form/sales/questions/previous_tenure_buyer2_spec.rb new file mode 100644 index 000000000..713d4b3e8 --- /dev/null +++ b/spec/models/form/sales/questions/previous_tenure_buyer2_spec.rb @@ -0,0 +1,49 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::PreviousTenureBuyer2, type: :model do + subject(:question) { described_class.new(nil, nil, page) } + + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("prevtenbuy2") + end + + it "has the correct header" do + expect(question.header).to eq("What was buyer 2’s previous tenure?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Buyer 2’s previous tenure") + end + + it "has the correct type" do + expect(question.type).to eq("radio") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint_text" do + expect(question.hint_text).to eq("") + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "1" => { "value" => "Local authority tenant" }, + "2" => { "value" => "Private registered provider or housing association tenant" }, + "3" => { "value" => "Private tenant" }, + "5" => { "value" => "Owner occupier" }, + "4" => { "value" => "Tied home or renting with job" }, + "6" => { "value" => "Living with family or friends" }, + "7" => { "value" => "Temporary accommodation" }, + "9" => { "value" => "Other" }, + "0" => { "value" => "Don't know" }, + }) + end +end diff --git a/spec/models/form/sales/questions/prevloc_spec.rb b/spec/models/form/sales/questions/prevloc_spec.rb index 5d985ba64..e27b295be 100644 --- a/spec/models/form/sales/questions/prevloc_spec.rb +++ b/spec/models/form/sales/questions/prevloc_spec.rb @@ -5,7 +5,9 @@ RSpec.describe Form::Sales::Questions::Prevloc, type: :model do let(:question_id) { nil } let(:question_definition) { nil } - let(:page) { instance_double(Form::Page) } + let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date:)) } + let(:page) { instance_double(Form::Page, subsection:) } + let(:start_date) { Time.utc(2022, 4, 1) } it "has correct page" do expect(question.page).to eq(page) @@ -31,393 +33,777 @@ RSpec.describe Form::Sales::Questions::Prevloc, type: :model do expect(question.derived?).to be false end - it "has the correct answer_options" do - expect(question.answer_options).to eq({ - "" => "Select an option", - "S12000033" => "Aberdeen City", - "S12000034" => "Aberdeenshire", - "E07000223" => "Adur", - "E07000026" => "Allerdale", - "E07000032" => "Amber Valley", - "S12000041" => "Angus", - "N09000001" => "Antrim and Newtownabbey", - "N09000011" => "Ards and North Down", - "S12000035" => "Argyll and Bute", - "N09000002" => "Armagh City, Banbridge and Craigavon", - "E07000224" => "Arun", - "E07000170" => "Ashfield", - "E07000105" => "Ashford", - "E07000200" => "Babergh", - "E09000002" => "Barking and Dagenham", - "E09000003" => "Barnet", - "E08000016" => "Barnsley", - "E07000027" => "Barrow-in-Furness", - "E07000066" => "Basildon", - "E07000084" => "Basingstoke and Deane", - "E07000171" => "Bassetlaw", - "E06000022" => "Bath and North East Somerset", - "E06000055" => "Bedford", - "N09000003" => "Belfast", - "E09000004" => "Bexley", - "E08000025" => "Birmingham", - "E07000129" => "Blaby", - "E06000008" => "Blackburn with Darwen", - "E06000009" => "Blackpool", - "W06000019" => "Blaenau Gwent", - "E07000033" => "Bolsover", - "E08000001" => "Bolton", - "E07000136" => "Boston", - "E06000058" => "Bournemouth, Christchurch and Poole", - "E06000036" => "Bracknell Forest", - "E08000032" => "Bradford", - "E07000067" => "Braintree", - "E07000143" => "Breckland", - "E09000005" => "Brent", - "E07000068" => "Brentwood", - "W06000013" => "Bridgend", - "E06000043" => "Brighton and Hove", - "E06000023" => "Bristol, City of", - "E07000144" => "Broadland", - "E09000006" => "Bromley", - "E07000234" => "Bromsgrove", - "E07000095" => "Broxbourne", - "E07000172" => "Broxtowe", - "E06000060" => "Buckinghamshire", - "E07000117" => "Burnley", - "E08000002" => "Bury", - "W06000018" => "Caerphilly", - "E08000033" => "Calderdale", - "E07000008" => "Cambridge", - "E09000007" => "Camden", - "E07000192" => "Cannock Chase", - "E07000106" => "Canterbury", - "W06000015" => "Cardiff", - "E07000028" => "Carlisle", - "W06000010" => "Carmarthenshire", - "E07000069" => "Castle Point", - "N09000004" => "Causeway Coast and Glens", - "E06000056" => "Central Bedfordshire", - "W06000008" => "Ceredigion", - "E07000130" => "Charnwood", - "E07000070" => "Chelmsford", - "E07000078" => "Cheltenham", - "E07000177" => "Cherwell", - "E06000049" => "Cheshire East", - "E06000050" => "Cheshire West and Chester", - "E07000034" => "Chesterfield", - "E07000225" => "Chichester", - "E07000118" => "Chorley", - "S12000036" => "City of Edinburgh", - "E09000001" => "City of London", - "S12000005" => "Clackmannanshire", - "E07000071" => "Colchester", - "W06000003" => "Conwy", - "E07000029" => "Copeland", - "E07000150" => "Corby", - "E06000052" => "Cornwall", - "E07000079" => "Cotswold", - "E06000047" => "County Durham", - "E08000026" => "Coventry", - "E07000163" => "Craven", - "E07000226" => "Crawley", - "E09000008" => "Croydon", - "E07000096" => "Dacorum", - "E06000005" => "Darlington", - "E07000107" => "Dartford", - "E07000151" => "Daventry", - "W06000004" => "Denbighshire", - "E06000015" => "Derby", - "E07000035" => "Derbyshire Dales", - "N09000005" => "Derry City and Strabane", - "E08000017" => "Doncaster", - "E06000059" => "Dorset", - "E07000108" => "Dover", - "E08000027" => "Dudley", - "S12000006" => "Dumfries and Galloway", - "S12000042" => "Dundee City", - "E09000009" => "Ealing", - "S12000008" => "East Ayrshire", - "E07000009" => "East Cambridgeshire", - "E07000040" => "East Devon", - "S12000045" => "East Dunbartonshire", - "E07000085" => "East Hampshire", - "E07000242" => "East Hertfordshire", - "E07000137" => "East Lindsey", - "S12000010" => "East Lothian", - "E07000152" => "East Northamptonshire", - "S12000011" => "East Renfrewshire", - "E06000011" => "East Riding of Yorkshire", - "E07000193" => "East Staffordshire", - "E07000244" => "East Suffolk", - "E07000061" => "Eastbourne", - "E07000086" => "Eastleigh", - "E07000030" => "Eden", - "E07000207" => "Elmbridge", - "E09000010" => "Enfield", - "E07000072" => "Epping Forest", - "E07000208" => "Epsom and Ewell", - "E07000036" => "Erewash", - "E07000041" => "Exeter", - "S12000014" => "Falkirk", - "E07000087" => "Fareham", - "E07000010" => "Fenland", - "N09000006" => "Fermanagh and Omagh", - "S12000047" => "Fife", - "W06000005" => "Flintshire", - "E07000112" => "Folkestone and Hythe", - "E07000080" => "Forest of Dean", - "E07000119" => "Fylde", - "E08000037" => "Gateshead", - "E07000173" => "Gedling", - "S12000049" => "Glasgow City", - "E07000081" => "Gloucester", - "E07000088" => "Gosport", - "E07000109" => "Gravesham", - "E07000145" => "Great Yarmouth", - "E09000011" => "Greenwich", - "E07000209" => "Guildford", - "W06000002" => "Gwynedd", - "E09000012" => "Hackney", - "E06000006" => "Halton", - "E07000164" => "Hambleton", - "E09000013" => "Hammersmith and Fulham", - "E07000131" => "Harborough", - "E09000014" => "Haringey", - "E07000073" => "Harlow", - "E07000165" => "Harrogate", - "E09000015" => "Harrow", - "E07000089" => "Hart", - "E06000001" => "Hartlepool", - "E07000062" => "Hastings", - "E07000090" => "Havant", - "E09000016" => "Havering", - "E06000019" => "Herefordshire, County of", - "E07000098" => "Hertsmere", - "E07000037" => "High Peak", - "S12000017" => "Highland", - "E09000017" => "Hillingdon", - "E07000132" => "Hinckley and Bosworth", - "E07000227" => "Horsham", - "E09000018" => "Hounslow", - "E07000011" => "Huntingdonshire", - "E07000120" => "Hyndburn", - "S12000018" => "Inverclyde", - "E07000202" => "Ipswich", - "W06000001" => "Isle of Anglesey", - "E06000046" => "Isle of Wight", - "E06000053" => "Isles of Scilly", - "E09000019" => "Islington", - "E09000020" => "Kensington and Chelsea", - "E07000153" => "Kettering", - "E07000146" => "King’s Lynn and West Norfolk", - "E06000010" => "Kingston upon Hull, City of", - "E09000021" => "Kingston upon Thames", - "E08000034" => "Kirklees", - "E08000011" => "Knowsley", - "E09000022" => "Lambeth", - "E07000121" => "Lancaster", - "E08000035" => "Leeds", - "E06000016" => "Leicester", - "E07000063" => "Lewes", - "E09000023" => "Lewisham", - "E07000194" => "Lichfield", - "E07000138" => "Lincoln", - "N09000007" => "Lisburn and Castlereagh", - "E08000012" => "Liverpool", - "E06000032" => "Luton", - "E07000110" => "Maidstone", - "E07000074" => "Maldon", - "E07000235" => "Malvern Hills", - "E08000003" => "Manchester", - "E07000174" => "Mansfield", - "E06000035" => "Medway", - "E07000133" => "Melton", - "E07000187" => "Mendip", - "W06000024" => "Merthyr Tydfil", - "E09000024" => "Merton", - "E07000042" => "Mid Devon", - "E07000203" => "Mid Suffolk", - "E07000228" => "Mid Sussex", - "N09000009" => "Mid Ulster", - "N09000008" => "Mid and East Antrim", - "E06000002" => "Middlesbrough", - "S12000019" => "Midlothian", - "E06000042" => "Milton Keynes", - "E07000210" => "Mole Valley", - "W06000021" => "Monmouthshire", - "S12000020" => "Moray", - "S12000013" => "Na h-Eileanan Siar", - "W06000012" => "Neath Port Talbot", - "E07000091" => "New Forest", - "E07000175" => "Newark and Sherwood", - "E08000021" => "Newcastle upon Tyne", - "E07000195" => "Newcastle-under-Lyme", - "E09000025" => "Newham", - "W06000022" => "Newport", - "N09000010" => "Newry, Mourne and Down", - "S12000021" => "North Ayrshire", - "E07000043" => "North Devon", - "E07000038" => "North East Derbyshire", - "E06000012" => "North East Lincolnshire", - "E07000099" => "North Hertfordshire", - "E07000139" => "North Kesteven", - "S12000050" => "North Lanarkshire", - "E06000013" => "North Lincolnshire", - "E07000147" => "North Norfolk", - "E06000024" => "North Somerset", - "E08000022" => "North Tyneside", - "E07000218" => "North Warwickshire", - "E07000134" => "North West Leicestershire", - "E07000154" => "Northampton", - "E06000057" => "Northumberland", - "E07000148" => "Norwich", - "E06000018" => "Nottingham", - "E07000219" => "Nuneaton and Bedworth", - "E07000135" => "Oadby and Wigston", - "E08000004" => "Oldham", - "S12000023" => "Orkney Islands", - "E07000178" => "Oxford", - "W06000009" => "Pembrokeshire", - "E07000122" => "Pendle", - "S12000048" => "Perth and Kinross", - "E06000031" => "Peterborough", - "E06000026" => "Plymouth", - "E06000044" => "Portsmouth", - "W06000023" => "Powys", - "E07000123" => "Preston", - "E06000038" => "Reading", - "E09000026" => "Redbridge", - "E06000003" => "Redcar and Cleveland", - "E07000236" => "Redditch", - "E07000211" => "Reigate and Banstead", - "S12000038" => "Renfrewshire", - "W06000016" => "Rhondda Cynon Taf", - "E07000124" => "Ribble Valley", - "E09000027" => "Richmond upon Thames", - "E07000166" => "Richmondshire", - "E08000005" => "Rochdale", - "E07000075" => "Rochford", - "E07000125" => "Rossendale", - "E07000064" => "Rother", - "E08000018" => "Rotherham", - "E07000220" => "Rugby", - "E07000212" => "Runnymede", - "E07000176" => "Rushcliffe", - "E07000092" => "Rushmoor", - "E06000017" => "Rutland", - "E07000167" => "Ryedale", - "E08000006" => "Salford", - "E08000028" => "Sandwell", - "E07000168" => "Scarborough", - "S12000026" => "Scottish Borders", - "E07000188" => "Sedgemoor", - "E08000014" => "Sefton", - "E07000169" => "Selby", - "E07000111" => "Sevenoaks", - "E08000019" => "Sheffield", - "S12000027" => "Shetland Islands", - "E06000051" => "Shropshire", - "E06000039" => "Slough", - "E08000029" => "Solihull", - "E07000246" => "Somerset West and Taunton", - "S12000028" => "South Ayrshire", - "E07000012" => "South Cambridgeshire", - "E07000039" => "South Derbyshire", - "E06000025" => "South Gloucestershire", - "E07000044" => "South Hams", - "E07000140" => "South Holland", - "E07000141" => "South Kesteven", - "E07000031" => "South Lakeland", - "S12000029" => "South Lanarkshire", - "E07000149" => "South Norfolk", - "E07000155" => "South Northamptonshire", - "E07000179" => "South Oxfordshire", - "E07000126" => "South Ribble", - "E07000189" => "South Somerset", - "E07000196" => "South Staffordshire", - "E08000023" => "South Tyneside", - "E06000045" => "Southampton", - "E06000033" => "Southend-on-Sea", - "E09000028" => "Southwark", - "E07000213" => "Spelthorne", - "E07000240" => "St Albans", - "E08000013" => "St. Helens", - "E07000197" => "Stafford", - "E07000198" => "Staffordshire Moorlands", - "E07000243" => "Stevenage", - "S12000030" => "Stirling", - "E08000007" => "Stockport", - "E06000004" => "Stockton-on-Tees", - "E06000021" => "Stoke-on-Trent", - "E07000221" => "Stratford-on-Avon", - "E07000082" => "Stroud", - "E08000024" => "Sunderland", - "E07000214" => "Surrey Heath", - "E09000029" => "Sutton", - "E07000113" => "Swale", - "W06000011" => "Swansea", - "E06000030" => "Swindon", - "E08000008" => "Tameside", - "E07000199" => "Tamworth", - "E07000215" => "Tandridge", - "E07000045" => "Teignbridge", - "E06000020" => "Telford and Wrekin", - "E07000076" => "Tendring", - "E07000093" => "Test Valley", - "E07000083" => "Tewkesbury", - "E07000114" => "Thanet", - "E07000102" => "Three Rivers", - "E06000034" => "Thurrock", - "E07000115" => "Tonbridge and Malling", - "E06000027" => "Torbay", - "W06000020" => "Torfaen", - "E07000046" => "Torridge", - "E09000030" => "Tower Hamlets", - "E08000009" => "Trafford", - "E07000116" => "Tunbridge Wells", - "E07000077" => "Uttlesford", - "W06000014" => "Vale of Glamorgan", - "E07000180" => "Vale of White Horse", - "E08000036" => "Wakefield", - "E08000030" => "Walsall", - "E09000031" => "Waltham Forest", - "E09000032" => "Wandsworth", - "E06000007" => "Warrington", - "E07000222" => "Warwick", - "E07000103" => "Watford", - "E07000216" => "Waverley", - "E07000065" => "Wealden", - "E07000156" => "Wellingborough", - "E07000241" => "Welwyn Hatfield", - "E06000037" => "West Berkshire", - "E07000047" => "West Devon", - "S12000039" => "West Dunbartonshire", - "E07000127" => "West Lancashire", - "E07000142" => "West Lindsey", - "S12000040" => "West Lothian", - "E07000181" => "West Oxfordshire", - "E07000245" => "West Suffolk", - "E09000033" => "Westminster", - "E08000010" => "Wigan", - "E06000054" => "Wiltshire", - "E07000094" => "Winchester", - "E06000040" => "Windsor and Maidenhead", - "E08000015" => "Wirral", - "E07000217" => "Woking", - "E06000041" => "Wokingham", - "E08000031" => "Wolverhampton", - "E07000237" => "Worcester", - "E07000229" => "Worthing", - "W06000006" => "Wrexham", - "E07000238" => "Wychavon", - "E07000128" => "Wyre", - "E07000239" => "Wyre Forest", - "E06000014" => "York", - "N92000002" => "Northern Ireland", - "S92000003" => "Scotland", - "W92000004" => "Wales", - "9300000XX" => "Outside UK", - }) + context "with 2022/23 form" do + let(:start_date) { Time.utc(2022, 4, 1) } + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "" => "Select an option", + "S12000033" => "Aberdeen City", + "S12000034" => "Aberdeenshire", + "E07000223" => "Adur", + "E07000026" => "Allerdale", + "E07000032" => "Amber Valley", + "S12000041" => "Angus", + "N09000001" => "Antrim and Newtownabbey", + "N09000011" => "Ards and North Down", + "S12000035" => "Argyll and Bute", + "N09000002" => "Armagh City, Banbridge and Craigavon", + "E07000224" => "Arun", + "E07000170" => "Ashfield", + "E07000105" => "Ashford", + "E07000200" => "Babergh", + "E09000002" => "Barking and Dagenham", + "E09000003" => "Barnet", + "E08000016" => "Barnsley", + "E07000027" => "Barrow-in-Furness", + "E07000066" => "Basildon", + "E07000084" => "Basingstoke and Deane", + "E07000171" => "Bassetlaw", + "E06000022" => "Bath and North East Somerset", + "E06000055" => "Bedford", + "N09000003" => "Belfast", + "E09000004" => "Bexley", + "E08000025" => "Birmingham", + "E07000129" => "Blaby", + "E06000008" => "Blackburn with Darwen", + "E06000009" => "Blackpool", + "W06000019" => "Blaenau Gwent", + "E07000033" => "Bolsover", + "E08000001" => "Bolton", + "E07000136" => "Boston", + "E06000058" => "Bournemouth, Christchurch and Poole", + "E06000036" => "Bracknell Forest", + "E08000032" => "Bradford", + "E07000067" => "Braintree", + "E07000143" => "Breckland", + "E09000005" => "Brent", + "E07000068" => "Brentwood", + "W06000013" => "Bridgend", + "E06000043" => "Brighton and Hove", + "E06000023" => "Bristol, City of", + "E07000144" => "Broadland", + "E09000006" => "Bromley", + "E07000234" => "Bromsgrove", + "E07000095" => "Broxbourne", + "E07000172" => "Broxtowe", + "E06000060" => "Buckinghamshire", + "E07000117" => "Burnley", + "E08000002" => "Bury", + "W06000018" => "Caerphilly", + "E08000033" => "Calderdale", + "E07000008" => "Cambridge", + "E09000007" => "Camden", + "E07000192" => "Cannock Chase", + "E07000106" => "Canterbury", + "W06000015" => "Cardiff", + "E07000028" => "Carlisle", + "W06000010" => "Carmarthenshire", + "E07000069" => "Castle Point", + "N09000004" => "Causeway Coast and Glens", + "E06000056" => "Central Bedfordshire", + "W06000008" => "Ceredigion", + "E07000130" => "Charnwood", + "E07000070" => "Chelmsford", + "E07000078" => "Cheltenham", + "E07000177" => "Cherwell", + "E06000049" => "Cheshire East", + "E06000050" => "Cheshire West and Chester", + "E07000034" => "Chesterfield", + "E07000225" => "Chichester", + "E07000118" => "Chorley", + "S12000036" => "City of Edinburgh", + "E09000001" => "City of London", + "S12000005" => "Clackmannanshire", + "E07000071" => "Colchester", + "W06000003" => "Conwy", + "E07000029" => "Copeland", + "E07000150" => "Corby", + "E06000052" => "Cornwall", + "E07000079" => "Cotswold", + "E06000047" => "County Durham", + "E08000026" => "Coventry", + "E07000163" => "Craven", + "E07000226" => "Crawley", + "E09000008" => "Croydon", + "E07000096" => "Dacorum", + "E06000005" => "Darlington", + "E07000107" => "Dartford", + "E07000151" => "Daventry", + "W06000004" => "Denbighshire", + "E06000015" => "Derby", + "E07000035" => "Derbyshire Dales", + "N09000005" => "Derry City and Strabane", + "E08000017" => "Doncaster", + "E06000059" => "Dorset", + "E07000108" => "Dover", + "E08000027" => "Dudley", + "S12000006" => "Dumfries and Galloway", + "S12000042" => "Dundee City", + "E09000009" => "Ealing", + "S12000008" => "East Ayrshire", + "E07000009" => "East Cambridgeshire", + "E07000040" => "East Devon", + "S12000045" => "East Dunbartonshire", + "E07000085" => "East Hampshire", + "E07000242" => "East Hertfordshire", + "E07000137" => "East Lindsey", + "S12000010" => "East Lothian", + "E07000152" => "East Northamptonshire", + "S12000011" => "East Renfrewshire", + "E06000011" => "East Riding of Yorkshire", + "E07000193" => "East Staffordshire", + "E07000244" => "East Suffolk", + "E07000061" => "Eastbourne", + "E07000086" => "Eastleigh", + "E07000030" => "Eden", + "E07000207" => "Elmbridge", + "E09000010" => "Enfield", + "E07000072" => "Epping Forest", + "E07000208" => "Epsom and Ewell", + "E07000036" => "Erewash", + "E07000041" => "Exeter", + "S12000014" => "Falkirk", + "E07000087" => "Fareham", + "E07000010" => "Fenland", + "N09000006" => "Fermanagh and Omagh", + "S12000047" => "Fife", + "W06000005" => "Flintshire", + "E07000112" => "Folkestone and Hythe", + "E07000080" => "Forest of Dean", + "E07000119" => "Fylde", + "E08000037" => "Gateshead", + "E07000173" => "Gedling", + "S12000049" => "Glasgow City", + "E07000081" => "Gloucester", + "E07000088" => "Gosport", + "E07000109" => "Gravesham", + "E07000145" => "Great Yarmouth", + "E09000011" => "Greenwich", + "E07000209" => "Guildford", + "W06000002" => "Gwynedd", + "E09000012" => "Hackney", + "E06000006" => "Halton", + "E07000164" => "Hambleton", + "E09000013" => "Hammersmith and Fulham", + "E07000131" => "Harborough", + "E09000014" => "Haringey", + "E07000073" => "Harlow", + "E07000165" => "Harrogate", + "E09000015" => "Harrow", + "E07000089" => "Hart", + "E06000001" => "Hartlepool", + "E07000062" => "Hastings", + "E07000090" => "Havant", + "E09000016" => "Havering", + "E06000019" => "Herefordshire, County of", + "E07000098" => "Hertsmere", + "E07000037" => "High Peak", + "S12000017" => "Highland", + "E09000017" => "Hillingdon", + "E07000132" => "Hinckley and Bosworth", + "E07000227" => "Horsham", + "E09000018" => "Hounslow", + "E07000011" => "Huntingdonshire", + "E07000120" => "Hyndburn", + "S12000018" => "Inverclyde", + "E07000202" => "Ipswich", + "W06000001" => "Isle of Anglesey", + "E06000046" => "Isle of Wight", + "E06000053" => "Isles of Scilly", + "E09000019" => "Islington", + "E09000020" => "Kensington and Chelsea", + "E07000153" => "Kettering", + "E07000146" => "King’s Lynn and West Norfolk", + "E06000010" => "Kingston upon Hull, City of", + "E09000021" => "Kingston upon Thames", + "E08000034" => "Kirklees", + "E08000011" => "Knowsley", + "E09000022" => "Lambeth", + "E07000121" => "Lancaster", + "E08000035" => "Leeds", + "E06000016" => "Leicester", + "E07000063" => "Lewes", + "E09000023" => "Lewisham", + "E07000194" => "Lichfield", + "E07000138" => "Lincoln", + "N09000007" => "Lisburn and Castlereagh", + "E08000012" => "Liverpool", + "E06000032" => "Luton", + "E07000110" => "Maidstone", + "E07000074" => "Maldon", + "E07000235" => "Malvern Hills", + "E08000003" => "Manchester", + "E07000174" => "Mansfield", + "E06000035" => "Medway", + "E07000133" => "Melton", + "E07000187" => "Mendip", + "W06000024" => "Merthyr Tydfil", + "E09000024" => "Merton", + "E07000042" => "Mid Devon", + "E07000203" => "Mid Suffolk", + "E07000228" => "Mid Sussex", + "N09000009" => "Mid Ulster", + "N09000008" => "Mid and East Antrim", + "E06000002" => "Middlesbrough", + "S12000019" => "Midlothian", + "E06000042" => "Milton Keynes", + "E07000210" => "Mole Valley", + "W06000021" => "Monmouthshire", + "S12000020" => "Moray", + "S12000013" => "Na h-Eileanan Siar", + "W06000012" => "Neath Port Talbot", + "E07000091" => "New Forest", + "E07000175" => "Newark and Sherwood", + "E08000021" => "Newcastle upon Tyne", + "E07000195" => "Newcastle-under-Lyme", + "E09000025" => "Newham", + "W06000022" => "Newport", + "N09000010" => "Newry, Mourne and Down", + "S12000021" => "North Ayrshire", + "E07000043" => "North Devon", + "E07000038" => "North East Derbyshire", + "E06000012" => "North East Lincolnshire", + "E07000099" => "North Hertfordshire", + "E07000139" => "North Kesteven", + "S12000050" => "North Lanarkshire", + "E06000013" => "North Lincolnshire", + "E07000147" => "North Norfolk", + "E06000024" => "North Somerset", + "E08000022" => "North Tyneside", + "E07000218" => "North Warwickshire", + "E07000134" => "North West Leicestershire", + "E07000154" => "Northampton", + "E06000057" => "Northumberland", + "E07000148" => "Norwich", + "E06000018" => "Nottingham", + "E07000219" => "Nuneaton and Bedworth", + "E07000135" => "Oadby and Wigston", + "E08000004" => "Oldham", + "S12000023" => "Orkney Islands", + "E07000178" => "Oxford", + "W06000009" => "Pembrokeshire", + "E07000122" => "Pendle", + "S12000048" => "Perth and Kinross", + "E06000031" => "Peterborough", + "E06000026" => "Plymouth", + "E06000044" => "Portsmouth", + "W06000023" => "Powys", + "E07000123" => "Preston", + "E06000038" => "Reading", + "E09000026" => "Redbridge", + "E06000003" => "Redcar and Cleveland", + "E07000236" => "Redditch", + "E07000211" => "Reigate and Banstead", + "S12000038" => "Renfrewshire", + "W06000016" => "Rhondda Cynon Taf", + "E07000124" => "Ribble Valley", + "E09000027" => "Richmond upon Thames", + "E07000166" => "Richmondshire", + "E08000005" => "Rochdale", + "E07000075" => "Rochford", + "E07000125" => "Rossendale", + "E07000064" => "Rother", + "E08000018" => "Rotherham", + "E07000220" => "Rugby", + "E07000212" => "Runnymede", + "E07000176" => "Rushcliffe", + "E07000092" => "Rushmoor", + "E06000017" => "Rutland", + "E07000167" => "Ryedale", + "E08000006" => "Salford", + "E08000028" => "Sandwell", + "E07000168" => "Scarborough", + "S12000026" => "Scottish Borders", + "E07000188" => "Sedgemoor", + "E08000014" => "Sefton", + "E07000169" => "Selby", + "E07000111" => "Sevenoaks", + "E08000019" => "Sheffield", + "S12000027" => "Shetland Islands", + "E06000051" => "Shropshire", + "E06000039" => "Slough", + "E08000029" => "Solihull", + "E07000246" => "Somerset West and Taunton", + "S12000028" => "South Ayrshire", + "E07000012" => "South Cambridgeshire", + "E07000039" => "South Derbyshire", + "E06000025" => "South Gloucestershire", + "E07000044" => "South Hams", + "E07000140" => "South Holland", + "E07000141" => "South Kesteven", + "E07000031" => "South Lakeland", + "S12000029" => "South Lanarkshire", + "E07000149" => "South Norfolk", + "E07000155" => "South Northamptonshire", + "E07000179" => "South Oxfordshire", + "E07000126" => "South Ribble", + "E07000189" => "South Somerset", + "E07000196" => "South Staffordshire", + "E08000023" => "South Tyneside", + "E06000045" => "Southampton", + "E06000033" => "Southend-on-Sea", + "E09000028" => "Southwark", + "E07000213" => "Spelthorne", + "E07000240" => "St Albans", + "E08000013" => "St. Helens", + "E07000197" => "Stafford", + "E07000198" => "Staffordshire Moorlands", + "E07000243" => "Stevenage", + "S12000030" => "Stirling", + "E08000007" => "Stockport", + "E06000004" => "Stockton-on-Tees", + "E06000021" => "Stoke-on-Trent", + "E07000221" => "Stratford-on-Avon", + "E07000082" => "Stroud", + "E08000024" => "Sunderland", + "E07000214" => "Surrey Heath", + "E09000029" => "Sutton", + "E07000113" => "Swale", + "W06000011" => "Swansea", + "E06000030" => "Swindon", + "E08000008" => "Tameside", + "E07000199" => "Tamworth", + "E07000215" => "Tandridge", + "E07000045" => "Teignbridge", + "E06000020" => "Telford and Wrekin", + "E07000076" => "Tendring", + "E07000093" => "Test Valley", + "E07000083" => "Tewkesbury", + "E07000114" => "Thanet", + "E07000102" => "Three Rivers", + "E06000034" => "Thurrock", + "E07000115" => "Tonbridge and Malling", + "E06000027" => "Torbay", + "W06000020" => "Torfaen", + "E07000046" => "Torridge", + "E09000030" => "Tower Hamlets", + "E08000009" => "Trafford", + "E07000116" => "Tunbridge Wells", + "E07000077" => "Uttlesford", + "W06000014" => "Vale of Glamorgan", + "E07000180" => "Vale of White Horse", + "E08000036" => "Wakefield", + "E08000030" => "Walsall", + "E09000031" => "Waltham Forest", + "E09000032" => "Wandsworth", + "E06000007" => "Warrington", + "E07000222" => "Warwick", + "E07000103" => "Watford", + "E07000216" => "Waverley", + "E07000065" => "Wealden", + "E07000156" => "Wellingborough", + "E07000241" => "Welwyn Hatfield", + "E06000037" => "West Berkshire", + "E07000047" => "West Devon", + "S12000039" => "West Dunbartonshire", + "E07000127" => "West Lancashire", + "E07000142" => "West Lindsey", + "S12000040" => "West Lothian", + "E07000181" => "West Oxfordshire", + "E07000245" => "West Suffolk", + "E09000033" => "Westminster", + "E08000010" => "Wigan", + "E06000054" => "Wiltshire", + "E07000094" => "Winchester", + "E06000040" => "Windsor and Maidenhead", + "E08000015" => "Wirral", + "E07000217" => "Woking", + "E06000041" => "Wokingham", + "E08000031" => "Wolverhampton", + "E07000237" => "Worcester", + "E07000229" => "Worthing", + "W06000006" => "Wrexham", + "E07000238" => "Wychavon", + "E07000128" => "Wyre", + "E07000239" => "Wyre Forest", + "E06000014" => "York", + "N92000002" => "Northern Ireland", + "S92000003" => "Scotland", + "W92000004" => "Wales", + "9300000XX" => "Outside UK", + }) + end + end + + context "with 2023/24 form" do + let(:start_date) { Time.utc(2023, 4, 1) } + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "" => "Select an option", + "S12000033" => "Aberdeen City", + "S12000034" => "Aberdeenshire", + "E07000223" => "Adur", + "E07000032" => "Amber Valley", + "S12000041" => "Angus", + "N09000001" => "Antrim and Newtownabbey", + "N09000011" => "Ards and North Down", + "S12000035" => "Argyll and Bute", + "N09000002" => "Armagh City, Banbridge and Craigavon", + "E07000224" => "Arun", + "E07000170" => "Ashfield", + "E07000105" => "Ashford", + "E07000200" => "Babergh", + "E09000002" => "Barking and Dagenham", + "E09000003" => "Barnet", + "E08000016" => "Barnsley", + "E07000066" => "Basildon", + "E07000084" => "Basingstoke and Deane", + "E07000171" => "Bassetlaw", + "E06000022" => "Bath and North East Somerset", + "E06000055" => "Bedford", + "N09000003" => "Belfast", + "E09000004" => "Bexley", + "E08000025" => "Birmingham", + "E07000129" => "Blaby", + "E06000008" => "Blackburn with Darwen", + "E06000009" => "Blackpool", + "W06000019" => "Blaenau Gwent", + "E07000033" => "Bolsover", + "E08000001" => "Bolton", + "E07000136" => "Boston", + "E06000058" => "Bournemouth, Christchurch and Poole", + "E06000036" => "Bracknell Forest", + "E08000032" => "Bradford", + "E07000067" => "Braintree", + "E07000143" => "Breckland", + "E09000005" => "Brent", + "E07000068" => "Brentwood", + "W06000013" => "Bridgend", + "E06000043" => "Brighton and Hove", + "E06000023" => "Bristol, City of", + "E07000144" => "Broadland", + "E09000006" => "Bromley", + "E07000234" => "Bromsgrove", + "E07000095" => "Broxbourne", + "E07000172" => "Broxtowe", + "E06000060" => "Buckinghamshire", + "E07000117" => "Burnley", + "E08000002" => "Bury", + "W06000018" => "Caerphilly", + "E08000033" => "Calderdale", + "E07000008" => "Cambridge", + "E09000007" => "Camden", + "E07000192" => "Cannock Chase", + "E07000106" => "Canterbury", + "W06000015" => "Cardiff", + "W06000010" => "Carmarthenshire", + "E07000069" => "Castle Point", + "N09000004" => "Causeway Coast and Glens", + "E06000056" => "Central Bedfordshire", + "W06000008" => "Ceredigion", + "E07000130" => "Charnwood", + "E07000070" => "Chelmsford", + "E07000078" => "Cheltenham", + "E07000177" => "Cherwell", + "E06000049" => "Cheshire East", + "E06000050" => "Cheshire West and Chester", + "E07000034" => "Chesterfield", + "E07000225" => "Chichester", + "E07000118" => "Chorley", + "S12000036" => "City of Edinburgh", + "E09000001" => "City of London", + "S12000005" => "Clackmannanshire", + "E07000071" => "Colchester", + "W06000003" => "Conwy", + "E07000150" => "Corby", + "E06000052" => "Cornwall", + "E07000079" => "Cotswold", + "E06000047" => "County Durham", + "E08000026" => "Coventry", + "E07000226" => "Crawley", + "E09000008" => "Croydon", + "E06000063" => "Cumberland", + "E07000096" => "Dacorum", + "E06000005" => "Darlington", + "E07000107" => "Dartford", + "E07000151" => "Daventry", + "W06000004" => "Denbighshire", + "E06000015" => "Derby", + "E07000035" => "Derbyshire Dales", + "N09000005" => "Derry City and Strabane", + "E08000017" => "Doncaster", + "E06000059" => "Dorset", + "E07000108" => "Dover", + "E08000027" => "Dudley", + "S12000006" => "Dumfries and Galloway", + "S12000042" => "Dundee City", + "E09000009" => "Ealing", + "S12000008" => "East Ayrshire", + "E07000009" => "East Cambridgeshire", + "E07000040" => "East Devon", + "S12000045" => "East Dunbartonshire", + "E07000085" => "East Hampshire", + "E07000242" => "East Hertfordshire", + "E07000137" => "East Lindsey", + "S12000010" => "East Lothian", + "E07000152" => "East Northamptonshire", + "S12000011" => "East Renfrewshire", + "E06000011" => "East Riding of Yorkshire", + "E07000193" => "East Staffordshire", + "E07000244" => "East Suffolk", + "E07000061" => "Eastbourne", + "E07000086" => "Eastleigh", + "E07000207" => "Elmbridge", + "E09000010" => "Enfield", + "E07000072" => "Epping Forest", + "E07000208" => "Epsom and Ewell", + "E07000036" => "Erewash", + "E07000041" => "Exeter", + "S12000014" => "Falkirk", + "E07000087" => "Fareham", + "E07000010" => "Fenland", + "N09000006" => "Fermanagh and Omagh", + "S12000047" => "Fife", + "W06000005" => "Flintshire", + "E07000112" => "Folkestone and Hythe", + "E07000080" => "Forest of Dean", + "E07000119" => "Fylde", + "E08000037" => "Gateshead", + "E07000173" => "Gedling", + "S12000049" => "Glasgow City", + "E07000081" => "Gloucester", + "E07000088" => "Gosport", + "E07000109" => "Gravesham", + "E07000145" => "Great Yarmouth", + "E09000011" => "Greenwich", + "E07000209" => "Guildford", + "W06000002" => "Gwynedd", + "E09000012" => "Hackney", + "E06000006" => "Halton", + "E09000013" => "Hammersmith and Fulham", + "E07000131" => "Harborough", + "E09000014" => "Haringey", + "E07000073" => "Harlow", + "E09000015" => "Harrow", + "E07000089" => "Hart", + "E06000001" => "Hartlepool", + "E07000062" => "Hastings", + "E07000090" => "Havant", + "E09000016" => "Havering", + "E06000019" => "Herefordshire, County of", + "E07000098" => "Hertsmere", + "E07000037" => "High Peak", + "S12000017" => "Highland", + "E09000017" => "Hillingdon", + "E07000132" => "Hinckley and Bosworth", + "E07000227" => "Horsham", + "E09000018" => "Hounslow", + "E07000011" => "Huntingdonshire", + "E07000120" => "Hyndburn", + "S12000018" => "Inverclyde", + "E07000202" => "Ipswich", + "W06000001" => "Isle of Anglesey", + "E06000046" => "Isle of Wight", + "E06000053" => "Isles of Scilly", + "E09000019" => "Islington", + "E09000020" => "Kensington and Chelsea", + "E07000153" => "Kettering", + "E07000146" => "King’s Lynn and West Norfolk", + "E06000010" => "Kingston upon Hull, City of", + "E09000021" => "Kingston upon Thames", + "E08000034" => "Kirklees", + "E08000011" => "Knowsley", + "E09000022" => "Lambeth", + "E07000121" => "Lancaster", + "E08000035" => "Leeds", + "E06000016" => "Leicester", + "E07000063" => "Lewes", + "E09000023" => "Lewisham", + "E07000194" => "Lichfield", + "E07000138" => "Lincoln", + "N09000007" => "Lisburn and Castlereagh", + "E08000012" => "Liverpool", + "E06000032" => "Luton", + "E07000110" => "Maidstone", + "E07000074" => "Maldon", + "E07000235" => "Malvern Hills", + "E08000003" => "Manchester", + "E07000174" => "Mansfield", + "E06000035" => "Medway", + "E07000133" => "Melton", + "W06000024" => "Merthyr Tydfil", + "E09000024" => "Merton", + "E07000042" => "Mid Devon", + "E07000203" => "Mid Suffolk", + "E07000228" => "Mid Sussex", + "N09000009" => "Mid Ulster", + "N09000008" => "Mid and East Antrim", + "E06000002" => "Middlesbrough", + "S12000019" => "Midlothian", + "E06000042" => "Milton Keynes", + "E07000210" => "Mole Valley", + "W06000021" => "Monmouthshire", + "S12000020" => "Moray", + "S12000013" => "Na h-Eileanan Siar", + "W06000012" => "Neath Port Talbot", + "E07000091" => "New Forest", + "E07000175" => "Newark and Sherwood", + "E08000021" => "Newcastle upon Tyne", + "E07000195" => "Newcastle-under-Lyme", + "E09000025" => "Newham", + "W06000022" => "Newport", + "N09000010" => "Newry, Mourne and Down", + "S12000021" => "North Ayrshire", + "E07000043" => "North Devon", + "E07000038" => "North East Derbyshire", + "E06000012" => "North East Lincolnshire", + "E07000099" => "North Hertfordshire", + "E07000139" => "North Kesteven", + "S12000050" => "North Lanarkshire", + "E06000013" => "North Lincolnshire", + "E07000147" => "North Norfolk", + "E06000024" => "North Somerset", + "E08000022" => "North Tyneside", + "E07000218" => "North Warwickshire", + "E06000065" => "North Yorkshire", + "E07000134" => "North West Leicestershire", + "E07000154" => "Northampton", + "E06000057" => "Northumberland", + "E07000148" => "Norwich", + "E06000018" => "Nottingham", + "E07000219" => "Nuneaton and Bedworth", + "E07000135" => "Oadby and Wigston", + "E08000004" => "Oldham", + "S12000023" => "Orkney Islands", + "E07000178" => "Oxford", + "W06000009" => "Pembrokeshire", + "E07000122" => "Pendle", + "S12000048" => "Perth and Kinross", + "E06000031" => "Peterborough", + "E06000026" => "Plymouth", + "E06000044" => "Portsmouth", + "W06000023" => "Powys", + "E07000123" => "Preston", + "E06000038" => "Reading", + "E09000026" => "Redbridge", + "E06000003" => "Redcar and Cleveland", + "E07000236" => "Redditch", + "E07000211" => "Reigate and Banstead", + "S12000038" => "Renfrewshire", + "W06000016" => "Rhondda Cynon Taf", + "E07000124" => "Ribble Valley", + "E09000027" => "Richmond upon Thames", + "E08000005" => "Rochdale", + "E07000075" => "Rochford", + "E07000125" => "Rossendale", + "E07000064" => "Rother", + "E08000018" => "Rotherham", + "E07000220" => "Rugby", + "E07000212" => "Runnymede", + "E07000176" => "Rushcliffe", + "E07000092" => "Rushmoor", + "E06000017" => "Rutland", + "E08000006" => "Salford", + "E08000028" => "Sandwell", + "S12000026" => "Scottish Borders", + "E08000014" => "Sefton", + "E07000111" => "Sevenoaks", + "E08000019" => "Sheffield", + "S12000027" => "Shetland Islands", + "E06000051" => "Shropshire", + "E06000039" => "Slough", + "E08000029" => "Solihull", + "E06000066" => "Somerset", + "S12000028" => "South Ayrshire", + "E07000012" => "South Cambridgeshire", + "E07000039" => "South Derbyshire", + "E06000025" => "South Gloucestershire", + "E07000044" => "South Hams", + "E07000140" => "South Holland", + "E07000141" => "South Kesteven", + "S12000029" => "South Lanarkshire", + "E07000149" => "South Norfolk", + "E07000155" => "South Northamptonshire", + "E07000179" => "South Oxfordshire", + "E07000126" => "South Ribble", + "E07000196" => "South Staffordshire", + "E08000023" => "South Tyneside", + "E06000045" => "Southampton", + "E06000033" => "Southend-on-Sea", + "E09000028" => "Southwark", + "E07000213" => "Spelthorne", + "E07000240" => "St Albans", + "E08000013" => "St. Helens", + "E07000197" => "Stafford", + "E07000198" => "Staffordshire Moorlands", + "E07000243" => "Stevenage", + "S12000030" => "Stirling", + "E08000007" => "Stockport", + "E06000004" => "Stockton-on-Tees", + "E06000021" => "Stoke-on-Trent", + "E07000221" => "Stratford-on-Avon", + "E07000082" => "Stroud", + "E08000024" => "Sunderland", + "E07000214" => "Surrey Heath", + "E09000029" => "Sutton", + "E07000113" => "Swale", + "W06000011" => "Swansea", + "E06000030" => "Swindon", + "E08000008" => "Tameside", + "E07000199" => "Tamworth", + "E07000215" => "Tandridge", + "E07000045" => "Teignbridge", + "E06000020" => "Telford and Wrekin", + "E07000076" => "Tendring", + "E07000093" => "Test Valley", + "E07000083" => "Tewkesbury", + "E07000114" => "Thanet", + "E07000102" => "Three Rivers", + "E06000034" => "Thurrock", + "E07000115" => "Tonbridge and Malling", + "E06000027" => "Torbay", + "W06000020" => "Torfaen", + "E07000046" => "Torridge", + "E09000030" => "Tower Hamlets", + "E08000009" => "Trafford", + "E07000116" => "Tunbridge Wells", + "E07000077" => "Uttlesford", + "W06000014" => "Vale of Glamorgan", + "E07000180" => "Vale of White Horse", + "E08000036" => "Wakefield", + "E08000030" => "Walsall", + "E09000031" => "Waltham Forest", + "E09000032" => "Wandsworth", + "E06000007" => "Warrington", + "E07000222" => "Warwick", + "E07000103" => "Watford", + "E07000216" => "Waverley", + "E07000065" => "Wealden", + "E07000156" => "Wellingborough", + "E07000241" => "Welwyn Hatfield", + "E06000037" => "West Berkshire", + "E07000047" => "West Devon", + "S12000039" => "West Dunbartonshire", + "E07000127" => "West Lancashire", + "E07000142" => "West Lindsey", + "S12000040" => "West Lothian", + "E07000181" => "West Oxfordshire", + "E07000245" => "West Suffolk", + "E09000033" => "Westminster", + "E06000064" => "Westmorland and Furness", + "E08000010" => "Wigan", + "E06000054" => "Wiltshire", + "E07000094" => "Winchester", + "E06000040" => "Windsor and Maidenhead", + "E08000015" => "Wirral", + "E07000217" => "Woking", + "E06000041" => "Wokingham", + "E08000031" => "Wolverhampton", + "E07000237" => "Worcester", + "E07000229" => "Worthing", + "W06000006" => "Wrexham", + "E07000238" => "Wychavon", + "E07000128" => "Wyre", + "E07000239" => "Wyre Forest", + "E06000014" => "York", + "N92000002" => "Northern Ireland", + "S92000003" => "Scotland", + "W92000004" => "Wales", + "9300000XX" => "Outside UK", + }) + end end it "has the correct inferred_check_answers_value" do diff --git a/spec/models/form/sales/questions/prevown_spec.rb b/spec/models/form/sales/questions/prevown_spec.rb index dda2b7c70..d7b101c99 100644 --- a/spec/models/form/sales/questions/prevown_spec.rb +++ b/spec/models/form/sales/questions/prevown_spec.rb @@ -1,11 +1,12 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::Prevown, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } + subject(:question) { described_class.new(question_id, question_definition, page, joint_purchase:) } let(:question_id) { nil } let(:question_definition) { nil } let(:page) { instance_double(Form::Page) } + let(:joint_purchase) { false } it "has correct page" do expect(question.page).to eq(page) @@ -15,12 +16,26 @@ RSpec.describe Form::Sales::Questions::Prevown, type: :model do expect(question.id).to eq("prevown") end - it "has the correct header" do - expect(question.header).to eq("Has the buyer previously owned a property?") + context "when sale is not a joint purchase" do + it "has the correct header" do + expect(question.header).to eq("Has the buyer previously owned a property?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Buyer previously owned a property") + end end - it "has the correct check_answer_label" do - expect(question.check_answer_label).to eq("Buyers previously owned a property") + context "when sale is a joint purchase" do + let(:joint_purchase) { true } + + it "has the correct header" do + expect(question.header).to eq("Have any of the buyers previously owned a property?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Buyers previously owned a property") + end end it "has the correct type" do diff --git a/spec/models/form/sales/questions/property_local_authority_spec.rb b/spec/models/form/sales/questions/property_local_authority_spec.rb index 060f69bfa..174a37347 100644 --- a/spec/models/form/sales/questions/property_local_authority_spec.rb +++ b/spec/models/form/sales/questions/property_local_authority_spec.rb @@ -5,7 +5,9 @@ RSpec.describe Form::Sales::Questions::PropertyLocalAuthority, type: :model do let(:question_id) { nil } let(:question_definition) { nil } - let(:page) { instance_double(Form::Page) } + let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date:)) } + let(:page) { instance_double(Form::Page, subsection:) } + let(:start_date) { Time.utc(2022, 4, 1) } it "has correct page" do expect(question.page).to eq(page) @@ -16,7 +18,7 @@ RSpec.describe Form::Sales::Questions::PropertyLocalAuthority, type: :model do end it "has the correct header" do - expect(question.header).to eq("What is the local authority of the property?") + expect(question.header).to eq("What is the property’s local authority?") end it "has the correct check_answer_label" do @@ -31,325 +33,668 @@ RSpec.describe Form::Sales::Questions::PropertyLocalAuthority, type: :model do expect(question.derived?).to be false end - it "has the correct answer_options" do - expect(question.answer_options).to eq({ - "" => "Select an option", - "E06000001" => "Hartlepool", - "E06000002" => "Middlesbrough", - "E06000003" => "Redcar and Cleveland", - "E06000004" => "Stockton-on-Tees", - "E06000005" => "Darlington", - "E06000006" => "Halton", - "E06000007" => "Warrington", - "E06000008" => "Blackburn with Darwen", - "E06000009" => "Blackpool", - "E06000010" => "Kingston upon Hull, City of", - "E06000011" => "East Riding of Yorkshire", - "E06000012" => "North East Lincolnshire", - "E06000013" => "North Lincolnshire", - "E06000014" => "York", - "E06000015" => "Derby", - "E06000016" => "Leicester", - "E06000017" => "Rutland", - "E06000018" => "Nottingham", - "E06000019" => "Herefordshire, County of", - "E06000020" => "Telford and Wrekin", - "E06000021" => "Stoke-on-Trent", - "E06000022" => "Bath and North East Somerset", - "E06000023" => "Bristol, City of", - "E06000024" => "North Somerset", - "E06000025" => "South Gloucestershire", - "E06000026" => "Plymouth", - "E06000027" => "Torbay", - "E06000030" => "Swindon", - "E06000031" => "Peterborough", - "E06000032" => "Luton", - "E06000033" => "Southend-on-Sea", - "E06000034" => "Thurrock", - "E06000035" => "Medway", - "E06000036" => "Bracknell Forest", - "E06000037" => "West Berkshire", - "E06000038" => "Reading", - "E06000039" => "Slough", - "E06000040" => "Windsor and Maidenhead", - "E06000041" => "Wokingham", - "E06000042" => "Milton Keynes", - "E06000043" => "Brighton and Hove", - "E06000044" => "Portsmouth", - "E06000045" => "Southampton", - "E06000046" => "Isle of Wight", - "E06000047" => "County Durham", - "E06000049" => "Cheshire East", - "E06000050" => "Cheshire West and Chester", - "E06000051" => "Shropshire", - "E06000052" => "Cornwall", - "E06000053" => "Isles of Scilly", - "E06000054" => "Wiltshire", - "E06000055" => "Bedford", - "E06000056" => "Central Bedfordshire", - "E06000057" => "Northumberland", - "E06000058" => "Bournemouth, Christchurch and Poole", - "E06000059" => "Dorset", - "E06000060" => "Buckinghamshire", - "E07000008" => "Cambridge", - "E07000009" => "East Cambridgeshire", - "E07000010" => "Fenland", - "E07000011" => "Huntingdonshire", - "E07000012" => "South Cambridgeshire", - "E07000026" => "Allerdale", - "E07000027" => "Barrow-in-Furness", - "E07000028" => "Carlisle", - "E07000029" => "Copeland", - "E07000030" => "Eden", - "E07000031" => "South Lakeland", - "E07000032" => "Amber Valley", - "E07000033" => "Bolsover", - "E07000034" => "Chesterfield", - "E07000035" => "Derbyshire Dales", - "E07000036" => "Erewash", - "E07000037" => "High Peak", - "E07000038" => "North East Derbyshire", - "E07000039" => "South Derbyshire", - "E07000040" => "East Devon", - "E07000041" => "Exeter", - "E07000042" => "Mid Devon", - "E07000043" => "North Devon", - "E07000044" => "South Hams", - "E07000045" => "Teignbridge", - "E07000046" => "Torridge", - "E07000047" => "West Devon", - "E07000061" => "Eastbourne", - "E07000062" => "Hastings", - "E07000063" => "Lewes", - "E07000064" => "Rother", - "E07000065" => "Wealden", - "E07000066" => "Basildon", - "E07000067" => "Braintree", - "E07000068" => "Brentwood", - "E07000069" => "Castle Point", - "E07000070" => "Chelmsford", - "E07000071" => "Colchester", - "E07000072" => "Epping Forest", - "E07000073" => "Harlow", - "E07000074" => "Maldon", - "E07000075" => "Rochford", - "E07000076" => "Tendring", - "E07000077" => "Uttlesford", - "E07000078" => "Cheltenham", - "E07000079" => "Cotswold", - "E07000080" => "Forest of Dean", - "E07000081" => "Gloucester", - "E07000082" => "Stroud", - "E07000083" => "Tewkesbury", - "E07000084" => "Basingstoke and Deane", - "E07000085" => "East Hampshire", - "E07000086" => "Eastleigh", - "E07000087" => "Fareham", - "E07000088" => "Gosport", - "E07000089" => "Hart", - "E07000090" => "Havant", - "E07000091" => "New Forest", - "E07000092" => "Rushmoor", - "E07000093" => "Test Valley", - "E07000094" => "Winchester", - "E07000095" => "Broxbourne", - "E07000096" => "Dacorum", - "E07000098" => "Hertsmere", - "E07000099" => "North Hertfordshire", - "E07000102" => "Three Rivers", - "E07000103" => "Watford", - "E07000105" => "Ashford", - "E07000106" => "Canterbury", - "E07000107" => "Dartford", - "E07000108" => "Dover", - "E07000109" => "Gravesham", - "E07000110" => "Maidstone", - "E07000111" => "Sevenoaks", - "E07000112" => "Folkestone and Hythe", - "E07000113" => "Swale", - "E07000114" => "Thanet", - "E07000115" => "Tonbridge and Malling", - "E07000116" => "Tunbridge Wells", - "E07000117" => "Burnley", - "E07000118" => "Chorley", - "E07000119" => "Fylde", - "E07000120" => "Hyndburn", - "E07000121" => "Lancaster", - "E07000122" => "Pendle", - "E07000123" => "Preston", - "E07000124" => "Ribble Valley", - "E07000125" => "Rossendale", - "E07000126" => "South Ribble", - "E07000127" => "West Lancashire", - "E07000128" => "Wyre", - "E07000129" => "Blaby", - "E07000130" => "Charnwood", - "E07000131" => "Harborough", - "E07000132" => "Hinckley and Bosworth", - "E07000133" => "Melton", - "E07000134" => "North West Leicestershire", - "E07000135" => "Oadby and Wigston", - "E07000136" => "Boston", - "E07000137" => "East Lindsey", - "E07000138" => "Lincoln", - "E07000139" => "North Kesteven", - "E07000140" => "South Holland", - "E07000141" => "South Kesteven", - "E07000142" => "West Lindsey", - "E07000143" => "Breckland", - "E07000144" => "Broadland", - "E07000145" => "Great Yarmouth", - "E07000146" => "King’s Lynn and West Norfolk", - "E07000147" => "North Norfolk", - "E07000148" => "Norwich", - "E07000149" => "South Norfolk", - "E07000150" => "Corby", - "E07000151" => "Daventry", - "E07000152" => "East Northamptonshire", - "E07000153" => "Kettering", - "E07000154" => "Northampton", - "E07000155" => "South Northamptonshire", - "E07000156" => "Wellingborough", - "E07000163" => "Craven", - "E07000164" => "Hambleton", - "E07000165" => "Harrogate", - "E07000166" => "Richmondshire", - "E07000167" => "Ryedale", - "E07000168" => "Scarborough", - "E07000169" => "Selby", - "E07000170" => "Ashfield", - "E07000171" => "Bassetlaw", - "E07000172" => "Broxtowe", - "E07000173" => "Gedling", - "E07000174" => "Mansfield", - "E07000175" => "Newark and Sherwood", - "E07000176" => "Rushcliffe", - "E07000177" => "Cherwell", - "E07000178" => "Oxford", - "E07000179" => "South Oxfordshire", - "E07000180" => "Vale of White Horse", - "E07000181" => "West Oxfordshire", - "E07000187" => "Mendip", - "E07000188" => "Sedgemoor", - "E07000189" => "South Somerset", - "E07000192" => "Cannock Chase", - "E07000193" => "East Staffordshire", - "E07000194" => "Lichfield", - "E07000195" => "Newcastle-under-Lyme", - "E07000196" => "South Staffordshire", - "E07000197" => "Stafford", - "E07000198" => "Staffordshire Moorlands", - "E07000199" => "Tamworth", - "E07000200" => "Babergh", - "E07000202" => "Ipswich", - "E07000203" => "Mid Suffolk", - "E07000207" => "Elmbridge", - "E07000208" => "Epsom and Ewell", - "E07000209" => "Guildford", - "E07000210" => "Mole Valley", - "E07000211" => "Reigate and Banstead", - "E07000212" => "Runnymede", - "E07000213" => "Spelthorne", - "E07000214" => "Surrey Heath", - "E07000215" => "Tandridge", - "E07000216" => "Waverley", - "E07000217" => "Woking", - "E07000218" => "North Warwickshire", - "E07000219" => "Nuneaton and Bedworth", - "E07000220" => "Rugby", - "E07000221" => "Stratford-on-Avon", - "E07000222" => "Warwick", - "E07000223" => "Adur", - "E07000224" => "Arun", - "E07000225" => "Chichester", - "E07000226" => "Crawley", - "E07000227" => "Horsham", - "E07000228" => "Mid Sussex", - "E07000229" => "Worthing", - "E07000234" => "Bromsgrove", - "E07000235" => "Malvern Hills", - "E07000236" => "Redditch", - "E07000237" => "Worcester", - "E07000238" => "Wychavon", - "E07000239" => "Wyre Forest", - "E07000240" => "St Albans", - "E07000241" => "Welwyn Hatfield", - "E07000242" => "East Hertfordshire", - "E07000243" => "Stevenage", - "E07000244" => "East Suffolk", - "E07000245" => "West Suffolk", - "E07000246" => "Somerset West and Taunton", - "E08000001" => "Bolton", - "E08000002" => "Bury", - "E08000003" => "Manchester", - "E08000004" => "Oldham", - "E08000005" => "Rochdale", - "E08000006" => "Salford", - "E08000007" => "Stockport", - "E08000008" => "Tameside", - "E08000009" => "Trafford", - "E08000010" => "Wigan", - "E08000011" => "Knowsley", - "E08000012" => "Liverpool", - "E08000013" => "St. Helens", - "E08000014" => "Sefton", - "E08000015" => "Wirral", - "E08000016" => "Barnsley", - "E08000017" => "Doncaster", - "E08000018" => "Rotherham", - "E08000019" => "Sheffield", - "E08000021" => "Newcastle upon Tyne", - "E08000022" => "North Tyneside", - "E08000023" => "South Tyneside", - "E08000024" => "Sunderland", - "E08000025" => "Birmingham", - "E08000026" => "Coventry", - "E08000027" => "Dudley", - "E08000028" => "Sandwell", - "E08000029" => "Solihull", - "E08000030" => "Walsall", - "E08000031" => "Wolverhampton", - "E08000032" => "Bradford", - "E08000033" => "Calderdale", - "E08000034" => "Kirklees", - "E08000035" => "Leeds", - "E08000036" => "Wakefield", - "E08000037" => "Gateshead", - "E09000001" => "City of London", - "E09000002" => "Barking and Dagenham", - "E09000003" => "Barnet", - "E09000004" => "Bexley", - "E09000005" => "Brent", - "E09000006" => "Bromley", - "E09000007" => "Camden", - "E09000008" => "Croydon", - "E09000009" => "Ealing", - "E09000010" => "Enfield", - "E09000011" => "Greenwich", - "E09000012" => "Hackney", - "E09000013" => "Hammersmith and Fulham", - "E09000014" => "Haringey", - "E09000015" => "Harrow", - "E09000016" => "Havering", - "E09000017" => "Hillingdon", - "E09000018" => "Hounslow", - "E09000019" => "Islington", - "E09000020" => "Kensington and Chelsea", - "E09000021" => "Kingston upon Thames", - "E09000022" => "Lambeth", - "E09000023" => "Lewisham", - "E09000024" => "Merton", - "E09000025" => "Newham", - "E09000026" => "Redbridge", - "E09000027" => "Richmond upon Thames", - "E09000028" => "Southwark", - "E09000029" => "Sutton", - "E09000030" => "Tower Hamlets", - "E09000031" => "Waltham Forest", - "E09000032" => "Wandsworth", - "E09000033" => "Westminster", - "S12000017" => "Highland", - "W06000002" => "Gwynedd", - }) + context "with 2022/23 form" do + let(:start_date) { Time.utc(2022, 4, 1) } + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "" => "Select an option", + "E06000001" => "Hartlepool", + "E06000002" => "Middlesbrough", + "E06000003" => "Redcar and Cleveland", + "E06000004" => "Stockton-on-Tees", + "E06000005" => "Darlington", + "E06000006" => "Halton", + "E06000007" => "Warrington", + "E06000008" => "Blackburn with Darwen", + "E06000009" => "Blackpool", + "E06000010" => "Kingston upon Hull, City of", + "E06000011" => "East Riding of Yorkshire", + "E06000012" => "North East Lincolnshire", + "E06000013" => "North Lincolnshire", + "E06000014" => "York", + "E06000015" => "Derby", + "E06000016" => "Leicester", + "E06000017" => "Rutland", + "E06000018" => "Nottingham", + "E06000019" => "Herefordshire, County of", + "E06000020" => "Telford and Wrekin", + "E06000021" => "Stoke-on-Trent", + "E06000022" => "Bath and North East Somerset", + "E06000023" => "Bristol, City of", + "E06000024" => "North Somerset", + "E06000025" => "South Gloucestershire", + "E06000026" => "Plymouth", + "E06000027" => "Torbay", + "E06000030" => "Swindon", + "E06000031" => "Peterborough", + "E06000032" => "Luton", + "E06000033" => "Southend-on-Sea", + "E06000034" => "Thurrock", + "E06000035" => "Medway", + "E06000036" => "Bracknell Forest", + "E06000037" => "West Berkshire", + "E06000038" => "Reading", + "E06000039" => "Slough", + "E06000040" => "Windsor and Maidenhead", + "E06000041" => "Wokingham", + "E06000042" => "Milton Keynes", + "E06000043" => "Brighton and Hove", + "E06000044" => "Portsmouth", + "E06000045" => "Southampton", + "E06000046" => "Isle of Wight", + "E06000047" => "County Durham", + "E06000049" => "Cheshire East", + "E06000050" => "Cheshire West and Chester", + "E06000051" => "Shropshire", + "E06000052" => "Cornwall", + "E06000053" => "Isles of Scilly", + "E06000054" => "Wiltshire", + "E06000055" => "Bedford", + "E06000056" => "Central Bedfordshire", + "E06000057" => "Northumberland", + "E06000058" => "Bournemouth, Christchurch and Poole", + "E06000059" => "Dorset", + "E06000060" => "Buckinghamshire", + "E07000008" => "Cambridge", + "E07000009" => "East Cambridgeshire", + "E07000010" => "Fenland", + "E07000011" => "Huntingdonshire", + "E07000012" => "South Cambridgeshire", + "E07000026" => "Allerdale", + "E07000027" => "Barrow-in-Furness", + "E07000028" => "Carlisle", + "E07000029" => "Copeland", + "E07000030" => "Eden", + "E07000031" => "South Lakeland", + "E07000032" => "Amber Valley", + "E07000033" => "Bolsover", + "E07000034" => "Chesterfield", + "E07000035" => "Derbyshire Dales", + "E07000036" => "Erewash", + "E07000037" => "High Peak", + "E07000038" => "North East Derbyshire", + "E07000039" => "South Derbyshire", + "E07000040" => "East Devon", + "E07000041" => "Exeter", + "E07000042" => "Mid Devon", + "E07000043" => "North Devon", + "E07000044" => "South Hams", + "E07000045" => "Teignbridge", + "E07000046" => "Torridge", + "E07000047" => "West Devon", + "E07000061" => "Eastbourne", + "E07000062" => "Hastings", + "E07000063" => "Lewes", + "E07000064" => "Rother", + "E07000065" => "Wealden", + "E07000066" => "Basildon", + "E07000067" => "Braintree", + "E07000068" => "Brentwood", + "E07000069" => "Castle Point", + "E07000070" => "Chelmsford", + "E07000071" => "Colchester", + "E07000072" => "Epping Forest", + "E07000073" => "Harlow", + "E07000074" => "Maldon", + "E07000075" => "Rochford", + "E07000076" => "Tendring", + "E07000077" => "Uttlesford", + "E07000078" => "Cheltenham", + "E07000079" => "Cotswold", + "E07000080" => "Forest of Dean", + "E07000081" => "Gloucester", + "E07000082" => "Stroud", + "E07000083" => "Tewkesbury", + "E07000084" => "Basingstoke and Deane", + "E07000085" => "East Hampshire", + "E07000086" => "Eastleigh", + "E07000087" => "Fareham", + "E07000088" => "Gosport", + "E07000089" => "Hart", + "E07000090" => "Havant", + "E07000091" => "New Forest", + "E07000092" => "Rushmoor", + "E07000093" => "Test Valley", + "E07000094" => "Winchester", + "E07000095" => "Broxbourne", + "E07000096" => "Dacorum", + "E07000098" => "Hertsmere", + "E07000099" => "North Hertfordshire", + "E07000102" => "Three Rivers", + "E07000103" => "Watford", + "E07000105" => "Ashford", + "E07000106" => "Canterbury", + "E07000107" => "Dartford", + "E07000108" => "Dover", + "E07000109" => "Gravesham", + "E07000110" => "Maidstone", + "E07000111" => "Sevenoaks", + "E07000112" => "Folkestone and Hythe", + "E07000113" => "Swale", + "E07000114" => "Thanet", + "E07000115" => "Tonbridge and Malling", + "E07000116" => "Tunbridge Wells", + "E07000117" => "Burnley", + "E07000118" => "Chorley", + "E07000119" => "Fylde", + "E07000120" => "Hyndburn", + "E07000121" => "Lancaster", + "E07000122" => "Pendle", + "E07000123" => "Preston", + "E07000124" => "Ribble Valley", + "E07000125" => "Rossendale", + "E07000126" => "South Ribble", + "E07000127" => "West Lancashire", + "E07000128" => "Wyre", + "E07000129" => "Blaby", + "E07000130" => "Charnwood", + "E07000131" => "Harborough", + "E07000132" => "Hinckley and Bosworth", + "E07000133" => "Melton", + "E07000134" => "North West Leicestershire", + "E07000135" => "Oadby and Wigston", + "E07000136" => "Boston", + "E07000137" => "East Lindsey", + "E07000138" => "Lincoln", + "E07000139" => "North Kesteven", + "E07000140" => "South Holland", + "E07000141" => "South Kesteven", + "E07000142" => "West Lindsey", + "E07000143" => "Breckland", + "E07000144" => "Broadland", + "E07000145" => "Great Yarmouth", + "E07000146" => "King’s Lynn and West Norfolk", + "E07000147" => "North Norfolk", + "E07000148" => "Norwich", + "E07000149" => "South Norfolk", + "E07000150" => "Corby", + "E07000151" => "Daventry", + "E07000152" => "East Northamptonshire", + "E07000153" => "Kettering", + "E07000154" => "Northampton", + "E07000155" => "South Northamptonshire", + "E07000156" => "Wellingborough", + "E07000163" => "Craven", + "E07000164" => "Hambleton", + "E07000165" => "Harrogate", + "E07000166" => "Richmondshire", + "E07000167" => "Ryedale", + "E07000168" => "Scarborough", + "E07000169" => "Selby", + "E07000170" => "Ashfield", + "E07000171" => "Bassetlaw", + "E07000172" => "Broxtowe", + "E07000173" => "Gedling", + "E07000174" => "Mansfield", + "E07000175" => "Newark and Sherwood", + "E07000176" => "Rushcliffe", + "E07000177" => "Cherwell", + "E07000178" => "Oxford", + "E07000179" => "South Oxfordshire", + "E07000180" => "Vale of White Horse", + "E07000181" => "West Oxfordshire", + "E07000187" => "Mendip", + "E07000188" => "Sedgemoor", + "E07000189" => "South Somerset", + "E07000192" => "Cannock Chase", + "E07000193" => "East Staffordshire", + "E07000194" => "Lichfield", + "E07000195" => "Newcastle-under-Lyme", + "E07000196" => "South Staffordshire", + "E07000197" => "Stafford", + "E07000198" => "Staffordshire Moorlands", + "E07000199" => "Tamworth", + "E07000200" => "Babergh", + "E07000202" => "Ipswich", + "E07000203" => "Mid Suffolk", + "E07000207" => "Elmbridge", + "E07000208" => "Epsom and Ewell", + "E07000209" => "Guildford", + "E07000210" => "Mole Valley", + "E07000211" => "Reigate and Banstead", + "E07000212" => "Runnymede", + "E07000213" => "Spelthorne", + "E07000214" => "Surrey Heath", + "E07000215" => "Tandridge", + "E07000216" => "Waverley", + "E07000217" => "Woking", + "E07000218" => "North Warwickshire", + "E07000219" => "Nuneaton and Bedworth", + "E07000220" => "Rugby", + "E07000221" => "Stratford-on-Avon", + "E07000222" => "Warwick", + "E07000223" => "Adur", + "E07000224" => "Arun", + "E07000225" => "Chichester", + "E07000226" => "Crawley", + "E07000227" => "Horsham", + "E07000228" => "Mid Sussex", + "E07000229" => "Worthing", + "E07000234" => "Bromsgrove", + "E07000235" => "Malvern Hills", + "E07000236" => "Redditch", + "E07000237" => "Worcester", + "E07000238" => "Wychavon", + "E07000239" => "Wyre Forest", + "E07000240" => "St Albans", + "E07000241" => "Welwyn Hatfield", + "E07000242" => "East Hertfordshire", + "E07000243" => "Stevenage", + "E07000244" => "East Suffolk", + "E07000245" => "West Suffolk", + "E07000246" => "Somerset West and Taunton", + "E08000001" => "Bolton", + "E08000002" => "Bury", + "E08000003" => "Manchester", + "E08000004" => "Oldham", + "E08000005" => "Rochdale", + "E08000006" => "Salford", + "E08000007" => "Stockport", + "E08000008" => "Tameside", + "E08000009" => "Trafford", + "E08000010" => "Wigan", + "E08000011" => "Knowsley", + "E08000012" => "Liverpool", + "E08000013" => "St. Helens", + "E08000014" => "Sefton", + "E08000015" => "Wirral", + "E08000016" => "Barnsley", + "E08000017" => "Doncaster", + "E08000018" => "Rotherham", + "E08000019" => "Sheffield", + "E08000021" => "Newcastle upon Tyne", + "E08000022" => "North Tyneside", + "E08000023" => "South Tyneside", + "E08000024" => "Sunderland", + "E08000025" => "Birmingham", + "E08000026" => "Coventry", + "E08000027" => "Dudley", + "E08000028" => "Sandwell", + "E08000029" => "Solihull", + "E08000030" => "Walsall", + "E08000031" => "Wolverhampton", + "E08000032" => "Bradford", + "E08000033" => "Calderdale", + "E08000034" => "Kirklees", + "E08000035" => "Leeds", + "E08000036" => "Wakefield", + "E08000037" => "Gateshead", + "E09000001" => "City of London", + "E09000002" => "Barking and Dagenham", + "E09000003" => "Barnet", + "E09000004" => "Bexley", + "E09000005" => "Brent", + "E09000006" => "Bromley", + "E09000007" => "Camden", + "E09000008" => "Croydon", + "E09000009" => "Ealing", + "E09000010" => "Enfield", + "E09000011" => "Greenwich", + "E09000012" => "Hackney", + "E09000013" => "Hammersmith and Fulham", + "E09000014" => "Haringey", + "E09000015" => "Harrow", + "E09000016" => "Havering", + "E09000017" => "Hillingdon", + "E09000018" => "Hounslow", + "E09000019" => "Islington", + "E09000020" => "Kensington and Chelsea", + "E09000021" => "Kingston upon Thames", + "E09000022" => "Lambeth", + "E09000023" => "Lewisham", + "E09000024" => "Merton", + "E09000025" => "Newham", + "E09000026" => "Redbridge", + "E09000027" => "Richmond upon Thames", + "E09000028" => "Southwark", + "E09000029" => "Sutton", + "E09000030" => "Tower Hamlets", + "E09000031" => "Waltham Forest", + "E09000032" => "Wandsworth", + "E09000033" => "Westminster", + }) + end + end + + context "with 2023/24 form" do + let(:start_date) { Time.utc(2023, 4, 1) } + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "" => "Select an option", + "E06000001" => "Hartlepool", + "E06000002" => "Middlesbrough", + "E06000003" => "Redcar and Cleveland", + "E06000004" => "Stockton-on-Tees", + "E06000005" => "Darlington", + "E06000006" => "Halton", + "E06000007" => "Warrington", + "E06000008" => "Blackburn with Darwen", + "E06000009" => "Blackpool", + "E06000010" => "Kingston upon Hull, City of", + "E06000011" => "East Riding of Yorkshire", + "E06000012" => "North East Lincolnshire", + "E06000013" => "North Lincolnshire", + "E06000014" => "York", + "E06000015" => "Derby", + "E06000016" => "Leicester", + "E06000017" => "Rutland", + "E06000018" => "Nottingham", + "E06000019" => "Herefordshire, County of", + "E06000020" => "Telford and Wrekin", + "E06000021" => "Stoke-on-Trent", + "E06000022" => "Bath and North East Somerset", + "E06000023" => "Bristol, City of", + "E06000024" => "North Somerset", + "E06000025" => "South Gloucestershire", + "E06000026" => "Plymouth", + "E06000027" => "Torbay", + "E06000030" => "Swindon", + "E06000031" => "Peterborough", + "E06000032" => "Luton", + "E06000033" => "Southend-on-Sea", + "E06000034" => "Thurrock", + "E06000035" => "Medway", + "E06000036" => "Bracknell Forest", + "E06000037" => "West Berkshire", + "E06000038" => "Reading", + "E06000039" => "Slough", + "E06000040" => "Windsor and Maidenhead", + "E06000041" => "Wokingham", + "E06000042" => "Milton Keynes", + "E06000043" => "Brighton and Hove", + "E06000044" => "Portsmouth", + "E06000045" => "Southampton", + "E06000046" => "Isle of Wight", + "E06000047" => "County Durham", + "E06000049" => "Cheshire East", + "E06000050" => "Cheshire West and Chester", + "E06000051" => "Shropshire", + "E06000052" => "Cornwall", + "E06000053" => "Isles of Scilly", + "E06000054" => "Wiltshire", + "E06000055" => "Bedford", + "E06000056" => "Central Bedfordshire", + "E06000057" => "Northumberland", + "E06000058" => "Bournemouth, Christchurch and Poole", + "E06000059" => "Dorset", + "E06000060" => "Buckinghamshire", + "E07000008" => "Cambridge", + "E07000009" => "East Cambridgeshire", + "E07000010" => "Fenland", + "E07000011" => "Huntingdonshire", + "E07000012" => "South Cambridgeshire", + "E07000032" => "Amber Valley", + "E07000033" => "Bolsover", + "E07000034" => "Chesterfield", + "E07000035" => "Derbyshire Dales", + "E07000036" => "Erewash", + "E07000037" => "High Peak", + "E07000038" => "North East Derbyshire", + "E07000039" => "South Derbyshire", + "E07000040" => "East Devon", + "E07000041" => "Exeter", + "E07000042" => "Mid Devon", + "E07000043" => "North Devon", + "E07000044" => "South Hams", + "E07000045" => "Teignbridge", + "E07000046" => "Torridge", + "E07000047" => "West Devon", + "E07000061" => "Eastbourne", + "E07000062" => "Hastings", + "E07000063" => "Lewes", + "E07000064" => "Rother", + "E07000065" => "Wealden", + "E07000066" => "Basildon", + "E07000067" => "Braintree", + "E07000068" => "Brentwood", + "E07000069" => "Castle Point", + "E07000070" => "Chelmsford", + "E07000071" => "Colchester", + "E07000072" => "Epping Forest", + "E07000073" => "Harlow", + "E07000074" => "Maldon", + "E07000075" => "Rochford", + "E07000076" => "Tendring", + "E07000077" => "Uttlesford", + "E07000078" => "Cheltenham", + "E07000079" => "Cotswold", + "E07000080" => "Forest of Dean", + "E07000081" => "Gloucester", + "E07000082" => "Stroud", + "E07000083" => "Tewkesbury", + "E07000084" => "Basingstoke and Deane", + "E07000085" => "East Hampshire", + "E07000086" => "Eastleigh", + "E07000087" => "Fareham", + "E07000088" => "Gosport", + "E07000089" => "Hart", + "E07000090" => "Havant", + "E07000091" => "New Forest", + "E07000092" => "Rushmoor", + "E07000093" => "Test Valley", + "E07000094" => "Winchester", + "E07000095" => "Broxbourne", + "E07000096" => "Dacorum", + "E07000098" => "Hertsmere", + "E07000099" => "North Hertfordshire", + "E07000102" => "Three Rivers", + "E07000103" => "Watford", + "E07000105" => "Ashford", + "E07000106" => "Canterbury", + "E07000107" => "Dartford", + "E07000108" => "Dover", + "E07000109" => "Gravesham", + "E07000110" => "Maidstone", + "E07000111" => "Sevenoaks", + "E07000112" => "Folkestone and Hythe", + "E07000113" => "Swale", + "E07000114" => "Thanet", + "E07000115" => "Tonbridge and Malling", + "E07000116" => "Tunbridge Wells", + "E07000117" => "Burnley", + "E07000118" => "Chorley", + "E07000119" => "Fylde", + "E07000120" => "Hyndburn", + "E07000121" => "Lancaster", + "E07000122" => "Pendle", + "E07000123" => "Preston", + "E07000124" => "Ribble Valley", + "E07000125" => "Rossendale", + "E07000126" => "South Ribble", + "E07000127" => "West Lancashire", + "E07000128" => "Wyre", + "E07000129" => "Blaby", + "E07000130" => "Charnwood", + "E07000131" => "Harborough", + "E07000132" => "Hinckley and Bosworth", + "E07000133" => "Melton", + "E07000134" => "North West Leicestershire", + "E07000135" => "Oadby and Wigston", + "E07000136" => "Boston", + "E07000137" => "East Lindsey", + "E07000138" => "Lincoln", + "E07000139" => "North Kesteven", + "E07000140" => "South Holland", + "E07000141" => "South Kesteven", + "E07000142" => "West Lindsey", + "E07000143" => "Breckland", + "E07000144" => "Broadland", + "E07000145" => "Great Yarmouth", + "E07000146" => "King’s Lynn and West Norfolk", + "E07000147" => "North Norfolk", + "E07000148" => "Norwich", + "E07000149" => "South Norfolk", + "E07000150" => "Corby", + "E07000151" => "Daventry", + "E07000152" => "East Northamptonshire", + "E07000153" => "Kettering", + "E07000154" => "Northampton", + "E07000155" => "South Northamptonshire", + "E07000156" => "Wellingborough", + "E07000170" => "Ashfield", + "E07000171" => "Bassetlaw", + "E07000172" => "Broxtowe", + "E07000173" => "Gedling", + "E07000174" => "Mansfield", + "E07000175" => "Newark and Sherwood", + "E07000176" => "Rushcliffe", + "E07000177" => "Cherwell", + "E07000178" => "Oxford", + "E07000179" => "South Oxfordshire", + "E07000180" => "Vale of White Horse", + "E07000181" => "West Oxfordshire", + "E07000192" => "Cannock Chase", + "E07000193" => "East Staffordshire", + "E07000194" => "Lichfield", + "E07000195" => "Newcastle-under-Lyme", + "E07000196" => "South Staffordshire", + "E07000197" => "Stafford", + "E07000198" => "Staffordshire Moorlands", + "E07000199" => "Tamworth", + "E07000200" => "Babergh", + "E07000202" => "Ipswich", + "E07000203" => "Mid Suffolk", + "E07000207" => "Elmbridge", + "E07000208" => "Epsom and Ewell", + "E07000209" => "Guildford", + "E07000210" => "Mole Valley", + "E07000211" => "Reigate and Banstead", + "E07000212" => "Runnymede", + "E07000213" => "Spelthorne", + "E07000214" => "Surrey Heath", + "E07000215" => "Tandridge", + "E07000216" => "Waverley", + "E07000217" => "Woking", + "E07000218" => "North Warwickshire", + "E07000219" => "Nuneaton and Bedworth", + "E07000220" => "Rugby", + "E07000221" => "Stratford-on-Avon", + "E07000222" => "Warwick", + "E07000223" => "Adur", + "E07000224" => "Arun", + "E07000225" => "Chichester", + "E07000226" => "Crawley", + "E07000227" => "Horsham", + "E07000228" => "Mid Sussex", + "E07000229" => "Worthing", + "E07000234" => "Bromsgrove", + "E07000235" => "Malvern Hills", + "E07000236" => "Redditch", + "E07000237" => "Worcester", + "E07000238" => "Wychavon", + "E07000239" => "Wyre Forest", + "E07000240" => "St Albans", + "E07000241" => "Welwyn Hatfield", + "E07000242" => "East Hertfordshire", + "E07000243" => "Stevenage", + "E07000244" => "East Suffolk", + "E07000245" => "West Suffolk", + "E08000001" => "Bolton", + "E08000002" => "Bury", + "E08000003" => "Manchester", + "E08000004" => "Oldham", + "E08000005" => "Rochdale", + "E08000006" => "Salford", + "E08000007" => "Stockport", + "E08000008" => "Tameside", + "E08000009" => "Trafford", + "E08000010" => "Wigan", + "E08000011" => "Knowsley", + "E08000012" => "Liverpool", + "E08000013" => "St. Helens", + "E08000014" => "Sefton", + "E08000015" => "Wirral", + "E08000016" => "Barnsley", + "E08000017" => "Doncaster", + "E08000018" => "Rotherham", + "E08000019" => "Sheffield", + "E08000021" => "Newcastle upon Tyne", + "E08000022" => "North Tyneside", + "E08000023" => "South Tyneside", + "E08000024" => "Sunderland", + "E08000025" => "Birmingham", + "E08000026" => "Coventry", + "E08000027" => "Dudley", + "E08000028" => "Sandwell", + "E08000029" => "Solihull", + "E06000066" => "Somerset", + "E08000030" => "Walsall", + "E08000031" => "Wolverhampton", + "E08000032" => "Bradford", + "E08000033" => "Calderdale", + "E08000034" => "Kirklees", + "E08000035" => "Leeds", + "E08000036" => "Wakefield", + "E08000037" => "Gateshead", + "E09000001" => "City of London", + "E09000002" => "Barking and Dagenham", + "E09000003" => "Barnet", + "E09000004" => "Bexley", + "E09000005" => "Brent", + "E09000006" => "Bromley", + "E09000007" => "Camden", + "E09000008" => "Croydon", + "E06000063" => "Cumberland", + "E09000009" => "Ealing", + "E09000010" => "Enfield", + "E09000011" => "Greenwich", + "E09000012" => "Hackney", + "E09000013" => "Hammersmith and Fulham", + "E09000014" => "Haringey", + "E09000015" => "Harrow", + "E09000016" => "Havering", + "E09000017" => "Hillingdon", + "E09000018" => "Hounslow", + "E09000019" => "Islington", + "E09000020" => "Kensington and Chelsea", + "E09000021" => "Kingston upon Thames", + "E09000022" => "Lambeth", + "E09000023" => "Lewisham", + "E09000024" => "Merton", + "E09000025" => "Newham", + "E09000026" => "Redbridge", + "E09000027" => "Richmond upon Thames", + "E09000028" => "Southwark", + "E09000029" => "Sutton", + "E09000030" => "Tower Hamlets", + "E09000031" => "Waltham Forest", + "E09000032" => "Wandsworth", + "E09000033" => "Westminster", + "E06000064" => "Westmorland and Furness", + "E06000065" => "North Yorkshire", + }) + end + end + + describe "has the correct hidden_in_check_answers" do + context "when saledate.year before 2023" do + let(:log) { build(:sales_log, saledate: Time.zone.parse("2022-07-01")) } + + it "returns false" do + expect(question.hidden_in_check_answers?(log)).to eq(false) + end + end + + context "when saledate.year >= 2023" do + let(:log) { build(:sales_log, saledate: Time.zone.parse("2023-07-01")) } + + it "returns true" do + expect(question.hidden_in_check_answers?(log)).to eq(false) + end + end + + context "when saledate.year >= 2023 and la inferred" do + let(:log) { build(:sales_log, saledate: Time.zone.parse("2023-07-01")) } + + before do + allow(log).to receive(:is_la_inferred?).and_return(true) + end + + it "returns true" do + expect(question.hidden_in_check_answers?(log)).to eq(true) + end + end end end diff --git a/spec/models/form/sales/questions/purchase_price_spec.rb b/spec/models/form/sales/questions/purchase_price_spec.rb index ce0aaae9c..e9e7ee3c3 100644 --- a/spec/models/form/sales/questions/purchase_price_spec.rb +++ b/spec/models/form/sales/questions/purchase_price_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::PurchasePrice, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } + subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1) } let(:question_id) { nil } let(:question_definition) { nil } diff --git a/spec/models/form/sales/questions/staircase_owned_spec.rb b/spec/models/form/sales/questions/staircase_owned_spec.rb index cbd577784..8e78d540a 100644 --- a/spec/models/form/sales/questions/staircase_owned_spec.rb +++ b/spec/models/form/sales/questions/staircase_owned_spec.rb @@ -1,11 +1,12 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::StaircaseOwned, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } + subject(:question) { described_class.new(question_id, question_definition, page, joint_purchase:) } let(:question_id) { nil } let(:question_definition) { nil } let(:page) { instance_double(Form::Page) } + let(:joint_purchase) { false } it "has correct page" do expect(question.page).to eq(page) @@ -15,12 +16,26 @@ RSpec.describe Form::Sales::Questions::StaircaseOwned, type: :model do expect(question.id).to eq("stairowned") end - it "has the correct header" do - expect(question.header).to eq("What percentage of the property does the buyer now own in total?") + context "when a joint purchase" do + let(:joint_purchase) { true } + + it "has the correct header" do + expect(question.header).to eq("What percentage of the property do the buyers now own in total?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Percentage the buyers now own in total") + end end - it "has the correct check_answer_label" do - expect(question.check_answer_label).to eq("Percentage the buyer now owns in total") + context "when not a joint purchase" do + it "has the correct header" do + expect(question.header).to eq("What percentage of the property does the buyer now own in total?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Percentage the buyer now owns in total") + end end it "has the correct type" do diff --git a/spec/models/form/sales/questions/town_or_city_spec.rb b/spec/models/form/sales/questions/town_or_city_spec.rb new file mode 100644 index 000000000..d66315864 --- /dev/null +++ b/spec/models/form/sales/questions/town_or_city_spec.rb @@ -0,0 +1,49 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::TownOrCity, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("town_or_city") + end + + it "has the correct header" do + expect(question.header).to eq("Town or city") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to be_nil + end + + it "has the correct type" do + expect(question.type).to eq("text") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint" do + expect(question.hint_text).to be_nil + end + + it "has the correct inferred check answers value" do + expect(question.inferred_check_answers_value).to be_nil + end + + it "has the correct check_answers_card_number" do + expect(question.check_answers_card_number).to be_nil + end + + it "has the correct hidden_in_check_answers" do + expect(question.hidden_in_check_answers?).to eq(true) + end +end diff --git a/spec/models/form/sales/questions/uprn_confirmation_spec.rb b/spec/models/form/sales/questions/uprn_confirmation_spec.rb new file mode 100644 index 000000000..60111cc42 --- /dev/null +++ b/spec/models/form/sales/questions/uprn_confirmation_spec.rb @@ -0,0 +1,90 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::UprnConfirmation, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("uprn_confirmed") + end + + it "has the correct header" do + expect(question.header).to eq("Is this the property address?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Is this the right address?") + end + + it "has the correct type" do + expect(question.type).to eq("radio") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint" do + expect(question.hint_text).to be_nil + end + + it "has the correct unanswered_error_message" do + expect(question.unanswered_error_message).to eq("You must answer is this the right address?") + end + + describe "notification_banner" do + context "when address is not present" do + it "returns nil" do + log = create(:sales_log) + + expect(question.notification_banner(log)).to be_nil + end + end + + context "when address is present" do + it "returns formatted value" do + log = create(:sales_log, address_line1: "1, Test Street", town_or_city: "Test Town", county: "Test County", postcode_full: "AA1 1AA", uprn: "1234") + + expect(question.notification_banner(log)).to eq( + { + heading: "1, Test Street\nAA1 1AA\nTest Town\nTest County", + title: "UPRN: 1234", + }, + ) + end + end + end + + describe "has the correct hidden_in_check_answers" do + context "when uprn_known != 1 && uprn_confirmed == nil" do + let(:log) { create(:sales_log, uprn_known: 0, uprn_confirmed: nil) } + + it "returns true" do + expect(question.hidden_in_check_answers?(log)).to eq(true) + end + end + + context "when uprn_known == 1 && uprn_confirmed == nil" do + let(:log) { create(:sales_log, uprn_known: 1, uprn_confirmed: nil) } + + it "returns false" do + expect(question.hidden_in_check_answers?(log)).to eq(false) + end + end + + context "when uprn_known != 1 && uprn_confirmed == 1" do + let(:log) { create(:sales_log, uprn_known: 1, uprn_confirmed: 1) } + + it "returns true" do + expect(question.hidden_in_check_answers?(log)).to eq(true) + end + end + end +end diff --git a/spec/models/form/sales/questions/uprn_known_spec.rb b/spec/models/form/sales/questions/uprn_known_spec.rb new file mode 100644 index 000000000..528e60a1f --- /dev/null +++ b/spec/models/form/sales/questions/uprn_known_spec.rb @@ -0,0 +1,59 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::UprnKnown, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("uprn_known") + end + + it "has the correct header" do + expect(question.header).to eq("Do you know the property UPRN?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("UPRN known?") + end + + it "has the correct type" do + expect(question.type).to eq("radio") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "0" => { "value" => "No" }, + "1" => { "value" => "Yes" }, + }) + end + + it "has correct conditional for" do + expect(question.conditional_for).to be_nil + end + + it "has the correct unanswered_error_message" do + expect(question.unanswered_error_message).to eq("You must answer UPRN known?") + end + + it "has the correct hint" do + expect(question.hint_text).to eq( + "The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355.

+ You can continue without the UPRN, but it means we will need you to enter the address of the property.", + ) + end + + it "has the correct hidden_in_check_answers" do + expect(question.hidden_in_check_answers).to be_nil + end +end diff --git a/spec/models/form/sales/questions/uprn_spec.rb b/spec/models/form/sales/questions/uprn_spec.rb new file mode 100644 index 000000000..2f42c1cdd --- /dev/null +++ b/spec/models/form/sales/questions/uprn_spec.rb @@ -0,0 +1,88 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::Uprn, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("uprn") + end + + it "has the correct header" do + expect(question.header).to eq("What is the property's UPRN") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("UPRN") + end + + it "has the correct type" do + expect(question.type).to eq("text") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint" do + expect(question.hint_text).to eq("The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355.") + end + + it "has the correct unanswered_error_message" do + expect(question.unanswered_error_message).to eq("UPRN must be 12 digits or less") + end + + describe "get_extra_check_answer_value" do + context "when address is not present" do + let(:log) { create(:sales_log) } + + it "returns nil" do + expect(question.get_extra_check_answer_value(log)).to be_nil + end + end + + context "when address is present" do + let(:log) do + create( + :sales_log, + address_line1: "1, Test Street", + town_or_city: "Test Town", + county: "Test County", + postcode_full: "AA1 1AA", + la: "E09000003", + ) + end + + it "returns formatted value" do + expect(question.get_extra_check_answer_value(log)).to eq( + "\n\n1, Test Street\nTest Town\nTest County\nAA1 1AA\nWestminster", + ) + end + end + end + + describe "has the correct hidden_in_check_answers" do + context "when uprn_known == 1" do + let(:log) { create(:sales_log, uprn_known: 1) } + + it "returns false" do + expect(question.hidden_in_check_answers?(log)).to eq(false) + end + end + + context "when uprn_known != 1" do + let(:log) { create(:sales_log, uprn_known: 0) } + + it "returns false" do + expect(question.hidden_in_check_answers?(log)).to eq(true) + end + end + end +end diff --git a/spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb b/spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb index 5d1d30037..b6947661d 100644 --- a/spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb +++ b/spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb @@ -19,7 +19,7 @@ RSpec.describe Form::Sales::Subsections::DiscountedOwnershipScheme, type: :model extra_borrowing_price_value_check about_price_not_rtb grant_value_check - purchase_price_outright_ownership + purchase_price_discounted_ownership about_price_discounted_ownership_value_check discounted_ownership_deposit_and_mortgage_value_check_after_value_and_discount mortgage_used_discounted_ownership diff --git a/spec/models/form/sales/subsections/household_characteristics_spec.rb b/spec/models/form/sales/subsections/household_characteristics_spec.rb index 4645b7231..57a9ce019 100644 --- a/spec/models/form/sales/subsections/household_characteristics_spec.rb +++ b/spec/models/form/sales/subsections/household_characteristics_spec.rb @@ -40,57 +40,75 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model working_situation_buyer_1_income_value_check buyer_1_live_in_property buyer_2_relationship_to_buyer_1 + buyer_2_relationship_student_not_child_value_check buyer_2_age age_2_old_persons_shared_ownership_value_check age_2_buyer_retirement_value_check + buyer_2_age_student_not_child_value_check buyer_2_gender_identity gender_2_buyer_retirement_value_check buyer_2_working_situation working_situation_2_retirement_value_check_joint_purchase working_situation_buyer_2_income_value_check + buyer_2_working_situation_student_not_child_value_check buyer_2_live_in_property number_of_others_in_property number_of_others_in_property_joint_purchase person_2_known person_2_relationship_to_buyer_1 + relationship_2_student_not_child_value_check person_2_age age_2_retirement_value_check + age_2_student_not_child_value_check person_2_gender_identity gender_2_retirement_value_check person_2_working_situation working_situation_2_retirement_value_check + working_situation_2_student_not_child_value_check person_3_known person_3_relationship_to_buyer_1 + relationship_3_student_not_child_value_check person_3_age age_3_retirement_value_check + age_3_student_not_child_value_check person_3_gender_identity gender_3_retirement_value_check person_3_working_situation working_situation_3_retirement_value_check + working_situation_3_student_not_child_value_check person_4_known person_4_relationship_to_buyer_1 + relationship_4_student_not_child_value_check person_4_age age_4_retirement_value_check + age_4_student_not_child_value_check person_4_gender_identity gender_4_retirement_value_check person_4_working_situation working_situation_4_retirement_value_check + working_situation_4_student_not_child_value_check person_5_known person_5_relationship_to_buyer_1 + relationship_5_student_not_child_value_check person_5_age age_5_retirement_value_check + age_5_student_not_child_value_check person_5_gender_identity gender_5_retirement_value_check person_5_working_situation working_situation_5_retirement_value_check + working_situation_5_student_not_child_value_check person_6_known person_6_relationship_to_buyer_1 + relationship_6_student_not_child_value_check person_6_age age_6_retirement_value_check + age_6_student_not_child_value_check person_6_gender_identity gender_6_retirement_value_check person_6_working_situation working_situation_6_retirement_value_check + working_situation_6_student_not_child_value_check ], ) end @@ -124,9 +142,11 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model working_situation_buyer_1_income_value_check buyer_1_live_in_property buyer_2_relationship_to_buyer_1 + buyer_2_relationship_student_not_child_value_check buyer_2_age age_2_old_persons_shared_ownership_value_check age_2_buyer_retirement_value_check + buyer_2_age_student_not_child_value_check buyer_2_gender_identity gender_2_buyer_retirement_value_check buyer_2_ethnic_group @@ -135,52 +155,69 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model buyer_2_ethnic_background_arab buyer_2_ethnic_background_mixed buyer_2_ethnic_background_white + buyer_2_nationality buyer_2_working_situation working_situation_2_retirement_value_check_joint_purchase working_situation_buyer_2_income_value_check + buyer_2_working_situation_student_not_child_value_check buyer_2_live_in_property number_of_others_in_property number_of_others_in_property_joint_purchase person_2_known person_2_relationship_to_buyer_1 + relationship_2_student_not_child_value_check person_2_age age_2_retirement_value_check + age_2_student_not_child_value_check person_2_gender_identity gender_2_retirement_value_check person_2_working_situation working_situation_2_retirement_value_check + working_situation_2_student_not_child_value_check person_3_known person_3_relationship_to_buyer_1 + relationship_3_student_not_child_value_check person_3_age age_3_retirement_value_check + age_3_student_not_child_value_check person_3_gender_identity gender_3_retirement_value_check person_3_working_situation working_situation_3_retirement_value_check + working_situation_3_student_not_child_value_check person_4_known person_4_relationship_to_buyer_1 + relationship_4_student_not_child_value_check person_4_age age_4_retirement_value_check + age_4_student_not_child_value_check person_4_gender_identity gender_4_retirement_value_check person_4_working_situation working_situation_4_retirement_value_check + working_situation_4_student_not_child_value_check person_5_known person_5_relationship_to_buyer_1 + relationship_5_student_not_child_value_check person_5_age age_5_retirement_value_check + age_5_student_not_child_value_check person_5_gender_identity gender_5_retirement_value_check person_5_working_situation working_situation_5_retirement_value_check + working_situation_5_student_not_child_value_check person_6_known person_6_relationship_to_buyer_1 + relationship_6_student_not_child_value_check person_6_age age_6_retirement_value_check + age_6_student_not_child_value_check person_6_gender_identity gender_6_retirement_value_check person_6_working_situation working_situation_6_retirement_value_check + working_situation_6_student_not_child_value_check ], ) end @@ -195,6 +232,22 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model end it "has correct depends on" do - expect(household_characteristics.depends_on).to eq([{ "setup_completed?" => true }]) + expect(household_characteristics.depends_on).to eq([{ "setup_completed?" => true, "company_buyer?" => false }]) + end + + context "when the sale is to a company buyer" do + let(:log) { FactoryBot.create(:sales_log, ownershipsch: 3, companybuy: 1) } + + it "is not displayed in tasklist" do + expect(household_characteristics.displayed_in_tasklist?(log)).to eq(false) + end + end + + context "when the sale is not to a company buyer" do + let(:log) { FactoryBot.create(:sales_log, ownershipsch: 3, companybuy: 2) } + + it "is displayed in tasklist" do + expect(household_characteristics.displayed_in_tasklist?(log)).to eq(true) + end end end diff --git a/spec/models/form/sales/subsections/household_situation_spec.rb b/spec/models/form/sales/subsections/household_situation_spec.rb index e88dda99f..10898b27c 100644 --- a/spec/models/form/sales/subsections/household_situation_spec.rb +++ b/spec/models/form/sales/subsections/household_situation_spec.rb @@ -1,25 +1,44 @@ require "rails_helper" RSpec.describe Form::Sales::Subsections::HouseholdSituation, type: :model do - subject(:household_characteristics) { described_class.new(subsection_id, subsection_definition, section) } + subject(:household_characteristics) { described_class.new(nil, nil, section) } - let(:subsection_id) { nil } - let(:subsection_definition) { nil } - let(:section) { instance_double(Form::Sales::Sections::Household) } + let(:start_date) { Time.utc(2023, 4, 1) } + let(:form) { instance_double(Form, start_date:) } + let(:section) { instance_double(Form::Sales::Sections::Household, form:) } it "has correct section" do expect(household_characteristics.section).to eq(section) end - it "has correct pages" do - expect(household_characteristics.pages.map(&:id)).to eq( - %w[ - buyer1_previous_tenure - last_accommodation - last_accommodation_la - buyers_organisations - ], - ) + context "when the log belongs to the 22/23 collection" do + let(:start_date) { Time.utc(2022, 4, 1) } + + it "has correct pages" do + expect(household_characteristics.pages.map(&:id)).to eq( + %w[ + buyer1_previous_tenure + last_accommodation + last_accommodation_la + buyers_organisations + ], + ) + end + end + + context "when the log belongs to the 23/24 collection" do + it "has correct pages" do + expect(household_characteristics.pages.map(&:id)).to eq( + %w[ + buyer1_previous_tenure + last_accommodation + last_accommodation_la + buyers_organisations + buyer_2_living_in + buyer_2_previous_housing_situation + ], + ) + end end it "has the correct id" do diff --git a/spec/models/form/sales/subsections/income_benefits_and_savings_spec.rb b/spec/models/form/sales/subsections/income_benefits_and_savings_spec.rb index 6c0997fd2..aef451878 100644 --- a/spec/models/form/sales/subsections/income_benefits_and_savings_spec.rb +++ b/spec/models/form/sales/subsections/income_benefits_and_savings_spec.rb @@ -35,7 +35,8 @@ RSpec.describe Form::Sales::Subsections::IncomeBenefitsAndSavings, type: :model savings savings_value_check savings_deposit_value_check - previous_ownership + previous_ownership_joint_purchase + previous_ownership_not_joint_purchase ], ) end @@ -62,7 +63,8 @@ RSpec.describe Form::Sales::Subsections::IncomeBenefitsAndSavings, type: :model savings savings_value_check savings_deposit_value_check - previous_ownership + previous_ownership_joint_purchase + previous_ownership_not_joint_purchase previous_shared ], ) diff --git a/spec/models/form/sales/subsections/property_information_spec.rb b/spec/models/form/sales/subsections/property_information_spec.rb index e65e8dd36..1c049ea97 100644 --- a/spec/models/form/sales/subsections/property_information_spec.rb +++ b/spec/models/form/sales/subsections/property_information_spec.rb @@ -11,20 +11,51 @@ RSpec.describe Form::Sales::Subsections::PropertyInformation, type: :model do expect(property_information.section).to eq(section) end - it "has correct pages" do - expect(property_information.pages.map(&:id)).to eq( - %w[ - property_number_of_bedrooms - about_price_bedrooms_value_check - property_unit_type - monthly_charges_property_type_value_check - property_building_type - property_postcode - property_local_authority - about_price_la_value_check - property_wheelchair_accessible - ], - ) + describe "pages" do + let(:section) { instance_double(Form::Sales::Sections::Household, form: instance_double(Form, start_date:)) } + + context "when 2022" do + let(:start_date) { Time.utc(2022, 2, 8) } + + it "has correct pages" do + expect(property_information.pages.compact.map(&:id)).to eq( + %w[ + property_number_of_bedrooms + about_price_bedrooms_value_check + property_unit_type + monthly_charges_property_type_value_check + property_building_type + property_postcode + property_local_authority + about_price_la_value_check + property_wheelchair_accessible + ], + ) + end + end + + context "when 2023" do + let(:start_date) { Time.utc(2023, 2, 8) } + + it "has correct pages" do + expect(property_information.pages.map(&:id)).to eq( + %w[ + uprn_known + uprn + uprn_confirmation + address + property_local_authority + property_number_of_bedrooms + about_price_bedrooms_value_check + property_unit_type + monthly_charges_property_type_value_check + property_building_type + about_price_la_value_check + property_wheelchair_accessible + ], + ) + end + end end it "has the correct id" do diff --git a/spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb b/spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb index ee9f624aa..3c189f93f 100644 --- a/spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb +++ b/spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb @@ -16,14 +16,16 @@ RSpec.describe Form::Sales::Subsections::SharedOwnershipScheme, type: :model do %w[ living_before_purchase_shared_ownership staircasing - about_staircasing + about_staircasing_joint_purchase + about_staircasing_not_joint_purchase staircase_bought_value_check resale exchange_contracts handover_date handover_date_check la_nominations - buyer_previous + buyer_previous_joint_purchase + buyer_previous_not_joint_purchase previous_bedrooms previous_property_type shared_ownership_previous_tenure diff --git a/spec/models/form/subsection_spec.rb b/spec/models/form/subsection_spec.rb index 46880a33a..3e224dd38 100644 --- a/spec/models/form/subsection_spec.rb +++ b/spec/models/form/subsection_spec.rb @@ -4,6 +4,15 @@ require_relative "../../request_helper" RSpec.describe Form::Subsection, type: :model do subject(:subsection) { described_class.new(subsection_id, subsection_definition, section) } + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + let(:lettings_log) { FactoryBot.build(:lettings_log) } let(:form) { lettings_log.form } let(:section_id) { "household" } diff --git a/spec/models/form_handler_spec.rb b/spec/models/form_handler_spec.rb index a6b5b181a..417da6639 100644 --- a/spec/models/form_handler_spec.rb +++ b/spec/models/form_handler_spec.rb @@ -9,6 +9,7 @@ RSpec.describe FormHandler do Singleton.__init__(described_class) example.run end + Timecop.return Singleton.__init__(described_class) end diff --git a/spec/models/form_spec.rb b/spec/models/form_spec.rb index cd58587dc..cac779e33 100644 --- a/spec/models/form_spec.rb +++ b/spec/models/form_spec.rb @@ -1,6 +1,15 @@ require "rails_helper" RSpec.describe Form, type: :model do + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + let(:user) { FactoryBot.build(:user) } let(:lettings_log) { FactoryBot.build(:lettings_log, :in_progress) } let(:form) { lettings_log.form } diff --git a/spec/models/forms/bulk_upload_lettings/year_spec.rb b/spec/models/forms/bulk_upload_lettings/year_spec.rb index 0b0babb30..ebb65e517 100644 --- a/spec/models/forms/bulk_upload_lettings/year_spec.rb +++ b/spec/models/forms/bulk_upload_lettings/year_spec.rb @@ -5,8 +5,8 @@ RSpec.describe Forms::BulkUploadLettings::Year do describe "#options" do it "returns correct years" do - expect(form.options.map(&:id)).to eql([2022, 2021]) - expect(form.options.map(&:name)).to eql(%w[2022/2023 2021/2022]) + expect(form.options.map(&:id)).to eql([2023, 2022]) + expect(form.options.map(&:name)).to eql(%w[2023/2024 2022/2023]) end end end diff --git a/spec/models/lettings_log_spec.rb b/spec/models/lettings_log_spec.rb index c1bfafb57..57b5de21a 100644 --- a/spec/models/lettings_log_spec.rb +++ b/spec/models/lettings_log_spec.rb @@ -2,10 +2,20 @@ require "rails_helper" require "shared/shared_examples_for_derived_fields" RSpec.describe LettingsLog do - let(:different_managing_organisation) { FactoryBot.create(:organisation) } - let(:created_by_user) { FactoryBot.create(:user) } + let(:different_managing_organisation) { create(:organisation) } + let(:created_by_user) { create(:user) } let(:owning_organisation) { created_by_user.organisation } let(:fake_2021_2022_form) { Form.new("spec/fixtures/forms/2021_2022.json") } + let(:fake_2022_2023_form) { Form.new("spec/fixtures/forms/2022_2023.json") } + + around do |example| + Timecop.freeze(Time.utc(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end before do allow(FormHandler.instance).to receive(:current_lettings_form).and_return(fake_2021_2022_form) @@ -19,21 +29,29 @@ RSpec.describe LettingsLog do end it "is a not a sales log" do - lettings_log = FactoryBot.build(:lettings_log, created_by: created_by_user) + lettings_log = build(:lettings_log, created_by: created_by_user) expect(lettings_log.sales?).to be false end it "is a lettings log" do - lettings_log = FactoryBot.build(:lettings_log, created_by: created_by_user) + lettings_log = build(:lettings_log, created_by: created_by_user) expect(lettings_log).to be_lettings end describe "#form" do - let(:lettings_log) { FactoryBot.build(:lettings_log, created_by: created_by_user) } - let(:lettings_log_2) { FactoryBot.build(:lettings_log, startdate: Time.zone.local(2022, 1, 1), created_by: created_by_user) } - let(:lettings_log_year_2) { FactoryBot.build(:lettings_log, startdate: Time.zone.local(2023, 5, 1), created_by: created_by_user) } + let(:lettings_log) { build(:lettings_log, created_by: created_by_user) } + let(:lettings_log_2) { build(:lettings_log, startdate: Time.zone.local(2022, 1, 1), created_by: created_by_user) } + let(:lettings_log_year_2) { build(:lettings_log, startdate: Time.zone.local(2023, 5, 1), created_by: created_by_user) } + + before do + Timecop.freeze(2023, 1, 1) + end + + after do + Timecop.unfreeze + end - it "has returns the correct form based on the start date" do + it "returns the correct form based on the start date" do expect(lettings_log.form_name).to be_nil expect(lettings_log.form).to be_a(Form) expect(lettings_log_2.form_name).to eq("previous_lettings") @@ -43,7 +61,7 @@ RSpec.describe LettingsLog do end context "when a date outside the collection window is passed" do - let(:lettings_log) { FactoryBot.build(:lettings_log, startdate: Time.zone.local(2015, 1, 1), created_by: created_by_user) } + let(:lettings_log) { build(:lettings_log, startdate: Time.zone.local(2015, 1, 1), created_by: created_by_user) } it "returns the first form" do expect(lettings_log.form).to be_a(Form) @@ -70,7 +88,7 @@ RSpec.describe LettingsLog do end describe "#update" do - let(:lettings_log) { FactoryBot.create(:lettings_log, created_by: created_by_user) } + let(:lettings_log) { create(:lettings_log, created_by: created_by_user) } let(:validator) { lettings_log._validators[nil].first } after do @@ -168,9 +186,9 @@ RSpec.describe LettingsLog do end describe "status" do - let!(:empty_lettings_log) { FactoryBot.create(:lettings_log) } - let!(:in_progress_lettings_log) { FactoryBot.create(:lettings_log, :in_progress) } - let!(:completed_lettings_log) { FactoryBot.create(:lettings_log, :completed) } + let!(:empty_lettings_log) { create(:lettings_log) } + let!(:in_progress_lettings_log) { create(:lettings_log, :in_progress) } + let!(:completed_lettings_log) { create(:lettings_log, :completed) } it "is set to not started for an empty lettings log" do expect(empty_lettings_log.not_started?).to be(true) @@ -208,7 +226,7 @@ RSpec.describe LettingsLog do describe "weekly_net_income" do let(:net_income) { 5000 } - let(:lettings_log) { FactoryBot.build(:lettings_log, earnings: net_income) } + let(:lettings_log) { build(:lettings_log, earnings: net_income) } it "returns input income if frequency is already weekly" do lettings_log.incfreq = 1 @@ -1477,10 +1495,15 @@ RSpec.describe LettingsLog do context "when deriving renttype and unitletas" do before do + Timecop.freeze(Time.zone.local(2022, 1, 1)) allow(FeatureToggle).to receive(:startdate_two_week_validation_enabled?).and_return(false) lettings_log.update!(rent_type:, irproduct_other: "other") end + after do + Timecop.unfreeze + end + context "when the rent_type is Social Rent (0)" do let(:rent_type) { 0 } @@ -1497,6 +1520,23 @@ RSpec.describe LettingsLog do end context "and it is a 23/24 form" do + before do + Timecop.freeze(Time.zone.local(2023, 5, 1)) + end + + after do + Timecop.unfreeze + end + + around do |example| + Timecop.freeze(Time.zone.local(2023, 5, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + it "derives and saves unitletas as Social rent(1)" do lettings_log.update!(startdate: Time.zone.local(2023, 5, 1)) record_from_db = ActiveRecord::Base.connection.execute("select unitletas from lettings_logs where id=#{lettings_log.id}").to_a[0] @@ -1522,6 +1562,23 @@ RSpec.describe LettingsLog do end context "and it is a 23/24 form" do + before do + Timecop.freeze(Time.zone.local(2023, 5, 1)) + end + + after do + Timecop.unfreeze + end + + around do |example| + Timecop.freeze(Time.zone.local(2023, 5, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + it "derives and saves unitletas as Affordable Rent basis(2)" do lettings_log.update!(startdate: Time.zone.local(2023, 5, 1)) record_from_db = ActiveRecord::Base.connection.execute("select unitletas from lettings_logs where id=#{lettings_log.id}").to_a[0] @@ -1547,6 +1604,23 @@ RSpec.describe LettingsLog do end context "and it is a 23/24 form" do + before do + Timecop.freeze(Time.zone.local(2023, 5, 1)) + end + + after do + Timecop.unfreeze + end + + around do |example| + Timecop.freeze(Time.zone.local(2023, 5, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + it "derives and saves unitletas as London Affordable Rent basis(5)" do lettings_log.update!(startdate: Time.zone.local(2023, 5, 1)) record_from_db = ActiveRecord::Base.connection.execute("select unitletas from lettings_logs where id=#{lettings_log.id}").to_a[0] @@ -1572,6 +1646,23 @@ RSpec.describe LettingsLog do end context "and it is a 23/24 form" do + before do + Timecop.freeze(Time.zone.local(2023, 5, 1)) + end + + after do + Timecop.unfreeze + end + + around do |example| + Timecop.freeze(Time.zone.local(2023, 5, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + it "derives and saves unitletas as Rent to Buy basis(6)" do lettings_log.update!(startdate: Time.zone.local(2023, 5, 1)) record_from_db = ActiveRecord::Base.connection.execute("select unitletas from lettings_logs where id=#{lettings_log.id}").to_a[0] @@ -1597,6 +1688,23 @@ RSpec.describe LettingsLog do end context "and it is a 23/24 form" do + before do + Timecop.freeze(Time.zone.local(2023, 5, 1)) + end + + after do + Timecop.unfreeze + end + + around do |example| + Timecop.freeze(Time.zone.local(2023, 5, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + it "derives and saves unitletas as London Living Rent basis(7)" do lettings_log.update!(startdate: Time.zone.local(2023, 5, 1)) record_from_db = ActiveRecord::Base.connection.execute("select unitletas from lettings_logs where id=#{lettings_log.id}").to_a[0] @@ -1622,6 +1730,23 @@ RSpec.describe LettingsLog do end context "and it is a 23/24 form" do + before do + Timecop.freeze(Time.zone.local(2023, 5, 1)) + end + + after do + Timecop.unfreeze + end + + around do |example| + Timecop.freeze(Time.zone.local(2023, 5, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + it "derives and saves unitletas as Other intermediate rent basis(8)" do lettings_log.update!(startdate: Time.zone.local(2023, 5, 1)) record_from_db = ActiveRecord::Base.connection.execute("select unitletas from lettings_logs where id=#{lettings_log.id}").to_a[0] @@ -1860,21 +1985,72 @@ RSpec.describe LettingsLog do end context "and a scheme with a single log is selected" do - let(:scheme) { FactoryBot.create(:scheme) } - let!(:location) { FactoryBot.create(:location, scheme:) } + let(:scheme) { create(:scheme) } + let!(:location) { create(:location, scheme:) } - before { lettings_log.update!(startdate: Time.zone.local(2022, 4, 2), scheme:) } + before do + Timecop.freeze(Time.zone.local(2022, 4, 2)) + lettings_log.update!(startdate: Time.zone.local(2022, 4, 2), scheme:) + Timecop.unfreeze + end it "derives the scheme location" do record_from_db = ActiveRecord::Base.connection.execute("select location_id from lettings_logs where id=#{lettings_log.id}").to_a[0] expect(record_from_db["location_id"]).to eq(location.id) expect(lettings_log["location_id"]).to eq(location.id) end + + context "and the location has multiple local authorities for different years" do + before do + LocalAuthorityLink.create!(local_authority_id: LocalAuthority.find_by(code: "E07000030").id, linked_local_authority_id: LocalAuthority.find_by(code: "E06000063").id) + location.update!(location_code: "E07000030") + Timecop.freeze(startdate) + Singleton.__init__(FormHandler) + lettings_log.update!(startdate:) + lettings_log.reload + end + + after do + Timecop.unfreeze + Singleton.__init__(FormHandler) + end + + context "with 22/23" do + let(:startdate) { Time.zone.local(2022, 4, 2) } + + it "returns the correct la" do + expect(lettings_log["location_id"]).to eq(location.id) + expect(lettings_log.la).to eq("E07000030") + end + end + + context "with 23/24" do + let(:startdate) { Time.zone.local(2023, 4, 2) } + + it "returns the correct la" do + expect(lettings_log["location_id"]).to eq(location.id) + expect(lettings_log.la).to eq("E06000063") + end + end + end + + context "and the location no local authorities associated with the location_code" do + before do + location.update!(location_code: "E01231231") + lettings_log.update!(location:) + end + + it "returns the correct la" do + expect(location.location_code).to eq("E01231231") + expect(lettings_log["location_id"]).to eq(location.id) + expect(lettings_log.la).to eq("E01231231") + end + end end context "and not renewal" do - let(:scheme) { FactoryBot.create(:scheme) } - let(:location) { FactoryBot.create(:location, scheme:, postcode: "M11AE", type_of_unit: 1, mobility_type: "W") } + let(:scheme) { create(:scheme) } + let(:location) { create(:location, scheme:, postcode: "M11AE", type_of_unit: 1, mobility_type: "W") } let(:supported_housing_lettings_log) do described_class.create!({ @@ -1916,9 +2092,16 @@ RSpec.describe LettingsLog do end context "and renewal" do - let(:scheme) { FactoryBot.create(:scheme) } - let(:location) { FactoryBot.create(:location, scheme:) } + before do + Timecop.freeze(Time.zone.local(2022, 4, 2)) + end + + after do + Timecop.unfreeze + end + let(:scheme) { create(:scheme) } + let(:location) { create(:location, scheme:) } let!(:supported_housing_lettings_log) do described_class.create!({ managing_organisation: owning_organisation, @@ -1928,12 +2111,12 @@ RSpec.describe LettingsLog do scheme_id: scheme.id, location_id: location.id, renewal: 1, - startdate: Time.zone.now, + startdate: Time.zone.local(2022, 4, 2), created_at: Time.utc(2022, 2, 8, 16, 52, 15), }) end - it "correcly infers and saves the renewal date" do + it "correctly infers and saves the renewal date" do record_from_db = ActiveRecord::Base.connection.execute("SELECT voiddate from lettings_logs where id=#{supported_housing_lettings_log.id}").to_a[0] expect(record_from_db["voiddate"].to_i).to eq(supported_housing_lettings_log.startdate.to_i) end @@ -2035,7 +2218,7 @@ RSpec.describe LettingsLog do end describe "optional fields" do - let(:lettings_log) { FactoryBot.create(:lettings_log) } + let(:lettings_log) { create(:lettings_log) } context "when tshortfall is marked as not known" do it "makes tshortfall optional" do @@ -2043,13 +2226,42 @@ RSpec.describe LettingsLog do expect(lettings_log.optional_fields).to include("tshortfall") end end + + context "when saledate is before 2023" do + let(:lettings_log) { build(:lettings_log, startdate: Time.zone.parse("2022-07-01")) } + + it "returns optional fields" do + expect(lettings_log.optional_fields).to eq(%w[ + first_time_property_let_as_social_housing + tenancycode + propcode + tenancylength + ]) + end + end + + context "when saledate is after 2023" do + let(:lettings_log) { build(:lettings_log, startdate: Time.zone.parse("2023-07-01")) } + + it "returns optional fields" do + expect(lettings_log.optional_fields).to eq(%w[ + first_time_property_let_as_social_housing + tenancycode + propcode + tenancylength + address_line2 + county + postcode_full + ]) + end + end end describe "resetting invalidated fields" do - let(:scheme) { FactoryBot.create(:scheme, owning_organisation: created_by_user.organisation) } - let(:location) { FactoryBot.create(:location, location_code: "E07000223", scheme:) } + let(:scheme) { create(:scheme, owning_organisation: created_by_user.organisation) } + let(:location) { create(:location, location_code: "E07000223", scheme:) } let(:lettings_log) do - FactoryBot.create( + create( :lettings_log, renewal: 0, rsnvac: 5, @@ -2084,14 +2296,14 @@ RSpec.describe LettingsLog do end context "when a question that has already been answered, no longer has met dependencies" do - let(:lettings_log) { FactoryBot.create(:lettings_log, :in_progress, cbl: 1, preg_occ: 2, wchair: 2) } + let(:lettings_log) { create(:lettings_log, :in_progress, cbl: 1, preg_occ: 2, wchair: 2) } it "clears the answer" do expect { lettings_log.update!(preg_occ: nil) }.to change(lettings_log, :cbl).from(1).to(nil) end context "when the question type does not have answer options" do - let(:lettings_log) { FactoryBot.create(:lettings_log, :in_progress, housingneeds_a: 1, age1: 19) } + let(:lettings_log) { create(:lettings_log, :in_progress, housingneeds_a: 1, age1: 19) } it "clears the answer" do expect { lettings_log.update!(housingneeds_a: 0) }.to change(lettings_log, :age1).from(19).to(nil) @@ -2099,7 +2311,7 @@ RSpec.describe LettingsLog do end context "when the question type has answer options" do - let(:lettings_log) { FactoryBot.create(:lettings_log, :in_progress, illness: 1, illness_type_1: 1) } + let(:lettings_log) { create(:lettings_log, :in_progress, illness: 1, illness_type_1: 1) } it "clears the answer" do expect { lettings_log.update!(illness: 2) }.to change(lettings_log, :illness_type_1).from(1).to(nil) @@ -2108,7 +2320,7 @@ RSpec.describe LettingsLog do end context "with two pages having the same question key, only one's dependency is met" do - let(:lettings_log) { FactoryBot.create(:lettings_log, :in_progress, cbl: 0, preg_occ: 2, wchair: 2) } + let(:lettings_log) { create(:lettings_log, :in_progress, cbl: 0, preg_occ: 2, wchair: 2) } it "does not clear the value for answers that apply to both pages" do expect(lettings_log.cbl).to eq(0) @@ -2123,7 +2335,7 @@ RSpec.describe LettingsLog do end context "when a non select question associated with several pages is routed to" do - let(:lettings_log) { FactoryBot.create(:lettings_log, :in_progress, period: 2, needstype: 1, renewal: 0) } + let(:lettings_log) { create(:lettings_log, :in_progress, period: 2, needstype: 1, renewal: 0) } it "does not clear the answer value" do lettings_log.update!({ unitletas: 1 }) @@ -2133,7 +2345,7 @@ RSpec.describe LettingsLog do end context "when the lettings log does not have a valid form set yet" do - let(:lettings_log) { FactoryBot.create(:lettings_log) } + let(:lettings_log) { create(:lettings_log) } it "does not throw an error" do expect { lettings_log.update(startdate: Time.zone.local(2015, 1, 1)) }.not_to raise_error @@ -2141,7 +2353,7 @@ RSpec.describe LettingsLog do end context "when it changes from a renewal to not a renewal" do - let(:lettings_log) { FactoryBot.create(:lettings_log) } + let(:lettings_log) { create(:lettings_log) } it "resets inferred waityear value" do lettings_log.update!({ renewal: 1 }) @@ -2173,8 +2385,8 @@ RSpec.describe LettingsLog do end context "when it changes from a supported housing to not a supported housing" do - let(:location) { FactoryBot.create(:location, mobility_type: "A", postcode: "SW1P 4DG") } - let(:lettings_log) { FactoryBot.create(:lettings_log, location:) } + let(:location) { create(:location, mobility_type: "A", postcode: "SW1P 4DG") } + let(:lettings_log) { create(:lettings_log, location:) } it "resets inferred wchair value" do lettings_log.update!({ needstype: 2 }) @@ -2203,7 +2415,7 @@ RSpec.describe LettingsLog do end context "when it is not a renewal" do - let(:lettings_log) { FactoryBot.create(:lettings_log) } + let(:lettings_log) { create(:lettings_log) } it "saves waityear value" do lettings_log.update!({ renewal: 0, waityear: 2 }) @@ -2215,13 +2427,13 @@ RSpec.describe LettingsLog do end context "when a support user changes the owning organisation of the log" do - let(:lettings_log) { FactoryBot.create(:lettings_log, created_by: created_by_user) } - let(:organisation_2) { FactoryBot.create(:organisation) } + let(:lettings_log) { create(:lettings_log, created_by: created_by_user) } + let(:organisation_2) { create(:organisation) } context "when the organisation selected doesn't match the scheme set" do - let(:scheme) { FactoryBot.create(:scheme, owning_organisation: created_by_user.organisation) } - let(:location) { FactoryBot.create(:location, scheme:) } - let(:lettings_log) { FactoryBot.create(:lettings_log, owning_organisation: nil, needstype: 2, scheme_id: scheme.id) } + let(:scheme) { create(:scheme, owning_organisation: created_by_user.organisation) } + let(:location) { create(:location, scheme:) } + let(:lettings_log) { create(:lettings_log, owning_organisation: nil, needstype: 2, scheme_id: scheme.id) } it "clears the scheme value" do lettings_log.update!(owning_organisation: organisation_2) @@ -2230,9 +2442,9 @@ RSpec.describe LettingsLog do end context "when the organisation selected still matches the scheme set" do - let(:scheme) { FactoryBot.create(:scheme, owning_organisation: organisation_2) } - let(:location) { FactoryBot.create(:location, scheme:) } - let(:lettings_log) { FactoryBot.create(:lettings_log, owning_organisation: nil, needstype: 2, scheme_id: scheme.id) } + let(:scheme) { create(:scheme, owning_organisation: organisation_2) } + let(:location) { create(:location, scheme:) } + let(:lettings_log) { create(:lettings_log, owning_organisation: nil, needstype: 2, scheme_id: scheme.id) } it "does not clear the scheme value" do lettings_log.update!(owning_organisation: organisation_2) @@ -2270,6 +2482,15 @@ RSpec.describe LettingsLog do end context "and the new location triggers the rent range validation" do + around do |example| + Timecop.freeze(Time.zone.local(2022, 4, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + it "clears rent values" do lettings_log.update!(location:, scheme:) lettings_log.reload @@ -2319,7 +2540,7 @@ RSpec.describe LettingsLog do describe "tshortfall_unknown?" do context "when tshortfall is nil" do - let(:lettings_log) { FactoryBot.create(:lettings_log, :in_progress, tshortfall_known: nil) } + let(:lettings_log) { create(:lettings_log, :in_progress, tshortfall_known: nil) } it "returns false" do expect(lettings_log.tshortfall_unknown?).to be false @@ -2327,7 +2548,7 @@ RSpec.describe LettingsLog do end context "when tshortfall is No" do - let(:lettings_log) { FactoryBot.create(:lettings_log, :in_progress, tshortfall_known: 1) } + let(:lettings_log) { create(:lettings_log, :in_progress, tshortfall_known: 1) } it "returns false" do expect(lettings_log.tshortfall_unknown?).to be true @@ -2335,7 +2556,7 @@ RSpec.describe LettingsLog do end context "when tshortfall is Yes" do - let(:lettings_log) { FactoryBot.create(:lettings_log, :in_progress, tshortfall_known: 0) } + let(:lettings_log) { create(:lettings_log, :in_progress, tshortfall_known: 0) } it "returns false" do expect(lettings_log.tshortfall_unknown?).to be false @@ -2344,7 +2565,7 @@ RSpec.describe LettingsLog do end describe "paper trail" do - let(:lettings_log) { FactoryBot.create(:lettings_log, :in_progress) } + let(:lettings_log) { create(:lettings_log, :in_progress) } it "creates a record of changes to a log" do expect { lettings_log.update!(age1: 64) }.to change(lettings_log.versions, :count).by(1) @@ -2357,7 +2578,7 @@ RSpec.describe LettingsLog do end describe "soft values for period" do - let(:lettings_log) { FactoryBot.create(:lettings_log) } + let(:lettings_log) { create(:lettings_log) } before do LaRentRange.create!( @@ -2404,12 +2625,12 @@ RSpec.describe LettingsLog do end describe "scopes" do - let!(:lettings_log_1) { FactoryBot.create(:lettings_log, :in_progress, startdate: Time.utc(2021, 5, 3), created_by: created_by_user) } - let!(:lettings_log_2) { FactoryBot.create(:lettings_log, :completed, startdate: Time.utc(2021, 5, 3), created_by: created_by_user) } + let!(:lettings_log_1) { create(:lettings_log, :in_progress, startdate: Time.utc(2021, 5, 3), mrcdate: Time.utc(2021, 5, 3), voiddate: Time.utc(2021, 5, 3), created_by: created_by_user) } + let!(:lettings_log_2) { create(:lettings_log, :completed, startdate: Time.utc(2021, 5, 3), mrcdate: Time.utc(2021, 5, 3), voiddate: Time.utc(2021, 5, 3), created_by: created_by_user) } before do Timecop.freeze(Time.utc(2022, 6, 3)) - FactoryBot.create(:lettings_log, startdate: Time.utc(2022, 6, 3)) + create(:lettings_log, startdate: Time.utc(2022, 6, 3)) end after do @@ -2417,10 +2638,10 @@ RSpec.describe LettingsLog do end context "when searching logs" do - let!(:lettings_log_to_search) { FactoryBot.create(:lettings_log, :completed) } + let!(:lettings_log_to_search) { create(:lettings_log, :completed) } before do - FactoryBot.create_list(:lettings_log, 5, :completed) + create_list(:lettings_log, 5, :completed) end describe "#filter_by_id" do @@ -2475,7 +2696,7 @@ RSpec.describe LettingsLog do end context "when lettings log is supported housing" do - let(:location) { FactoryBot.create(:location, postcode: "W6 0ST") } + let(:location) { create(:location, postcode: "W6 0ST") } before do lettings_log_to_search.update!(needstype: 2, location:) @@ -2515,7 +2736,7 @@ RSpec.describe LettingsLog do end context "when lettings log is supported housing" do - let(:location) { FactoryBot.create(:location, postcode: "W6 0ST") } + let(:location) { create(:location, postcode: "W6 0ST") } before do lettings_log_to_search.update!(needstype: 2, location:) @@ -2573,15 +2794,15 @@ RSpec.describe LettingsLog do end context "when filtering by organisation" do - let(:organisation_1) { FactoryBot.create(:organisation) } - let(:organisation_2) { FactoryBot.create(:organisation) } - let(:organisation_3) { FactoryBot.create(:organisation) } + let(:organisation_1) { create(:organisation) } + let(:organisation_2) { create(:organisation) } + let(:organisation_3) { create(:organisation) } before do - FactoryBot.create(:lettings_log, :in_progress, owning_organisation: organisation_1, managing_organisation: organisation_1, created_by: nil) - FactoryBot.create(:lettings_log, :completed, owning_organisation: organisation_1, managing_organisation: organisation_2, created_by: nil) - FactoryBot.create(:lettings_log, :completed, owning_organisation: organisation_2, managing_organisation: organisation_1, created_by: nil) - FactoryBot.create(:lettings_log, :completed, owning_organisation: organisation_2, managing_organisation: organisation_2, created_by: nil) + create(:lettings_log, :in_progress, owning_organisation: organisation_1, managing_organisation: organisation_1, created_by: nil) + create(:lettings_log, :completed, owning_organisation: organisation_1, managing_organisation: organisation_2, created_by: nil) + create(:lettings_log, :completed, owning_organisation: organisation_2, managing_organisation: organisation_1, created_by: nil) + create(:lettings_log, :completed, owning_organisation: organisation_2, managing_organisation: organisation_2, created_by: nil) end it "filters by given organisation" do @@ -2623,7 +2844,7 @@ RSpec.describe LettingsLog do describe "#retirement_age_for_person" do context "when a person gender is Male" do - let(:lettings_log) { FactoryBot.build(:lettings_log, sex1: "M") } + let(:lettings_log) { build(:lettings_log, sex1: "M") } it "returns the expected retirement age" do expect(lettings_log.retirement_age_for_person_1).to eq(67) @@ -2635,7 +2856,7 @@ RSpec.describe LettingsLog do end context "when a person gender is Female" do - let(:lettings_log) { FactoryBot.build(:lettings_log, sex2: "F") } + let(:lettings_log) { build(:lettings_log, sex2: "F") } it "returns the expected retirement age" do expect(lettings_log.retirement_age_for_person_2).to eq(60) @@ -2647,7 +2868,7 @@ RSpec.describe LettingsLog do end context "when a person gender is Non-Binary" do - let(:lettings_log) { FactoryBot.build(:lettings_log, sex3: "X") } + let(:lettings_log) { build(:lettings_log, sex3: "X") } it "returns the expected retirement age" do expect(lettings_log.retirement_age_for_person_3).to eq(67) @@ -2659,7 +2880,7 @@ RSpec.describe LettingsLog do end context "when the person gender is not set" do - let(:lettings_log) { FactoryBot.build(:lettings_log) } + let(:lettings_log) { build(:lettings_log) } it "returns nil" do expect(lettings_log.retirement_age_for_person_3).to be_nil @@ -2671,7 +2892,7 @@ RSpec.describe LettingsLog do end context "when a postcode contains unicode characters" do - let(:lettings_log) { FactoryBot.build(:lettings_log, postcode_full: "SR81LS\u00A0") } + let(:lettings_log) { build(:lettings_log, postcode_full: "SR81LS\u00A0") } it "triggers a validation error" do expect { lettings_log.save! }.to raise_error(ActiveRecord::RecordInvalid, /Enter a postcode in the correct format/) @@ -2680,45 +2901,90 @@ RSpec.describe LettingsLog do end describe "csv download" do - let(:scheme) { FactoryBot.create(:scheme) } - let(:location) { FactoryBot.create(:location, :export, scheme:, type_of_unit: 6, postcode: "SE11TE", startdate: Time.zone.local(2021, 10, 1)) } - let(:user) { FactoryBot.create(:user, organisation: location.scheme.owning_organisation) } + let(:scheme) { create(:scheme) } + let(:location) { create(:location, :export, scheme:, type_of_unit: 6, postcode: "SE11TE", startdate: Time.zone.local(2021, 10, 1)) } + let(:user) { create(:user, organisation: location.scheme.owning_organisation) } let(:expected_content) { csv_export_file.read } - before do - Timecop.freeze(Time.utc(2022, 6, 5)) - lettings_log = FactoryBot.create(:lettings_log, needstype: 2, scheme:, location:, owning_organisation: scheme.owning_organisation, created_by: user, rent_type: 2, startdate: Time.zone.local(2021, 10, 2)) - expected_content.sub!(/\{id\}/, lettings_log["id"].to_s) - expected_content.sub!(/\{scheme_code\}/, "S#{scheme['id']}") - expected_content.sub!(/\{scheme_service_name\}/, scheme["service_name"].to_s) - expected_content.sub!(/\{scheme_sensitive\}/, scheme["sensitive"].to_s) - expected_content.sub!(/\{scheme_primary_client_group\}/, scheme["primary_client_group"].to_s) - expected_content.sub!(/\{scheme_secondary_client_group\}/, scheme["secondary_client_group"].to_s) - expected_content.sub!(/\{scheme_support_type\}/, scheme["support_type"].to_s) - expected_content.sub!(/\{scheme_intended_stay\}/, scheme["intended_stay"].to_s) - expected_content.sub!(/\{location_code\}/, location["id"].to_s) - expected_content.sub!(/\{location_startdate\}/, location["startdate"].to_s) - expected_content.sub!(/\{scheme_id\}/, scheme["service_name"].to_s) - expected_content.sub!(/\{location_id\}/, location["id"].to_s) - end - after do Timecop.unfreeze end - context "with a support user" do - let(:csv_export_file) { File.open("spec/fixtures/files/lettings_logs_download.csv", "r:UTF-8") } + context "with values represented as human readable labels" do + before do + Timecop.freeze(Time.utc(2022, 6, 5)) + lettings_log = FactoryBot.create(:lettings_log, needstype: 2, scheme:, location:, owning_organisation: scheme.owning_organisation, created_by: user, rent_type: 2, startdate: Time.zone.local(2021, 10, 2), created_at: Time.zone.local(2022, 2, 8, 16, 52, 15), updated_at: Time.zone.local(2022, 2, 8, 16, 52, 15)) + expected_content.sub!(/\{id\}/, lettings_log["id"].to_s) + expected_content.sub!(/\{scheme_code\}/, "S#{scheme['id']}") + expected_content.sub!(/\{scheme_service_name\}/, scheme["service_name"].to_s) + expected_content.sub!(/\{scheme_sensitive\}/, scheme["sensitive"].to_s) + expected_content.sub!(/\{scheme_primary_client_group\}/, scheme["primary_client_group"].to_s) + expected_content.sub!(/\{scheme_secondary_client_group\}/, scheme["secondary_client_group"].to_s) + expected_content.sub!(/\{scheme_support_type\}/, scheme["support_type"].to_s) + expected_content.sub!(/\{scheme_intended_stay\}/, scheme["intended_stay"].to_s) + expected_content.sub!(/\{location_code\}/, location["id"].to_s) + expected_content.sub!(/\{location_startdate\}/, location["startdate"].to_s) + expected_content.sub!(/\{scheme_id\}/, scheme["service_name"].to_s) + expected_content.sub!(/\{location_id\}/, location["id"].to_s) + end - it "generates a correct csv from a lettings log" do - expect(described_class.to_csv).to eq(expected_content) + around do |example| + Timecop.freeze(Time.zone.local(2022, 6, 5)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + + context "with a support user" do + let(:csv_export_file) { File.open("spec/fixtures/files/lettings_logs_download.csv", "r:UTF-8") } + + it "generates a correct csv from a lettings log" do + expect(described_class.to_csv(codes_only_export: false)).to eq(expected_content) + end + end + + context "with a non support user" do + let(:csv_export_file) { File.open("spec/fixtures/files/lettings_logs_download_non_support.csv", "r:UTF-8") } + + it "generates a correct csv from a lettings log" do + expect(described_class.to_csv(user, codes_only_export: false)).to eq(expected_content) + end end end - context "with a non support user" do - let(:csv_export_file) { File.open("spec/fixtures/files/lettings_logs_download_non_support.csv", "r:UTF-8") } + context "with values represented as codes" do + before do + Timecop.freeze(Time.utc(2022, 6, 5)) + lettings_log = FactoryBot.create(:lettings_log, needstype: 2, scheme:, location:, owning_organisation: scheme.owning_organisation, created_by: user, rent_type: 2, startdate: Time.zone.local(2021, 10, 2), created_at: Time.zone.local(2022, 2, 8, 16, 52, 15), updated_at: Time.zone.local(2022, 2, 8, 16, 52, 15)) + expected_content.sub!(/\{id\}/, lettings_log["id"].to_s) + expected_content.sub!(/\{scheme_code\}/, "S#{scheme.id}") + expected_content.sub!(/\{scheme_service_name\}/, scheme.service_name.to_s) + expected_content.sub!(/\{scheme_sensitive\}/, scheme.sensitive_before_type_cast.to_s) + expected_content.sub!(/\{scheme_primary_client_group\}/, scheme.primary_client_group_before_type_cast.to_s) + expected_content.sub!(/\{scheme_secondary_client_group\}/, scheme.secondary_client_group_before_type_cast.to_s) + expected_content.sub!(/\{scheme_support_type\}/, scheme.support_type_before_type_cast.to_s) + expected_content.sub!(/\{scheme_intended_stay\}/, scheme.intended_stay_before_type_cast.to_s) + expected_content.sub!(/\{location_code\}/, location.id.to_s) + expected_content.sub!(/\{location_startdate\}/, location.startdate.to_s) + expected_content.sub!(/\{scheme_id\}/, scheme.service_name.to_s) + expected_content.sub!(/\{location_id\}/, location.id.to_s) + end + + let(:csv_export_file) { File.open("spec/fixtures/files/lettings_logs_download_codes_only.csv", "r:UTF-8") } + + around do |example| + Timecop.freeze(Time.zone.local(2022, 6, 5)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end it "generates a correct csv from a lettings log" do - expect(described_class.to_csv(user)).to eq(expected_content) + expect(described_class.to_csv(codes_only_export: true)).to eq(expected_content) end end end diff --git a/spec/models/location_spec.rb b/spec/models/location_spec.rb index 51509d765..eded7d1ee 100644 --- a/spec/models/location_spec.rb +++ b/spec/models/location_spec.rb @@ -1,12 +1,19 @@ require "rails_helper" RSpec.describe Location, type: :model do + before do + LocalAuthorityLink.create(local_authority_id: LocalAuthority.find_by(code: "E07000030").id, linked_local_authority_id: LocalAuthority.find_by(code: "E06000063").id) + end + describe "#new" do let(:location) { FactoryBot.build(:location) } before do stub_request(:get, /api.postcodes.io/) .to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\",\"codes\":{\"admin_district\": \"E08000003\"}}}", headers: {}) + + stub_request(:get, /api.postcodes.io\/postcodes\/CA101AA/) + .to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Eden","codes":{"admin_district":"E07000030"}}}', headers: {}) end it "belongs to an organisation" do @@ -18,6 +25,26 @@ RSpec.describe Location, type: :model do location.save! expect(location.location_code).to eq("E08000003") end + + it "infers and returns the list of local authorities" do + location.update!(postcode: "CA10 1AA") + expect(location.linked_local_authorities.count).to eq(2) + expect(location.linked_local_authorities.active(Time.zone.local(2022, 4, 1)).first.code).to eq("E07000030") + expect(location.linked_local_authorities.active(Time.zone.local(2023, 4, 1)).first.code).to eq("E06000063") + end + + context "when location_code is no in LocalAuthorities table" do + before do + stub_request(:get, /api.postcodes.io\/postcodes\/CA101AA/) + .to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Eden","codes":{"admin_district":"E01231231"}}}', headers: {}) + end + + it "defaults for location code for la" do + location.update!(postcode: "CA10 1AA") + expect(location.linked_local_authorities.count).to eq(0) + expect(location.location_code).to eq("E01231231") + end + end end describe "#postcode" do @@ -52,6 +79,657 @@ RSpec.describe Location, type: :model do end end + describe "#local_authorities_for_current_year" do + context "when the current collection year is 22/23" do + let(:today) { Time.zone.local(2022, 4, 1) } + + before do + Timecop.freeze(today) + end + + after do + Timecop.unfreeze + end + + it "returns a list of local authorities" do + expect(described_class.local_authorities_for_current_year).to eq({ + "E07000223" => "Adur", + "E07000026" => "Allerdale", + "E07000032" => "Amber Valley", + "E07000224" => "Arun", + "E07000170" => "Ashfield", + "E07000105" => "Ashford", + "E07000200" => "Babergh", + "E09000002" => "Barking and Dagenham", + "E09000003" => "Barnet", + "E08000016" => "Barnsley", + "E07000027" => "Barrow-in-Furness", + "E07000066" => "Basildon", + "E07000084" => "Basingstoke and Deane", + "E07000171" => "Bassetlaw", + "E06000022" => "Bath and North East Somerset", + "E06000055" => "Bedford", + "E09000004" => "Bexley", + "E08000025" => "Birmingham", + "E07000129" => "Blaby", + "E06000008" => "Blackburn with Darwen", + "E06000009" => "Blackpool", + "E07000033" => "Bolsover", + "E08000001" => "Bolton", + "E07000136" => "Boston", + "E06000058" => "Bournemouth, Christchurch and Poole", + "E06000036" => "Bracknell Forest", + "E08000032" => "Bradford", + "E07000067" => "Braintree", + "E07000143" => "Breckland", + "E09000005" => "Brent", + "E07000068" => "Brentwood", + "E06000043" => "Brighton and Hove", + "E06000023" => "Bristol, City of", + "E07000144" => "Broadland", + "E09000006" => "Bromley", + "E07000234" => "Bromsgrove", + "E07000095" => "Broxbourne", + "E07000172" => "Broxtowe", + "E06000060" => "Buckinghamshire", + "E07000117" => "Burnley", + "E08000002" => "Bury", + "E08000033" => "Calderdale", + "E07000008" => "Cambridge", + "E09000007" => "Camden", + "E07000192" => "Cannock Chase", + "E07000106" => "Canterbury", + "E07000028" => "Carlisle", + "E07000069" => "Castle Point", + "E06000056" => "Central Bedfordshire", + "E07000130" => "Charnwood", + "E07000070" => "Chelmsford", + "E07000078" => "Cheltenham", + "E07000177" => "Cherwell", + "E06000049" => "Cheshire East", + "E06000050" => "Cheshire West and Chester", + "E07000034" => "Chesterfield", + "E07000225" => "Chichester", + "E07000118" => "Chorley", + "E09000001" => "City of London", + "E07000071" => "Colchester", + "E07000029" => "Copeland", + "E07000150" => "Corby", + "E06000052" => "Cornwall", + "E07000079" => "Cotswold", + "E06000047" => "County Durham", + "E08000026" => "Coventry", + "E07000163" => "Craven", + "E07000226" => "Crawley", + "E09000008" => "Croydon", + "E07000096" => "Dacorum", + "E06000005" => "Darlington", + "E07000107" => "Dartford", + "E07000151" => "Daventry", + "E06000015" => "Derby", + "E07000035" => "Derbyshire Dales", + "E08000017" => "Doncaster", + "E06000059" => "Dorset", + "E07000108" => "Dover", + "E08000027" => "Dudley", + "E09000009" => "Ealing", + "E07000009" => "East Cambridgeshire", + "E07000040" => "East Devon", + "E07000085" => "East Hampshire", + "E07000242" => "East Hertfordshire", + "E07000137" => "East Lindsey", + "E07000152" => "East Northamptonshire", + "E06000011" => "East Riding of Yorkshire", + "E07000193" => "East Staffordshire", + "E07000244" => "East Suffolk", + "E07000061" => "Eastbourne", + "E07000086" => "Eastleigh", + "E07000030" => "Eden", + "E07000207" => "Elmbridge", + "E09000010" => "Enfield", + "E07000072" => "Epping Forest", + "E07000208" => "Epsom and Ewell", + "E07000036" => "Erewash", + "E07000041" => "Exeter", + "E07000087" => "Fareham", + "E07000010" => "Fenland", + "E07000112" => "Folkestone and Hythe", + "E07000080" => "Forest of Dean", + "E07000119" => "Fylde", + "E08000037" => "Gateshead", + "E07000173" => "Gedling", + "E07000081" => "Gloucester", + "E07000088" => "Gosport", + "E07000109" => "Gravesham", + "E07000145" => "Great Yarmouth", + "E09000011" => "Greenwich", + "E07000209" => "Guildford", + "E09000012" => "Hackney", + "E06000006" => "Halton", + "E07000164" => "Hambleton", + "E09000013" => "Hammersmith and Fulham", + "E07000131" => "Harborough", + "E09000014" => "Haringey", + "E07000073" => "Harlow", + "E07000165" => "Harrogate", + "E09000015" => "Harrow", + "E07000089" => "Hart", + "E06000001" => "Hartlepool", + "E07000062" => "Hastings", + "E07000090" => "Havant", + "E09000016" => "Havering", + "E06000019" => "Herefordshire, County of", + "E07000098" => "Hertsmere", + "E07000037" => "High Peak", + "E09000017" => "Hillingdon", + "E07000132" => "Hinckley and Bosworth", + "E07000227" => "Horsham", + "E09000018" => "Hounslow", + "E07000011" => "Huntingdonshire", + "E07000120" => "Hyndburn", + "E07000202" => "Ipswich", + "E06000046" => "Isle of Wight", + "E06000053" => "Isles of Scilly", + "E09000019" => "Islington", + "E09000020" => "Kensington and Chelsea", + "E07000153" => "Kettering", + "E07000146" => "King’s Lynn and West Norfolk", + "E06000010" => "Kingston upon Hull, City of", + "E09000021" => "Kingston upon Thames", + "E08000034" => "Kirklees", + "E08000011" => "Knowsley", + "E09000022" => "Lambeth", + "E07000121" => "Lancaster", + "E08000035" => "Leeds", + "E06000016" => "Leicester", + "E07000063" => "Lewes", + "E09000023" => "Lewisham", + "E07000194" => "Lichfield", + "E07000138" => "Lincoln", + "E08000012" => "Liverpool", + "E06000032" => "Luton", + "E07000110" => "Maidstone", + "E07000074" => "Maldon", + "E07000235" => "Malvern Hills", + "E08000003" => "Manchester", + "E07000174" => "Mansfield", + "E06000035" => "Medway", + "E07000133" => "Melton", + "E07000187" => "Mendip", + "E09000024" => "Merton", + "E07000042" => "Mid Devon", + "E07000203" => "Mid Suffolk", + "E07000228" => "Mid Sussex", + "E06000002" => "Middlesbrough", + "E06000042" => "Milton Keynes", + "E07000210" => "Mole Valley", + "E07000091" => "New Forest", + "E07000175" => "Newark and Sherwood", + "E08000021" => "Newcastle upon Tyne", + "E07000195" => "Newcastle-under-Lyme", + "E09000025" => "Newham", + "E07000043" => "North Devon", + "E07000038" => "North East Derbyshire", + "E06000012" => "North East Lincolnshire", + "E07000099" => "North Hertfordshire", + "E07000139" => "North Kesteven", + "E06000013" => "North Lincolnshire", + "E07000147" => "North Norfolk", + "E06000024" => "North Somerset", + "E08000022" => "North Tyneside", + "E07000218" => "North Warwickshire", + "E07000134" => "North West Leicestershire", + "E07000154" => "Northampton", + "E06000057" => "Northumberland", + "E07000148" => "Norwich", + "E06000018" => "Nottingham", + "E07000219" => "Nuneaton and Bedworth", + "E07000135" => "Oadby and Wigston", + "E08000004" => "Oldham", + "E07000178" => "Oxford", + "E07000122" => "Pendle", + "E06000031" => "Peterborough", + "E06000026" => "Plymouth", + "E06000044" => "Portsmouth", + "E07000123" => "Preston", + "E06000038" => "Reading", + "E09000026" => "Redbridge", + "E06000003" => "Redcar and Cleveland", + "E07000236" => "Redditch", + "E07000211" => "Reigate and Banstead", + "E07000124" => "Ribble Valley", + "E09000027" => "Richmond upon Thames", + "E07000166" => "Richmondshire", + "E08000005" => "Rochdale", + "E07000075" => "Rochford", + "E07000125" => "Rossendale", + "E07000064" => "Rother", + "E08000018" => "Rotherham", + "E07000220" => "Rugby", + "E07000212" => "Runnymede", + "E07000176" => "Rushcliffe", + "E07000092" => "Rushmoor", + "E06000017" => "Rutland", + "E07000167" => "Ryedale", + "E08000006" => "Salford", + "E08000028" => "Sandwell", + "E07000168" => "Scarborough", + "E07000188" => "Sedgemoor", + "E08000014" => "Sefton", + "E07000169" => "Selby", + "E07000111" => "Sevenoaks", + "E08000019" => "Sheffield", + "E06000051" => "Shropshire", + "E06000039" => "Slough", + "E08000029" => "Solihull", + "E07000246" => "Somerset West and Taunton", + "E07000012" => "South Cambridgeshire", + "E07000039" => "South Derbyshire", + "E06000025" => "South Gloucestershire", + "E07000044" => "South Hams", + "E07000140" => "South Holland", + "E07000141" => "South Kesteven", + "E07000031" => "South Lakeland", + "E07000149" => "South Norfolk", + "E07000155" => "South Northamptonshire", + "E07000179" => "South Oxfordshire", + "E07000126" => "South Ribble", + "E07000189" => "South Somerset", + "E07000196" => "South Staffordshire", + "E08000023" => "South Tyneside", + "E06000045" => "Southampton", + "E06000033" => "Southend-on-Sea", + "E09000028" => "Southwark", + "E07000213" => "Spelthorne", + "E07000240" => "St Albans", + "E08000013" => "St. Helens", + "E07000197" => "Stafford", + "E07000198" => "Staffordshire Moorlands", + "E07000243" => "Stevenage", + "E08000007" => "Stockport", + "E06000004" => "Stockton-on-Tees", + "E06000021" => "Stoke-on-Trent", + "E07000221" => "Stratford-on-Avon", + "E07000082" => "Stroud", + "E08000024" => "Sunderland", + "E07000214" => "Surrey Heath", + "E09000029" => "Sutton", + "E07000113" => "Swale", + "E06000030" => "Swindon", + "E08000008" => "Tameside", + "E07000199" => "Tamworth", + "E07000215" => "Tandridge", + "E07000045" => "Teignbridge", + "E06000020" => "Telford and Wrekin", + "E07000076" => "Tendring", + "E07000093" => "Test Valley", + "E07000083" => "Tewkesbury", + "E07000114" => "Thanet", + "E07000102" => "Three Rivers", + "E06000034" => "Thurrock", + "E07000115" => "Tonbridge and Malling", + "E06000027" => "Torbay", + "E07000046" => "Torridge", + "E09000030" => "Tower Hamlets", + "E08000009" => "Trafford", + "E07000116" => "Tunbridge Wells", + "E07000077" => "Uttlesford", + "E07000180" => "Vale of White Horse", + "E08000036" => "Wakefield", + "E08000030" => "Walsall", + "E09000031" => "Waltham Forest", + "E09000032" => "Wandsworth", + "E06000007" => "Warrington", + "E07000222" => "Warwick", + "E07000103" => "Watford", + "E07000216" => "Waverley", + "E07000065" => "Wealden", + "E07000156" => "Wellingborough", + "E07000241" => "Welwyn Hatfield", + "E06000037" => "West Berkshire", + "E07000047" => "West Devon", + "E07000127" => "West Lancashire", + "E07000142" => "West Lindsey", + "E07000181" => "West Oxfordshire", + "E07000245" => "West Suffolk", + "E09000033" => "Westminster", + "E08000010" => "Wigan", + "E06000054" => "Wiltshire", + "E07000094" => "Winchester", + "E06000040" => "Windsor and Maidenhead", + "E08000015" => "Wirral", + "E07000217" => "Woking", + "E06000041" => "Wokingham", + "E08000031" => "Wolverhampton", + "E07000237" => "Worcester", + "E07000229" => "Worthing", + "E07000238" => "Wychavon", + "E07000128" => "Wyre", + "E07000239" => "Wyre Forest", + "E06000014" => "York", + }) + end + end + + context "when the current collection year is 23/24" do + let(:today) { Time.zone.local(2023, 5, 1) } + + before do + Timecop.freeze(today) + end + + after do + Timecop.unfreeze + end + + it "returns a list of local authorities" do + expect(described_class.local_authorities_for_current_year).to eq({ + "E07000223" => "Adur", + "E07000032" => "Amber Valley", + "E07000224" => "Arun", + "E07000170" => "Ashfield", + "E07000105" => "Ashford", + "E07000200" => "Babergh", + "E09000002" => "Barking and Dagenham", + "E09000003" => "Barnet", + "E08000016" => "Barnsley", + "E07000066" => "Basildon", + "E07000084" => "Basingstoke and Deane", + "E07000171" => "Bassetlaw", + "E06000022" => "Bath and North East Somerset", + "E06000055" => "Bedford", + "E09000004" => "Bexley", + "E08000025" => "Birmingham", + "E07000129" => "Blaby", + "E06000008" => "Blackburn with Darwen", + "E06000009" => "Blackpool", + "E07000033" => "Bolsover", + "E08000001" => "Bolton", + "E07000136" => "Boston", + "E06000058" => "Bournemouth, Christchurch and Poole", + "E06000036" => "Bracknell Forest", + "E08000032" => "Bradford", + "E07000067" => "Braintree", + "E07000143" => "Breckland", + "E09000005" => "Brent", + "E07000068" => "Brentwood", + "E06000043" => "Brighton and Hove", + "E06000023" => "Bristol, City of", + "E07000144" => "Broadland", + "E09000006" => "Bromley", + "E07000234" => "Bromsgrove", + "E07000095" => "Broxbourne", + "E07000172" => "Broxtowe", + "E06000060" => "Buckinghamshire", + "E07000117" => "Burnley", + "E08000002" => "Bury", + "E08000033" => "Calderdale", + "E07000008" => "Cambridge", + "E09000007" => "Camden", + "E07000192" => "Cannock Chase", + "E07000106" => "Canterbury", + "E07000069" => "Castle Point", + "E06000056" => "Central Bedfordshire", + "E07000130" => "Charnwood", + "E07000070" => "Chelmsford", + "E07000078" => "Cheltenham", + "E07000177" => "Cherwell", + "E06000049" => "Cheshire East", + "E06000050" => "Cheshire West and Chester", + "E07000034" => "Chesterfield", + "E07000225" => "Chichester", + "E07000118" => "Chorley", + "E09000001" => "City of London", + "E07000071" => "Colchester", + "E07000150" => "Corby", + "E06000052" => "Cornwall", + "E07000079" => "Cotswold", + "E06000047" => "County Durham", + "E08000026" => "Coventry", + "E07000226" => "Crawley", + "E09000008" => "Croydon", + "E06000063" => "Cumberland", + "E07000096" => "Dacorum", + "E06000005" => "Darlington", + "E07000107" => "Dartford", + "E07000151" => "Daventry", + "E06000015" => "Derby", + "E07000035" => "Derbyshire Dales", + "E08000017" => "Doncaster", + "E06000059" => "Dorset", + "E07000108" => "Dover", + "E08000027" => "Dudley", + "E09000009" => "Ealing", + "E07000009" => "East Cambridgeshire", + "E07000040" => "East Devon", + "E07000085" => "East Hampshire", + "E07000242" => "East Hertfordshire", + "E07000137" => "East Lindsey", + "E07000152" => "East Northamptonshire", + "E06000011" => "East Riding of Yorkshire", + "E07000193" => "East Staffordshire", + "E07000244" => "East Suffolk", + "E07000061" => "Eastbourne", + "E07000086" => "Eastleigh", + "E07000207" => "Elmbridge", + "E09000010" => "Enfield", + "E07000072" => "Epping Forest", + "E07000208" => "Epsom and Ewell", + "E07000036" => "Erewash", + "E07000041" => "Exeter", + "E07000087" => "Fareham", + "E07000010" => "Fenland", + "E07000112" => "Folkestone and Hythe", + "E07000080" => "Forest of Dean", + "E07000119" => "Fylde", + "E08000037" => "Gateshead", + "E07000173" => "Gedling", + "E07000081" => "Gloucester", + "E07000088" => "Gosport", + "E07000109" => "Gravesham", + "E07000145" => "Great Yarmouth", + "E09000011" => "Greenwich", + "E07000209" => "Guildford", + "E09000012" => "Hackney", + "E06000006" => "Halton", + "E09000013" => "Hammersmith and Fulham", + "E07000131" => "Harborough", + "E09000014" => "Haringey", + "E07000073" => "Harlow", + "E09000015" => "Harrow", + "E07000089" => "Hart", + "E06000001" => "Hartlepool", + "E07000062" => "Hastings", + "E07000090" => "Havant", + "E09000016" => "Havering", + "E06000019" => "Herefordshire, County of", + "E07000098" => "Hertsmere", + "E07000037" => "High Peak", + "E09000017" => "Hillingdon", + "E07000132" => "Hinckley and Bosworth", + "E07000227" => "Horsham", + "E09000018" => "Hounslow", + "E07000011" => "Huntingdonshire", + "E07000120" => "Hyndburn", + "E07000202" => "Ipswich", + "E06000046" => "Isle of Wight", + "E06000053" => "Isles of Scilly", + "E09000019" => "Islington", + "E09000020" => "Kensington and Chelsea", + "E07000153" => "Kettering", + "E07000146" => "King’s Lynn and West Norfolk", + "E06000010" => "Kingston upon Hull, City of", + "E09000021" => "Kingston upon Thames", + "E08000034" => "Kirklees", + "E08000011" => "Knowsley", + "E09000022" => "Lambeth", + "E07000121" => "Lancaster", + "E08000035" => "Leeds", + "E06000016" => "Leicester", + "E07000063" => "Lewes", + "E09000023" => "Lewisham", + "E07000194" => "Lichfield", + "E07000138" => "Lincoln", + "E08000012" => "Liverpool", + "E06000032" => "Luton", + "E07000110" => "Maidstone", + "E07000074" => "Maldon", + "E07000235" => "Malvern Hills", + "E08000003" => "Manchester", + "E07000174" => "Mansfield", + "E06000035" => "Medway", + "E07000133" => "Melton", + "E09000024" => "Merton", + "E07000042" => "Mid Devon", + "E07000203" => "Mid Suffolk", + "E07000228" => "Mid Sussex", + "E06000002" => "Middlesbrough", + "E06000042" => "Milton Keynes", + "E07000210" => "Mole Valley", + "E07000091" => "New Forest", + "E07000175" => "Newark and Sherwood", + "E08000021" => "Newcastle upon Tyne", + "E07000195" => "Newcastle-under-Lyme", + "E09000025" => "Newham", + "E07000043" => "North Devon", + "E07000038" => "North East Derbyshire", + "E06000012" => "North East Lincolnshire", + "E07000099" => "North Hertfordshire", + "E07000139" => "North Kesteven", + "E06000013" => "North Lincolnshire", + "E07000147" => "North Norfolk", + "E06000024" => "North Somerset", + "E08000022" => "North Tyneside", + "E07000218" => "North Warwickshire", + "E07000134" => "North West Leicestershire", + "E06000065" => "North Yorkshire", + "E07000154" => "Northampton", + "E06000057" => "Northumberland", + "E07000148" => "Norwich", + "E06000018" => "Nottingham", + "E07000219" => "Nuneaton and Bedworth", + "E07000135" => "Oadby and Wigston", + "E08000004" => "Oldham", + "E07000178" => "Oxford", + "E07000122" => "Pendle", + "E06000031" => "Peterborough", + "E06000026" => "Plymouth", + "E06000044" => "Portsmouth", + "E07000123" => "Preston", + "E06000038" => "Reading", + "E09000026" => "Redbridge", + "E06000003" => "Redcar and Cleveland", + "E07000236" => "Redditch", + "E07000211" => "Reigate and Banstead", + "E07000124" => "Ribble Valley", + "E09000027" => "Richmond upon Thames", + "E08000005" => "Rochdale", + "E07000075" => "Rochford", + "E07000125" => "Rossendale", + "E07000064" => "Rother", + "E08000018" => "Rotherham", + "E07000220" => "Rugby", + "E07000212" => "Runnymede", + "E07000176" => "Rushcliffe", + "E07000092" => "Rushmoor", + "E06000017" => "Rutland", + "E08000006" => "Salford", + "E08000028" => "Sandwell", + "E08000014" => "Sefton", + "E07000111" => "Sevenoaks", + "E08000019" => "Sheffield", + "E06000051" => "Shropshire", + "E06000039" => "Slough", + "E08000029" => "Solihull", + "E06000066" => "Somerset", + "E07000012" => "South Cambridgeshire", + "E07000039" => "South Derbyshire", + "E06000025" => "South Gloucestershire", + "E07000044" => "South Hams", + "E07000140" => "South Holland", + "E07000141" => "South Kesteven", + "E07000149" => "South Norfolk", + "E07000155" => "South Northamptonshire", + "E07000179" => "South Oxfordshire", + "E07000126" => "South Ribble", + "E07000196" => "South Staffordshire", + "E08000023" => "South Tyneside", + "E06000045" => "Southampton", + "E06000033" => "Southend-on-Sea", + "E09000028" => "Southwark", + "E07000213" => "Spelthorne", + "E07000240" => "St Albans", + "E08000013" => "St. Helens", + "E07000197" => "Stafford", + "E07000198" => "Staffordshire Moorlands", + "E07000243" => "Stevenage", + "E08000007" => "Stockport", + "E06000004" => "Stockton-on-Tees", + "E06000021" => "Stoke-on-Trent", + "E07000221" => "Stratford-on-Avon", + "E07000082" => "Stroud", + "E08000024" => "Sunderland", + "E07000214" => "Surrey Heath", + "E09000029" => "Sutton", + "E07000113" => "Swale", + "E06000030" => "Swindon", + "E08000008" => "Tameside", + "E07000199" => "Tamworth", + "E07000215" => "Tandridge", + "E07000045" => "Teignbridge", + "E06000020" => "Telford and Wrekin", + "E07000076" => "Tendring", + "E07000093" => "Test Valley", + "E07000083" => "Tewkesbury", + "E07000114" => "Thanet", + "E07000102" => "Three Rivers", + "E06000034" => "Thurrock", + "E07000115" => "Tonbridge and Malling", + "E06000027" => "Torbay", + "E07000046" => "Torridge", + "E09000030" => "Tower Hamlets", + "E08000009" => "Trafford", + "E07000116" => "Tunbridge Wells", + "E07000077" => "Uttlesford", + "E07000180" => "Vale of White Horse", + "E08000036" => "Wakefield", + "E08000030" => "Walsall", + "E09000031" => "Waltham Forest", + "E09000032" => "Wandsworth", + "E06000007" => "Warrington", + "E07000222" => "Warwick", + "E07000103" => "Watford", + "E07000216" => "Waverley", + "E07000065" => "Wealden", + "E07000156" => "Wellingborough", + "E07000241" => "Welwyn Hatfield", + "E06000037" => "West Berkshire", + "E07000047" => "West Devon", + "E07000127" => "West Lancashire", + "E07000142" => "West Lindsey", + "E07000181" => "West Oxfordshire", + "E07000245" => "West Suffolk", + "E09000033" => "Westminster", + "E06000064" => "Westmorland and Furness", + "E08000010" => "Wigan", + "E06000054" => "Wiltshire", + "E07000094" => "Winchester", + "E06000040" => "Windsor and Maidenhead", + "E08000015" => "Wirral", + "E07000217" => "Woking", + "E06000041" => "Wokingham", + "E08000031" => "Wolverhampton", + "E07000237" => "Worcester", + "E07000229" => "Worthing", + "E07000238" => "Wychavon", + "E07000128" => "Wyre", + "E07000239" => "Wyre Forest", + "E06000014" => "York", + }) + end + end + end + describe "#name" do let(:location) { FactoryBot.build(:location) } diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb index b82fe6fe3..890fa069f 100644 --- a/spec/models/sales_log_spec.rb +++ b/spec/models/sales_log_spec.rb @@ -1,6 +1,7 @@ require "rails_helper" require "shared/shared_examples_for_derived_fields" +# rubocop:disable RSpec/AnyInstance RSpec.describe SalesLog, type: :model do let(:owning_organisation) { create(:organisation) } let(:created_by_user) { create(:user) } @@ -36,7 +37,7 @@ RSpec.describe SalesLog, type: :model do end describe "#update" do - let(:sales_log) { FactoryBot.create(:sales_log, created_by: created_by_user) } + let(:sales_log) { create(:sales_log, created_by: created_by_user) } let(:validator) { sales_log._validators[nil].first } after do @@ -49,10 +50,40 @@ RSpec.describe SalesLog, type: :model do end describe "#optional_fields" do - let(:sales_log) { build(:sales_log) } + context "when saledate is before 2023" do + let(:sales_log) { build(:sales_log, saledate: Time.zone.parse("2022-07-01")) } + + it "returns optional fields" do + expect(sales_log.optional_fields).to eq(%w[ + saledate_check + purchid + monthly_charges_value_check + old_persons_shared_ownership_value_check + mortgagelender + othtype + proplen + mortlen + frombeds + ]) + end + end - it "returns optional fields" do - expect(sales_log.optional_fields).to eq(%w[saledate_check purchid monthly_charges_value_check old_persons_shared_ownership_value_check]) + context "when saledate is after 2023" do + let(:sales_log) { build(:sales_log, saledate: Time.zone.parse("2023-07-01")) } + + it "returns optional fields" do + expect(sales_log.optional_fields).to eq(%w[ + saledate_check + purchid + monthly_charges_value_check + old_persons_shared_ownership_value_check + mortgagelender + othtype + address_line2 + county + postcode_full + ]) + end end end @@ -135,7 +166,7 @@ RSpec.describe SalesLog, type: :model do end describe "derived variables" do - let(:sales_log) { FactoryBot.create(:sales_log, :completed) } + let(:sales_log) { create(:sales_log, :completed) } it "correctly derives and saves exday, exmonth and exyear" do sales_log.update!(exdate: Time.gm(2022, 5, 4), saledate: Time.gm(2022, 7, 4), ownershipsch: 1, staircase: 2, resale: 2) @@ -192,7 +223,7 @@ RSpec.describe SalesLog, type: :model do end let!(:address_sales_log) do - FactoryBot.create( + create( :sales_log, :completed, owning_organisation:, @@ -226,6 +257,66 @@ RSpec.describe SalesLog, type: :model do expect(record_from_db["la"]).to eq("E08000003") end + context "with 22/23 logs" do + let(:address_sales_log_22_23) do + described_class.create({ + owning_organisation:, + created_by: created_by_user, + ppcodenk: 1, + postcode_full: "CA10 1AA", + saledate: Time.zone.local(2022, 5, 2), + }) + end + + before do + WebMock.stub_request(:get, /api.postcodes.io\/postcodes\/CA101AA/) + .to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Cumberland","codes":{"admin_district":"E06000064"}}}', headers: {}) + + Timecop.freeze(2023, 5, 1) + Singleton.__init__(FormHandler) + end + + after do + Timecop.unfreeze + end + + it "correctly sets la as nil" do + record_from_db = ActiveRecord::Base.connection.execute("select la from sales_logs where id=#{address_sales_log_22_23.id}").to_a[0] + expect(address_sales_log_22_23.la).to eq(nil) + expect(record_from_db["la"]).to eq(nil) + end + end + + context "with 23/24 logs" do + let(:address_sales_log_23_24) do + described_class.create({ + owning_organisation:, + created_by: created_by_user, + ppcodenk: 1, + postcode_full: "CA10 1AA", + saledate: Time.zone.local(2023, 5, 2), + }) + end + + before do + WebMock.stub_request(:get, /api.postcodes.io\/postcodes\/CA101AA/) + .to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Eden","codes":{"admin_district":"E07000030"}}}', headers: {}) + + Timecop.freeze(2023, 4, 1) + Singleton.__init__(FormHandler) + end + + after do + Timecop.unfreeze + end + + it "correctly infers new la" do + record_from_db = ActiveRecord::Base.connection.execute("select la from sales_logs where id=#{address_sales_log_23_24.id}").to_a[0] + expect(address_sales_log_23_24.la).to eq("E06000064") + expect(record_from_db["la"]).to eq("E06000064") + end + end + it "errors if the property postcode is emptied" do expect { address_sales_log.update!({ postcode_full: "" }) } .to raise_error(ActiveRecord::RecordInvalid, /#{I18n.t("validations.postcode")}/) @@ -276,7 +367,7 @@ RSpec.describe SalesLog, type: :model do context "when deriving household variables" do let!(:sales_log) do - FactoryBot.create( + create( :sales_log, :completed, jointpur: 1, @@ -403,7 +494,7 @@ RSpec.describe SalesLog, type: :model do end describe "#field_formatted_as_currency" do - let(:completed_sales_log) { FactoryBot.create(:sales_log, :completed) } + let(:completed_sales_log) { create(:sales_log, :completed) } it "returns small numbers correctly formatted as currency" do completed_sales_log.update!(savings: 4) @@ -423,4 +514,52 @@ RSpec.describe SalesLog, type: :model do expect(completed_sales_log.field_formatted_as_currency("savings")).to eq("£400,000,000.00") end end + + describe "#process_uprn_change!" do + context "when UPRN set to a value" do + let(:sales_log) { create(:sales_log, uprn: "123456789", uprn_confirmed: 1) } + + it "updates sales log fields" do + sales_log.uprn = "1111111" + + allow_any_instance_of(UprnClient).to receive(:call) + allow_any_instance_of(UprnClient).to receive(:result).and_return({ + "UPRN" => "UPRN", + "UDPRN" => "UDPRN", + "ADDRESS" => "full address", + "SUB_BUILDING_NAME" => "0", + "BUILDING_NAME" => "building name", + "THOROUGHFARE_NAME" => "thoroughfare", + "POST_TOWN" => "posttown", + "POSTCODE" => "postcode", + }) + + expect { sales_log.process_uprn_change! }.to change(sales_log, :address_line1).from(nil).to("0, Building Name, Thoroughfare") + .and change(sales_log, :town_or_city).from(nil).to("Posttown") + .and change(sales_log, :postcode_full).from(nil).to("POSTCODE") + .and change(sales_log, :uprn_confirmed).from(1).to(nil) + end + end + + context "when UPRN nil" do + let(:sales_log) { create(:sales_log, uprn: nil) } + + it "does not update sales log" do + expect { sales_log.process_uprn_change! }.not_to change(sales_log, :attributes) + end + end + + context "when service errors" do + let(:sales_log) { create(:sales_log, uprn: "123456789", uprn_confirmed: 1) } + let(:error_message) { "error" } + + it "adds error to sales log" do + allow_any_instance_of(UprnClient).to receive(:call) + allow_any_instance_of(UprnClient).to receive(:error).and_return(error_message) + + expect { sales_log.process_uprn_change! }.to change { sales_log.errors[:uprn] }.from([]).to([error_message]) + end + end + end end +# rubocop:enable RSpec/AnyInstance diff --git a/spec/models/validations/date_validations_spec.rb b/spec/models/validations/date_validations_spec.rb index 20d1e094c..cd6e38f50 100644 --- a/spec/models/validations/date_validations_spec.rb +++ b/spec/models/validations/date_validations_spec.rb @@ -9,18 +9,6 @@ RSpec.describe Validations::DateValidations do let(:scheme_no_end_date) { FactoryBot.create(:scheme, end_date: nil) } describe "tenancy start date" do - it "cannot be before the first collection window start date" do - record.startdate = Time.zone.local(2020, 1, 1) - date_validator.validate_startdate(record) - expect(record.errors["startdate"]).to include(match I18n.t("validations.date.outside_collection_window")) - end - - it "cannot be after the second collection window end date" do - record.startdate = Time.zone.local(2023, 7, 1, 6) - date_validator.validate_startdate(record) - expect(record.errors["startdate"]).to include(match I18n.t("validations.date.outside_collection_window")) - end - it "must be a valid date" do record.startdate = Time.zone.local(0, 7, 1) date_validator.validate_startdate(record) @@ -98,7 +86,7 @@ RSpec.describe Validations::DateValidations do record.location = location date_validator.validate_startdate(record) expect(record.errors["startdate"]) - .to include(match I18n.t("validations.setup.startdate.location.deactivated", postcode: location.postcode, date: "4 June 2022")) + .to include(match I18n.t("validations.setup.startdate.location.deactivated", postcode: location.postcode, date: "4 June 2022")) end it "produces no error when tenancy start date is during an active location period" do @@ -123,7 +111,7 @@ RSpec.describe Validations::DateValidations do record.location = location date_validator.validate_startdate(record) expect(record.errors["startdate"]) - .to include(match I18n.t("validations.setup.startdate.location.reactivating_soon", postcode: location.postcode, date: "4 August 2022")) + .to include(match I18n.t("validations.setup.startdate.location.reactivating_soon", postcode: location.postcode, date: "4 August 2022")) end it "produces no error when tenancy start date is during an active location period" do @@ -150,7 +138,7 @@ RSpec.describe Validations::DateValidations do record.location = location date_validator.validate_startdate(record) expect(record.errors["startdate"]) - .to include(match I18n.t("validations.setup.startdate.location.reactivating_soon", postcode: location.postcode, date: "4 September 2022")) + .to include(match I18n.t("validations.setup.startdate.location.reactivating_soon", postcode: location.postcode, date: "4 September 2022")) end it "produces no error when tenancy start date is during an active location period" do @@ -177,7 +165,7 @@ RSpec.describe Validations::DateValidations do record.location = location date_validator.validate_startdate(record) expect(record.errors["startdate"]) - .to include(match I18n.t("validations.setup.startdate.location.activating_soon", postcode: location.postcode, date: "15 September 2022")) + .to include(match I18n.t("validations.setup.startdate.location.activating_soon", postcode: location.postcode, date: "15 September 2022")) end end @@ -194,7 +182,7 @@ RSpec.describe Validations::DateValidations do record.scheme = scheme date_validator.validate_startdate(record) expect(record.errors["startdate"]) - .to include(match I18n.t("validations.setup.startdate.scheme.reactivating_soon", name: scheme.service_name, date: "4 August 2022")) + .to include(match I18n.t("validations.setup.startdate.scheme.reactivating_soon", name: scheme.service_name, date: "4 August 2022")) end it "produces no error when tenancy start date is during an active scheme period" do @@ -220,7 +208,7 @@ RSpec.describe Validations::DateValidations do record.scheme = scheme date_validator.validate_startdate(record) expect(record.errors["startdate"]) - .to include(match I18n.t("validations.setup.startdate.scheme.reactivating_soon", name: scheme.service_name, date: "4 September 2022")) + .to include(match I18n.t("validations.setup.startdate.scheme.reactivating_soon", name: scheme.service_name, date: "4 September 2022")) end it "produces no error when tenancy start date is during an active scheme period" do diff --git a/spec/models/validations/financial_validations_spec.rb b/spec/models/validations/financial_validations_spec.rb index bdd76cded..c2fe3b963 100644 --- a/spec/models/validations/financial_validations_spec.rb +++ b/spec/models/validations/financial_validations_spec.rb @@ -86,7 +86,7 @@ RSpec.describe Validations::FinancialValidations do end context "when outstanding rent or charges is yes" do - let(:record) { FactoryBot.create(:lettings_log, :about_completed) } + let(:record) { FactoryBot.create(:lettings_log, :about_completed, startdate: Time.zone.now) } it "expects that a shortfall is provided" do record.hbrentshortfall = 1 diff --git a/spec/models/validations/property_validations_spec.rb b/spec/models/validations/property_validations_spec.rb index b3965b3d6..3b3e42e9e 100644 --- a/spec/models/validations/property_validations_spec.rb +++ b/spec/models/validations/property_validations_spec.rb @@ -290,4 +290,33 @@ RSpec.describe Validations::PropertyValidations do end end end + + describe "#validate_uprn" do + context "when within length limit but alphanumeric" do + let(:record) { build(:sales_log, uprn: "123abc") } + + it "adds an error" do + property_validator.validate_uprn(record) + expect(record.errors.added?(:uprn, "UPRN must be 12 digits or less")).to be true + end + end + + context "when over the length limit" do + let(:record) { build(:sales_log, uprn: "1234567890123") } + + it "adds an error" do + property_validator.validate_uprn(record) + expect(record.errors.added?(:uprn, "UPRN must be 12 digits or less")).to be true + end + end + + context "when within the limit and only numeric" do + let(:record) { build(:sales_log, uprn: "123456789012") } + + it "does not add an error" do + property_validator.validate_uprn(record) + expect(record.errors).not_to be_present + end + end + end end diff --git a/spec/models/validations/sales/financial_validations_spec.rb b/spec/models/validations/sales/financial_validations_spec.rb index fae0e4536..b60ef5e6a 100644 --- a/spec/models/validations/sales/financial_validations_spec.rb +++ b/spec/models/validations/sales/financial_validations_spec.rb @@ -160,6 +160,48 @@ RSpec.describe Validations::Sales::FinancialValidations do end end + describe "#validate_percentage_bought_at_least_threshold" do + let(:record) { FactoryBot.create(:sales_log) } + + it "adds an error to stairbought and type if the percentage bought is less than the threshold (which is 1% by default, but higher for some shared ownership types)" do + record.stairbought = 9 + [2, 16, 18, 24].each do |type| + record.type = type + financial_validator.validate_percentage_bought_at_least_threshold(record) + expect(record.errors["stairbought"]).to eq(["The minimum increase in equity while staircasing is 10%"]) + expect(record.errors["type"]).to eq(["The minimum increase in equity while staircasing is 10% for this shared ownership type"]) + record.errors.clear + end + + record.stairbought = 0 + [28, 30, 31, 32].each do |type| + record.type = type + financial_validator.validate_percentage_bought_at_least_threshold(record) + expect(record.errors["stairbought"]).to eq(["The minimum increase in equity while staircasing is 1%"]) + expect(record.errors["type"]).to eq(["The minimum increase in equity while staircasing is 1% for this shared ownership type"]) + record.errors.clear + end + end + + it "doesn't add an error to stairbought and type if the percentage bought is less than the threshold (which is 1% by default, but higher for some shared ownership types)" do + record.stairbought = 10 + [2, 16, 18, 24].each do |type| + record.type = type + financial_validator.validate_percentage_bought_at_least_threshold(record) + expect(record.errors).to be_empty + record.errors.clear + end + + record.stairbought = 1 + [28, 30, 31, 32].each do |type| + record.type = type + financial_validator.validate_percentage_bought_at_least_threshold(record) + expect(record.errors).to be_empty + record.errors.clear + end + end + end + describe "#validate_percentage_owned_not_too_much_if_older_person" do let(:record) { FactoryBot.create(:sales_log) } @@ -209,6 +251,7 @@ RSpec.describe Validations::Sales::FinancialValidations do context "when buyer 2 is a child" do it "does not add an error if buyer 2 has no income" do + record.saledate = Time.zone.local(2023, 4, 3) record.ecstat2 = 9 record.income2 = 0 financial_validator.validate_child_income(record) @@ -216,12 +259,102 @@ RSpec.describe Validations::Sales::FinancialValidations do end it "adds errors if buyer 2 has an income" do + record.saledate = Time.zone.local(2023, 4, 3) record.ecstat2 = 9 record.income2 = 40_000 financial_validator.validate_child_income(record) expect(record.errors["ecstat2"]).to include(match I18n.t("validations.financial.income.child_has_income")) expect(record.errors["income2"]).to include(match I18n.t("validations.financial.income.child_has_income")) end + + it "does not add an error if the saledate is before the 23/24 collection window" do + record.saledate = Time.zone.local(2022, 4, 3) + record.ecstat2 = 9 + record.income2 = 40_000 + financial_validator.validate_child_income(record) + expect(record.errors).to be_empty + end + end + end + + describe "#validate_equity_in_range_for_year_and_type" do + let(:record) { FactoryBot.create(:sales_log, saledate: now) } + + around do |example| + Timecop.freeze(now) do + example.run + end + Timecop.return + end + + context "with a log in the 22/23 collection year" do + let(:now) { Time.zone.local(2023, 1, 1) } + + it "adds an error for type 2, equity below min with the correct percentage" do + record.type = 2 + record.equity = 1 + financial_validator.validate_equity_in_range_for_year_and_type(record) + expect(record.errors["equity"]).to include(match I18n.t("validations.financial.equity.under_min", min_equity: 25)) + expect(record.errors["type"]).to include(match I18n.t("validations.financial.equity.under_min", min_equity: 25)) + end + + it "adds an error for type 30, equity below min with the correct percentage" do + record.type = 30 + record.equity = 1 + financial_validator.validate_equity_in_range_for_year_and_type(record) + expect(record.errors["equity"]).to include(match I18n.t("validations.financial.equity.under_min", min_equity: 10)) + expect(record.errors["type"]).to include(match I18n.t("validations.financial.equity.under_min", min_equity: 10)) + end + + it "does not add an error for equity in range with the correct percentage" do + record.type = 2 + record.equity = 50 + financial_validator.validate_equity_in_range_for_year_and_type(record) + expect(record.errors).to be_empty + end + + it "adds an error for equity above max with the correct percentage" do + record.type = 2 + record.equity = 90 + financial_validator.validate_equity_in_range_for_year_and_type(record) + expect(record.errors["equity"]).to include(match I18n.t("validations.financial.equity.over_max", max_equity: 75)) + expect(record.errors["type"]).to include(match I18n.t("validations.financial.equity.over_max", max_equity: 75)) + end + end + + context "with a log in 23/24 collection year" do + let(:now) { Time.zone.local(2024, 1, 1) } + + it "adds an error for type 2, equity below min with the correct percentage" do + record.type = 2 + record.equity = 1 + financial_validator.validate_equity_in_range_for_year_and_type(record) + expect(record.errors["equity"]).to include(match I18n.t("validations.financial.equity.under_min", min_equity: 10)) + expect(record.errors["type"]).to include(match I18n.t("validations.financial.equity.under_min", min_equity: 10)) + end + + it "adds an error for type 30, equity below min with the correct percentage" do + record.type = 30 + record.equity = 1 + financial_validator.validate_equity_in_range_for_year_and_type(record) + expect(record.errors["equity"]).to include(match I18n.t("validations.financial.equity.under_min", min_equity: 25)) + expect(record.errors["type"]).to include(match I18n.t("validations.financial.equity.under_min", min_equity: 25)) + end + + it "does not add an error for equity in range with the correct percentage" do + record.type = 2 + record.equity = 50 + financial_validator.validate_equity_in_range_for_year_and_type(record) + expect(record.errors).to be_empty + end + + it "adds an error for equity above max with the correct percentage" do + record.type = 2 + record.equity = 90 + financial_validator.validate_equity_in_range_for_year_and_type(record) + expect(record.errors["equity"]).to include(match I18n.t("validations.financial.equity.over_max", max_equity: 75)) + expect(record.errors["type"]).to include(match I18n.t("validations.financial.equity.over_max", max_equity: 75)) + end end end end diff --git a/spec/models/validations/sales/household_validations_spec.rb b/spec/models/validations/sales/household_validations_spec.rb index 10367390e..5c7a921e4 100644 --- a/spec/models/validations/sales/household_validations_spec.rb +++ b/spec/models/validations/sales/household_validations_spec.rb @@ -84,17 +84,14 @@ RSpec.describe Validations::Sales::HouseholdValidations do .to include(match I18n.t("validations.household.age.child_over_20")) end - it "adds errors for a person aged 16-19 who is a student but not a child of the buyer" do + it "does not add and error for a person aged 16-19 who is a student but not a child of the buyer" do record.age2 = 18 record.ecstat2 = "7" record.relat2 = "P" household_validator.validate_household_number_of_other_members(record) - expect(record.errors["relat2"]) - .to include(match I18n.t("validations.household.relat.student_16_19.must_be_child")) - expect(record.errors["age2"]) - .to include(match I18n.t("validations.household.age.student_16_19.cannot_be_16_19.student_not_child")) - expect(record.errors["ecstat2"]) - .to include(match I18n.t("validations.household.ecstat.student_16_19.cannot_be_student.16_19_not_child")) + expect(record.errors["relat2"]).to be_empty + expect(record.errors["ecstat2"]).to be_empty + expect(record.errors["age2"]).to be_empty end it "adds errors for a person aged 16-19 who is a child of the buyer but not a student" do diff --git a/spec/models/validations/sales/property_validations_spec.rb b/spec/models/validations/sales/property_validations_spec.rb index 180f16021..af65446fc 100644 --- a/spec/models/validations/sales/property_validations_spec.rb +++ b/spec/models/validations/sales/property_validations_spec.rb @@ -7,7 +7,7 @@ RSpec.describe Validations::Sales::PropertyValidations do describe "#validate_postcodes_match_if_discounted_ownership" do context "when ownership scheme is not discounted ownership" do - let(:record) { FactoryBot.build(:sales_log, ownershipsch: 1) } + let(:record) { build(:sales_log, ownershipsch: 1) } it "when postcodes match no error is added" do record.postcode_full = "SW1A 1AA" @@ -19,7 +19,7 @@ RSpec.describe Validations::Sales::PropertyValidations do end context "when ownership scheme is discounted ownership" do - let(:record) { FactoryBot.build(:sales_log, ownershipsch: 2) } + let(:record) { build(:sales_log, ownershipsch: 2) } it "when ppostcode_full is not present no error is added" do record.postcode_full = "SW1A 1AA" @@ -51,7 +51,7 @@ RSpec.describe Validations::Sales::PropertyValidations do describe "#validate_property_unit_type" do context "when number of bedrooms is 1" do - let(:record) { FactoryBot.build(:sales_log, beds: 1, proptype: 2) } + let(:record) { build(:sales_log, beds: 1, proptype: 2) } it "does not add an error if it's a bedsit" do property_validator.validate_bedsit_number_of_beds(record) @@ -60,7 +60,7 @@ RSpec.describe Validations::Sales::PropertyValidations do end context "when number of bedrooms is > 1" do - let(:record) { FactoryBot.build(:sales_log, beds: 2, proptype: 2) } + let(:record) { build(:sales_log, beds: 2, proptype: 2) } it "does add an error if it's a bedsit" do property_validator.validate_bedsit_number_of_beds(record) @@ -76,7 +76,7 @@ RSpec.describe Validations::Sales::PropertyValidations do end context "when number of bedrooms is undefined" do - let(:record) { FactoryBot.build(:sales_log, beds: nil, proptype: 2) } + let(:record) { build(:sales_log, beds: nil, proptype: 2) } it "does not add an error if it's a bedsit" do property_validator.validate_bedsit_number_of_beds(record) @@ -84,4 +84,33 @@ RSpec.describe Validations::Sales::PropertyValidations do end end end + + describe "#validate_uprn" do + context "when within length limit but alphanumeric" do + let(:record) { build(:sales_log, uprn: "123abc") } + + it "adds an error" do + property_validator.validate_uprn(record) + expect(record.errors.added?(:uprn, "UPRN must be 12 digits or less")).to be true + end + end + + context "when over the length limit" do + let(:record) { build(:sales_log, uprn: "1234567890123") } + + it "adds an error" do + property_validator.validate_uprn(record) + expect(record.errors.added?(:uprn, "UPRN must be 12 digits or less")).to be true + end + end + + context "when within the limit and only numeric" do + let(:record) { build(:sales_log, uprn: "123456789012") } + + it "does not add an error" do + property_validator.validate_uprn(record) + expect(record.errors).not_to be_present + end + end + end end diff --git a/spec/models/validations/sales/setup_validations_spec.rb b/spec/models/validations/sales/setup_validations_spec.rb index 4571ae5cd..136e239d3 100644 --- a/spec/models/validations/sales/setup_validations_spec.rb +++ b/spec/models/validations/sales/setup_validations_spec.rb @@ -17,7 +17,7 @@ RSpec.describe Validations::Sales::SetupValidations do end end - context "when saledate is in the 22/23 financial year" do + context "when saledate is in the 22/23 collection year" do let(:record) { build(:sales_log, saledate: Time.zone.local(2023, 1, 1)) } it "does not add an error" do @@ -27,23 +27,23 @@ RSpec.describe Validations::Sales::SetupValidations do end end - context "when saledate is before the 22/23 financial year" do + context "when saledate is before the 22/23 collection year" do let(:record) { build(:sales_log, saledate: Time.zone.local(2020, 1, 1)) } it "adds error" do setup_validator.validate_saledate(record) - expect(record.errors[:saledate]).to include("Enter a date within the 22/23 financial year, which is between 1st April 2022 and 31st March 2023") + expect(record.errors[:saledate]).to include("Enter a date within the 22/23 collection year, which is between 1st April 2022 and 31st March 2023") end end - context "when saledate is after the 22/23 financial year" do + context "when saledate is after the 22/23 collection year" do let(:record) { build(:sales_log, saledate: Time.zone.local(2025, 4, 1)) } it "adds error" do setup_validator.validate_saledate(record) - expect(record.errors[:saledate]).to include("Enter a date within the 22/23 financial year, which is between 1st April 2022 and 31st March 2023") + expect(record.errors[:saledate]).to include("Enter a date within the 22/23 collection year, which is between 1st April 2022 and 31st March 2023") end end end @@ -55,7 +55,6 @@ RSpec.describe Validations::Sales::SetupValidations do example.run end Timecop.return - Singleton.__init__(FormHandler) end context "when saledate is blank" do @@ -68,7 +67,7 @@ RSpec.describe Validations::Sales::SetupValidations do end end - context "when saledate is in the 22/23 financial year" do + context "when saledate is in the 22/23 collection year" do let(:record) { build(:sales_log, saledate: Time.zone.local(2024, 1, 1)) } it "does not add an error" do @@ -78,23 +77,23 @@ RSpec.describe Validations::Sales::SetupValidations do end end - context "when saledate is before the 22/23 financial year" do + context "when saledate is before the 22/23 collection year" do let(:record) { build(:sales_log, saledate: Time.zone.local(2020, 5, 1)) } it "adds error" do setup_validator.validate_saledate(record) - expect(record.errors[:saledate]).to include("Enter a date within the 23/24 or 24/25 financial years, which is between 1st April 2023 and 31st March 2025") + expect(record.errors[:saledate]).to include("Enter a date within the 23/24 or 24/25 collection years, which is between 1st April 2023 and 31st March 2025") end end - context "when saledate is after the 22/23 financial year" do + context "when saledate is after the 22/23 collection year" do let(:record) { build(:sales_log, saledate: Time.zone.local(2025, 4, 1)) } it "adds error" do setup_validator.validate_saledate(record) - expect(record.errors[:saledate]).to include("Enter a date within the 23/24 or 24/25 financial years, which is between 1st April 2023 and 31st March 2025") + expect(record.errors[:saledate]).to include("Enter a date within the 23/24 or 24/25 collection years, which is between 1st April 2023 and 31st March 2025") end end end diff --git a/spec/models/validations/sales/soft_validations_spec.rb b/spec/models/validations/sales/soft_validations_spec.rb index 5d475b450..dc8bbfedd 100644 --- a/spec/models/validations/sales/soft_validations_spec.rb +++ b/spec/models/validations/sales/soft_validations_spec.rb @@ -730,4 +730,72 @@ RSpec.describe Validations::Sales::SoftValidations do end end end + + describe "#person_2_student_not_child?" do + it "returns false if age is not given" do + record.age2 = nil + record.relat2 = "P" + record.ecstat2 = 7 + + expect(record).not_to be_person_2_student_not_child + end + + it "returns false if retaltionship is not given" do + record.age2 = 17 + record.relat2 = nil + record.ecstat2 = 7 + + expect(record).not_to be_person_2_student_not_child + end + + it "returns false if economic status is not given" do + record.age2 = 17 + record.relat2 = "P" + record.ecstat2 = nil + + expect(record).not_to be_person_2_student_not_child + end + + it "returns true if it's a student aged 16-19 and not a child" do + record.age2 = 17 + record.relat2 = "P" + record.ecstat2 = 7 + + expect(record).to be_person_2_student_not_child + end + end + + describe "#person_3_student_not_child?" do + it "returns false if age is not given" do + record.age3 = nil + record.relat3 = "P" + record.ecstat3 = 7 + + expect(record).not_to be_person_3_student_not_child + end + + it "returns false if retaltionship is not given" do + record.age3 = 17 + record.relat3 = nil + record.ecstat3 = 7 + + expect(record).not_to be_person_3_student_not_child + end + + it "returns false if economic status is not given" do + record.age3 = 17 + record.relat3 = "P" + record.ecstat3 = nil + + expect(record).not_to be_person_3_student_not_child + end + + it "returns true if it's a student aged 16-19 and not a child" do + record.age3 = 17 + record.relat3 = "P" + record.ecstat3 = 7 + + expect(record).to be_person_3_student_not_child + end + end end diff --git a/spec/models/validations/setup_validations_spec.rb b/spec/models/validations/setup_validations_spec.rb index 326a6936d..69e22f1e2 100644 --- a/spec/models/validations/setup_validations_spec.rb +++ b/spec/models/validations/setup_validations_spec.rb @@ -6,13 +6,95 @@ RSpec.describe Validations::SetupValidations do let(:setup_validator_class) { Class.new { include Validations::SetupValidations } } let(:record) { FactoryBot.create(:lettings_log) } + describe "tenancy start date" do + context "when in 22/23 collection" do + context "when in the crossover period" do + before do + allow(Time).to receive(:now).and_return(Time.zone.local(2022, 4, 1)) + record.created_at = Time.zone.local(2022, 4, 1) + end + + it "cannot be before the first collection window start date" do + record.startdate = Time.zone.local(2021, 1, 1) + setup_validator.validate_startdate_setup(record) + expect(record.errors["startdate"]).to include(match "Enter a date within the 21/22 or 22/23 collection years, which is between 1st April 2021 and 31st March 2023") + end + + it "cannot be after the second collection window end date" do + record.startdate = Time.zone.local(2023, 7, 1, 6) + setup_validator.validate_startdate_setup(record) + expect(record.errors["startdate"]).to include(match "Enter a date within the 21/22 or 22/23 collection years, which is between 1st April 2021 and 31st March 2023") + end + end + + context "when after the crossover period" do + before do + allow(Time).to receive(:now).and_return(Time.zone.local(2023, 1, 1)) + record.created_at = Time.zone.local(2023, 1, 1) + end + + it "cannot be before the first collection window start date" do + record.startdate = Time.zone.local(2022, 1, 1) + setup_validator.validate_startdate_setup(record) + expect(record.errors["startdate"]).to include(match "Enter a date within the 22/23 collection year, which is between 1st April 2022 and 31st March 2023") + end + + it "cannot be after the second collection window end date" do + record.startdate = Time.zone.local(2023, 7, 1, 6) + setup_validator.validate_startdate_setup(record) + expect(record.errors["startdate"]).to include(match "Enter a date within the 22/23 collection year, which is between 1st April 2022 and 31st March 2023") + end + end + end + + context "when in 23/24 collection" do + context "when in the crossover period" do + before do + allow(Time).to receive(:now).and_return(Time.zone.local(2023, 4, 1)) + record.created_at = Time.zone.local(2023, 4, 1) + end + + it "cannot be before the first collection window start date" do + record.startdate = Time.zone.local(2022, 1, 1) + setup_validator.validate_startdate_setup(record) + expect(record.errors["startdate"]).to include(match "Enter a date within the 22/23 or 23/24 collection years, which is between 1st April 2022 and 31st March 2024") + end + + it "cannot be after the second collection window end date" do + record.startdate = Time.zone.local(2024, 7, 1, 6) + setup_validator.validate_startdate_setup(record) + expect(record.errors["startdate"]).to include(match "Enter a date within the 22/23 or 23/24 collection years, which is between 1st April 2022 and 31st March 2024") + end + end + + context "when after the crossover period" do + before do + allow(Time).to receive(:now).and_return(Time.zone.local(2024, 1, 1)) + record.created_at = Time.zone.local(2024, 1, 1) + end + + it "cannot be before the first collection window start date" do + record.startdate = Time.zone.local(2023, 1, 1) + setup_validator.validate_startdate_setup(record) + expect(record.errors["startdate"]).to include(match "Enter a date within the 23/24 collection year, which is between 1st April 2023 and 31st March 2024") + end + + it "cannot be after the second collection window end date" do + record.startdate = Time.zone.local(2024, 7, 1, 6) + setup_validator.validate_startdate_setup(record) + expect(record.errors["startdate"]).to include(match "Enter a date within the 23/24 collection year, which is between 1st April 2023 and 31st March 2024") + end + end + end + end + describe "#validate_irproduct" do it "adds an error when the intermediate rent product name is not provided but the rent type was given as other intermediate rent product" do record.rent_type = 5 record.irproduct_other = nil setup_validator.validate_irproduct_other(record) expect(record.errors["irproduct_other"]) - .to include(match I18n.t("validations.setup.intermediate_rent_product_name.blank")) + .to include(match I18n.t("validations.setup.intermediate_rent_product_name.blank")) end it "adds an error when the intermediate rent product name is blank but the rent type was given as other intermediate rent product" do @@ -20,7 +102,7 @@ RSpec.describe Validations::SetupValidations do record.irproduct_other = "" setup_validator.validate_irproduct_other(record) expect(record.errors["irproduct_other"]) - .to include(match I18n.t("validations.setup.intermediate_rent_product_name.blank")) + .to include(match I18n.t("validations.setup.intermediate_rent_product_name.blank")) end it "Does not add an error when the intermediate rent product name is provided and the rent type was given as other intermediate rent product" do @@ -46,7 +128,7 @@ RSpec.describe Validations::SetupValidations do record.location = location setup_validator.validate_scheme(record) expect(record.errors["scheme_id"]) - .to include(match I18n.t("validations.setup.startdate.location.deactivated", postcode: location.postcode, date: "4 June 2022")) + .to include(match I18n.t("validations.setup.startdate.location.deactivated", postcode: location.postcode, date: "4 June 2022")) end it "produces no error when tenancy start date is during an active location period" do @@ -71,7 +153,7 @@ RSpec.describe Validations::SetupValidations do record.location = location setup_validator.validate_scheme(record) expect(record.errors["scheme_id"]) - .to include(match I18n.t("validations.setup.startdate.location.reactivating_soon", postcode: location.postcode, date: "4 August 2022")) + .to include(match I18n.t("validations.setup.startdate.location.reactivating_soon", postcode: location.postcode, date: "4 August 2022")) end it "produces no error when tenancy start date is during an active location period" do @@ -98,7 +180,7 @@ RSpec.describe Validations::SetupValidations do record.location = location setup_validator.validate_scheme(record) expect(record.errors["scheme_id"]) - .to include(match I18n.t("validations.setup.startdate.location.activating_soon", postcode: location.postcode, date: "15 September 2022")) + .to include(match I18n.t("validations.setup.startdate.location.activating_soon", postcode: location.postcode, date: "15 September 2022")) end end @@ -115,7 +197,7 @@ RSpec.describe Validations::SetupValidations do record.scheme = scheme setup_validator.validate_scheme(record) expect(record.errors["scheme_id"]) - .to include(match I18n.t("validations.setup.startdate.scheme.reactivating_soon", name: scheme.service_name, date: "4 August 2022")) + .to include(match I18n.t("validations.setup.startdate.scheme.reactivating_soon", name: scheme.service_name, date: "4 August 2022")) end it "produces no error when tenancy start date is during an active scheme period" do @@ -141,7 +223,7 @@ RSpec.describe Validations::SetupValidations do record.scheme = scheme setup_validator.validate_scheme(record) expect(record.errors["scheme_id"]) - .to include(match I18n.t("validations.setup.startdate.scheme.reactivating_soon", name: scheme.service_name, date: "4 September 2022")) + .to include(match I18n.t("validations.setup.startdate.scheme.reactivating_soon", name: scheme.service_name, date: "4 September 2022")) end it "produces no error when tenancy start date is during an active scheme period" do @@ -168,7 +250,7 @@ RSpec.describe Validations::SetupValidations do record.location = location setup_validator.validate_location(record) expect(record.errors["location_id"]) - .to include(match I18n.t("validations.setup.startdate.location.deactivated", postcode: location.postcode, date: "4 June 2022")) + .to include(match I18n.t("validations.setup.startdate.location.deactivated", postcode: location.postcode, date: "4 June 2022")) end it "produces no error when tenancy start date is during an active location period" do @@ -193,7 +275,7 @@ RSpec.describe Validations::SetupValidations do record.location = location setup_validator.validate_location(record) expect(record.errors["location_id"]) - .to include(match I18n.t("validations.setup.startdate.location.reactivating_soon", postcode: location.postcode, date: "4 August 2022")) + .to include(match I18n.t("validations.setup.startdate.location.reactivating_soon", postcode: location.postcode, date: "4 August 2022")) end it "produces no error when tenancy start date is during an active location period" do @@ -220,7 +302,7 @@ RSpec.describe Validations::SetupValidations do record.location = location setup_validator.validate_location(record) expect(record.errors["location_id"]) - .to include(match I18n.t("validations.setup.startdate.location.activating_soon", postcode: location.postcode, date: "15 September 2022")) + .to include(match I18n.t("validations.setup.startdate.location.activating_soon", postcode: location.postcode, date: "15 September 2022")) end end end diff --git a/spec/models/validations/soft_validations_spec.rb b/spec/models/validations/soft_validations_spec.rb index 9ca9436fb..3ce2b4527 100644 --- a/spec/models/validations/soft_validations_spec.rb +++ b/spec/models/validations/soft_validations_spec.rb @@ -207,6 +207,14 @@ RSpec.describe Validations::SoftValidations do end describe "major repairs date soft validations" do + before do + Timecop.freeze(Time.zone.local(2022, 2, 1)) + end + + after do + Timecop.unfreeze + end + context "when the major repairs date is within 10 years of the tenancy start date" do it "shows the interruption screen" do record.update!(startdate: Time.zone.local(2022, 2, 1), mrcdate: Time.zone.local(2013, 2, 1)) @@ -223,6 +231,14 @@ RSpec.describe Validations::SoftValidations do end describe "void date soft validations" do + before do + Timecop.freeze(Time.zone.local(2022, 2, 1)) + end + + after do + Timecop.unfreeze + end + context "when the void date is within 10 years of the tenancy start date" do it "shows the interruption screen" do record.update!(startdate: Time.zone.local(2022, 2, 1), voiddate: Time.zone.local(2013, 2, 1)) diff --git a/spec/models/validations/tenancy_validations_spec.rb b/spec/models/validations/tenancy_validations_spec.rb index 2d008e6e3..9f3a2b873 100644 --- a/spec/models/validations/tenancy_validations_spec.rb +++ b/spec/models/validations/tenancy_validations_spec.rb @@ -3,6 +3,14 @@ require "rails_helper" RSpec.describe Validations::TenancyValidations do subject(:tenancy_validator) { validator_class.new } + before do + Timecop.freeze(Time.zone.local(2021, 5, 1)) + end + + after do + Timecop.unfreeze + end + let(:validator_class) { Class.new { include Validations::TenancyValidations } } let(:record) { FactoryBot.create(:lettings_log, startdate: Time.zone.local(2021, 5, 1), needstype: 1, rent_type: 1) } @@ -117,6 +125,14 @@ RSpec.describe Validations::TenancyValidations do end context "when the collection start year is 2022 or later" do + before do + Timecop.freeze(2022, 5, 1) + end + + after do + Timecop.unfreeze + end + let(:record) { FactoryBot.create(:lettings_log, startdate: Time.zone.local(2022, 5, 1), needstype: 1, rent_type: 1) } context "when type of tenancy is Secure - fixed term" do @@ -260,6 +276,14 @@ RSpec.describe Validations::TenancyValidations do describe "joint tenancy validation" do context "when the data inputter has said that there is only one member in the household" do + before do + Timecop.freeze(2022, 5, 1) + end + + after do + Timecop.unfreeze + end + let(:record) { FactoryBot.create(:lettings_log, startdate: Time.zone.local(2022, 5, 1)) } let(:expected_error) { I18n.t("validations.tenancy.not_joint") } let(:hhmemb_expected_error) { I18n.t("validations.tenancy.joint_more_than_one_member") } diff --git a/spec/requests/form_controller_spec.rb b/spec/requests/form_controller_spec.rb index d5a8dbcf8..9dce39af2 100644 --- a/spec/requests/form_controller_spec.rb +++ b/spec/requests/form_controller_spec.rb @@ -17,7 +17,6 @@ RSpec.describe FormController, type: :request do :lettings_log, :about_completed, status: 1, - startdate: Time.zone.local(2021, 10, 10), created_by: user, ) end @@ -26,7 +25,6 @@ RSpec.describe FormController, type: :request do :lettings_log, :completed, created_by: user, - startdate: Time.zone.local(2021, 5, 1), ) end let(:headers) { { "Accept" => "text/html" } } @@ -204,10 +202,13 @@ RSpec.describe FormController, type: :request do describe "GET" do context "with form pages" do context "when forms exist for multiple years" do - let(:lettings_log_year_1) { create(:lettings_log, startdate: Time.zone.local(2021, 5, 1), owning_organisation: organisation, created_by: user) } + let(:lettings_log_year_1) { create(:lettings_log, owning_organisation: organisation, created_by: user) } let(:lettings_log_year_2) { create(:lettings_log, :about_completed, startdate: Time.zone.local(2022, 5, 1), owning_organisation: organisation, created_by: user) } before do + Timecop.freeze(Time.zone.local(2021, 5, 1)) + lettings_log_year_1.update!(startdate: Time.zone.local(2021, 5, 1)) + Timecop.unfreeze allow(lettings_log_year_1.form).to receive(:end_date).and_return(Time.zone.today + 1.day) end @@ -663,6 +664,15 @@ RSpec.describe FormController, type: :request do end let(:referrer) { "/lettings-logs/#{completed_lettings_log.id}/net-income-value-check?referrer=check_answers" } + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + before do completed_lettings_log.update!(ecstat1: 1, earnings: 130, hhmemb: 1) # we're not routing to that page, so it gets cleared? allow(completed_lettings_log).to receive(:net_income_soft_validation_triggered?).and_return(true) diff --git a/spec/requests/lettings_logs_controller_spec.rb b/spec/requests/lettings_logs_controller_spec.rb index 9db2c3236..066cd1f35 100644 --- a/spec/requests/lettings_logs_controller_spec.rb +++ b/spec/requests/lettings_logs_controller_spec.rb @@ -108,7 +108,7 @@ RSpec.describe LettingsLogsController, type: :request do lettings_log_params.merge(org_params) { |_k, a_val, b_val| a_val.merge(b_val) } end - it "marks the record as completed" do + xit "marks the record as completed" do json_response = JSON.parse(response.body) expect(json_response).not_to have_key("errors") @@ -252,24 +252,36 @@ RSpec.describe LettingsLogsController, type: :request do end it "does have organisation values" do - get "/lettings-logs", headers: headers, params: {} + get "/lettings-logs", headers:, params: {} expect(page).to have_content("Owned by") expect(page).to have_content("Managed by") end it "shows lettings logs for all organisations" do - get "/lettings-logs", headers: headers, params: {} + get "/lettings-logs", headers:, params: {} expect(page).to have_content("LC783") expect(page).to have_content("UA984") end + it "displays CSV download links with the correct paths" do + get "/lettings-logs", headers:, params: {} + expect(page).to have_link("Download (CSV)", href: "/lettings-logs/csv-download?codes_only=false") + expect(page).to have_link("Download (CSV, codes only)", href: "/lettings-logs/csv-download?codes_only=true") + end + context "when there are no logs in the database" do before do LettingsLog.destroy_all end + it "does not display CSV download links" do + get "/lettings-logs", headers:, params: {} + expect(page).not_to have_link("Download (CSV)") + expect(page).not_to have_link("Download (CSV, codes only)") + end + it "page has correct title" do - get "/lettings-logs", headers: headers, params: {} + get "/lettings-logs", headers:, params: {} expect(page).to have_title("Logs - Submit social housing lettings and sales data (CORE) - GOV.UK") end end @@ -292,35 +304,42 @@ RSpec.describe LettingsLogsController, type: :request do end it "shows lettings logs for multiple selected statuses" do - get "/lettings-logs?status[]=in_progress&status[]=completed", headers: headers, params: {} + get "/lettings-logs?status[]=in_progress&status[]=completed", headers:, params: {} expect(page).to have_link(in_progress_lettings_log.id.to_s) expect(page).to have_link(completed_lettings_log.id.to_s) end it "shows lettings logs for one selected status" do - get "/lettings-logs?status[]=in_progress", headers: headers, params: {} + get "/lettings-logs?status[]=in_progress", headers:, params: {} expect(page).to have_link(in_progress_lettings_log.id.to_s) expect(page).not_to have_link(completed_lettings_log.id.to_s) end it "filters on organisation" do - get "/lettings-logs?organisation[]=#{organisation_2.id}", headers: headers, params: {} + get "/lettings-logs?organisation[]=#{organisation_2.id}", headers:, params: {} expect(page).to have_link(completed_lettings_log.id.to_s) expect(page).not_to have_link(in_progress_lettings_log.id.to_s) end it "does not reset the filters" do - get "/lettings-logs?status[]=in_progress", headers: headers, params: {} + get "/lettings-logs?status[]=in_progress", headers:, params: {} expect(page).to have_link(in_progress_lettings_log.id.to_s) expect(page).not_to have_link(completed_lettings_log.id.to_s) - get "/lettings-logs", headers: headers, params: {} + get "/lettings-logs", headers:, params: {} expect(page).to have_link(in_progress_lettings_log.id.to_s) expect(page).not_to have_link(completed_lettings_log.id.to_s) end end context "with year filter" do + around do |example| + Timecop.freeze(2022, 3, 1) do + example.run + end + Timecop.return + end + let!(:lettings_log_2021) do FactoryBot.create(:lettings_log, :in_progress, created_by: user, @@ -338,13 +357,13 @@ RSpec.describe LettingsLogsController, type: :request do end it "shows lettings logs for multiple selected years" do - get "/lettings-logs?years[]=2021&years[]=2022", headers: headers, params: {} + get "/lettings-logs?years[]=2021&years[]=2022", headers:, params: {} expect(page).to have_link(lettings_log_2021.id.to_s) expect(page).to have_link(lettings_log_2022.id.to_s) end it "shows lettings logs for one selected year" do - get "/lettings-logs?years[]=2021", headers: headers, params: {} + get "/lettings-logs?years[]=2021", headers:, params: {} expect(page).to have_link(lettings_log_2021.id.to_s) expect(page).not_to have_link(lettings_log_2022.id.to_s) end @@ -352,6 +371,8 @@ RSpec.describe LettingsLogsController, type: :request do context "with year and status filter" do before do + Timecop.freeze(Time.zone.local(2022, 3, 1)) + lettings_log_2021.update!(startdate: Time.zone.local(2022, 3, 1)) Timecop.freeze(Time.zone.local(2022, 12, 1)) end @@ -362,7 +383,6 @@ RSpec.describe LettingsLogsController, type: :request do let!(:lettings_log_2021) do FactoryBot.create(:lettings_log, :in_progress, owning_organisation: organisation, - startdate: Time.zone.local(2022, 3, 1), managing_organisation: organisation, created_by: user) end @@ -371,6 +391,7 @@ RSpec.describe LettingsLogsController, type: :request do owning_organisation: organisation, mrcdate: Time.zone.local(2022, 2, 1), startdate: Time.zone.local(2022, 12, 1), + voiddate: Time.zone.local(2022, 2, 1), tenancy: 6, managing_organisation: organisation, created_by: user) @@ -387,14 +408,14 @@ RSpec.describe LettingsLogsController, type: :request do end it "shows lettings logs for multiple selected statuses and years" do - get "/lettings-logs?years[]=2021&years[]=2022&status[]=in_progress&status[]=completed", headers: headers, params: {} + get "/lettings-logs?years[]=2021&years[]=2022&status[]=in_progress&status[]=completed", headers:, params: {} expect(page).to have_link(lettings_log_2021.id.to_s) expect(page).to have_link(lettings_log_2022.id.to_s) expect(page).to have_link(lettings_log_2022_in_progress.id.to_s) end it "shows lettings logs for one selected status" do - get "/lettings-logs?years[]=2022&status[]=in_progress", headers: headers, params: {} + get "/lettings-logs?years[]=2022&status[]=in_progress", headers:, params: {} expect(page).to have_link(lettings_log_2022_in_progress.id.to_s) expect(page).not_to have_link(lettings_log_2021.id.to_s) expect(page).not_to have_link(lettings_log_2022.id.to_s) @@ -512,23 +533,36 @@ RSpec.describe LettingsLogsController, type: :request do end it "does not have organisation columns" do - get "/lettings-logs", headers: headers, params: {} + get "/lettings-logs", headers:, params: {} expect(page).not_to have_content("Owning organisation") expect(page).not_to have_content("Managing organisation") end + it "displays standard CSV download link only, with the correct path" do + get "/lettings-logs", headers:, params: {} + expect(page).to have_link("Download (CSV)", href: "/lettings-logs/csv-download?codes_only=false") + expect(page).not_to have_link("Download (CSV, codes only)") + end + + it "does not display CSV download links if there are no logs" do + LettingsLog.destroy_all + get "/lettings-logs", headers:, params: {} + expect(page).not_to have_link("Download (CSV)") + expect(page).not_to have_link("Download (CSV, codes only)") + end + context "when using a search query" do let(:logs) { FactoryBot.create_list(:lettings_log, 3, :completed, owning_organisation: user.organisation, created_by: user) } let(:log_to_search) { FactoryBot.create(:lettings_log, :completed, owning_organisation: user.organisation, created_by: user) } let(:log_total_count) { LettingsLog.where(owning_organisation: user.organisation).count } it "has search results in the title" do - get "/lettings-logs?search=#{log_to_search.id}", headers: headers, params: {} + get "/lettings-logs?search=#{log_to_search.id}", headers:, params: {} expect(page).to have_title("Logs (1 logs matching ‘#{log_to_search.id}’) - Submit social housing lettings and sales data (CORE) - GOV.UK") end it "shows lettings logs matching the id" do - get "/lettings-logs?search=#{log_to_search.id}", headers: headers, params: {} + get "/lettings-logs?search=#{log_to_search.id}", headers:, params: {} expect(page).to have_link(log_to_search.id.to_s) logs.each do |log| expect(page).not_to have_link(log.id.to_s) @@ -536,7 +570,7 @@ RSpec.describe LettingsLogsController, type: :request do end it "shows lettings logs matching the tenant code" do - get "/lettings-logs?search=#{log_to_search.tenancycode}", headers: headers, params: {} + get "/lettings-logs?search=#{log_to_search.tenancycode}", headers:, params: {} expect(page).to have_link(log_to_search.id.to_s) logs.each do |log| expect(page).not_to have_link(log.id.to_s) @@ -544,7 +578,7 @@ RSpec.describe LettingsLogsController, type: :request do end it "shows lettings logs matching the property reference" do - get "/lettings-logs?search=#{log_to_search.propcode}", headers: headers, params: {} + get "/lettings-logs?search=#{log_to_search.propcode}", headers:, params: {} expect(page).to have_link(log_to_search.id.to_s) logs.each do |log| expect(page).not_to have_link(log.id.to_s) @@ -552,25 +586,27 @@ RSpec.describe LettingsLogsController, type: :request do end it "shows lettings logs matching the property postcode" do - get "/lettings-logs?search=#{log_to_search.postcode_full}", headers: headers, params: {} + get "/lettings-logs?search=#{log_to_search.postcode_full}", headers:, params: {} expect(page).to have_link(log_to_search.id.to_s) logs.each do |log| expect(page).not_to have_link(log.id.to_s) end end - it "includes the search on the CSV link" do + it "includes the search on the CSV links" do search_term = "foo" FactoryBot.create(:lettings_log, created_by: user, owning_organisation: user.organisation, tenancycode: "foo") - get "/lettings-logs?search=#{search_term}", headers: headers, params: {} - expect(page).to have_link("Download (CSV)", href: "/lettings-logs/csv-download?search=#{search_term}") + get "/lettings-logs?search=#{search_term}", headers:, params: {} + download_link = page.find_link("Download (CSV)") + download_link_params = CGI.parse(URI.parse(download_link[:href]).query) + expect(download_link_params).to include("search" => [search_term]) end context "when more than one results with matching postcode" do let!(:matching_postcode_log) { FactoryBot.create(:lettings_log, :completed, owning_organisation: user.organisation, postcode_full: log_to_search.postcode_full) } it "displays all matching logs" do - get "/lettings-logs?search=#{log_to_search.postcode_full}", headers: headers, params: {} + get "/lettings-logs?search=#{log_to_search.postcode_full}", headers:, params: {} expect(page).to have_link(log_to_search.id.to_s) expect(page).to have_link(matching_postcode_log.id.to_s) logs.each do |log| @@ -585,12 +621,12 @@ RSpec.describe LettingsLogsController, type: :request do let(:log_total_count) { LettingsLog.where(owning_organisation: user.organisation).count } it "has title with pagination details for page 1" do - get "/lettings-logs?search=#{logs[0].postcode_full}", headers: headers, params: {} + get "/lettings-logs?search=#{logs[0].postcode_full}", headers:, params: {} expect(page).to have_title("Logs (#{logs.count} logs matching ‘#{postcode}’) (page 1 of 2) - Submit social housing lettings and sales data (CORE) - GOV.UK") end it "has title with pagination details for page 2" do - get "/lettings-logs?search=#{logs[0].postcode_full}&page=2", headers: headers, params: {} + get "/lettings-logs?search=#{logs[0].postcode_full}&page=2", headers:, params: {} expect(page).to have_title("Logs (#{logs.count} logs matching ‘#{postcode}’) (page 2 of 2) - Submit social housing lettings and sales data (CORE) - GOV.UK") end end @@ -621,7 +657,7 @@ RSpec.describe LettingsLogsController, type: :request do let!(:log_matching_filter_and_search) { FactoryBot.create(:lettings_log, :in_progress, owning_organisation: user.organisation, postcode_full: matching_postcode, created_by: user) } it "shows only logs matching both search and filters" do - get "/lettings-logs?search=#{matching_postcode}&status[]=#{matching_status}", headers: headers, params: {} + get "/lettings-logs?search=#{matching_postcode}&status[]=#{matching_status}", headers:, params: {} expect(page).to have_link(log_matching_filter_and_search.id.to_s) expect(page).not_to have_link(log_to_search.id.to_s) logs.each do |log| @@ -631,7 +667,7 @@ RSpec.describe LettingsLogsController, type: :request do end end - context "when there are less than 20 logs" do + context "when there are fewer than 20 logs" do before do get "/lettings-logs", headers:, params: {} end @@ -675,7 +711,7 @@ RSpec.describe LettingsLogsController, type: :request do end it "shows the CSV download link" do - expect(page).to have_link("Download (CSV)", href: "/lettings-logs/csv-download") + expect(page).to have_link("Download (CSV)", href: "/lettings-logs/csv-download?codes_only=false") end it "does not show the organisation filter" do @@ -809,7 +845,7 @@ RSpec.describe LettingsLogsController, type: :request do context "with a user that is not signed in" do it "does not let the user get lettings log tasklist pages they don't have access to" do - get "/lettings-logs/#{lettings_log.id}", headers: headers, params: {} + get "/lettings-logs/#{lettings_log.id}", headers:, params: {} expect(response).to redirect_to("/account/sign-in") end end @@ -819,6 +855,10 @@ RSpec.describe LettingsLogsController, type: :request do before do sign_in user get "/lettings-logs/#{lettings_log.id}", headers:, params: {} + Timecop.freeze(2021, 4, 1) + completed_lettings_log.update!(startdate: Time.zone.local(2021, 4, 1), voiddate: Time.zone.local(2021, 4, 1), mrcdate: Time.zone.local(2021, 4, 1)) + completed_lettings_log.reload + Timecop.unfreeze end it "shows the tasklist for lettings logs you have access to" do @@ -844,9 +884,6 @@ RSpec.describe LettingsLogsController, type: :request do end it "displays a closed collection window message for previous collection year logs" do - completed_lettings_log.update!(startdate: Time.zone.local(2021, 4, 1)) - completed_lettings_log.reload - get "/lettings-logs/#{completed_lettings_log.id}", headers:, params: {} expect(completed_lettings_log.form.end_date).to eq(Time.zone.local(2022, 7, 1)) expect(completed_lettings_log.status).to eq("completed") @@ -913,19 +950,22 @@ RSpec.describe LettingsLogsController, type: :request do end context "when accessing the check answers page" do + before do + Timecop.freeze(2021, 4, 1) + completed_lettings_log.update!(startdate: Time.zone.local(2021, 4, 1), voiddate: Time.zone.local(2021, 4, 1), mrcdate: Time.zone.local(2021, 4, 1)) + Timecop.unfreeze + stub_request(:get, /api.postcodes.io/) + .to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\", \"codes\":{\"admin_district\": \"E08000003\"}}}", headers: {}) + sign_in user + end + let(:postcode_lettings_log) do FactoryBot.create(:lettings_log, created_by: user, postcode_known: "No") end let(:id) { postcode_lettings_log.id } - let(:completed_lettings_log) { FactoryBot.create(:lettings_log, :completed, owning_organisation: user.organisation, managing_organisation: user.organisation, created_by: user, startdate: Time.zone.local(2021, 4, 1)) } - - before do - stub_request(:get, /api.postcodes.io/) - .to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\", \"codes\":{\"admin_district\": \"E08000003\"}}}", headers: {}) - sign_in user - end + let(:completed_lettings_log) { FactoryBot.create(:lettings_log, :completed, owning_organisation: user.organisation, managing_organisation: user.organisation, created_by: user) } it "shows the inferred la" do lettings_log = FactoryBot.create(:lettings_log, @@ -975,7 +1015,7 @@ RSpec.describe LettingsLogsController, type: :request do before do sign_in user - get "/lettings-logs/csv-download?search=#{search_term}", headers: + get "/lettings-logs/csv-download?search=#{search_term}&codes_only=false", headers: end it "returns http success" do @@ -1127,6 +1167,15 @@ RSpec.describe LettingsLogsController, type: :request do end context "with an invalid lettings log params" do + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + let(:params) { { age1: 200 } } it "returns 422" do @@ -1246,8 +1295,91 @@ RSpec.describe LettingsLogsController, type: :request do end end + describe "GET #csv-download" do + let(:page) { Capybara::Node::Simple.new(response.body) } + let(:user) { FactoryBot.create(:user) } + let(:headers) { { "Accept" => "text/html" } } + + before do + allow(user).to receive(:need_two_factor_authentication?).and_return(false) + sign_in user + end + + it "renders a page with the correct header" do + get "/lettings-logs/csv-download?codes_only=false", headers:, params: {} + header = page.find_css("h1") + expect(header.text).to include("Download CSV") + end + + it "renders a form with the correct target containing a button with the correct text" do + get "/lettings-logs/csv-download?codes_only=false", headers:, params: {} + form = page.find("form.button_to") + expect(form[:method]).to eq("post") + expect(form[:action]).to eq("/lettings-logs/email-csv") + expect(form).to have_button("Send email") + end + + it "when query string contains search parameter, form contains hidden field with correct value" do + search_term = "blam" + get "/lettings-logs/csv-download?codes_only=false&search=#{search_term}", headers:, params: {} + hidden_field = page.find("form.button_to").find_field("search", type: "hidden") + expect(hidden_field.value).to eq(search_term) + end + + context "when the user is a data coordinator" do + let(:user) { FactoryBot.create(:user, :data_coordinator) } + + it "when codes_only query parameter is false, form contains hidden field with correct value" do + codes_only = false + get "/lettings-logs/csv-download?codes_only=#{codes_only}", headers:, params: {} + hidden_field = page.find("form.button_to").find_field("codes_only", type: "hidden") + expect(hidden_field.value).to eq(codes_only.to_s) + end + + it "when codes_only query parameter is true, user is not authorized" do + codes_only = true + get "/lettings-logs/csv-download?codes_only=#{codes_only}", headers:, params: {} + expect(response).to have_http_status(:unauthorized) + end + end + + context "when the user is a data provider" do + it "when codes_only query parameter is false, form contains hidden field with correct value" do + codes_only = false + get "/lettings-logs/csv-download?codes_only=#{codes_only}", headers:, params: {} + hidden_field = page.find("form.button_to").find_field("codes_only", type: "hidden") + expect(hidden_field.value).to eq(codes_only.to_s) + end + + it "when codes_only query parameter is true, user is not authorized" do + codes_only = true + get "/lettings-logs/csv-download?codes_only=#{codes_only}", headers:, params: {} + expect(response).to have_http_status(:unauthorized) + end + end + + context "when the user is a support user" do + let(:user) { FactoryBot.create(:user, :support) } + + it "when codes_only query parameter is false, form contains hidden field with correct value" do + codes_only = false + get "/lettings-logs/csv-download?codes_only=#{codes_only}", headers:, params: {} + hidden_field = page.find("form.button_to").find_field("codes_only", type: "hidden") + expect(hidden_field.value).to eq(codes_only.to_s) + end + + it "when codes_only query parameter is true, form contains hidden field with correct value" do + codes_only = true + get "/lettings-logs/csv-download?codes_only=#{codes_only}", headers:, params: {} + hidden_field = page.find("form.button_to").find_field("codes_only", type: "hidden") + expect(hidden_field.value).to eq(codes_only.to_s) + end + end + end + describe "POST #email-csv" do let(:other_organisation) { FactoryBot.create(:organisation) } + let(:user) { FactoryBot.create(:user, :support) } context "when a log exists" do let!(:lettings_log) do @@ -1259,6 +1391,7 @@ RSpec.describe LettingsLogsController, type: :request do end before do + allow(user).to receive(:need_two_factor_authentication?).and_return(false) sign_in user FactoryBot.create(:lettings_log) FactoryBot.create(:lettings_log, @@ -1270,33 +1403,59 @@ RSpec.describe LettingsLogsController, type: :request do it "creates an E-mail job" do expect { - post "/lettings-logs/email-csv", headers:, params: {} - }.to enqueue_job(EmailCsvJob).with(user, nil, {}, false) + post "/lettings-logs/email-csv?codes_only=true", headers:, params: {} + }.to enqueue_job(EmailCsvJob).with(user, nil, {}, false, nil, true) end it "redirects to the confirmation page" do - post "/lettings-logs/email-csv", headers:, params: {} + post "/lettings-logs/email-csv?codes_only=true", headers:, params: {} expect(response).to redirect_to(csv_confirmation_lettings_logs_path) end it "passes the search term" do expect { - post "/lettings-logs/email-csv?search=#{lettings_log.id}", headers:, params: {} - }.to enqueue_job(EmailCsvJob).with(user, lettings_log.id.to_s, {}, false) + post "/lettings-logs/email-csv?search=#{lettings_log.id}&codes_only=false", headers:, params: {} + }.to enqueue_job(EmailCsvJob).with(user, lettings_log.id.to_s, {}, false, nil, false) end it "passes filter parameters" do expect { - post "/lettings-logs/email-csv?status[]=completed", headers:, params: {} - }.to enqueue_job(EmailCsvJob).with(user, nil, { "status" => %w[completed] }, false) + post "/lettings-logs/email-csv?status[]=completed&codes_only=true", headers:, params: {} + }.to enqueue_job(EmailCsvJob).with(user, nil, { "status" => %w[completed] }, false, nil, true) end - it "passes a combination of search term and filter parameters" do + it "passes export type flag" do + expect { + post "/lettings-logs/email-csv?codes_only=true", headers:, params: {} + }.to enqueue_job(EmailCsvJob).with(user, nil, {}, false, nil, true) + expect { + post "/lettings-logs/email-csv?codes_only=false", headers:, params: {} + }.to enqueue_job(EmailCsvJob).with(user, nil, {}, false, nil, false) + end + + it "passes a combination of search term, export type and filter parameters" do postcode = "XX1 1TG" expect { - post "/lettings-logs/email-csv?status[]=completed&search=#{postcode}", headers:, params: {} - }.to enqueue_job(EmailCsvJob).with(user, postcode, { "status" => %w[completed] }, false) + post "/lettings-logs/email-csv?status[]=completed&search=#{postcode}&codes_only=false", headers:, params: {} + }.to enqueue_job(EmailCsvJob).with(user, postcode, { "status" => %w[completed] }, false, nil, false) + end + + context "when the user is not a support user" do + let(:user) { FactoryBot.create(:user, :data_coordinator) } + + it "has permission to download human readable csv" do + codes_only_export = false + expect { + post "/lettings-logs/email-csv?codes_only=#{codes_only_export}", headers:, params: {} + }.to enqueue_job(EmailCsvJob).with(user, nil, {}, false, nil, false) + end + + it "is not authorized to download codes only csv" do + codes_only_export = true + post "/lettings-logs/email-csv?codes_only=#{codes_only_export}", headers:, params: {} + expect(response).to have_http_status(:unauthorized) + end end end end diff --git a/spec/requests/locations_controller_spec.rb b/spec/requests/locations_controller_spec.rb index 3b75339ff..154d18735 100644 --- a/spec/requests/locations_controller_spec.rb +++ b/spec/requests/locations_controller_spec.rb @@ -417,7 +417,7 @@ RSpec.describe LocationsController, type: :request do it "redirects correctly when postcodes.io does return a local authority" do follow_redirect! - expect(page).to have_content("What is the name of this location?") + expect(page).to have_content("What is the local authority") end end @@ -478,7 +478,7 @@ RSpec.describe LocationsController, type: :request do it "redirects correctly when postcodes.io does return a local authority" do follow_redirect! - expect(page).to have_content("What is the name of this location?") + expect(page).to have_content("What is the local authority") end end diff --git a/spec/requests/organisations_controller_spec.rb b/spec/requests/organisations_controller_spec.rb index 004ea538a..e7cb7fea3 100644 --- a/spec/requests/organisations_controller_spec.rb +++ b/spec/requests/organisations_controller_spec.rb @@ -1142,11 +1142,12 @@ RSpec.describe OrganisationsController, type: :request do context "when they view the logs tab" do before do FactoryBot.create(:lettings_log, owning_organisation: organisation) - get "/organisations/#{organisation.id}/lettings-logs" end - it "has a CSV download button with the correct path if at least 1 log exists" do - expect(page).to have_link("Download (CSV)", href: "/organisations/#{organisation.id}/logs/csv-download") + it "has CSV download buttons with the correct paths if at least 1 log exists" do + get "/organisations/#{organisation.id}/lettings-logs" + expect(page).to have_link("Download (CSV)", href: "/organisations/#{organisation.id}/logs/csv-download?codes_only=false") + expect(page).to have_link("Download (CSV, codes only)", href: "/organisations/#{organisation.id}/logs/csv-download?codes_only=true") end context "when you download the CSV" do @@ -1158,16 +1159,64 @@ RSpec.describe OrganisationsController, type: :request do end it "only includes logs from that organisation" do - get "/organisations/#{organisation.id}/logs/csv-download" + get "/organisations/#{organisation.id}/logs/csv-download?codes_only=false" expect(page).to have_text("You've selected 3 logs.") end it "provides the organisation to the mail job" do expect { - post "/organisations/#{organisation.id}/logs/email-csv?status[]=completed", headers:, params: {} - }.to enqueue_job(EmailCsvJob).with(user, nil, { "status" => %w[completed] }, false, organisation) + post "/organisations/#{organisation.id}/logs/email-csv?status[]=completed&codes_only=false", headers:, params: {} + }.to enqueue_job(EmailCsvJob).with(user, nil, { "status" => %w[completed] }, false, organisation, false) end + + it "provides the export type to the mail job" do + codes_only_export_type = false + expect { + post "/organisations/#{organisation.id}/logs/email-csv?codes_only=#{codes_only_export_type}", headers:, params: {} + }.to enqueue_job(EmailCsvJob).with(user, nil, {}, false, organisation, codes_only_export_type) + codes_only_export_type = true + expect { + post "/organisations/#{organisation.id}/logs/email-csv?codes_only=#{codes_only_export_type}", headers:, params: {} + }.to enqueue_job(EmailCsvJob).with(user, nil, {}, false, organisation, codes_only_export_type) + end + end + end + + describe "GET #download_csv" do + it "renders a page with the correct header" do + get "/organisations/#{organisation.id}/logs/csv-download?codes_only=false", headers:, params: {} + header = page.find_css("h1") + expect(header.text).to include("Download CSV") + end + + it "renders a form with the correct target containing a button with the correct text" do + get "/organisations/#{organisation.id}/logs/csv-download?codes_only=false", headers:, params: {} + form = page.find("form.button_to") + expect(form[:method]).to eq("post") + expect(form[:action]).to eq("/organisations/#{organisation.id}/logs/email-csv") + expect(form).to have_button("Send email") + end + + it "when codes_only query parameter is false, form contains hidden field with correct value" do + codes_only = false + get "/organisations/#{organisation.id}/logs/csv-download?codes_only=#{codes_only}", headers:, params: {} + hidden_field = page.find("form.button_to").find_field("codes_only", type: "hidden") + expect(hidden_field.value).to eq(codes_only.to_s) + end + + it "when codes_only query parameter is true, form contains hidden field with correct value" do + codes_only = true + get "/organisations/#{organisation.id}/logs/csv-download?codes_only=#{codes_only}", headers:, params: {} + hidden_field = page.find("form.button_to").find_field("codes_only", type: "hidden") + expect(hidden_field.value).to eq(codes_only.to_s) + end + + it "when query string contains search parameter, form contains hidden field with correct value" do + search_term = "blam" + get "/organisations/#{organisation.id}/logs/csv-download?codes_only=true&search=#{search_term}", headers:, params: {} + hidden_field = page.find("form.button_to").find_field("search", type: "hidden") + expect(hidden_field.value).to eq(search_term) end end diff --git a/spec/requests/sales_logs_controller_spec.rb b/spec/requests/sales_logs_controller_spec.rb index e45fee440..0a7ca0790 100644 --- a/spec/requests/sales_logs_controller_spec.rb +++ b/spec/requests/sales_logs_controller_spec.rb @@ -231,12 +231,11 @@ RSpec.describe SalesLogsController, type: :request do end context "with year and status filter" do - before do - Timecop.freeze(Time.zone.local(2022, 12, 1)) - end - - after do - Timecop.unfreeze + around do |example| + Timecop.freeze(2022, 12, 1) do + example.run + end + Timecop.return end let!(:sales_log_2022) do diff --git a/spec/services/bulk_upload/lettings/log_creator_spec.rb b/spec/services/bulk_upload/lettings/log_creator_spec.rb index 39dfd00fe..8b320c35f 100644 --- a/spec/services/bulk_upload/lettings/log_creator_spec.rb +++ b/spec/services/bulk_upload/lettings/log_creator_spec.rb @@ -30,9 +30,9 @@ RSpec.describe BulkUpload::Lettings::LogCreator do let(:log) { LettingsLog.new } before do - file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_csv_row) + file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_2022_csv_row) file.rewind end @@ -61,7 +61,7 @@ RSpec.describe BulkUpload::Lettings::LogCreator do end before do - file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_csv_row) + file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_2022_csv_row) file.rewind end diff --git a/spec/services/bulk_upload/lettings/validator_spec.rb b/spec/services/bulk_upload/lettings/validator_spec.rb index b9d351281..f7048fa27 100644 --- a/spec/services/bulk_upload/lettings/validator_spec.rb +++ b/spec/services/bulk_upload/lettings/validator_spec.rb @@ -28,6 +28,18 @@ RSpec.describe BulkUpload::Lettings::Validator do end end + context "when file has too few columns" do + before do + file.write("a," * 132) + file.write("\n") + file.rewind + end + + it "is not valid" do + expect(validator).not_to be_valid + end + end + context "when incorrect headers" end @@ -53,12 +65,52 @@ RSpec.describe BulkUpload::Lettings::Validator do expect(error.col).to eql("L") expect(error.category).to be_nil - error = BulkUploadError.order(:row, :field).find_by(field: "field_111") + error = BulkUploadError.find_by(row: "7", category: "setup", field: "field_111") expect(error.category).to eql("setup") end end + context "with arbitrary ordered 23/24 csv" do + let(:bulk_upload) { create(:bulk_upload, user:, year: 2023) } + let(:log) { build(:lettings_log, :completed) } + let(:file) { Tempfile.new } + let(:path) { file.path } + let(:seed) { 321 } + + around do |example| + FormHandler.instance.use_real_forms! + + example.run + + FormHandler.instance.use_fake_forms! + end + + before do + file.write(BulkUpload::LogToCsv.new(log:, line_ending: "\r\n").default_2023_field_numbers_row(seed:)) + file.write(BulkUpload::LogToCsv.new(log:, line_ending: "\r\n").to_2023_csv_row(seed:)) + file.close + end + + it "creates validation errors" do + expect { validator.call }.to change(BulkUploadError, :count) + end + + it "create validation error with correct values" do + validator.call + + error = BulkUploadError.find_by(field: "field_5") + + expect(error.field).to eql("field_5") + expect(error.error).to eql("You must answer letting type") + expect(error.tenant_code).to eql(log.tenancycode) + expect(error.property_ref).to eql(log.propcode) + expect(error.row).to eql("2") + expect(error.cell).to eql("DD2") + expect(error.col).to eql("DD") + end + end + context "with unix line endings" do let(:fixture_path) { file_fixture("2022_23_lettings_bulk_upload.csv") } let(:file) { Tempfile.new } @@ -82,7 +134,7 @@ RSpec.describe BulkUpload::Lettings::Validator do let(:path) { file.path } before do - file.write(BulkUpload::LogToCsv.new(log:, line_ending: "\r\n", col_offset: 0).to_csv_row) + file.write(BulkUpload::LogToCsv.new(log:, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) file.close end @@ -122,8 +174,8 @@ RSpec.describe BulkUpload::Lettings::Validator do let(:log_2) { build(:lettings_log, :completed, created_by: user) } before do - file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0, overrides: { illness: 100 }).to_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0, overrides: { illness: 100 }).to_2022_csv_row) file.close end @@ -138,8 +190,8 @@ RSpec.describe BulkUpload::Lettings::Validator do let(:log_2) { build(:lettings_log, :completed, renttype: 1, created_by: user) } before do - file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0).to_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) file.close end @@ -155,7 +207,7 @@ RSpec.describe BulkUpload::Lettings::Validator do let(:log_1) { build(:lettings_log, :completed, renttype: 1, created_by: user, owning_organisation: unaffiliated_org) } before do - file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) file.close end @@ -169,7 +221,7 @@ RSpec.describe BulkUpload::Lettings::Validator do let(:log) { build(:lettings_log, :in_progress, created_by: user, startdate: Time.zone.local(2022, 5, 1)) } before do - file.write(BulkUpload::LogToCsv.new(log:, line_ending: "\r\n", col_offset: 0).to_csv_row) + file.write(BulkUpload::LogToCsv.new(log:, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) file.close end @@ -188,11 +240,11 @@ RSpec.describe BulkUpload::Lettings::Validator do let(:log_5) { build(:lettings_log, renttype: 2, created_by: user, builtype: nil, startdate: Time.zone.local(2022, 5, 1)) } before do - file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_3, line_ending: "\r\n", col_offset: 0).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_4, line_ending: "\r\n", col_offset: 0).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_5, line_ending: "\r\n", col_offset: 0).to_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_3, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_4, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_5, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) file.close end @@ -210,11 +262,11 @@ RSpec.describe BulkUpload::Lettings::Validator do let(:log_5) { build(:lettings_log, renttype: 2, created_by: user, builtype: nil, startdate: Time.zone.local(2022, 5, 1)) } before do - file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_3, line_ending: "\r\n", col_offset: 0).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_4, line_ending: "\r\n", col_offset: 0).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_5, line_ending: "\r\n", col_offset: 0).to_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_3, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_4, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_5, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) file.close end @@ -238,11 +290,11 @@ RSpec.describe BulkUpload::Lettings::Validator do let(:log_5) { build(:lettings_log, renttype: 2, created_by: user, builtype: nil, startdate: Time.zone.local(2022, 5, 1)) } before do - file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_3, line_ending: "\r\n", col_offset: 0).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_4, line_ending: "\r\n", col_offset: 0).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_5, line_ending: "\r\n", col_offset: 0).to_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_3, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_4, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_5, line_ending: "\r\n", col_offset: 0).to_2022_csv_row) file.close end @@ -262,11 +314,11 @@ RSpec.describe BulkUpload::Lettings::Validator do before do overrides = { age1: 50, age2: "R", age3: "R", age4: "4", age5: "R", age6: "R", age7: "R", age8: "R" } - file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0, overrides:).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0, overrides:).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_3, line_ending: "\r\n", col_offset: 0, overrides:).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_4, line_ending: "\r\n", col_offset: 0, overrides:).to_csv_row) - file.write(BulkUpload::LogToCsv.new(log: log_5, line_ending: "\r\n", col_offset: 0, overrides:).to_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0, overrides:).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0, overrides:).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_3, line_ending: "\r\n", col_offset: 0, overrides:).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_4, line_ending: "\r\n", col_offset: 0, overrides:).to_2022_csv_row) + file.write(BulkUpload::LogToCsv.new(log: log_5, line_ending: "\r\n", col_offset: 0, overrides:).to_2022_csv_row) file.close end diff --git a/spec/services/bulk_upload/lettings/csv_parser_spec.rb b/spec/services/bulk_upload/lettings/year2022/csv_parser_spec.rb similarity index 67% rename from spec/services/bulk_upload/lettings/csv_parser_spec.rb rename to spec/services/bulk_upload/lettings/year2022/csv_parser_spec.rb index 80c8e37dc..d396ad78e 100644 --- a/spec/services/bulk_upload/lettings/csv_parser_spec.rb +++ b/spec/services/bulk_upload/lettings/year2022/csv_parser_spec.rb @@ -1,6 +1,6 @@ require "rails_helper" -RSpec.describe BulkUpload::Lettings::CsvParser do +RSpec.describe BulkUpload::Lettings::Year2022::CsvParser do subject(:service) { described_class.new(path:) } let(:path) { file_fixture("2022_23_lettings_bulk_upload.csv") } @@ -22,7 +22,7 @@ RSpec.describe BulkUpload::Lettings::CsvParser do let(:log) { build(:lettings_log, :completed) } before do - file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_csv_row) + file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_2022_csv_row) file.rewind end @@ -44,7 +44,7 @@ RSpec.describe BulkUpload::Lettings::CsvParser do before do file.write(bom) - file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_csv_row) + file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_2022_csv_row) file.close end @@ -61,7 +61,7 @@ RSpec.describe BulkUpload::Lettings::CsvParser do before do file.write(invalid_sequence) - file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_csv_row) + file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_2022_csv_row) file.close end @@ -69,4 +69,29 @@ RSpec.describe BulkUpload::Lettings::CsvParser do expect(service.row_parsers[0].field_12.to_i).to eql(log.age1) end end + + describe "#column_for_field", aggregate_failures: true do + context "when headers present" do + it "returns correct column" do + expect(service.column_for_field("field_1")).to eql("B") + expect(service.column_for_field("field_134")).to eql("EE") + end + end + + context "when no headers" do + let(:file) { Tempfile.new } + let(:path) { file.path } + let(:log) { build(:lettings_log, :completed) } + + before do + file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_2022_csv_row) + file.rewind + end + + it "returns correct column" do + expect(service.column_for_field("field_1")).to eql("A") + expect(service.column_for_field("field_134")).to eql("ED") + end + end + end end diff --git a/spec/services/bulk_upload/lettings/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb similarity index 96% rename from spec/services/bulk_upload/lettings/row_parser_spec.rb rename to spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb index 73b35d70c..f03ea894b 100644 --- a/spec/services/bulk_upload/lettings/row_parser_spec.rb +++ b/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb @@ -1,6 +1,6 @@ require "rails_helper" -RSpec.describe BulkUpload::Lettings::RowParser do +RSpec.describe BulkUpload::Lettings::Year2022::RowParser do subject(:parser) { described_class.new(attributes) } let(:now) { Time.zone.today } @@ -298,10 +298,13 @@ RSpec.describe BulkUpload::Lettings::RowParser do describe "#field_4" do context "when nullable not permitted" do + let(:bulk_upload) { create(:bulk_upload, :lettings, user:, needstype: 2) } let(:attributes) { { bulk_upload:, field_1: "2", field_4: nil } } it "cannot be nulled" do - expect(parser.errors[:field_4]).to be_present + setup_errors = parser.errors.select { |e| e.options[:category] == "setup" } + + expect(setup_errors.find { |e| e.attribute == :field_4 }).to be_present end end @@ -350,6 +353,17 @@ RSpec.describe BulkUpload::Lettings::RowParser do end describe "#field_5" do + context "when not nullable" do + let(:bulk_upload) { create(:bulk_upload, :lettings, user:, needstype: 2) } + let(:attributes) { { bulk_upload:, field_1: "2", field_5: nil } } + + it "cannot be nulled" do + setup_errors = parser.errors.select { |e| e.options[:category] == "setup" } + + expect(setup_errors.find { |e| e.attribute == :field_5 }).to be_present + end + end + context "when location does not exist" do let(:scheme) { create(:scheme, :with_old_visible_id, owning_organisation: owning_org) } let(:attributes) do @@ -544,12 +558,12 @@ RSpec.describe BulkUpload::Lettings::RowParser do context "when all of these fields are blank" do let(:attributes) { { bulk_upload:, field_1: "1", field_96: nil, field_97: nil, field_98: nil } } - it "returns an error" do - parser.valid? + it "returns them as setup errors" do + setup_errors = parser.errors.select { |e| e.options[:category] == :setup } - expect(parser.errors[:field_96]).to be_present - expect(parser.errors[:field_97]).to be_present - expect(parser.errors[:field_98]).to be_present + expect(setup_errors.find { |e| e.attribute == :field_96 }).to be_present + expect(setup_errors.find { |e| e.attribute == :field_97 }).to be_present + expect(setup_errors.find { |e| e.attribute == :field_98 }).to be_present end end @@ -557,8 +571,6 @@ RSpec.describe BulkUpload::Lettings::RowParser do let(:attributes) { { bulk_upload:, field_1: "1", field_96: "1", field_97: "1", field_98: nil } } it "returns an error only on blank field" do - parser.valid? - expect(parser.errors[:field_96]).to be_blank expect(parser.errors[:field_97]).to be_blank expect(parser.errors[:field_98]).to be_present @@ -569,8 +581,6 @@ RSpec.describe BulkUpload::Lettings::RowParser do let(:attributes) { { bulk_upload:, field_98: "2022" } } it "returns an error" do - parser.valid? - expect(parser.errors[:field_98]).to include("Tenancy start year must be 2 digits") end end @@ -589,8 +599,6 @@ RSpec.describe BulkUpload::Lettings::RowParser do let(:bulk_upload) { create(:bulk_upload, :lettings, user:, year: 2022) } it "does not return errors" do - parser.valid? - expect(parser.errors[:field_96]).not_to be_present expect(parser.errors[:field_97]).not_to be_present expect(parser.errors[:field_98]).not_to be_present @@ -602,6 +610,7 @@ RSpec.describe BulkUpload::Lettings::RowParser do Timecop.freeze(Date.new(2022, 4, 2)) do example.run end + Timecop.return end let(:attributes) { { bulk_upload:, field_96: "1", field_97: "1", field_98: "22" } } @@ -609,8 +618,6 @@ RSpec.describe BulkUpload::Lettings::RowParser do let(:bulk_upload) { create(:bulk_upload, :lettings, user:, year: 2022) } it "returns errors" do - parser.valid? - expect(parser.errors[:field_96]).to be_present expect(parser.errors[:field_97]).to be_present expect(parser.errors[:field_98]).to be_present @@ -619,6 +626,16 @@ RSpec.describe BulkUpload::Lettings::RowParser do end describe "#field_111" do # owning org + context "when no data given" do + let(:attributes) { { bulk_upload:, field_1: "1", field_111: "" } } + + it "is not permitted as setup error" do + setup_errors = parser.errors.select { |e| e.options[:category] == :setup } + + expect(setup_errors.find { |e| e.attribute == :field_111 }.message).to eql("The owning organisation code is incorrect") + end + end + context "when cannot find owning org" do let(:attributes) { { bulk_upload:, field_111: "donotexist" } } diff --git a/spec/services/bulk_upload/lettings/year2023/csv_parser_spec.rb b/spec/services/bulk_upload/lettings/year2023/csv_parser_spec.rb new file mode 100644 index 000000000..a8cf227f4 --- /dev/null +++ b/spec/services/bulk_upload/lettings/year2023/csv_parser_spec.rb @@ -0,0 +1,181 @@ +require "rails_helper" + +RSpec.describe BulkUpload::Lettings::Year2023::CsvParser do + subject(:service) { described_class.new(path:) } + + let(:file) { Tempfile.new } + let(:path) { file.path } + let(:log) { build(:lettings_log, :completed) } + + context "when parsing csv with headers" do + before do + file.write("Question\n") + file.write("Additional info\n") + file.write("Values\n") + file.write("Can be empty?\n") + file.write("Type of letting the question applies to\n") + file.write("Duplicate check field?\n") + file.write(BulkUpload::LogToCsv.new(log:).default_2023_field_numbers_row) + file.write(BulkUpload::LogToCsv.new(log:).to_2023_csv_row) + file.rewind + end + + it "returns correct offsets" do + expect(service.row_offset).to eq(7) + expect(service.col_offset).to eq(1) + end + + it "parses csv correctly" do + expect(service.row_parsers[0].field_13).to eql(log.tenancycode) + end + end + + context "when parsing csv with headers with extra rows" do + before do + file.write("Section\n") + file.write("Question\n") + file.write("Additional info\n") + file.write("Values\n") + file.write("Can be empty?\n") + file.write("Type of letting the question applies to\n") + file.write("Duplicate check field?\n") + file.write(BulkUpload::LogToCsv.new(log:).default_2023_field_numbers_row) + file.write(BulkUpload::LogToCsv.new(log:).to_2023_csv_row) + file.rewind + end + + it "returns correct offsets" do + expect(service.row_offset).to eq(8) + expect(service.col_offset).to eq(1) + end + + it "parses csv correctly" do + expect(service.row_parsers[0].field_13).to eql(log.tenancycode) + end + end + + context "when parsing csv with headers in arbitrary order" do + let(:seed) { rand } + + before do + file.write("Question\n") + file.write("Additional info\n") + file.write("Values\n") + file.write("Can be empty?\n") + file.write("Type of letting the question applies to\n") + file.write("Duplicate check field?\n") + file.write(BulkUpload::LogToCsv.new(log:).default_2023_field_numbers_row(seed:)) + file.write(BulkUpload::LogToCsv.new(log:).to_2023_csv_row(seed:)) + file.rewind + end + + it "returns correct offsets" do + expect(service.row_offset).to eq(7) + expect(service.col_offset).to eq(1) + end + + it "parses csv correctly" do + expect(service.row_parsers[0].field_13).to eql(log.tenancycode) + end + end + + context "when parsing csv without headers" do + before do + file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_2023_csv_row) + file.rewind + end + + it "returns correct offsets" do + expect(service.row_offset).to eq(0) + expect(service.col_offset).to eq(0) + end + + it "parses csv correctly" do + expect(service.row_parsers[0].field_13).to eql(log.tenancycode) + end + end + + context "when parsing with BOM aka byte order mark" do + let(:bom) { "\uFEFF" } + + before do + file.write(bom) + file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_2023_csv_row) + file.rewind + end + + it "parses csv correctly" do + expect(service.row_parsers[0].field_13).to eql(log.tenancycode) + end + end + + context "when an invalid byte sequence" do + let(:invalid_sequence) { "\x81" } + + before do + file.write(invalid_sequence) + file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_2023_csv_row) + file.rewind + end + + it "parses csv correctly" do + expect(service.row_parsers[0].field_13).to eql(log.tenancycode) + end + end + + describe "#column_for_field", aggregate_failures: true do + context "when with headers using default ordering" do + before do + file.write("Question\n") + file.write("Additional info\n") + file.write("Values\n") + file.write("Can be empty?\n") + file.write("Type of letting the question applies to\n") + file.write("Duplicate check field?\n") + file.write(BulkUpload::LogToCsv.new(log:).default_2023_field_numbers_row) + file.write(BulkUpload::LogToCsv.new(log:).to_2023_csv_row) + file.rewind + end + + it "returns correct column" do + expect(service.column_for_field("field_5")).to eql("B") + expect(service.column_for_field("field_22")).to eql("EL") + end + end + + context "when without headers using default ordering" do + before do + file.write(BulkUpload::LogToCsv.new(log:, col_offset: 0).to_2023_csv_row) + file.rewind + end + + it "returns correct column" do + expect(service.column_for_field("field_5")).to eql("A") + expect(service.column_for_field("field_22")).to eql("EK") + end + end + + context "when with headers using custom ordering" do + let(:seed) { 123 } + + before do + file.write("Question\n") + file.write("Additional info\n") + file.write("Values\n") + file.write("Can be empty?\n") + file.write("Type of letting the question applies to\n") + file.write("Duplicate check field?\n") + file.write(BulkUpload::LogToCsv.new(log:).default_2023_field_numbers_row(seed:)) + file.write(BulkUpload::LogToCsv.new(log:).to_2023_csv_row(seed:)) + file.rewind + end + + it "returns correct column" do + expect(service.column_for_field("field_5")).to eql("N") + expect(service.column_for_field("field_22")).to eql("O") + expect(service.column_for_field("field_26")).to eql("B") + expect(service.column_for_field("field_25")).to eql("EF") + end + end + end +end diff --git a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb new file mode 100644 index 000000000..80df8f54f --- /dev/null +++ b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb @@ -0,0 +1,1283 @@ +require "rails_helper" + +RSpec.describe BulkUpload::Lettings::Year2023::RowParser do + subject(:parser) { described_class.new(attributes) } + + let(:now) { Time.zone.today } + + let(:attributes) { { bulk_upload: } } + let(:bulk_upload) { create(:bulk_upload, :lettings, user:, needstype: nil) } + let(:user) { create(:user, organisation: owning_org) } + + let(:owning_org) { create(:organisation, :with_old_visible_id) } + let(:managing_org) { create(:organisation, :with_old_visible_id) } + let(:scheme) { create(:scheme, :with_old_visible_id, owning_organisation: owning_org) } + let(:location) { create(:location, :with_old_visible_id, scheme:) } + + let(:setup_section_params) do + { + bulk_upload:, + field_1: owning_org.old_visible_id, + field_2: managing_org.old_visible_id, + field_4: "1", + field_5: "2", + field_6: "2", + field_7: now.day.to_s, + field_8: now.month.to_s, + field_9: now.strftime("%g"), + } + end + + before do + create(:organisation_relationship, parent_organisation: owning_org, child_organisation: managing_org) + end + + around do |example| + FormHandler.instance.use_real_forms! + + example.run + + FormHandler.instance.use_fake_forms! + end + + describe "#blank_row?" do + context "when a new object" do + it "returns true" do + expect(parser).to be_blank_row + end + end + + context "when any field is populated" do + before do + parser.field_1 = "1" + end + + it "returns false" do + expect(parser).not_to be_blank_row + end + end + end + + describe "validations" do + before do + stub_request(:get, /api.postcodes.io/) + .to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\", \"codes\":{\"admin_district\": \"E08000003\"}}}", headers: {}) + + parser.valid? + end + + describe "#valid?" do + context "when the row is blank" do + let(:attributes) { { bulk_upload: } } + + it "returns true" do + expect(parser).to be_valid + end + end + + context "when calling the method multiple times" do + let(:attributes) { { bulk_upload:, field_134: 2 } } + + it "does not add keep adding errors to the pile" do + expect { parser.valid? }.not_to change(parser.errors, :count) + end + end + + context "when valid row" do + let(:attributes) do + { + bulk_upload:, + field_5: "1", + field_13: "123", + field_7: now.day.to_s, + field_8: now.month.to_s, + field_9: now.strftime("%g"), + field_23: "EC1N", + field_24: "2TD", + field_1: owning_org.old_visible_id, + field_2: managing_org.old_visible_id, + field_11: "1", + field_6: "2", + field_29: "2", + field_30: "1", + field_31: "1", + field_32: "1", + field_39: "2", + field_40: "1", + field_41: "2", + field_45: "1", + + field_46: "42", + field_52: "41", + field_56: "20", + field_60: "18", + field_64: "16", + field_68: "14", + field_72: "12", + field_76: "20", + + field_47: "F", + field_53: "M", + field_57: "F", + field_61: "M", + field_65: "F", + field_69: "M", + field_73: "F", + field_77: "M", + + field_48: "17", + field_49: "18", + + field_51: "P", + field_55: "C", + field_59: "X", + field_63: "R", + field_67: "C", + field_71: "C", + field_75: "X", + + field_50: "1", + field_54: "2", + field_58: "6", + field_62: "7", + field_66: "8", + field_70: "9", + field_74: "0", + field_78: "10", + + field_79: "1", + field_80: "4", + field_81: "1", + + field_82: "1", + + field_89: "2", + + field_100: "5", + field_101: "2", + field_102: "31", + field_104: "3", + field_105: "12", + + field_106: "1", + field_107: "EC1N", + field_108: "2TD", + + field_110: "1", + field_111: "1", + field_112: "", + field_113: "1", + field_114: "", + field_115: "", + + field_116: "1", + field_117: "2", + field_118: "2", + + field_119: "2", + + field_120: "1", + field_122: "2000", + field_121: "2", + field_123: "1", + field_124: "1", + + field_126: "4", + field_128: "1234.56", + field_129: "43.32", + field_130: "13.14", + field_131: "101.11", + field_132: "1500.19", + field_133: "1", + field_134: "234.56", + + field_27: "15", + field_28: "0", + field_33: now.day.to_s, + field_34: now.month.to_s, + field_35: now.strftime("%g"), + + field_4: "1", + } + end + + it "returns true" do + expect(parser).to be_valid + end + + it "instantiates a log with everything completed", aggregate_failures: true do + questions = parser.send(:questions).reject do |q| + parser.send(:log).optional_fields.include?(q.id) || q.completed?(parser.send(:log)) + end + + expect(questions.map(&:id).size).to eq(0) + expect(questions.map(&:id)).to eql([]) + end + end + end + + context "when setup section not complete" do + let(:attributes) { { bulk_upload:, field_13: "123" } } + + it "has errors on setup fields" do + errors = parser.errors.select { |e| e.options[:category] == :setup }.map(&:attribute) + + expect(errors).to eql(%i[field_4 field_5 field_7 field_8 field_9 field_1 field_2]) + end + end + + describe "#field_5" do + context "when null" do + let(:attributes) { { bulk_upload:, field_5: nil, field_15: "1" } } + + it "returns an error" do + expect(parser.errors[:field_5]).to be_present + end + end + + context "when incorrect data type" do + let(:attributes) { { bulk_upload:, field_5: "foo" } } + + it "returns an error" do + expect(parser.errors[:field_5]).to be_present + end + end + + context "when unpermitted value" do + let(:attributes) { { bulk_upload:, field_5: "101" } } + + it "returns an error" do + expect(parser.errors[:field_5]).to be_present + end + end + + context "when valid" do + let(:attributes) { { bulk_upload:, field_5: "1", field_4: "1" } } + + it "does not return any errors" do + expect(parser.errors[:field_5]).to be_blank + end + end + + context "when bulk upload is for general needs" do + context "when general needs option selected" do + let(:attributes) { { bulk_upload:, field_5: "1", field_4: "1" } } + + it "is permitted" do + expect(parser.errors[:field_5]).to be_blank + end + end + + context "when supported housing option selected" do + let(:attributes) { { bulk_upload:, field_5: "2", field_4: "1" } } + + it "is not permitted" do + expect(parser.errors[:field_5]).to include("Lettings type must be a general needs type because you selected general needs when uploading the file") + end + end + end + + context "when bulk upload is for supported housing" do + let(:bulk_upload) { create(:bulk_upload, :lettings, user:) } + + context "when general needs option selected" do + let(:attributes) { { bulk_upload:, field_5: "1", field_4: "2" } } + + it "is not permitted" do + expect(parser.errors[:field_5]).to include("Lettings type must be a supported housing type because you selected supported housing when uploading the file") + end + end + + context "when supported housing option selected" do + let(:attributes) { { bulk_upload:, field_5: "2", field_4: "2" } } + + it "is permitted" do + expect(parser.errors[:field_5]).to be_blank + end + end + end + end + + describe "#field_16" do + context "when nullable not permitted" do + let(:attributes) { { bulk_upload:, field_5: "2", field_16: nil } } + + it "cannot be nulled" do + expect(parser.errors[:field_16]).to be_present + end + end + + context "when nullable permitted" do + let(:attributes) { { bulk_upload:, field_5: "1", field_16: nil } } + + it "can be nulled" do + expect(parser.errors[:field_15]).to be_blank + end + end + + context "when matching scheme cannot be found" do + let(:attributes) { { bulk_upload:, field_5: "1", field_16: "123" } } + + it "returns an error" do + expect(parser.errors[:field_16]).to be_present + end + end + + context "when scheme belongs to someone else" do + let(:other_scheme) { create(:scheme, :with_old_visible_id) } + let(:attributes) { { bulk_upload:, field_5: "1", field_16: other_scheme.old_visible_id, field_1: owning_org.old_visible_id } } + + it "returns an error" do + expect(parser.errors[:field_16]).to include("This management group code does not belong to your organisation, or any of your stock owners / managing agents") + end + end + + context "when scheme belongs to owning org" do + let(:scheme) { create(:scheme, :with_old_visible_id, owning_organisation: owning_org) } + let(:attributes) { { bulk_upload:, field_5: "1", field_16: scheme.old_visible_id, field_1: owning_org.old_visible_id } } + + it "does not return an error" do + expect(parser.errors[:field_16]).to be_blank + end + end + + context "when scheme belongs to managing org" do + let(:scheme) { create(:scheme, :with_old_visible_id, owning_organisation: managing_org) } + let(:attributes) { { bulk_upload:, field_5: "1", field_16: scheme.old_visible_id, field_2: managing_org.old_visible_id } } + + it "does not return an error" do + expect(parser.errors[:field_16]).to be_blank + end + end + end + + describe "#field_17" do + context "when location does not exist" do + let(:scheme) { create(:scheme, :with_old_visible_id, owning_organisation: owning_org) } + let(:attributes) do + { + bulk_upload:, + field_5: "1", + field_16: scheme.old_visible_id, + field_17: "dontexist", + field_1: owning_org.old_visible_id, + } + end + + it "returns an error" do + expect(parser.errors[:field_17]).to be_present + end + end + + context "when location exists" do + let(:scheme) { create(:scheme, :with_old_visible_id, owning_organisation: owning_org) } + let(:attributes) do + { + bulk_upload:, + field_5: "1", + field_16: scheme.old_visible_id, + field_17: location.old_visible_id, + field_1: owning_org.old_visible_id, + } + end + + it "does not return an error" do + expect(parser.errors[:field_17]).to be_blank + end + end + + context "when location exists but not related" do + let(:location) { create(:scheme, :with_old_visible_id) } + let(:attributes) do + { + bulk_upload:, + field_5: "1", + field_16: scheme.old_visible_id, + field_17: location.old_visible_id, + field_1: owning_org.old_visible_id, + } + end + + it "returns an error" do + expect(parser.errors[:field_17]).to be_present + end + end + end + + describe "#field_102" do # leaving reason + context "when field_6 is 1 meaning it is a renewal" do + context "when field_102 is 40" do + let(:attributes) { { bulk_upload:, field_102: "40", field_6: "1" } } + + it "is permitted" do + expect(parser.errors[:field_102]).to be_blank + end + end + + context "when field_102 is 42" do + let(:attributes) { { bulk_upload:, field_102: "42", field_6: "1" } } + + it "is permitted" do + expect(parser.errors[:field_102]).to be_blank + end + end + + context "when field_102 is not 40 or 42" do + let(:attributes) { { bulk_upload:, field_102: "1", field_6: "1" } } + + it "is not permitted" do + expect(parser.errors[:field_102]).to be_present + end + end + end + end + + describe "#field_83, #field_84, #field_85" do + context "when more than one item selected" do + let(:attributes) { { bulk_upload:, field_83: "1", field_84: "1" } } + + it "is not permitted" do + expect(parser.errors[:field_83]).to be_present + expect(parser.errors[:field_84]).to be_present + expect(parser.errors[:field_85]).to be_present + end + end + end + + describe "#field_87" do + context "when 1 and another disability field selected" do + let(:attributes) { { bulk_upload:, field_87: "1", field_86: "1" } } + + it "is not permitted" do + expect(parser.errors[:field_87]).to be_present + end + end + end + + describe "#field_88" do + context "when 1 and another disability field selected" do + let(:attributes) { { bulk_upload:, field_88: "1", field_86: "1" } } + + it "is not permitted" do + expect(parser.errors[:field_88]).to be_present + end + end + end + + describe "#field_87, #field_88" do + context "when both 1" do + let(:attributes) { { bulk_upload:, field_87: "1", field_88: "1" } } + + it "is not permitted" do + expect(parser.errors[:field_87]).to be_present + expect(parser.errors[:field_88]).to be_present + end + end + end + + describe "#field_119" do # referral + context "when 3 ie PRP nominated by LA and owning org is LA" do + let(:attributes) { { bulk_upload:, field_119: "3", field_1: owning_org.old_visible_id } } + + it "is not permitted" do + expect(parser.errors[:field_119]).to be_present + end + end + + context "when 4 ie referred by LA and is general needs and owning org is LA" do + let(:attributes) { { bulk_upload:, field_119: "4", field_1: owning_org.old_visible_id.to_s, field_4: "1" } } + + it "is not permitted" do + expect(parser.errors[:field_119]).to be_present + end + end + + context "when 4 ie referred by LA and is general needs and owning org is PRP" do + let(:owning_org) { create(:organisation, :prp, :with_old_visible_id) } + + let(:attributes) { { bulk_upload:, field_119: "4", field_1: owning_org.old_visible_id.to_s } } + + it "is permitted" do + expect(parser.errors[:field_119]).to be_blank + end + end + + context "when 4 ie referred by LA and is not general needs" do + let(:bulk_upload) { create(:bulk_upload, :lettings, user:) } + let(:attributes) { { bulk_upload:, field_119: "4", field_4: "2" } } + + it "is permitted" do + expect(parser.errors[:field_119]).to be_blank + end + end + end + + describe "fields 7, 8, 9 => startdate" do + context "when any one of these fields is blank" do + let(:attributes) { { bulk_upload:, field_5: "1", field_7: nil, field_8: nil, field_9: nil } } + + it "returns an error" do + parser.valid? + + expect(parser.errors[:field_7]).to be_present + expect(parser.errors[:field_8]).to be_present + expect(parser.errors[:field_9]).to be_present + end + end + + context "when field_9 is 4 digits instead of 2" do + let(:attributes) { { bulk_upload:, field_9: "2022" } } + + it "returns an error" do + parser.valid? + + expect(parser.errors[:field_9]).to include("Tenancy start year must be 2 digits") + end + end + + context "when invalid date given" do + let(:attributes) { { bulk_upload:, field_5: "1", field_7: "a", field_8: "12", field_9: "22" } } + + it "does not raise an error" do + expect { parser.valid? }.not_to raise_error + end + end + + context "when inside of collection year" do + let(:attributes) { { bulk_upload:, field_7: "1", field_8: "10", field_9: "22" } } + + let(:bulk_upload) { create(:bulk_upload, :lettings, user:, year: 2022) } + + it "does not return errors" do + parser.valid? + + expect(parser.errors[:field_7]).not_to be_present + expect(parser.errors[:field_8]).not_to be_present + expect(parser.errors[:field_9]).not_to be_present + end + end + + context "when outside of collection year" do + around do |example| + Timecop.freeze(Date.new(2022, 4, 2)) do + example.run + end + Timecop.return + end + + let(:attributes) { { bulk_upload:, field_7: "1", field_8: "1", field_9: "22" } } + + let(:bulk_upload) { create(:bulk_upload, :lettings, user:, year: 2022) } + + it "returns errors" do + parser.valid? + + expect(parser.errors[:field_7]).to be_present + expect(parser.errors[:field_8]).to be_present + expect(parser.errors[:field_9]).to be_present + end + end + end + + describe "#field_1" do # owning org + context "when cannot find owning org" do + let(:attributes) { { bulk_upload:, field_1: "donotexist" } } + + it "is not permitted" do + expect(parser.errors[:field_1]).to eql(["The owning organisation code is incorrect"]) + end + end + + context "when org is not stock owning" do + let(:owning_org) { create(:organisation, :with_old_visible_id, :does_not_own_stock) } + + let(:attributes) { { bulk_upload:, field_1: owning_org.old_visible_id } } + + it "is not permitted" do + expect(parser.errors[:field_1]).to eql(["The owning organisation code provided is for an organisation that does not own stock"]) + end + + it "blocks log creation" do + expect(parser).to be_block_log_creation + end + end + + context "when not affiliated with owning org" do + let(:unaffiliated_org) { create(:organisation, :with_old_visible_id) } + + let(:attributes) { { bulk_upload:, field_1: unaffiliated_org.old_visible_id } } + + it "is not permitted" do + expect(parser.errors[:field_1]).to eql(["You do not have permission to add logs for this owning organisation"]) + end + + it "blocks log creation" do + expect(parser).to be_block_log_creation + end + end + end + + describe "#field_2" do # managing org + context "when cannot find managing org" do + let(:attributes) { { bulk_upload:, field_2: "donotexist" } } + + it "is not permitted" do + expect(parser.errors[:field_2]).to eql(["The managing organisation code is incorrect"]) + end + end + + context "when not affiliated with managing org" do + let(:unaffiliated_org) { create(:organisation, :with_old_visible_id) } + + let(:attributes) { { bulk_upload:, field_1: owning_org.old_visible_id, field_2: unaffiliated_org.old_visible_id } } + + it "is not permitted" do + expect(parser.errors[:field_2]).to eql(["This managing organisation does not have a relationship with the owning organisation"]) + end + + it "blocks log creation" do + expect(parser).to be_block_log_creation + end + end + end + + describe "#field_4" do + context "when blank" do + let(:attributes) { { bulk_upload:, field_4: nil, field_13: "123" } } + + it "is reported as a setup error" do + errors = parser.errors.select { |e| e.options[:category] == :setup } + error = errors.find { |e| e.attribute == :field_4 } + + expect(error).to be_present + expect(error.type).to eql("You must answer needs type") + end + end + end + + describe "#field_6" do + context "when an unpermitted value" do + let(:attributes) { { bulk_upload:, field_6: "3" } } + + it "has errors on the field" do + expect(parser.errors[:field_6]).to be_present + end + end + end + + describe "#field_30" do + context "when null" do + let(:attributes) { setup_section_params.merge({ field_30: nil }) } + + it "returns an error" do + expect(parser.errors[:field_30]).to be_present + end + + it "populates with correct error message" do + expect(parser.errors[:field_30]).to eql(["You must answer type of building"]) + end + end + + context "when unpermitted values" do + let(:attributes) { setup_section_params.merge({ field_30: "4" }) } + + it "returns an error" do + expect(parser.errors[:field_30]).to be_present + end + end + end + end + + describe "#log" do + [ + %w[age1_known age1 field_46], + %w[age2_known age2 field_52], + %w[age3_known age3 field_56], + %w[age4_known age4 field_60], + %w[age5_known age5 field_64], + %w[age6_known age6 field_68], + %w[age7_known age7 field_72], + %w[age8_known age8 field_76], + ].each do |known, age, field| + describe "##{known} and ##{age}" do + context "when #{field} is R" do + let(:attributes) { { bulk_upload:, field.to_s => "R" } } + + it "sets ##{known} 1" do + expect(parser.log.public_send(known)).to be(1) + end + + it "sets ##{age} to nil" do + expect(parser.log.public_send(age)).to be_nil + end + end + + context "when #{field} is a number" do + let(:attributes) { { bulk_upload:, field.to_s => "50" } } + + it "sets ##{known} to 0" do + expect(parser.log.public_send(known)).to be(0) + end + + it "sets ##{age} to given age" do + expect(parser.log.public_send(age)).to be(50) + end + end + end + end + + describe "#location" do + context "when lookup is via new core id" do + let(:attributes) { { bulk_upload:, field_16: scheme.old_visible_id, field_17: location.id, field_1: owning_org } } + + it "assigns the correct location" do + expect(parser.log.location).to eql(location) + end + end + end + + describe "#scheme" do + context "when lookup is via id prefixed with S" do + let(:attributes) { { bulk_upload:, field_16: "S#{scheme.id}", field_1: owning_org } } + + it "assigns the correct scheme" do + expect(parser.log.scheme).to eql(scheme) + end + end + end + + describe "#owning_organisation" do + context "when lookup is via id prefixed with ORG" do + let(:attributes) { { bulk_upload:, field_1: "ORG#{owning_org.id}" } } + + it "assigns the correct org" do + expect(parser.log.owning_organisation).to eql(owning_org) + end + end + end + + describe "#managing_organisation" do + context "when lookup is via id prefixed with ORG" do + let(:attributes) { { bulk_upload:, field_2: "ORG#{managing_org.id}" } } + + it "assigns the correct org" do + expect(parser.log.managing_organisation).to eql(managing_org) + end + end + end + + describe "#cbl" do + context "when field_116 is yes ie 1" do + let(:attributes) { { bulk_upload:, field_116: 1 } } + + it "sets value to 1" do + expect(parser.log.cbl).to be(1) + end + end + + context "when field_116 is no ie 2" do + let(:attributes) { { bulk_upload:, field_116: 2 } } + + it "sets value to 0" do + expect(parser.log.cbl).to be(0) + end + end + end + + describe "#chr" do + context "when field_118 is yes ie 1" do + let(:attributes) { { bulk_upload:, field_118: 1 } } + + it "sets value to 1" do + expect(parser.log.chr).to be(1) + end + end + + context "when field_118 is no ie 2" do + let(:attributes) { { bulk_upload:, field_118: 2 } } + + it "sets value to 0" do + expect(parser.log.chr).to be(0) + end + end + end + + describe "#cap" do + context "when field_117 is yes ie 1" do + let(:attributes) { { bulk_upload:, field_117: 1 } } + + it "sets value to 1" do + expect(parser.log.cap).to be(1) + end + end + + context "when field_117 is no ie 2" do + let(:attributes) { { bulk_upload:, field_117: 2 } } + + it "sets value to 0" do + expect(parser.log.cap).to be(0) + end + end + end + + describe "#letting_allocation_unknown" do + context "when field_116, 117, 118 are no ie 2" do + let(:attributes) { { bulk_upload:, field_116: 2, field_117: 2, field_118: 2 } } + + it "sets value to 1" do + expect(parser.log.letting_allocation_unknown).to be(1) + end + end + + context "when any one of field_116, 117, 118 is yes ie 1" do + let(:attributes) { { bulk_upload:, field_116: 1 } } + + it "sets value to 0" do + expect(parser.log.letting_allocation_unknown).to be(0) + end + end + end + + describe "#renewal" do + context "when field_6 is no ie 2" do + let(:attributes) { { bulk_upload:, field_6: 2 } } + + it "sets value to 0" do + expect(parser.log.renewal).to eq(0) + end + end + + context "when field_6 is null but rsnvac/field_27 is 14" do + let(:attributes) { { bulk_upload:, field_6: "", field_27: "14" } } + + it "sets renewal to 1" do + expect(parser.log.renewal).to eq(1) + end + end + end + + describe "#sexN fields" do + let(:attributes) do + { + bulk_upload:, + field_47: "F", + field_53: "M", + field_57: "X", + field_61: "R", + field_65: "F", + field_69: "M", + field_73: "X", + field_77: "R", + } + end + + it "sets value from correct mapping" do + expect(parser.log.sex1).to eql("F") + expect(parser.log.sex2).to eql("M") + expect(parser.log.sex3).to eql("X") + expect(parser.log.sex4).to eql("R") + expect(parser.log.sex5).to eql("F") + expect(parser.log.sex6).to eql("M") + expect(parser.log.sex7).to eql("X") + expect(parser.log.sex8).to eql("R") + end + end + + describe "#ecstatN fields" do + let(:attributes) do + { + bulk_upload:, + field_50: "1", + field_54: "2", + field_58: "6", + field_62: "7", + field_66: "8", + field_70: "9", + field_74: "0", + field_78: "10", + } + end + + it "sets value from correct mapping", aggregate_failures: true do + expect(parser.log.ecstat1).to eq(1) + expect(parser.log.ecstat2).to eq(2) + expect(parser.log.ecstat3).to eq(6) + expect(parser.log.ecstat4).to eq(7) + expect(parser.log.ecstat5).to eq(8) + expect(parser.log.ecstat6).to eq(9) + expect(parser.log.ecstat7).to eq(0) + expect(parser.log.ecstat8).to eq(10) + end + end + + describe "#relatN fields" do + let(:attributes) do + { + bulk_upload:, + field_51: "P", + field_55: "C", + field_59: "X", + field_63: "R", + field_67: "P", + field_71: "C", + field_75: "X", + } + end + + it "sets value from correct mapping", aggregate_failures: true do + expect(parser.log.relat2).to eq("P") + expect(parser.log.relat3).to eq("C") + expect(parser.log.relat4).to eq("X") + expect(parser.log.relat5).to eq("R") + expect(parser.log.relat6).to eq("P") + expect(parser.log.relat7).to eq("C") + expect(parser.log.relat8).to eq("X") + end + end + + describe "#net_income_known" do + let(:attributes) { { bulk_upload:, field_120: "1" } } + + it "sets value from correct mapping" do + expect(parser.log.net_income_known).to eq(0) + end + end + + describe "#unitletas" do + let(:attributes) { { bulk_upload:, field_26: "1" } } + + it "sets value from correct mapping" do + expect(parser.log.unitletas).to eq(1) + end + end + + describe "#rsnvac" do + let(:attributes) { { bulk_upload:, field_27: "5" } } + + it "sets value from correct mapping" do + expect(parser.log.rsnvac).to eq(5) + end + end + + describe "#sheltered" do + let(:attributes) { { bulk_upload:, field_44: "1" } } + + it "sets value from correct mapping" do + expect(parser.log.sheltered).to eq(1) + end + end + + describe "illness fields" do + mapping = [ + { attribute: :illness_type_1, field: :field_98 }, + { attribute: :illness_type_2, field: :field_92 }, + { attribute: :illness_type_3, field: :field_95 }, + { attribute: :illness_type_4, field: :field_90 }, + { attribute: :illness_type_5, field: :field_91 }, + { attribute: :illness_type_6, field: :field_93 }, + { attribute: :illness_type_7, field: :field_94 }, + { attribute: :illness_type_8, field: :field_97 }, + { attribute: :illness_type_9, field: :field_96 }, + { attribute: :illness_type_10, field: :field_99 }, + ] + + mapping.each do |hash| + describe "##{hash[:attribute]}" do + context "when yes" do + let(:attributes) { { bulk_upload:, hash[:field] => "1" } } + + it "sets value from correct mapping" do + expect(parser.log.public_send(hash[:attribute])).to eq(1) + end + end + + context "when no" do + let(:attributes) { { bulk_upload:, hash[:field] => "" } } + + it "sets value from correct mapping" do + expect(parser.log.public_send(hash[:attribute])).to be_nil + end + end + end + end + end + + describe "#irproduct_other" do + let(:attributes) { { bulk_upload:, field_12: "some other product" } } + + it "sets value to given free text string" do + expect(parser.log.irproduct_other).to eql("some other product") + end + end + + describe "#tenancyother" do + let(:attributes) { { bulk_upload:, field_42: "some other tenancy" } } + + it "sets value to given free text string" do + expect(parser.log.tenancyother).to eql("some other tenancy") + end + end + + describe "#tenancylength" do + let(:attributes) { { bulk_upload:, field_43: "2" } } + + it "sets value to given free text string" do + expect(parser.log.tenancylength).to eq(2) + end + end + + describe "#earnings" do + let(:attributes) { { bulk_upload:, field_122: "104.50" } } + + it "rounds to the nearest whole pound" do + expect(parser.log.earnings).to eq(105) + end + end + + describe "#reasonother" do + let(:attributes) { { bulk_upload:, field_103: "some other reason" } } + + it "sets value to given free text string" do + expect(parser.log.reasonother).to eql("some other reason") + end + end + + describe "#ppcodenk" do + let(:attributes) { { bulk_upload:, field_106: "2" } } + + it "sets correct value from mapping" do + expect(parser.log.ppcodenk).to eq(0) + end + end + + describe "#household_charge" do + let(:attributes) { { bulk_upload:, field_125: "1" } } + + it "sets correct value from mapping" do + expect(parser.log.household_charge).to eq(1) + end + end + + describe "#chcharge" do + let(:attributes) { { bulk_upload:, field_127: "123.45" } } + + it "sets value given" do + expect(parser.log.chcharge).to eq(123.45) + end + end + + describe "#tcharge" do + let(:attributes) { { bulk_upload:, field_132: "123.45" } } + + it "sets value given" do + expect(parser.log.tcharge).to eq(123.45) + end + end + + describe "#supcharg" do + let(:attributes) { { bulk_upload:, field_131: "123.45" } } + + it "sets value given" do + expect(parser.log.supcharg).to eq(123.45) + end + end + + describe "#pscharge" do + let(:attributes) { { bulk_upload:, field_130: "123.45" } } + + it "sets value given" do + expect(parser.log.pscharge).to eq(123.45) + end + end + + describe "#scharge" do + let(:attributes) { { bulk_upload:, field_129: "123.45" } } + + it "sets value given" do + expect(parser.log.scharge).to eq(123.45) + end + end + + describe "#offered" do + let(:attributes) { { bulk_upload:, field_28: "3" } } + + it "sets value given" do + expect(parser.log.offered).to eq(3) + end + end + + describe "#propcode" do + let(:attributes) { { bulk_upload:, field_14: "abc123" } } + + it "sets value given" do + expect(parser.log.propcode).to eq("abc123") + end + end + + describe "#mrcdate" do + let(:attributes) { { bulk_upload:, field_36: "13", field_37: "12", field_38: "22" } } + + it "sets value given" do + expect(parser.log.mrcdate).to eq(Date.new(2022, 12, 13)) + end + end + + describe "#majorrepairs" do + context "when mrcdate given" do + let(:attributes) { { bulk_upload:, field_36: "13", field_37: "12", field_38: "22" } } + + it "sets #majorrepairs to 1" do + expect(parser.log.majorrepairs).to eq(1) + end + end + + context "when mrcdate not given" do + let(:attributes) { { bulk_upload:, field_36: "", field_37: "", field_38: "" } } + + it "sets #majorrepairs to 0" do + expect(parser.log.majorrepairs).to eq(0) + end + end + end + + describe "#voiddate" do + let(:attributes) { { bulk_upload:, field_33: "13", field_34: "12", field_35: "22" } } + + it "sets value given" do + expect(parser.log.voiddate).to eq(Date.new(2022, 12, 13)) + end + end + + describe "#startdate" do + let(:attributes) { { bulk_upload:, field_7: now.day.to_s, field_8: now.month.to_s, field_9: now.strftime("%g") } } + + it "sets value given" do + expect(parser.log.startdate).to eq(now) + end + end + + describe "#postcode_full" do + let(:attributes) { { bulk_upload:, field_23: " EC1N ", field_24: " 2TD " } } + + it "strips whitespace" do + expect(parser.log.postcode_full).to eql("EC1N 2TD") + end + end + + describe "#la" do + let(:attributes) { { bulk_upload:, field_25: "E07000223" } } + + it "sets to given value" do + expect(parser.log.la).to eql("E07000223") + end + end + + describe "#prevloc" do + let(:attributes) { { bulk_upload:, field_109: "E07000223" } } + + it "sets to given value" do + expect(parser.log.prevloc).to eql("E07000223") + end + end + + describe "#previous_la_known" do + context "when known" do + let(:attributes) { { bulk_upload:, field_109: "E07000223" } } + + it "sets to 1" do + expect(parser.log.previous_la_known).to eq(1) + end + end + + context "when not known" do + let(:attributes) { { bulk_upload:, field_109: "" } } + + it "sets to 0" do + expect(parser.log.previous_la_known).to eq(0) + end + end + end + + describe "#first_time_property_let_as_social_housing" do + context "when field_27 is 15, 16, or 17" do + let(:attributes) { { bulk_upload:, field_27: %w[15 16 17].sample } } + + it "sets to 1" do + expect(parser.log.first_time_property_let_as_social_housing).to eq(1) + end + end + + context "when field_27 is not 15, 16, or 17" do + let(:attributes) { { bulk_upload:, field_27: "1" } } + + it "sets to 0" do + expect(parser.log.first_time_property_let_as_social_housing).to eq(0) + end + end + end + + describe "#housingneeds" do + context "when no disabled needs" do + let(:attributes) { { bulk_upload:, field_87: "1" } } + + it "sets to 2" do + expect(parser.log.housingneeds).to eq(2) + end + end + + context "when dont know about disabled needs" do + let(:attributes) { { bulk_upload:, field_88: "1" } } + + it "sets to 3" do + expect(parser.log.housingneeds).to eq(3) + end + end + end + + describe "#housingneeds_type" do + context "when field_83 is 1" do + let(:attributes) { { bulk_upload:, field_83: "1" } } + + it "set to 0" do + expect(parser.log.housingneeds_type).to eq(0) + end + end + + context "when field_84 is 1" do + let(:attributes) { { bulk_upload:, field_84: "1" } } + + it "set to 1" do + expect(parser.log.housingneeds_type).to eq(1) + end + end + + context "when field_85 is 1" do + let(:attributes) { { bulk_upload:, field_85: "1" } } + + it "set to 2" do + expect(parser.log.housingneeds_type).to eq(2) + end + end + end + + describe "#housingneeds_other" do + context "when field_58 is 1" do + let(:attributes) { { bulk_upload:, field_86: "1" } } + + it "sets to 1" do + expect(parser.log.housingneeds_other).to eq(1) + end + end + end + end + + describe "#start_date" do + context "when year of 9 is passed to represent 2009" do + let(:attributes) { { bulk_upload:, field_7: "1", field_8: "1", field_9: "9" } } + + it "uses the year 2009" do + expect(parser.send(:start_date)).to eql(Date.new(2009, 1, 1)) + end + end + end +end diff --git a/spec/services/bulk_upload/processor_spec.rb b/spec/services/bulk_upload/processor_spec.rb index 48b0c0258..2254e1b75 100644 --- a/spec/services/bulk_upload/processor_spec.rb +++ b/spec/services/bulk_upload/processor_spec.rb @@ -21,6 +21,7 @@ RSpec.describe BulkUpload::Processor do BulkUpload::Lettings::Validator, invalid?: true, call: nil, + errors: [], ) end @@ -106,7 +107,7 @@ RSpec.describe BulkUpload::Processor do BulkUpload::Lettings::Validator, invalid?: false, call: nil, - any_setup_sections_incomplete?: true, + any_setup_errors?: true, ) end @@ -142,7 +143,7 @@ RSpec.describe BulkUpload::Processor do BulkUpload::Lettings::Validator, invalid?: false, call: nil, - any_setup_sections_incomplete?: false, + any_setup_errors?: false, create_logs?: true, ) end @@ -193,7 +194,7 @@ RSpec.describe BulkUpload::Processor do BulkUpload::Lettings::Validator, invalid?: false, call: nil, - any_setup_sections_incomplete?: false, + any_setup_errors?: false, create_logs?: false, ) end @@ -254,7 +255,7 @@ RSpec.describe BulkUpload::Processor do BulkUpload::Lettings::Validator, call: nil, create_logs?: true, - any_setup_sections_incomplete?: false, + any_setup_errors?: false, invalid?: false, ) end diff --git a/spec/services/bulk_upload/sales/row_parser_spec.rb b/spec/services/bulk_upload/sales/year2022/row_parser_spec.rb similarity index 87% rename from spec/services/bulk_upload/sales/row_parser_spec.rb rename to spec/services/bulk_upload/sales/year2022/row_parser_spec.rb index 38f02fabb..e27355dc4 100644 --- a/spec/services/bulk_upload/sales/row_parser_spec.rb +++ b/spec/services/bulk_upload/sales/year2022/row_parser_spec.rb @@ -1,6 +1,6 @@ require "rails_helper" -RSpec.describe BulkUpload::Sales::RowParser do +RSpec.describe BulkUpload::Sales::Year2022::RowParser do subject(:parser) { described_class.new(attributes) } describe "validations" do diff --git a/spec/services/csv/lettings_log_csv_service_spec.rb b/spec/services/csv/lettings_log_csv_service_spec.rb index 95b3069dc..b1064acd5 100644 --- a/spec/services/csv/lettings_log_csv_service_spec.rb +++ b/spec/services/csv/lettings_log_csv_service_spec.rb @@ -6,7 +6,7 @@ RSpec.describe Csv::LettingsLogCsvService do let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json") } before do - LettingsLog.create!(startdate: "2021-10-10", created_at: Time.utc(2022, 2, 8, 16, 52, 15)) + LettingsLog.create!(startdate: Time.zone.today, created_at: Time.utc(2022, 2, 8, 16, 52, 15)) allow(FormHandler.instance).to receive(:get_form).and_return(real_2021_2022_form) end @@ -201,6 +201,13 @@ RSpec.describe Csv::LettingsLogCsvService do vacdays unresolved updated_by_id + uprn + uprn_known + uprn_confirmed + address_line1 + address_line2 + town_or_city + county unittype_sh scheme_code scheme_service_name @@ -222,7 +229,9 @@ RSpec.describe Csv::LettingsLogCsvService do location_mobility_type location_admin_district location_startdate] - csv = CSV.parse(described_class.new(user).to_csv) + + csv = CSV.parse(described_class.new(user, export_type: "labels").to_csv) + expect(csv.first).to eq(expected_csv_attributes) end end diff --git a/spec/services/exports/lettings_log_export_service_spec.rb b/spec/services/exports/lettings_log_export_service_spec.rb index 55897c354..7c17f95dc 100644 --- a/spec/services/exports/lettings_log_export_service_spec.rb +++ b/spec/services/exports/lettings_log_export_service_spec.rb @@ -59,7 +59,7 @@ RSpec.describe Exports::LettingsLogExportService do end context "and one lettings log is available for export" do - let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", tenancycode: "BZ737", startdate: Time.utc(2022, 2, 2, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4) } + let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", tenancycode: "BZ737", startdate: Time.zone.local(2022, 2, 2, 10, 36, 49), voiddate: Time.zone.local(2019, 11, 3), mrcdate: Time.zone.local(2020, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4) } it "generates a ZIP export file with the expected filename" do expect(storage_service).to receive(:write_file).with(expected_zip_filename, any_args) @@ -161,7 +161,7 @@ RSpec.describe Exports::LettingsLogExportService do context "when this is a second export (partial)" do before do - start_time = Time.zone.local(2022, 4, 1) + start_time = Time.zone.local(2022, 6, 1) LogsExport.new(started_at: start_time).save! end @@ -237,7 +237,7 @@ RSpec.describe Exports::LettingsLogExportService do let(:csv_export_file) { File.open("spec/fixtures/exports/general_needs_log.csv", "r:UTF-8") } let(:expected_csv_filename) { "export_2022_05_01.csv" } - let(:lettings_log) { FactoryBot.create(:lettings_log, :completed, propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", tenancycode: "BZ737", startdate: Time.utc(2022, 2, 2, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4) } + let(:lettings_log) { FactoryBot.create(:lettings_log, :completed, propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", tenancycode: "BZ737", startdate: Time.zone.local(2022, 2, 2, 10, 36, 49), voiddate: Time.zone.local(2019, 11, 3), mrcdate: Time.zone.local(2020, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4) } it "generates an CSV export file with the expected content" do expected_content = replace_entity_ids(lettings_log, csv_export_file.read) @@ -256,7 +256,7 @@ RSpec.describe Exports::LettingsLogExportService do let(:scheme) { FactoryBot.create(:scheme, :export, owning_organisation: organisation) } let(:location) { FactoryBot.create(:location, :export, scheme:, startdate: Time.zone.local(2021, 4, 1)) } - let(:lettings_log) { FactoryBot.create(:lettings_log, :completed, :export, :sh, scheme:, location:, created_by: user, owning_organisation: organisation, startdate: Time.utc(2022, 2, 2, 10, 36, 49), underoccupation_benefitcap: 4, sheltered: 1) } + let(:lettings_log) { FactoryBot.create(:lettings_log, :completed, :export, :sh, scheme:, location:, created_by: user, owning_organisation: organisation, startdate: Time.zone.local(2022, 2, 2, 10, 36, 49), voiddate: Time.zone.local(2019, 11, 3), mrcdate: Time.zone.local(2020, 5, 5, 10, 36, 49), underoccupation_benefitcap: 4, sheltered: 1) } before do FactoryBot.create(:location, scheme:, startdate: Time.zone.local(2021, 4, 1), units: nil) diff --git a/spec/services/filter_service_spec.rb b/spec/services/filter_service_spec.rb index 2c89b1302..e1d4652a7 100644 --- a/spec/services/filter_service_spec.rb +++ b/spec/services/filter_service_spec.rb @@ -29,13 +29,12 @@ describe FilterService do context "when filtering logs" do context "when filtering lettings logs" do - before do - FactoryBot.create_list(:lettings_log, 5) - FactoryBot.create(:lettings_log, postcode_full: "SW1 1AA") + let(:lettings_log_list) do + logs = FactoryBot.create_list(:lettings_log, 5) + searched_log = FactoryBot.create(:lettings_log, postcode_full: "SW1 1AA") + LettingsLog.where(id: [searched_log.id] + logs.map(&:id)) end - let(:lettings_log_list) { LettingsLog.all } - context "when given a postcode" do let(:search_term) { "SW1 1AA" } @@ -54,15 +53,14 @@ describe FilterService do end context "when filtering sales logs" do - before do - FactoryBot.create_list(:sales_log, 5) - FactoryBot.create(:sales_log, purchid: "2") + let(:sales_log_list) do + logs = FactoryBot.create_list(:sales_log, 5) + searched_log = FactoryBot.create(:sales_log, purchid: "kzmgaiFNsx323") + SalesLog.where(id: [searched_log.id] + logs.map(&:id)) end - let(:sales_log_list) { SalesLog.all } - context "when given a purchid" do - let(:search_term) { "2" } + let(:search_term) { "kzmgaiFNsx323" } it "filters the collection on search term" do expect(described_class.filter_by_search(sales_log_list, search_term).count).to eq(1) diff --git a/spec/services/imports/lettings_logs_field_import_service_spec.rb b/spec/services/imports/lettings_logs_field_import_service_spec.rb index 685617041..0c55139e8 100644 --- a/spec/services/imports/lettings_logs_field_import_service_spec.rb +++ b/spec/services/imports/lettings_logs_field_import_service_spec.rb @@ -16,6 +16,15 @@ RSpec.describe Imports::LettingsLogsFieldImportService do let(:old_user_id) { "c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa" } let(:organisation) { FactoryBot.create(:organisation, old_visible_id: "1", provider_type: "PRP") } + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + def open_file(directory, filename) File.open("#{directory}/#{filename}.xml") end @@ -27,7 +36,7 @@ RSpec.describe Imports::LettingsLogsFieldImportService do FactoryBot.create(:user, old_user_id:, organisation:) # Stub the form handler to use the real form - allow(FormHandler.instance).to receive(:get_form).with("previous_lettings").and_return(real_2021_2022_form) + allow(FormHandler.instance).to receive(:get_form).with("current_lettings").and_return(real_2021_2022_form) WebMock.stub_request(:get, /api.postcodes.io\/postcodes\/LS166FT/) .to_return(status: 200, body: '{"status":200,"result":{"codes":{"admin_district":"E08000035"}}}', headers: {}) diff --git a/spec/services/imports/lettings_logs_import_service_spec.rb b/spec/services/imports/lettings_logs_import_service_spec.rb index 846c266a5..bfd907620 100644 --- a/spec/services/imports/lettings_logs_import_service_spec.rb +++ b/spec/services/imports/lettings_logs_import_service_spec.rb @@ -1,348 +1,333 @@ require "rails_helper" RSpec.describe Imports::LettingsLogsImportService do - subject(:lettings_log_service) { described_class.new(storage_service, logger) } + context "with 21/22 logs" do + subject(:lettings_log_service) { described_class.new(storage_service, logger) } - let(:storage_service) { instance_double(Storage::S3Service) } - let(:logger) { instance_double(ActiveSupport::Logger) } - - let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json") } - let(:real_2022_2023_form) { Form.new("config/forms/2022_2023.json") } - let(:fixture_directory) { "spec/fixtures/imports/logs" } - - let(:organisation) { FactoryBot.create(:organisation, old_visible_id: "1", provider_type: "PRP") } - let(:managing_organisation) { FactoryBot.create(:organisation, old_visible_id: "2", provider_type: "PRP") } - let(:scheme1) { FactoryBot.create(:scheme, old_visible_id: "0123", owning_organisation: organisation) } - let(:scheme2) { FactoryBot.create(:scheme, old_visible_id: "456", owning_organisation: organisation) } - - def open_file(directory, filename) - File.open("#{directory}/#{filename}.xml") - end - - before do - WebMock.stub_request(:get, /api.postcodes.io\/postcodes\/LS166FT/) - .to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Westminster","codes":{"admin_district":"E08000035"}}}', headers: {}) - - allow(Organisation).to receive(:find_by).and_return(nil) - allow(Organisation).to receive(:find_by).with(old_visible_id: organisation.old_visible_id).and_return(organisation) - allow(Organisation).to receive(:find_by).with(old_visible_id: managing_organisation.old_visible_id).and_return(managing_organisation) - - # Created by users - FactoryBot.create(:user, old_user_id: "c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa", organisation:) - FactoryBot.create(:user, old_user_id: "e29c492473446dca4d50224f2bb7cf965a261d6f", organisation:) - - # Location setup - FactoryBot.create(:location, old_visible_id: "10", postcode: "LS166FT", scheme_id: scheme1.id, mobility_type: "W", startdate: Time.zone.local(2021, 4, 1)) - FactoryBot.create(:location, scheme_id: scheme1.id, startdate: Time.zone.local(2021, 4, 1)) - FactoryBot.create(:location, old_visible_id: "10", postcode: "LS166FT", scheme_id: scheme2.id, mobility_type: "W", startdate: Time.zone.local(2021, 4, 1)) - - # Stub the form handler to use the real form - allow(FormHandler.instance).to receive(:get_form).with("previous_lettings").and_return(real_2021_2022_form) - allow(FormHandler.instance).to receive(:get_form).with("current_lettings").and_return(real_2022_2023_form) - end + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end - context "when importing lettings logs" do - let(:remote_folder) { "lettings_logs" } - let(:lettings_log_id) { "0ead17cb-1668-442d-898c-0d52879ff592" } - let(:lettings_log_id2) { "166fc004-392e-47a8-acb8-1c018734882b" } - let(:lettings_log_id3) { "00d2343e-d5fa-4c89-8400-ec3854b0f2b4" } - let(:lettings_log_id4) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" } - let(:sales_log) { "shared_ownership_sales_log" } + let(:storage_service) { instance_double(Storage::S3Service) } + let(:logger) { instance_double(ActiveSupport::Logger) } - before do - # Stub the S3 file listing and download - allow(storage_service).to receive(:list_files) - .and_return(%W[#{remote_folder}/#{lettings_log_id}.xml #{remote_folder}/#{lettings_log_id2}.xml #{remote_folder}/#{lettings_log_id3}.xml #{remote_folder}/#{lettings_log_id4}.xml #{remote_folder}/#{sales_log}.xml]) - allow(storage_service).to receive(:get_file_io) - .with("#{remote_folder}/#{lettings_log_id}.xml") - .and_return(open_file(fixture_directory, lettings_log_id), open_file(fixture_directory, lettings_log_id)) - allow(storage_service).to receive(:get_file_io) - .with("#{remote_folder}/#{lettings_log_id2}.xml") - .and_return(open_file(fixture_directory, lettings_log_id2), open_file(fixture_directory, lettings_log_id2)) - allow(storage_service).to receive(:get_file_io) - .with("#{remote_folder}/#{lettings_log_id3}.xml") - .and_return(open_file(fixture_directory, lettings_log_id3), open_file(fixture_directory, lettings_log_id3)) - allow(storage_service).to receive(:get_file_io) - .with("#{remote_folder}/#{lettings_log_id4}.xml") - .and_return(open_file(fixture_directory, lettings_log_id4), open_file(fixture_directory, lettings_log_id4)) - allow(storage_service).to receive(:get_file_io) - .with("#{remote_folder}/#{sales_log}.xml") - .and_return(open_file(fixture_directory, sales_log), open_file(fixture_directory, sales_log)) - end + let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json") } + let(:real_2022_2023_form) { Form.new("config/forms/2022_2023.json") } + let(:fixture_directory) { "spec/fixtures/imports/logs" } - it "successfully create all lettings logs" do - expect(logger).not_to receive(:error) - expect(logger).not_to receive(:warn) - expect(logger).not_to receive(:info) - expect { lettings_log_service.create_logs(remote_folder) } - .to change(LettingsLog, :count).by(4) - end + let(:organisation) { FactoryBot.create(:organisation, old_visible_id: "1", provider_type: "PRP") } + let(:managing_organisation) { FactoryBot.create(:organisation, old_visible_id: "2", provider_type: "PRP") } + let(:scheme1) { FactoryBot.create(:scheme, old_visible_id: "0123", owning_organisation: organisation) } + let(:scheme2) { FactoryBot.create(:scheme, old_visible_id: "456", owning_organisation: organisation) } - it "only updates existing lettings logs" do - expect(logger).not_to receive(:error) - expect(logger).not_to receive(:warn) - expect(logger).to receive(:info).with(/Updating lettings log/).exactly(4).times - expect { 2.times { lettings_log_service.create_logs(remote_folder) } } - .to change(LettingsLog, :count).by(4) + def open_file(directory, filename) + File.open("#{directory}/#{filename}.xml") end - it "creates organisation relationship once" do - expect(logger).not_to receive(:error) - expect(logger).not_to receive(:warn) - expect { lettings_log_service.create_logs(remote_folder) } - .to change(OrganisationRelationship, :count).by(1) + before do + WebMock.stub_request(:get, /api.postcodes.io\/postcodes\/LS166FT/) + .to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Westminster","codes":{"admin_district":"E08000035"}}}', headers: {}) + + allow(Organisation).to receive(:find_by).and_return(nil) + allow(Organisation).to receive(:find_by).with(old_visible_id: organisation.old_visible_id).and_return(organisation) + allow(Organisation).to receive(:find_by).with(old_visible_id: managing_organisation.old_visible_id).and_return(managing_organisation) + + # Created by users + FactoryBot.create(:user, old_user_id: "c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa", organisation:) + FactoryBot.create(:user, old_user_id: "e29c492473446dca4d50224f2bb7cf965a261d6f", organisation:) + + # Location setup + FactoryBot.create(:location, old_visible_id: "10", postcode: "LS166FT", scheme_id: scheme1.id, mobility_type: "W", startdate: Time.zone.local(2021, 4, 1)) + FactoryBot.create(:location, scheme_id: scheme1.id, startdate: Time.zone.local(2021, 4, 1)) + FactoryBot.create(:location, old_visible_id: "10", postcode: "LS166FT", scheme_id: scheme2.id, mobility_type: "W", startdate: Time.zone.local(2021, 4, 1)) + + # Stub the form handler to use the real form + allow(FormHandler.instance).to receive(:get_form).with("current_lettings").and_return(real_2021_2022_form) + allow(FormHandler.instance).to receive(:get_form).with("previous_lettings").and_return(real_2021_2022_form) + allow(FormHandler.instance).to receive(:get_form).with("next_lettings").and_return(real_2022_2023_form) end - context "when there are status discrepancies" do - let(:lettings_log_id5) { "893ufj2s-lq77-42m4-rty6-ej09gh585uy1" } - let(:lettings_log_id6) { "5ybz29dj-l33t-k1l0-hj86-n4k4ma77xkcd" } - let(:lettings_log_file) { open_file(fixture_directory, lettings_log_id5) } - let(:lettings_log_xml) { Nokogiri::XML(lettings_log_file) } + context "when importing lettings logs" do + let(:remote_folder) { "lettings_logs" } + let(:lettings_log_id) { "0ead17cb-1668-442d-898c-0d52879ff592" } + let(:lettings_log_id2) { "166fc004-392e-47a8-acb8-1c018734882b" } + let(:lettings_log_id3) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" } + let(:sales_log) { "shared_ownership_sales_log" } before do + # Stub the S3 file listing and download + allow(storage_service).to receive(:list_files) + .and_return(%W[#{remote_folder}/#{lettings_log_id}.xml #{remote_folder}/#{lettings_log_id2}.xml #{remote_folder}/#{lettings_log_id3}.xml #{remote_folder}/#{sales_log}.xml]) allow(storage_service).to receive(:get_file_io) - .with("#{remote_folder}/#{lettings_log_id5}.xml") - .and_return(open_file(fixture_directory, lettings_log_id5), open_file(fixture_directory, lettings_log_id5)) + .with("#{remote_folder}/#{lettings_log_id}.xml") + .and_return(open_file(fixture_directory, lettings_log_id), open_file(fixture_directory, lettings_log_id)) allow(storage_service).to receive(:get_file_io) - .with("#{remote_folder}/#{lettings_log_id6}.xml") - .and_return(open_file(fixture_directory, lettings_log_id6), open_file(fixture_directory, lettings_log_id6)) + .with("#{remote_folder}/#{lettings_log_id2}.xml") + .and_return(open_file(fixture_directory, lettings_log_id2), open_file(fixture_directory, lettings_log_id2)) + allow(storage_service).to receive(:get_file_io) + .with("#{remote_folder}/#{lettings_log_id3}.xml") + .and_return(open_file(fixture_directory, lettings_log_id3), open_file(fixture_directory, lettings_log_id3)) + allow(storage_service).to receive(:get_file_io) + .with("#{remote_folder}/#{sales_log}.xml") + .and_return(open_file(fixture_directory, sales_log), open_file(fixture_directory, sales_log)) end - it "the logger logs a warning with the lettings log's old id/filename" do - expect(logger).to receive(:warn).with(/is not completed/).once - expect(logger).to receive(:warn).with(/lettings log with old id:#{lettings_log_id5} is incomplete but status should be complete/).once - - lettings_log_service.send(:create_log, lettings_log_xml) + it "successfully create all lettings logs" do + expect(logger).not_to receive(:error) + expect(logger).not_to receive(:warn) + expect(logger).not_to receive(:info) + expect { lettings_log_service.create_logs(remote_folder) } + .to change(LettingsLog, :count).by(3) end - it "on completion the ids of all logs with status discrepancies are logged in a warning" do - allow(storage_service).to receive(:list_files) - .and_return(%W[#{remote_folder}/#{lettings_log_id5}.xml #{remote_folder}/#{lettings_log_id6}.xml]) - expect(logger).to receive(:warn).with(/is not completed/).twice - expect(logger).to receive(:warn).with(/is incomplete but status should be complete/).twice - expect(logger).to receive(:warn).with(/The following lettings logs had status discrepancies: \[893ufj2s-lq77-42m4-rty6-ej09gh585uy1, 5ybz29dj-l33t-k1l0-hj86-n4k4ma77xkcd\]/) - - lettings_log_service.create_logs(remote_folder) + it "only updates existing lettings logs" do + expect(logger).not_to receive(:error) + expect(logger).not_to receive(:warn) + expect(logger).to receive(:info).with(/Updating lettings log/).exactly(3).times + expect { 2.times { lettings_log_service.create_logs(remote_folder) } } + .to change(LettingsLog, :count).by(3) end - end - end - context "when importing a specific log" do - let(:lettings_log_id) { "0ead17cb-1668-442d-898c-0d52879ff592" } - let(:lettings_log_file) { open_file(fixture_directory, lettings_log_id) } - let(:lettings_log_xml) { Nokogiri::XML(lettings_log_file) } + it "creates organisation relationship once" do + expect(logger).not_to receive(:error) + expect(logger).not_to receive(:warn) + expect { lettings_log_service.create_logs(remote_folder) } + .to change(OrganisationRelationship, :count).by(1) + end - context "and the void date is after the start date" do - before { lettings_log_xml.at_xpath("//xmlns:VYEAR").content = 2023 } + context "when there are status discrepancies" do + let(:lettings_log_id5) { "893ufj2s-lq77-42m4-rty6-ej09gh585uy1" } + let(:lettings_log_id6) { "5ybz29dj-l33t-k1l0-hj86-n4k4ma77xkcd" } + let(:lettings_log_file) { open_file(fixture_directory, lettings_log_id5) } + let(:lettings_log_xml) { Nokogiri::XML(lettings_log_file) } - it "does not import the voiddate" do - expect(logger).to receive(:warn).with(/is not completed/) - expect(logger).to receive(:warn).with(/lettings log with old id:#{lettings_log_id} is incomplete but status should be complete/) + before do + allow(storage_service).to receive(:get_file_io) + .with("#{remote_folder}/#{lettings_log_id5}.xml") + .and_return(open_file(fixture_directory, lettings_log_id5), open_file(fixture_directory, lettings_log_id5)) + allow(storage_service).to receive(:get_file_io) + .with("#{remote_folder}/#{lettings_log_id6}.xml") + .and_return(open_file(fixture_directory, lettings_log_id6), open_file(fixture_directory, lettings_log_id6)) + end - lettings_log_service.send(:create_log, lettings_log_xml) + it "the logger logs a warning with the lettings log's old id/filename" do + expect(logger).to receive(:warn).with(/is not completed/).once + expect(logger).to receive(:warn).with(/lettings log with old id:#{lettings_log_id5} is incomplete but status should be complete/).once - lettings_log = LettingsLog.where(old_id: lettings_log_id).first - expect(lettings_log&.voiddate).to be_nil - end - end + lettings_log_service.send(:create_log, lettings_log_xml) + end - context "and the organisation legacy ID does not exist" do - before { lettings_log_xml.at_xpath("//xmlns:OWNINGORGID").content = 99_999 } + it "on completion the ids of all logs with status discrepancies are logged in a warning" do + allow(storage_service).to receive(:list_files) + .and_return(%W[#{remote_folder}/#{lettings_log_id5}.xml #{remote_folder}/#{lettings_log_id6}.xml]) + expect(logger).to receive(:warn).with(/is not completed/).twice + expect(logger).to receive(:warn).with(/is incomplete but status should be complete/).twice + expect(logger).to receive(:warn).with(/The following lettings logs had status discrepancies: \[893ufj2s-lq77-42m4-rty6-ej09gh585uy1, 5ybz29dj-l33t-k1l0-hj86-n4k4ma77xkcd\]/) - it "raises an exception" do - expect { lettings_log_service.send(:create_log, lettings_log_xml) } - .to raise_error(RuntimeError, "Organisation not found with legacy ID 99999") + lettings_log_service.create_logs(remote_folder) + end end end - context "and a person is under 16" do - before { lettings_log_xml.at_xpath("//xmlns:P2Age").content = 14 } + context "when importing a specific log" do + let(:lettings_log_id) { "0ead17cb-1668-442d-898c-0d52879ff592" } + let(:lettings_log_file) { open_file(fixture_directory, lettings_log_id) } + let(:lettings_log_xml) { Nokogiri::XML(lettings_log_file) } + + context "and the void date is after the start date" do + before { lettings_log_xml.at_xpath("//xmlns:VYEAR").content = 2023 } - context "when the economic status is set to refuse" do - before { lettings_log_xml.at_xpath("//xmlns:P2Eco").content = "10) Refused" } + it "does not import the voiddate" do + expect(logger).to receive(:warn).with(/is not completed/) + expect(logger).to receive(:warn).with(/lettings log with old id:#{lettings_log_id} is incomplete but status should be complete/) - it "sets the economic status to child under 16" do - # The update is done when calculating derived variables - expect(logger).to receive(:warn).with(/Differences found when saving log/) lettings_log_service.send(:create_log, lettings_log_xml) lettings_log = LettingsLog.where(old_id: lettings_log_id).first - expect(lettings_log&.ecstat2).to be(9) + expect(lettings_log&.voiddate).to be_nil end end - context "when the relationship to lead tenant is set to refuse" do - before { lettings_log_xml.at_xpath("//xmlns:P2Rel").content = "Refused" } - - it "sets the relationship to lead tenant to child" do - lettings_log_service.send(:create_log, lettings_log_xml) + context "and the organisation legacy ID does not exist" do + before { lettings_log_xml.at_xpath("//xmlns:OWNINGORGID").content = 99_999 } - lettings_log = LettingsLog.where(old_id: lettings_log_id).first - expect(lettings_log&.relat2).to eq("C") + it "raises an exception" do + expect { lettings_log_service.send(:create_log, lettings_log_xml) } + .to raise_error(RuntimeError, "Organisation not found with legacy ID 99999") end end - end - context "and this is an internal transfer that is in-progress with invalid answers" do - before do - lettings_log_xml.at_xpath("//meta:status").content = "submitted-invalid" - lettings_log_xml.at_xpath("//xmlns:P2Age").content = 999 - end + context "and a person is under 16" do + before { lettings_log_xml.at_xpath("//xmlns:P2Age").content = 14 } - it "intercepts the relevant validation error" do - expect(logger).to receive(:warn).with(/Removing field age2 from log triggering validation: Answer cannot be over 16/) - expect(logger).to receive(:warn).with(/Removing field age2 from log triggering validation: Person 2’s age must be between/) - expect(logger).to receive(:warn).with(/Removing field ecstat2 from log triggering validation: Answer cannot be ‘child under 16’/) - expect { lettings_log_service.send(:create_log, lettings_log_xml) } - .not_to raise_error - end + context "when the economic status is set to refuse" do + before { lettings_log_xml.at_xpath("//xmlns:P2Eco").content = "10) Refused" } - it "clears out the invalid answers" do - allow(logger).to receive(:warn) + it "sets the economic status to child under 16" do + # The update is done when calculating derived variables + expect(logger).to receive(:warn).with(/Differences found when saving log/) + lettings_log_service.send(:create_log, lettings_log_xml) - lettings_log_service.send(:create_log, lettings_log_xml) - lettings_log = LettingsLog.find_by(old_id: lettings_log_id) + lettings_log = LettingsLog.where(old_id: lettings_log_id).first + expect(lettings_log&.ecstat2).to be(9) + end + end - expect(lettings_log).not_to be_nil - expect(lettings_log.age2).to be_nil - expect(lettings_log.ecstat2).to be_nil - end - end + context "when the relationship to lead tenant is set to refuse" do + before { lettings_log_xml.at_xpath("//xmlns:P2Rel").content = "Refused" } - context "and it has zero earnings" do - before do - lettings_log_xml.at_xpath("//meta:status").content = "submitted" - lettings_log_xml.at_xpath("//xmlns:Q8Money").content = 0 - end + it "sets the relationship to lead tenant to child" do + lettings_log_service.send(:create_log, lettings_log_xml) - it "intercepts the relevant validation error" do - expect(logger).to receive(:warn).with(/Where the income is 0, set earnings and income to blank and set incref to refused/) - expect { lettings_log_service.send(:create_log, lettings_log_xml) } - .not_to raise_error + lettings_log = LettingsLog.where(old_id: lettings_log_id).first + expect(lettings_log&.relat2).to eq("C") + end + end end - it "clears out the invalid answers" do - allow(logger).to receive(:warn) + context "and this is an internal transfer that is in-progress with invalid answers" do + before do + lettings_log_xml.at_xpath("//meta:status").content = "submitted-invalid" + lettings_log_xml.at_xpath("//xmlns:P2Age").content = 999 + end - lettings_log_service.send(:create_log, lettings_log_xml) - lettings_log = LettingsLog.find_by(old_id: lettings_log_id) + it "intercepts the relevant validation error" do + expect(logger).to receive(:warn).with(/Removing field age2 from log triggering validation: Answer cannot be over 16/) + expect(logger).to receive(:warn).with(/Removing field age2 from log triggering validation: Person 2’s age must be between/) + expect(logger).to receive(:warn).with(/Removing field ecstat2 from log triggering validation: Answer cannot be ‘child under 16’/) + expect { lettings_log_service.send(:create_log, lettings_log_xml) } + .not_to raise_error + end - expect(lettings_log).not_to be_nil - expect(lettings_log.earnings).to be_nil - expect(lettings_log.incref).to eq(1) - expect(lettings_log.net_income_known).to eq(2) - end - end + it "clears out the invalid answers" do + allow(logger).to receive(:warn) - context "and an invalid tenancy length for tenancy type" do - before do - lettings_log_xml.at_xpath("//meta:status").content = "submitted" - lettings_log_xml.at_xpath("//xmlns:_2cYears").content = "1" - lettings_log_xml.at_xpath("//xmlns:Q2b").content = "4" - end + lettings_log_service.send(:create_log, lettings_log_xml) + lettings_log = LettingsLog.find_by(old_id: lettings_log_id) - it "intercepts the relevant validation error" do - expect(logger).to receive(:warn).with(/Removing tenancylength as invalid/) - expect { lettings_log_service.send(:create_log, lettings_log_xml) } - .not_to raise_error + expect(lettings_log).not_to be_nil + expect(lettings_log.age2).to be_nil + expect(lettings_log.ecstat2).to be_nil + end end - it "clears out the invalid answers" do - allow(logger).to receive(:warn) + context "and it has zero earnings" do + before do + lettings_log_xml.at_xpath("//meta:status").content = "submitted" + lettings_log_xml.at_xpath("//xmlns:Q8Money").content = 0 + end - lettings_log_service.send(:create_log, lettings_log_xml) - lettings_log = LettingsLog.find_by(old_id: lettings_log_id) + it "intercepts the relevant validation error" do + expect(logger).to receive(:warn).with(/Where the income is 0, set earnings and income to blank and set incref to refused/) + expect { lettings_log_service.send(:create_log, lettings_log_xml) } + .not_to raise_error + end - expect(lettings_log).not_to be_nil - expect(lettings_log.tenancylength).to be_nil - expect(lettings_log.tenancy).to be_nil - end - end + it "clears out the invalid answers" do + allow(logger).to receive(:warn) - context "and an lead tenant must be under 20 if childrens home or foster care" do - before do - lettings_log_xml.at_xpath("//meta:status").content = "submitted" - lettings_log_xml.at_xpath("//xmlns:Q11").content = "13" - lettings_log_xml.at_xpath("//xmlns:P1Age").content = "22" - end + lettings_log_service.send(:create_log, lettings_log_xml) + lettings_log = LettingsLog.find_by(old_id: lettings_log_id) - it "intercepts the relevant validation error" do - expect(logger).to receive(:warn).with(/Removing age1 and prevten as incompatible/) - expect { lettings_log_service.send(:create_log, lettings_log_xml) } - .not_to raise_error + expect(lettings_log).not_to be_nil + expect(lettings_log.earnings).to be_nil + expect(lettings_log.incref).to eq(1) + expect(lettings_log.net_income_known).to eq(2) + end end - it "clears out the invalid answers" do - allow(logger).to receive(:warn) + context "and an invalid tenancy length for tenancy type" do + before do + lettings_log_xml.at_xpath("//meta:status").content = "submitted" + lettings_log_xml.at_xpath("//xmlns:_2cYears").content = "1" + lettings_log_xml.at_xpath("//xmlns:Q2b").content = "4" + end - lettings_log_service.send(:create_log, lettings_log_xml) - lettings_log = LettingsLog.find_by(old_id: lettings_log_id) + it "intercepts the relevant validation error" do + expect(logger).to receive(:warn).with(/Removing tenancylength as invalid/) + expect { lettings_log_service.send(:create_log, lettings_log_xml) } + .not_to raise_error + end - expect(lettings_log).not_to be_nil - expect(lettings_log.age1).to be_nil - expect(lettings_log.prevten).to be_nil - end - end + it "clears out the invalid answers" do + allow(logger).to receive(:warn) - context "and is a carehome but missing carehome charge" do - let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" } + lettings_log_service.send(:create_log, lettings_log_xml) + lettings_log = LettingsLog.find_by(old_id: lettings_log_id) - before do - lettings_log_xml.at_xpath("//meta:status").content = "submitted" - lettings_log_xml.at_xpath("//xmlns:_1cmangroupcode").content = scheme2.old_visible_id - scheme2.update!(registered_under_care_act: 2) - lettings_log_xml.at_xpath("//xmlns:Q18b").content = "" + expect(lettings_log).not_to be_nil + expect(lettings_log.tenancylength).to be_nil + expect(lettings_log.tenancy).to be_nil + end end - it "intercepts the relevant validation error" do - allow(logger).to receive(:warn) + context "and an lead tenant must be under 20 if childrens home or foster care" do + before do + lettings_log_xml.at_xpath("//meta:status").content = "submitted" + lettings_log_xml.at_xpath("//xmlns:Q11").content = "13" + lettings_log_xml.at_xpath("//xmlns:P1Age").content = "22" + end - expect { lettings_log_service.send(:create_log, lettings_log_xml) } - .not_to raise_error - end + it "intercepts the relevant validation error" do + expect(logger).to receive(:warn).with(/Removing age1 and prevten as incompatible/) + expect { lettings_log_service.send(:create_log, lettings_log_xml) } + .not_to raise_error + end - it "clears out the invalid answers" do - allow(logger).to receive(:warn) + it "clears out the invalid answers" do + allow(logger).to receive(:warn) - lettings_log_service.send(:create_log, lettings_log_xml) - lettings_log = LettingsLog.find_by(old_id: lettings_log_id) + lettings_log_service.send(:create_log, lettings_log_xml) + lettings_log = LettingsLog.find_by(old_id: lettings_log_id) - expect(lettings_log).not_to be_nil - expect(lettings_log.is_carehome).to be_truthy - expect(lettings_log.chcharge).to be_nil + expect(lettings_log).not_to be_nil + expect(lettings_log.age1).to be_nil + expect(lettings_log.prevten).to be_nil + end end - end - context "and this is an internal transfer from a non social housing" do - before do - lettings_log_xml.at_xpath("//xmlns:Q11").content = "9 Residential care home" - lettings_log_xml.at_xpath("//xmlns:Q16").content = "1 Internal Transfer" - end + context "and is a carehome but missing carehome charge" do + let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" } - it "intercepts the relevant validation error" do - expect(logger).to receive(:warn).with(/Removing internal transfer referral since previous tenancy is a non social housing/) - expect { lettings_log_service.send(:create_log, lettings_log_xml) } - .not_to raise_error - end + before do + lettings_log_xml.at_xpath("//meta:status").content = "submitted" + lettings_log_xml.at_xpath("//xmlns:_1cmangroupcode").content = scheme2.old_visible_id + scheme2.update!(registered_under_care_act: 2) + lettings_log_xml.at_xpath("//xmlns:Q18b").content = "" + end - it "clears out the referral answer" do - allow(logger).to receive(:warn) + it "intercepts the relevant validation error" do + allow(logger).to receive(:warn) - lettings_log_service.send(:create_log, lettings_log_xml) - lettings_log = LettingsLog.find_by(old_id: lettings_log_id) + expect { lettings_log_service.send(:create_log, lettings_log_xml) } + .not_to raise_error + end + + it "clears out the invalid answers" do + allow(logger).to receive(:warn) + + lettings_log_service.send(:create_log, lettings_log_xml) + lettings_log = LettingsLog.find_by(old_id: lettings_log_id) - expect(lettings_log).not_to be_nil - expect(lettings_log.referral).to be_nil + expect(lettings_log).not_to be_nil + expect(lettings_log.is_carehome).to be_truthy + expect(lettings_log.chcharge).to be_nil + end end - context "and this is an internal transfer from a previous fixed term tenancy" do + context "and this is an internal transfer from a non social housing" do before do - lettings_log_xml.at_xpath("//xmlns:Q11").content = "30 Fixed term Local Authority General Needs tenancy" + lettings_log_xml.at_xpath("//xmlns:Q11").content = "9 Residential care home" lettings_log_xml.at_xpath("//xmlns:Q16").content = "1 Internal Transfer" end it "intercepts the relevant validation error" do - expect(logger).to receive(:warn).with(/Removing internal transfer referral since previous tenancy is fixed terms or lifetime/) + expect(logger).to receive(:warn).with(/Removing internal transfer referral since previous tenancy is a non social housing/) expect { lettings_log_service.send(:create_log, lettings_log_xml) } .not_to raise_error end @@ -356,86 +341,202 @@ RSpec.describe Imports::LettingsLogsImportService do expect(lettings_log).not_to be_nil expect(lettings_log.referral).to be_nil end + + context "and this is an internal transfer from a previous fixed term tenancy" do + before do + lettings_log_xml.at_xpath("//xmlns:Q11").content = "30 Fixed term Local Authority General Needs tenancy" + lettings_log_xml.at_xpath("//xmlns:Q16").content = "1 Internal Transfer" + end + + it "intercepts the relevant validation error" do + expect(logger).to receive(:warn).with(/Removing internal transfer referral since previous tenancy is fixed terms or lifetime/) + expect { lettings_log_service.send(:create_log, lettings_log_xml) } + .not_to raise_error + end + + it "clears out the referral answer" do + allow(logger).to receive(:warn) + + lettings_log_service.send(:create_log, lettings_log_xml) + lettings_log = LettingsLog.find_by(old_id: lettings_log_id) + + expect(lettings_log).not_to be_nil + expect(lettings_log.referral).to be_nil + end + end end - end - context "and the net income soft validation is triggered (net_income_value_check)" do - before do - lettings_log_xml.at_xpath("//xmlns:Q8a").content = "1 Weekly" - lettings_log_xml.at_xpath("//xmlns:Q8Money").content = 890.00 + context "and the net income soft validation is triggered (net_income_value_check)" do + before do + lettings_log_xml.at_xpath("//xmlns:Q8a").content = "1 Weekly" + lettings_log_xml.at_xpath("//xmlns:Q8Money").content = 890.00 + end + + it "completes the log" do + lettings_log_service.send(:create_log, lettings_log_xml) + lettings_log = LettingsLog.find_by(old_id: lettings_log_id) + expect(lettings_log.status).to eq("completed") + end end - it "completes the log" do - lettings_log_service.send(:create_log, lettings_log_xml) - lettings_log = LettingsLog.find_by(old_id: lettings_log_id) - expect(lettings_log.status).to eq("completed") + context "and the rent soft validation is triggered (rent_value_check)" do + before do + lettings_log_xml.at_xpath("//xmlns:Q18ai").content = 200.00 + lettings_log_xml.at_xpath("//xmlns:Q18av").content = 232.02 + lettings_log_xml.at_xpath("//xmlns:Q17").content = "1 Weekly for 52 weeks" + LaRentRange.create!( + start_year: 2021, + la: "E08000035", + beds: 2, + lettype: 1, + soft_max: 900, + hard_max: 1500, + soft_min: 500, + hard_min: 100, + ) + end + + it "completes the log" do + lettings_log_service.send(:create_log, lettings_log_xml) + lettings_log = LettingsLog.find_by(old_id: lettings_log_id) + expect(lettings_log.status).to eq("completed") + end end - end - context "and the rent soft validation is triggered (rent_value_check)" do - before do - lettings_log_xml.at_xpath("//xmlns:Q18ai").content = 200.00 - lettings_log_xml.at_xpath("//xmlns:Q18av").content = 232.02 - lettings_log_xml.at_xpath("//xmlns:Q17").content = "1 Weekly for 52 weeks" - LaRentRange.create!( - start_year: 2021, - la: "E08000035", - beds: 2, - lettype: 1, - soft_max: 900, - hard_max: 1500, - soft_min: 500, - hard_min: 100, - ) + context "and the retirement soft validation is triggered (retirement_value_check)" do + before do + lettings_log_xml.at_xpath("//xmlns:P1Age").content = 68 + lettings_log_xml.at_xpath("//xmlns:P1Eco").content = "6) Not Seeking Work" + end + + it "completes the log" do + lettings_log_service.send(:create_log, lettings_log_xml) + lettings_log = LettingsLog.find_by(old_id: lettings_log_id) + expect(lettings_log.status).to eq("completed") + end end - it "completes the log" do - lettings_log_service.send(:create_log, lettings_log_xml) - lettings_log = LettingsLog.find_by(old_id: lettings_log_id) - expect(lettings_log.status).to eq("completed") + context "and this is a supported housing log with multiple locations under a scheme" do + let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" } + + it "sets the scheme and location values" do + expect(logger).not_to receive(:warn) + lettings_log_service.send(:create_log, lettings_log_xml) + lettings_log = LettingsLog.find_by(old_id: lettings_log_id) + + expect(lettings_log.scheme_id).not_to be_nil + expect(lettings_log.location_id).not_to be_nil + expect(lettings_log.status).to eq("completed") + end end - end - context "and the retirement soft validation is triggered (retirement_value_check)" do - before do - lettings_log_xml.at_xpath("//xmlns:P1Age").content = 68 - lettings_log_xml.at_xpath("//xmlns:P1Eco").content = "6) Not Seeking Work" + context "and this is a supported housing log with a single location under a scheme" do + let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" } + + before { lettings_log_xml.at_xpath("//xmlns:_1cmangroupcode").content = scheme2.old_visible_id } + + it "sets the scheme and location values" do + expect(logger).not_to receive(:warn) + lettings_log_service.send(:create_log, lettings_log_xml) + lettings_log = LettingsLog.find_by(old_id: lettings_log_id) + + expect(lettings_log.scheme_id).not_to be_nil + expect(lettings_log.location_id).not_to be_nil + expect(lettings_log.status).to eq("completed") + end end + end + end - it "completes the log" do - lettings_log_service.send(:create_log, lettings_log_xml) - lettings_log = LettingsLog.find_by(old_id: lettings_log_id) - expect(lettings_log.status).to eq("completed") + context "with 22/23 logs" do + subject(:lettings_log_service) { described_class.new(storage_service, logger) } + + around do |example| + Timecop.freeze(Time.zone.local(2023, 1, 1)) do + Singleton.__init__(FormHandler) + example.run end + Timecop.return + Singleton.__init__(FormHandler) end - context "and this is a supported housing log with multiple locations under a scheme" do - let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" } + let(:storage_service) { instance_double(Storage::S3Service) } + let(:logger) { instance_double(ActiveSupport::Logger) } - it "sets the scheme and location values" do - expect(logger).not_to receive(:warn) - lettings_log_service.send(:create_log, lettings_log_xml) - lettings_log = LettingsLog.find_by(old_id: lettings_log_id) + let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json") } + let(:real_2022_2023_form) { Form.new("config/forms/2022_2023.json") } + let(:fixture_directory) { "spec/fixtures/imports/logs" } - expect(lettings_log.scheme_id).not_to be_nil - expect(lettings_log.location_id).not_to be_nil - expect(lettings_log.status).to eq("completed") - end + let(:organisation) { FactoryBot.create(:organisation, old_visible_id: "1", provider_type: "PRP") } + let(:managing_organisation) { FactoryBot.create(:organisation, old_visible_id: "2", provider_type: "PRP") } + let(:scheme1) { FactoryBot.create(:scheme, old_visible_id: "0123", owning_organisation: organisation) } + let(:scheme2) { FactoryBot.create(:scheme, old_visible_id: "456", owning_organisation: organisation) } + + def open_file(directory, filename) + File.open("#{directory}/#{filename}.xml") end - context "and this is a supported housing log with a single location under a scheme" do - let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" } + before do + WebMock.stub_request(:get, /api.postcodes.io\/postcodes\/LS166FT/) + .to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Westminster","codes":{"admin_district":"E08000035"}}}', headers: {}) + + allow(Organisation).to receive(:find_by).and_return(nil) + allow(Organisation).to receive(:find_by).with(old_visible_id: organisation.old_visible_id).and_return(organisation) + allow(Organisation).to receive(:find_by).with(old_visible_id: managing_organisation.old_visible_id).and_return(managing_organisation) + + # Created by users + FactoryBot.create(:user, old_user_id: "c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa", organisation:) + FactoryBot.create(:user, old_user_id: "e29c492473446dca4d50224f2bb7cf965a261d6f", organisation:) + + # Location setup + FactoryBot.create(:location, old_visible_id: "10", postcode: "LS166FT", scheme_id: scheme1.id, mobility_type: "W", startdate: Time.zone.local(2021, 4, 1)) + FactoryBot.create(:location, scheme_id: scheme1.id, startdate: Time.zone.local(2021, 4, 1)) + FactoryBot.create(:location, old_visible_id: "10", postcode: "LS166FT", scheme_id: scheme2.id, mobility_type: "W", startdate: Time.zone.local(2021, 4, 1)) + + # Stub the form handler to use the real form + allow(FormHandler.instance).to receive(:get_form).with("current_lettings").and_return(real_2022_2023_form) + allow(FormHandler.instance).to receive(:get_form).with("previous_lettings").and_return(real_2021_2022_form) + allow(FormHandler.instance).to receive(:get_form).with("next_lettings").and_return(real_2022_2023_form) + end - before { lettings_log_xml.at_xpath("//xmlns:_1cmangroupcode").content = scheme2.old_visible_id } + context "when importing lettings logs" do + let(:remote_folder) { "lettings_logs" } + let(:lettings_log_id) { "00d2343e-d5fa-4c89-8400-ec3854b0f2b4" } + let(:sales_log) { "shared_ownership_sales_log" } - it "sets the scheme and location values" do + before do + # Stub the S3 file listing and download + allow(storage_service).to receive(:list_files) + .and_return(%W[#{remote_folder}/#{lettings_log_id}.xml #{remote_folder}/#{sales_log}.xml]) + allow(storage_service).to receive(:get_file_io) + .with("#{remote_folder}/#{lettings_log_id}.xml") + .and_return(open_file(fixture_directory, lettings_log_id), open_file(fixture_directory, lettings_log_id)) + allow(storage_service).to receive(:get_file_io) + .with("#{remote_folder}/#{sales_log}.xml") + .and_return(open_file(fixture_directory, sales_log), open_file(fixture_directory, sales_log)) + end + + it "successfully create all lettings logs" do + expect(logger).not_to receive(:error) expect(logger).not_to receive(:warn) - lettings_log_service.send(:create_log, lettings_log_xml) - lettings_log = LettingsLog.find_by(old_id: lettings_log_id) + expect(logger).not_to receive(:info) + expect { lettings_log_service.create_logs(remote_folder) } + .to change(LettingsLog, :count).by(1) + end - expect(lettings_log.scheme_id).not_to be_nil - expect(lettings_log.location_id).not_to be_nil - expect(lettings_log.status).to eq("completed") + it "only updates existing lettings logs" do + expect(logger).not_to receive(:error) + expect(logger).not_to receive(:warn) + expect(logger).to receive(:info).with(/Updating lettings log/).once + expect { 2.times { lettings_log_service.create_logs(remote_folder) } } + .to change(LettingsLog, :count).by(1) + end + + it "creates organisation relationship once" do + expect(logger).not_to receive(:error) + expect(logger).not_to receive(:warn) + expect { lettings_log_service.create_logs(remote_folder) } + .to change(OrganisationRelationship, :count).by(1) end end end diff --git a/spec/services/imports/sales_logs_import_service_spec.rb b/spec/services/imports/sales_logs_import_service_spec.rb index 2481cdce7..d0e1f807d 100644 --- a/spec/services/imports/sales_logs_import_service_spec.rb +++ b/spec/services/imports/sales_logs_import_service_spec.rb @@ -363,20 +363,34 @@ RSpec.describe Imports::SalesLogsImportService do end end - context "and it has an invalid record with invalid child, student and 16-19 age combination" do + context "and the student not child soft validation is triggered (student_not_child_value_check)" do + let(:sales_log_id) { "shared_ownership_sales_log" } + + before do + sales_log_xml.at_xpath("//xmlns:P2Rel").content = "P" + sales_log_xml.at_xpath("//xmlns:P2Eco").content = "7" + sales_log_xml.at_xpath("//xmlns:P2Age").content = "16" + end + + it "completes the log" do + sales_log_service.send(:create_log, sales_log_xml) + sales_log = SalesLog.find_by(old_id: sales_log_id) + expect(sales_log.status).to eq("completed") + end + end + + context "and it has an invalid record with invalid child age" do let(:sales_log_id) { "discounted_ownership_sales_log" } before do sales_log_xml.at_xpath("//meta:status").content = "submitted-invalid" - sales_log_xml.at_xpath("//xmlns:P2Age").content = 16 - sales_log_xml.at_xpath("//xmlns:P2Eco").content = 7 - sales_log_xml.at_xpath("//xmlns:P2Rel").content = "X" + sales_log_xml.at_xpath("//xmlns:P2Age").content = 17 + sales_log_xml.at_xpath("//xmlns:P2Eco").content = 9 end it "intercepts the relevant validation error" do - expect(logger).to receive(:warn).with(/Removing field age2 from log triggering validation: Person cannot be aged 16-19 if they are a student but don't have relationship ‘child’/) - expect(logger).to receive(:warn).with(/Removing field relat2 from log triggering validation: Answer must be ‘child’ if the person is aged 16-19 and a student/) - expect(logger).to receive(:warn).with(/Removing field ecstat2 from log triggering validation: Person cannot be a student if they are aged 16-19 but don‘t have relationship ‘child’/) + expect(logger).to receive(:warn).with(/Log discounted_ownership_sales_log: Removing field ecstat2 from log triggering validation: Answer cannot be ‘child under 16’ as you told us the person 2 is older than 16/) + expect(logger).to receive(:warn).with(/Log discounted_ownership_sales_log: Removing field age2 from log triggering validation: Answer cannot be over 16 as person’s 2 working situation is ‘child under 16‘/) expect { sales_log_service.send(:create_log, sales_log_xml) } .not_to raise_error end @@ -389,7 +403,6 @@ RSpec.describe Imports::SalesLogsImportService do expect(sales_log).not_to be_nil expect(sales_log.age2).to be_nil - expect(sales_log.relat2).to be_nil expect(sales_log.ecstat2).to be_nil end end @@ -398,17 +411,12 @@ RSpec.describe Imports::SalesLogsImportService do let(:sales_log_id) { "discounted_ownership_sales_log" } before do - sales_log_xml.at_xpath("//meta:status").content = "submitted-invalid" - sales_log_xml.at_xpath("//xmlns:Q7Postcode").content = "A1 1AA" - sales_log_xml.at_xpath("//xmlns:Q14Postcode").content = "A1 2AA" + sales_log_xml.at_xpath("//xmlns:Q7Postcode").content = "A1 1AA" # previous postcode + sales_log_xml.at_xpath("//xmlns:Q14Postcode").content = "A1 2AA" # postcode end it "intercepts the relevant validation error" do - expect(logger).to receive(:warn).with(/Removing field postcode_full from log triggering validation: Buyer's last accommodation and discounted ownership postcodes must match/) - expect(logger).to receive(:warn).with(/Removing field ppostcode_full from log triggering validation: Buyer's last accommodation and discounted ownership postcodes must match/) - expect(logger).to receive(:warn).with(/Removing field postcode_full from log triggering validation: postcodes_not_matching/) - expect(logger).to receive(:warn).with(/Removing field ppostcode_full from log triggering validation: postcodes_not_matching/) - expect(logger).to receive(:warn).with(/Removing postcode known and previous postcode known as the postcodes are invalid/) + expect(logger).to receive(:warn).with(/Removing previous postcode known and previous postcode as the postcode is invalid/) expect { sales_log_service.send(:create_log, sales_log_xml) } .not_to raise_error end @@ -420,11 +428,66 @@ RSpec.describe Imports::SalesLogsImportService do sales_log = SalesLog.find_by(old_id: sales_log_id) expect(sales_log).not_to be_nil - expect(sales_log.postcode_full).to be_nil + expect(sales_log.postcode_full).to eq("A1 2AA") expect(sales_log.ppostcode_full).to be_nil end end + context "and it has an invalid record with invalid contracts exchange date" do + let(:sales_log_id) { "shared_ownership_sales_log" } + + before do + sales_log_xml.at_xpath("//xmlns:DAY").content = "1" + sales_log_xml.at_xpath("//xmlns:MONTH").content = "10" + sales_log_xml.at_xpath("//xmlns:YEAR").content = "2022" + sales_log_xml.at_xpath("//xmlns:EXDAY").content = "1" + sales_log_xml.at_xpath("//xmlns:EXMONTH").content = "4" + sales_log_xml.at_xpath("//xmlns:EXYEAR").content = "2020" + end + + it "intercepts the relevant validation error" do + expect(logger).to receive(:warn).with(/Removing exchange date as the exchange date is invalid/) + expect { sales_log_service.send(:create_log, sales_log_xml) } + .not_to raise_error + end + + it "clears out the invalid answers" do + allow(logger).to receive(:warn) + + sales_log_service.send(:create_log, sales_log_xml) + sales_log = SalesLog.find_by(old_id: sales_log_id) + + expect(sales_log).not_to be_nil + expect(sales_log.saledate).to eq(Time.zone.local(2022, 10, 1)) + expect(sales_log.exdate).to be_nil + end + end + + context "and it has an invalid income" do + let(:sales_log_id) { "shared_ownership_sales_log" } + + before do + sales_log_xml.at_xpath("//xmlns:Q2Person1Income").content = "85000" + sales_log_xml.at_xpath("//xmlns:Q14ONSLACode").content = "E07000223" + end + + it "intercepts the relevant validation error" do + expect(logger).to receive(:warn).with(/Removing income1 as the income1 is invalid/) + expect { sales_log_service.send(:create_log, sales_log_xml) } + .not_to raise_error + end + + it "clears out the invalid answers" do + allow(logger).to receive(:warn) + + sales_log_service.send(:create_log, sales_log_xml) + sales_log = SalesLog.find_by(old_id: sales_log_id) + + expect(sales_log).not_to be_nil + expect(sales_log.income1).to be_nil + end + end + context "when inferring default answers for completed sales logs" do context "when the armedforcesspouse is not answered" do let(:sales_log_id) { "discounted_ownership_sales_log" } @@ -1126,6 +1189,54 @@ RSpec.describe Imports::SalesLogsImportService do expect(sales_log&.mortgageused).to eq(1) end end + + context "when the extrabor is not answered" do + let(:sales_log_id) { "discounted_ownership_sales_log" } + + before do + sales_log_xml.at_xpath("//xmlns:Q35Borrowing").content = "" + allow(logger).to receive(:warn).and_return(nil) + end + + it "sets extrabor to don't know" do + sales_log_service.send(:create_log, sales_log_xml) + + sales_log = SalesLog.find_by(old_id: sales_log_id) + expect(sales_log&.extrabor).to be(3) + end + end + + context "when the fromprop is not answered" do + let(:sales_log_id) { "shared_ownership_sales_log" } + + before do + sales_log_xml.at_xpath("//xmlns:Q21PropertyType").content = "" + allow(logger).to receive(:warn).and_return(nil) + end + + it "sets fromprop to don't know" do + sales_log_service.send(:create_log, sales_log_xml) + + sales_log = SalesLog.find_by(old_id: sales_log_id) + expect(sales_log&.fromprop).to be(0) + end + end + + context "when the socprevten is not answered" do + let(:sales_log_id) { "shared_ownership_sales_log" } + + before do + sales_log_xml.at_xpath("//xmlns:PrevRentType").content = "" + allow(logger).to receive(:warn).and_return(nil) + end + + it "sets socprevten to don't know" do + sales_log_service.send(:create_log, sales_log_xml) + + sales_log = SalesLog.find_by(old_id: sales_log_id) + expect(sales_log&.socprevten).to be(10) + end + end end end end diff --git a/spec/services/uprn_client_spec.rb b/spec/services/uprn_client_spec.rb new file mode 100644 index 000000000..b595b7e76 --- /dev/null +++ b/spec/services/uprn_client_spec.rb @@ -0,0 +1,68 @@ +require "rails_helper" + +describe UprnClient do + let(:client) { described_class.new("123") } + + let(:valid_response) do + { results: [{ DPA: { postcode: "12345" } }] }.to_json + end + + def stub_api_request(body:, status: 200) + stub_request(:get, "https://api.os.uk/search/places/v1/uprn?key=OS_DATA_KEY&uprn=123") + .to_return(status:, body:, headers: {}) + end + + describe "call" do + context "when json parse error" do + before do + stub_api_request(body: "{", status: 200) + + client.call + end + + it "returns error" do + expect(client.error).to eq("UPRN is not recognised. Check the number, or enter the address") + end + end + + context "when http error" do + before do + stub_api_request(body: valid_response, status: 500) + + client.call + end + + it "returns error" do + expect(client.error).to eq("UPRN is not recognised. Check the number, or enter the address") + end + end + + context "when results empty" do + before do + stub_api_request(body: {}.to_json) + + client.call + end + + it "returns error" do + expect(client.error).to eq("UPRN is not recognised. Check the number, or enter the address") + end + end + + context "with results" do + before do + stub_api_request(body: valid_response) + + client.call + end + + it "returns result" do + expect(client.result).to eq({ "postcode" => "12345" }) + end + + it "returns no error" do + expect(client.error).to be_nil + end + end + end +end diff --git a/spec/services/uprn_data_presenter_spec.rb b/spec/services/uprn_data_presenter_spec.rb new file mode 100644 index 000000000..16ae9318f --- /dev/null +++ b/spec/services/uprn_data_presenter_spec.rb @@ -0,0 +1,66 @@ +require "rails_helper" + +describe UprnDataPresenter do + let(:data) do + JSON.parse( + '{ + "UPRN": "UPRN", + "UDPRN": "UDPRN", + "ADDRESS": "full address", + "SUB_BUILDING_NAME": "0", + "BUILDING_NAME": "building name", + "THOROUGHFARE_NAME": "thoroughfare", + "POST_TOWN": "posttown", + "POSTCODE": "postcode", + "STATUS": "APPROVED", + "DOUBLE_DEPENDENT_LOCALITY": "double dependent locality", + "DEPENDENT_LOCALITY": "dependent locality", + "CLASSIFICATION_CODE": "classification code", + "LOCAL_CUSTODIAN_CODE_DESCRIPTION": "LONDON BOROUGH OF HARINGEY", + "BLPU_STATE_CODE": "2", + "BLPU_STATE_CODE_DESCRIPTION": "In use", + "LAST_UPDATE_DATE": "31/07/2020", + "ENTRY_DATE": "30/01/2015", + "BLPU_STATE_DATE": "30/01/2015", + "LANGUAGE": "EN", + "MATCH_DESCRIPTION": "EXACT" + }', + ) + end + + let(:presenter) { described_class.new(data) } + + describe "#postcode" do + it "returns postcode" do + expect(presenter.postcode).to eq("postcode") + end + end + + describe "#address_line1" do + it "returns address_line1" do + expect(presenter.address_line1).to eq("0, Building Name, Thoroughfare") + end + end + + describe "#address_line2" do + it "returns address_line2" do + expect(presenter.address_line2).to eq("Double Dependent Locality, Dependent Locality") + end + end + + describe "#town_or_city" do + it "returns town_or_city" do + expect(presenter.town_or_city).to eq("Posttown") + end + end + + context "when address_line2 fields are missing" do + let(:data) { {} } + + describe "#address_line2" do + it "returns nil" do + expect(presenter.address_line2).to be_nil + end + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c5ea8e451..9677a128c 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -111,8 +111,18 @@ RSpec.configure do |config| config.include FactoryBot::Syntax::Methods - config.before { RequestHelper.stub_http_requests } - config.after { RequestHelper.real_http_requests } + config.before do + RequestHelper.stub_http_requests + end + + config.before(:suite) do + Rails.application.load_seed + end + + config.after do + RequestHelper.real_http_requests + Singleton.__init__(FormHandler) + end end RSpec::Matchers.define_negated_matcher :not_change, :change diff --git a/spec/support/bulk_upload/log_to_csv.rb b/spec/support/bulk_upload/log_to_csv.rb index e15c9173b..86167376d 100644 --- a/spec/support/bulk_upload/log_to_csv.rb +++ b/spec/support/bulk_upload/log_to_csv.rb @@ -8,9 +8,49 @@ class BulkUpload::LogToCsv @overrides = overrides end - def to_csv_row + def row_prefix + [nil] * col_offset + end + + def to_2022_csv_row + (row_prefix + to_2022_row).flatten.join(",") + line_ending + end + + def to_2023_csv_row(seed: nil) + if seed + row = to_2023_row.shuffle(random: Random.new(seed)) + (row_prefix + row).flatten.join(",") + line_ending + else + (row_prefix + to_2023_row).flatten.join(",") + line_ending + end + end + + def to_2023_row + to_2022_row + [ + log.needstype, + log.location&.id, + nil, # uprn, + nil, # address_line_1, + nil, # address_line_2, + nil, # town_or_city, + nil, # county, + ] + end + + def default_2023_field_numbers_row(seed: nil) + if seed + ["Bulk upload field number"] + default_2023_field_numbers.shuffle(random: Random.new(seed)) + else + ["Bulk upload field number"] + default_2023_field_numbers + end.flatten.join(",") + line_ending + end + + def default_2023_field_numbers + [5, nil, nil, 15, 16, nil, 13, 40, 41, 42, 43, 46, 52, 56, 60, 64, 68, 72, 76, 47, 53, 57, 61, 65, 69, 73, 77, 51, 55, 59, 63, 67, 71, 75, 50, 54, 58, 62, 66, 70, 74, 78, 48, 49, 79, 81, 82, 123, 124, 122, 120, 102, 103, nil, 83, 84, 85, 86, 87, 88, 104, 109, 107, 108, 106, 100, 101, 105, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 126, 128, 129, 130, 131, 132, 127, 125, 133, 134, 33, 34, 35, 36, 37, 38, nil, 7, 8, 9, 28, 14, 32, 29, 30, 31, 26, 27, 25, 23, 24, nil, 1, 3, 2, 80, nil, 121, 44, 89, 98, 92, 95, 90, 91, 93, 94, 97, 96, 99, 10, 11, 12, 45, 39, 6, 4, 17, 18, 19, 20, 21, 22] + end + + def to_2022_row [ - [nil] * col_offset, # 0 log.renttype, # 1 nil, nil, @@ -155,10 +195,11 @@ class BulkUpload::LogToCsv log.declaration, log.joint, renewal, - line_ending, - ].flatten.join(",") + ] end +private + def renewal checkbox_value(log.renewal) end diff --git a/spec/views/form/page_view_spec.rb b/spec/views/form/page_view_spec.rb index a7039a9a9..074a7fd6a 100644 --- a/spec/views/form/page_view_spec.rb +++ b/spec/views/form/page_view_spec.rb @@ -17,6 +17,15 @@ RSpec.describe "form/page" do end end + around do |example| + Timecop.freeze(Time.zone.local(2022, 1, 1)) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + before do assign(:log, lettings_log) assign(:page, page)