Skip to content

Commit

Permalink
None to OnceAtMaturity variant
Browse files Browse the repository at this point in the history
  • Loading branch information
lemunozm committed Jun 6, 2024
1 parent 70ea49c commit f9db4fc
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 13 deletions.
2 changes: 1 addition & 1 deletion pallets/loans/src/tests/create_loan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ fn with_wrong_schedule() {
let loan = LoanInfo {
schedule: RepaymentSchedule {
maturity: Maturity::fixed(now().as_secs()),
interest_payments: InterestPayments::None,
interest_payments: InterestPayments::OnceAtMaturity,
pay_down_schedule: PayDownSchedule::None,
},
..util::base_internal_loan()
Expand Down
5 changes: 3 additions & 2 deletions pallets/loans/src/tests/mutate_loan.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::*;

const DEFAULT_MUTATION: LoanMutation<Rate> = LoanMutation::InterestPayments(InterestPayments::None);
const DEFAULT_MUTATION: LoanMutation<Rate> =
LoanMutation::InterestPayments(InterestPayments::OnceAtMaturity);

fn config_mocks(loan_id: LoanId, loan_mutation: &LoanMutation<Rate>) {
MockPermissions::mock_has(|scope, who, role| {
Expand Down Expand Up @@ -213,7 +214,7 @@ fn with_successful_mutation_application() {
date: (now() + YEAR).as_secs(),
extension: YEAR.as_secs(),
},
interest_payments: InterestPayments::None,
interest_payments: InterestPayments::OnceAtMaturity,
pay_down_schedule: PayDownSchedule::None,
},
interest_rate: InterestRate::Fixed {
Expand Down
4 changes: 2 additions & 2 deletions pallets/loans/src/tests/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ pub fn base_internal_loan() -> LoanInfo<Runtime> {
date: (now() + YEAR).as_secs(),
extension: (YEAR / 2).as_secs(),
},
interest_payments: InterestPayments::None,
interest_payments: InterestPayments::OnceAtMaturity,
pay_down_schedule: PayDownSchedule::None,
},
interest_rate: default_interest_rate(),
Expand All @@ -144,7 +144,7 @@ pub fn base_external_loan() -> LoanInfo<Runtime> {
LoanInfo {
schedule: RepaymentSchedule {
maturity: Maturity::fixed((now() + YEAR).as_secs()),
interest_payments: InterestPayments::None,
interest_payments: InterestPayments::OnceAtMaturity,
pay_down_schedule: PayDownSchedule::None,
},
interest_rate: default_interest_rate(),
Expand Down
45 changes: 37 additions & 8 deletions pallets/loans/src/types/cashflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl Maturity {
#[derive(Encode, Decode, Clone, PartialEq, Eq, TypeInfo, RuntimeDebug, MaxEncodedLen)]
pub enum InterestPayments {
/// All interest is expected to be paid at the maturity date
None,
OnceAtMaturity,

/// Interest is expected to be paid monthly
/// The associated value correspond to the paydown day in the month,
Expand Down Expand Up @@ -124,7 +124,7 @@ pub struct RepaymentSchedule {
impl RepaymentSchedule {
pub fn is_valid(&self, now: Seconds) -> Result<bool, DispatchError> {
let valid = match self.interest_payments {
InterestPayments::None => true,
InterestPayments::OnceAtMaturity => true,
InterestPayments::Monthly(_) => {
match self.maturity.date() {
Some(maturity) => {
Expand Down Expand Up @@ -162,7 +162,7 @@ impl RepaymentSchedule {
let end_date = date::from_seconds(maturity)?;

let timeflow = match &self.interest_payments {
InterestPayments::None => vec![],
InterestPayments::OnceAtMaturity => vec![(end_date, 1)],
InterestPayments::Monthly(reference_day) => {
date::monthly_intervals(start_date, end_date, (*reference_day).into())?
}
Expand Down Expand Up @@ -344,6 +344,39 @@ pub mod tests {
secs_from_ymdhms(year, month, day, 23, 59, 59)
}

mod once_at_maturity {
use super::*;

#[test]
fn correct_amounts() {
// To understand the expected interest amounts:
// A rate per year of 0.12 means each month you nearly pay with a rate of 0.01.
// 0.01 of the total principal is 25000 * 0.01 = 250 each month.
// A minor extra amount comes from the secondly compounding interest during 2.5
// months.
assert_eq!(
RepaymentSchedule {
maturity: Maturity::fixed(last_secs_from_ymd(2022, 7, 1)),
interest_payments: InterestPayments::OnceAtMaturity,
pay_down_schedule: PayDownSchedule::None,
}
.generate_cashflows(
last_secs_from_ymd(2022, 4, 16),
25000u128, /* principal */
&InterestRate::Fixed {
rate_per_year: Rate::from_float(0.12),
compounding: CompoundingSchedule::Secondly,
}
)
.unwrap()
.into_iter()
.map(|payment| (payment.principal, payment.interest))
.collect::<Vec<_>>(),
vec![(25000, 632)]
)
}
}

mod months {
use super::*;

Expand Down Expand Up @@ -421,11 +454,7 @@ pub mod tests {

#[test]
fn correct_amounts() {
// To understand the expected interest amounts:
// A rate per year of 0.12 means each month you nearly pay with a rate of 0.01.
// 0.01 of the total principal is 25000 * 0.01 = 250 each month.
// A minor extra amount comes from the secondly compounding interest during 2.5
// months.
// See comment at once_at_maturity::correct_amounts() to know about the numbers
assert_eq!(
RepaymentSchedule {
maturity: Maturity::fixed(last_secs_from_ymd(2022, 7, 1)),
Expand Down

0 comments on commit f9db4fc

Please sign in to comment.