diff --git a/rater/calldesc.go b/rater/calldesc.go index 6431580e6..039b11405 100644 --- a/rater/calldesc.go +++ b/rater/calldesc.go @@ -75,6 +75,8 @@ type CallDescriptor struct { TOR string Tenant, Subject, Account, Destination string TimeStart, TimeEnd time.Time + LoopIndex float64 // indicates the postion of this segment in a cost request loop + CallDuration float64 // the call duration so far (partial or final) Amount float64 FallbackSubject string // the subject to check for destination if not found on primary subject ActivationPeriods []*ActivationPeriod @@ -266,11 +268,13 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) { timespans := cd.splitInTimeSpans() cost := 0.0 connectionFee := 0.0 - for i, ts := range timespans { - if i == 0 && ts.MinuteInfo == nil && ts.Interval != nil { - connectionFee = ts.Interval.ConnectFee + if cd.LoopIndex == 0 { // only add connect fee if this is the first/only call cost request + for i, ts := range timespans { + if i == 0 && ts.MinuteInfo == nil && ts.Interval != nil { + connectionFee = ts.Interval.ConnectFee + } + cost += ts.getCost(cd) } - cost += ts.getCost(cd) } cc := &CallCost{ Direction: cd.Direction, diff --git a/sessionmanager/fssessionmanager.go b/sessionmanager/fssessionmanager.go index b36c73905..48e1e9960 100644 --- a/sessionmanager/fssessionmanager.go +++ b/sessionmanager/fssessionmanager.go @@ -211,6 +211,8 @@ func (sm *FSSessionManager) OnChannelHangupComplete(ev Event) { TOR: ev.GetTOR(), Subject: ev.GetSubject(), Account: ev.GetAccount(), + LoopIndex: 0, + CallDuration: endTime.Sub(startTime).Seconds(), Destination: ev.GetDestination(), TimeStart: startTime, TimeEnd: endTime, @@ -230,7 +232,7 @@ func (sm *FSSessionManager) OnChannelHangupComplete(ev Event) { return // why would we have 0 callcosts } lastCC := s.CallCosts[len(s.CallCosts)-1] - // put credit back + // put credit back start := time.Now() end := lastCC.Timespans[len(lastCC.Timespans)-1].TimeEnd refoundDuration := end.Sub(start).Seconds() @@ -303,9 +305,11 @@ func (sm *FSSessionManager) OnChannelHangupComplete(ev Event) { } -func (sm *FSSessionManager) LoopAction(s *Session, cd *rater.CallDescriptor) { +func (sm *FSSessionManager) LoopAction(s *Session, cd *rater.CallDescriptor, index float64) { cc := &rater.CallCost{} + cd.LoopIndex = index cd.Amount = sm.debitPeriod.Seconds() + cd.CallDuration += cd.Amount err := sm.connector.MaxDebit(*cd, cc) if err != nil { rater.Logger.Err(fmt.Sprintf("Could not complete debit opperation: %v", err)) diff --git a/sessionmanager/session.go b/sessionmanager/session.go index 0dc7acde2..ccded4cea 100644 --- a/sessionmanager/session.go +++ b/sessionmanager/session.go @@ -38,7 +38,7 @@ type Session struct { // Creates a new session and starts the debit loop func NewSession(ev Event, sm SessionManager) (s *Session) { - // Ignore calls which have nothing to do with CGRateS + // Ignore calls which have nothing to do with CGRateS if strings.TrimSpace(ev.GetReqType()) == "" { return } @@ -80,6 +80,7 @@ func NewSession(ev Event, sm SessionManager) (s *Session) { // the debit loop method (to be stoped by sending somenting on stopDebit channel) func (s *Session) startDebitLoop() { nextCd := *s.callDescriptor + index := 0.0 for { select { case <-s.stopDebit: @@ -90,8 +91,9 @@ func (s *Session) startDebitLoop() { nextCd.TimeStart = time.Now() } nextCd.TimeEnd = time.Now().Add(s.sessionManager.GetDebitPeriod()) - s.sessionManager.LoopAction(s, &nextCd) + s.sessionManager.LoopAction(s, &nextCd, index) time.Sleep(s.sessionManager.GetDebitPeriod()) + index++ } } @@ -127,7 +129,7 @@ func (s *Session) String() string { return fmt.Sprintf("%v: %s(%s) -> %s", s.callDescriptor.TimeStart, s.callDescriptor.Subject, s.callDescriptor.Account, s.callDescriptor.Destination) } -// +// func (s *Session) SaveOperations() { go func() { if s == nil || len(s.CallCosts) == 0 { diff --git a/sessionmanager/sessionmanager.go b/sessionmanager/sessionmanager.go index 81a6d9ed0..ba58f25de 100644 --- a/sessionmanager/sessionmanager.go +++ b/sessionmanager/sessionmanager.go @@ -28,7 +28,7 @@ type SessionManager interface { Connect(*config.CGRConfig) error DisconnectSession(*Session, string) RemoveSession(*Session) - LoopAction(*Session, *rater.CallDescriptor) + LoopAction(*Session, *rater.CallDescriptor, float64) GetDebitPeriod() time.Duration GetDbLogger() rater.DataStorage Shutdown() error