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

cboddeposit-30-agreement-product.spp

cboddeposit/accrual/cboddeposit-30-agreement-product.spp

Download original file · Bank deposit source contents

1domain cboddeposit;23// CSAPRD2 5500/5555: retain the five source slots, traversed 5 down to 1.4// Normal and agreement periods have already been clipped/decoded by calendar services.56Role AgreementBand {7    int slot;8    BigDecimal(19, 2) threshold;9    BigDecimal(19, 2) product;10}1112Role AgreementPolicy {13    String mode;14    String currency;15    boolean enabled;16}1718Role AgreementProduct {19    BigDecimal(19, 2) normalProduct;20    BigDecimal(19, 2) bandProduct;21    BigDecimal(19, 2) remainingAmount;22    int selectedSlot;23    String appliedMode;24}2526atomic calculate calculateAgreementProduct(27    InterestPeriod normal,28    InterestPeriod overlap,29    AgreementPolicy,30    AgreementBand[],31    AgreementProduct32) {33    AgreementProduct.normalProduct = roundDown(normal.amount / normal.unit, 0) * normal.unit * normal.days;34    AgreementProduct.bandProduct = 0;35    AgreementProduct.remainingAmount = normal.amount;36    AgreementProduct.selectedSlot = 0;37    AgreementProduct.appliedMode = AgreementPolicy.mode;38    if (AgreementPolicy.mode != "1" && AgreementPolicy.mode != "2") {39        if (AgreementPolicy.currency == "CNY") {40            AgreementProduct.appliedMode = "2";41        } else {42            AgreementProduct.appliedMode = "1";43        }44    }45    for (AgreementBand band : AgreementBand[]) {46        band.product = 0;47    }48    if (AgreementPolicy.enabled && overlap.days > 0) {49        for (AgreementBand band : AgreementBand[]) {50            if (AgreementProduct.appliedMode == "2") {51                if (AgreementProduct.remainingAmount > band.threshold) {52                    band.product = roundDown(53                        (AgreementProduct.remainingAmount - band.threshold) / normal.unit,54                        055                    ) * normal.unit * overlap.days;56                    AgreementProduct.bandProduct += band.product;57                    AgreementProduct.remainingAmount = band.threshold;58                    if (band.slot == 1) {59                        AgreementProduct.normalProduct -= roundDown(60                            (normal.amount - band.threshold) / normal.unit,61                            062                        ) * normal.unit * overlap.days;63                    }64                }65            } else {66                if (normal.amount >= band.threshold) {67                    band.product = roundDown(normal.amount / normal.unit, 0) * normal.unit * overlap.days;68                    AgreementProduct.bandProduct = band.product;69                    AgreementProduct.normalProduct -= band.product;70                    AgreementProduct.selectedSlot = band.slot;71                    break;72                }73            }74        }75    }76}7778atomic check checkAgreementProductInput(InterestPeriod normal, InterestPeriod overlap, AgreementBand[]) {79    require(normal.amount >= 0 && normal.unit > 0 && normal.days >= 0, "INVALID_INTEREST_PERIOD");80    require(81        overlap.amount == normal.amount82            && overlap.unit == normal.unit83            && overlap.days >= 084            && overlap.days <= normal.days,85        "INVALID_AGREEMENT_PERIOD"86    );87    int expectedSlot = 5;88    for (AgreementBand band : AgreementBand[]) {89        require(band.slot == expectedSlot && band.threshold >= 0, "INVALID_AGREEMENT_BANDS");90        expectedSlot--;91    }92    require(expectedSlot == 0, "INVALID_AGREEMENT_BANDS");93}