From 952c817f8694b77c05b07d5f288c3d907584da77 Mon Sep 17 00:00:00 2001 From: DanB Date: Sun, 21 May 2017 20:55:31 +0200 Subject: [PATCH] Adding AccountSummary in CallCost and EventCost This reverts commit ab279b600f43eed5629414880ee27e8e94c2d6bb. --- engine/account.go | 2 +- engine/callcost.go | 7 +++- engine/calldesc.go | 10 +++++ engine/eventcost.go | 85 +++++++++++++++++++++++------------------ engine/storage_redis.go | 1 + utils/coreutils.go | 6 +++ 6 files changed, 70 insertions(+), 41 deletions(-) diff --git a/engine/account.go b/engine/account.go index b22f9a495..e3361e747 100644 --- a/engine/account.go +++ b/engine/account.go @@ -1076,7 +1076,7 @@ func NewAccountSummaryFromJSON(jsn string) (acntSummary *AccountSummary, err err return } -// AccountDigest contains compressed information about an Account +// AccountSummary contains compressed information about an Account type AccountSummary struct { Tenant string ID string diff --git a/engine/callcost.go b/engine/callcost.go index 3f260e3d4..74f809792 100644 --- a/engine/callcost.go +++ b/engine/callcost.go @@ -30,6 +30,7 @@ type CallCost struct { Cost float64 Timespans TimeSpans RatedUsage float64 + AccountSummary *AccountSummary deductConnectFee bool negativeConnectFee bool // the connect fee went negative on default balance maxCostDisconect bool @@ -180,6 +181,7 @@ func (cc *CallCost) updateCost() { cc.Cost = cost } +// Round creates the RoundIncrements in timespans func (cc *CallCost) Round() { if len(cc.Timespans) == 0 || cc.Timespans[0] == nil { return @@ -191,11 +193,12 @@ func (cc *CallCost) Round() { } inc := ts.Increments[0] if inc.BalanceInfo.Monetary == nil || inc.Cost == 0 { - // this is a unit payied timespan, nothing to round + // this is a unit paid timespan, nothing to round continue } cost := ts.CalculateCost() - roundedCost := utils.Round(cost, ts.RateInterval.Rating.RoundingDecimals, + roundedCost := utils.Round(cost, + ts.RateInterval.Rating.RoundingDecimals, ts.RateInterval.Rating.RoundingMethod) correctionCost := roundedCost - cost //log.Print(cost, roundedCost, correctionCost) diff --git a/engine/calldesc.go b/engine/calldesc.go index 0f42eba1f..2107b3525 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -754,6 +754,7 @@ func (cd *CallDescriptor) MaxDebit() (cc *CallCost, err error) { //log.Print("AFTER MAX SESSION: ", cd) if err != nil || remainingDuration == 0 { cc = cd.CreateCallCost() + cc.AccountSummary = cd.AccountSummary() if cd.GetDuration() == 0 { // add RatingInfo err = cd.LoadRatingPlans() @@ -777,6 +778,7 @@ func (cd *CallDescriptor) MaxDebit() (cc *CallCost, err error) { } //log.Print("Remaining duration: ", remainingDuration) cc, err = cd.debit(account, cd.DryRun, !cd.DenyNegativeAccount) + cc.AccountSummary = cd.AccountSummary() //log.Print(balanceMap[0].Value, balanceMap[1].Value) return }, 0, lkIDs...) @@ -1308,3 +1310,11 @@ func (cd *CallDescriptor) GetLCR(stats rpcclient.RpcClientConnection, lcrFltr *L } return lcrCost, nil } + +// AccountSummary returns the AccountSummary for cached account +func (cd *CallDescriptor) AccountSummary() *AccountSummary { + if cd.account == nil { + return nil + } + return cd.account.AsAccountSummary() +} diff --git a/engine/eventcost.go b/engine/eventcost.go index 590a2da11..0168c11bd 100644 --- a/engine/eventcost.go +++ b/engine/eventcost.go @@ -20,7 +20,6 @@ package engine import ( "time" - "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/utils" ) @@ -34,7 +33,7 @@ func (rfs RatingFilters) GetUUIDWithSet(rmf RatingMatchedFilters) string { } } // not found, set it here - uuid := utils.GenUUID() + uuid := utils.UUIDSha1Prefix() rfs[uuid] = rmf return uuid } @@ -49,7 +48,7 @@ func (crus Rating) GetUUIDWithSet(cru *RatingUnit) string { } } // not found, set it here - uuid := utils.GenUUID() + uuid := utils.UUIDSha1Prefix() crus[uuid] = cru return uuid } @@ -64,7 +63,7 @@ func (crs ChargedRates) GetUUIDWithSet(rg RateGroups) string { } } // not found, set it here - uuid := utils.GenUUID() + uuid := utils.UUIDSha1Prefix() crs[uuid] = rg return uuid } @@ -79,7 +78,7 @@ func (cts ChargedTimings) GetUUIDWithSet(ct *ChargedTiming) string { } } // not found, set it here - uuid := utils.GenUUID() + uuid := utils.UUIDSha1Prefix() cts[uuid] = ct return uuid } @@ -94,18 +93,19 @@ func (cbs Accounting) GetUUIDWithSet(cb *BalanceCharge) string { } } // not found, set it here - uuid := utils.GenUUID() + uuid := utils.UUIDSha1Prefix() cbs[uuid] = cb return uuid } func NewEventCostFromCallCost(cc *CallCost, cgrID, runID string) (ec *EventCost) { ec = &EventCost{CGRID: cgrID, RunID: runID, - RatingFilters: make(RatingFilters), - Rating: make(Rating), - Rates: make(ChargedRates), - Timings: make(ChargedTimings), - Accounting: make(Accounting), + AccountSummary: cc.AccountSummary, + RatingFilters: make(RatingFilters), + Rating: make(Rating), + Rates: make(ChargedRates), + Timings: make(ChargedTimings), + Accounting: make(Accounting), } if len(cc.Timespans) != 0 { ec.Charges = make([]*ChargingInterval, len(cc.Timespans)) @@ -165,16 +165,17 @@ func NewEventCostFromCallCost(cc *CallCost, cgrID, runID string) (ec *EventCost) // EventCost stores cost for an Event type EventCost struct { - CGRID string - RunID string - Cost *float64 // pointer so we can nil it when dirty - Usage *time.Duration - Charges []*ChargingInterval - Rating Rating - Accounting Accounting - RatingFilters RatingFilters - Rates ChargedRates - Timings ChargedTimings + CGRID string + RunID string + Cost *float64 // pointer so we can nil it when dirty + Usage *time.Duration + Charges []*ChargingInterval + AccountSummary *AccountSummary // Account summary at the end of the event calculation + Rating Rating + Accounting Accounting + RatingFilters RatingFilters + Rates ChargedRates + Timings ChargedTimings } func (ec *EventCost) ratingUUIDForRateInterval(ri *RateInterval, rf RatingMatchedFilters) string { @@ -237,9 +238,9 @@ func (ec *EventCost) ComputeCost() float64 { if ec.Cost == nil { var cost float64 for _, ci := range ec.Charges { - cost += ci.Cost() * float64(ci.CompressFactor) + cost += ci.GetCost() * float64(ci.CompressFactor) } - cost = utils.Round(cost, config.CgrConfig().RoundingDecimals, utils.ROUNDING_MIDDLE) + cost = utils.Round(cost, globalRoundingDecimals, utils.ROUNDING_MIDDLE) ec.Cost = &cost } return *ec.Cost @@ -250,21 +251,26 @@ func (ec *EventCost) ComputeUsage() time.Duration { if ec.Usage == nil { var usage time.Duration for _, ci := range ec.Charges { - usage += time.Duration(ci.Usage().Nanoseconds() * int64(ci.CompressFactor)) + usage += time.Duration(ci.GetUsage().Nanoseconds() * int64(ci.CompressFactor)) } ec.Usage = &usage } return *ec.Usage } +func (ec *EventCost) ComputeRounding() []*ChargingIncrement { + return nil +} + func (ec *EventCost) AsCallCost(ToR, Tenant, Direction, Category, Account, Subject, Destination string) *CallCost { cc := &CallCost{Direction: Direction, Category: Category, Tenant: Tenant, Subject: Subject, Account: Account, Destination: Destination, TOR: ToR, - Cost: ec.ComputeCost(), RatedUsage: ec.ComputeUsage().Seconds()} + Cost: ec.ComputeCost(), RatedUsage: ec.ComputeUsage().Seconds(), + AccountSummary: ec.AccountSummary} cc.Timespans = make(TimeSpans, len(ec.Charges)) for i, cIl := range ec.Charges { - ts := &TimeSpan{TimeStart: cIl.StartTime, TimeEnd: cIl.StartTime.Add(cIl.Usage()), - Cost: cIl.Cost(), DurationIndex: cIl.Usage(), CompressFactor: cIl.CompressFactor} + ts := &TimeSpan{TimeStart: cIl.StartTime, TimeEnd: cIl.StartTime.Add(cIl.GetUsage()), + Cost: cIl.GetCost(), DurationIndex: cIl.GetUsage(), CompressFactor: cIl.CompressFactor} if cIl.RatingUUID != "" { if ec.Rating[cIl.RatingUUID].RatingFiltersUUID != "" { rfs := ec.RatingFilters[ec.Rating[cIl.RatingUUID].RatingFiltersUUID] @@ -311,8 +317,8 @@ type ChargingInterval struct { RatingUUID string // reference to RatingUnit Increments []*ChargingIncrement // specific increments applied to this interval CompressFactor int - usage *time.Duration // cache usage computation for this interval - cost *float64 // cache cost calculation on this interval + Usage *time.Duration // cache usage computation for this interval + Cost *float64 // cache cost calculation on this interval } func (cIl *ChargingInterval) Equals(oCIl *ChargingInterval) (equals bool) { @@ -331,28 +337,31 @@ func (cIl *ChargingInterval) Equals(oCIl *ChargingInterval) (equals bool) { } // Usage computes the total usage of this ChargingInterval, ignoring CompressFactor -func (cIl *ChargingInterval) Usage() time.Duration { - if cIl.usage == nil { +func (cIl *ChargingInterval) GetUsage() time.Duration { + if cIl.Usage == nil { var usage time.Duration for _, incr := range cIl.Increments { usage += time.Duration(incr.Usage.Nanoseconds() * int64(incr.CompressFactor)) } - cIl.usage = &usage + cIl.Usage = &usage } - return *cIl.usage + return *cIl.Usage } // Cost computes the total cost on this ChargingInterval -func (cIl *ChargingInterval) Cost() float64 { - if cIl.cost == nil { +func (cIl *ChargingInterval) GetCost() float64 { + if cIl.Cost == nil { var cost float64 for _, incr := range cIl.Increments { cost += incr.Cost * float64(incr.CompressFactor) } - cost = utils.Round(cost, config.CgrConfig().RoundingDecimals, utils.ROUNDING_MIDDLE) - cIl.cost = &cost + if cIl.RoundingIncrement != nil { + + } + cost = utils.Round(cost, globalRoundingDecimals, utils.ROUNDING_MIDDLE) + cIl.Cost = &cost } - return *cIl.cost + return *cIl.Cost } // ChargingIncrement represents one unit charged inside an interval diff --git a/engine/storage_redis.go b/engine/storage_redis.go index f96533f53..a96baa355 100644 --- a/engine/storage_redis.go +++ b/engine/storage_redis.go @@ -384,6 +384,7 @@ func (rs *RedisStorage) GetRatingPlan(key string, skipCache bool, transactionID return nil, err } cache.Set(key, rp, cacheCommit(transactionID), transactionID) + fmt.Printf("RatingPlan: %s\n", utils.ToJSON(rp)) return } diff --git a/utils/coreutils.go b/utils/coreutils.go index b4d2f24b2..30eb7d90c 100644 --- a/utils/coreutils.go +++ b/utils/coreutils.go @@ -105,6 +105,12 @@ func GenUUID() string { b[10:]) } +// UUIDSha1Prefix generates a prefix of the sha1 applied to an UUID +// prefix 8 is chosen since the probability of colision starts being minimal after 7 characters (see git commits) +func UUIDSha1Prefix() string { + return Sha1(GenUUID())[:8] +} + // Round return rounded version of x with prec precision. // // Special cases are: