mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
AccountS debitUsage returning usage within EventCharges
This commit is contained in:
@@ -43,7 +43,7 @@ type abstractBalance struct {
|
||||
|
||||
// debitUsage implements the balanceOperator interface
|
||||
func (aB *abstractBalance) debitUsage(usage *utils.Decimal,
|
||||
cgrEv *utils.CGREvent) (dbted *utils.Decimal, ec *utils.EventCharges, err error) {
|
||||
cgrEv *utils.CGREvent) (ec *utils.EventCharges, err error) {
|
||||
|
||||
evNm := utils.MapStorage{
|
||||
utils.MetaOpts: cgrEv.Opts,
|
||||
@@ -55,7 +55,7 @@ func (aB *abstractBalance) debitUsage(usage *utils.Decimal,
|
||||
if pass, err = aB.fltrS.Pass(cgrEv.Tenant, aB.blnCfg.FilterIDs, evNm); err != nil {
|
||||
return
|
||||
} else if !pass {
|
||||
return nil, nil, utils.ErrFilterNotPassingNoCaps
|
||||
return nil, utils.ErrFilterNotPassingNoCaps
|
||||
}
|
||||
|
||||
// balanceLimit
|
||||
@@ -95,7 +95,7 @@ func (aB *abstractBalance) debitUsage(usage *utils.Decimal,
|
||||
}
|
||||
|
||||
// attempt to debit usage with cost
|
||||
if dbted, ec, err = maxDebitUsageFromConcretes(aB.cncrtBlncs, usage,
|
||||
if ec, err = maxDebitUsageFromConcretes(aB.cncrtBlncs, usage,
|
||||
aB.connMgr, cgrEv,
|
||||
aB.attrSConns, aB.blnCfg.AttributeIDs,
|
||||
aB.rateSConns, aB.blnCfg.RateProfileIDs,
|
||||
@@ -103,8 +103,8 @@ func (aB *abstractBalance) debitUsage(usage *utils.Decimal,
|
||||
return
|
||||
}
|
||||
|
||||
if dbted.Cmp(decimal.New(0, 0)) != 0 {
|
||||
aB.blnCfg.Units.Big = utils.SubstractBig(aB.blnCfg.Units.Big, dbted.Big)
|
||||
if ec.Usage.Cmp(decimal.New(0, 0)) != 0 {
|
||||
aB.blnCfg.Units.Big = utils.SubstractBig(aB.blnCfg.Units.Big, ec.Usage)
|
||||
}
|
||||
if hasLmt { // put back the limit
|
||||
aB.blnCfg.Units.Big = utils.SumBig(aB.blnCfg.Units.Big, blncLmt.Big)
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/ericlagergren/decimal"
|
||||
)
|
||||
|
||||
func TestdebitUsageFromConcretes(t *testing.T) {
|
||||
@@ -133,11 +134,11 @@ func TestABDebitUsage(t *testing.T) {
|
||||
fltrS: new(engine.FilterS),
|
||||
}
|
||||
|
||||
if dbted, _, err := aB.debitUsage(utils.NewDecimal(int64(30*time.Second), 0),
|
||||
if ec, 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)
|
||||
} else if ec.Usage.Cmp(decimal.New(int64(30*time.Second), 0)) != 0 {
|
||||
t.Errorf("Unexpected debited units: %s", ec.Usage)
|
||||
} else if aB.blnCfg.Units.Compare(utils.NewDecimal(int64(30*time.Second), 0)) != 0 {
|
||||
t.Errorf("Unexpected units in abstract balance: %s", aB.blnCfg.Units)
|
||||
} else if aB.cncrtBlncs[0].blnCfg.Units.Compare(utils.NewDecimal(20, 0)) != 0 {
|
||||
@@ -148,11 +149,11 @@ 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(30*time.Second), 0),
|
||||
if ec, 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)
|
||||
} else if ec.Usage.Cmp(decimal.New(int64(29*time.Second), 0)) != 0 {
|
||||
t.Errorf("Unexpected debited units: %s", ec.Usage)
|
||||
} else if aB.blnCfg.Units.Compare(utils.NewDecimal(int64(time.Duration(31*time.Second)), 0)) != 0 { // used 29 units
|
||||
t.Errorf("Unexpected units in abstract balance: %s", aB.blnCfg.Units)
|
||||
} else if aB.cncrtBlncs[0].blnCfg.Units.Compare(utils.NewDecimal(0, 0)) != 0 {
|
||||
@@ -162,11 +163,11 @@ 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(30*time.Second), 0),
|
||||
if ec, 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 ec.Usage.Cmp(decimal.New(0, 0)) != 0 {
|
||||
t.Errorf("Unexpected debited units: %s", ec.Usage)
|
||||
} 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
|
||||
@@ -177,11 +178,11 @@ 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(30*time.Second), 0),
|
||||
if ec, 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)
|
||||
} else if ec.Usage.Cmp(decimal.New(int64(29*time.Second), 0)) != 0 {
|
||||
t.Errorf("Unexpected debited units: %s", ec.Usage)
|
||||
} 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)
|
||||
} else if aB.cncrtBlncs[0].blnCfg.Units.Compare(utils.NewDecimal(31, 0)) != 0 {
|
||||
|
||||
@@ -151,14 +151,15 @@ func (aS *AccountS) accountProcessEvent(acnt *utils.AccountProfile,
|
||||
if usage.Big.Cmp(decimal.New(0, 0)) == 0 {
|
||||
return // no more debit
|
||||
}
|
||||
var dbted *utils.Decimal
|
||||
if dbted, _, err = blncOper.debitUsage(usage, cgrEv); err != nil {
|
||||
var ecDbt *utils.EventCharges
|
||||
if ec, err = blncOper.debitUsage(usage, cgrEv); err != nil {
|
||||
if err == utils.ErrFilterNotPassingNoCaps {
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
}
|
||||
usage.Big = utils.SubstractBig(usage.Big, dbted.Big)
|
||||
usage.Big = utils.SubstractBig(usage.Big, ecDbt.Usage)
|
||||
ec.Merge(ecDbt)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ func (cB *concreteBalance) debitUnits(dUnts *utils.Decimal, tnt string,
|
||||
|
||||
// debit implements the balanceOperator interface
|
||||
func (cB *concreteBalance) debitUsage(usage *utils.Decimal,
|
||||
cgrEv *utils.CGREvent) (dbted *utils.Decimal, ec *utils.EventCharges, err error) {
|
||||
cgrEv *utils.CGREvent) (ec *utils.EventCharges, err error) {
|
||||
|
||||
evNm := utils.MapStorage{
|
||||
utils.MetaOpts: cgrEv.Opts,
|
||||
@@ -123,7 +123,7 @@ func (cB *concreteBalance) debitUsage(usage *utils.Decimal,
|
||||
if pass, err = cB.fltrS.Pass(cgrEv.Tenant, cB.blnCfg.FilterIDs, evNm); err != nil {
|
||||
return
|
||||
} else if !pass {
|
||||
return nil, nil, utils.ErrFilterNotPassingNoCaps
|
||||
return nil, utils.ErrFilterNotPassingNoCaps
|
||||
}
|
||||
|
||||
// costIncrement
|
||||
@@ -145,7 +145,8 @@ func (cB *concreteBalance) debitUsage(usage *utils.Decimal,
|
||||
}
|
||||
}
|
||||
|
||||
return maxDebitUsageFromConcretes([]*concreteBalance{cB}, usage,
|
||||
return maxDebitUsageFromConcretes(
|
||||
[]*concreteBalance{cB}, usage,
|
||||
cB.connMgr, cgrEv,
|
||||
cB.attrSConns, cB.blnCfg.AttributeIDs,
|
||||
cB.rateSConns, cB.blnCfg.RateProfileIDs,
|
||||
|
||||
@@ -75,7 +75,7 @@ func newBalanceOperator(blncCfg *utils.Balance, cncrtBlncs []*concreteBalance,
|
||||
|
||||
// balanceOperator is the implementation of a balance type
|
||||
type balanceOperator interface {
|
||||
debitUsage(usage *utils.Decimal, cgrEv *utils.CGREvent) (dbted *utils.Decimal, ec *utils.EventCharges, err error)
|
||||
debitUsage(usage *utils.Decimal, cgrEv *utils.CGREvent) (ec *utils.EventCharges, err error)
|
||||
}
|
||||
|
||||
// roundUsageWithIncrements rounds the usage based on increments
|
||||
@@ -234,7 +234,7 @@ func debitUsageFromConcretes(cncrtBlncs []*concreteBalance, usage *utils.Decimal
|
||||
func maxDebitUsageFromConcretes(cncrtBlncs []*concreteBalance, usage *utils.Decimal,
|
||||
connMgr *engine.ConnManager, cgrEv *utils.CGREvent,
|
||||
attrSConns, attributeIDs, rateSConns, rpIDs []string,
|
||||
costIcrm *utils.CostIncrement) (dbtedUsage *utils.Decimal, ec *utils.EventCharges, err error) {
|
||||
costIcrm *utils.CostIncrement) (ec *utils.EventCharges, err error) {
|
||||
|
||||
// process AttributeS if needed
|
||||
if costIcrm.RecurrentFee.Cmp(decimal.New(-1, 0)) == 0 &&
|
||||
@@ -260,7 +260,7 @@ func maxDebitUsageFromConcretes(cncrtBlncs []*concreteBalance, usage *utils.Deci
|
||||
restoreUnitsFromClones(cncrtBlncs, origConcrtUnts)
|
||||
}
|
||||
if i == maxItr {
|
||||
return nil, nil, utils.ErrMaxIncrementsExceeded
|
||||
return nil, utils.ErrMaxIncrementsExceeded
|
||||
}
|
||||
qriedUsage := usage.Big // so we can detect loops
|
||||
if err = debitUsageFromConcretes(cncrtBlncs, usage, costIcrm, cgrEv,
|
||||
@@ -308,5 +308,5 @@ func maxDebitUsageFromConcretes(cncrtBlncs []*concreteBalance, usage *utils.Deci
|
||||
usagePaid = decimal.New(0, 0)
|
||||
}
|
||||
restoreUnitsFromClones(cncrtBlncs, paidConcrtUnts)
|
||||
return &utils.Decimal{usagePaid}, nil, nil
|
||||
return &utils.EventCharges{Usage: usagePaid}, nil
|
||||
}
|
||||
|
||||
@@ -19,14 +19,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package utils
|
||||
|
||||
import (
|
||||
"time"
|
||||
"errors"
|
||||
|
||||
"github.com/ericlagergren/decimal"
|
||||
)
|
||||
|
||||
// EventCharges records the charges applied to an Event
|
||||
type EventCharges struct {
|
||||
StartTime *time.Time
|
||||
Usage *decimal.Big
|
||||
Cost *decimal.Big
|
||||
Charges []*ChargedInterval
|
||||
@@ -34,3 +33,41 @@ type EventCharges struct {
|
||||
Accounting *ChargedAccounting
|
||||
Rating *ChargedRating
|
||||
}
|
||||
|
||||
// Merge will merge the event charges into existing
|
||||
func (ec *EventCharges) Merge(eCs ...*EventCharges) {
|
||||
for _, nEc := range eCs {
|
||||
if ec.Usage == nil {
|
||||
ec.Usage = nEc.Usage
|
||||
continue
|
||||
}
|
||||
ec.Usage = SumBig(ec.Usage, nEc.Usage)
|
||||
}
|
||||
}
|
||||
|
||||
// AsExtEventCharges converts EventCharges to ExtEventCharges
|
||||
func (ec *EventCharges) AsExtEventCharges() (eEc *ExtEventCharges, err error) {
|
||||
eEc = new(ExtEventCharges)
|
||||
if ec.Usage != nil {
|
||||
if flt, ok := ec.Usage.Float64(); !ok {
|
||||
return nil, errors.New("cannot convert decimal Usage to float64")
|
||||
} else {
|
||||
eEc.Usage = &flt
|
||||
}
|
||||
}
|
||||
if ec.Cost != nil {
|
||||
if flt, ok := ec.Cost.Float64(); !ok {
|
||||
return nil, errors.New("cannot convert decimal Cost to float64")
|
||||
} else {
|
||||
eEc.Cost = &flt
|
||||
}
|
||||
}
|
||||
// add here code for the rest of the fields
|
||||
return
|
||||
}
|
||||
|
||||
// ExtEventCharges is a generic EventCharges used in APIs
|
||||
type ExtEventCharges struct {
|
||||
Usage *float64
|
||||
Cost *float64
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user