mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
EventCharges - adding SyncIDs method and some Equals
This commit is contained in:
@@ -19,6 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package accounts
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/ericlagergren/decimal"
|
||||
@@ -61,10 +63,10 @@ type concreteBalance struct {
|
||||
}
|
||||
|
||||
// debitAbstracts implements the balanceOperator interface
|
||||
func (cB *concreteBalance) debitAbstracts(usage *decimal.Big,
|
||||
func (cB *concreteBalance) debitAbstracts(aUnits *decimal.Big,
|
||||
cgrEv *utils.CGREvent) (ec *utils.EventCharges, err error) {
|
||||
evNm := cgrEv.AsDataProvider()
|
||||
|
||||
fmt.Printf("debitAbstracts, aUnits: %s, ev: %+v\n", aUnits, cgrEv)
|
||||
// pass the general balance filters
|
||||
var pass bool
|
||||
if pass, err = cB.fltrS.Pass(cgrEv.Tenant, cB.blnCfg.FilterIDs, evNm); err != nil {
|
||||
@@ -79,14 +81,17 @@ func (cB *concreteBalance) debitAbstracts(usage *decimal.Big,
|
||||
cB.fltrS, cgrEv.Tenant, evNm); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return maxDebitAbstractsFromConcretes(usage,
|
||||
fmt.Printf("costIcrm: %+v\n", costIcrm)
|
||||
if ec, err = maxDebitAbstractsFromConcretes(aUnits,
|
||||
cB.acntID, []*concreteBalance{cB},
|
||||
cB.connMgr, cgrEv,
|
||||
cB.attrSConns, cB.blnCfg.AttributeIDs,
|
||||
cB.rateSConns, cB.blnCfg.RateProfileIDs,
|
||||
costIcrm)
|
||||
|
||||
costIcrm); err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Printf("received ec: %s\n", utils.ToIJSON(ec))
|
||||
return
|
||||
}
|
||||
|
||||
// debitConcretes implements the balanceOperator interface
|
||||
@@ -139,6 +144,7 @@ func (cB *concreteBalance) debitConcretes(cUnits *decimal.Big,
|
||||
if dbted.Cmp(decimal.New(0, 0)) == 0 {
|
||||
return // no event cost for 0 debit
|
||||
}
|
||||
// EventCharges
|
||||
ec = utils.NewEventCharges()
|
||||
ec.Concretes = &utils.Decimal{dbted}
|
||||
// UnitFactors
|
||||
@@ -155,5 +161,18 @@ func (cB *concreteBalance) debitConcretes(cUnits *decimal.Big,
|
||||
BalanceLimit: blncLmt,
|
||||
UnitFactorID: ufID,
|
||||
}
|
||||
ec.ChargingIntervals = []*utils.ChargingInterval{
|
||||
{
|
||||
Increments: []*utils.ChargingIncrement{
|
||||
{
|
||||
Units: &utils.Decimal{dbted},
|
||||
AccountChargeID: acntID,
|
||||
CompressFactor: 1,
|
||||
},
|
||||
},
|
||||
CompressFactor: 1,
|
||||
},
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -225,9 +225,7 @@ func maxDebitAbstractsFromConcretes(aUnits *decimal.Big,
|
||||
connMgr *engine.ConnManager, cgrEv *utils.CGREvent,
|
||||
attrSConns, attributeIDs, rateSConns, rpIDs []string,
|
||||
costIcrm *utils.CostIncrement) (ec *utils.EventCharges, err error) {
|
||||
|
||||
// Init EventCharges
|
||||
ec = utils.NewEventCharges()
|
||||
calculateCost := costIcrm.RecurrentFee.Cmp(decimal.New(-1, 0)) == 0 && costIcrm.FixedFee == nil
|
||||
//var attrIDs []string // will be populated if attributes are processed successfully
|
||||
// process AttributeS if needed
|
||||
@@ -301,7 +299,9 @@ func maxDebitAbstractsFromConcretes(aUnits *decimal.Big,
|
||||
} else { // debit for the usage succeeded
|
||||
aPaid = new(decimal.Big).Copy(aUnits)
|
||||
paidConcrtUnts = cloneUnitsFromConcretes(cncrtBlncs)
|
||||
ec = utils.NewEventCharges()
|
||||
ec.Merge(ecDbt)
|
||||
fmt.Printf("ecDbt: %s\n", utils.ToIJSON(ecDbt))
|
||||
if i == 0 { // no estimation done, covering full
|
||||
break
|
||||
}
|
||||
@@ -323,6 +323,7 @@ func maxDebitAbstractsFromConcretes(aUnits *decimal.Big,
|
||||
if aPaid == nil {
|
||||
// since we are erroring, we restore the concerete balances
|
||||
aPaid = decimal.New(0, 0)
|
||||
ec = utils.NewEventCharges()
|
||||
}
|
||||
ec.Abstracts = &utils.Decimal{aPaid}
|
||||
restoreUnitsFromClones(cncrtBlncs, paidConcrtUnts)
|
||||
|
||||
@@ -163,6 +163,29 @@ type UnitFactor struct {
|
||||
Factor *Decimal
|
||||
}
|
||||
|
||||
// Equals compares two UnitFactors
|
||||
func (uF *UnitFactor) Equals(nUf *UnitFactor) (eq bool) {
|
||||
if uF.FilterIDs == nil && nUf.FilterIDs != nil ||
|
||||
uF.FilterIDs != nil && nUf.FilterIDs == nil ||
|
||||
len(uF.FilterIDs) != len(nUf.FilterIDs) {
|
||||
return
|
||||
}
|
||||
for i := range uF.FilterIDs {
|
||||
if uF.FilterIDs[i] != nUf.FilterIDs[i] {
|
||||
return
|
||||
}
|
||||
}
|
||||
if uF.Factor == nil && nUf.Factor != nil ||
|
||||
uF.Factor != nil && nUf.Factor == nil {
|
||||
return
|
||||
}
|
||||
if uF.Factor == nil && nUf == nil {
|
||||
return true
|
||||
}
|
||||
return uF.Factor.Compare(nUf.Factor) == 0
|
||||
}
|
||||
|
||||
// TenantID returns the combined Tenant:ID
|
||||
func (aP *AccountProfile) TenantID() string {
|
||||
return ConcatenatedKey(aP.Tenant, aP.ID)
|
||||
}
|
||||
|
||||
@@ -58,7 +58,74 @@ func (ec *EventCharges) Merge(eCs ...*EventCharges) {
|
||||
} else { // initial
|
||||
ec.Concretes = nEc.Concretes
|
||||
}
|
||||
ec.AppendChargingIntervals(ec.ChargingIntervals...)
|
||||
}
|
||||
}
|
||||
|
||||
// SyncIDs will repopulate Accounting, UnitFactors and Rating IDs if they equal the references in ec
|
||||
func (ec *EventCharges) SyncIDs(eCs ...*EventCharges) {
|
||||
for _, nEc := range eCs {
|
||||
for _, cIl := range nEc.ChargingIntervals {
|
||||
for _, cIcrm := range cIl.Increments {
|
||||
|
||||
nEcAcntChrg := nEc.Accounting[cIcrm.AccountChargeID]
|
||||
|
||||
// UnitFactors
|
||||
if nEcAcntChrg.UnitFactorID != EmptyString {
|
||||
if uFctID := ec.UnitFactorID(nEc.UnitFactors[nEcAcntChrg.UnitFactorID]); uFctID != EmptyString &&
|
||||
uFctID != nEcAcntChrg.UnitFactorID {
|
||||
nEc.UnitFactors[uFctID] = ec.UnitFactors[uFctID]
|
||||
delete(nEc.UnitFactors, nEcAcntChrg.UnitFactorID)
|
||||
nEcAcntChrg.UnitFactorID = uFctID
|
||||
}
|
||||
}
|
||||
|
||||
// Rating
|
||||
if nEcAcntChrg.RatingID != EmptyString {
|
||||
if rtID := ec.RatingID(nEc.Rating[nEcAcntChrg.RatingID]); rtID != EmptyString &&
|
||||
rtID != nEcAcntChrg.RatingID {
|
||||
nEc.Rating[rtID] = ec.Rating[rtID]
|
||||
delete(nEc.Rating, nEcAcntChrg.RatingID)
|
||||
nEcAcntChrg.RatingID = rtID
|
||||
}
|
||||
}
|
||||
|
||||
// AccountCharges
|
||||
for i, chrgID := range nEc.Accounting[cIcrm.AccountChargeID].JoinedChargeIDs {
|
||||
if acntChrgID := ec.AccountChargeID(nEc.Accounting[chrgID]); acntChrgID != chrgID {
|
||||
// matched the AccountChargeID with an existing one in reference ec, replace in nEc
|
||||
nEc.Accounting[acntChrgID] = ec.Accounting[acntChrgID]
|
||||
delete(nEc.Accounting, chrgID)
|
||||
nEc.Accounting[cIcrm.AccountChargeID].JoinedChargeIDs[i] = acntChrgID
|
||||
}
|
||||
}
|
||||
if acntChrgID := ec.AccountChargeID(nEcAcntChrg); acntChrgID != EmptyString &&
|
||||
acntChrgID != cIcrm.AccountChargeID {
|
||||
// matched the AccountChargeID with an existing one in reference ec, replace in nEc
|
||||
nEc.Accounting[acntChrgID] = ec.Accounting[cIcrm.AccountChargeID]
|
||||
delete(nEc.Accounting, cIcrm.AccountChargeID)
|
||||
cIcrm.AccountChargeID = acntChrgID
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AppendChargingIntervals will add new charging intervals to the existing.
|
||||
// if possible, the existing last one in ec will be compressed
|
||||
func (ec *EventCharges) AppendChargingIntervals(cIls ...*ChargingInterval) {
|
||||
for i, cIl := range cIls {
|
||||
if i == 0 && len(ec.ChargingIntervals) == 0 {
|
||||
ec.ChargingIntervals = []*ChargingInterval{cIl}
|
||||
continue
|
||||
}
|
||||
|
||||
if ec.ChargingIntervals[len(ec.ChargingIntervals)-1].CompressEquals(cIl) {
|
||||
ec.ChargingIntervals[len(ec.ChargingIntervals)-1].CompressFactor += 1
|
||||
continue
|
||||
}
|
||||
ec.ChargingIntervals = append(ec.ChargingIntervals, cIl)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,6 +150,36 @@ func (ec *EventCharges) AsExtEventCharges() (eEc *ExtEventCharges, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// UnitFactorID returns the ID of the matching UnitFactor within ec.UnitFactors
|
||||
func (ec *EventCharges) UnitFactorID(uF *UnitFactor) (ufID string) {
|
||||
for ecUfID, ecUf := range ec.UnitFactors {
|
||||
if ecUf.Equals(uF) {
|
||||
return ecUfID
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// RatingID returns the ID of the matching RateSInterval within ec.Rating
|
||||
func (ec *EventCharges) RatingID(rIl *RateSInterval) (rID string) {
|
||||
for ecID, ecRtIl := range ec.Rating {
|
||||
if ecRtIl.Equals(rIl) {
|
||||
return ecID
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AccountChargeID returns the ID of the matching AccountCharge within ec.Accounting
|
||||
func (ec *EventCharges) AccountChargeID(ac *AccountCharge) (acID string) {
|
||||
for ecID, ecAc := range ec.Accounting {
|
||||
if ecAc.Equals(ac) {
|
||||
return ecID
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ExtEventCharges is a generic EventCharges used in APIs
|
||||
type ExtEventCharges struct {
|
||||
Abstracts *float64
|
||||
@@ -94,10 +191,15 @@ type ChargingInterval struct {
|
||||
CompressFactor int
|
||||
}
|
||||
|
||||
// CompressEquals compares two ChargingIntervals for aproximate equality, ignoring compress field
|
||||
func (cIl *ChargingInterval) CompressEquals(nCil *ChargingInterval) (eq bool) {
|
||||
return
|
||||
}
|
||||
|
||||
// ChargingIncrement represents one unit charged inside an interval
|
||||
type ChargingIncrement struct {
|
||||
Units *Decimal
|
||||
AccountChargeID string // Account charging information
|
||||
Units *Decimal // Can differ from AccountCharge due to JoinedCharging
|
||||
AccountChargeID string // Account charging information
|
||||
CompressFactor int
|
||||
}
|
||||
|
||||
@@ -112,3 +214,8 @@ type AccountCharge struct {
|
||||
RatingID string // identificator in cost increments
|
||||
JoinedChargeIDs []string // identificator of extra account charges
|
||||
}
|
||||
|
||||
// Equals compares two AccountCharges
|
||||
func (ac *AccountCharge) Equals(nAc *AccountCharge) (eq bool) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -140,6 +140,11 @@ type RateSIncrement struct {
|
||||
cost *decimal.Big // unexported total increment cost
|
||||
}
|
||||
|
||||
// Equals compares two RateSIntervals
|
||||
func (rIl *RateSInterval) Equals(nRil *RateSInterval) (eq bool) {
|
||||
return // ToDo
|
||||
}
|
||||
|
||||
// RateProfileCost is the cost returned by RateS at cost queries
|
||||
type RateProfileCost struct {
|
||||
ID string // RateProfileID
|
||||
|
||||
Reference in New Issue
Block a user