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

cboddeposit-00-postings.spp

cboddeposit/posting/cboddeposit-00-postings.spp

Download original file · Bank deposit source contents

1domain cboddeposit;23// KSADEP0 6100: business amount categories before runtime accounting rule selection.45Role DepositAccounting {6    BigDecimal(19, 2) transactionAmount;7    BigDecimal(19, 2) depositIncrease;8    BigDecimal(19, 2) depositDecrease;9    BigDecimal(19, 2) principalPaid;10    BigDecimal(19, 2) interestPaid;11    BigDecimal(19, 2) collectionPaid;12    BigDecimal(19, 2) fundingTotal;13    BigDecimal(19, 2) allocationTotal;14}1516atomic calculate classifyDepositAccounting(DepositRequest, DepositPlan, DepositAccounting) {17    DepositAccounting.transactionAmount = DepositRequest.amount;18    DepositAccounting.depositIncrease = DepositPlan.interestBaseIncrease;19    DepositAccounting.depositDecrease = DepositPlan.interestBaseDecrease;20    DepositAccounting.principalPaid = DepositPlan.principalPaid;21    DepositAccounting.interestPaid = DepositPlan.interestPaid;22    DepositAccounting.collectionPaid = DepositPlan.collectionInterestPaid;23    DepositAccounting.fundingTotal = DepositAccounting.transactionAmount + DepositAccounting.depositDecrease;24    DepositAccounting.allocationTotal = DepositAccounting.depositIncrease25        + DepositAccounting.principalPaid26        + DepositAccounting.interestPaid27        + DepositAccounting.collectionPaid;28}2930atomic check checkDepositAccounting(DepositAccounting) {31    require(32        DepositAccounting.transactionAmount >= 033            && DepositAccounting.depositIncrease >= 034            && DepositAccounting.depositDecrease >= 035            && DepositAccounting.principalPaid >= 036            && DepositAccounting.interestPaid >= 037            && DepositAccounting.collectionPaid >= 0,38        "NEGATIVE_DEPOSIT_ACCOUNTING_AMOUNT"39    );40    require(41        DepositAccounting.fundingTotal == DepositAccounting.transactionAmount42            + DepositAccounting.depositDecrease43            && DepositAccounting.allocationTotal == DepositAccounting.depositIncrease44            + DepositAccounting.principalPaid45            + DepositAccounting.interestPaid46            + DepositAccounting.collectionPaid,47        "DEPOSIT_ACCOUNTING_TOTAL_MISMATCH"48    );49    require(50        DepositAccounting.fundingTotal == DepositAccounting.allocationTotal,51        "DEPOSIT_ACCOUNTING_NOT_BALANCED"52    );53}5455// Explicit demo rule slots, not a reconstruction of the unavailable ART subject configuration.5657Role DepositPostingLine {58    CashDepositAgreement deposit;59    int slot;60    String subject;61    String side;62    BigDecimal(19, 2) amount;63}6465Role DepositPostingTotals {66    BigDecimal(19, 2) debit;67    BigDecimal(19, 2) credit;68    BigDecimal(19, 2) fee;69}7071atomic calculate calculateDepositPostings(72    DepositAccounting,73    DepositFeePlan,74    DepositPostingLine[],75    DepositPostingTotals76) {77    DepositPostingTotals.debit = 0;78    DepositPostingTotals.credit = 0;79    DepositPostingTotals.fee = DepositFeePlan.fee;80    for (DepositPostingLine line : DepositPostingLine[]) {81        switch (line.slot) {82            case 1:83                line.amount = DepositAccounting.transactionAmount;84                break;85            case 2:86                line.amount = DepositAccounting.depositDecrease;87                break;88            case 3:89                line.amount = DepositAccounting.depositIncrease;90                break;91            case 4:92                line.amount = DepositAccounting.principalPaid;93                break;94            case 5:95                line.amount = DepositAccounting.interestPaid;96                break;97            case 6:98                line.amount = DepositAccounting.collectionPaid;99                break;100            case 7:101                line.amount = DepositFeePlan.fee;102                break;103            case 8:104                line.amount = DepositFeePlan.fee;105                break;106        }107        if (line.side == "Debit") {108            DepositPostingTotals.debit += line.amount;109        } else {110            DepositPostingTotals.credit += line.amount;111        }112    }113}114115atomic check checkDepositPostings(DepositPostingTotals) {116    require(DepositPostingTotals.debit == DepositPostingTotals.credit, "DEPOSIT_POSTINGS_NOT_BALANCED");117}118119atomic check checkPostingRules(DepositPostingLine[], DepositFeePlan) {120    int expected = 1;121    for (DepositPostingLine line : DepositPostingLine[]) {122        require(123            line.slot == expected && line.subject != null && line.subject != "",124            "INVALID_DEPOSIT_POSTING_RULES"125        );126        if (line.slot == 1 || line.slot == 2 || line.slot == 7) {127            require(line.side == "Debit", "INVALID_DEPOSIT_POSTING_SIDE");128        } else {129            require(line.side == "Credit", "INVALID_DEPOSIT_POSTING_SIDE");130        }131        expected++;132    }133    require(expected == 9 && DepositFeePlan.fee >= 0, "INVALID_DEPOSIT_POSTING_RULES");134}135136atomic calculate attachDepositPostings(CashDepositAgreement, DepositPostingLine[]) {137    for (DepositPostingLine line : DepositPostingLine[]) {138        line.deposit = CashDepositAgreement;139    }140}141142atomic calculate preserveDepositPostingEvidence(CashDepositAgreement, DepositPostingLine[]) {143    CashDepositAgreement.postingEvidence = new DepositPostingLine[] {144    };145    for (DepositPostingLine line : DepositPostingLine[]) {146        DepositPostingLine evidence = new DepositPostingLine();147        evidence.slot = line.slot;148        evidence.subject = line.subject;149        evidence.side = line.side;150        evidence.amount = line.amount;151        CashDepositAgreement.postingEvidence = append(CashDepositAgreement.postingEvidence, evidence);152    }153}