From de5834219bb896892bcafc5d92453aa4ebd5eae3 Mon Sep 17 00:00:00 2001 From: DanB Date: Mon, 4 Jan 2021 14:08:27 +0100 Subject: [PATCH] AccountS - centralized costIncrement, unitFactor, balanceLimit in concreteBalance --- accounts/concretebalance.go | 91 ++++++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 22 deletions(-) diff --git a/accounts/concretebalance.go b/accounts/concretebalance.go index fbc67784a..233762901 100644 --- a/accounts/concretebalance.go +++ b/accounts/concretebalance.go @@ -41,6 +41,55 @@ type concreteBalance struct { ralsConns []string } +// costIncrement finds out the cost increment for the event +func (cB *concreteBalance) costIncrement(tnt string, ev utils.DataProvider) (costIcrm *utils.CostIncrement, err error) { + for _, cIcrm := range cB.blnCfg.CostIncrements { + var pass bool + if pass, err = cB.fltrS.Pass(tnt, cIcrm.FilterIDs, ev); err != nil { + return + } else if !pass { + continue + } + costIcrm = cIcrm.Clone() // need clone since we might modify + return + } + // nothing matched, return default + costIcrm = &utils.CostIncrement{ + Increment: decimal.New(1, 0), + RecurrentFee: decimal.New(-1, 0)} + + return +} + +// unitFactor returns the unitFactor for the event +func (cB *concreteBalance) unitFactor(tnt string, ev utils.DataProvider) (uF *utils.UnitFactor, err error) { + for _, uF = range cB.blnCfg.UnitFactors { + var pass bool + if pass, err = cB.fltrS.Pass(tnt, uF.FilterIDs, ev); err != nil { + return + } else if !pass { + continue + } + return + } + // nothing matched, return default + uF = &utils.UnitFactor{ + Factor: decimal.New(1, 0), + } + return +} + +// balanceLimit returns the balance's limit +func (cB *concreteBalance) balanceLimit() (bL *decimal.Big) { + if lmtIface, has := cB.blnCfg.Opts[utils.MetaBalanceLimit]; has { + bL = lmtIface.(*decimal.Big) + return + } + // nothing matched, return default + bL = decimal.New(0, 0) + return +} + // debit implements the balanceOperator interface func (cB *concreteBalance) debitUsage(usage *decimal.Big, startTime time.Time, cgrEv *utils.CGREventWithOpts) (ec *utils.EventCharges, err error) { @@ -63,45 +112,43 @@ func (cB *concreteBalance) debitUsage(usage *decimal.Big, startTime time.Time, // debitUnits is a direct debit of balance units func (cB *concreteBalance) debitUnits(dUnts *decimal.Big, incrm *decimal.Big, - cgrEv *utils.CGREventWithOpts) (dbted *decimal.Big, mtchedUF *utils.UnitFactor, err error) { + cgrEv *utils.CGREventWithOpts) (dbted *decimal.Big, uF *utils.UnitFactor, err error) { evNm := utils.MapStorage{ utils.MetaOpts: cgrEv.Opts, utils.MetaReq: cgrEv.Event, } - // dynamic unit factor - fctr := decimal.New(1, 0) - for _, uF := range cB.blnCfg.UnitFactors { - var pass bool - if pass, err = cB.fltrS.Pass(cgrEv.CGREvent.Tenant, uF.FilterIDs, evNm); err != nil { - return nil, nil, err - } else if !pass { - continue - } - fctr = uF.Factor - mtchedUF = uF - break + // pass the general balance filters + var pass bool + if pass, err = cB.fltrS.Pass(cgrEv.CGREvent.Tenant, cB.blnCfg.FilterIDs, evNm); err != nil { + return + } else if !pass { + return nil, nil, utils.ErrFilterNotPassingNoCaps } + + // unitFactor + if uF, err = cB.unitFactor(cgrEv.CGREvent.Tenant, evNm); err != nil { + return + } + var hasUF bool - if mtchedUF != nil && fctr.Cmp(decimal.New(1, 0)) != 0 { - dUnts = utils.MultiplyBig(dUnts, fctr) - incrm = utils.MultiplyBig(incrm, fctr) + if uF.Factor.Cmp(decimal.New(1, 0)) != 0 { + dUnts = utils.MultiplyBig(dUnts, uF.Factor) + incrm = utils.MultiplyBig(incrm, uF.Factor) hasUF = true } blcVal := new(decimal.Big).SetFloat64(cB.blnCfg.Value) // FixMe without float64 - // *balanceLimit + // balanceLimit var hasLmt bool - blncLmt := decimal.New(0, 0) - if lmt, has := cB.blnCfg.Opts[utils.MetaBalanceLimit].(*decimal.Big); has { - blncLmt = lmt - } + blncLmt := cB.balanceLimit() if blncLmt.Cmp(decimal.New(0, 0)) != 0 { blcVal = utils.SubstractBig(blcVal, blncLmt) hasLmt = true } + if blcVal.Cmp(dUnts) == -1 { // balance smaller than debit maxIncrm := utils.DivideBig(blcVal, incrm).RoundToInt() dUnts = utils.MultiplyBig(incrm, maxIncrm) @@ -111,7 +158,7 @@ func (cB *concreteBalance) debitUnits(dUnts *decimal.Big, incrm *decimal.Big, rmain = utils.AddBig(rmain, blncLmt) } if hasUF { - dbted = utils.DivideBig(dUnts, fctr) + dbted = utils.DivideBig(dUnts, uF.Factor) } else { dbted = dUnts }