AccountS - centralized costIncrement, unitFactor, balanceLimit in concreteBalance

This commit is contained in:
DanB
2021-01-04 14:08:27 +01:00
parent dc5ecf9956
commit de5834219b

View File

@@ -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
}