Updating Interest Rates
From time to time our interest rates change, either the prime or minus prime rate will need to be adjusted.
We usually know about interest rate changes ahead of time however a bit of trial and error might be required to establish the exact rates and the effective date.
When rates change #banking-info will send a error message from the banking service:
Note the UUID at the top of this message as this will be used when drawing a interest rate report later.
Step 1: View existing rates
Open up Rails console in the banking service and list the current interest rate table:
irb(main):001:0> puts InterestRate.all.map {|ir| [ir.effective_at, ir.category, ir.prime.to_s, ir.prime_minus.to_s]}.to_table
table
InterestRate Load (0.7ms) SELECT "interest_rates".* FROM "interest_rates" ORDER BY effective_at ASC
+---------------------------+---------------+------+------+
| 2020-01-17 00:00:00 +0200 | rentalconnect | 9.75 | 3.9 |
| 2020-01-17 00:00:00 +0200 | reos | 9.75 | 4.84 |
| 2020-03-20 00:00:00 +0200 | rentalconnect | 8.75 | 3.9 |
| 2020-03-20 00:00:00 +0200 | reos | 8.75 | 4.84 |
| 2020-04-15 00:00:00 +0200 | reos | 7.75 | 4.84 |
| 2020-04-15 00:00:00 +0200 | rentalconnect | 7.75 | 3.9 |
| 2020-05-22 00:00:00 +0200 | rentalconnect | 7.25 | 3.9 |
| 2020-05-22 00:00:00 +0200 | reos | 7.25 | 4.84 |
| 2020-06-01 00:00:00 +0200 | reos | 7.25 | 3.4 |
| 2021-11-19 00:00:00 +0200 | reos | 7.25 | 3.27 |
+---------------------------+---------------+------+------+
Step 2: Check ABSA's prime rate table
ABSA Indices and Rates in this example the latest rate is 7.5 which took effect on 2022/01/28 sometimes it's a day earlier then what is reported in this table.
Step 3: Create the Interest Rate record with the updated rates
In the Rails console:
irb(main):001:0> InterestRate.create(prime: BigDecimal("7.5"), prime_minus: BigDecimal("3.27"), category: :reos, effective_at: "2022-01-26".to_date)
(0.5ms) BEGIN
SQL (32.7ms) INSERT INTO "interest_rates" ("prime", "prime_minus", "effective_at") VALUES ($1, $2, $3) RETURNING "id" [["prime", "7.5"], ["prime_minus", "3.27"], ["effective_at", "2022-01-25 22:00:00"]]
(1.5ms) COMMIT
=> #<InterestRate id: "f7b026a2-c00c-4015-9ddb-457a62c9a14e", prime: #<BigDecimal:558899546f38,'0.75E1',18(27)>, prime_minus: #<BigDecimal:558899546e70,'0.327E1',18(27)>, category: "reos", effective_at: "2022-01-25 22:00:00">
Step 4: Generate Interest Report
Using the UUID in the Slack message search for the related Event record, then fetch the Detail Record relating to that event and generate a interest report.
irb(main):001:0> event = Event.find("98ac8571-7822-4e82-bdea-1c88d4cb6a44")
irb(main):002:0> record = DetailRecord.find(event.event_id)
irb(main):003:0> InterestRate.report(record, :reos)
{:rates=>{"2021-11-19"=>{:annual=>"3.98", :daily=>"0.00010904109589041095890410959", :annual_admin_fee=>"1.0", :daily_fee=>"0.0000273972602739726"}, "2022-01-26"=>{:annual=>"4.23", :daily=>"0.0001158904109589041095890411", :annual_admin_fee=>"2.0", :daily_fee=>"0.00005479452054794521"}}, :interest=>5372153, :calculated=>{:interest=>5416327, :difference=>44174}}
The calculated difference should be zero if not adjust the new rates table record and retry the report.
irb(main):001:0> rate = InterestRate.last # verify that this record is the one you added!
irb(main):002:0> rate.effective_at
=> Wed, 26 Jan 2022 00:00:00 SAST +02:00
irb(main):003:0> rate.effective_at = "2022-01-27".to_date
=> Thu, 27 Jan 2022
irb(main):004:0> rate.save!
(0.4ms) BEGIN
SQL (1.2ms) UPDATE "interest_rates" SET "effective_at" = $1 WHERE "interest_rates"."id" = $2 [["effective_at", "2022-01-26 22:00:00"], ["id", "f7b026a2-c00c-4015-9ddb-457a62c9a14e"]]
(1.3ms) COMMIT
=> true
In this example our rates turn out to be effective at 2022-01-28, prime was 7.5 and prime minus was 3.39.
{:rates=>{"2021-11-19"=>{:annual=>"3.98", :daily=>"0.00010904109589041095890410959", :annual_admin_fee=>"1.0", :daily_fee=>"0.0000273972602739726"}, "2022-01-28"=>{:annual=>"4.11", :daily=>"0.00011260273972602739726027397", :annual_admin_fee=>"2.0", :daily_fee=>"0.00005479452054794521"}}, :interest=>5372153, :calculated=>{:interest=>5372153, :difference=>0}}
Step 5: Replay the event for wallet service
Now that the rates are correct the interest allocation can take place in the wallet service. To replay the allocation message update the Event record's created_at
timestamp to now and wait for the listener. In the Rails console:
irb(main):001:0> event = Event.find("98ac8571-7822-4e82-bdea-1c88d4cb6a44")
irb(main):002:0> event.created_at = Time.now
irb(main):003:0> event.save!