diff --git a/engine/account.go b/engine/account.go index fb2e2e246..494d71f66 100644 --- a/engine/account.go +++ b/engine/account.go @@ -316,7 +316,7 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo //log.Print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") } //log.Printf("After balances CD: %+v", cd) - leftCC, err = cd.GetCost() + leftCC, err = cd.getCost() if err != nil { Logger.Err(fmt.Sprintf("Error getting new cost for balance subject: %v", err)) } diff --git a/engine/balances.go b/engine/balances.go index 2c3cc202c..f5c7e8efb 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -242,7 +242,7 @@ func (b *Balance) GetCost(cd *CallDescriptor, getStandardIfEmpty bool) (*CallCos origAccount := cd.Account cd.Account = cd.Subject cd.RatingInfos = nil - cc, err := cd.GetCost() + cc, err := cd.getCost() // restor orig values cd.Subject = origSubject cd.Account = origAccount @@ -250,7 +250,7 @@ func (b *Balance) GetCost(cd *CallDescriptor, getStandardIfEmpty bool) (*CallCos } if getStandardIfEmpty { cd.RatingInfos = nil - return cd.GetCost() + return cd.getCost() } else { cc := cd.CreateCallCost() cc.Cost = 0 diff --git a/engine/callcost_test.go b/engine/callcost_test.go index 5d862b228..5349b104b 100644 --- a/engine/callcost_test.go +++ b/engine/callcost_test.go @@ -29,7 +29,7 @@ func TestSingleResultMerge(t *testing.T) { t1 := time.Date(2012, time.February, 2, 17, 0, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 17, 1, 0, 0, time.UTC) cd := &CallDescriptor{Direction: OUTBOUND, Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} - cc1, _ := cd.GetCost() + cc1, _ := cd.getCost() if cc1.Cost != 61 { t.Errorf("expected 61 was %v", cc1.Cost) } @@ -53,7 +53,7 @@ func TestMultipleResultMerge(t *testing.T) { t1 := time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 18, 0, 0, 0, time.UTC) cd := &CallDescriptor{Direction: OUTBOUND, Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} - cc1, _ := cd.GetCost() + cc1, _ := cd.getCost() if cc1.Cost != 61 { t.Errorf("expected 61 was %v", cc1.Cost) for _, ts := range cc1.Timespans { @@ -63,7 +63,7 @@ func TestMultipleResultMerge(t *testing.T) { t1 = time.Date(2012, time.February, 2, 18, 00, 0, 0, time.UTC) t2 = time.Date(2012, time.February, 2, 18, 01, 0, 0, time.UTC) cd = &CallDescriptor{Direction: OUTBOUND, Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} - cc2, _ := cd.GetCost() + cc2, _ := cd.getCost() if cc2.Cost != 30 { t.Errorf("expected 30 was %v", cc2.Cost) for _, ts := range cc1.Timespans { @@ -83,7 +83,7 @@ func TestMultipleInputLeftMerge(t *testing.T) { t1 := time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 18, 01, 0, 0, time.UTC) cd := &CallDescriptor{Direction: OUTBOUND, Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} - cc1, _ := cd.GetCost() + cc1, _ := cd.getCost() //log.Printf("Timing: %+v", cc1.Timespans[1].RateInterval.Timing) //log.Printf("Rating: %+v", cc1.Timespans[1].RateInterval.Rating) if cc1.Cost != 91 { @@ -92,7 +92,7 @@ func TestMultipleInputLeftMerge(t *testing.T) { /*t1 = time.Date(2012, time.February, 2, 18, 01, 0, 0, time.UTC) t2 = time.Date(2012, time.February, 2, 18, 02, 0, 0, time.UTC) cd = &CallDescriptor{Direction: OUTBOUND, TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} - cc2, _ := cd.GetCost() + cc2, _ := cd.getCost() if cc2.Cost != 30 { t.Errorf("expected 30 was %v", cc2.Cost) } @@ -109,14 +109,14 @@ func TestMultipleInputRightMerge(t *testing.T) { t1 := time.Date(2012, time.February, 2, 17, 58, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC) cd := &CallDescriptor{Direction: OUTBOUND, Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} - cc1, _ := cd.GetCost() + cc1, _ := cd.getCost() if cc1.Cost != 61 { t.Errorf("expected 61 was %v", cc1.Cost) } t1 = time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC) t2 = time.Date(2012, time.February, 2, 18, 01, 0, 0, time.UTC) cd = &CallDescriptor{Direction: OUTBOUND, Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} - cc2, _ := cd.GetCost() + cc2, _ := cd.getCost() if cc2.Cost != 91 { t.Errorf("expected 91 was %v", cc2.Cost) } @@ -133,7 +133,7 @@ func TestCallCostMergeEmpty(t *testing.T) { t1 := time.Date(2012, time.February, 2, 17, 58, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC) cd := &CallDescriptor{Direction: OUTBOUND, Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} - cc1, _ := cd.GetCost() + cc1, _ := cd.getCost() cc2 := &CallCost{} cc1.Merge(cc2) if len(cc1.Timespans) != 1 { @@ -177,7 +177,7 @@ func TestCallCostToDataCostError(t *testing.T) { TimeEnd: time.Date(2014, 3, 4, 6, 1, 5, 0, time.UTC), TOR: utils.VOICE, } - cc, _ := cd.GetCost() + cc, _ := cd.getCost() _, err := cc.ToDataCost() if err == nil { t.Error("Failed to throw error on call to datacost!") @@ -195,7 +195,7 @@ func TestCallCostToDataCostError(t *testing.T) { TimeEnd: time.Date(2014, 3, 4, 6, 1, 5, 0, time.UTC), TOR: DATA, } - cc, _ := cd.GetCost() + cc, _ := cd.getCost() dc, err := cc.ToDataCost() if err != nil { t.Error("Error convertiong to data cost: ", err) diff --git a/engine/calldesc.go b/engine/calldesc.go index 3e1b26fff..626d754ba 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -405,6 +405,38 @@ func (cd *CallDescriptor) GetDuration() time.Duration { Creates a CallCost structure with the cost information calculated for the received CallDescriptor. */ func (cd *CallDescriptor) GetCost() (*CallCost, error) { + cc, err := cd.getCost() + if err != nil { + return nil, err + } + + cost := 0.0 + for i, ts := range cc.Timespans { + // only add connect fee if this is the first/only call cost request + //log.Printf("Interval: %+v", ts.RateInterval.Timing) + if cd.LoopIndex == 0 && i == 0 && ts.RateInterval != nil { + cost += ts.RateInterval.Rating.ConnectFee + } + // handle max cost + maxCost, strategy := ts.RateInterval.GetMaxCost() + if strategy != "" && maxCost > 0 { + if strategy == utils.MAX_COST_FREE && cd.MaxCostSoFar >= maxCost { + cost = maxCost + cd.MaxCostSoFar = maxCost + } else { + cost += ts.getCost() + cd.MaxCostSoFar += cost + } + + } else { + cost += ts.getCost() + } + } + cc.Cost = cost + return cc, nil +} + +func (cd *CallDescriptor) getCost() (*CallCost, error) { // check for 0 duration if cd.TimeEnd.Sub(cd.TimeStart) == 0 { return cd.CreateCallCost(), nil @@ -420,7 +452,6 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) { Logger.Err(fmt.Sprintf("error getting cost for key <%s>: %s", cd.GetKey(cd.Subject), err.Error())) return &CallCost{Cost: -1}, err } - timespans := cd.splitInTimeSpans() cost := 0.0 @@ -432,6 +463,7 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) { } cost += ts.getCost() } + //startIndex := len(fmt.Sprintf("%s:%s:%s:", cd.Direction, cd.Tenant, cd.Category)) cc := cd.CreateCallCost() cc.Cost = cost