From 4d6be144c32972a0a599ec1a28c738d1bc1b79d0 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Wed, 20 Jan 2016 15:59:27 +0200 Subject: [PATCH 1/4] added RatedUsage to call cost --- engine/callcost.go | 7 +++++++ engine/callcost_test.go | 4 ++++ engine/calldesc.go | 2 ++ engine/cdrs.go | 1 + 4 files changed, 14 insertions(+) diff --git a/engine/callcost.go b/engine/callcost.go index 767efc8f1..391b2a33a 100644 --- a/engine/callcost.go +++ b/engine/callcost.go @@ -29,6 +29,7 @@ type CallCost struct { Direction, Category, Tenant, Subject, Account, Destination, TOR string Cost float64 Timespans TimeSpans + RatedUsage float64 deductConnectFee bool negativeConnectFee bool // the connect fee went negative on default balance maxCostDisconect bool @@ -61,6 +62,12 @@ func (cc *CallCost) GetDuration() (td time.Duration) { return } +func (cc *CallCost) UpdateRatedUsage() time.Duration { + totalDuration := cc.GetDuration() + cc.RatedUsage = totalDuration.Seconds() + return totalDuration +} + func (cc *CallCost) GetConnectFee() float64 { if len(cc.Timespans) == 0 || cc.Timespans[0].RateInterval == nil || diff --git a/engine/callcost_test.go b/engine/callcost_test.go index c9ce24f01..55b0eced8 100644 --- a/engine/callcost_test.go +++ b/engine/callcost_test.go @@ -50,6 +50,10 @@ func TestSingleResultMerge(t *testing.T) { if cc1.Cost != 122 { t.Errorf("Exdpected 120 was %v", cc1.Cost) } + d := cc1.UpdateRatedUsage() + if d != 2*time.Minute || cc1.RatedUsage != 120.0 { + t.Errorf("error updating rating usage: %v, %v", d, cc1.RatedUsage) + } } func TestMultipleResultMerge(t *testing.T) { diff --git a/engine/calldesc.go b/engine/calldesc.go index 46771baa4..c38b3be18 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -526,6 +526,7 @@ func (cd *CallDescriptor) getCost() (*CallCost, error) { cc.Cost = utils.Round(cc.Cost, roundingDecimals, roundingMethod) //utils.Logger.Info(fmt.Sprintf(" Get Cost: %s => %v", cd.GetKey(), cc)) cc.Timespans.Compress() + cc.UpdateRatedUsage() return cc, err } @@ -668,6 +669,7 @@ func (cd *CallDescriptor) debit(account *Account, dryRun bool, goNegative bool) return nil, err } cc.updateCost() + cc.UpdateRatedUsage() cc.Timespans.Compress() //log.Printf("OUT CC: ", cc) return diff --git a/engine/cdrs.go b/engine/cdrs.go index 457a5fcfd..51a9249e5 100644 --- a/engine/cdrs.go +++ b/engine/cdrs.go @@ -107,6 +107,7 @@ func (self *CdrServer) ProcessExternalCdr(eCDR *ExternalCDR) error { // RPC method, used to log callcosts to db func (self *CdrServer) LogCallCost(ccl *CallCostLog) error { + ccl.CallCost.UpdateRatedUsage() // make sure rated usage is updated if ccl.CheckDuplicate { _, err := self.guard.Guard(func() (interface{}, error) { cc, err := self.cdrDb.GetCallCostLog(ccl.CgrId, ccl.RunId) From 12c09575e33bf943938a43246f90468d032ddfa3 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Wed, 20 Jan 2016 16:04:14 +0200 Subject: [PATCH 2/4] fix for smggenreic nil pointer --- sessionmanager/smgeneric.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sessionmanager/smgeneric.go b/sessionmanager/smgeneric.go index dd3cf163f..7254a7620 100644 --- a/sessionmanager/smgeneric.go +++ b/sessionmanager/smgeneric.go @@ -237,9 +237,14 @@ func (self *SMGeneric) ChargeEvent(gev SMGenericEvent, clnt *rpc2.Client) (maxDu } var withErrors bool for _, sR := range sessionRuns { - var cc *engine.CallCost - for _, ccSR := range sR.CallCosts { - cc.Merge(ccSR) + if len(sR.CallCosts) == 0 { + continue + } + cc := sR.CallCosts[0] + if len(sR.CallCosts) > 1 { + for _, ccSR := range sR.CallCosts[1:] { + cc.Merge(ccSR) + } } var reply string if err := self.cdrsrv.LogCallCost(&engine.CallCostLog{ From 3c88c9248852c636e1bc32005956c19a5892522f Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Wed, 20 Jan 2016 16:21:40 +0200 Subject: [PATCH 3/4] session runs refund --- sessionmanager/smg_session.go | 2 +- sessionmanager/smgeneric.go | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/sessionmanager/smg_session.go b/sessionmanager/smg_session.go index 84eb2c8aa..18a86a9b5 100644 --- a/sessionmanager/smg_session.go +++ b/sessionmanager/smg_session.go @@ -157,7 +157,7 @@ func (self *SMGSession) refund(refundDuration time.Duration) error { Increments: refundIncrements, } cd.Increments.Compress() - utils.Logger.Info(fmt.Sprintf("Refunding duration %v with cd: %+v", initialRefundDuration, utils.ToJSON(cd))) + utils.Logger.Info(fmt.Sprintf("Refunding duration %v with cd: %s", initialRefundDuration, utils.ToJSON(cd))) var response float64 err := self.rater.RefundIncrements(cd, &response) if err != nil { diff --git a/sessionmanager/smgeneric.go b/sessionmanager/smgeneric.go index 7254a7620..59ac17337 100644 --- a/sessionmanager/smgeneric.go +++ b/sessionmanager/smgeneric.go @@ -228,10 +228,41 @@ func (self *SMGeneric) ChargeEvent(gev SMGenericEvent, clnt *rpc2.Client) (maxDu } if err != nil { // Refund the ones already taken since we have error on one of the debits for _, sR := range sessionRuns { - for _, cc := range sR.CallCosts { - utils.Logger.Debug(fmt.Sprintf("%+v", cc)) // Refund here + if len(sR.CallCosts) == 0 { continue } + cc := sR.CallCosts[0] + if len(sR.CallCosts) > 1 { + for _, ccSR := range sR.CallCosts { + cc.Merge(ccSR) + } + } + // collect increments + var refundIncrements engine.Increments + cc.Timespans.Decompress() + for _, ts := range cc.Timespans { + refundIncrements = append(refundIncrements, ts.Increments...) + } + // refund cc + if len(refundIncrements) > 0 { + cd := &engine.CallDescriptor{ + Direction: cc.Direction, + Tenant: cc.Tenant, + Category: cc.Category, + Subject: cc.Subject, + Account: cc.Account, + Destination: cc.Destination, + TOR: cc.TOR, + Increments: refundIncrements, + } + cd.Increments.Compress() + utils.Logger.Info(fmt.Sprintf("Refunding session run callcost: %s", utils.ToJSON(cd))) + var response float64 + err := self.rater.RefundIncrements(cd, &response) + if err != nil { + return nilDuration, err + } + } } return nilDuration, err } From 7d833beb9a042f19cec84743851acc109d0d724f Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Wed, 20 Jan 2016 16:57:16 +0200 Subject: [PATCH 4/4] one more cond test --- utils/cond_loader_test.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/utils/cond_loader_test.go b/utils/cond_loader_test.go index 996d12d27..34b01cbe3 100644 --- a/utils/cond_loader_test.go +++ b/utils/cond_loader_test.go @@ -89,6 +89,13 @@ func TestCondKeyValue(t *testing.T) { if check, err := cl.Check(o); !check || err != nil { t.Errorf("Error checking struct: %v %v (%v)", check, err, ToIJSON(cl.rootElement)) } + err = cl.Parse(`{"Other":true, "Field":{"*gt":7}}`) + if err != nil { + t.Errorf("Error loading structure: %+v (%v)", ToIJSON(cl.rootElement), err) + } + if check, err := cl.Check(o); check || err != nil { + t.Errorf("Error checking struct: %v %v (%v)", check, err, ToIJSON(cl.rootElement)) + } err = cl.Parse(``) if err != nil { t.Errorf("Error loading structure: %+v (%v)", ToIJSON(cl.rootElement), err)