Skip to content

Commit

Permalink
move original final payment day to pro-rata
Browse files Browse the repository at this point in the history
  • Loading branch information
simontreanor committed Apr 23, 2024
1 parent 2155bad commit c7f0a75
Showing 12 changed files with 115 additions and 99 deletions.
2 changes: 1 addition & 1 deletion docs/exampleAmortisation.fsx
Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ let scheduleParameters =
FeesAndCharges = {
Fees = [||]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [| Charge.LatePayment (Amount.Simple 10_00L<Cent>) |]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
16 changes: 8 additions & 8 deletions src/Amortisation.fs
Original file line number Diff line number Diff line change
@@ -311,13 +311,13 @@ module Amortisation =
match sp.FeesAndCharges.FeesSettlementRefund with
| Fees.SettlementRefund.None ->
0L<Cent>
| Fees.SettlementRefund.ProRata ->
match sp.ScheduleType with
| ScheduleType.Original ->
| Fees.SettlementRefund.ProRata originalFinalPaymentDay ->
match originalFinalPaymentDay with
| ValueNone ->
let originalFinalPaymentDay = sp.PaymentSchedule |> paymentDays sp.StartDate |> Array.vTryLastBut 0 |> ValueOption.defaultValue 0<OffsetDay>
calculateFees originalFinalPaymentDay
| ScheduleType.Rescheduled originalFinalPaymentDay ->
calculateFees originalFinalPaymentDay
| ValueSome ofpd ->
calculateFees ofpd
| Fees.SettlementRefund.Balance ->
a.CumulativeFees

@@ -542,7 +542,7 @@ module Amortisation =
PaymentDetails =
match sp.ScheduleType with
| ScheduleType.Original -> ScheduledPayment (ScheduledPaymentType.Original si.Payment.Value)
| ScheduleType.Rescheduled _ -> ScheduledPayment (ScheduledPaymentType.Rescheduled si.Payment.Value)
| ScheduleType.Rescheduled -> ScheduledPayment (ScheduledPaymentType.Rescheduled si.Payment.Value)
})
| ValueNone ->
[||]
@@ -556,7 +556,7 @@ module Amortisation =
PaymentDetails =
match sp.ScheduleType with
| ScheduleType.Original -> ScheduledPayment (ScheduledPaymentType.Original rfs.PaymentAmount)
| ScheduleType.Rescheduled _ -> ScheduledPayment (ScheduledPaymentType.Rescheduled rfs.PaymentAmount)
| ScheduleType.Rescheduled -> ScheduledPayment (ScheduledPaymentType.Rescheduled rfs.PaymentAmount)
}
)
)
@@ -572,6 +572,6 @@ module Amortisation =
payments
|> applyPayments asOfDay intendedPurpose sp.FeesAndCharges.LatePaymentGracePeriod latePaymentCharge sp.FeesAndCharges.ChargesGrouping sp.Calculation.PaymentTimeout actualPayments
|> calculate sp intendedPurpose
|> Array.trimEnd(fun si -> match sp.ScheduleType with ScheduleType.Rescheduled _ when si.PaymentStatus = NoLongerRequired -> true | _ -> false) // remove extra items from rescheduling
|> Array.trimEnd(fun si -> match sp.ScheduleType with ScheduleType.Rescheduled when si.PaymentStatus = NoLongerRequired -> true | _ -> false) // remove extra items from rescheduling
|> calculateStats sp intendedPurpose
|> ValueSome
4 changes: 2 additions & 2 deletions src/FeesAndCharges.fs
Original file line number Diff line number Diff line change
@@ -46,8 +46,8 @@ module FeesAndCharges =
type SettlementRefund =
/// fees are due in full with no discount or refund
| None
/// fees are refunded proportionately to the number of days elapsed in the current schedule
| ProRata
/// fees are refunded proportionately to the number of days elapsed in the current schedule, based on the original final payment day
| ProRata of OriginalFinalPaymentDay: int<OffsetDay> voption
/// the current fee balance is refunded
| Balance

4 changes: 2 additions & 2 deletions src/PaymentSchedule.fs
Original file line number Diff line number Diff line change
@@ -82,8 +82,8 @@ module PaymentSchedule =
type ScheduleType =
/// an original schedule
| Original
/// a schedule based on a previous one; the original final payment day is carried over to ensure any pro-rating is based on the original schedule
| Rescheduled of OriginalFinalPaymentDay: int<OffsetDay>
/// a schedule based on a previous one
| Rescheduled

/// parameters for creating a payment schedule
[<Struct>]
22 changes: 15 additions & 7 deletions src/Rescheduling.fs
Original file line number Diff line number Diff line change
@@ -16,10 +16,8 @@ module Rescheduling =
/// the parameters used for setting up additional items for an existing schedule or new items for a new schedule
[<RequireQualifiedAccess; Struct>]
type RescheduleParameters = {
/// the final payment day of the original schedule
OriginalFinalPaymentDay: int<OffsetDay>
/// whether the fees should be pro-rated or due in full in the new schedule
FeesSettlement: Fees.SettlementRefund
FeesSettlementRefund: Fees.SettlementRefund
/// whether the plan is autogenerated or a manual plan provided
PaymentSchedule: CustomerPaymentSchedule
/// how to handle interest on negative principal balances
@@ -67,9 +65,13 @@ module Rescheduling =
// configure the parameters for the new schedule
let spNew =
{ sp with
ScheduleType = PaymentSchedule.ScheduleType.Rescheduled rp.OriginalFinalPaymentDay
ScheduleType = PaymentSchedule.ScheduleType.Rescheduled
PaymentSchedule = [| oldPaymentSchedule; newPaymentSchedule |] |> Array.concat |> IrregularSchedule
FeesAndCharges = { sp.FeesAndCharges with ChargesHolidays = rp.ChargesHolidays }
FeesAndCharges =
{ sp.FeesAndCharges with
FeesSettlementRefund = rp.FeesSettlementRefund
ChargesHolidays = rp.ChargesHolidays
}
Interest =
{ sp.Interest with
InitialGracePeriod = 0<DurationDay>
@@ -122,15 +124,21 @@ module Rescheduling =
let spNew =
{ sp with
StartDate = sp.AsOfDate
ScheduleType = PaymentSchedule.ScheduleType.Rescheduled rp.OriginalFinalPaymentDay
ScheduleType = PaymentSchedule.ScheduleType.Rescheduled
Principal = principalPortion
PaymentSchedule = rp.PaymentSchedule
FeesAndCharges =
match rp.FeeHandling with
| Fees.FeeHandling.CarryOverAsIs ->
{ sp.FeesAndCharges with
Fees = [| Fee.CustomFee ("Rolled-Over Fee", Amount.Simple feesPortion) |]
FeesSettlementRefund = if feesRefundIfSettled = 0L<Cent> then Fees.SettlementRefund.None else Fees.SettlementRefund.ProRata
FeesSettlementRefund =
if feesRefundIfSettled = 0L<Cent> then
Fees.SettlementRefund.None
else
match sp.FeesAndCharges.FeesSettlementRefund with
| Fees.SettlementRefund.ProRata _ -> Fees.SettlementRefund.ProRata (ValueSome rp.OriginalFinalPaymentDay)
| _ as fsr -> fsr
}
| _ ->
{ sp.FeesAndCharges with Fees = [||]; FeesSettlementRefund = Fees.SettlementRefund.None }
40 changes: 20 additions & 20 deletions tests/ActualPaymentTests.fs
Original file line number Diff line number Diff line change
@@ -68,7 +68,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [||]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [| Charge.LatePayment (Amount.Simple 10_00L<Cent>) |]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -115,7 +115,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [||]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [| Charge.LatePayment (Amount.Simple 10_00L<Cent>) |]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -162,7 +162,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [||]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [| Charge.LatePayment (Amount.Simple 10_00L<Cent>) |]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -209,7 +209,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [||]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [| Charge.LatePayment (Amount.Simple 10_00L<Cent>) |]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -280,7 +280,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [||]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [| Charge.LatePayment (Amount.Simple 10_00L<Cent>) |]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -351,7 +351,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [||]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [| Charge.LatePayment (Amount.Simple 10_00L<Cent>) |]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -427,7 +427,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [||]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [| Charge.LatePayment (Amount.Simple 10_00L<Cent>) |]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -501,7 +501,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [||]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [| Charge.LatePayment (Amount.Simple 10_00L<Cent>) |]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -576,7 +576,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [||]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [| Charge.LatePayment (Amount.Simple 10_00L<Cent>) |]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -652,7 +652,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [||]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [| Charge.LatePayment (Amount.Simple 10_00L<Cent>) |]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -727,7 +727,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [||]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [| Charge.LatePayment (Amount.Simple 10_00L<Cent>) |]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -802,7 +802,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [||]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [| Charge.LatePayment (Amount.Simple 10_00L<Cent>) |]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -879,7 +879,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [||]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [||]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -928,7 +928,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 154.47m, ValueNone, ValueSome RoundDown)) |]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [||]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -1000,7 +1000,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 154.47m, ValueNone, ValueSome RoundDown)) |]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [||]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -1049,7 +1049,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 154.47m, ValueNone, ValueSome RoundDown)) |]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [||]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -1099,7 +1099,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 154.47m, ValueNone, ValueSome RoundDown)) |]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [||]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -1150,7 +1150,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 154.47m, ValueNone, ValueSome RoundDown)) |]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [||]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -1201,7 +1201,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [| Fee.CabOrCsoFee (Amount.Percentage (Percent 154.47m, ValueNone, ValueSome RoundDown)) |]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [||]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
@@ -1249,7 +1249,7 @@ module ActualPaymentTests =
FeesAndCharges = {
Fees = [||]
FeesAmortisation = Fees.FeeAmortisation.AmortiseProportionately
FeesSettlementRefund = Fees.SettlementRefund.ProRata
FeesSettlementRefund = Fees.SettlementRefund.ProRata ValueNone
Charges = [||]
ChargesHolidays = [||]
ChargesGrouping = OneChargeTypePerDay
Loading
Oops, something went wrong.

0 comments on commit c7f0a75

Please sign in to comment.