cboddeposit-00-deposit-kernel.spp
cboddeposit/calculation/cboddeposit-00-deposit-kernel.spp
Download original file · Bank deposit source contents
1domain cboddeposit;23// Source-derived KSADEP0 4110/4111 and balance formulas in 4150.4// Account is an immutable input snapshot; plan contains proposed changes.56Role DepositRequest {7BigDecimal(19, 2) amount;8String currency;9int valueDate;10}1112Role DepositAccount {13String accountNumber;14quantum BigDecimal(19, 2) interestBase;15quantum BigDecimal(19, 2) frozenAmount;16quantum BigDecimal(19, 2) authorizedAmount;17quantum BigDecimal(19, 2) overdraftInterest;18quantum BigDecimal(19, 2) collectionInterest;19quantum BigDecimal(19, 2) overdraftPrincipal;20quantum BigDecimal(19, 2) overdraftExposure;21LoanState loanState; // Normal, BadDebt, WrittenOff: decoded business states, not deployment flags.22}2324Role DepositPlan {25BigDecimal(19, 2) interestPaid;26BigDecimal(19, 2) collectionInterestPaid;27BigDecimal(19, 2) principalPaid;28BigDecimal(19, 2) newInterestBase;29BigDecimal(19, 2) newAvailableBalance;30BigDecimal(19, 2) newOverdraftExposure;31BigDecimal(19, 2) newAccountBalance;32BigDecimal(19, 2) interestBaseIncrease;33BigDecimal(19, 2) interestBaseDecrease;34}3536atomic check checkKernelInput(DepositRequest) {37require(DepositRequest.amount >= 0, "E1095");38}3940atomic calculate calculateDepositPlan(DepositRequest, DepositAccount, DepositPlan) {41boolean principalFirst = DepositAccount.loanState == LoanState.BAD_DEBT42|| DepositAccount.loanState == LoanState.WRITTEN_OFF;43BigDecimal remaining = DepositRequest.amount + DepositAccount.interestBase - DepositAccount.frozenAmount;44DepositPlan.interestPaid = 0;45DepositPlan.collectionInterestPaid = 0;46DepositPlan.principalPaid = 0;47DepositPlan.newOverdraftExposure = DepositAccount.overdraftExposure;48if (remaining > 0) {49if (principalFirst) {50DepositPlan.principalPaid = min(remaining, DepositAccount.overdraftPrincipal);51if (remaining <= DepositAccount.overdraftPrincipal) {52DepositPlan.newOverdraftExposure = max(530,54DepositAccount.overdraftExposure - DepositPlan.principalPaid55);56} else {57DepositPlan.newOverdraftExposure = 0;58}59remaining -= DepositPlan.principalPaid;60}61DepositPlan.interestPaid = min(remaining, DepositAccount.overdraftInterest);62remaining -= DepositPlan.interestPaid;63DepositPlan.collectionInterestPaid = min(remaining, DepositAccount.collectionInterest);64remaining -= DepositPlan.collectionInterestPaid;65if (!principalFirst && remaining > 0) {66DepositPlan.principalPaid = min(remaining, DepositAccount.overdraftPrincipal);67if (remaining <= DepositAccount.overdraftPrincipal) {68DepositPlan.newOverdraftExposure = max(690,70DepositAccount.overdraftExposure - DepositPlan.principalPaid71);72} else {73DepositPlan.newOverdraftExposure = 0;74}75remaining -= DepositPlan.principalPaid;76}77}78DepositPlan.newInterestBase = DepositAccount.interestBase79+ DepositRequest.amount80- DepositPlan.interestPaid81- DepositPlan.collectionInterestPaid82- DepositPlan.principalPaid;83DepositPlan.newAvailableBalance = max(840,85DepositPlan.newInterestBase - DepositAccount.frozenAmount - DepositAccount.authorizedAmount86);87DepositPlan.newAccountBalance = DepositPlan.newInterestBase88- (DepositAccount.overdraftInterest89- DepositPlan.interestPaid)90- (DepositAccount.collectionInterest91- DepositPlan.collectionInterestPaid)92- (DepositAccount.overdraftPrincipal93- DepositPlan.principalPaid);94DepositPlan.interestBaseIncrease = max(0, DepositPlan.newInterestBase - DepositAccount.interestBase);95DepositPlan.interestBaseDecrease = max(0, DepositAccount.interestBase - DepositPlan.newInterestBase);96}9798atomic check checkPlan(DepositRequest, DepositAccount, DepositPlan) {99// Derived arithmetic invariant, rather than DepositAccount new claim about COBOL checks.100require(101DepositPlan.newAccountBalance == DepositAccount.interestBase102- DepositAccount.overdraftInterest103- DepositAccount.collectionInterest104- DepositAccount.overdraftPrincipal105+ DepositRequest.amount,106"net balance invariant"107);108}109110take BankAccount as DepositAccount {111mapsame;112}