removed connect fee as a separte field in call cost

This commit is contained in:
Radu Ioan Fericean
2014-02-05 20:02:40 +02:00
parent 9f9174d0cc
commit 3bf3f04cc6
11 changed files with 62 additions and 57 deletions

View File

@@ -14,7 +14,6 @@ CREATE TABLE `cost_details` (
`account` varchar(128) NOT NULL,
`subject` varchar(128) NOT NULL,
`destination` varchar(128) NOT NULL,
`connect_fee` DECIMAL(5,4) NOT NULL,
`cost` DECIMAL(20,4) NOT NULL,
`timespans` text,
`source` varchar(64) NOT NULL,

View File

@@ -138,7 +138,7 @@ func (b *Balance) DebitMinutes(cc *CallCost, count bool, ub *UserBalance, moneyB
if b.Value >= amount {
b.Value -= amount
increment.SetMinuteBalance(b.Uuid)
increment.MinuteInfo = &MinuteInfo{cc.Destination, amount, 0}
increment.MinuteInfo = &MinuteInfo{cc.Destination, amount}
increment.Cost = 0
increment.paid = true
if count {
@@ -180,7 +180,7 @@ func (b *Balance) DebitMinutes(cc *CallCost, count bool, ub *UserBalance, moneyB
cc.Timespans.RemoveOverlapedFromIndex(tsIndex)
b.Value -= amount
newTs.Increments[0].SetMinuteBalance(b.Uuid)
newTs.Increments[0].MinuteInfo = &MinuteInfo{cc.Destination, amount, 0}
newTs.Increments[0].MinuteInfo = &MinuteInfo{cc.Destination, amount}
newTs.Increments[0].Cost = 0
newTs.Increments[0].paid = true
if count {
@@ -222,7 +222,7 @@ func (b *Balance) DebitMinutes(cc *CallCost, count bool, ub *UserBalance, moneyB
nInc.SetMinuteBalance(b.Uuid)
nInc.SetMoneyBalance(moneyBal.Uuid)
nInc.MinuteInfo = &MinuteInfo{newCC.Destination, seconds, 0}
nInc.MinuteInfo = &MinuteInfo{newCC.Destination, seconds}
nInc.paid = true
if count {
ub.countUnits(&Action{BalanceId: MINUTES, Direction: newCC.Direction, Balance: &Balance{Value: seconds, DestinationId: newCC.Destination}})

View File

@@ -26,13 +26,13 @@ import (
// The output structure that will be returned with the call cost information.
type CallCost struct {
Direction, TOR, Tenant, Subject, Account, Destination string
Cost, ConnectFee float64
Cost float64
Timespans TimeSpans
}
// Pretty printing for call cost
func (cc *CallCost) String() (r string) {
r = fmt.Sprintf("%v[%v] : %s(%s) -> %s (", cc.Cost, cc.ConnectFee, cc.Subject, cc.Account, cc.Destination)
r = fmt.Sprintf("%v[%v] : %s(%s) -> %s (", cc.Cost, cc.GetConnectFee(), cc.Subject, cc.Account, cc.Destination)
for _, ts := range cc.Timespans {
r += fmt.Sprintf(" %v,", ts.GetDuration())
}
@@ -81,6 +81,15 @@ func (cc *CallCost) GetDuration() (td time.Duration) {
return
}
func (cc *CallCost) GetConnectFee() float64 {
if len(cc.Timespans) == 0 ||
cc.Timespans[0].RateInterval == nil ||
cc.Timespans[0].RateInterval.Rating == nil {
return 0
}
return cc.Timespans[0].RateInterval.Rating.ConnectFee
}
// Creates a CallDescriptor structure copying related data from CallCost
func (cc *CallCost) CreateCallDescriptor() *CallDescriptor {
return &CallDescriptor{

View File

@@ -28,8 +28,8 @@ func TestSingleResultMerge(t *testing.T) {
t2 := time.Date(2012, time.February, 2, 17, 1, 0, 0, time.UTC)
cd := &CallDescriptor{Direction: OUTBOUND, TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
cc1, _ := cd.GetCost()
if cc1.Cost != 60 {
t.Errorf("expected 60 was %v", cc1.Cost)
if cc1.Cost != 61 {
t.Errorf("expected 61 was %v", cc1.Cost)
}
/*t1 = time.Date(2012, time.February, 2, 17, 1, 0, 0, time.UTC)
t2 = time.Date(2012, time.February, 2, 17, 2, 0, 0, time.UTC)
@@ -52,8 +52,8 @@ func TestMultipleResultMerge(t *testing.T) {
t2 := time.Date(2012, time.February, 2, 18, 0, 0, 0, time.UTC)
cd := &CallDescriptor{Direction: OUTBOUND, TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
cc1, _ := cd.GetCost()
if cc1.Cost != 60 {
t.Errorf("expected 60 was %v", cc1.Cost)
if cc1.Cost != 61 {
t.Errorf("expected 61 was %v", cc1.Cost)
for _, ts := range cc1.Timespans {
t.Log(ts.RateInterval)
}
@@ -72,8 +72,8 @@ func TestMultipleResultMerge(t *testing.T) {
if len(cc1.Timespans) != 2 || cc1.Timespans[0].GetDuration().Seconds() != 60 {
t.Error("wrong resulted timespan: ", len(cc1.Timespans))
}
if cc1.Cost != 90 {
t.Errorf("Exdpected 90 was %v", cc1.Cost)
if cc1.Cost != 91 {
t.Errorf("Exdpected 91 was %v", cc1.Cost)
}
}
@@ -82,8 +82,8 @@ func TestMultipleInputLeftMerge(t *testing.T) {
t2 := time.Date(2012, time.February, 2, 18, 01, 0, 0, time.UTC)
cd := &CallDescriptor{Direction: OUTBOUND, TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
cc1, _ := cd.GetCost()
if cc1.Cost != 90 {
t.Errorf("expected 90 was %v", cc1.Cost)
if cc1.Cost != 91 {
t.Errorf("expected 91 was %v", cc1.Cost)
}
/*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)
@@ -106,22 +106,22 @@ func TestMultipleInputRightMerge(t *testing.T) {
t2 := time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC)
cd := &CallDescriptor{Direction: OUTBOUND, TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
cc1, _ := cd.GetCost()
if cc1.Cost != 60 {
t.Errorf("expected 60 was %v", cc1.Cost)
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, TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
cc2, _ := cd.GetCost()
if cc2.Cost != 90 {
t.Errorf("expected 90 was %v", cc2.Cost)
if cc2.Cost != 91 {
t.Errorf("expected 91 was %v", cc2.Cost)
}
cc1.Merge(cc2)
if len(cc1.Timespans) != 2 || cc1.Timespans[0].GetDuration().Seconds() != 120 {
t.Error("wrong resulted timespan: ", len(cc1.Timespans))
}
if cc1.Cost != 150 {
t.Errorf("Exdpected 150 was %v", cc1.Cost)
if cc1.Cost != 152 {
t.Errorf("Exdpected 152 was %v", cc1.Cost)
}
}

View File

@@ -382,7 +382,7 @@ 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) {
if cd.CallDuration == 0 {
if cd.CallDuration < cd.TimeEnd.Sub(cd.TimeStart) {
cd.CallDuration = cd.TimeEnd.Sub(cd.TimeStart)
}
err := cd.LoadRatingPlans()
@@ -392,12 +392,11 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) {
}
timespans := cd.splitInTimeSpans(nil)
cost := 0.0
connectionFee := 0.0
for i, ts := range timespans {
// only add connect fee if this is the first/only call cost request
if cd.LoopIndex == 0 && i == 0 && ts.RateInterval != nil {
connectionFee = ts.RateInterval.Rating.ConnectFee
cost += ts.RateInterval.Rating.ConnectFee
}
cost += ts.getCost()
}
@@ -412,7 +411,6 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) {
Destination: cd.Destination,
Subject: cd.Subject,
Cost: cost,
ConnectFee: connectionFee,
Timespans: timespans}
//Logger.Info(fmt.Sprintf("<Rater> Get Cost: %s => %v", cd.GetKey(), cc))
return cc, err
@@ -463,7 +461,7 @@ func (cd *CallDescriptor) GetMaxSessionDuration() (time.Duration, error) {
cd.TimeStart = cd.TimeStart.Add(availableDuration)
// substract the connect fee
cc, err := cd.GetCost()
availableCredit -= cc.ConnectFee
availableCredit -= cc.GetConnectFee()
if err != nil {
Logger.Err(fmt.Sprintf("Could not get cost for %s: %s.", cd.GetKey(cd.Subject), err.Error()))
return 0, err
@@ -503,7 +501,7 @@ func (cd *CallDescriptor) Debit() (cc *CallCost, err error) {
//Logger.Debug(fmt.Sprintf("UserBalance: %s", ub))
//cCost, _ := json.Marshal(cc)
//Logger.Debug(fmt.Sprintf("CallCost: %s", cCost))
if cc.Cost != 0 || cc.ConnectFee != 0 {
if cc.Cost != 0 || cc.GetConnectFee() != 0 {
userBalance.debitCreditBalance(cc, true)
}
cost := 0.0

View File

@@ -104,8 +104,8 @@ func TestGetCost(t *testing.T) {
t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC)
cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2, LoopIndex: 0}
result, _ := cd.GetCost()
expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2700, ConnectFee: 1}
if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee {
expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2701}
if result.Cost != expected.Cost || result.GetConnectFee() != 1 {
t.Errorf("Expected %v was %v", expected, result)
}
}
@@ -115,8 +115,8 @@ func TestGetCostTimespans(t *testing.T) {
t2 := time.Date(2013, time.October, 8, 9, 24, 27, 0, time.UTC)
cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "test", Subject: "trp", Destination: "0256", TimeStart: t1, TimeEnd: t2, LoopIndex: 0, CallDuration: 85 * time.Second}
result, _ := cd.GetCost()
expected := &CallCost{Tenant: "test", Subject: "trp", Destination: "0256", Cost: 85, ConnectFee: 0}
if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee || len(result.Timespans) != 2 {
expected := &CallCost{Tenant: "test", Subject: "trp", Destination: "0256", Cost: 85}
if result.Cost != expected.Cost || result.GetConnectFee() != 0 || len(result.Timespans) != 2 {
t.Errorf("Expected %+v was %+v", expected, result)
}
@@ -172,8 +172,9 @@ func TestGetCostNoConnectFee(t *testing.T) {
t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC)
cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2, LoopIndex: 1}
result, _ := cd.GetCost()
expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2700, ConnectFee: 0}
if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee {
expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2700}
// connect fee is not added because LoopIndex is 1
if result.Cost != expected.Cost || result.GetConnectFee() != 1 {
t.Errorf("Expected %v was %v", expected, result)
}
}
@@ -183,8 +184,8 @@ func TestGetCostAccount(t *testing.T) {
t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC)
cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Account: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
result, _ := cd.GetCost()
expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2700, ConnectFee: 1}
if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee {
expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2701}
if result.Cost != expected.Cost || result.GetConnectFee() != 1 {
t.Errorf("Expected %v was %v", expected, result)
}
}
@@ -194,8 +195,8 @@ func TestFullDestNotFound(t *testing.T) {
t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC)
cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256308200", TimeStart: t1, TimeEnd: t2}
result, _ := cd.GetCost()
expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2700, ConnectFee: 1}
if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee {
expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2701}
if result.Cost != expected.Cost || result.GetConnectFee() != 1 {
t.Log(cd.RatingInfos)
t.Errorf("Expected %v was %v", expected, result)
}
@@ -206,8 +207,8 @@ func TestSubjectNotFound(t *testing.T) {
t2 := time.Date(2013, time.February, 1, 18, 30, 0, 0, time.UTC)
cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "not_exiting", Destination: "025740532", TimeStart: t1, TimeEnd: t2}
result, _ := cd.GetCost()
expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0257", Cost: 2700, ConnectFee: 1}
if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee {
expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0257", Cost: 2701}
if result.Cost != expected.Cost || result.GetConnectFee() != 1 {
t.Logf("%+v", result.Timespans[0].RateInterval)
t.Errorf("Expected %v was %v", expected, result)
}
@@ -218,8 +219,8 @@ func TestMultipleRatingPlans(t *testing.T) {
t2 := time.Date(2012, time.February, 8, 18, 30, 0, 0, time.UTC)
cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0257308200", TimeStart: t1, TimeEnd: t2}
result, _ := cd.GetCost()
expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0257", Cost: 2700, ConnectFee: 1}
if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee {
expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0257", Cost: 2701}
if result.Cost != expected.Cost || result.GetConnectFee() != 1 {
t.Log(result.Timespans)
t.Errorf("Expected %v was %v", expected, result)
}
@@ -230,7 +231,7 @@ func TestSpansMultipleRatingPlans(t *testing.T) {
t2 := time.Date(2012, time.February, 8, 0, 30, 0, 0, time.UTC)
cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0257308200", TimeStart: t1, TimeEnd: t2}
result, _ := cd.GetCost()
if result.Cost != 1200 || result.ConnectFee != 0 {
if result.Cost != 1200 || result.GetConnectFee() != 0 {
t.Errorf("Expected %v was %v", 1200, result)
}
}
@@ -240,8 +241,8 @@ func TestLessThanAMinute(t *testing.T) {
t2 := time.Date(2012, time.February, 8, 23, 50, 30, 0, time.UTC)
cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0257308200", TimeStart: t1, TimeEnd: t2}
result, _ := cd.GetCost()
expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0257", Cost: 15, ConnectFee: 0}
if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee {
expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0257", Cost: 15}
if result.Cost != expected.Cost || result.GetConnectFee() != 0 {
t.Errorf("Expected %v was %v", expected, result)
}
}
@@ -251,8 +252,8 @@ func TestUniquePrice(t *testing.T) {
t2 := time.Date(2012, time.February, 8, 23, 50, 21, 0, time.UTC)
cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0723045326", TimeStart: t1, TimeEnd: t2}
result, _ := cd.GetCost()
expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0723", Cost: 1810.5, ConnectFee: 0}
if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee {
expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0723", Cost: 1810.5}
if result.Cost != expected.Cost || result.GetConnectFee() != 0 {
t.Errorf("Expected %v was %v", expected, result)
}
}
@@ -262,8 +263,8 @@ func TestMinutesCost(t *testing.T) {
t2 := time.Date(2012, time.February, 8, 22, 51, 50, 0, time.UTC)
cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0723", TimeStart: t1, TimeEnd: t2}
result, _ := cd.GetCost()
expected := &CallCost{Tenant: "vdf", Subject: "minutosu", Destination: "0723", Cost: 55, ConnectFee: 0}
if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee {
expected := &CallCost{Tenant: "vdf", Subject: "minutosu", Destination: "0723", Cost: 55}
if result.Cost != expected.Cost || result.GetConnectFee() != 0 {
t.Errorf("Expected %v was %v", expected, result)
}
}

View File

@@ -656,7 +656,6 @@ func (self *SQLStorage) LogCallCost(uuid, source, runid string, cc *CallCost) (e
cc.Account,
cc.Subject,
cc.Destination,
cc.ConnectFee,
cc.Cost,
tss,
source,
@@ -673,7 +672,7 @@ func (self *SQLStorage) GetCallCostLog(cgrid, source, runid string) (cc *CallCos
var timespansJson string
cc = &CallCost{Cost: -1}
err = row.Scan(&cgrid, &accid, &cc.Direction, &cc.Tenant, &cc.TOR, &cc.Account, &cc.Subject,
&cc.Destination, &cc.ConnectFee, &cc.Cost, &timespansJson, &src)
&cc.Destination, &cc.Cost, &timespansJson, &src)
if err = json.Unmarshal([]byte(timespansJson), &cc.Timespans); err != nil {
return nil, err
}

View File

@@ -52,7 +52,7 @@ type Increment struct {
type MinuteInfo struct {
DestinationId string
Quantity float64
Price float64
//Price float64
}
type TimeSpans []*TimeSpan
@@ -124,7 +124,6 @@ func (timespans *TimeSpans) OverlapWithTimeSpans(paidTs TimeSpans, newTs *TimeSp
} else {
tss = append(tss[:overlapStartIndex], tss[overlapEndIndex+1:]...)
}
// append the timespans to outer tss
for i, pts := range paidTs {
tss = append(tss, nil)

View File

@@ -155,8 +155,8 @@ func (ub *UserBalance) debitCreditBalance(cc *CallCost, count bool) error {
usefulMinuteBalances := ub.getBalancesForPrefix(cc.Destination, ub.BalanceMap[MINUTES+cc.Direction])
usefulMoneyBalances := ub.getBalancesForPrefix(cc.Destination, ub.BalanceMap[CREDIT+cc.Direction])
// debit connect fee
if cc.ConnectFee > 0 {
amount := cc.ConnectFee
if cc.GetConnectFee() > 0 {
amount := cc.GetConnectFee()
paid := false
for _, b := range usefulMoneyBalances {
if b.Value >= amount {

View File

@@ -510,13 +510,12 @@ func TestDebitCreditNoConectFeeCredit(t *testing.T) {
cc := &CallCost{
Direction: OUTBOUND,
Destination: "0723045326",
ConnectFee: 10.0,
Timespans: []*TimeSpan{
&TimeSpan{
TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC),
TimeEnd: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC),
CallDuration: 0,
RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}},
RateInterval: &RateInterval{Rating: &RIRate{ConnectFee: 10.0, Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}},
},
&TimeSpan{
TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC),

View File

@@ -21,10 +21,11 @@ package mediator
import (
"errors"
"fmt"
"time"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
"time"
)
func NewMediator(connector engine.Connector, logDb engine.LogStorage, cdrDb engine.CdrStorage, cfg *config.CGRConfig) (m *Mediator, err error) {
@@ -123,7 +124,7 @@ func (self *Mediator) rateCDR(cdr *utils.StoredCdr) error {
} else if qryCC == nil {
return errors.New("No cost returned from rater")
}
cdr.Cost = qryCC.ConnectFee + qryCC.Cost
cdr.Cost = qryCC.Cost
return nil
}