diff --git a/app/helpers/money_formatting_helper.rb b/app/helpers/money_formatting_helper.rb new file mode 100644 index 000000000..246d910fe --- /dev/null +++ b/app/helpers/money_formatting_helper.rb @@ -0,0 +1,23 @@ +module MoneyFormattingHelper + include ActionView::Helpers::NumberHelper + + def format_money_input(log:, question:) + value = log[question.id] + + return unless value + return value unless question.prefix == "£" + + number_with_precision( + value, + precision: 2, + ) + end + + def format_as_currency(num_string) + number_to_currency( + num_string, + unit: "£", + precision: 2, + ) + end +end diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index 281ab5ab2..df5ac5c30 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -20,6 +20,7 @@ class LettingsLog < Log include DerivedVariables::LettingsLogVariables include Validations::DateValidations include Validations::FinancialValidations + include MoneyFormattingHelper has_paper_trail @@ -149,7 +150,7 @@ class LettingsLog < Log def weekly_to_value_per_period(field_value) num_of_weeks = NUM_OF_WEEKS_FROM_PERIOD[period] - sprintf("%.2f", (field_value * 52) / num_of_weeks) + format_as_currency((field_value * 52) / num_of_weeks) end def applicable_income_range @@ -650,7 +651,7 @@ private num_of_weeks = NUM_OF_WEEKS_FROM_PERIOD[period] return "" unless value && num_of_weeks - sprintf("%.2f", (value * 52 / num_of_weeks)) + format_as_currency((value * 52 / num_of_weeks)) end def fully_wheelchair_accessible? diff --git a/app/models/log.rb b/app/models/log.rb index 407ec2746..fc1a3a4d7 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -201,8 +201,4 @@ private self[is_inferred_key] = false self[postcode_key] = nil end - - def format_as_currency(num_string) - ActionController::Base.helpers.number_to_currency(num_string, unit: "£") - end end diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index a5de0d0f7..5c6d306da 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -18,6 +18,7 @@ class SalesLog < Log include DerivedVariables::SalesLogVariables include Validations::Sales::SoftValidations include Validations::SoftValidations + include MoneyFormattingHelper self.inheritance_column = :_type_disabled @@ -223,7 +224,7 @@ class SalesLog < Log def expected_shared_ownership_deposit_value return unless value && equity - sprintf("%.2f", (value * equity / 100)) + format_as_currency(value * equity / 100) end def process_postcode(postcode, postcode_known_key, la_inferred_key, la_key) diff --git a/app/models/validations/financial_validations.rb b/app/models/validations/financial_validations.rb index 5fba288bb..db80b6bb7 100644 --- a/app/models/validations/financial_validations.rb +++ b/app/models/validations/financial_validations.rb @@ -120,10 +120,10 @@ module Validations::FinancialValidations elsif !weekly_value_in_range(record, "chcharge", 10, 1000) max_chcharge = record.weekly_to_value_per_period(1000) min_chcharge = record.weekly_to_value_per_period(10) - max_chcharge = [record.form.get_question("chcharge", record).prefix, max_chcharge].join("") if record.form.get_question("chcharge", record).present? - min_chcharge = [record.form.get_question("chcharge", record).prefix, min_chcharge].join("") if record.form.get_question("chcharge", record).present? - record.errors.add :period, I18n.t("validations.financial.carehome.out_of_range", period:, min_chcharge:, max_chcharge:) - record.errors.add :chcharge, :out_of_range, message: I18n.t("validations.financial.carehome.out_of_range", period:, min_chcharge:, max_chcharge:) + message = I18n.t("validations.financial.carehome.out_of_range", period:, min_chcharge:, max_chcharge:) + + record.errors.add :period, message + record.errors.add :chcharge, :out_of_range, message: message end end end diff --git a/app/views/form/_numeric_output_question.html.erb b/app/views/form/_numeric_output_question.html.erb index 8892523aa..7d681f7ea 100644 --- a/app/views/form/_numeric_output_question.html.erb +++ b/app/views/form/_numeric_output_question.html.erb @@ -16,7 +16,8 @@ type="number" name="lettings_log[tcharge]" for="<%= question.fields_added.present? ? question.fields_added.map { |x| "lettings-log-#{x}-field" }.join(" ") : "" %>"> - <%= lettings_log[question.id] %> + <%= format_money_input(log: lettings_log, question:) %> + <%= question.suffix_label(lettings_log) %> diff --git a/app/views/form/_numeric_question.html.erb b/app/views/form/_numeric_question.html.erb index 0aeb63801..b92d0f736 100644 --- a/app/views/form/_numeric_question.html.erb +++ b/app/views/form/_numeric_question.html.erb @@ -1,14 +1,19 @@ <%= render partial: "form/guidance/#{question.guidance_partial}" if question.top_guidance? %> -<%= f.govuk_number_field question.id.to_sym, +<%= f.govuk_number_field( + question.id.to_sym, caption: caption(caption_text, page_header, conditional), label: legend(question, page_header, conditional), hint: { text: question.hint_text&.html_safe }, - min: question.min, max: question.max, step: question.step, + min: question.min, + max: question.max, + step: question.step, width: question.width, readonly: question.read_only?, prefix_text: question.prefix.to_s, suffix_text: question.suffix_label(@log), - **stimulus_html_attributes(question) %> + value: format_money_input(log: @log, question:), + **stimulus_html_attributes(question), +) %> <%= render partial: "form/guidance/#{question.guidance_partial}" if question.bottom_guidance? %> diff --git a/spec/helpers/money_formatting_helper_spec.rb b/spec/helpers/money_formatting_helper_spec.rb new file mode 100644 index 000000000..cd16ea86c --- /dev/null +++ b/spec/helpers/money_formatting_helper_spec.rb @@ -0,0 +1,41 @@ +require "rails_helper" + +RSpec.describe MoneyFormattingHelper do + describe "#format_money_input" do + let!(:log) { create(:lettings_log, :completed, brent: 1000) } + let(:question) { instance_double(Form::Question, id: "brent", prefix:) } + + context "with £ prefix" do + let(:prefix) { "£" } + + it "returns formatted input" do + expect(format_money_input(log:, question:)).to eq("1000.00") + end + end + + context "with other prefix" do + let(:prefix) { "other" } + + it "does not format the input" do + expect(format_money_input(log:, question:)).to eq(BigDecimal(1000)) + end + end + + context "without prefix" do + let(:prefix) { nil } + + it "does not format the input" do + expect(format_money_input(log:, question:)).to eq(BigDecimal(1000)) + end + end + + context "when value is nil" do + let(:prefix) { "£" } + let(:log) { create(:lettings_log, brent: nil) } + + it "does not format the input" do + expect(format_money_input(log:, question:)).to be_nil + end + end + end +end diff --git a/spec/models/lettings_log_spec.rb b/spec/models/lettings_log_spec.rb index 1ee3cf2ba..c8f680c1c 100644 --- a/spec/models/lettings_log_spec.rb +++ b/spec/models/lettings_log_spec.rb @@ -2605,24 +2605,24 @@ RSpec.describe LettingsLog do context "when period is weekly for 52 weeks" do it "returns weekly soft min for 52 weeks" do lettings_log.period = 1 - expect(lettings_log.soft_min_for_period).to eq("100.00 every week") + expect(lettings_log.soft_min_for_period).to eq("£100.00 every week") end it "returns weekly soft max for 52 weeks" do lettings_log.period = 1 - expect(lettings_log.soft_max_for_period).to eq("400.00 every week") + expect(lettings_log.soft_max_for_period).to eq("£400.00 every week") end end context "when period is weekly for 47 weeks" do it "returns weekly soft min for 47 weeks" do lettings_log.period = 8 - expect(lettings_log.soft_min_for_period).to eq("110.64 every week") + expect(lettings_log.soft_min_for_period).to eq("£110.64 every week") end it "returns weekly soft max for 47 weeks" do lettings_log.period = 8 - expect(lettings_log.soft_max_for_period).to eq("442.55 every week") + expect(lettings_log.soft_max_for_period).to eq("£442.55 every week") end end end diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb index 150656fd2..9b3a60bf3 100644 --- a/spec/models/sales_log_spec.rb +++ b/spec/models/sales_log_spec.rb @@ -498,7 +498,7 @@ RSpec.describe SalesLog, type: :model do let!(:completed_sales_log) { create(:sales_log, :completed, ownershipsch: 1, type: 2, value: 1000, equity: 50) } it "is set to completed for a completed sales log" do - expect(completed_sales_log.expected_shared_ownership_deposit_value).to eq("500.00") + expect(completed_sales_log.expected_shared_ownership_deposit_value).to eq("£500.00") end end diff --git a/spec/models/validations/financial_validations_spec.rb b/spec/models/validations/financial_validations_spec.rb index 0ae131ad3..ab7fd1693 100644 --- a/spec/models/validations/financial_validations_spec.rb +++ b/spec/models/validations/financial_validations_spec.rb @@ -913,15 +913,15 @@ RSpec.describe Validations::FinancialValidations do record.is_carehome = 1 end - context "and charges are over the valid limit (£1000 per week)" do + context "and charges are over the valid limit (£1,000 per week)" do it "validates charge when period is weekly for 52 weeks" do record.period = 1 record.chcharge = 1001 financial_validator.validate_care_home_charges(record) expect(record.errors["chcharge"]) - .to include("Household rent and other charges must be between 10.00 and 1000.00 if paying weekly for 52 weeks") + .to include("Household rent and other charges must be between £10.00 and £1,000.00 if paying weekly for 52 weeks") expect(record.errors["period"]) - .to include("Household rent and other charges must be between 10.00 and 1000.00 if paying weekly for 52 weeks") + .to include("Household rent and other charges must be between £10.00 and £1,000.00 if paying weekly for 52 weeks") end it "validates charge when period is monthly" do @@ -929,9 +929,9 @@ RSpec.describe Validations::FinancialValidations do record.chcharge = 4334 financial_validator.validate_care_home_charges(record) expect(record.errors["chcharge"]) - .to include("Household rent and other charges must be between 43.00 and 4333.00 if paying every calendar month") + .to include("Household rent and other charges must be between £43.00 and £4,333.00 if paying every calendar month") expect(record.errors["period"]) - .to include("Household rent and other charges must be between 43.00 and 4333.00 if paying every calendar month") + .to include("Household rent and other charges must be between £43.00 and £4,333.00 if paying every calendar month") end it "validates charge when period is every 2 weeks" do @@ -939,9 +939,9 @@ RSpec.describe Validations::FinancialValidations do record.chcharge = 2001 financial_validator.validate_care_home_charges(record) expect(record.errors["chcharge"]) - .to include("Household rent and other charges must be between 20.00 and 2000.00 if paying every 2 weeks") + .to include("Household rent and other charges must be between £20.00 and £2,000.00 if paying every 2 weeks") expect(record.errors["period"]) - .to include("Household rent and other charges must be between 20.00 and 2000.00 if paying every 2 weeks") + .to include("Household rent and other charges must be between £20.00 and £2,000.00 if paying every 2 weeks") end it "validates charge when period is every 4 weeks" do @@ -949,13 +949,13 @@ RSpec.describe Validations::FinancialValidations do record.chcharge = 4001 financial_validator.validate_care_home_charges(record) expect(record.errors["chcharge"]) - .to include("Household rent and other charges must be between 40.00 and 4000.00 if paying every 4 weeks") + .to include("Household rent and other charges must be between £40.00 and £4,000.00 if paying every 4 weeks") expect(record.errors["period"]) - .to include("Household rent and other charges must be between 40.00 and 4000.00 if paying every 4 weeks") + .to include("Household rent and other charges must be between £40.00 and £4,000.00 if paying every 4 weeks") end end - context "and charges are within the valid limit (£1000 per week)" do + context "and charges are within the valid limit (£1,000 per week)" do it "does not throw error when period is weekly for 52 weeks" do record.period = 1 record.chcharge = 999 @@ -1007,9 +1007,9 @@ RSpec.describe Validations::FinancialValidations do record.chcharge = 9 financial_validator.validate_care_home_charges(record) expect(record.errors["chcharge"]) - .to include("Household rent and other charges must be between 10.00 and 1000.00 if paying weekly for 52 weeks") + .to include("Household rent and other charges must be between £10.00 and £1,000.00 if paying weekly for 52 weeks") expect(record.errors["period"]) - .to include("Household rent and other charges must be between 10.00 and 1000.00 if paying weekly for 52 weeks") + .to include("Household rent and other charges must be between £10.00 and £1,000.00 if paying weekly for 52 weeks") end it "validates charge when period is monthly" do @@ -1017,9 +1017,9 @@ RSpec.describe Validations::FinancialValidations do record.chcharge = 42 financial_validator.validate_care_home_charges(record) expect(record.errors["chcharge"]) - .to include("Household rent and other charges must be between 43.00 and 4333.00 if paying every calendar month") + .to include("Household rent and other charges must be between £43.00 and £4,333.00 if paying every calendar month") expect(record.errors["period"]) - .to include("Household rent and other charges must be between 43.00 and 4333.00 if paying every calendar month") + .to include("Household rent and other charges must be between £43.00 and £4,333.00 if paying every calendar month") end it "validates charge when period is every 2 weeks" do @@ -1027,9 +1027,9 @@ RSpec.describe Validations::FinancialValidations do record.chcharge = 19 financial_validator.validate_care_home_charges(record) expect(record.errors["chcharge"]) - .to include("Household rent and other charges must be between 20.00 and 2000.00 if paying every 2 weeks") + .to include("Household rent and other charges must be between £20.00 and £2,000.00 if paying every 2 weeks") expect(record.errors["period"]) - .to include("Household rent and other charges must be between 20.00 and 2000.00 if paying every 2 weeks") + .to include("Household rent and other charges must be between £20.00 and £2,000.00 if paying every 2 weeks") end it "validates charge when period is every 4 weeks" do @@ -1037,9 +1037,9 @@ RSpec.describe Validations::FinancialValidations do record.chcharge = 39 financial_validator.validate_care_home_charges(record) expect(record.errors["chcharge"]) - .to include("Household rent and other charges must be between 40.00 and 4000.00 if paying every 4 weeks") + .to include("Household rent and other charges must be between £40.00 and £4,000.00 if paying every 4 weeks") expect(record.errors["period"]) - .to include("Household rent and other charges must be between 40.00 and 4000.00 if paying every 4 weeks") + .to include("Household rent and other charges must be between £40.00 and £4,000.00 if paying every 4 weeks") end end end diff --git a/spec/services/imports/lettings_logs_import_service_spec.rb b/spec/services/imports/lettings_logs_import_service_spec.rb index d89468164..475bca6bf 100644 --- a/spec/services/imports/lettings_logs_import_service_spec.rb +++ b/spec/services/imports/lettings_logs_import_service_spec.rb @@ -762,7 +762,7 @@ RSpec.describe Imports::LettingsLogsImportService do end it "intercepts the relevant validation error" do - expect(logger).to receive(:warn).with(/Removing chcharge with error: Household rent and other charges must be between £10.00 and £1000.00 if paying weekly for 52 weeks/) + expect(logger).to receive(:warn).with(/Removing chcharge with error: Household rent and other charges must be between £10.00 and £1,000.00 if paying weekly for 52 weeks/) expect { lettings_log_service.send(:create_log, lettings_log_xml) } .not_to raise_error end