From eda367afb06ae895cbabbc8e4be5720d8f2e99ee Mon Sep 17 00:00:00 2001 From: Arthur Campbell <51094020+arfacamble@users.noreply.github.com> Date: Thu, 30 May 2024 12:36:28 +0100 Subject: [PATCH] Cldc 3114 enable support control of rent periods per organisation (#2389) * write helper method to support having the correct rent period checkboxes checked * update new and create in organisations controller and view to enable creation of relevant organisation rent periods write tests for this * small changes to models * enable editing rent period in the UI display change button on org details page display rent periods question on edit page * enable updating org rent periods update logic in #update related tests * alter redirect after support user creates an organisation * adjust various UI elements: ordering of rows, copy changes, label size and associated tests * rework the #rent_period_labels method to return All under the correct conditions, rework tests related to that. + fix assorted tests that were either flakey or breaking due to addition of rent periods logic to create and update * amend failing tests and resolve linting complaints * changes following review * disable checkboxes for rent periods if they are in use so that users are not able to make existing logs invalid hint text added to the question to explain this I have also added all rent periods to a hidden field to remove the need to fetch them again form the db in the update method * update validation to reflect the fact that an org having no associated rent periods no longer means they accept all rent periods update tests adding both cases and removing unnecessary additional db additions * rake task to create rent period associations for orgs that have none * revert mistaken copy changes in designs * create rent periods in factories as default, with an option to skip. skip automatic creation in tests specifically related to rent periods * stub api call for factory value, update csv tests and fixtures accordingly * extract a good chunk of tests out of lettings_log_spec and into a dedicated derived fields spec file. in many cases refactor tests * remove before(:context) and associated patterns. use assign_attributes in various places for cleaner code * escape . in regex for API call stubs to satisfy codeQL remove destroy_all call at the start of a test that was dealing with leftover modesl in the test db * further refactoring of various tests to reduce database interactions and improve speed * remove outdated distinction between unitletas mappings from before 23/24 * remove tests that seem to be testing active record and/or ruby Date class --- app/controllers/organisations_controller.rb | 31 +- app/helpers/organisations_helper.rb | 11 +- .../lettings_log_variables.rb | 12 +- app/models/organisation.rb | 9 +- app/models/organisation_rent_period.rb | 2 + .../validations/financial_validations.rb | 5 +- app/views/organisations/edit.html.erb | 25 +- app/views/organisations/new.html.erb | 14 +- app/views/organisations/show.html.erb | 33 +- config/locales/en.yml | 1 + .../create_organisation_rent_periods.rake | 11 + spec/factories/organisation.rb | 12 + spec/features/form/page_routing_spec.rb | 2 +- .../files/sales_logs_csv_export_codes_23.csv | 2 +- .../files/sales_logs_csv_export_codes_24.csv | 2 +- .../files/sales_logs_csv_export_labels_23.csv | 2 +- .../files/sales_logs_csv_export_labels_24.csv | 2 +- ..._logs_csv_export_non_support_labels_24.csv | 2 +- spec/helpers/organisations_helper_spec.rb | 44 +- .../lettings_log_derived_fields_spec.rb | 1144 ++++++++++ spec/models/lettings_log_spec.rb | 1942 ++--------------- spec/models/location_spec.rb | 2 +- spec/models/organisation_spec.rb | 67 +- spec/models/sales_log_spec.rb | 4 +- .../validations/financial_validations_spec.rb | 29 +- spec/request_helper.rb | 4 +- ...anisations_controller_rent_periods_spec.rb | 119 + .../requests/lettings_logs_controller_spec.rb | 2 +- .../requests/organisations_controller_spec.rb | 36 +- .../lettings/year2023/row_parser_spec.rb | 2 +- .../sales/year2023/row_parser_spec.rb | 2 +- .../csv/sales_log_csv_service_spec.rb | 8 +- .../merge/merge_organisations_service_spec.rb | 6 + .../views/organisations/show.html.erb_spec.rb | 5 - 34 files changed, 1695 insertions(+), 1899 deletions(-) create mode 100644 lib/tasks/create_organisation_rent_periods.rake create mode 100644 spec/models/lettings_log_derived_fields_spec.rb create mode 100644 spec/requests/OrganisationsController/organisations_controller_rent_periods_spec.rb diff --git a/app/controllers/organisations_controller.rb b/app/controllers/organisations_controller.rb index 686a5f36c..583a64fdc 100644 --- a/app/controllers/organisations_controller.rb +++ b/app/controllers/organisations_controller.rb @@ -73,21 +73,31 @@ class OrganisationsController < ApplicationController end def new - @resource = Organisation.new + @organisation = Organisation.new + @rent_periods = helpers.rent_periods_with_checked_attr render "new", layout: "application" end def create - @resource = Organisation.new(org_params) - if @resource.save - redirect_to organisations_path + selected_rent_periods = rent_period_params[:rent_periods].compact_blank + @organisation = Organisation.new(org_params) + if @organisation.save + OrganisationRentPeriod.transaction do + selected_rent_periods.each { |period| OrganisationRentPeriod.create!(organisation: @organisation, rent_period: period) } + end + flash[:notice] = I18n.t("organisation.created", organisation: @organisation.name) + redirect_to organisation_path @organisation else + @rent_periods = helpers.rent_periods_with_checked_attr(checked_periods: selected_rent_periods) render :new, status: :unprocessable_entity end end def edit if current_user.data_coordinator? || current_user.support? + current_allowed_rent_periods = @organisation.organisation_rent_periods.pluck(:rent_period).map(&:to_s) + @used_rent_periods = @organisation.lettings_logs.pluck(:period).uniq.compact.map(&:to_s) + @rent_periods = helpers.rent_periods_with_checked_attr(checked_periods: current_allowed_rent_periods) render "edit", layout: "application" else head :unauthorized @@ -107,6 +117,7 @@ class OrganisationsController < ApplicationController end def update + selected_rent_periods = rent_period_params[:rent_periods].compact_blank if (current_user.data_coordinator? && org_params[:active].nil?) || current_user.support? if @organisation.update(org_params) case org_params[:active] @@ -125,7 +136,15 @@ class OrganisationsController < ApplicationController else flash[:notice] = I18n.t("organisation.updated") end + rent_periods_to_delete = rent_period_params[:all_rent_periods] - selected_rent_periods + OrganisationRentPeriod.transaction do + selected_rent_periods.each { |period| OrganisationRentPeriod.create(organisation: @organisation, rent_period: period) } + OrganisationRentPeriod.where(organisation: @organisation, rent_period: rent_periods_to_delete).destroy_all + end redirect_to details_organisation_path(@organisation) + else + @rent_periods = helpers.rent_periods_with_checked_attr(checked_periods: selected_rent_periods) + render :edit, status: :unprocessable_entity end else head :unauthorized @@ -273,6 +292,10 @@ private params.require(:organisation).permit(:name, :address_line1, :address_line2, :postcode, :phone, :holds_own_stock, :provider_type, :housing_registration_no, :active) end + def rent_period_params + params.require(:organisation).permit(rent_periods: [], all_rent_periods: []) + end + def codes_only_export? params.require(:codes_only) == "true" end diff --git a/app/helpers/organisations_helper.rb b/app/helpers/organisations_helper.rb index cf53bd244..7d37b9289 100644 --- a/app/helpers/organisations_helper.rb +++ b/app/helpers/organisations_helper.rb @@ -14,10 +14,11 @@ module OrganisationsHelper { name: "Organisation ID", value: "ORG#{organisation.id}", editable: false }, { name: "Address", value: organisation.address_string, editable: true }, { name: "Telephone number", value: organisation.phone, editable: true }, - { name: "Type of provider", value: organisation.display_provider_type, editable: false }, { name: "Registration number", value: organisation.housing_registration_no || "", editable: false }, - { name: "Rent periods", value: organisation.rent_period_labels, editable: false, format: :bullet }, + { name: "Type of provider", value: organisation.display_provider_type, editable: false }, { name: "Owns housing stock", value: organisation.holds_own_stock ? "Yes" : "No", editable: false }, + { name: "Rent periods", value: organisation.rent_period_labels, editable: true, format: :bullet }, + { name: "Data Sharing Agreement" }, { name: "Status", value: status_tag(organisation.status), editable: false }, ] end @@ -37,4 +38,10 @@ module OrganisationsHelper end end end + + def rent_periods_with_checked_attr(checked_periods: nil) + RentPeriod.rent_period_mappings.each_with_object({}) do |(period_code, period_value), result| + result[period_code] = period_value.merge(checked: checked_periods.nil? || checked_periods.include?(period_code)) + end + end end diff --git a/app/models/derived_variables/lettings_log_variables.rb b/app/models/derived_variables/lettings_log_variables.rb index 815fbbe55..7bed44cbd 100644 --- a/app/models/derived_variables/lettings_log_variables.rb +++ b/app/models/derived_variables/lettings_log_variables.rb @@ -1,7 +1,6 @@ module DerivedVariables::LettingsLogVariables include DerivedVariables::SharedLogic - # renttype and unitletas values are different for intermediate rent (3 for renttype and 4 for unitletas) RENT_TYPE_MAPPING = { 0 => 1, # "Social Rent" => "Social Rent" 1 => 2, # "Affordable Rent" => "Affordable Rent" @@ -12,15 +11,6 @@ module DerivedVariables::LettingsLogVariables }.freeze UNITLETAS_MAPPING = { - 0 => 1, # "Social Rent" => "Social Rent basis" - 1 => 2, # "Affordable Rent" => "Affordable Rent basis" - 2 => 2, # "London Affordable Rent" => "Affordable Rent basis" - 3 => 4, # "Rent to Buy" => "Intermediate Rent basis" - 4 => 4, # "London Living Rent" => "Intermediate Rent basis" - 5 => 4, # "Other intermediate rent product" => "Intermediate Rent basis" - }.freeze - - UNITLETAS_MAPPING_23_24 = { 0 => 1, # "Social Rent" => "Social Rent basis" 1 => 2, # "Affordable Rent" => "Affordable Rent basis" 2 => 5, # "London Affordable Rent" => "London Affordable Rent basis" @@ -120,7 +110,7 @@ module DerivedVariables::LettingsLogVariables if is_renewal? self.underoccupation_benefitcap = 2 if collection_start_year == 2021 self.voiddate = startdate - self.unitletas = form.start_date.year >= 2023 ? UNITLETAS_MAPPING_23_24[rent_type] : UNITLETAS_MAPPING[rent_type] + self.unitletas = UNITLETAS_MAPPING[rent_type] if is_general_needs? self.prevten = 32 if owning_organisation&.provider_type == "PRP" self.prevten = 30 if owning_organisation&.provider_type == "LA" diff --git a/app/models/organisation.rb b/app/models/organisation.rb index b5c6f36aa..0bd69f847 100644 --- a/app/models/organisation.rb +++ b/app/models/organisation.rb @@ -2,7 +2,7 @@ class Organisation < ApplicationRecord has_many :users, dependent: :delete_all has_many :data_protection_officers, -> { where(is_dpo: true) }, class_name: "User" has_one :data_protection_confirmation - has_many :organisation_rent_periods + has_many :organisation_rent_periods, dependent: :destroy has_many :owned_schemes, class_name: "Scheme", foreign_key: "owning_organisation_id", dependent: :delete_all has_many :parent_organisation_relationships, foreign_key: :child_organisation_id, class_name: "OrganisationRelationship" has_many :parent_organisations, through: :parent_organisation_relationships @@ -108,8 +108,11 @@ class Organisation < ApplicationRecord end def rent_period_labels - labels = rent_periods.map { |period| RentPeriod.rent_period_mappings.dig(period.to_s, "value") } - labels.compact.presence || %w[All] + rent_period_ids = rent_periods + mappings = RentPeriod.rent_period_mappings + return %w[All] if (mappings.keys.map(&:to_i) - rent_period_ids).empty? + + rent_period_ids.map { |id| mappings.dig(id.to_s, "value") }.compact end def data_protection_confirmed? diff --git a/app/models/organisation_rent_period.rb b/app/models/organisation_rent_period.rb index 292ac75b2..94934d74b 100644 --- a/app/models/organisation_rent_period.rb +++ b/app/models/organisation_rent_period.rb @@ -1,3 +1,5 @@ class OrganisationRentPeriod < ApplicationRecord belongs_to :organisation + + validates :organisation_id, uniqueness: { scope: :rent_period } # rubocop:disable Rails/UniqueValidationWithoutIndex end diff --git a/app/models/validations/financial_validations.rb b/app/models/validations/financial_validations.rb index e0e3f081e..5e7d92d2c 100644 --- a/app/models/validations/financial_validations.rb +++ b/app/models/validations/financial_validations.rb @@ -145,8 +145,9 @@ module Validations::FinancialValidations end def validate_rent_period(record) - if record.managing_organisation.present? && record.managing_organisation.rent_periods.present? && - record.period && !record.managing_organisation.rent_periods.include?(record.period) + return unless record.managing_organisation && record.period + + unless record.managing_organisation.rent_periods.include? record.period record.errors.add :period, :wrong_rent_period, message: I18n.t( "validations.financial.rent_period.invalid_for_org", org_name: record.managing_organisation.name, diff --git a/app/views/organisations/edit.html.erb b/app/views/organisations/edit.html.erb index 21297ec86..b0bd05bf6 100644 --- a/app/views/organisations/edit.html.erb +++ b/app/views/organisations/edit.html.erb @@ -12,26 +12,43 @@ <% if current_user.support? %> - <%= f.govuk_text_field :name, autocomplete: "name" %> + <%= f.govuk_text_field :name, autocomplete: "name", label: { size: "m" } %> <% end %> <%= f.govuk_text_field :address_line1, - label: { text: "Address line 1" }, + label: { text: "Address line 1", size: "m" }, autocomplete: "address-line1" %> <%= f.govuk_text_field :address_line2, - label: { text: "Address line 2" }, + label: { text: "Address line 2", size: "m" }, autocomplete: "address-line2" %> <%= f.govuk_text_field :postcode, + label: { size: "m" }, autocomplete: "postal-code", width: 10 %> <%= f.govuk_phone_field :phone, - label: { text: "Telephone number" }, + label: { text: "Telephone number", size: "m" }, autocomplete: "tel", width: 20 %> + <%= f.govuk_check_boxes_fieldset :rent_periods, + legend: { text: "What are the rent periods for the organisation?" }, + hint: { text: "It is not possible to deselect rent periods that are used in logs" } do %> + <% @rent_periods.map do |key, period| %> + <%= f.govuk_check_box :rent_periods, + key, + label: { text: period["value"] }, + checked: period[:checked], + disabled: @used_rent_periods.include?(key) %> + <% end %> + <% end %> + + <% @rent_periods.keys.each do |period_key| %> + <%= f.hidden_field :all_rent_periods, value: period_key, multiple: true %> + <% end %> + <%= f.govuk_submit "Save changes" %> diff --git a/app/views/organisations/new.html.erb b/app/views/organisations/new.html.erb index 5d1747ed7..20d4d2cc6 100644 --- a/app/views/organisations/new.html.erb +++ b/app/views/organisations/new.html.erb @@ -4,7 +4,7 @@ <%= govuk_back_link(href: :back) %> <% end %> -<%= form_for(@resource, as: :organisation, html: { method: :post }) do |f| %> +<%= form_for(@organisation, as: :organisation, html: { method: :post }) do |f| %>
To report a merge or update your organisation details, <%= govuk_link_to "contact the helpdesk", GlobalConstants::HELPDESK_URL %>.
<%= render partial: "organisations/merged_organisation_details" %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 941c12c52..63b159b32 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -33,6 +33,7 @@ en: service_name: "Submit social housing lettings and sales data (CORE)" feedback_form: "https://forms.office.com/Pages/ResponsePage.aspx?id=EGg0v32c3kOociSi7zmVqC4YDsCJ3llAvEZelBFBLUBURFVUTzFDTUJPQlM4M0laTE5DTlNFSjJBQi4u" organisation: + created: "%{organisation} was created" updated: "Organisation details updated" reactivated: "%{organisation} has been reactivated." deactivated: "%{organisation} has been deactivated." diff --git a/lib/tasks/create_organisation_rent_periods.rake b/lib/tasks/create_organisation_rent_periods.rake new file mode 100644 index 000000000..002d24513 --- /dev/null +++ b/lib/tasks/create_organisation_rent_periods.rake @@ -0,0 +1,11 @@ +desc "Create OrganisationRentPeriods for organisations that have none as they were previously assumed to have all" +task create_organisation_rent_periods: :environment do + org_ids_with_no_associated_rent_periods = Organisation.includes(:organisation_rent_periods).group(:id).count(:organisation_rent_periods).select { |_org_id, period_count| period_count.zero? }.keys + org_ids_with_no_associated_rent_periods.each do |organisation_id| + OrganisationRentPeriod.transaction do + (1..11).each do |rent_period| + OrganisationRentPeriod.create(organisation_id:, rent_period:) + end + end + end +end diff --git a/spec/factories/organisation.rb b/spec/factories/organisation.rb index c65533b3d..6a0aac85f 100644 --- a/spec/factories/organisation.rb +++ b/spec/factories/organisation.rb @@ -14,6 +14,18 @@ FactoryBot.define do with_dsa { true } end + transient do + skip_rent_period_creation { false } + end + + after(:build) do |organisation, evaluator| + unless evaluator.skip_rent_period_creation + (1..11).each do |rent_period| + organisation.organisation_rent_periods << build(:organisation_rent_period, organisation:, rent_period:) + end + end + end + after(:create) do |org, evaluator| if evaluator.with_dsa create( diff --git a/spec/features/form/page_routing_spec.rb b/spec/features/form/page_routing_spec.rb index ee2894198..8ee63de03 100644 --- a/spec/features/form/page_routing_spec.rb +++ b/spec/features/form/page_routing_spec.rb @@ -72,7 +72,7 @@ RSpec.describe "Form Page Routing" do end it "does not show question if the answer could be inferred" do - stub_request(:get, /api.postcodes.io/) + stub_request(:get, /api\.postcodes\.io/) .to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\", \"codes\":{\"admin_district\": \"E08000003\"}}}", headers: {}) visit("/lettings-logs/#{id}/property-postcode") diff --git a/spec/fixtures/files/sales_logs_csv_export_codes_23.csv b/spec/fixtures/files/sales_logs_csv_export_codes_23.csv index ad22b82c7..6bc3ae6a4 100644 --- a/spec/fixtures/files/sales_logs_csv_export_codes_23.csv +++ b/spec/fixtures/files/sales_logs_csv_export_codes_23.csv @@ -1,2 +1,2 @@ ID,STATUS,DUPLICATESET,CREATEDDATE,UPLOADDATE,FORM,COLLECTIONYEAR,CREATIONMETHOD,DATAPROTECT,OWNINGORGNAME,MANINGORGNAME,CREATEDBY,USERNAME,DAY,MONTH,YEAR,PURCHID,OWNERSHIP,TYPE,OTHTYPE,COMPANY,LIVEINBUYER,JOINT,JOINTMORE,BEDS,PROPTYPE,BUILTYPE,UPRN,UPRNCONFIRMED,ADDRESS1,ADDRESS2,TOWNCITY,COUNTY,PCODE1,PCODE2,LA,LANAME,WCHAIR,NOINT,PRIVACYNOTICE,AGE1,SEX1,ETHNICGROUP1,ETHNIC,NATIONAL,ECSTAT1,LIVEINBUYER1,RELAT2,AGE2,SEX2,ETHNICGROUP2,ETHNIC2,NATIONAL2,ECSTAT2,LIVEINBUYER2,HHTYPE,RELAT3,AGE3,SEX3,ECSTAT3,RELAT4,AGE4,SEX4,ECSTAT4,RELAT5,AGE5,SEX5,ECSTAT5,RELAT6,AGE6,SEX6,ECSTAT6,PREVTEN,PPCODENK,PPOSTC1,PPOSTC2,PREVIOUSLAKNOWN,PREVLOC,PREVLOCNAME,PREGYRHA,PREGOTHER,PREGLA,PREGGHB,PREGBLANK,BUY2LIVING,PREVTEN2,HHREGRES,HHREGRESSTILL,ARMEDFORCESSPOUSE,DISABLED,WHEEL,INC1NK,INCOME1,INC1MORT,INC2NK,INCOME2,INC2MORT,HB,SAVINGSNK,SAVINGS,PREVOWN,PREVSHARED,PROPLEN,STAIRCASE,STAIRBOUGHT,STAIROWNED,STAIRCASETOSALE,RESALE,EXDAY,EXMONTH,EXYEAR,HODAY,HOMONTH,HOYEAR,LANOMAGR,SOCTEN,FROMBEDS,FROMPROP,SOCPREVTEN,VALUE,VALUE_VALUE_CHECK,EQUITY,MORTGAGEUSED,MORTGAGE,MORTGAGELENDER,MORTGAGELENDEROTHER,MORTLEN1,EXTRABOR,DEPOSIT,CASHDIS,MRENT,HASMSCHARGE,MSCHARGE,MSCHARGE_VALUE_CHECK,DISCOUNT,GRANT -,completed,,2023-12-08T00:00:00+00:00,2024-01-01T00:00:00+00:00,,2023,1,false,DLUHC,DLUHC,billyboy@eyeklaud.com,billyboy@eyeklaud.com,8,12,2023,,2,8,,,,1,1,2,1,1,,,Address line 1,,Town or city,,SW1A,1AA,E09000003,Barnet,1,2,1,30,X,17,17,18,1,1,P,35,X,17,,13,1,1,3,C,14,X,,X,-9,X,3,R,-9,R,10,,,,,1,1,,,0,,,1,1,1,1,,3,,1,4,5,1,1,0,10000,1,0,10000,1,4,1,,1,2,10,,,,,,,,,,,,,,,,,110000.0,,,1,20000.0,5,,10,1,80000.0,,,1,100.0,,,10000.0 +,completed,,2023-12-08T00:00:00+00:00,2024-01-01T00:00:00+00:00,,2023,1,false,DLUHC,DLUHC,billyboy@eyeklaud.com,billyboy@eyeklaud.com,8,12,2023,,2,8,,,,1,1,2,1,1,,,Address line 1,,Town or city,,SW1A,1AA,E09000033,Westminster,1,2,1,30,X,17,17,18,1,1,P,35,X,17,,13,1,1,3,C,14,X,,X,-9,X,3,R,-9,R,10,,,,,1,1,,,0,,,1,1,1,1,,3,,1,4,5,1,1,0,10000,1,0,10000,1,4,1,,1,2,10,,,,,,,,,,,,,,,,,110000.0,,,1,20000.0,5,,10,1,80000.0,,,1,100.0,,,10000.0 diff --git a/spec/fixtures/files/sales_logs_csv_export_codes_24.csv b/spec/fixtures/files/sales_logs_csv_export_codes_24.csv index f7c86872d..651c881d3 100644 --- a/spec/fixtures/files/sales_logs_csv_export_codes_24.csv +++ b/spec/fixtures/files/sales_logs_csv_export_codes_24.csv @@ -1,2 +1,2 @@ ID,STATUS,DUPLICATESET,CREATEDDATE,UPLOADDATE,COLLECTIONYEAR,CREATIONMETHOD,BULKUPLOADID,DATAPROTECT,OWNINGORGNAME,MANINGORGNAME,CREATEDBY,USERNAME,DAY,MONTH,YEAR,PURCHID,OWNERSHIP,TYPE,OTHTYPE,COMPANY,LIVEINBUYER,JOINT,JOINTMORE,NOINT,PRIVACYNOTICE,UPRN,ADDRESS1,ADDRESS2,TOWNCITY,COUNTY,POSTCODE,ISLAINFERRED,LANAME,LA,UPRNSELECTED,ADDRESS_SEARCH_VALUE_CHECK,ADDRESS1INPUT,POSTCODEINPUT,BULKADDRESS1,BULKADDRESS2,BULKTOWNCITY,BULKCOUNTY,BULKPOSTCODE,BULKLA,BEDS,PROPTYPE,BUILTYPE,WCHAIR,AGE1,SEX1,ETHNICGROUP1,ETHNIC,NATIONALITYALL1,ECSTAT1,LIVEINBUYER1,RELAT2,AGE2,SEX2,ETHNICGROUP2,ETHNIC2,NATIONALITYALL2,ECSTAT2,LIVEINBUYER2,HHTYPE,RELAT3,AGE3,SEX3,ECSTAT3,RELAT4,AGE4,SEX4,ECSTAT4,RELAT5,AGE5,SEX5,ECSTAT5,RELAT6,AGE6,SEX6,ECSTAT6,PREVTEN,PPCODENK,PPOSTC1,PPOSTC2,PREVIOUSLAKNOWN,PREVLOC,PREVLOCNAME,PREGYRHA,PREGOTHER,PREGLA,PREGGHB,PREGBLANK,BUY2LIVING,PREVTEN2,HHREGRES,HHREGRESSTILL,ARMEDFORCESSPOUSE,DISABLED,WHEEL,INC1NK,INCOME1,INC1MORT,INC2NK,INCOME2,INC2MORT,HB,SAVINGSNK,SAVINGS,PREVOWN,PREVSHARED,PROPLEN,STAIRCASE,STAIRBOUGHT,STAIROWNED,STAIRCASETOSALE,RESALE,EXDAY,EXMONTH,EXYEAR,HODAY,HOMONTH,HOYEAR,LANOMAGR,SOCTEN,FROMBEDS,FROMPROP,SOCPREVTEN,VALUE,VALUE_VALUE_CHECK,EQUITY,MORTGAGEUSED,MORTGAGE,MORTGAGELENDER,MORTGAGELENDEROTHER,MORTLEN1,EXTRABOR,DEPOSIT,CASHDIS,MRENT,HASMSCHARGE,MSCHARGE,MSCHARGE_VALUE_CHECK,DISCOUNT,GRANT -,in_progress,,2024-05-01T00:00:00+01:00,2024-05-01T00:00:00+01:00,2024,1,,false,DLUHC,DLUHC,billyboy@eyeklaud.com,billyboy@eyeklaud.com,1,5,2024,,2,8,,,,1,1,2,1,,Address line 1,,Town or city,,SW1A 1AA,false,Barnet,E09000003,,,,,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,2,1,1,1,30,X,17,17,,1,1,P,35,X,17,,,1,1,3,C,14,X,9,X,-9,X,3,R,-9,R,10,,,,,1,0,SW1A,1AA,1,E09000003,Barnet,1,1,1,1,,3,,1,4,5,1,1,0,10000,1,0,10000,1,4,1,,1,2,10,,,,,,,,,,,,,,,,,110000.0,,,1,20000.0,5,,10,1,80000.0,,,1,100.0,,,10000.0 +,in_progress,,2024-05-01T00:00:00+01:00,2024-05-01T00:00:00+01:00,2024,1,,false,DLUHC,DLUHC,billyboy@eyeklaud.com,billyboy@eyeklaud.com,1,5,2024,,2,8,,,,1,1,2,1,,Address line 1,,Town or city,,SW1A 1AA,true,Westminster,E09000033,,,,,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,2,1,1,1,30,X,17,17,,1,1,P,35,X,17,,,1,1,3,C,14,X,9,X,-9,X,3,R,-9,R,10,,,,,1,0,SW1A,1AA,1,E09000033,Westminster,1,1,1,1,,3,,1,4,5,1,1,0,10000,1,0,10000,1,4,1,,1,2,10,,,,,,,,,,,,,,,,,110000.0,,,1,20000.0,5,,10,1,80000.0,,,1,100.0,,,10000.0 diff --git a/spec/fixtures/files/sales_logs_csv_export_labels_23.csv b/spec/fixtures/files/sales_logs_csv_export_labels_23.csv index 04e3cafc1..bd3736deb 100644 --- a/spec/fixtures/files/sales_logs_csv_export_labels_23.csv +++ b/spec/fixtures/files/sales_logs_csv_export_labels_23.csv @@ -1,2 +1,2 @@ ID,STATUS,DUPLICATESET,CREATEDDATE,UPLOADDATE,FORM,COLLECTIONYEAR,CREATIONMETHOD,DATAPROTECT,OWNINGORGNAME,MANINGORGNAME,CREATEDBY,USERNAME,DAY,MONTH,YEAR,PURCHID,OWNERSHIP,TYPE,OTHTYPE,COMPANY,LIVEINBUYER,JOINT,JOINTMORE,BEDS,PROPTYPE,BUILTYPE,UPRN,UPRNCONFIRMED,ADDRESS1,ADDRESS2,TOWNCITY,COUNTY,PCODE1,PCODE2,LA,LANAME,WCHAIR,NOINT,PRIVACYNOTICE,AGE1,SEX1,ETHNICGROUP1,ETHNIC,NATIONAL,ECSTAT1,LIVEINBUYER1,RELAT2,AGE2,SEX2,ETHNICGROUP2,ETHNIC2,NATIONAL2,ECSTAT2,LIVEINBUYER2,HHTYPE,RELAT3,AGE3,SEX3,ECSTAT3,RELAT4,AGE4,SEX4,ECSTAT4,RELAT5,AGE5,SEX5,ECSTAT5,RELAT6,AGE6,SEX6,ECSTAT6,PREVTEN,PPCODENK,PPOSTC1,PPOSTC2,PREVIOUSLAKNOWN,PREVLOC,PREVLOCNAME,PREGYRHA,PREGOTHER,PREGLA,PREGGHB,PREGBLANK,BUY2LIVING,PREVTEN2,HHREGRES,HHREGRESSTILL,ARMEDFORCESSPOUSE,DISABLED,WHEEL,INC1NK,INCOME1,INC1MORT,INC2NK,INCOME2,INC2MORT,HB,SAVINGSNK,SAVINGS,PREVOWN,PREVSHARED,PROPLEN,STAIRCASE,STAIRBOUGHT,STAIROWNED,STAIRCASETOSALE,RESALE,EXDAY,EXMONTH,EXYEAR,HODAY,HOMONTH,HOYEAR,LANOMAGR,SOCTEN,FROMBEDS,FROMPROP,SOCPREVTEN,VALUE,VALUE_VALUE_CHECK,EQUITY,MORTGAGEUSED,MORTGAGE,MORTGAGELENDER,MORTGAGELENDEROTHER,MORTLEN1,EXTRABOR,DEPOSIT,CASHDIS,MRENT,HASMSCHARGE,MSCHARGE,MSCHARGE_VALUE_CHECK,DISCOUNT,GRANT -,completed,,2023-12-08T00:00:00+00:00,2024-01-01T00:00:00+00:00,,2023,single log,false,DLUHC,DLUHC,billyboy@eyeklaud.com,billyboy@eyeklaud.com,8,12,2023,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,2,Flat or maisonette,Purpose built,,,Address line 1,,Town or city,,SW1A,1AA,E09000003,Barnet,Yes,Yes,1,30,Non-binary,Buyer prefers not to say,17,United Kingdom,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,Buyer prefers not to say,,Buyer prefers not to say,Full-time - 30 hours or more,Yes,3,Child,14,Non-binary,,Other,Not known,Non-binary,In government training into work,Prefers not to say,Not known,Prefers not to say,Prefers not to say,,,,,Local authority tenant,No,,,No,,,1,1,1,1,,Don't know,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,Don’t know ,No,,Yes,No,10,,,,,,,,,,,,,,,,,110000.0,,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,,10000.0 +,completed,,2023-12-08T00:00:00+00:00,2024-01-01T00:00:00+00:00,,2023,single log,false,DLUHC,DLUHC,billyboy@eyeklaud.com,billyboy@eyeklaud.com,8,12,2023,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,2,Flat or maisonette,Purpose built,,,Address line 1,,Town or city,,SW1A,1AA,E09000033,Westminster,Yes,Yes,1,30,Non-binary,Buyer prefers not to say,17,United Kingdom,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,Buyer prefers not to say,,Buyer prefers not to say,Full-time - 30 hours or more,Yes,3,Child,14,Non-binary,,Other,Not known,Non-binary,In government training into work,Prefers not to say,Not known,Prefers not to say,Prefers not to say,,,,,Local authority tenant,No,,,No,,,1,1,1,1,,Don't know,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,Don’t know ,No,,Yes,No,10,,,,,,,,,,,,,,,,,110000.0,,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,,10000.0 diff --git a/spec/fixtures/files/sales_logs_csv_export_labels_24.csv b/spec/fixtures/files/sales_logs_csv_export_labels_24.csv index 4feac3c6e..77e302899 100644 --- a/spec/fixtures/files/sales_logs_csv_export_labels_24.csv +++ b/spec/fixtures/files/sales_logs_csv_export_labels_24.csv @@ -1,2 +1,2 @@ ID,STATUS,DUPLICATESET,CREATEDDATE,UPLOADDATE,COLLECTIONYEAR,CREATIONMETHOD,BULKUPLOADID,DATAPROTECT,OWNINGORGNAME,MANINGORGNAME,CREATEDBY,USERNAME,DAY,MONTH,YEAR,PURCHID,OWNERSHIP,TYPE,OTHTYPE,COMPANY,LIVEINBUYER,JOINT,JOINTMORE,NOINT,PRIVACYNOTICE,UPRN,ADDRESS1,ADDRESS2,TOWNCITY,COUNTY,POSTCODE,ISLAINFERRED,LANAME,LA,UPRNSELECTED,ADDRESS_SEARCH_VALUE_CHECK,ADDRESS1INPUT,POSTCODEINPUT,BULKADDRESS1,BULKADDRESS2,BULKTOWNCITY,BULKCOUNTY,BULKPOSTCODE,BULKLA,BEDS,PROPTYPE,BUILTYPE,WCHAIR,AGE1,SEX1,ETHNICGROUP1,ETHNIC,NATIONALITYALL1,ECSTAT1,LIVEINBUYER1,RELAT2,AGE2,SEX2,ETHNICGROUP2,ETHNIC2,NATIONALITYALL2,ECSTAT2,LIVEINBUYER2,HHTYPE,RELAT3,AGE3,SEX3,ECSTAT3,RELAT4,AGE4,SEX4,ECSTAT4,RELAT5,AGE5,SEX5,ECSTAT5,RELAT6,AGE6,SEX6,ECSTAT6,PREVTEN,PPCODENK,PPOSTC1,PPOSTC2,PREVIOUSLAKNOWN,PREVLOC,PREVLOCNAME,PREGYRHA,PREGOTHER,PREGLA,PREGGHB,PREGBLANK,BUY2LIVING,PREVTEN2,HHREGRES,HHREGRESSTILL,ARMEDFORCESSPOUSE,DISABLED,WHEEL,INC1NK,INCOME1,INC1MORT,INC2NK,INCOME2,INC2MORT,HB,SAVINGSNK,SAVINGS,PREVOWN,PREVSHARED,PROPLEN,STAIRCASE,STAIRBOUGHT,STAIROWNED,STAIRCASETOSALE,RESALE,EXDAY,EXMONTH,EXYEAR,HODAY,HOMONTH,HOYEAR,LANOMAGR,SOCTEN,FROMBEDS,FROMPROP,SOCPREVTEN,VALUE,VALUE_VALUE_CHECK,EQUITY,MORTGAGEUSED,MORTGAGE,MORTGAGELENDER,MORTGAGELENDEROTHER,MORTLEN1,EXTRABOR,DEPOSIT,CASHDIS,MRENT,HASMSCHARGE,MSCHARGE,MSCHARGE_VALUE_CHECK,DISCOUNT,GRANT -,in_progress,,2024-05-01T00:00:00+01:00,2024-05-01T00:00:00+01:00,2024,single log,,false,DLUHC,DLUHC,billyboy@eyeklaud.com,billyboy@eyeklaud.com,1,5,2024,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,Yes,1,,Address line 1,,Town or city,,SW1A 1AA,No,Barnet,E09000003,,,,,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,2,Flat or maisonette,Purpose built,Yes,30,Non-binary,Buyer prefers not to say,17,Australia,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,Buyer prefers not to say,,,Full-time - 30 hours or more,Yes,3,Child,14,Non-binary,Child under 16,Other,Not known,Non-binary,In government training into work,Prefers not to say,Not known,Prefers not to say,Prefers not to say,,,,,Local authority tenant,Yes,SW1A,1AA,Yes,E09000003,Barnet,1,1,1,1,,Don't know,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,Don’t know ,No,,Yes,No,10,,,,,,,,,,,,,,,,,110000.0,,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,,10000.0 +,in_progress,,2024-05-01T00:00:00+01:00,2024-05-01T00:00:00+01:00,2024,single log,,false,DLUHC,DLUHC,billyboy@eyeklaud.com,billyboy@eyeklaud.com,1,5,2024,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,Yes,1,,Address line 1,,Town or city,,SW1A 1AA,Yes,Westminster,E09000033,,,,,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,2,Flat or maisonette,Purpose built,Yes,30,Non-binary,Buyer prefers not to say,17,Australia,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,Buyer prefers not to say,,,Full-time - 30 hours or more,Yes,3,Child,14,Non-binary,Child under 16,Other,Not known,Non-binary,In government training into work,Prefers not to say,Not known,Prefers not to say,Prefers not to say,,,,,Local authority tenant,Yes,SW1A,1AA,Yes,E09000033,Westminster,1,1,1,1,,Don't know,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,Don’t know ,No,,Yes,No,10,,,,,,,,,,,,,,,,,110000.0,,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,,10000.0 diff --git a/spec/fixtures/files/sales_logs_csv_export_non_support_labels_24.csv b/spec/fixtures/files/sales_logs_csv_export_non_support_labels_24.csv index 2ca4deac7..f25be1133 100644 --- a/spec/fixtures/files/sales_logs_csv_export_non_support_labels_24.csv +++ b/spec/fixtures/files/sales_logs_csv_export_non_support_labels_24.csv @@ -1,2 +1,2 @@ id,status,duplicate_set_id,created_at,updated_at,collection_start_year,creation_method,bulk_upload_id,is_dpo,owning_organisation_name,managing_organisation_name,assigned_to,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,noint,privacynotice,uprn,uprn_confirmed,address_line1_input,postcode_full_input,uprn_selection,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la,la_label,beds,proptype,builtype,wchair,age1,sex1,ethnic_group,ethnic,nationality_all,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationality_all_buyer2,ecstat2,buy2livein,hholdcount,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,prevten,ppcodenk,ppostc1,ppostc2,previous_la_known,prevloc,prevloc_label,pregyrha,pregother,pregla,pregghb,pregblank,buy2living,prevtenbuy2,hhregres,hhregresstill,armedforcesspouse,disabled,wheel,income1nk,income1,inc1mort,income2nk,income2,inc2mort,hb,savingsnk,savings,prevown,prevshared,proplen,staircase,stairbought,stairowned,staircasesale,resale,exday,exmonth,exyear,hoday,homonth,hoyear,lanomagr,soctenant,frombeds,fromprop,socprevten,value,equity,mortgageused,mortgage,mortgagelender,mortgagelenderother,mortlen,extrabor,deposit,cashdis,mrent,has_mscharge,mscharge,discount,grant -,in_progress,,2024-05-01T00:00:00+01:00,2024-05-01T00:00:00+01:00,2024,single log,,false,DLUHC,DLUHC,billyboy@eyeklaud.com,1,5,2024,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,Yes,1,,,,,,Address line 1,,Town or city,,SW1A,1AA,E09000003,Barnet,2,Flat or maisonette,Purpose built,Yes,30,Non-binary,Buyer prefers not to say,17,Australia,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,Buyer prefers not to say,,,Full-time - 30 hours or more,Yes,3,Child,14,Non-binary,Child under 16,Other,Not known,Non-binary,In government training into work,Prefers not to say,Not known,Prefers not to say,Prefers not to say,,,,,Local authority tenant,Yes,SW1A,1AA,Yes,E09000003,Barnet,1,1,1,1,,Don't know,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,Don’t know ,No,,Yes,No,10,,,,,,,,,,,,,,,,,110000.0,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,10000.0 +,in_progress,,2024-05-01T00:00:00+01:00,2024-05-01T00:00:00+01:00,2024,single log,,false,DLUHC,DLUHC,billyboy@eyeklaud.com,1,5,2024,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,Yes,1,,,,,,Address line 1,,Town or city,,SW1A,1AA,E09000033,Westminster,2,Flat or maisonette,Purpose built,Yes,30,Non-binary,Buyer prefers not to say,17,Australia,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,Buyer prefers not to say,,,Full-time - 30 hours or more,Yes,3,Child,14,Non-binary,Child under 16,Other,Not known,Non-binary,In government training into work,Prefers not to say,Not known,Prefers not to say,Prefers not to say,,,,,Local authority tenant,Yes,SW1A,1AA,Yes,E09000033,Westminster,1,1,1,1,,Don't know,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,Don’t know ,No,,Yes,No,10,,,,,,,,,,,,,,,,,110000.0,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,10000.0 diff --git a/spec/helpers/organisations_helper_spec.rb b/spec/helpers/organisations_helper_spec.rb index f8afb3e04..bdd774b18 100644 --- a/spec/helpers/organisations_helper_spec.rb +++ b/spec/helpers/organisations_helper_spec.rb @@ -3,21 +3,57 @@ require "rails_helper" RSpec.describe OrganisationsHelper do include TagHelper describe "display_organisation_attributes" do - let(:organisation) { create(:organisation) } + let(:organisation) { create(:organisation, skip_rent_period_creation: true) } - it "does not include data protection agreement" do + it "has the correct values" do expect(display_organisation_attributes(organisation)).to eq( [{ editable: false, name: "Organisation ID", value: "ORG#{organisation.id}" }, { editable: true, name: "Address", value: "2 Marsham Street\nLondon\nSW1P 4DF" }, { editable: true, name: "Telephone number", value: nil }, - { editable: false, name: "Type of provider", value: "Local authority" }, { editable: false, name: "Registration number", value: "1234" }, - { editable: false, format: :bullet, name: "Rent periods", value: %w[All] }, + { editable: false, name: "Type of provider", value: "Local authority" }, { editable: false, name: "Owns housing stock", value: "Yes" }, + { editable: true, format: :bullet, name: "Rent periods", value: [] }, + { name: "Data Sharing Agreement" }, { editable: false, name: "Status", value: status_tag(organisation.status) }], ) end end + + describe "rent_periods_with_checked_attr" do + let(:fake_rent_periods) do + { + "1" => { "value" => "Every minute" }, + "2" => { "value" => "Every decade" }, + } + end + + before do + allow(RentPeriod).to receive(:rent_period_mappings).and_return fake_rent_periods + end + + it "returns rent_period_mappings" do + actual = rent_periods_with_checked_attr + expect(actual.keys).to eq RentPeriod.rent_period_mappings.keys + end + + context "when checked_periods is nil" do + it "returns all rent periods with checked true" do + actual = rent_periods_with_checked_attr + checked_attrs = actual.values.map { |p| p[:checked] } + expect(checked_attrs).to all be true + end + end + + context "when checked_periods is not nil" do + it "returns the rent_periods with the correct values checked" do + checked_rent_period = "1" + actual = rent_periods_with_checked_attr(checked_periods: [checked_rent_period]) + expect(actual[checked_rent_period][:checked]).to be true + expect(actual["2"][:checked]).to be_falsey + end + end + end end diff --git a/spec/models/lettings_log_derived_fields_spec.rb b/spec/models/lettings_log_derived_fields_spec.rb new file mode 100644 index 000000000..8b7783d36 --- /dev/null +++ b/spec/models/lettings_log_derived_fields_spec.rb @@ -0,0 +1,1144 @@ +require "rails_helper" +require "shared/shared_examples_for_derived_fields" + +RSpec.describe LettingsLog, type: :model do + let(:organisation) { build(:organisation, name: "derived fields org", skip_rent_period_creation: true) } + let(:user) { build(:user, organisation:) } + let(:log) { build(:lettings_log, :startdate_today, assigned_to: user) } + + include_examples "shared examples for derived fields", :lettings_log + + it "correctly derives incref from net_income_known" do + log.net_income_known = 0 + expect { log.set_derived_fields! }.to change(log, :incref).to 0 + + log.net_income_known = 1 + expect { log.set_derived_fields! }.to change(log, :incref).to 2 + + log.net_income_known = 2 + expect { log.set_derived_fields! }.to change(log, :incref).to 1 + end + + it "derives shortfall_known when tshortfall is set" do + log.tshortfall = 10 + + expect { log.set_derived_fields! }.to change(log, :tshortfall_known).to 0 + end + + describe "deriving has_benefits" do + it "correctly derives when the household receives benefits" do + benefits_codes = [1, 6, 8, 7] + log.hb = benefits_codes.sample + + log.set_derived_fields! + + expect(log.has_benefits).to be 1 + end + + it "correctly derives when the household does not receive benefits" do + no_benefits_codes = [9, 3, 10, 4] + log.hb = no_benefits_codes.sample + + log.set_derived_fields! + + expect(log.has_benefits).to be 0 + end + end + + describe "deriving vacant days" do + it "correctly derives vacdays from startdate and mrcdate" do + day_count = 8 + log.startdate = Time.zone.today + log.mrcdate = Time.zone.today - day_count.days + + log.set_derived_fields! + + expect(log.vacdays).to be day_count + end + + it "correctly derives vacdays from startdate and voiddate if mrcdate is nil" do + day_count = 3 + log.startdate = Time.zone.today + log.voiddate = Time.zone.today - day_count.days + log.mrcdate = nil + + log.set_derived_fields! + + expect(log.vacdays).to be day_count + end + + it "does not derive vacdays if voiddate and mrcdate are blank" do + log.startdate = Time.zone.today + log.voiddate = nil + log.mrcdate = nil + + log.set_derived_fields! + + expect(log.vacdays).to be nil + end + + it "does not derive vacdays if startdate is blank" do + log.startdate = nil + log.voiddate = Time.zone.today + log.mrcdate = Time.zone.today + + log.set_derived_fields! + + expect(log.vacdays).to be nil + end + end + + describe "deriving household member fields" do + before do + log.assign_attributes( + relat2: "X", + relat3: "C", + relat4: "X", + relat5: "C", + relat7: "C", + relat8: "X", + age1: 22, + age2: 16, + age4: 60, + age6: 88, + age7: 14, + age8: 42, + ) + + log.set_derived_fields! + end + + it "correctly derives totchild" do + expect(log.totchild).to eq 3 + end + + it "correctly derives totelder" do + expect(log.totelder).to eq 2 + end + + it "correctly derives totadult" do + expect(log.totadult).to eq 3 + end + + it "correctly derives economic status for tenants under 16" do + expect(log.ecstat7).to eq 9 + end + end + + describe "deriving lettype" do + context "when the owning organisation is a PRP" do + before do + log.owning_organisation.provider_type = "PRP" + end + + [ + { + context: "when the rent type is intermediate rent and supported housing", + rent_type: 4, + needstype: 2, + expected_lettype: 10, + }, + { + context: "when the rent type is intermediate rent and general needs housing", + rent_type: 4, + needstype: 1, + expected_lettype: 9, + }, + { + context: "when the rent type is affordable rent and supported housing", + rent_type: 2, + needstype: 2, + expected_lettype: 6, + }, + { + context: "when the rent type is affordable rent and general needs housing", + rent_type: 2, + needstype: 1, + expected_lettype: 5, + }, + { + context: "when the rent type is social rent and supported housing", + rent_type: 0, + needstype: 2, + expected_lettype: 2, + }, + { + context: "when the rent type is social rent and general needs housing", + rent_type: 0, + needstype: 1, + expected_lettype: 1, + }, + ].each do |test_case| + context test_case[:context] do + it "correctly derives lettype" do + log.assign_attributes( + rent_type: test_case[:rent_type], + needstype: test_case[:needstype], + ) + expect { log.set_derived_fields! }.to change(log, :lettype).to test_case[:expected_lettype] + end + end + end + end + + context "when the owning organisation is an LA" do + before do + log.owning_organisation.provider_type = "LA" + end + + [ + { + context: "when the rent type is intermediate rent and supported housing", + rent_type: 4, + needstype: 2, + expected_lettype: 12, + }, + { + context: "when the rent type is intermediate rent and general needs housing", + rent_type: 4, + needstype: 1, + expected_lettype: 11, + }, + { + context: "when the rent type is affordable rent and supported housing", + rent_type: 2, + needstype: 2, + expected_lettype: 8, + }, + { + context: "when the rent type is affordable rent and general needs housing", + rent_type: 2, + needstype: 1, + expected_lettype: 7, + }, + { + context: "when the rent type is social rent and supported housing", + rent_type: 0, + needstype: 2, + expected_lettype: 4, + }, + { + context: "when the rent type is social rent and general needs housing", + rent_type: 0, + needstype: 1, + expected_lettype: 3, + }, + ].each do |test_case| + context test_case[:context] do + it "correctly derives lettype" do + log.assign_attributes( + rent_type: test_case[:rent_type], + needstype: test_case[:needstype], + ) + expect { log.set_derived_fields! }.to change(log, :lettype).to test_case[:expected_lettype] + end + end + end + end + end + + describe "deriving newprop" do + it "updates newprop correctly when this is the first time the property has been let" do + first_time_let_codes = [15, 16, 17] + log.rsnvac = first_time_let_codes.sample + + log.set_derived_fields! + + expect(log.newprop).to eq 1 + end + + it "updates newprop correctly when this is not the first time the property has been let" do + not_first_time_let_codes = [14, 9, 13, 12, 8, 18, 20, 5, 19, 6, 10, 11, 21, 22] + log.rsnvac = not_first_time_let_codes.sample + + log.set_derived_fields! + + expect(log.newprop).to eq 2 + end + end + + describe "deriving charges based on rent period" do + context "when rent is paid bi-weekly" do + before do + log.period = 2 + end + + [ + { + test_title: "correctly derives weekly rent", + fields_to_set: { brent: 100 }, + expected_values: { wrent: 50.0 }, + }, + { + test_title: "correctly derives weekly service charge", + fields_to_set: { scharge: 70 }, + expected_values: { wscharge: 35.0 }, + }, + { + test_title: "correctly derives weekly personal service charge", + fields_to_set: { pscharge: 60 }, + expected_values: { wpschrge: 30.0 }, + }, + { + test_title: "correctly derives weekly support charge", + fields_to_set: { supcharg: 80 }, + expected_values: { wsupchrg: 40.0 }, + }, + { + test_title: "correctly derives weekly total shortfall", + fields_to_set: { hbrentshortfall: 1, tshortfall: 100, hb: 6 }, + expected_values: { wtshortfall: 50.0 }, + }, + { + test_title: "correctly clears weekly total shortfall if the tenant does not receive applicable benefits", + fields_to_set: { hbrentshortfall: 1, tshortfall: 100, hb: 9 }, + expected_values: { wtshortfall: nil }, + }, + { + test_title: "correctly derives floats and weekly total charge", + fields_to_set: { supcharg: 60.12, pscharge: 50.13, scharge: 60.98, brent: 60.97 }, + expected_values: { wsupchrg: 30.06, wpschrge: 25.06, wscharge: 30.49, wrent: 30.49, wtcharge: 116.1 }, + }, + { + test_title: "correctly derives weekly care home charge when the letting is supported housing", + fields_to_set: { needstype: 2, chcharge: 57.86 }, + expected_values: { wchchrg: 28.93 }, + }, + ].each do |test_case| + it test_case[:test_title] do + log.assign_attributes(test_case[:fields_to_set]) + log.set_derived_fields! + test_case[:expected_values].each do |field, expected_value| + expect(log[field]).to eq expected_value + end + end + end + end + + context "when rent is paid every 4 weeks" do + before do + log.period = 3 + end + + [ + { + test_title: "correctly derives weekly rent", + fields_to_set: { brent: 120 }, + expected_values: { wrent: 30.0 }, + }, + { + test_title: "correctly derives weekly service charge", + fields_to_set: { scharge: 120 }, + expected_values: { wscharge: 30.0 }, + }, + { + test_title: "correctly derives weekly personal service charge", + fields_to_set: { pscharge: 120 }, + expected_values: { wpschrge: 30.0 }, + }, + { + test_title: "correctly derives weekly support charge", + fields_to_set: { supcharg: 120 }, + expected_values: { wsupchrg: 30.0 }, + }, + { + test_title: "correctly derives weekly total shortfall", + fields_to_set: { hbrentshortfall: 1, tshortfall: 120, hb: 6 }, + expected_values: { wtshortfall: 30.0 }, + }, + { + test_title: "correctly clears weekly total shortfall if the tenant does not receive applicable benefits", + fields_to_set: { hbrentshortfall: 1, tshortfall: 100, hb: 9 }, + expected_values: { wtshortfall: nil }, + }, + { + test_title: "correctly derives floats and weekly total charge", + fields_to_set: { supcharg: 100.12, pscharge: 100.13, scharge: 100.98, brent: 100.97 }, + expected_values: { wsupchrg: 25.03, wpschrge: 25.03, wscharge: 25.24, wrent: 25.24, wtcharge: 100.55 }, + }, + { + test_title: "correctly derives weekly care home charge when the letting is supported housing", + fields_to_set: { needstype: 2, chcharge: 57.86 }, + expected_values: { wchchrg: 14.46 }, + }, + ].each do |test_case| + it test_case[:test_title] do + log.assign_attributes(test_case[:fields_to_set]) + log.set_derived_fields! + test_case[:expected_values].each do |field, expected_value| + expect(log[field]).to eq expected_value + end + end + end + end + + context "when rent is paid every calendar month" do + before do + log.period = 4 + end + + [ + { + test_title: "correctly derives weekly rent", + fields_to_set: { brent: 130 }, + expected_values: { wrent: 30.0 }, + }, + { + test_title: "correctly derives weekly service charge", + fields_to_set: { scharge: 130 }, + expected_values: { wscharge: 30.0 }, + }, + { + test_title: "correctly derives weekly personal service charge", + fields_to_set: { pscharge: 130 }, + expected_values: { wpschrge: 30.0 }, + }, + { + test_title: "correctly derives weekly support charge", + fields_to_set: { supcharg: 130 }, + expected_values: { wsupchrg: 30.0 }, + }, + { + test_title: "correctly derives weekly total shortfall", + fields_to_set: { hbrentshortfall: 1, tshortfall: 130, hb: 6 }, + expected_values: { wtshortfall: 30.0 }, + }, + { + test_title: "correctly clears weekly total shortfall if the tenant does not receive applicable benefits", + fields_to_set: { hbrentshortfall: 1, tshortfall: 100, hb: 9 }, + expected_values: { wtshortfall: nil }, + }, + { + test_title: "correctly derives floats and weekly total charge", + fields_to_set: { supcharg: 100.12, pscharge: 100.13, scharge: 100.98, brent: 100.97 }, + expected_values: { wsupchrg: 23.10, wpschrge: 23.11, wscharge: 23.30, wrent: 23.30, wtcharge: 92.82 }, + }, + { + test_title: "correctly derives weekly care home charge when the letting is supported housing", + fields_to_set: { needstype: 2, chcharge: 57.86 }, + expected_values: { wchchrg: 13.35 }, + }, + ].each do |test_case| + it test_case[:test_title] do + log.assign_attributes(test_case[:fields_to_set]) + log.set_derived_fields! + test_case[:expected_values].each do |field, expected_value| + expect(log[field]).to eq expected_value + end + end + end + end + + context "when rent is paid weekly for 50 weeks" do + before do + log.period = 5 + end + + [ + { + test_title: "correctly derives weekly rent", + fields_to_set: { brent: 130 }, + expected_values: { wrent: 125.0 }, + }, + { + test_title: "correctly derives weekly service charge", + fields_to_set: { scharge: 130 }, + expected_values: { wscharge: 125.0 }, + }, + { + test_title: "correctly derives weekly personal service charge", + fields_to_set: { pscharge: 130 }, + expected_values: { wpschrge: 125.0 }, + }, + { + test_title: "correctly derives weekly support charge", + fields_to_set: { supcharg: 130 }, + expected_values: { wsupchrg: 125.0 }, + }, + { + test_title: "correctly derives weekly total shortfall", + fields_to_set: { hbrentshortfall: 1, tshortfall: 130, hb: 6 }, + expected_values: { wtshortfall: 125.0 }, + }, + { + test_title: "correctly clears weekly total shortfall if the tenant does not receive applicable benefits", + fields_to_set: { hbrentshortfall: 1, tshortfall: 100, hb: 9 }, + expected_values: { wtshortfall: nil }, + }, + { + test_title: "correctly derives floats and weekly total charge", + fields_to_set: { supcharg: 20.12, pscharge: 20.13, scharge: 20.98, brent: 100.97 }, + expected_values: { wsupchrg: 19.35, wpschrge: 19.36, wscharge: 20.17, wrent: 97.09, wtcharge: 155.96 }, + }, + { + test_title: "correctly derives weekly care home charge when the letting is supported housing", + fields_to_set: { needstype: 2, chcharge: 57.86 }, + expected_values: { wchchrg: 55.63 }, + }, + ].each do |test_case| + it test_case[:test_title] do + log.assign_attributes(test_case[:fields_to_set]) + log.set_derived_fields! + test_case[:expected_values].each do |field, expected_value| + expect(log[field]).to eq expected_value + end + end + end + end + + context "when rent is paid weekly for 49 weeks" do + before do + log.period = 6 + end + + [ + { + test_title: "correctly derives weekly rent", + fields_to_set: { brent: 130 }, + expected_values: { wrent: 122.5 }, + }, + { + test_title: "correctly derives weekly service charge", + fields_to_set: { scharge: 130 }, + expected_values: { wscharge: 122.5 }, + }, + { + test_title: "correctly derives weekly personal service charge", + fields_to_set: { pscharge: 130 }, + expected_values: { wpschrge: 122.5 }, + }, + { + test_title: "correctly derives weekly support charge", + fields_to_set: { supcharg: 130 }, + expected_values: { wsupchrg: 122.5 }, + }, + { + test_title: "correctly derives weekly total shortfall", + fields_to_set: { hbrentshortfall: 1, tshortfall: 130, hb: 6 }, + expected_values: { wtshortfall: 122.5 }, + }, + { + test_title: "correctly clears weekly total shortfall if the tenant does not receive applicable benefits", + fields_to_set: { hbrentshortfall: 1, tshortfall: 100, hb: 9 }, + expected_values: { wtshortfall: nil }, + }, + { + test_title: "correctly derives floats and weekly total charge", + fields_to_set: { supcharg: 30.12, pscharge: 30.13, scharge: 30.98, brent: 100.97 }, + expected_values: { wsupchrg: 28.38, wpschrge: 28.39, wscharge: 29.19, wrent: 95.14, wtcharge: 181.11 }, + }, + { + test_title: "correctly derives weekly care home charge when the letting is supported housing", + fields_to_set: { needstype: 2, chcharge: 57.86 }, + expected_values: { wchchrg: 54.52 }, + }, + ].each do |test_case| + it test_case[:test_title] do + log.assign_attributes(test_case[:fields_to_set]) + log.set_derived_fields! + test_case[:expected_values].each do |field, expected_value| + expect(log[field]).to eq expected_value + end + end + end + end + + context "when rent is paid weekly for 48 weeks" do + before do + log.period = 7 + end + + [ + { + test_title: "correctly derives weekly rent", + fields_to_set: { brent: 130 }, + expected_values: { wrent: 120 }, + }, + { + test_title: "correctly derives weekly service charge", + fields_to_set: { scharge: 130 }, + expected_values: { wscharge: 120 }, + }, + { + test_title: "correctly derives weekly personal service charge", + fields_to_set: { pscharge: 130 }, + expected_values: { wpschrge: 120 }, + }, + { + test_title: "correctly derives weekly support charge", + fields_to_set: { supcharg: 130 }, + expected_values: { wsupchrg: 120 }, + }, + { + test_title: "correctly derives weekly total shortfall", + fields_to_set: { hbrentshortfall: 1, tshortfall: 130, hb: 6 }, + expected_values: { wtshortfall: 120 }, + }, + { + test_title: "correctly clears weekly total shortfall if the tenant does not receive applicable benefits", + fields_to_set: { hbrentshortfall: 1, tshortfall: 100, hb: 9 }, + expected_values: { wtshortfall: nil }, + }, + { + test_title: "correctly derives floats and weekly total charge", + fields_to_set: { supcharg: 30.12, pscharge: 30.13, scharge: 30.98, brent: 100.97 }, + expected_values: { wsupchrg: 27.8, wpschrge: 27.81, wscharge: 28.6, wrent: 93.20, wtcharge: 177.42 }, + }, + { + test_title: "correctly derives weekly care home charge when the letting is supported housing", + fields_to_set: { needstype: 2, chcharge: 57.86 }, + expected_values: { wchchrg: 53.41 }, + }, + ].each do |test_case| + it test_case[:test_title] do + log.assign_attributes(test_case[:fields_to_set]) + log.set_derived_fields! + test_case[:expected_values].each do |field, expected_value| + expect(log[field]).to eq expected_value + end + end + end + end + + context "when rent is paid weekly for 47 weeks" do + before do + log.period = 8 + end + + [ + { + test_title: "correctly derives weekly rent", + fields_to_set: { brent: 130 }, + expected_values: { wrent: 117.5 }, + }, + { + test_title: "correctly derives weekly service charge", + fields_to_set: { scharge: 130 }, + expected_values: { wscharge: 117.5 }, + }, + { + test_title: "correctly derives weekly personal service charge", + fields_to_set: { pscharge: 130 }, + expected_values: { wpschrge: 117.5 }, + }, + { + test_title: "correctly derives weekly support charge", + fields_to_set: { supcharg: 130 }, + expected_values: { wsupchrg: 117.5 }, + }, + { + test_title: "correctly derives weekly total shortfall", + fields_to_set: { hbrentshortfall: 1, tshortfall: 130, hb: 6 }, + expected_values: { wtshortfall: 117.5 }, + }, + { + test_title: "correctly clears weekly total shortfall if the tenant does not receive applicable benefits", + fields_to_set: { hbrentshortfall: 1, tshortfall: 100, hb: 9 }, + expected_values: { wtshortfall: nil }, + }, + { + test_title: "correctly derives floats and weekly total charge", + fields_to_set: { supcharg: 30.12, pscharge: 30.13, scharge: 30.98, brent: 100.97 }, + expected_values: { wsupchrg: 27.22, wpschrge: 27.23, wscharge: 28, wrent: 91.26, wtcharge: 173.72 }, + }, + { + test_title: "correctly derives weekly care home charge when the letting is supported housing", + fields_to_set: { needstype: 2, chcharge: 57.86 }, + expected_values: { wchchrg: 52.3 }, + }, + ].each do |test_case| + it test_case[:test_title] do + log.assign_attributes(test_case[:fields_to_set]) + log.set_derived_fields! + test_case[:expected_values].each do |field, expected_value| + expect(log[field]).to eq expected_value + end + end + end + end + + context "when rent is paid weekly for 46 weeks" do + before do + log.period = 9 + end + + [ + { + test_title: "correctly derives weekly rent", + fields_to_set: { brent: 130 }, + expected_values: { wrent: 115 }, + }, + { + test_title: "correctly derives weekly service charge", + fields_to_set: { scharge: 130 }, + expected_values: { wscharge: 115 }, + }, + { + test_title: "correctly derives weekly personal service charge", + fields_to_set: { pscharge: 130 }, + expected_values: { wpschrge: 115 }, + }, + { + test_title: "correctly derives weekly support charge", + fields_to_set: { supcharg: 130 }, + expected_values: { wsupchrg: 115 }, + }, + { + test_title: "correctly derives weekly total shortfall", + fields_to_set: { hbrentshortfall: 1, tshortfall: 130, hb: 6 }, + expected_values: { wtshortfall: 115 }, + }, + { + test_title: "correctly clears weekly total shortfall if the tenant does not receive applicable benefits", + fields_to_set: { hbrentshortfall: 1, tshortfall: 100, hb: 9 }, + expected_values: { wtshortfall: nil }, + }, + { + test_title: "correctly derives floats and weekly total charge", + fields_to_set: { supcharg: 30.12, pscharge: 30.13, scharge: 30.98, brent: 100.97 }, + expected_values: { wsupchrg: 26.64, wpschrge: 26.65, wscharge: 27.41, wrent: 89.32, wtcharge: 170.02 }, + }, + { + test_title: "correctly derives weekly care home charge when the letting is supported housing", + fields_to_set: { needstype: 2, chcharge: 57.86 }, + expected_values: { wchchrg: 51.18 }, + }, + ].each do |test_case| + it test_case[:test_title] do + log.assign_attributes(test_case[:fields_to_set]) + log.set_derived_fields! + test_case[:expected_values].each do |field, expected_value| + expect(log[field]).to eq expected_value + end + end + end + end + + context "when rent is paid weekly for 52 weeks" do + before do + log.period = 1 + end + + [ + { + test_title: "correctly derives weekly rent", + fields_to_set: { brent: 130 }, + expected_values: { wrent: 130 }, + }, + { + test_title: "correctly derives weekly service charge", + fields_to_set: { scharge: 130 }, + expected_values: { wscharge: 130 }, + }, + { + test_title: "correctly derives weekly personal service charge", + fields_to_set: { pscharge: 130 }, + expected_values: { wpschrge: 130 }, + }, + { + test_title: "correctly derives weekly support charge", + fields_to_set: { supcharg: 130 }, + expected_values: { wsupchrg: 130 }, + }, + { + test_title: "correctly derives weekly total shortfall", + fields_to_set: { hbrentshortfall: 1, tshortfall: 130, hb: 6 }, + expected_values: { wtshortfall: 130 }, + }, + { + test_title: "correctly clears weekly total shortfall if the tenant does not receive applicable benefits", + fields_to_set: { hbrentshortfall: 1, tshortfall: 100, hb: 9 }, + expected_values: { wtshortfall: nil }, + }, + { + test_title: "correctly derives floats and weekly total charge", + fields_to_set: { supcharg: 30.12, pscharge: 25.13, scharge: 30.98, brent: 100.97 }, + expected_values: { wsupchrg: 30.12, wpschrge: 25.13, wscharge: 30.98, wrent: 100.97, wtcharge: 187.2 }, + }, + { + test_title: "correctly derives weekly care home charge when the letting is supported housing", + fields_to_set: { needstype: 2, chcharge: 57.86 }, + expected_values: { wchchrg: 57.86 }, + }, + ].each do |test_case| + it test_case[:test_title] do + log.assign_attributes(test_case[:fields_to_set]) + log.set_derived_fields! + test_case[:expected_values].each do |field, expected_value| + expect(log[field]).to eq expected_value + end + end + end + end + + context "when rent is paid weekly for 53 weeks" do + before do + log.period = 10 + end + + [ + { + test_title: "correctly derives weekly rent", + fields_to_set: { brent: 130 }, + expected_values: { wrent: 132.5 }, + }, + { + test_title: "correctly derives weekly service charge", + fields_to_set: { scharge: 130 }, + expected_values: { wscharge: 132.5 }, + }, + { + test_title: "correctly derives weekly personal service charge", + fields_to_set: { pscharge: 130 }, + expected_values: { wpschrge: 132.5 }, + }, + { + test_title: "correctly derives weekly support charge", + fields_to_set: { supcharg: 130 }, + expected_values: { wsupchrg: 132.5 }, + }, + { + test_title: "correctly derives weekly total shortfall", + fields_to_set: { hbrentshortfall: 1, tshortfall: 130, hb: 6 }, + expected_values: { wtshortfall: 132.5 }, + }, + { + test_title: "correctly clears weekly total shortfall if the tenant does not receive applicable benefits", + fields_to_set: { hbrentshortfall: 1, tshortfall: 100, hb: 9 }, + expected_values: { wtshortfall: nil }, + }, + { + test_title: "correctly derives floats and weekly total charge", + fields_to_set: { supcharg: 30.12, pscharge: 25.13, scharge: 30.98, brent: 100.97 }, + expected_values: { wsupchrg: 30.7, wpschrge: 25.61, wscharge: 31.58, wrent: 102.91, wtcharge: 190.8 }, + }, + { + test_title: "correctly derives weekly care home charge when the letting is supported housing", + fields_to_set: { needstype: 2, chcharge: 57.86 }, + expected_values: { wchchrg: 58.97 }, + }, + ].each do |test_case| + it test_case[:test_title] do + log.assign_attributes(test_case[:fields_to_set]) + log.set_derived_fields! + test_case[:expected_values].each do |field, expected_value| + expect(log[field]).to eq expected_value + end + end + end + end + end + + describe "deriving charges" do + describe "deriving the total charge" do + it "sums all the charges" do + brent = 5.77 + scharge = 10.01 + pscharge = 3 + supcharg = 12.2 + log.assign_attributes(brent:, scharge:, pscharge:, supcharg:) + + log.set_derived_fields! + + expect(log.tcharge).to eq(brent + scharge + pscharge + supcharg) + end + + it "takes nil values to be zero" do + brent = 5.77 + scharge = nil + pscharge = nil + supcharg = 12.2 + log.assign_attributes(brent:, scharge:, pscharge:, supcharg:) + + log.set_derived_fields! + + expect(log.tcharge).to eq(brent + supcharg) + end + end + + it "when any charge field is set all blank charge fields are set to 0, non-blank fields are left the same" do + log.set_derived_fields! + %i[brent scharge pscharge supcharg].each do |field| + expect(log[field]).to be nil + end + + brent_val = 111 + log.brent = brent_val + log.set_derived_fields! + %i[scharge pscharge supcharg].each do |field| + expect(log[field]).to eq 0 + end + + log.scharge = 22 + log.set_derived_fields! + expect(log.brent).to eq brent_val + end + end + + describe "deriving refused" do + it "derives refused when any age field is refused or details field is unknown" do + age_and_details_fields = %i[age1_known age2_known age3_known age4_known age5_known age6_known age7_known age8_known details_known_2 details_known_3 details_known_4 details_known_5 details_known_6 details_known_7 details_known_8] + + log[age_and_details_fields.sample] = 1 + log.set_derived_fields! + + expect(log.refused).to eq 1 + end + + it "derives refused when any sex or relationship field is refused" do + age_fields = %i[sex1 sex2 sex3 sex4 sex5 sex6 sex7 sex8 relat2 relat3 relat4 relat5 relat6 relat7 relat8] + + log[age_fields.sample] = "R" + log.set_derived_fields! + + expect(log.refused).to eq 1 + end + + it "derives refused when any economic status field is refused" do + economic_status_fields = %i[ecstat1 ecstat2 ecstat3 ecstat4 ecstat5 ecstat6 ecstat7 ecstat8] + + log[economic_status_fields.sample] = 10 + log.set_derived_fields! + + expect(log.refused).to eq 1 + end + end + + describe "deriving renttype from rent_type" do + it "when rent_type is Social Rent derives renttype as Social Rent" do + log.rent_type = 0 + expect { log.set_derived_fields! }.to change(log, :renttype).to 1 + end + + it "when rent_type is Affordable Rent derives renttype as Affordable Rent" do + log.rent_type = 1 + expect { log.set_derived_fields! }.to change(log, :renttype).to 2 + end + + it "when rent_type is London Affordable Rent derives renttype as Affordable Rent" do + log.rent_type = 2 + expect { log.set_derived_fields! }.to change(log, :renttype).to 2 + end + + it "when rent_type is Rent to Buy derives renttype as Intermediate Rent" do + log.rent_type = 3 + expect { log.set_derived_fields! }.to change(log, :renttype).to 3 + end + + it "when rent_type is London Living Rent derives renttype as Intermediate Rent" do + log.rent_type = 4 + expect { log.set_derived_fields! }.to change(log, :renttype).to 3 + end + + it "when rent_type is Other intermediate rent product derives renttype as Intermediate Rent" do + log.rent_type = 5 + expect { log.set_derived_fields! }.to change(log, :renttype).to 3 + end + end + + describe "variables dependent on whether a letting is a renewal" do + let(:organisation) { create(:organisation, skip_rent_period_creation: true) } + let(:user) { create(:user, organisation:) } + let(:startdate) { Time.zone.today } + let(:persisted_renewal_lettings_log) { create(:lettings_log, :setup_completed, startdate:, renewal: 1, assigned_to: user) } + + it "derives waityear offered referral first_time_property_let_as_social_housing rsnvac when renewal" do + log.renewal = 1 + expect { log.set_derived_fields! } + .to change(log, :waityear).to(2) + .and change(log, :offered).to(0) + .and change(log, :referral).to(1) + .and change(log, :first_time_property_let_as_social_housing).to(0) + .and change(log, :rsnvac).to(14) + end + + it "clears waityear offered referral first_time_property_let_as_social_housing rsnvac when not a renewal" do + expect { persisted_renewal_lettings_log.update!(renewal: 0) } + .to change(persisted_renewal_lettings_log, :waityear).from(2).to(nil) + .and change(persisted_renewal_lettings_log, :offered).from(0).to(nil) + .and change(persisted_renewal_lettings_log, :referral).from(1).to(nil) + .and change(persisted_renewal_lettings_log, :first_time_property_let_as_social_housing).from(0).to(nil) + .and change(persisted_renewal_lettings_log, :rsnvac).from(14).to(nil) + end + + describe "deriving voiddate from startdate" do + let(:startdate) { Time.zone.now } + + it "correctly derives voiddate if the letting is a renewal and clears it if it is not" do + log.assign_attributes(renewal: 1, startdate:) + + expect { log.set_derived_fields! }.to change(log, :voiddate).to startdate + end + + it "clears voiddate if the letting is no longer a renewal" do + expect { persisted_renewal_lettings_log.update!(renewal: 0) }.to change(persisted_renewal_lettings_log, :voiddate).from(startdate).to nil + end + end + + it "derives values for local authority and previous location if postcode is set and log is a renewal" do + expected_la = "E09000033" + postcode = "SW1A 1AA" + log.assign_attributes(postcode_known: 1, postcode_full: postcode, renewal: 1) + + expect { log.send :process_postcode_changes! }.to change(log, :la).to(expected_la) + expect { log.set_derived_fields! } + .to change(log, :ppostcode_full).to(postcode) + .and change(log, :ppcodenk).to(0) + .and change(log, :prevloc).to(expected_la) + end + + context "when the log is general needs" do + context "and the managing organisation is a private registered provider" do + before do + log.managing_organisation.provider_type = "PRP" + log.renewal = 1 + end + + it "correctly derives prevten" do + log.needstype = 1 + log.set_derived_fields! + + expect(log.prevten).to be 32 + end + + it "clears prevten if the log is marked as supported housing" do + log.needstype = 2 + log.set_derived_fields! + + expect(log.prevten).to be nil + end + + it "clears prevten if renewal is update to no" do + log.renewal = 0 + log.set_derived_fields! + + expect(log.prevten).to be nil + end + end + + context "and the managing organisation is a local authority" do + before do + log.managing_organisation.provider_type = "LA" + log.renewal = 1 + end + + it "correctly derives prevten if the log is general needs" do + log.needstype = 1 + log.set_derived_fields! + + expect(log.prevten).to be 30 + end + + it "clears prevten if the log is marked as supported housing" do + log.needstype = 2 + log.set_derived_fields! + + expect(log.prevten).to be nil + end + + it "clears prevten if renewal is update to no" do + log.renewal = 0 + log.set_derived_fields! + + expect(log.prevten).to be nil + end + end + end + + context "and updating rent_type" do + let(:irproduct_other) { nil } + let(:persisted_renewal_lettings_log) { create(:lettings_log, :setup_completed, assigned_to: user, rent_type:, irproduct_other:, renewal: 1) } + + context "when rent_type is Social Rent" do + let(:rent_type) { 0 } + let(:expected_unitletas) { 1 } + + it "derives the most recent let type as Social Rent basis if it is a renewal" do + log.assign_attributes(renewal: 1, rent_type:) + + expect { log.set_derived_fields! }.to change(log, :unitletas).to expected_unitletas + end + + it "clears the most recent let type if it is not a renewal" do + expect { persisted_renewal_lettings_log.update!(renewal: 0) }.to change(persisted_renewal_lettings_log, :unitletas).from(expected_unitletas).to nil + end + end + + context "when rent_type is Affordable Rent" do + let(:rent_type) { 1 } + let(:expected_unitletas) { 2 } + + it "derives the most recent let type as Affordable Rent basis if it is a renewal" do + log.assign_attributes(renewal: 1, rent_type:) + + expect { log.set_derived_fields! }.to change(log, :unitletas).to expected_unitletas + end + + it "clears the most recent let type if it is not a renewal" do + expect { persisted_renewal_lettings_log.update!(renewal: 0) }.to change(persisted_renewal_lettings_log, :unitletas).from(expected_unitletas).to nil + end + end + + context "when rent_type is London Affordable Rent" do + let(:rent_type) { 2 } + let(:expected_unitletas) { 5 } + + it "derives the most recent let type as London Affordable Rent basis if it is a renewal" do + log.assign_attributes(renewal: 1, rent_type:) + + expect { log.set_derived_fields! }.to change(log, :unitletas).to expected_unitletas + end + + it "clears the most recent let type if it is not a renewal" do + expect { persisted_renewal_lettings_log.update!(renewal: 0) }.to change(persisted_renewal_lettings_log, :unitletas).from(expected_unitletas).to nil + end + end + + context "when rent_type is Rent to Buy" do + let(:rent_type) { 3 } + let(:expected_unitletas) { 6 } + + it "derives the most recent let type as Rent to Buy basis if it is a renewal" do + log.assign_attributes(renewal: 1, rent_type:) + + expect { log.set_derived_fields! }.to change(log, :unitletas).to expected_unitletas + end + + it "clears the most recent let type if it is not a renewal" do + expect { persisted_renewal_lettings_log.update!(renewal: 0) }.to change(persisted_renewal_lettings_log, :unitletas).from(expected_unitletas).to nil + end + end + + context "when rent_type is London Living Rent" do + let(:rent_type) { 4 } + let(:expected_unitletas) { 7 } + + it "derives the most recent let type as London Living Rent basis if it is a renewal" do + log.assign_attributes(renewal: 1, rent_type:) + + expect { log.set_derived_fields! }.to change(log, :unitletas).to expected_unitletas + end + + it "clears the most recent let type if it is not a renewal" do + expect { persisted_renewal_lettings_log.update!(renewal: 0) }.to change(persisted_renewal_lettings_log, :unitletas).from(expected_unitletas).to nil + end + end + + context "when rent_type is Other intermediate rent product" do + let(:rent_type) { 5 } + let(:irproduct_other) { "Rent first" } + let(:expected_unitletas) { 8 } + + it "derives the most recent let type as London Living Rent basis if it is a renewal" do + log.assign_attributes(renewal: 1, rent_type:, irproduct_other:) + + expect { log.set_derived_fields! }.to change(log, :unitletas).to expected_unitletas + end + + it "clears the most recent let type if it is not a renewal" do + expect { persisted_renewal_lettings_log.update!(renewal: 0) }.to change(persisted_renewal_lettings_log, :unitletas).from(expected_unitletas).to nil + end + end + end + end +end diff --git a/spec/models/lettings_log_spec.rb b/spec/models/lettings_log_spec.rb index a0281af45..9e77c45e1 100644 --- a/spec/models/lettings_log_spec.rb +++ b/spec/models/lettings_log_spec.rb @@ -241,1850 +241,232 @@ RSpec.describe LettingsLog do describe "derived variables" do let!(:lettings_log) do - described_class.create({ - managing_organisation: owning_organisation, - owning_organisation:, - assigned_to: assigned_to_user, - postcode_full: "M1 1AE", - ppostcode_full: "M2 2AE", - startdate: Time.gm(2021, 10, 10), - mrcdate: Time.gm(2021, 5, 4), - voiddate: Time.gm(2021, 3, 3), - net_income_known: 2, - hhmemb: 7, - rent_type: 4, - hb: 1, - hbrentshortfall: 1, - created_at: Time.utc(2022, 2, 8, 16, 52, 15), - }) - end - - it "correctly derives and saves partial and full major repairs date" do - record_from_db = described_class.find(lettings_log.id) - expect(record_from_db["mrcdate"].day).to eq(4) - expect(record_from_db["mrcdate"].month).to eq(5) - expect(record_from_db["mrcdate"].year).to eq(2021) - end - - it "correctly derives and saves incref" do - expect(lettings_log.reload.incref).to eq(1) - - lettings_log.update!(net_income_known: 1) - expect(lettings_log.reload.incref).to eq(2) - - lettings_log.update!(net_income_known: 0) - expect(lettings_log.reload.incref).to eq(0) - end - - it "correctly derives and saves renttype" do - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.renttype).to eq(3) - expect(record_from_db["renttype"]).to eq(3) - end - - context "when deriving lettype" do - context "when the owning organisation is a PRP" do - before { lettings_log.owning_organisation.update!(provider_type: 2) } - - context "when the rent type is intermediate rent and supported housing" do - it "correctly derives and saves lettype" do - lettings_log.update!(rent_type: 4, needstype: 2) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.lettype).to eq(10) - expect(record_from_db["lettype"]).to eq(10) - end - end - - context "when the rent type is intermediate rent and general needs housing" do - it "correctly derives and saves lettype" do - lettings_log.update!(rent_type: 4, needstype: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.lettype).to eq(9) - expect(record_from_db["lettype"]).to eq(9) - end - end - - context "when the rent type is affordable rent and supported housing" do - it "correctly derives and saves lettype" do - lettings_log.update!(rent_type: 2, needstype: 2) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.lettype).to eq(6) - expect(record_from_db["lettype"]).to eq(6) - end - end - - context "when the rent type is affordable rent and general needs housing" do - it "correctly derives and saves lettype" do - lettings_log.update!(rent_type: 2, needstype: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.lettype).to eq(5) - expect(record_from_db["lettype"]).to eq(5) - end - end - - context "when the rent type is social rent and supported housing" do - it "correctly derives and saves lettype" do - lettings_log.update!(rent_type: 0, needstype: 2) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.lettype).to eq(2) - expect(record_from_db["lettype"]).to eq(2) - end - end - - context "when the rent type is social rent and general needs housing" do - it "correctly derives and saves lettype" do - lettings_log.update!(rent_type: 0, needstype: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.lettype).to eq(1) - expect(record_from_db["lettype"]).to eq(1) - end - end - - context "when the tenant is not in receipt of applicable benefits" do - it "correctly resets total shortfall" do - lettings_log.update!(hbrentshortfall: 2, wtshortfall: 100, hb: 9) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to be_nil - expect(record_from_db["wtshortfall"]).to be_nil - end - end - - context "when rent is paid bi-weekly" do - it "correctly derives and saves weekly rent" do - lettings_log.update!(brent: 100, period: 2) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wrent).to eq(50.0) - expect(record_from_db["wrent"]).to eq(50.0) - end - - it "correctly derives and saves weekly service charge" do - lettings_log.update!(scharge: 70, period: 2) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wscharge).to eq(35.0) - expect(record_from_db["wscharge"]).to eq(35.0) - end - - it "correctly derives and saves weekly personal service charge" do - lettings_log.update!(pscharge: 60, period: 2) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wpschrge).to eq(30.0) - expect(record_from_db["wpschrge"]).to eq(30.0) - end - - it "correctly derives and saves weekly support charge" do - lettings_log.update!(supcharg: 80, period: 2) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(40.0) - expect(record_from_db["wsupchrg"]).to eq(40.0) - end - - it "correctly derives and saves weekly total charge" do - lettings_log.update!(tcharge: 100, period: 2) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtcharge).to eq(50.0) - expect(record_from_db["wtcharge"]).to eq(50.0) - end - - context "when the tenant has an outstanding amount after benefits" do - context "when tenant is in receipt of housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 100, period: 2, hb: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(50.0) - expect(record_from_db["wtshortfall"]).to eq(50.0) - end - end - - context "when tenant is in receipt of universal credit with housing element exc. housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 100, period: 2, hb: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(50.0) - expect(record_from_db["wtshortfall"]).to eq(50.0) - end - end - - context "when tenant is in receipt of housing benefit and universal credit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 100, period: 2, hb: 8) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(50.0) - expect(record_from_db["wtshortfall"]).to eq(50.0) - end - end - end - - it "correctly derives floats" do - lettings_log.update!(supcharg: 60.12, pscharge: 50.13, scharge: 60.98, brent: 60.97, period: 2) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(30.06) - expect(lettings_log.wpschrge).to eq(25.06) - expect(lettings_log.wscharge).to eq(30.49) - expect(lettings_log.wrent).to eq(30.49) - expect(lettings_log.wtcharge).to eq(116.1) - expect(record_from_db["wsupchrg"]).to eq(30.06) - expect(record_from_db["wpschrge"]).to eq(25.06) - expect(record_from_db["wscharge"]).to eq(30.49) - expect(record_from_db["wrent"]).to eq(30.49) - expect(record_from_db["wtcharge"]).to eq(116.1) - end - end - - context "when rent is paid every 4 weeks" do - it "correctly derives and saves weekly rent" do - lettings_log.update!(brent: 120, period: 3) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wrent).to eq(30.0) - expect(record_from_db["wrent"]).to eq(30.0) - end - - it "correctly derives and saves weekly service charge" do - lettings_log.update!(scharge: 120, period: 3) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wscharge).to eq(30.0) - expect(record_from_db["wscharge"]).to eq(30.0) - end - - it "correctly derives and saves weekly personal service charge" do - lettings_log.update!(pscharge: 120, period: 3) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wpschrge).to eq(30.0) - expect(record_from_db["wpschrge"]).to eq(30.0) - end - - it "correctly derives and saves weekly support charge" do - lettings_log.update!(supcharg: 120, period: 3) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(30.0) - expect(record_from_db["wsupchrg"]).to eq(30.0) - end - - it "correctly derives and saves weekly total charge" do - lettings_log.update!(tcharge: 120, period: 3) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtcharge).to eq(30.0) - expect(record_from_db["wtcharge"]).to eq(30.0) - end - - context "when the tenant has an outstanding amount after benefits" do - context "when tenant is in receipt of housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 120, period: 3, hb: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(30.0) - expect(record_from_db["wtshortfall"]).to eq(30.0) - end - end - - context "when tenant is in receipt of universal credit with housing element exc. housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 120, period: 3, hb: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(30.0) - expect(record_from_db["wtshortfall"]).to eq(30.0) - end - end - - context "when tenant is in receipt of housing benefit and universal credit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 120, period: 3, hb: 8) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(30.0) - expect(record_from_db["wtshortfall"]).to eq(30.0) - end - end - end - - it "correctly derives floats" do - lettings_log.update!(supcharg: 100.12, pscharge: 100.13, scharge: 100.98, brent: 100.97, period: 3) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(25.03) - expect(lettings_log.wpschrge).to eq(25.03) - expect(lettings_log.wscharge).to eq(25.24) - expect(lettings_log.wrent).to eq(25.24) - expect(lettings_log.wtcharge).to eq(100.55) - expect(record_from_db["wsupchrg"]).to eq(25.03) - expect(record_from_db["wpschrge"]).to eq(25.03) - expect(record_from_db["wscharge"]).to eq(25.24) - expect(record_from_db["wrent"]).to eq(25.24) - expect(record_from_db["wtcharge"]).to eq(100.55) - end - end - - context "when rent is paid every calendar month" do - it "correctly derives and saves weekly rent" do - lettings_log.update!(brent: 130, period: 4) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wrent).to eq(30.0) - expect(record_from_db["wrent"]).to eq(30.0) - end - - it "correctly derives and saves weekly service charge" do - lettings_log.update!(scharge: 130, period: 4) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wscharge).to eq(30.0) - expect(record_from_db["wscharge"]).to eq(30.0) - end - - it "correctly derives and saves weekly personal service charge" do - lettings_log.update!(pscharge: 130, period: 4) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wpschrge).to eq(30.0) - expect(record_from_db["wpschrge"]).to eq(30.0) - end - - it "correctly derives and saves weekly support charge" do - lettings_log.update!(supcharg: 130, period: 4) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(30.0) - expect(record_from_db["wsupchrg"]).to eq(30.0) - end - - it "correctly derives and saves weekly total charge" do - lettings_log.update!(tcharge: 130, period: 4) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtcharge).to eq(30.0) - expect(record_from_db["wtcharge"]).to eq(30.0) - end - - context "when the tenant has an outstanding amount after benefits" do - context "when tenant is in receipt of housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 4, hb: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(30.0) - expect(record_from_db["wtshortfall"]).to eq(30.0) - end - end - - context "when tenant is in receipt of universal credit with housing element exc. housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 4, hb: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(30.0) - expect(record_from_db["wtshortfall"]).to eq(30.0) - end - end - - context "when tenant is in receipt of housing benefit and universal credit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 4, hb: 8) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(30.0) - expect(record_from_db["wtshortfall"]).to eq(30.0) - end - end - end - - it "correctly derives floats" do - lettings_log.update!(supcharg: 100.12, pscharge: 100.13, scharge: 100.98, brent: 100.97, period: 4) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(23.10) - expect(lettings_log.wpschrge).to eq(23.11) - expect(lettings_log.wscharge).to eq(23.30) - expect(lettings_log.wrent).to eq(23.30) - expect(lettings_log.wtcharge).to eq(92.82) - expect(record_from_db["wsupchrg"]).to eq(23.10) - expect(record_from_db["wpschrge"]).to eq(23.11) - expect(record_from_db["wscharge"]).to eq(23.30) - expect(record_from_db["wrent"]).to eq(23.30) - expect(record_from_db["wtcharge"]).to eq(92.82) - end - end - - context "when rent is paid weekly for 50 weeks" do - it "correctly derives and saves weekly rent" do - lettings_log.update!(brent: 130, period: 5) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wrent).to eq(125.0) - expect(record_from_db["wrent"]).to eq(125.0) - end - - it "correctly derives and saves weekly service charge" do - lettings_log.update!(scharge: 20, period: 5) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wscharge).to eq(19.23) - expect(record_from_db["wscharge"]).to eq(19.23) - end - - it "correctly derives and saves weekly personal service charge" do - lettings_log.update!(pscharge: 20, period: 5) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wpschrge).to eq(19.23) - expect(record_from_db["wpschrge"]).to eq(19.23) - end - - it "correctly derives and saves weekly support charge" do - lettings_log.update!(supcharg: 20, period: 5) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(19.23) - expect(record_from_db["wsupchrg"]).to eq(19.23) - end - - it "correctly derives and saves weekly total charge" do - lettings_log.update!(tcharge: 130, period: 5) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtcharge).to eq(125.0) - expect(record_from_db["wtcharge"]).to eq(125.0) - end - - context "when the tenant has an outstanding amount after benefits" do - context "when tenant is in receipt of housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 5, hb: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(125.0) - expect(record_from_db["wtshortfall"]).to eq(125.0) - end - end - - context "when tenant is in receipt of universal credit with housing element exc. housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 5, hb: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(125.0) - expect(record_from_db["wtshortfall"]).to eq(125.0) - end - end - - context "when tenant is in receipt of housing benefit and universal credit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 5, hb: 8) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(125.0) - expect(record_from_db["wtshortfall"]).to eq(125.0) - end - end - end - - it "correctly derives floats" do - lettings_log.update!(supcharg: 20.12, pscharge: 20.13, scharge: 20.98, brent: 100.97, period: 5) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(19.35) - expect(lettings_log.wpschrge).to eq(19.36) - expect(lettings_log.wscharge).to eq(20.17) - expect(lettings_log.wrent).to eq(97.09) - expect(lettings_log.wtcharge).to eq(155.96) - expect(record_from_db["wsupchrg"]).to eq(19.35) - expect(record_from_db["wpschrge"]).to eq(19.36) - expect(record_from_db["wscharge"]).to eq(20.17) - expect(record_from_db["wrent"]).to eq(97.09) - expect(record_from_db["wtcharge"]).to eq(155.96) - end - end - - context "when rent is paid weekly for 49 weeks" do - it "correctly derives and saves weekly rent" do - lettings_log.update!(brent: 130, period: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wrent).to eq(122.5) - expect(record_from_db["wrent"]).to eq(122.5) - end - - it "correctly derives and saves weekly service charge" do - lettings_log.update!(scharge: 30, period: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wscharge).to eq(28.27) - expect(record_from_db["wscharge"]).to eq(28.27) - end - - it "correctly derives and saves weekly personal service charge" do - lettings_log.update!(pscharge: 30, period: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wpschrge).to eq(28.27) - expect(record_from_db["wpschrge"]).to eq(28.27) - end - - it "correctly derives and saves weekly support charge" do - lettings_log.update!(supcharg: 30, period: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(28.27) - expect(record_from_db["wsupchrg"]).to eq(28.27) - end - - it "correctly derives and saves weekly total charge" do - lettings_log.update!(tcharge: 130, period: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtcharge).to eq(122.5) - expect(record_from_db["wtcharge"]).to eq(122.5) - end - - context "when the tenant has an outstanding amount after benefits" do - context "when tenant is in receipt of housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 6, hb: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(122.5) - expect(record_from_db["wtshortfall"]).to eq(122.5) - end - end - - context "when tenant is in receipt of universal credit with housing element exc. housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 6, hb: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(122.5) - expect(record_from_db["wtshortfall"]).to eq(122.5) - end - end - - context "when tenant is in receipt of housing benefit and universal credit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 6, hb: 8) - lettings_log.reload - expect(lettings_log.wtshortfall).to eq(122.5) - end - end - end - - it "correctly derives floats" do - lettings_log.update!(supcharg: 30.12, pscharge: 30.13, scharge: 30.98, brent: 100.97, period: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(28.38) - expect(lettings_log.wpschrge).to eq(28.39) - expect(lettings_log.wscharge).to eq(29.19) - expect(lettings_log.wrent).to eq(95.14) - expect(lettings_log.wtcharge).to eq(181.11) - expect(record_from_db["wsupchrg"]).to eq(28.38) - expect(record_from_db["wpschrge"]).to eq(28.39) - expect(record_from_db["wscharge"]).to eq(29.19) - expect(record_from_db["wrent"]).to eq(95.14) - expect(record_from_db["wtcharge"]).to eq(181.11) - end - end - - context "when rent is paid weekly for 48 weeks" do - it "correctly derives and saves weekly rent" do - lettings_log.update!(brent: 130, period: 7) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wrent).to eq(120.0) - expect(record_from_db["wrent"]).to eq(120.0) - end - - it "correctly derives and saves weekly service charge" do - lettings_log.update!(scharge: 30, period: 7) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wscharge).to eq(27.69) - expect(record_from_db["wscharge"]).to eq(27.69) - end - - it "correctly derives and saves weekly personal service charge" do - lettings_log.update!(pscharge: 30, period: 7) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wpschrge).to eq(27.69) - expect(record_from_db["wpschrge"]).to eq(27.69) - end - - it "correctly derives and saves weekly support charge" do - lettings_log.update!(supcharg: 30, period: 7) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(27.69) - expect(record_from_db["wsupchrg"]).to eq(27.69) - end - - it "correctly derives and saves weekly total charge" do - lettings_log.update!(tcharge: 130, period: 7) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtcharge).to eq(120.0) - expect(record_from_db["wtcharge"]).to eq(120.0) - end - - context "when the tenant has an outstanding amount after benefits" do - context "when tenant is in receipt of housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 7, hb: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(120.0) - expect(record_from_db["wtshortfall"]).to eq(120.0) - end - end - - context "when tenant is in receipt of universal credit with housing element exc. housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 7, hb: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(120.0) - expect(record_from_db["wtshortfall"]).to eq(120.0) - end - end - - context "when tenant is in receipt of housing benefit and universal credit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 7, hb: 8) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(120.0) - expect(record_from_db["wtshortfall"]).to eq(120.0) - end - end - end - - it "correctly derives floats" do - lettings_log.update!(supcharg: 30.12, pscharge: 30.13, scharge: 30.98, brent: 100.97, period: 7) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(27.8) - expect(lettings_log.wpschrge).to eq(27.81) - expect(lettings_log.wscharge).to eq(28.6) - expect(lettings_log.wrent).to eq(93.20) - expect(lettings_log.wtcharge).to eq(177.42) - expect(record_from_db["wsupchrg"]).to eq(27.8) - expect(record_from_db["wpschrge"]).to eq(27.81) - expect(record_from_db["wscharge"]).to eq(28.6) - expect(record_from_db["wrent"]).to eq(93.20) - expect(record_from_db["wtcharge"]).to eq(177.42) - end - end - - context "when rent is paid weekly for 47 weeks" do - it "correctly derives and saves weekly rent" do - lettings_log.update!(brent: 130, period: 8) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wrent).to eq(117.5) - expect(record_from_db["wrent"]).to eq(117.5) - end - - it "correctly derives and saves weekly service charge" do - lettings_log.update!(scharge: 30, period: 8) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wscharge).to eq(27.12) - expect(record_from_db["wscharge"]).to eq(27.12) - end - - it "correctly derives and saves weekly personal service charge" do - lettings_log.update!(pscharge: 30, period: 8) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wpschrge).to eq(27.12) - expect(record_from_db["wpschrge"]).to eq(27.12) - end - - it "correctly derives and saves weekly support charge" do - lettings_log.update!(supcharg: 30, period: 8) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(27.12) - expect(record_from_db["wsupchrg"]).to eq(27.12) - end - - it "correctly derives and saves weekly total charge" do - lettings_log.update!(tcharge: 130, period: 8) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtcharge).to eq(117.5) - expect(record_from_db["wtcharge"]).to eq(117.5) - end - - context "when the tenant has an outstanding amount after benefits" do - context "when tenant is in receipt of housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 8, hb: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(117.5) - expect(record_from_db["wtshortfall"]).to eq(117.5) - end - end - - context "when tenant is in receipt of universal credit with housing element exc. housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 8, hb: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(117.5) - expect(record_from_db["wtshortfall"]).to eq(117.5) - end - end - - context "when tenant is in receipt of housing benefit and universal credit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 8, hb: 8) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(117.5) - expect(record_from_db["wtshortfall"]).to eq(117.5) - end - end - end - - it "correctly derives floats" do - lettings_log.update!(supcharg: 30.12, pscharge: 30.13, scharge: 30.98, brent: 100.97, period: 8) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(27.22) - expect(lettings_log.wpschrge).to eq(27.23) - expect(lettings_log.wscharge).to eq(28) - expect(lettings_log.wrent).to eq(91.26) - expect(lettings_log.wtcharge).to eq(173.72) - expect(record_from_db["wsupchrg"]).to eq(27.22) - expect(record_from_db["wpschrge"]).to eq(27.23) - expect(record_from_db["wscharge"]).to eq(28) - expect(record_from_db["wrent"]).to eq(91.26) - expect(record_from_db["wtcharge"]).to eq(173.72) - end - end - - context "when rent is paid weekly for 46 weeks" do - it "correctly derives and saves weekly rent" do - lettings_log.update!(brent: 130, period: 9) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wrent).to eq(115.0) - expect(record_from_db["wrent"]).to eq(115.0) - end - - it "correctly derives and saves weekly service charge" do - lettings_log.update!(scharge: 30, period: 9) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wscharge).to eq(26.54) - expect(record_from_db["wscharge"]).to eq(26.54) - end - - it "correctly derives and saves weekly personal service charge" do - lettings_log.update!(pscharge: 30, period: 9) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wpschrge).to eq(26.54) - expect(record_from_db["wpschrge"]).to eq(26.54) - end - - it "correctly derives and saves weekly support charge" do - lettings_log.update!(supcharg: 30, period: 9) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(26.54) - expect(record_from_db["wsupchrg"]).to eq(26.54) - end - - it "correctly derives and saves weekly total charge" do - lettings_log.update!(tcharge: 130, period: 9) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtcharge).to eq(115.0) - expect(record_from_db["wtcharge"]).to eq(115.0) - end - - context "when the tenant has an outstanding amount after benefits" do - context "when tenant is in receipt of housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 9, hb: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(115.0) - expect(record_from_db["wtshortfall"]).to eq(115.0) - end - end - - context "when tenant is in receipt of universal credit with housing element exc. housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 9, hb: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(115.0) - expect(record_from_db["wtshortfall"]).to eq(115.0) - end - end - - context "when tenant is in receipt of housing benefit and universal credit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 9, hb: 8) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(115.0) - expect(record_from_db["wtshortfall"]).to eq(115.0) - end - end - end - - it "correctly derives floats" do - lettings_log.update!(supcharg: 30.12, pscharge: 30.13, scharge: 30.98, brent: 100.97, period: 9) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(26.64) - expect(lettings_log.wpschrge).to eq(26.65) - expect(lettings_log.wscharge).to eq(27.41) - expect(lettings_log.wrent).to eq(89.32) - expect(lettings_log.wtcharge).to eq(170.02) - expect(record_from_db["wsupchrg"]).to eq(26.64) - expect(record_from_db["wpschrge"]).to eq(26.65) - expect(record_from_db["wscharge"]).to eq(27.41) - expect(record_from_db["wrent"]).to eq(89.32) - expect(record_from_db["wtcharge"]).to eq(170.02) - end - end - - context "when rent is paid weekly for 52 weeks" do - it "correctly derives and saves weekly rent" do - lettings_log.update!(brent: 130, period: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wrent).to eq(130.0) - expect(record_from_db["wrent"]).to eq(130.0) - end - - it "correctly derives and saves weekly service charge" do - lettings_log.update!(scharge: 30, period: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wscharge).to eq(30.0) - expect(record_from_db["wscharge"]).to eq(30.0) - end - - it "correctly derives and saves weekly personal service charge" do - lettings_log.update!(pscharge: 30, period: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wpschrge).to eq(30.0) - expect(record_from_db["wpschrge"]).to eq(30.0) - end - - it "correctly derives and saves weekly support charge" do - lettings_log.update!(supcharg: 30, period: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(30.0) - expect(record_from_db["wsupchrg"]).to eq(30.0) - end - - it "correctly derives and saves weekly total charge" do - lettings_log.update!(tcharge: 30, period: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtcharge).to eq(30.0) - expect(record_from_db["wtcharge"]).to eq(30.0) - end - - context "when the tenant has an outstanding amount after benefits" do - context "when tenant is in receipt of housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 1, hb: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(130.0) - expect(record_from_db["wtshortfall"]).to eq(130.0) - end - end - - context "when tenant is in receipt of universal credit with housing element exc. housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 1, hb: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(130.0) - expect(record_from_db["wtshortfall"]).to eq(130.0) - end - end - - context "when tenant is in receipt of housing benefit and universal credit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 1, hb: 8) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(130.0) - expect(record_from_db["wtshortfall"]).to eq(130.0) - end - end - end - - it "correctly derives floats" do - lettings_log.update!(supcharg: 30.12, pscharge: 25.13, scharge: 30.98, brent: 100.97, period: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(30.12) - expect(lettings_log.wpschrge).to eq(25.13) - expect(lettings_log.wscharge).to eq(30.98) - expect(lettings_log.wrent).to eq(100.97) - expect(lettings_log.wtcharge).to eq(187.2) - expect(record_from_db["wsupchrg"]).to eq(30.12) - expect(record_from_db["wpschrge"]).to eq(25.13) - expect(record_from_db["wscharge"]).to eq(30.98) - expect(record_from_db["wrent"]).to eq(100.97) - expect(record_from_db["wtcharge"]).to eq(187.2) - end - end - - context "when rent is paid weekly for 53 weeks" do - it "correctly derives and saves weekly rent" do - lettings_log.update!(brent: 130, period: 10) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wrent).to eq(132.5) - expect(record_from_db["wrent"]).to eq(132.5) - end - - it "correctly derives and saves weekly service charge" do - lettings_log.update!(scharge: 30, period: 10) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wscharge).to eq(30.58) - expect(record_from_db["wscharge"]).to eq(30.58) - end - - it "correctly derives and saves weekly personal service charge" do - lettings_log.update!(pscharge: 30, period: 10) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wpschrge).to eq(30.58) - expect(record_from_db["wpschrge"]).to eq(30.58) - end - - it "correctly derives and saves weekly support charge" do - lettings_log.update!(supcharg: 30, period: 10) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(30.58) - expect(record_from_db["wsupchrg"]).to eq(30.58) - end - - it "correctly derives and saves weekly total charge" do - lettings_log.update!(tcharge: 30, period: 10) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtcharge).to eq(30.58) - expect(record_from_db["wtcharge"]).to eq(30.58) - end - - context "when the tenant has an outstanding amount after benefits" do - context "when tenant is in receipt of housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 10, hb: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(132.5) - expect(record_from_db["wtshortfall"]).to eq(132.5) - end - end - - context "when tenant is in receipt of universal credit with housing element exc. housing benefit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 10, hb: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(132.5) - expect(record_from_db["wtshortfall"]).to eq(132.5) - end - end - - context "when tenant is in receipt of housing benefit and universal credit" do - it "correctly derives and saves weekly total shortfall" do - lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 10, hb: 8) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wtshortfall).to eq(132.5) - expect(record_from_db["wtshortfall"]).to eq(132.5) - end - end - end - - it "correctly derives floats" do - lettings_log.update!(supcharg: 30.12, pscharge: 25.13, scharge: 30.98, brent: 100.97, period: 10) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wsupchrg).to eq(30.7) - expect(lettings_log.wpschrge).to eq(25.61) - expect(lettings_log.wscharge).to eq(31.58) - expect(lettings_log.wrent).to eq(102.91) - expect(lettings_log.wtcharge).to eq(190.8) - expect(record_from_db["wsupchrg"]).to eq(30.7) - expect(record_from_db["wpschrge"]).to eq(25.61) - expect(record_from_db["wscharge"]).to eq(31.58) - expect(record_from_db["wrent"]).to eq(102.91) - expect(record_from_db["wtcharge"]).to eq(190.8) - end - end - end - - context "when the owning organisation is a LA" do - before { lettings_log.owning_organisation.update!(provider_type: "LA") } - - context "when the rent type is intermediate rent and supported housing" do - it "correctly derives and saves lettype" do - lettings_log.update!(rent_type: 4, needstype: 2) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.lettype).to eq(12) - expect(record_from_db["lettype"]).to eq(12) - end - end - - context "when the rent type is intermediate rent and general needs housing" do - it "correctly derives and saves lettype" do - lettings_log.update!(rent_type: 4, needstype: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.lettype).to eq(11) - expect(record_from_db["lettype"]).to eq(11) - end - end - - context "when the rent type is affordable rent and supported housing" do - it "correctly derives and saves lettype" do - lettings_log.update!(rent_type: 2, needstype: 2) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.lettype).to eq(8) - expect(record_from_db["lettype"]).to eq(8) - end - end - - context "when the rent type is affordable rent and general needs housing" do - it "correctly derives and saves lettype" do - lettings_log.update!(rent_type: 2, needstype: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.lettype).to eq(7) - expect(record_from_db["lettype"]).to eq(7) - end - end - - context "when the rent type is social rent and supported housing" do - it "correctly derives and saves lettype" do - lettings_log.update!(rent_type: 0, needstype: 2) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.lettype).to eq(4) - expect(record_from_db["lettype"]).to eq(4) - end - end - - context "when the rent type is social rent and general needs housing" do - it "correctly derives and saves lettype" do - lettings_log.update!(rent_type: 0, needstype: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.lettype).to eq(3) - expect(record_from_db["lettype"]).to eq(3) - end - end - end - end - - it "correctly derives and saves day, month, year from start date" do - record_from_db = described_class.find(lettings_log.id) - expect(record_from_db["startdate"].day).to eq(10) - expect(record_from_db["startdate"].month).to eq(10) - expect(record_from_db["startdate"].year).to eq(2021) - end - - context "when any charge field is set" do - before do - lettings_log.update!(pscharge: 10) - end - - it "derives that any blank ones are 0" do - record_from_db = described_class.find(lettings_log.id) - expect(record_from_db["supcharg"].to_f).to eq(0.0) - expect(record_from_db["scharge"].to_f).to eq(0.0) - end - end - - def check_postcode_fields(postcode_field) - record_from_db = described_class.find(lettings_log.id) - expect(address_lettings_log[postcode_field]).to eq("M1 1AE") - expect(record_from_db[postcode_field]).to eq("M1 1AE") - end - - def check_previous_postcode_fields(postcode_field) - record_from_db = described_class.find(address_lettings_log.id) - expect(address_lettings_log[postcode_field]).to eq("M1 1AE") - expect(record_from_db[postcode_field]).to eq("M1 1AE") - end - - context "when saving addresses" 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: {}) - end - - let!(:address_lettings_log) do - described_class.create({ - managing_organisation: owning_organisation, - owning_organisation:, - assigned_to: assigned_to_user, - postcode_known: 1, - postcode_full: "M1 1AE", - }) - end - - def check_property_postcode_fields - check_postcode_fields("postcode_full") - end - - it "correctly formats previous postcode" do - address_lettings_log.update!(postcode_full: "M1 1AE") - check_property_postcode_fields - - address_lettings_log.update!(postcode_full: "m1 1ae") - check_property_postcode_fields - - address_lettings_log.update!(postcode_full: "m11Ae") - check_property_postcode_fields - - address_lettings_log.update!(postcode_full: "m11ae") - check_property_postcode_fields - end - - it "correctly infers la" do - record_from_db = described_class.find(address_lettings_log.id) - expect(address_lettings_log.la).to eq("E08000003") - expect(record_from_db["la"]).to eq("E08000003") - end - - it "errors if the property postcode is emptied" do - expect { address_lettings_log.update!({ postcode_full: "" }) } - .to raise_error(ActiveRecord::RecordInvalid, /#{I18n.t("validations.postcode")}/) - end - - it "errors if the property postcode is not valid" do - expect { address_lettings_log.update!({ postcode_full: "invalid_postcode" }) } - .to raise_error(ActiveRecord::RecordInvalid, /#{I18n.t("validations.postcode")}/) - end - - context "when the local authority lookup times out" do - before do - allow(Timeout).to receive(:timeout).and_raise(Timeout::Error) - end - - it "logs a warning" do - expect(Rails.logger).to receive(:warn).with("Postcodes.io lookup timed out") - address_lettings_log.update!({ postcode_known: 1, postcode_full: "M1 1AD" }) - end - end - - it "correctly resets all fields if property postcode not known" do - address_lettings_log.update!({ postcode_known: 0 }) - - record_from_db = described_class.find(address_lettings_log.id) - expect(record_from_db["postcode_full"]).to eq(nil) - expect(address_lettings_log.la).to eq(nil) - expect(record_from_db["la"]).to eq(nil) - end - - it "changes the LA if property postcode changes from not known to known and provided" do - address_lettings_log.update!({ postcode_known: 0 }) - address_lettings_log.update!({ la: "E09000033" }) - - record_from_db = described_class.find(address_lettings_log.id) - expect(record_from_db["postcode_full"]).to eq(nil) - expect(address_lettings_log.la).to eq("E09000033") - expect(record_from_db["la"]).to eq("E09000033") - - address_lettings_log.update!({ postcode_known: 1, postcode_full: "M1 1AD" }) - - record_from_db = described_class.find(address_lettings_log.id) - expect(record_from_db["postcode_full"]).to eq("M1 1AD") - expect(address_lettings_log.la).to eq("E08000003") - expect(record_from_db["la"]).to eq("E08000003") - end - end - - context "when uprn is not confirmed" do - it "clears previous address on renewal logs" do - log = FactoryBot.build(:lettings_log, uprn_known: 1, uprn: 1, uprn_confirmed: 0, renewal: 1, prevloc: "E08000003", ppostcode_full: "A1 1AA", ppcodenk: 0, previous_la_known: 1) - - expect { log.set_derived_fields! }.to change(log, :prevloc).from("E08000003").to(nil) - .and change(log, :ppostcode_full).from("A1 1AA").to(nil) - .and change(log, :ppcodenk).from(0).to(nil) - .and change(log, :previous_la_known).from(1).to(nil) - end - - it "does not clear previous address on non renewal logs" do - log = FactoryBot.build(:lettings_log, uprn_known: 1, uprn: 1, uprn_confirmed: 0, renewal: 0, prevloc: "E08000003", ppostcode_full: "A1 1AA", ppcodenk: 0, previous_la_known: 1) - log.set_derived_fields! - expect(log.prevloc).to eq("E08000003") - expect(log.ppostcode_full).to eq("A1 1AA") - expect(log.ppcodenk).to eq(0) - expect(log.previous_la_known).to eq(1) - end - end - - context "when saving previous address" 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: {}) - end - - let!(:address_lettings_log) do - described_class.create({ - managing_organisation: owning_organisation, - owning_organisation:, - assigned_to: assigned_to_user, - ppcodenk: 0, - ppostcode_full: "M1 1AE", - }) - end - - def previous_postcode_fields - check_previous_postcode_fields("ppostcode_full") - end - - it "correctly formats previous postcode" do - address_lettings_log.update!(ppostcode_full: "M1 1AE") - previous_postcode_fields - - address_lettings_log.update!(ppostcode_full: "m1 1ae") - previous_postcode_fields - - address_lettings_log.update!(ppostcode_full: "m11Ae") - previous_postcode_fields - - address_lettings_log.update!(ppostcode_full: "m11ae") - previous_postcode_fields - end - - it "correctly infers prevloc" do - record_from_db = described_class.find(address_lettings_log.id) - expect(address_lettings_log.prevloc).to eq("E08000003") - expect(record_from_db["prevloc"]).to eq("E08000003") - end - - it "errors if the previous postcode is emptied" do - expect { address_lettings_log.update!({ ppostcode_full: "" }) } - .to raise_error(ActiveRecord::RecordInvalid, /#{I18n.t("validations.postcode")}/) - end - - it "errors if the previous postcode is not valid" do - expect { address_lettings_log.update!({ ppostcode_full: "invalid_postcode" }) } - .to raise_error(ActiveRecord::RecordInvalid, /#{I18n.t("validations.postcode")}/) - end - - it "correctly resets all fields if previous postcode not known" do - address_lettings_log.update!({ ppcodenk: 1 }) - - record_from_db = described_class.find(address_lettings_log.id) - expect(record_from_db["ppostcode_full"]).to eq(nil) - expect(address_lettings_log.prevloc).to eq(nil) - expect(record_from_db["prevloc"]).to eq(nil) - end - - it "correctly resets la if la is not known" do - address_lettings_log.update!({ ppcodenk: 1 }) - address_lettings_log.update!({ previous_la_known: 1, prevloc: "S92000003" }) - record_from_db = described_class.find(address_lettings_log.id) - expect(record_from_db["prevloc"]).to eq("S92000003") - expect(address_lettings_log.prevloc).to eq("S92000003") - - address_lettings_log.update!({ previous_la_known: 0 }) - record_from_db = described_class.find(address_lettings_log.id) - expect(address_lettings_log.prevloc).to eq(nil) - expect(record_from_db["prevloc"]).to eq(nil) - end - - it "changes the prevloc if previous postcode changes from not known to known and provided" do - address_lettings_log.update!({ ppcodenk: 1 }) - address_lettings_log.update!({ previous_la_known: 1, prevloc: "E09000033" }) - - record_from_db = described_class.find(address_lettings_log.id) - expect(record_from_db["ppostcode_full"]).to eq(nil) - expect(address_lettings_log.prevloc).to eq("E09000033") - expect(record_from_db["prevloc"]).to eq("E09000033") - - address_lettings_log.update!({ ppcodenk: 0, ppostcode_full: "M1 1AD" }) - - record_from_db = described_class.find(address_lettings_log.id) - expect(record_from_db["ppostcode_full"]).to eq("M1 1AD") - expect(address_lettings_log.prevloc).to eq("E08000003") - expect(record_from_db["prevloc"]).to eq("E08000003") - end - end - - context "when saving rent and charges" do - let!(:lettings_log) do - described_class.create({ - managing_organisation: owning_organisation, - owning_organisation:, - assigned_to: assigned_to_user, - brent: 5.77, - scharge: 10.01, - pscharge: 3, - supcharg: 12.2, - }) - end - - it "correctly sums rental charges" do - record_from_db = described_class.find(lettings_log.id) - expect(record_from_db["tcharge"]).to eq(30.98) - end - end - - context "when validating household members derived vars" do - let!(:household_lettings_log) do - described_class.create!({ - managing_organisation: owning_organisation, - owning_organisation:, - assigned_to: assigned_to_user, - hhmemb: 3, - relat2: "X", - relat3: "C", - relat4: "X", - relat5: "C", - relat7: "C", - relat8: "X", - age1: 22, - age2: 16, - age4: 60, - age6: 88, - age7: 14, - age8: 42, - }) - end - - it "correctly derives and saves totchild" do - record_from_db = described_class.find(household_lettings_log.id) - expect(record_from_db["totchild"]).to eq(3) - end - - it "correctly derives and saves totelder" do - record_from_db = described_class.find(household_lettings_log.id) - expect(record_from_db["totelder"]).to eq(2) - end - - it "correctly derives and saves totadult" do - record_from_db = described_class.find(household_lettings_log.id) - expect(record_from_db["totadult"]).to eq(3) - end - - it "correctly derives economic status for tenants under 16" do - record_from_db = described_class.find(household_lettings_log.id) - expect(record_from_db["ecstat7"]).to eq(9) - end - end - - it "correctly derives and saves has_benefits" do - record_from_db = described_class.find(lettings_log.id) - expect(record_from_db["has_benefits"]).to eq(1) - end - - context "when updating values that derive vacdays" do - let(:lettings_log) { create(:lettings_log, startdate:) } - - context "when start date is set" do - let(:startdate) { Time.zone.now } - - it "correctly derives vacdays when voiddate is set" do - day_count = 3 - expect { lettings_log.update!(voiddate: startdate - day_count.days) }.to change(lettings_log, :vacdays).to day_count - expect { lettings_log.update!(voiddate: nil) }.to change(lettings_log, :vacdays).from(day_count).to nil - end - - it "correctly derives vacdays when mrcdate is set" do - day_count = 3 - expect { lettings_log.update!(mrcdate: startdate - day_count.days) }.to change(lettings_log, :vacdays).to day_count - expect { lettings_log.update!(mrcdate: nil) }.to change(lettings_log, :vacdays).from(day_count).to nil - end - end - - context "when start date is not set" do - let(:startdate) { nil } - - it "correctly derives vacdays when voiddate is set" do - day_count = 3 - lettings_log.update!(voiddate: Time.zone.now - day_count.days) - expect(lettings_log.vacdays).to be nil - end - - it "correctly derives vacdays when mrcdate is set" do - day_count = 3 - lettings_log.update!(mrcdate: Time.zone.now - day_count.days) - expect(lettings_log.vacdays).to be nil - end - end - end - - context "when updating renewal" do - let!(:lettings_log) do - described_class.create({ - managing_organisation: owning_organisation, - owning_organisation:, - assigned_to: assigned_to_user, - startdate: Time.zone.local(2021, 4, 10), - created_at: Time.utc(2022, 2, 8, 16, 52, 15), - }) - end - - it "correctly derives the length of time on local authority waiting list" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :waityear).to 2 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :waityear).from(2).to nil - end - - it "correctly derives the number of times previously offered since becoming available" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :offered).to 0 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :offered).from(0).to nil - end - - it "correctly derives referral if the letting is a renewal and clears it if it is not" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :referral).to 1 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :referral).from(1).to nil - end - - it "correctly derives voiddate if the letting is a renewal and clears it if it is not" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :voiddate).to lettings_log.startdate - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :voiddate).from(lettings_log.startdate).to nil - end - - it "correctly derives first_time_property_let_as_social_housing and clears it if it is not" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :first_time_property_let_as_social_housing).to 0 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :first_time_property_let_as_social_housing).from(0).to nil - end - - it "correctly derives vacancy reason and clears it if it is not" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :rsnvac).to 14 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :rsnvac).from(14).to nil - end - - it "derives vacdays as 0 if log is renewal" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :vacdays).to 0 - end - - it "correctly derives underoccupation_benefitcap if log is a renewal from 2021/22" do - lettings_log.update!(renewal: 1) - expect(lettings_log.underoccupation_benefitcap).to be 2 - end - - it "clears underoccupation_benefitcap if log is no longer a renewal" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :underoccupation_benefitcap).to 2 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :underoccupation_benefitcap).from(2).to nil - end - - it "clears underoccupation_benefitcap if log is no longer in 2021/22" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :underoccupation_benefitcap).to 2 - Timecop.return - Singleton.__init__(FormHandler) - expect { lettings_log.update!(startdate: Time.zone.local(2023, 4, 1)) }.to change(lettings_log, :underoccupation_benefitcap).from(2).to nil - end - - it "derives ppostcode_full as postcode_full if log is renewal" do - lettings_log.update!(renewal: 0, postcode_full: "M1 1AE", postcode_known: 1, ppostcode_full: "M1 1AD") - lettings_log.update!(renewal: 1) - lettings_log.reload - expect(lettings_log.ppostcode_full).to eq("M1 1AE") - expect(lettings_log.ppcodenk).to eq(0) - expect(lettings_log.prevloc).to eq(lettings_log.la) - end - - context "when the log is general needs" do - context "and the managing organisation is a private registered provider" do - before do - lettings_log.managing_organisation.update!(provider_type: "PRP") - lettings_log.update!(needstype: 1, renewal: 1) - end - - it "correctly derives prevten" do - expect(lettings_log.prevten).to be 32 - end - - it "clears prevten if the log is marked as supported housing" do - lettings_log.update!(needstype: 2) - expect(lettings_log.prevten).to be nil - end - - it "clears prevten if renewal is update to no" do - lettings_log.update!(renewal: 0) - expect(lettings_log.prevten).to be nil - end - end - - context "and the managing organisation is a local authority" do - before do - lettings_log.managing_organisation.update!(provider_type: "LA") - lettings_log.update!(needstype: 1, renewal: 1) - end - - it "correctly derives prevten" do - expect(lettings_log.prevten).to be 30 - end - - it "clears prevten if the log is marked as supported housing" do - expect { lettings_log.update!(needstype: 2) }.to change(lettings_log, :prevten).to nil - end - - it "clears prevten if renewal is update to no" do - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :prevten).to nil - end - end - end - - context "and updating rent_type" do - let(:irproduct_other) { nil } - - around do |example| - Timecop.freeze(now) do - Singleton.__init__(FormHandler) - lettings_log.update!(rent_type:, irproduct_other:, startdate: now) - example.run - end - end - - context "when collection year is 2022/23 or earlier" do - let(:now) { Time.zone.local(2023, 1, 1) } - - context "when rent_type is Social Rent" do - let(:rent_type) { 0 } - - it "derives the most recent let type as Social Rent basis if it is a renewal and clears it if it is not" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :unitletas).to 1 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :unitletas).from(1).to nil - end - end - - context "when rent_type is Affordable Rent" do - let(:rent_type) { 1 } - - it "derives the most recent let type as Affordable Rent basis if it is a renewal and clears it if it is not" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :unitletas).to 2 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :unitletas).from(2).to nil - end - end - - context "when rent_type is London Affordable Rent" do - let(:rent_type) { 2 } - - it "derives the most recent let type as Affordable Rent basis if it is a renewal and clears it if it is not" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :unitletas).to 2 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :unitletas).from(2).to nil - end - end - - context "when rent_type is Rent to Buy" do - let(:rent_type) { 3 } - - it "derives the most recent let type as Intermediate Rent basis if it is a renewal and clears it if it is not" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :unitletas).to 4 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :unitletas).from(4).to nil - end - end - - context "when rent_type is London Living Rent" do - let(:rent_type) { 4 } - - it "derives the most recent let type as Intermediate Rent basis if it is a renewal and clears it if it is not" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :unitletas).to 4 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :unitletas).from(4).to nil - end - end - - context "when rent_type is Other intermediate rent product" do - let(:rent_type) { 5 } - let(:irproduct_other) { "Rent first" } - - it "derives the most recent let type as Intermediate Rent basis if it is a renewal and clears it if it is not" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :unitletas).to 4 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :unitletas).from(4).to nil - end - end - end - - context "when collection year is 2023/24 or later" do - let(:now) { Time.zone.local(2024, 1, 1) } - - context "when rent_type is Social Rent" do - let(:rent_type) { 0 } - - it "derives the most recent let type as Social Rent basis if it is a renewal and clears it if it is not" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :unitletas).to 1 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :unitletas).from(1).to nil - end - end - - context "when rent_type is Affordable Rent" do - let(:rent_type) { 1 } + create( + :lettings_log, + managing_organisation: owning_organisation, + owning_organisation:, + assigned_to: assigned_to_user, + postcode_full: "M1 1AE", + ppostcode_full: "M2 2AE", + startdate: Time.gm(2021, 10, 10), + mrcdate: Time.gm(2021, 5, 4), + voiddate: Time.gm(2021, 3, 3), + net_income_known: 2, # refused + hhmemb: 7, + rent_type: 4, + hb: 1, + hbrentshortfall: 1, + created_at: Time.utc(2022, 2, 8, 16, 52, 15), + ) + end - it "derives the most recent let type as Affordable Rent basis if it is a renewal and clears it if it is not" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :unitletas).to 2 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :unitletas).from(2).to nil - end - end + def check_postcode_fields(postcode_field) + record_from_db = described_class.find(lettings_log.id) + expect(address_lettings_log[postcode_field]).to eq("M1 1AE") + expect(record_from_db[postcode_field]).to eq("M1 1AE") + end - context "when rent_type is London Affordable Rent" do - let(:rent_type) { 2 } + def check_previous_postcode_fields(postcode_field) + record_from_db = described_class.find(address_lettings_log.id) + expect(address_lettings_log[postcode_field]).to eq("M1 1AE") + expect(record_from_db[postcode_field]).to eq("M1 1AE") + end - it "derives the most recent let type as London Affordable Rent basis if it is a renewal and clears it if it is not" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :unitletas).to 5 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :unitletas).from(5).to nil - end - end + context "when saving addresses" 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: {}) + end - context "when rent_type is Rent to Buy" do - let(:rent_type) { 3 } + let!(:address_lettings_log) do + described_class.create({ + managing_organisation: owning_organisation, + owning_organisation:, + assigned_to: assigned_to_user, + postcode_known: 1, + postcode_full: "M1 1AE", + }) + end - it "derives the most recent let type as Rent to Buy basis if it is a renewal and clears it if it is not" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :unitletas).to 6 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :unitletas).from(6).to nil - end - end + def check_property_postcode_fields + check_postcode_fields("postcode_full") + end - context "when rent_type is London Living Rent" do - let(:rent_type) { 4 } + it "correctly formats previous postcode" do + address_lettings_log.update!(postcode_full: "M1 1AE") + check_property_postcode_fields - it "derives the most recent let type as London Living Rent basis if it is a renewal and clears it if it is not" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :unitletas).to 7 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :unitletas).from(7).to nil - end - end + address_lettings_log.update!(postcode_full: "m1 1ae") + check_property_postcode_fields - context "when rent_type is Other intermediate rent product" do - let(:rent_type) { 5 } - let(:irproduct_other) { "Rent first" } + address_lettings_log.update!(postcode_full: "m11Ae") + check_property_postcode_fields - it "derives the most recent let type as Another Intermediate Rent basis if it is a renewal and clears it if it is not" do - expect { lettings_log.update!(renewal: 1) }.to change(lettings_log, :unitletas).to 8 - expect { lettings_log.update!(renewal: 0) }.to change(lettings_log, :unitletas).from(8).to nil - end - end - end + address_lettings_log.update!(postcode_full: "m11ae") + check_property_postcode_fields end - end - context "when updating rent type" do - let(:irproduct_other) { nil } - - before do - lettings_log.update!(rent_type:, irproduct_other:) + it "correctly infers la" do + record_from_db = described_class.find(address_lettings_log.id) + expect(address_lettings_log.la).to eq("E08000003") + expect(record_from_db["la"]).to eq("E08000003") end - context "when rent_type is Social Rent" do - let(:rent_type) { 0 } - - it "derives renttype as Social Rent" do - expect(lettings_log.renttype).to be 1 - end + it "errors if the property postcode is emptied" do + expect { address_lettings_log.update!({ postcode_full: "" }) } + .to raise_error(ActiveRecord::RecordInvalid, /#{I18n.t("validations.postcode")}/) end - context "when rent_type is Affordable Rent" do - let(:rent_type) { 1 } - - it "derives renttype as Affordable Rent" do - expect(lettings_log.renttype).to be 2 - end + it "errors if the property postcode is not valid" do + expect { address_lettings_log.update!({ postcode_full: "invalid_postcode" }) } + .to raise_error(ActiveRecord::RecordInvalid, /#{I18n.t("validations.postcode")}/) end - context "when rent_type is London Affordable Rent" do - let(:rent_type) { 2 } + context "when the local authority lookup times out" do + before do + allow(Timeout).to receive(:timeout).and_raise(Timeout::Error) + end - it "derives renttype as Affordable Rent" do - expect(lettings_log.renttype).to be 2 + it "logs a warning" do + expect(Rails.logger).to receive(:warn).with("Postcodes.io lookup timed out") + address_lettings_log.update!({ postcode_known: 1, postcode_full: "M1 1AD" }) end end - context "when rent_type is Rent to Buy" do - let(:rent_type) { 3 } + it "correctly resets all fields if property postcode not known" do + address_lettings_log.update!({ postcode_known: 0 }) - it "derives renttype as Intermediate Rent" do - expect(lettings_log.renttype).to be 3 - end + record_from_db = described_class.find(address_lettings_log.id) + expect(record_from_db["postcode_full"]).to eq(nil) + expect(address_lettings_log.la).to eq(nil) + expect(record_from_db["la"]).to eq(nil) end - context "when rent_type is London Living Rent" do - let(:rent_type) { 4 } + it "changes the LA if property postcode changes from not known to known and provided" do + address_lettings_log.update!({ postcode_known: 0 }) + address_lettings_log.update!({ la: "E09000033" }) - it "derives renttype as Intermediate Rent" do - expect(lettings_log.renttype).to be 3 - end - end + record_from_db = described_class.find(address_lettings_log.id) + expect(record_from_db["postcode_full"]).to eq(nil) + expect(address_lettings_log.la).to eq("E09000033") + expect(record_from_db["la"]).to eq("E09000033") - context "when rent_type is Other intermediate rent product" do - let(:rent_type) { 5 } - let(:irproduct_other) { "Rent first" } + address_lettings_log.update!({ postcode_known: 1, postcode_full: "M1 1AD" }) - it "derives renttype as Intermediate Rent" do - expect(lettings_log.renttype).to be 3 - end + record_from_db = described_class.find(address_lettings_log.id) + expect(record_from_db["postcode_full"]).to eq("M1 1AD") + expect(address_lettings_log.la).to eq("E08000003") + expect(record_from_db["la"]).to eq("E08000003") end end - context "when answering the household characteristics questions" do - context "and some person details are refused" do - let!(:lettings_log) do - described_class.create({ - managing_organisation: owning_organisation, - owning_organisation:, - assigned_to: assigned_to_user, - age1_known: 1, - sex1: "R", - relat2: "R", - ecstat1: 10, - }) - end + context "when uprn is not confirmed" do + it "clears previous address on renewal logs" do + log = FactoryBot.build(:lettings_log, uprn_known: 1, uprn: 1, uprn_confirmed: 0, renewal: 1, prevloc: "E08000003", ppostcode_full: "A1 1AA", ppcodenk: 0, previous_la_known: 1) - it "correctly derives and saves refused" do - record_from_db = described_class.find(lettings_log.id) - expect(record_from_db["refused"]).to eq(1) - expect(lettings_log["refused"]).to eq(1) - end + expect { log.set_derived_fields! }.to change(log, :prevloc).from("E08000003").to(nil) + .and change(log, :ppostcode_full).from("A1 1AA").to(nil) + .and change(log, :ppcodenk).from(0).to(nil) + .and change(log, :previous_la_known).from(1).to(nil) end - context "and some person details are not known" do - let!(:lettings_log) do - described_class.create({ - managing_organisation: owning_organisation, - owning_organisation:, - assigned_to: assigned_to_user, - details_known_2: 1, - }) - end - - it "correctly derives and saves refused" do - record_from_db = described_class.find(lettings_log.id) - expect(record_from_db["refused"]).to eq(1) - expect(lettings_log["refused"]).to eq(1) - end + it "does not clear previous address on non renewal logs" do + log = FactoryBot.build(:lettings_log, uprn_known: 1, uprn: 1, uprn_confirmed: 0, renewal: 0, prevloc: "E08000003", ppostcode_full: "A1 1AA", ppcodenk: 0, previous_la_known: 1) + log.set_derived_fields! + expect(log.prevloc).to eq("E08000003") + expect(log.ppostcode_full).to eq("A1 1AA") + expect(log.ppcodenk).to eq(0) + expect(log.previous_la_known).to eq(1) end end - context "when it is supported housing and a care home charge has been supplied" do - let!(:lettings_log) do + context "when saving previous address" 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: {}) + end + + let!(:address_lettings_log) do described_class.create({ managing_organisation: owning_organisation, owning_organisation:, assigned_to: assigned_to_user, - needstype: 2, + ppcodenk: 0, + ppostcode_full: "M1 1AE", }) end - context "when the care home charge is paid bi-weekly" do - it "correctly derives and saves weekly care home charge" do - lettings_log.update!(chcharge: 100, period: 2) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(50.0) - expect(record_from_db["wchchrg"]).to eq(50.0) - end - - it "correctly derives floats" do - lettings_log.update!(chcharge: 100.12, period: 2) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(50.06) - expect(record_from_db["wchchrg"]).to eq(50.06) - end - end - - context "when the care home charge is paid every 4 weeks" do - it "correctly derives and saves weekly care home charge" do - lettings_log.update!(chcharge: 120, period: 3) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(30.0) - expect(record_from_db["wchchrg"]).to eq(30.0) - end - - it "correctly derives floats" do - lettings_log.update!(chcharge: 100.12, period: 3) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(25.03) - expect(record_from_db["wchchrg"]).to eq(25.03) - end + def previous_postcode_fields + check_previous_postcode_fields("ppostcode_full") end - context "when the care home charge is paid every calendar month" do - it "correctly derives and saves weekly care home charge" do - lettings_log.update!(chcharge: 130, period: 4) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(30.0) - expect(record_from_db["wchchrg"]).to eq(30.0) - end + it "correctly formats previous postcode" do + address_lettings_log.update!(ppostcode_full: "M1 1AE") + previous_postcode_fields - it "correctly derives floats" do - lettings_log.update!(chcharge: 100.12, period: 4) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(23.10) - expect(record_from_db["wchchrg"]).to eq(23.10) - end - end + address_lettings_log.update!(ppostcode_full: "m1 1ae") + previous_postcode_fields - context "when the care home charge is paid weekly for 50 weeks" do - it "correctly derives and saves weekly care home charge" do - lettings_log.update!(chcharge: 130, period: 5) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(125.0) - expect(record_from_db["wchchrg"]).to eq(125.0) - end + address_lettings_log.update!(ppostcode_full: "m11Ae") + previous_postcode_fields - it "correctly derives floats" do - lettings_log.update!(chcharge: 100.12, period: 5) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(96.27) - expect(record_from_db["wchchrg"]).to eq(96.27) - end + address_lettings_log.update!(ppostcode_full: "m11ae") + previous_postcode_fields end - context "when the care home charge is paid weekly for 49 weeks" do - it "correctly derives and saves weekly care home charge" do - lettings_log.update!(chcharge: 130, period: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(122.5) - expect(record_from_db["wchchrg"]).to eq(122.5) - end - - it "correctly derives floats" do - lettings_log.update!(chcharge: 100.12, period: 6) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(94.34) - expect(record_from_db["wchchrg"]).to eq(94.34) - end + it "correctly infers prevloc" do + record_from_db = described_class.find(address_lettings_log.id) + expect(address_lettings_log.prevloc).to eq("E08000003") + expect(record_from_db["prevloc"]).to eq("E08000003") end - context "when the care home charge is paid weekly for 48 weeks" do - it "correctly derives and saves weekly care home charge" do - lettings_log.update!(chcharge: 130, period: 7) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(120.0) - expect(record_from_db["wchchrg"]).to eq(120.0) - end - - it "correctly derives floats" do - lettings_log.update!(chcharge: 100.12, period: 7) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(92.42) - expect(record_from_db["wchchrg"]).to eq(92.42) - end + it "errors if the previous postcode is emptied" do + expect { address_lettings_log.update!({ ppostcode_full: "" }) } + .to raise_error(ActiveRecord::RecordInvalid, /#{I18n.t("validations.postcode")}/) end - context "when the care home charge is paid weekly for 47 weeks" do - it "correctly derives and saves weekly care home charge" do - lettings_log.update!(chcharge: 130, period: 8) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(117.5) - expect(record_from_db["wchchrg"]).to eq(117.5) - end - - it "correctly derives floats" do - lettings_log.update!(chcharge: 100.12, period: 8) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(90.49) - expect(record_from_db["wchchrg"]).to eq(90.49) - end + it "errors if the previous postcode is not valid" do + expect { address_lettings_log.update!({ ppostcode_full: "invalid_postcode" }) } + .to raise_error(ActiveRecord::RecordInvalid, /#{I18n.t("validations.postcode")}/) end - context "when the care home charge is paid weekly for 46 weeks" do - it "correctly derives and saves weekly care home charge" do - lettings_log.update!(chcharge: 130, period: 9) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(115.0) - expect(record_from_db["wchchrg"]).to eq(115.0) - end + it "correctly resets all fields if previous postcode not known" do + address_lettings_log.update!({ ppcodenk: 1 }) - it "correctly derives floats" do - lettings_log.update!(chcharge: 100.12, period: 9) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(88.57) - expect(record_from_db["wchchrg"]).to eq(88.57) - end + record_from_db = described_class.find(address_lettings_log.id) + expect(record_from_db["ppostcode_full"]).to eq(nil) + expect(address_lettings_log.prevloc).to eq(nil) + expect(record_from_db["prevloc"]).to eq(nil) end - context "when the care home charge is paid weekly for 52 weeks" do - it "correctly derives and saves weekly care home charge" do - lettings_log.update!(chcharge: 130, period: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(130.0) - expect(record_from_db["wchchrg"]).to eq(130.0) - end - - it "correctly derives floats" do - lettings_log.update!(chcharge: 100.12, period: 1) - record_from_db = described_class.find(lettings_log.id) - expect(lettings_log.wchchrg).to eq(100.12) - expect(record_from_db["wchchrg"]).to eq(100.12) - end - end - end + it "correctly resets la if la is not known" do + address_lettings_log.update!({ ppcodenk: 1 }) + address_lettings_log.update!({ previous_la_known: 1, prevloc: "S92000003" }) + record_from_db = described_class.find(address_lettings_log.id) + expect(record_from_db["prevloc"]).to eq("S92000003") + expect(address_lettings_log.prevloc).to eq("S92000003") - context "when the data provider is filling in the reason for the property being vacant" do - let!(:first_let_lettings_log) do - described_class.create({ - managing_organisation: owning_organisation, - owning_organisation:, - assigned_to: assigned_to_user, - first_time_property_let_as_social_housing: 1, - }) + address_lettings_log.update!({ previous_la_known: 0 }) + record_from_db = described_class.find(address_lettings_log.id) + expect(address_lettings_log.prevloc).to eq(nil) + expect(record_from_db["prevloc"]).to eq(nil) end - let!(:relet_lettings_log) do - described_class.create({ - managing_organisation: owning_organisation, - owning_organisation:, - assigned_to: assigned_to_user, - first_time_property_let_as_social_housing: 0, - }) - end + it "changes the prevloc if previous postcode changes from not known to known and provided" do + address_lettings_log.update!({ ppcodenk: 1 }) + address_lettings_log.update!({ previous_la_known: 1, prevloc: "E09000033" }) - it "the newprop variable is correctly derived and saved as 1 for a first let vacancy reason" do - first_let_lettings_log.update!({ rsnvac: 15 }) - record_from_db = described_class.find(first_let_lettings_log.id) - expect(record_from_db["newprop"]).to eq(1) - expect(first_let_lettings_log["newprop"]).to eq(1) - end + record_from_db = described_class.find(address_lettings_log.id) + expect(record_from_db["ppostcode_full"]).to eq(nil) + expect(address_lettings_log.prevloc).to eq("E09000033") + expect(record_from_db["prevloc"]).to eq("E09000033") - it "the newprop variable is correctly derived and saved as 2 for anything that is not a first let vacancy reason" do - relet_lettings_log.update!({ rsnvac: 2 }) - record_from_db = described_class.find(relet_lettings_log.id) - expect(record_from_db["newprop"]).to eq(2) - expect(relet_lettings_log["newprop"]).to eq(2) - end - end + address_lettings_log.update!({ ppcodenk: 0, ppostcode_full: "M1 1AD" }) - context "when a total shortfall is provided" do - it "derives that tshortfall is known" do - lettings_log.update!({ tshortfall: 10 }) - record_from_db = described_class.find(lettings_log.id) - expect(record_from_db["tshortfall_known"]).to eq(0) - expect(lettings_log["tshortfall_known"]).to eq(0) + record_from_db = described_class.find(address_lettings_log.id) + expect(record_from_db["ppostcode_full"]).to eq("M1 1AD") + expect(address_lettings_log.prevloc).to eq("E08000003") + expect(record_from_db["prevloc"]).to eq("E08000003") end end @@ -2201,7 +583,7 @@ RSpec.describe LettingsLog do end before do - stub_request(:get, /api.postcodes.io/) + stub_request(:get, /api\.postcodes\.io/) .to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\",\"codes\":{\"admin_district\": \"E08000003\"}}}", headers: {}) end diff --git a/spec/models/location_spec.rb b/spec/models/location_spec.rb index 3bdc55b44..50dc4b4f4 100644 --- a/spec/models/location_spec.rb +++ b/spec/models/location_spec.rb @@ -9,7 +9,7 @@ RSpec.describe Location, type: :model do let(:location) { FactoryBot.build(:location) } before do - stub_request(:get, /api.postcodes.io/) + 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/) diff --git a/spec/models/organisation_spec.rb b/spec/models/organisation_spec.rb index 5714e80b3..2aa033ccf 100644 --- a/spec/models/organisation_spec.rb +++ b/spec/models/organisation_spec.rb @@ -108,32 +108,63 @@ RSpec.describe Organisation, type: :model do end end - context "when the organisation only uses specific rent periods" do - let(:rent_period_mappings) do - { "2" => { "value" => "Weekly for 52 weeks" }, "3" => { "value" => "Every 2 weeks" } } + context "with associated rent periods" do + let(:organisation) { create(:organisation, skip_rent_period_creation: true) } + let(:period_1_label) { "Every minute" } + let(:fake_rent_periods) do + { + "1" => { "value" => period_1_label }, + "2" => { "value" => "Every decade" }, + } end before do - create(:organisation_rent_period, organisation:, rent_period: 2) - create(:organisation_rent_period, organisation:, rent_period: 3) - - # Unmapped and ignored by `rent_period_labels` - create(:organisation_rent_period, organisation:, rent_period: 10) - allow(RentPeriod).to receive(:rent_period_mappings).and_return(rent_period_mappings) + create(:organisation_rent_period, organisation:, rent_period: 1) + allow(RentPeriod).to receive(:rent_period_mappings).and_return(fake_rent_periods) end - it "has rent periods associated" do - expect(organisation.rent_periods).to eq([2, 3, 10]) - end + context "when the org does not use all rent periods" do + it "#rent_periods returns the correct ids" do + expect(organisation.rent_periods).to eq [1] + end + + it "#rent_period_labels returns the correct labels" do + expect(organisation.rent_period_labels).to eq [period_1_label] + end + + context "and has organisation rent periods associated for rent periods that no longer appear in the form" do + before do + create(:organisation_rent_period, organisation:, rent_period: 3) + end - it "maps the rent periods to display values" do - expect(organisation.rent_period_labels).to eq(["Weekly for 52 weeks", "Every 2 weeks"]) + it "#rent_period_labels returns the correct labels" do + expect(organisation.rent_period_labels).to eq [period_1_label] + end + end end - end - context "when the organisation has not specified which rent periods it uses" do - it "displays `all`" do - expect(organisation.rent_period_labels).to eq(%w[All]) + context "when the org uses all rent periods" do + before do + create(:organisation_rent_period, organisation:, rent_period: 2) + end + + it "#rent_periods returns the correct ids" do + expect(organisation.rent_periods).to eq [1, 2] + end + + it "#rent_period_labels returns All" do + expect(organisation.rent_period_labels).to eq %w[All] + end + + context "and has organisation rent periods associated for rent periods that no longer appear in the form" do + before do + create(:organisation_rent_period, organisation:, rent_period: 3) + end + + it "#rent_period_labels returns All" do + expect(organisation.rent_period_labels).to eq %w[All] + end + end end end diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb index 242fbd9d6..e19aaf94a 100644 --- a/spec/models/sales_log_spec.rb +++ b/spec/models/sales_log_spec.rb @@ -535,7 +535,7 @@ RSpec.describe SalesLog, type: :model do context "when saving addresses" do before do - stub_request(:get, /api.postcodes.io/) + stub_request(:get, /api\.postcodes\.io/) .to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\",\"codes\":{\"admin_district\": \"E08000003\"}}}", headers: {}) end @@ -820,7 +820,7 @@ RSpec.describe SalesLog, type: :model do end before do - stub_request(:get, /api.postcodes.io/) + stub_request(:get, /api\.postcodes\.io/) .to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\", \"codes\":{\"admin_district\": \"E08000003\"}}}", headers: {}) end diff --git a/spec/models/validations/financial_validations_spec.rb b/spec/models/validations/financial_validations_spec.rb index aa2e2e96a..5dd738f0d 100644 --- a/spec/models/validations/financial_validations_spec.rb +++ b/spec/models/validations/financial_validations_spec.rb @@ -139,23 +139,34 @@ RSpec.describe Validations::FinancialValidations do end describe "rent period validations" do - let(:organisation) { FactoryBot.create(:organisation) } - let(:user) { FactoryBot.create(:user) } - let(:record) { FactoryBot.create(:lettings_log, owning_organisation: user.organisation, managing_organisation: organisation, assigned_to: user) } + let(:organisation) { create(:organisation, skip_rent_period_creation: true) } + let(:user) { create(:user, organisation:) } + let(:record) { create(:lettings_log, owning_organisation: organisation, managing_organisation: organisation, assigned_to: user) } + let(:used_period) { 2 } before do - FactoryBot.create(:organisation_relationship, parent_organisation: user.organisation, child_organisation: organisation) - FactoryBot.create(:organisation_rent_period, organisation:, rent_period: 2) + create(:organisation_rent_period, organisation:, rent_period: used_period) + record.period = period end - context "when the organisation only uses specific rent periods" do - it "validates that the selected rent period is used by the managing organisation" do - record.period = 3 + context "when the log uses a period that the org allows" do + let(:period) { used_period } + + it "does not apply a validation" do + financial_validator.validate_rent_period(record) + expect(record.errors["period"]).to be_empty + end + end + + context "when the log uses a period that the org does not allow" do + let(:period) { used_period + 1 } + + it "does apply a validation" do financial_validator.validate_rent_period(record) expect(record.errors["period"]) .to include(match I18n.t( "validations.financial.rent_period.invalid_for_org", - org_name: organisation.name, + org_name: user.organisation.name, rent_period: "every 4 weeks", )) end diff --git a/spec/request_helper.rb b/spec/request_helper.rb index ee38568a7..d7de32b37 100644 --- a/spec/request_helper.rb +++ b/spec/request_helper.rb @@ -3,7 +3,7 @@ require "webmock/rspec" module RequestHelper def self.stub_http_requests WebMock.disable_net_connect!(allow_localhost: true) - WebMock.stub_request(:get, /api.postcodes.io/) + WebMock.stub_request(:get, /api\.postcodes\.io/) .to_return(status: 200, body: "{\"status\":404,\"error\":\"Postcode not found\"}", headers: {}) WebMock.stub_request(:get, "https://api.postcodes.io/postcodes/AA11AA") @@ -14,6 +14,8 @@ module RequestHelper .to_return(status: 200, body: "{\"status\":200,\"result\":{\"postcode\":\"NW1L 5DP\",\"admin_district\":\"Westminster\",\"codes\":{\"admin_district\":\"E09000033\"}}}", headers: {}) WebMock.stub_request(:get, "https://api.postcodes.io/postcodes/ZZ11ZZ") .to_return(status: 200, body: "{\"status\":200,\"result\":{\"postcode\":\"ZZ1 1ZZ\",\"admin_district\":\"Westminster\",\"codes\":{\"admin_district\":\"E09000033\"}}}", headers: {}) + WebMock.stub_request(:get, "https://api.postcodes.io/postcodes/SW1A1AA") + .to_return(status: 200, body: "{\"status\":200,\"result\":{\"postcode\":\"ZZ1 1ZZ\",\"admin_district\":\"Westminster\",\"codes\":{\"admin_district\":\"E09000033\"}}}", headers: {}) WebMock.stub_request(:post, /api.notifications.service.gov.uk\/v2\/notifications\/email/) .to_return(status: 200, body: "", headers: {}) diff --git a/spec/requests/OrganisationsController/organisations_controller_rent_periods_spec.rb b/spec/requests/OrganisationsController/organisations_controller_rent_periods_spec.rb new file mode 100644 index 000000000..390b747b8 --- /dev/null +++ b/spec/requests/OrganisationsController/organisations_controller_rent_periods_spec.rb @@ -0,0 +1,119 @@ +require "rails_helper" + +RSpec.describe OrganisationsController, type: :request do + let(:user) { create(:user, :support) } + let(:headers) { { "Accept" => "text/html" } } + let(:page) { Capybara::Node::Simple.new(response.body) } + + before do + allow(user).to receive(:need_two_factor_authentication?).and_return(false) + sign_in user + end + + describe "#new" do + before do + get new_organisation_path + end + + it "displays the rent periods question" do + expect(page).to have_content "What are the rent periods for the organisation?" + end + + it "the checkboxes for each rent period are checked by default" do + checkboxes = page.all "input[type='checkbox'][name='organisation[rent_periods][]']" + expect(checkboxes.count).to be > 5 + expect(checkboxes.all? { |box| box[:checked] }).to be true + end + end + + describe "#create" do + let(:org_name) { "abode team" } + let(:expected_rent_periods) { [1, 2, 3] } + let(:params) do + { + "organisation": { + name: org_name, + provider_type: "LA", + rent_periods: expected_rent_periods, + }, + } + end + + before do + post organisations_path headers:, params: + end + + it "creates organisation rent periods with the correct rent period and organisation id" do + org = Organisation.includes(:organisation_rent_periods).find_by_name(org_name) + org_rent_periods = org.organisation_rent_periods + expect(org_rent_periods.count).to be expected_rent_periods.count + expect(org_rent_periods.map(&:rent_period)).to match_array expected_rent_periods + expect(org_rent_periods.map(&:organisation_id)).to all be org.id + end + end + + describe "#edit" do + let(:organisation) { create(:organisation, skip_rent_period_creation: true) } + let(:fake_rent_periods) do + { + "1" => { "value" => "Every minute" }, + "2" => { "value" => "Every decade" }, + } + end + let(:checked_rent_period_id) { "1" } + + before do + allow(RentPeriod).to receive(:rent_period_mappings).and_return fake_rent_periods + create(:organisation_rent_period, organisation:, rent_period: checked_rent_period_id) + get edit_organisation_path organisation + end + + it "displays the rent periods question" do + expect(page).to have_content "What are the rent periods for the organisation?" + end + + it "the checkboxes for each rent period are checked where appropriate" do + checkboxes = page.all "input[type='checkbox']" + expect(checkboxes.count).to be 2 + expected_checked_checkbox = checkboxes.find { |cb| cb[:value] == checked_rent_period_id } + expect(expected_checked_checkbox[:checked]).to be true + expected_not_checked_checkbox = checkboxes.find { |cb| cb[:value] != checked_rent_period_id } + expect(expected_not_checked_checkbox[:checked]).to be false + end + end + + describe "#update" do + let(:organisation) { create(:organisation, skip_rent_period_creation: true) } + let(:initially_checked_rent_period_id) { "1" } + let(:initially_unchecked_rent_period_id) { "2" } + let(:params) do + { + "organisation": { + name: organisation.name, + rent_periods: [initially_unchecked_rent_period_id], + all_rent_periods: [initially_unchecked_rent_period_id, initially_checked_rent_period_id], + }, + } + end + + before do + create(:organisation_rent_period, organisation:, rent_period: initially_checked_rent_period_id) + end + + it "creates and destroys organisation rent periods as appropriate" do + rent_periods = Organisation.includes(:organisation_rent_periods) + .find(organisation.id) + .organisation_rent_periods + expect(rent_periods.count).to be 1 + expect(rent_periods.first.rent_period.to_s).to eq initially_checked_rent_period_id + + patch organisation_path(organisation, headers:, params:) + + rent_periods = Organisation.includes(:organisation_rent_periods) + .find(organisation.id) + .organisation_rent_periods + expect(rent_periods.count).to be 1 + expect(rent_periods.first.rent_period.to_s).to eq initially_unchecked_rent_period_id + end + end +end diff --git a/spec/requests/lettings_logs_controller_spec.rb b/spec/requests/lettings_logs_controller_spec.rb index 20aa085f3..725a8486d 100644 --- a/spec/requests/lettings_logs_controller_spec.rb +++ b/spec/requests/lettings_logs_controller_spec.rb @@ -1319,7 +1319,7 @@ RSpec.describe LettingsLogsController, type: :request do Singleton.__init__(FormHandler) 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/) + 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 diff --git a/spec/requests/organisations_controller_spec.rb b/spec/requests/organisations_controller_spec.rb index bed20ae15..1b236f8fc 100644 --- a/spec/requests/organisations_controller_spec.rb +++ b/spec/requests/organisations_controller_spec.rb @@ -7,7 +7,8 @@ RSpec.describe OrganisationsController, type: :request do let(:page) { Capybara::Node::Simple.new(response.body) } let(:user) { create(:user, :data_coordinator) } let(:new_value) { "Test Name 35" } - let(:params) { { id: organisation.id, organisation: { name: new_value } } } + let(:active) { nil } + let(:params) { { id: organisation.id, organisation: { name: new_value, active:, rent_periods: [], all_rent_periods: [] } } } before do Timecop.freeze(Time.zone.local(2024, 3, 1)) @@ -581,12 +582,7 @@ RSpec.describe OrganisationsController, type: :request do end context "with active parameter true" do - let(:params) do - { - id: organisation.id, - organisation: { active: "true" }, - } - end + let(:active) { true } it "redirects" do expect(response).to have_http_status(:unauthorized) @@ -594,12 +590,7 @@ RSpec.describe OrganisationsController, type: :request do end context "with active parameter false" do - let(:params) do - { - id: organisation.id, - organisation: { active: "false" }, - } - end + let(:active) { false } it "redirects" do expect(response).to have_http_status(:unauthorized) @@ -705,6 +696,7 @@ RSpec.describe OrganisationsController, type: :request do provider_type: "LA", holds_own_stock: "true", housing_registration_no: "7917937", + rent_periods: [], }, } end @@ -1329,7 +1321,7 @@ RSpec.describe OrganisationsController, type: :request do end it "allows to edit the organisation details" do - expect(page).to have_link("Change", count: 3) + expect(page).to have_link("Change") end end @@ -1434,8 +1426,10 @@ RSpec.describe OrganisationsController, type: :request do end describe "#update" do + let(:params) { { id: organisation.id, organisation: { active:, rent_periods: [], all_rent_periods: [] } } } + context "with active parameter false" do - let(:params) { { id: organisation.id, organisation: { active: "false" } } } + let(:active) { false } user_to_update = nil @@ -1455,15 +1449,9 @@ RSpec.describe OrganisationsController, type: :request do user_to_reactivate = nil user_not_to_reactivate = nil - let(:params) do - { - id: organisation.id, - organisation: { active: "true" }, - } - end let(:notify_client) { instance_double(Notifications::Client) } let(:devise_notify_mailer) { DeviseNotifyMailer.new } - + let(:active) { true } let(:expected_personalisation) do { name: user_to_reactivate.name, @@ -1547,6 +1535,7 @@ RSpec.describe OrganisationsController, type: :request do provider_type:, holds_own_stock:, housing_registration_no:, + rent_periods: [], }, } end @@ -1569,7 +1558,8 @@ RSpec.describe OrganisationsController, type: :request do it "redirects to the organisation list" do request - expect(response).to redirect_to("/organisations") + organisation = Organisation.find_by(housing_registration_no:) + expect(response).to redirect_to organisation_path(organisation) end context "when required params are missing" do diff --git a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb index 0c394b9c0..01de24879 100644 --- a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb +++ b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb @@ -84,7 +84,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do describe "validations" do before do - stub_request(:get, /api.postcodes.io/) + stub_request(:get, /api\.postcodes\.io/) .to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\", \"codes\":{\"admin_district\": \"E08000003\"}}}", headers: {}) parser.valid? diff --git a/spec/services/bulk_upload/sales/year2023/row_parser_spec.rb b/spec/services/bulk_upload/sales/year2023/row_parser_spec.rb index 02131381f..1a4f0375e 100644 --- a/spec/services/bulk_upload/sales/year2023/row_parser_spec.rb +++ b/spec/services/bulk_upload/sales/year2023/row_parser_spec.rb @@ -232,7 +232,7 @@ RSpec.describe BulkUpload::Sales::Year2023::RowParser do describe "validations" do before do - stub_request(:get, /api.postcodes.io/) + stub_request(:get, /api\.postcodes\.io/) .to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\", \"codes\":{\"admin_district\": \"E08000003\"}}}", headers: {}) parser.valid? diff --git a/spec/services/csv/sales_log_csv_service_spec.rb b/spec/services/csv/sales_log_csv_service_spec.rb index 9c6176afd..7f6ad8c2a 100644 --- a/spec/services/csv/sales_log_csv_service_spec.rb +++ b/spec/services/csv/sales_log_csv_service_spec.rb @@ -160,13 +160,13 @@ RSpec.describe Csv::SalesLogCsvService do it "exports the code for the local authority under the heading 'la'" do la_column_index = csv.first.index("LA") la_value = csv.second[la_column_index] - expect(la_value).to eq "E09000003" + expect(la_value).to eq "E09000033" end it "exports the label for the local authority under the heading 'la_label'" do la_label_column_index = csv.first.index("LANAME") la_label_value = csv.second[la_label_column_index] - expect(la_label_value).to eq "Barnet" + expect(la_label_value).to eq "Westminster" end context "when the requested form is 2024" do @@ -246,13 +246,13 @@ RSpec.describe Csv::SalesLogCsvService do it "exports the code for the local authority under the heading 'la'" do la_column_index = csv.first.index("LA") la_value = csv.second[la_column_index] - expect(la_value).to eq "E09000003" + expect(la_value).to eq "E09000033" end it "exports the label for the local authority under the heading 'la_label'" do la_label_column_index = csv.first.index("LANAME") la_label_value = csv.second[la_label_column_index] - expect(la_label_value).to eq "Barnet" + expect(la_label_value).to eq "Westminster" end context "when the requested form is 2024" do diff --git a/spec/services/merge/merge_organisations_service_spec.rb b/spec/services/merge/merge_organisations_service_spec.rb index 59b34e525..5c582a95f 100644 --- a/spec/services/merge/merge_organisations_service_spec.rb +++ b/spec/services/merge/merge_organisations_service_spec.rb @@ -75,6 +75,9 @@ RSpec.describe Merge::MergeOrganisationsService do end context "and merging organisation rent periods" do + let(:absorbing_organisation) { create(:organisation, holds_own_stock: false, name: "absorbing org", skip_rent_period_creation: true) } + let(:merging_organisation) { create(:organisation, holds_own_stock: true, name: "fake org", skip_rent_period_creation: true) } + before do OrganisationRentPeriod.create!(organisation: absorbing_organisation, rent_period: 1) OrganisationRentPeriod.create!(organisation: absorbing_organisation, rent_period: 3) @@ -1157,6 +1160,9 @@ RSpec.describe Merge::MergeOrganisationsService do end context "and merging organisation rent periods" do + let(:new_absorbing_organisation) { create(:organisation, :without_dpc, holds_own_stock: false, skip_rent_period_creation: true) } + let(:merging_organisation) { create(:organisation, holds_own_stock: true, name: "fake org", skip_rent_period_creation: true) } + before do OrganisationRentPeriod.create!(organisation: new_absorbing_organisation, rent_period: 1) OrganisationRentPeriod.create!(organisation: new_absorbing_organisation, rent_period: 3) diff --git a/spec/views/organisations/show.html.erb_spec.rb b/spec/views/organisations/show.html.erb_spec.rb index de4996c36..4314360dc 100644 --- a/spec/views/organisations/show.html.erb_spec.rb +++ b/spec/views/organisations/show.html.erb_spec.rb @@ -2,15 +2,10 @@ require "rails_helper" RSpec.describe "organisations/show.html.erb" do before do - Timecop.freeze(Time.zone.local(2023, 1, 10)) allow(view).to receive(:current_user).and_return(user) assign(:organisation, user.organisation) end - after do - Timecop.return - end - let(:fragment) { Capybara::Node::Simple.new(rendered) } let(:organisation_without_dpc) { create(:organisation, :without_dpc) } let(:organisation_with_dsa) { create(:organisation) }