diff --git a/sessions/sessions.go b/sessions/sessions.go index c10c277c4..f14b1ceff 100644 --- a/sessions/sessions.go +++ b/sessions/sessions.go @@ -1519,31 +1519,45 @@ func (sS *SessionS) endSession(s *Session, tUsage, lastUsage *time.Duration, sr.TotalUsage += *lastUsage sUsage = sr.TotalUsage } + var charged time.Duration // already charged if sr.EventCost != nil { - if notCharged := sUsage - sr.EventCost.GetUsage(); notCharged > 0 { // we did not charge enough, make a manual debit here - if sr.CD.LoopIndex > 0 { - sr.CD.TimeStart = sr.CD.TimeEnd - } - sr.CD.TimeEnd = sr.CD.TimeStart.Add(notCharged) - sr.CD.DurationIndex += notCharged - cc := new(engine.CallCost) - if err = sS.connMgr.Call(sS.cgrCfg.SessionSCfg().RALsConns, nil, utils.ResponderDebit, - &engine.CallDescriptorWithOpts{ - CallDescriptor: sr.CD, - Opts: s.OptsStart, - }, cc); err == nil { - sr.EventCost.Merge( - engine.NewEventCostFromCallCost(cc, s.CGRID, - sr.Event.GetStringIgnoreErrors(utils.RunID))) - } - } else if notCharged < 0 { // charged too much, try refund - if err = sS.refundSession(s, sRunIdx, -notCharged); err != nil { - utils.Logger.Warning( - fmt.Sprintf( - "<%s> failed refunding session: <%s>, srIdx: <%d>, error: <%s>", - utils.SessionS, s.CGRID, sRunIdx, err.Error())) - } + charged = sr.EventCost.GetUsage() + } + if notCharged := sUsage - charged; notCharged > 0 { // we did not charge enough, make a manual debit here + if sr.CD.LoopIndex > 0 { + sr.CD.TimeStart = sr.CD.TimeEnd } + sr.CD.TimeEnd = sr.CD.TimeStart.Add(notCharged) + sr.CD.DurationIndex += notCharged + cc := new(engine.CallCost) + if err = sS.connMgr.Call(sS.cgrCfg.SessionSCfg().RALsConns, nil, utils.ResponderDebit, + &engine.CallDescriptorWithOpts{ + CallDescriptor: sr.CD, + Opts: s.OptsStart, + }, cc); err != nil { + utils.Logger.Warning( + fmt.Sprintf( + "<%s> failed extra charging session: <%s>, srIdx: <%d>, error: <%s>", + utils.SessionS, s.CGRID, sRunIdx, err.Error())) + } else { + newEc := engine.NewEventCostFromCallCost(cc, s.CGRID, + sr.Event.GetStringIgnoreErrors(utils.RunID)) + if sr.EventCost == nil { + sr.EventCost = newEc + } else { + sr.EventCost.Merge(newEc) + } + + } + } else if notCharged < 0 { // charged too much, try refund + if err = sS.refundSession(s, sRunIdx, -notCharged); err != nil { + utils.Logger.Warning( + fmt.Sprintf( + "<%s> failed refunding session: <%s>, srIdx: <%d>, error: <%s>", + utils.SessionS, s.CGRID, sRunIdx, err.Error())) + } + } + if sr.EventCost != nil { if err := sS.roundCost(s, sRunIdx); err != nil { // will round the cost and refund the extra increment utils.Logger.Warning( fmt.Sprintf("<%s> failed rounding session cost for <%s>, srIdx: <%d>, error: <%s>", @@ -1557,11 +1571,11 @@ func (sS *SessionS) endSession(s *Session, tUsage, lastUsage *time.Duration, utils.SessionS, s.CGRID, sRunIdx, err.Error())) } } - // set cost fields sr.Event[utils.Cost] = sr.EventCost.GetCost() sr.Event[utils.CostDetails] = utils.ToJSON(sr.EventCost) // avoid map[string]interface{} when decoding sr.Event[utils.CostSource] = utils.MetaSessionS + } // Set Usage field if sRunIdx == 0 { diff --git a/sessions/sessions_it_test.go b/sessions/sessions_it_test.go index a6d033337..7d60704e1 100644 --- a/sessions/sessions_it_test.go +++ b/sessions/sessions_it_test.go @@ -44,8 +44,8 @@ var ( testSessionsItStartEngine, testSessionsItApierRpcConn, testSessionsItTPFromFolder, - testSessionsItTerminatUnexist, - testSessionsItUpdateUnexist, + testSessionsItTerminatNonexist, + testSessionsItUpdateNonexist, testSessionsItTerminatePassive, testSessionsItEventCostCompressing, testSessionsItStopCgrEngine, @@ -120,7 +120,7 @@ func testSessionsItTPFromFolder(t *testing.T) { time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups } -func testSessionsItTerminatUnexist(t *testing.T) { +func testSessionsItTerminatNonexist(t *testing.T) { var acnt *engine.Account attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} eAcntVal := 10.0 @@ -139,7 +139,7 @@ func testSessionsItTerminatUnexist(t *testing.T) { }, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", - ID: "TestSessionsItTerminatUnexist", + ID: "testSessionsItTerminatNonexist", Event: map[string]interface{}{ utils.EVENT_NAME: "TerminateEvent", utils.ToR: utils.VOICE, @@ -197,7 +197,7 @@ func testSessionsItTerminatUnexist(t *testing.T) { } -func testSessionsItUpdateUnexist(t *testing.T) { +func testSessionsItUpdateNonexist(t *testing.T) { var acnt *engine.Account attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} eAcntVal := 9.299800 @@ -216,7 +216,7 @@ func testSessionsItUpdateUnexist(t *testing.T) { }, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", - ID: "TestSessionsItUpdateUnexist", + ID: "testSessionsItUpdateNonexist", Event: map[string]interface{}{ utils.EVENT_NAME: "UpdateEvent", utils.ToR: utils.VOICE, @@ -257,7 +257,7 @@ func testSessionsItUpdateUnexist(t *testing.T) { CGREventWithOpts: &utils.CGREventWithOpts{ CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", - ID: "TestSessionsItTerminatUnexist", + ID: "testSessionsItTerminatNonexist", Event: map[string]interface{}{ utils.EVENT_NAME: "TerminateEvent", utils.ToR: utils.VOICE, @@ -339,7 +339,7 @@ func testSessionsItTerminatePassive(t *testing.T) { CGREventWithOpts: &utils.CGREventWithOpts{ CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", - ID: "TestSessionsItTerminatUnexist", + ID: "testSessionsItTerminatNonexist", Event: map[string]interface{}{ utils.EVENT_NAME: "TerminateEvent", utils.ToR: utils.VOICE,