S++Business systems language
DEMO SOURCE · SPP / APP / PHYRead the book

cboddeposit-10-cash-admission.spp

cboddeposit/admission/cboddeposit-10-cash-admission.spp

Download original file · Bank deposit source contents

1domain cboddeposit;23// GSA01102 normal cash entry, distinct from the zero-amount kernel.45Role BusinessDay {6    int date;7}89Role AccountEligibility {10    String accountNumber;11    AccountStatus status;12    boolean temporary;13    int expiresOn;14    boolean temporaryOpen;15    int detailCount;16    int lastTransactionDate;17    int openedOn;18    BigDecimal(19, 2) cashDepositedToday;19    BigDecimal(19, 2) transferredToday;20    BigDecimal(19, 2) accountBalance;21}2223Role DepositProduct {24    BigDecimal(19, 2) minimumOpeningAmount;25    BigDecimal(19, 2) maximumOpeningAmount;26    BigDecimal(19, 2) maximumBalance;27}2829atomic check checkCashInput(DepositRequest, BusinessDay) {30    require(DepositRequest.amount > 0, "E1155");31    require(DepositRequest.valueDate <= BusinessDay.date, "E1044");32    require(DepositRequest.valueDate >= BusinessDay.date, "E1043");33}3435atomic check checkDepositEligibility(DepositRequest, AccountEligibility, DepositProduct, BusinessDay) {36    require(37        !AccountEligibility.temporary38            || AccountEligibility.expiresOn >= BusinessDay.date39            || AccountEligibility.temporaryOpen,40        "EDF19"41    );42    require(AccountEligibility.status != AccountStatus.CLOSED, "EO082");43    boolean opening = AccountEligibility.detailCount == 044        || (AccountEligibility.detailCount > 045        && AccountEligibility.detailCount < 1046        && AccountEligibility.accountBalance == 047        && AccountEligibility.lastTransactionDate == AccountEligibility.openedOn48        && AccountEligibility.cashDepositedToday == 049        && AccountEligibility.transferredToday == 0);50    if (opening) {51        require(52            DepositProduct.minimumOpeningAmount <= 053                || DepositRequest.amount >= DepositProduct.minimumOpeningAmount,54            "EN173"55        );56        require(57            DepositProduct.maximumOpeningAmount <= 058                || DepositRequest.amount <= DepositProduct.maximumOpeningAmount,59            "EN174"60        );61    }62    require(63        DepositProduct.maximumBalance <= 064            || DepositRequest.amount65            + AccountEligibility.accountBalance <= DepositProduct.maximumBalance,66        "EN175"67    );68}6970// Cash-only subset of KSADEP0 warning/authorization. Parameter values are queried facts.7172Role CashAuthorizationPolicy {73    BigDecimal(19, 2) warningThreshold;74    BigDecimal(19, 2) tellerLimit;75    BigDecimal(19, 2) levelAMultiplier;76    BigDecimal(19, 2) specialUsdLevelB;77    BigDecimal(19, 2) specialUsdLevelA;78}7980Role CashChannel {81    boolean teller;82    String channel;83    business("Legacy bank transaction business code") String transactionId;84    String transactionFamily;85    String businessCode;86}8788Role AuthorizationEvidence {89    AuthorizationLevel grantedLevel;90}9192Role AdmissionDecision {93    String warningCode;94    String authorizationCode;95    AuthorizationLevel requiredLevel;96    AdmissionStatus status;97    boolean executable;98    BigDecimal(19, 2) dayCashTotal;99}100101atomic calculate assessCashAdmission(102    DepositRequest,103    AccountEligibility,104    BusinessDay,105    CashChannel,106    CashAuthorizationPolicy,107    AuthorizationEvidence,108    AdmissionDecision109) {110    AdmissionDecision.warningCode = "";111    AdmissionDecision.authorizationCode = "";112    AdmissionDecision.requiredLevel = AuthorizationLevel.NONE;113    AdmissionDecision.dayCashTotal = DepositRequest.amount;114    if (AccountEligibility.lastTransactionDate == BusinessDay.date) {115        AdmissionDecision.dayCashTotal += AccountEligibility.cashDepositedToday;116    }117    boolean applies = CashChannel.teller118        && CashChannel.channel != "AGS"119        && CashChannel.transactionId != "FL0658000"120        && CashChannel.transactionId != "FL0655400"121        && CashChannel.transactionId != "FL0659302"122        && CashChannel.transactionId != "FL0659304"123        && CashChannel.transactionId != "FL0659306"124        && CashChannel.transactionId != "FL0659308";125    if (applies) {126        boolean warningBusiness = CashChannel.businessCode == "SA0"127            || CashChannel.businessCode == "TD0"128            || CashChannel.businessCode == "CR0"129            || CashChannel.businessCode == "FS0";130        if (warningBusiness131            && CashAuthorizationPolicy.warningThreshold > 0132            && AdmissionDecision.dayCashTotal > CashAuthorizationPolicy.warningThreshold) {133            AdmissionDecision.warningCode = "F0554";134        }135        if (DepositRequest.amount > CashAuthorizationPolicy.tellerLimit) {136            if (CashChannel.transactionFamily == "XT01821" && DepositRequest.currency == "USD") {137                if (DepositRequest.amount > CashAuthorizationPolicy.specialUsdLevelB) {138                    if (DepositRequest.amount > CashAuthorizationPolicy.specialUsdLevelA) {139                        AdmissionDecision.requiredLevel = AuthorizationLevel.A;140                        AdmissionDecision.authorizationCode = "A8147";141                    } else {142                        AdmissionDecision.requiredLevel = AuthorizationLevel.B;143                        AdmissionDecision.authorizationCode = "B7006";144                    }145                }146            } else {147                if (DepositRequest.amount > CashAuthorizationPolicy.levelAMultiplier148                    * CashAuthorizationPolicy.tellerLimit) {149                    AdmissionDecision.requiredLevel = AuthorizationLevel.A;150                    AdmissionDecision.authorizationCode = "A8147";151                } else {152                    AdmissionDecision.requiredLevel = AuthorizationLevel.B;153                    AdmissionDecision.authorizationCode = "B7000";154                }155            }156        }157    }158    AdmissionDecision.executable = AdmissionDecision.requiredLevel == AuthorizationLevel.NONE159        || AuthorizationEvidence.grantedLevel == AuthorizationLevel.A160        || (AdmissionDecision.requiredLevel == AuthorizationLevel.B161        && AuthorizationEvidence.grantedLevel == AuthorizationLevel.B);162    if (!AdmissionDecision.executable) {163        AdmissionDecision.status = AdmissionStatus.PENDING_AUTHORIZATION;164    } else {165        if (AdmissionDecision.warningCode != "") {166            AdmissionDecision.status = AdmissionStatus.WARNING;167        } else {168            AdmissionDecision.status = AdmissionStatus.READY;169        }170    }171}172173atomic check checkCashAuthorization(AdmissionDecision) {174    require(AdmissionDecision.executable, "PENDING_AUTHORIZATION");175}