diff --git a/CHANGELOG.md b/CHANGELOG.md index 3498a73e1..63f83d096 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ [Full changelog][unreleased] - Display the budgets headings as "Activity budgets" for level C and D activities on the Financials tab +- model a financial value from a csv file ## Release 141 - 2023-12-04 diff --git a/app/models/import/csv/financial.rb b/app/models/import/csv/financial.rb new file mode 100644 index 000000000..edf331c75 --- /dev/null +++ b/app/models/import/csv/financial.rb @@ -0,0 +1,19 @@ +class Import::Csv::Financial + attr_reader :decimal_value, :original_value + + def initialize(value) + @decimal_value = convert_to_decimal(value.to_s) + @original_value = value.to_s + end + + private def convert_to_decimal(value) + return BigDecimal("0") if value.blank? + + begin + converted_value = ConvertFinancialValue.new.convert(value) + rescue ConvertFinancialValue::Error + return nil + end + converted_value + end +end diff --git a/spec/models/import/csv/financial_spec.rb b/spec/models/import/csv/financial_spec.rb new file mode 100644 index 000000000..4db7aeb8a --- /dev/null +++ b/spec/models/import/csv/financial_spec.rb @@ -0,0 +1,106 @@ +require "rails_helper" + +RSpec.describe Import::Csv::Financial do + describe "#value" do + context "when the value is positive number" do + it "returns a BigDecimal of the number" do + csv_value = "1000.0" + finance_value = described_class.new(csv_value) + + expect(finance_value.decimal_value).to eql BigDecimal("1_000") + end + end + + context "when the value is negative number" do + it "returns a BigDecimal of the number" do + csv_value = "-1000.0" + finance_value = described_class.new(csv_value) + + expect(finance_value.decimal_value).to eql BigDecimal("-1_000") + end + end + + context "when the value is zero" do + it "returns a BigDecimal of zero" do + csv_value = "0.0" + finance_value = described_class.new(csv_value) + + expect(finance_value.decimal_value).to eql BigDecimal("0") + end + end + + context "when the value has financial punctuation" do + it "returns a BigDecimal of the number" do + csv_value = "£1,000,000,000.0" + finance_value = described_class.new(csv_value) + + expect(finance_value.decimal_value).to eql BigDecimal("1_000_000_000") + end + end + + context "when the value is space" do + it "returns a BigDecimal of zero" do + csv_value = " " + finance_value = described_class.new(csv_value) + + expect(finance_value.decimal_value).to eql BigDecimal("0") + end + end + + context "when the value is multiple spaces" do + it "returns a BigDecimal of zero" do + csv_value = " " + finance_value = described_class.new(csv_value) + + expect(finance_value.decimal_value).to eql BigDecimal("0") + end + end + + context "when the value is nil" do + it "returns a BigDecimal of zero" do + csv_value = nil + finance_value = described_class.new(csv_value) + + expect(finance_value.decimal_value).to eql BigDecimal("0") + end + end + + context "when the value is empty" do + it "returns a BigDecimal of zero" do + csv_value = "" + finance_value = described_class.new(csv_value) + + expect(finance_value.decimal_value).to eql BigDecimal("0") + end + end + + context "when the value cannot be converted" do + it "returns nil" do + csv_value = "this cannot be converted" + finance_value = described_class.new(csv_value) + + expect(finance_value.decimal_value).to be_nil + end + end + end + + describe "#original_value" do + context "when the conversion can take place" do + it "returns the original string from the csv cell" do + csv_value = "1000.0" + finance_value = described_class.new(csv_value) + + expect(finance_value.original_value).to eql csv_value + end + end + + context "when the conversion cannot take place" do + it "returns the original string from the csv cell" do + csv_value = "ten thousand pounds" + finance_value = described_class.new(csv_value) + + expect(finance_value.original_value).to eql csv_value + end + end + end +end