diff --git a/lana/app/src/credit_facility/credit_chart_of_accounts/mod.rs b/lana/app/src/credit_facility/credit_chart_of_accounts/mod.rs index a3c770d10..f5cca3d6d 100644 --- a/lana/app/src/credit_facility/credit_chart_of_accounts/mod.rs +++ b/lana/app/src/credit_facility/credit_chart_of_accounts/mod.rs @@ -1,5 +1,5 @@ use audit::AuditInfo; -use cala_ledger::CalaLedger; +use cala_ledger::LedgerOperation; use chart_of_accounts::TransactionAccountFactory; use lana_ids::CreditFacilityId; @@ -11,7 +11,6 @@ use super::CreditFacilityAccountIds; #[derive(Clone)] pub struct CreditChartOfAccounts { - cala: CalaLedger, collateral_factory: TransactionAccountFactory, facility_factory: TransactionAccountFactory, disbursed_receivable_factory: TransactionAccountFactory, @@ -21,35 +20,31 @@ pub struct CreditChartOfAccounts { } impl CreditChartOfAccounts { - pub async fn init( - cala: &CalaLedger, + pub fn new( collateral_factory: TransactionAccountFactory, facility_factory: TransactionAccountFactory, disbursed_receivable_factory: TransactionAccountFactory, interest_receivable_factory: TransactionAccountFactory, interest_income_factory: TransactionAccountFactory, fee_income_factory: TransactionAccountFactory, - ) -> Result { - Ok(Self { - cala: cala.clone(), + ) -> Self { + Self { collateral_factory, facility_factory, disbursed_receivable_factory, interest_receivable_factory, interest_income_factory, fee_income_factory, - }) + } } pub async fn create_accounts_for_credit_facility( &self, - op: es_entity::DbOp<'_>, + op: &mut LedgerOperation<'_>, credit_facility_id: CreditFacilityId, account_ids: CreditFacilityAccountIds, audit_info: AuditInfo, ) -> Result<(), CreditChartOfAccountsError> { - let mut op = self.cala.ledger_operation_from_db_op(op); - let collateral_name = &format!( "Credit Facility Collateral Account for {}", credit_facility_id @@ -57,7 +52,7 @@ impl CreditChartOfAccounts { let _collateral_details = self .collateral_factory .create_transaction_account_in_op( - &mut op, + op, account_ids.collateral_account_id, collateral_name, collateral_name, @@ -72,7 +67,7 @@ impl CreditChartOfAccounts { let _facility_details = self .facility_factory .create_transaction_account_in_op( - &mut op, + op, account_ids.facility_account_id, facility_name, facility_name, @@ -87,7 +82,7 @@ impl CreditChartOfAccounts { let _disbursed_receivable_details = self .disbursed_receivable_factory .create_transaction_account_in_op( - &mut op, + op, account_ids.disbursed_receivable_account_id, disbursed_receivable_name, disbursed_receivable_name, @@ -102,7 +97,7 @@ impl CreditChartOfAccounts { let _interest_receivable_details = self .interest_receivable_factory .create_transaction_account_in_op( - &mut op, + op, account_ids.interest_receivable_account_id, interest_receivable_name, interest_receivable_name, @@ -117,7 +112,7 @@ impl CreditChartOfAccounts { let _interest_income_details = self .interest_income_factory .create_transaction_account_in_op( - &mut op, + op, account_ids.interest_account_id, interest_income_name, interest_income_name, @@ -132,7 +127,7 @@ impl CreditChartOfAccounts { let _fee_income_details = self .fee_income_factory .create_transaction_account_in_op( - &mut op, + op, account_ids.fee_income_account_id, fee_income_name, fee_income_name, @@ -140,8 +135,6 @@ impl CreditChartOfAccounts { ) .await?; - op.commit().await?; - Ok(()) } } diff --git a/lana/app/src/credit_facility/ledger/mod.rs b/lana/app/src/credit_facility/ledger/mod.rs index 7048a516f..373d53238 100644 --- a/lana/app/src/credit_facility/ledger/mod.rs +++ b/lana/app/src/credit_facility/ledger/mod.rs @@ -18,7 +18,7 @@ use error::*; pub(super) const BANK_COLLATERAL_ACCOUNT_CODE: &str = "BANK.COLLATERAL.OMNIBUS"; pub(super) const CREDIT_OMNIBUS_ACCOUNT_CODE: &str = "CREDIT.OMNIBUS"; pub(super) const CREDIT_FACILITY_VELOCITY_CONTROL_ID: uuid::Uuid = - uuid::uuid!("00000000-0000-0000-0000-000000000001"); + uuid::uuid!("00000000-0000-0000-0000-000000000002"); #[derive(Debug, Clone)] pub struct CreditFacilityCollateralUpdate { @@ -463,6 +463,7 @@ impl CreditLedger { &self, op: &mut cala_ledger::LedgerOperation<'_>, account_id: impl Into, + disbursal_limit: UsdCents, ) -> Result<(), CreditLedgerError> { self.cala .velocities() @@ -470,7 +471,9 @@ impl CreditLedger { op, self.credit_facility_control_id, account_id.into(), - Params::default(), + velocity::DisbursalLimitParams { + disbursal_limit: disbursal_limit.to_usd(), + }, ) .await?; diff --git a/lana/app/src/credit_facility/ledger/velocity/disbursal_limit.rs b/lana/app/src/credit_facility/ledger/velocity/disbursal_limit.rs index 31ae69c40..a1c16cd2c 100644 --- a/lana/app/src/credit_facility/ledger/velocity/disbursal_limit.rs +++ b/lana/app/src/credit_facility/ledger/velocity/disbursal_limit.rs @@ -1,3 +1,4 @@ +use rust_decimal::Decimal; use tracing::instrument; use cala_ledger::{velocity::*, *}; @@ -6,11 +7,36 @@ pub struct DisbursalLimit; const DISBURSAL_LIMIT_ID: uuid::Uuid = uuid::uuid!("00000000-0000-0000-0000-000000000002"); +#[derive(Debug)] +pub struct DisbursalLimitParams { + pub disbursal_limit: Decimal, +} + +impl DisbursalLimitParams { + pub fn defs() -> Vec { + vec![NewParamDefinition::builder() + .name("disbursal_limit") + .r#type(ParamDataType::Decimal) + .build() + .unwrap()] + } +} + +impl From for Params { + fn from(params: DisbursalLimitParams) -> Self { + let mut p = Self::default(); + p.insert("disbursal_limit", params.disbursal_limit); + p + } +} + impl DisbursalLimit { #[instrument(name = "ledger.overdraft_prevention.init", skip_all)] pub async fn init( ledger: &CalaLedger, ) -> Result { + let params = DisbursalLimitParams::defs(); + let limit = NewVelocityLimit::builder() .id(DISBURSAL_LIMIT_ID) .name("Disbursal Limit") @@ -20,13 +46,14 @@ impl DisbursalLimit { NewLimit::builder() .balance(vec![NewBalanceLimit::builder() .layer("SETTLED") - .amount("decimal('0.0')") + .amount("params.disbursal_limit") .enforcement_direction("DEBIT") .build() .expect("balance limit")]) .build() .expect("limit"), ) + .params(params) .build() .expect("velocity limit"); diff --git a/lana/app/src/credit_facility/mod.rs b/lana/app/src/credit_facility/mod.rs index 3246ec129..ab20c1fa4 100644 --- a/lana/app/src/credit_facility/mod.rs +++ b/lana/app/src/credit_facility/mod.rs @@ -67,6 +67,7 @@ pub struct CreditFacilities { price: Price, config: CreditFacilityConfig, approve_disbursal: ApproveDisbursal, + cala: CalaLedger, approve_credit_facility: ApproveCreditFacility, } @@ -102,16 +103,14 @@ impl CreditFacilities { governance, &ledger, ); - let chart_of_accounts = CreditChartOfAccounts::init( - cala, + let chart_of_accounts = CreditChartOfAccounts::new( collateral_factory, facility_factory, disbursed_receivable_factory, interest_receivable_factory, interest_income_factory, fee_income_factory, - ) - .await?; + ); let approve_credit_facility = ApproveCreditFacility::new(&credit_facility_repo, authz.audit(), governance); @@ -180,6 +179,7 @@ impl CreditFacilities { chart_of_accounts, price: price.clone(), config, + cala: cala.clone(), approve_disbursal, approve_credit_facility, }) @@ -242,15 +242,27 @@ impl CreditFacilities { .credit_facility_repo .create_in_op(&mut db, new_credit_facility) .await?; + + let mut op = self.cala.ledger_operation_from_db_op(db); self.chart_of_accounts .create_accounts_for_credit_facility( - db, + &mut op, credit_facility.id, credit_facility.account_ids, audit_info, ) .await?; + self.ledger + .add_credit_facility_control_to_account( + &mut op, + credit_facility.account_ids.disbursed_receivable_account_id, + facility, + ) + .await?; + + op.commit().await?; + Ok(credit_facility) } @@ -326,8 +338,6 @@ impl CreditFacilities { .await?; credit_facility.balances().check_against_ledger(balances)?; - credit_facility.balances().check_disbursal_amount(amount)?; - let price = self.price.usd_cents_per_btc().await?; let mut db = self.credit_facility_repo.begin_op().await?;