mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-16 13:49:53 +05:00
AccountS - debitUsage without startTime, standalone processAttributes method
This commit is contained in:
@@ -19,8 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package accounts
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/ericlagergren/decimal"
|
||||
@@ -94,30 +92,6 @@ func (aB *abstractBalance) balanceLimit() (bL *utils.Decimal) {
|
||||
return
|
||||
}
|
||||
|
||||
// processAttributeS will process the event with AttributeS
|
||||
func (aB *abstractBalance) processAttributeS(cgrEv *utils.CGREvent) (rplyEv *engine.AttrSProcessEventReply, err error) {
|
||||
if len(aB.attrSConns) == 0 {
|
||||
return nil, utils.NewErrNotConnected(utils.AttributeS)
|
||||
}
|
||||
var procRuns *int
|
||||
if val, has := cgrEv.Opts[utils.OptsAttributesProcessRuns]; has {
|
||||
if v, err := utils.IfaceAsTInt64(val); err == nil {
|
||||
procRuns = utils.IntPointer(int(v))
|
||||
}
|
||||
}
|
||||
attrArgs := &engine.AttrArgsProcessEvent{
|
||||
Context: utils.StringPointer(utils.FirstNonEmpty(
|
||||
engine.MapEvent(cgrEv.Opts).GetStringIgnoreErrors(utils.OptsContext),
|
||||
utils.MetaAccountS)),
|
||||
CGREvent: cgrEv,
|
||||
AttributeIDs: aB.blnCfg.AttributeIDs,
|
||||
ProcessRuns: procRuns,
|
||||
}
|
||||
err = aB.connMgr.Call(aB.attrSConns, nil, utils.AttributeSv1ProcessEvent,
|
||||
attrArgs, &rplyEv)
|
||||
return
|
||||
}
|
||||
|
||||
// rateSCostForEvent will process the event with RateS in order to get the cost
|
||||
func (aB *abstractBalance) rateSCostForEvent(cgrEv *utils.CGREvent) (rplyCost *engine.RateProfileCost, err error) {
|
||||
if len(aB.rateSConns) == 0 {
|
||||
@@ -177,7 +151,7 @@ func (aB *abstractBalance) debitUsageFromConcrete(usage *utils.Decimal,
|
||||
}
|
||||
|
||||
// debitUsage implements the balanceOperator interface
|
||||
func (aB *abstractBalance) debitUsage(usage *utils.Decimal, startTime time.Time,
|
||||
func (aB *abstractBalance) debitUsage(usage *utils.Decimal,
|
||||
cgrEv *utils.CGREvent) (dbted *utils.Decimal, ec *utils.EventCharges, err error) {
|
||||
|
||||
evNm := utils.MapStorage{
|
||||
@@ -202,7 +176,8 @@ func (aB *abstractBalance) debitUsage(usage *utils.Decimal, startTime time.Time,
|
||||
costIcrm.FixedFee == nil &&
|
||||
len(aB.blnCfg.AttributeIDs) != 0 { // cost unknown, apply AttributeS to query from RateS
|
||||
var rplyAttrS *engine.AttrSProcessEventReply
|
||||
if rplyAttrS, err = aB.processAttributeS(cgrEv); err != nil {
|
||||
if rplyAttrS, err = processAttributeS(aB.connMgr, cgrEv, aB.attrSConns,
|
||||
aB.blnCfg.AttributeIDs); err != nil {
|
||||
return
|
||||
}
|
||||
if len(rplyAttrS.AlteredFields) != 0 { // event was altered
|
||||
|
||||
@@ -133,8 +133,8 @@ func TestABDebitUsage(t *testing.T) {
|
||||
fltrS: new(engine.FilterS),
|
||||
}
|
||||
|
||||
if dbted, _, err := aB.debitUsage(utils.NewDecimal(int64(time.Duration(30*time.Second)), 0),
|
||||
time.Now(), new(utils.CGREvent)); err != nil {
|
||||
if dbted, _, err := aB.debitUsage(utils.NewDecimal(int64(30*time.Second), 0),
|
||||
new(utils.CGREvent)); err != nil {
|
||||
t.Error(err)
|
||||
} else if dbted.Compare(utils.NewDecimal(int64(30*time.Second), 0)) != 0 {
|
||||
t.Errorf("Unexpected debited units: %s", dbted)
|
||||
@@ -148,8 +148,8 @@ func TestABDebitUsage(t *testing.T) {
|
||||
aB.blnCfg.Units = utils.NewDecimal(int64(time.Duration(60*time.Second)), 0)
|
||||
aB.cncrtBlncs[0].blnCfg.Units = utils.NewDecimal(29, 0) // not enough concrete
|
||||
|
||||
if dbted, _, err := aB.debitUsage(utils.NewDecimal(int64(time.Duration(30*time.Second)), 0),
|
||||
time.Now(), new(utils.CGREvent)); err != nil {
|
||||
if dbted, _, err := aB.debitUsage(utils.NewDecimal(int64(30*time.Second), 0),
|
||||
new(utils.CGREvent)); err != nil {
|
||||
t.Error(err)
|
||||
} else if dbted.Compare(utils.NewDecimal(int64(29*time.Second), 0)) != 0 {
|
||||
t.Errorf("Unexpected debited units: %s", dbted)
|
||||
@@ -162,12 +162,12 @@ func TestABDebitUsage(t *testing.T) {
|
||||
// limited by concrete
|
||||
aB.cncrtBlncs[0].blnCfg.Units = utils.NewDecimal(0, 0) // not enough concrete
|
||||
|
||||
if dbted, _, err := aB.debitUsage(utils.NewDecimal(int64(time.Duration(30*time.Second)), 0),
|
||||
time.Now(), new(utils.CGREvent)); err != nil {
|
||||
if dbted, _, err := aB.debitUsage(utils.NewDecimal(int64(30*time.Second), 0),
|
||||
new(utils.CGREvent)); err != nil {
|
||||
t.Error(err)
|
||||
} else if dbted.Compare(utils.NewDecimal(0, 0)) != 0 {
|
||||
t.Errorf("Unexpected debited units: %s", dbted)
|
||||
} else if aB.blnCfg.Units.Compare(utils.NewDecimal(int64(time.Duration(31*time.Second)), 0)) != 0 { // same as above
|
||||
} else if aB.blnCfg.Units.Compare(utils.NewDecimal(int64(31*time.Second), 0)) != 0 { // same as above
|
||||
t.Errorf("Unexpected units in abstract balance: %s", aB.blnCfg.Units)
|
||||
} else if aB.cncrtBlncs[0].blnCfg.Units.Compare(utils.NewDecimal(0, 0)) != 0 { // same as above
|
||||
t.Errorf("Unexpected units in concrete balance: %s", aB.cncrtBlncs[0].blnCfg.Units)
|
||||
@@ -177,10 +177,10 @@ func TestABDebitUsage(t *testing.T) {
|
||||
aB.blnCfg.Units = utils.NewDecimal(int64(time.Duration(29*time.Second)), 0) // not enough abstract
|
||||
aB.cncrtBlncs[0].blnCfg.Units = utils.NewDecimal(60, 0)
|
||||
|
||||
if dbted, _, err := aB.debitUsage(utils.NewDecimal(int64(time.Duration(30*time.Second)), 0),
|
||||
time.Now(), new(utils.CGREvent)); err != nil {
|
||||
if dbted, _, err := aB.debitUsage(utils.NewDecimal(int64(30*time.Second), 0),
|
||||
new(utils.CGREvent)); err != nil {
|
||||
t.Error(err)
|
||||
} else if dbted.Compare(utils.NewDecimal(int64(time.Duration(29*time.Second)), 0)) != 0 {
|
||||
} else if dbted.Compare(utils.NewDecimal(int64(29*time.Second), 0)) != 0 {
|
||||
t.Errorf("Unexpected debited units: %s", dbted)
|
||||
} else if aB.blnCfg.Units.Compare(utils.NewDecimal(0, 0)) != 0 { // should be all used
|
||||
t.Errorf("Unexpected units in abstract balance: %s", aB.blnCfg.Units)
|
||||
|
||||
@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package accounts
|
||||
|
||||
import (
|
||||
"time"
|
||||
"fmt"
|
||||
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
@@ -91,26 +91,6 @@ func (cB *concreteBalance) balanceLimit() (bL *utils.Decimal) {
|
||||
return
|
||||
}
|
||||
|
||||
// debit implements the balanceOperator interface
|
||||
func (cB *concreteBalance) debitUsage(usage *utils.Decimal, startTime time.Time,
|
||||
cgrEv *utils.CGREvent) (dbted *utils.Decimal, ec *utils.EventCharges, err error) {
|
||||
|
||||
evNm := utils.MapStorage{
|
||||
utils.MetaOpts: cgrEv.Opts,
|
||||
utils.MetaReq: cgrEv.Event,
|
||||
}
|
||||
|
||||
// pass the general balance filters
|
||||
var pass bool
|
||||
if pass, err = cB.fltrS.Pass(cgrEv.Tenant, cB.blnCfg.FilterIDs, evNm); err != nil {
|
||||
return
|
||||
} else if !pass {
|
||||
return nil, nil, utils.ErrFilterNotPassingNoCaps
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// debitUnits is a direct debit of balance units
|
||||
func (cB *concreteBalance) debitUnits(dUnts *utils.Decimal, tnt string,
|
||||
ev utils.DataProvider) (dbted *utils.Decimal, uF *utils.UnitFactor, err error) {
|
||||
@@ -158,6 +138,72 @@ func (cB *concreteBalance) debitUnits(dUnts *utils.Decimal, tnt string,
|
||||
return
|
||||
}
|
||||
|
||||
// debit implements the balanceOperator interface
|
||||
func (cB *concreteBalance) debitUsage(usage *utils.Decimal,
|
||||
cgrEv *utils.CGREvent) (dbted *utils.Decimal, ec *utils.EventCharges, err error) {
|
||||
|
||||
evNm := utils.MapStorage{
|
||||
utils.MetaOpts: cgrEv.Opts,
|
||||
utils.MetaReq: cgrEv.Event,
|
||||
}
|
||||
|
||||
// pass the general balance filters
|
||||
var pass bool
|
||||
if pass, err = cB.fltrS.Pass(cgrEv.Tenant, cB.blnCfg.FilterIDs, evNm); err != nil {
|
||||
return
|
||||
} else if !pass {
|
||||
return nil, nil, utils.ErrFilterNotPassingNoCaps
|
||||
}
|
||||
|
||||
// costIncrement
|
||||
var costIcrm *utils.CostIncrement
|
||||
if costIcrm, err = cB.costIncrement(cgrEv.Tenant, evNm); err != nil {
|
||||
return
|
||||
}
|
||||
if costIcrm.RecurrentFee.Cmp(decimal.New(-1, 0)) == 0 &&
|
||||
costIcrm.FixedFee == nil &&
|
||||
len(cB.blnCfg.AttributeIDs) != 0 { // cost unknown, apply AttributeS to query from RateS
|
||||
var rplyAttrS *engine.AttrSProcessEventReply
|
||||
if rplyAttrS, err = processAttributeS(cB.connMgr, cgrEv, cB.attrSConns,
|
||||
cB.blnCfg.AttributeIDs); err != nil {
|
||||
return
|
||||
}
|
||||
if len(rplyAttrS.AlteredFields) != 0 { // event was altered
|
||||
cgrEv = rplyAttrS.CGREvent
|
||||
}
|
||||
}
|
||||
|
||||
// balanceLimit
|
||||
var hasLmt bool
|
||||
blncLmt := cB.balanceLimit()
|
||||
if blncLmt != nil && blncLmt.Cmp(decimal.New(0, 0)) != 0 {
|
||||
cB.blnCfg.Units.Big = utils.SubstractBig(cB.blnCfg.Units.Big, blncLmt.Big)
|
||||
hasLmt = true
|
||||
}
|
||||
|
||||
// unitFactor
|
||||
var uF *utils.UnitFactor
|
||||
if uF, err = cB.unitFactor(cgrEv.Tenant, evNm); err != nil {
|
||||
return
|
||||
}
|
||||
var hasUF bool
|
||||
if uF != nil && uF.Factor.Cmp(decimal.New(1, 0)) != 0 {
|
||||
usage.Big = utils.MultiplyBig(usage.Big, uF.Factor.Big)
|
||||
hasUF = true
|
||||
}
|
||||
|
||||
// balance smaller than usage, correct usage
|
||||
if cB.blnCfg.Units.Compare(usage) == -1 {
|
||||
// decrease the usage to match the maximum increments
|
||||
// will use special rounding to 0 since otherwise we go negative (ie: 0.05 as increment)
|
||||
usage.Big = roundedUsageWithIncrements(cB.blnCfg.Units.Big, costIcrm.Increment.Big)
|
||||
}
|
||||
|
||||
fmt.Printf("hasLmt: %v, hasUF: %v\n", hasLmt, hasUF)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// cloneUnitsFromConcretes returns cloned units from the concrete balances passed as parameters
|
||||
func cloneUnitsFromConcretes(cBs []*concreteBalance) (clnedUnts []*utils.Decimal) {
|
||||
if cBs == nil {
|
||||
@@ -170,6 +216,7 @@ func cloneUnitsFromConcretes(cBs []*concreteBalance) (clnedUnts []*utils.Decimal
|
||||
return
|
||||
}
|
||||
|
||||
// restoreUnitsFromClones will restore the units from the clones
|
||||
func restoreUnitsFromClones(cBs []*concreteBalance, clnedUnts []*utils.Decimal) {
|
||||
for i, clnedUnt := range clnedUnts {
|
||||
cBs[i].blnCfg.Units.Big = clnedUnt.Big
|
||||
|
||||
@@ -20,7 +20,6 @@ package accounts
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
@@ -91,8 +90,7 @@ func newBalanceOperator(blncCfg *utils.Balance, cncrtBlncs []*concreteBalance,
|
||||
|
||||
// balanceOperator is the implementation of a balance type
|
||||
type balanceOperator interface {
|
||||
debitUsage(usage *utils.Decimal, startTime time.Time,
|
||||
cgrEv *utils.CGREvent) (dbted *utils.Decimal, ec *utils.EventCharges, err error)
|
||||
debitUsage(usage *utils.Decimal, cgrEv *utils.CGREvent) (dbted *utils.Decimal, ec *utils.EventCharges, err error)
|
||||
}
|
||||
|
||||
// roundUsageWithIncrements rounds the usage based on increments
|
||||
@@ -103,3 +101,28 @@ func roundedUsageWithIncrements(usage, incrm *decimal.Big) (rndedUsage *decimal.
|
||||
rndedUsage = utils.MultiplyBig(usgMaxIncrm, incrm)
|
||||
return
|
||||
}
|
||||
|
||||
// processAttributeS will process the event with AttributeS
|
||||
func processAttributeS(connMgr *engine.ConnManager, cgrEv *utils.CGREvent,
|
||||
attrSConns, attrIDs []string) (rplyEv *engine.AttrSProcessEventReply, err error) {
|
||||
if len(attrSConns) == 0 {
|
||||
return nil, utils.NewErrNotConnected(utils.AttributeS)
|
||||
}
|
||||
var procRuns *int
|
||||
if val, has := cgrEv.Opts[utils.OptsAttributesProcessRuns]; has {
|
||||
if v, err := utils.IfaceAsTInt64(val); err == nil {
|
||||
procRuns = utils.IntPointer(int(v))
|
||||
}
|
||||
}
|
||||
attrArgs := &engine.AttrArgsProcessEvent{
|
||||
Context: utils.StringPointer(utils.FirstNonEmpty(
|
||||
engine.MapEvent(cgrEv.Opts).GetStringIgnoreErrors(utils.OptsContext),
|
||||
utils.MetaAccountS)),
|
||||
CGREvent: cgrEv,
|
||||
AttributeIDs: attrIDs,
|
||||
ProcessRuns: procRuns,
|
||||
}
|
||||
err = connMgr.Call(attrSConns, nil, utils.AttributeSv1ProcessEvent,
|
||||
attrArgs, &rplyEv)
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user