@@ -694,6 +694,39 @@ module Amortisation =
694694 | Fee.SettlementRebate.Zero -> 0 L< Cent>
695695 | ValueNone -> 0 L< Cent>
696696
697+ let createInitialScheduleItem startDate principal fee interest ( advancedFeeConfig : Fee.AdvancedConfig voption ) = {
698+ ScheduleItem.zero with
699+ OffsetDate = startDate
700+ Advances = [| principal |]
701+ PrincipalBalance = principal
702+ FeeBalance = fee
703+ InterestBalance = interest
704+ SettlementFigure = principal + fee
705+ FeeRebateIfSettled =
706+ match advancedFeeConfig with
707+ | ValueSome fc ->
708+ match fc.SettlementRebate with
709+ | Fee.SettlementRebate.Zero -> 0 L< Cent>
710+ | _ -> fee
711+ | ValueNone -> 0 L< Cent>
712+ }
713+
714+ let createInitialTotals interest = {
715+ CumulativeScheduledPayments = 0 L< Cent>
716+ CumulativeActualPayments = 0 L< Cent>
717+ CumulativeGeneratedPayments = 0 L< Cent>
718+ CumulativeFee = 0 L< Cent>
719+ CumulativeInterest = interest
720+ CumulativeInterestPortions = 0 L< Cent>
721+ CumulativeActuarialInterestM = 0 m< Cent>
722+ }
723+
724+ // removes duplicated initial offset day
725+ let deduplicateDay0 ( a : ( int < OffsetDay > * ScheduleItem ) array ) =
726+ if a |> Array.filter ( fun ( day , _ ) -> day = 0 < OffsetDay>) |> Array.length = 2 then
727+ a |> Array.tail
728+ else
729+ a
697730
698731 /// calculates an amortisation schedule detailing how elements (principal, fee, interest and charges) are paid off over time
699732 let internal calculate ( p : Parameters ) initialStats ( appliedPayments : Map < int < OffsetDay >, AppliedPayment >) =
@@ -1168,44 +1201,18 @@ module Amortisation =
11681201 (
11691202 // initialise the values for the scan
11701203 ( 0 < OffsetDay>,
1171- {
1172- ScheduleItem.zero with
1173- OffsetDate = p.Basic.StartDate
1174- Advances = [| p.Basic.Principal |]
1175- PrincipalBalance = p.Basic.Principal
1176- FeeBalance = feeTotal
1177- InterestBalance = initialInterestBalanceM
1178- SettlementFigure = p.Basic.Principal + feeTotal
1179- FeeRebateIfSettled =
1180- match p.Advanced.FeeConfig with
1181- | ValueSome fc ->
1182- match fc.SettlementRebate with
1183- | Fee.SettlementRebate.Zero -> 0 L< Cent>
1184- | _ -> feeTotal
1185- | ValueNone -> 0 L< Cent>
1186- }),
1187- {
1188- CumulativeScheduledPayments = 0 L< Cent>
1189- CumulativeActualPayments = 0 L< Cent>
1190- CumulativeGeneratedPayments = 0 L< Cent>
1191- CumulativeFee = 0 L< Cent>
1192- CumulativeInterest = initialInterestBalanceM
1193- CumulativeInterestPortions = 0 L< Cent>
1194- CumulativeActuarialInterestM = 0 m< Cent>
1195- })
1204+ createInitialScheduleItem
1205+ p.Basic.StartDate
1206+ p.Basic.Principal
1207+ feeTotal
1208+ initialInterestBalanceM
1209+ p.Advanced.FeeConfig),
1210+ createInitialTotals initialInterestBalanceM)
11961211 // separate and discard the accumulator
11971212 |> Array.unzip
11981213 |> fst
11991214 // handle duplicated initial offset day
1200- |> fun a ->
1201- if
1202- a
1203- |> Array.filter ( fun ( siOffsetDay , _ ) -> siOffsetDay = 0 < OffsetDay>)
1204- |> Array.length = 2
1205- then
1206- a |> Array.tail
1207- else
1208- a
1215+ |> deduplicateDay0
12091216 // post-process missed payments or underpayments
12101217 |> markMissedPaymentsAsLate
12111218
0 commit comments