data get cost

This commit is contained in:
Radu Ioan Fericean
2014-04-24 20:01:20 +03:00
parent 251d504d40
commit 42718617b9
4 changed files with 69 additions and 22 deletions

View File

@@ -116,6 +116,7 @@ type CallDescriptor struct {
FallbackSubject string // the subject to check for destination if not found on primary subject
RatingInfos RatingInfos
Increments Increments
Amount float64
account *Account
}
@@ -296,10 +297,9 @@ func (cd *CallDescriptor) GetKey(subject string) string {
}
// Splits the received timespan into sub time spans according to the activation periods intervals.
func (cd *CallDescriptor) splitInTimeSpans(firstSpan *TimeSpan) (timespans []*TimeSpan) {
if firstSpan == nil {
firstSpan = &TimeSpan{TimeStart: cd.TimeStart, TimeEnd: cd.TimeEnd, CallDuration: cd.CallDuration}
}
func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) {
firstSpan := &TimeSpan{TimeStart: cd.TimeStart, TimeEnd: cd.TimeEnd, CallDuration: cd.CallDuration}
timespans = append(timespans, firstSpan)
if len(cd.RatingInfos) == 0 {
return
@@ -327,6 +327,12 @@ func (cd *CallDescriptor) splitInTimeSpans(firstSpan *TimeSpan) (timespans []*Ti
}
}
}
if cd.Amount > 0 {
cd.TimeEnd = cd.TimeStart.Add(time.Duration(utils.Round(cd.Amount, 0, utils.ROUNDING_UP)) * time.Second)
cd.CallDuration = cd.TimeEnd.Sub(cd.TimeStart)
//first span should be still the only one
firstSpan.TimeStart, firstSpan.TimeEnd, firstSpan.CallDuration = cd.TimeStart, cd.TimeEnd, cd.CallDuration
}
// Logger.Debug(fmt.Sprintf("After SplitByRatingPlan: %+v", timespans))
// split on price intervals
for i := 0; i < len(timespans); i++ {
@@ -402,7 +408,8 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) {
Logger.Err(fmt.Sprintf("error getting cost for key %s: %v", cd.GetKey(cd.Subject), err))
return &CallCost{Cost: -1}, err
}
timespans := cd.splitInTimeSpans(nil)
timespans := cd.splitInTimeSpans()
cost := 0.0
for i, ts := range timespans {

View File

@@ -93,7 +93,7 @@ func TestSplitSpans(t *testing.T) {
cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
cd.LoadRatingPlans()
timespans := cd.splitInTimeSpans(nil)
timespans := cd.splitInTimeSpans()
if len(timespans) != 2 {
t.Log(cd.RatingInfos)
t.Error("Wrong number of timespans: ", len(timespans))
@@ -106,7 +106,7 @@ func TestSplitSpansRoundToIncrements(t *testing.T) {
cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "test", Subject: "trp", Destination: "0256", TimeStart: t1, TimeEnd: t2, CallDuration: 132 * time.Second}
cd.LoadRatingPlans()
timespans := cd.splitInTimeSpans(nil)
timespans := cd.splitInTimeSpans()
if len(timespans) != 2 {
t.Logf("%+v", cd)
t.Log(cd.RatingInfos)
@@ -649,16 +649,56 @@ func TestMaxDebitConsumesMinutes(t *testing.T) {
func TestCDGetCostANY(t *testing.T) {
cd1 := &CallDescriptor{
Direction: "*out",
TOR: "0",
Tenant: "vdf",
TOR: "data",
Tenant: "cgrates.org",
Subject: "rif",
Destination: utils.ANY,
TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC),
TimeEnd: time.Date(2014, 3, 4, 6, 0, 5, 0, time.UTC),
TimeEnd: time.Date(2014, 3, 4, 6, 0, 1, 0, time.UTC),
LoopIndex: 0,
CallDuration: 0}
cc, err := cd1.GetCost()
if err != nil || cc.Cost != 6 {
if err != nil || cc.Cost != 60 {
t.Errorf("Error getting *any dest: %+v %v", cc, err)
}
}
func TestCDSplitInDataSlots(t *testing.T) {
cd := &CallDescriptor{
Direction: "*out",
TOR: "data",
Tenant: "cgrates.org",
Subject: "rif",
Destination: utils.ANY,
TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC),
TimeEnd: time.Date(2014, 3, 4, 6, 0, 1, 0, time.UTC),
LoopIndex: 0,
CallDuration: 0,
Amount: 65,
}
cd.LoadRatingPlans()
timespans := cd.splitInTimeSpans()
if len(timespans) != 2 {
t.Log(cd.RatingInfos[0])
t.Error("Wrong number of timespans: ", len(timespans))
}
}
func TestCDDataGetCost(t *testing.T) {
cd := &CallDescriptor{
Direction: "*out",
TOR: "data",
Tenant: "cgrates.org",
Subject: "rif",
Destination: utils.ANY,
TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC),
TimeEnd: time.Date(2014, 3, 4, 6, 0, 1, 0, time.UTC),
LoopIndex: 0,
CallDuration: 0,
Amount: 65,
}
cc, err := cd.GetCost()
if err != nil || cc.Cost != 65 {
t.Errorf("Error getting *any dest: %+v %v", cc, err)
}
}
@@ -705,7 +745,7 @@ func BenchmarkSplitting(b *testing.B) {
cd.LoadRatingPlans()
b.StartTimer()
for i := 0; i < b.N; i++ {
cd.splitInTimeSpans(nil)
cd.splitInTimeSpans()
}
}

View File

@@ -61,8 +61,8 @@ R2,0,0.1,60s,1s,0,*middle,2
R3,0,0.05,60s,1s,0,*middle,2
R4,1,1,1s,1s,0,*up,2
R5,0,0.5,1s,1s,0,*down,2
LANDLINE_OFFPEAK,0,1,1s,60s,0s,*up,4
LANDLINE_OFFPEAK,0,1,1s,1s,60s,*up,4
LANDLINE_OFFPEAK,0,1,1,60,0,*up,4
LANDLINE_OFFPEAK,0,1,1,1,60,*up,4
GBP_71,0.000000,5.55555,1s,1s,0s,*up,4
GBP_72,0.000000,7.77777,1s,1s,0s,*up,4
GBP_70,0.000000,1,1,1,0,*up,4
@@ -84,7 +84,7 @@ T2,GERMANY_O2,GBP_70
T2,GERMANY_PREMIUM,GBP_71
DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5
DATA_RATE,*any,R4
DATA_RATE,*any,LANDLINE_OFFPEAK
`
ratingPlans = `
STANDARD,RT_STANDARD,WORKDAYS_00,10
@@ -97,13 +97,13 @@ DEFAULT,RT_DEFAULT,WORKDAYS_00,10
EVENING,P1,WORKDAYS_00,10
EVENING,P2,WORKDAYS_18,10
EVENING,P2,WEEKENDS,10
EVENING,DATA_RATE,ALWAYS,10
TDRT,T1,WORKDAYS_00,10
TDRT,T2,WORKDAYS_00,10
G,RT_STANDARD,WORKDAYS_00,10
R,P1,WORKDAYS_00,10
RP_UK_Mobile_BIG5_PKG,DR_UK_Mobile_BIG5_PKG,ALWAYS,10
RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10
RP_DATA,DATA_RATE,ALWAYS,10
`
ratingProfiles = `
CUSTOMER_1,0,*out,rif:from:tm,2012-01-01T00:00:00Z,PREMIUM,danb
@@ -124,6 +124,7 @@ vdf,0,*out,fallback1,2013-11-18T13:47:00Z,G,fallback2
vdf,0,*out,fallback2,2013-11-18T13:45:00Z,R,rif
cgrates.org,call,*out,*any,2013-01-06T00:00:00Z,RP_UK,
cgrates.org,call,*out,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,
cgrates.org,data,*out,rif,2013-01-06T00:00:00Z,RP_DATA,
`
sharedGroups = `
SG1,*any,*lowest,
@@ -345,7 +346,7 @@ func TestLoadRates(t *testing.T) {
t.Error("Error loading rate: ", rate)
}
rate = csvr.rates["LANDLINE_OFFPEAK"].RateSlots[0]
if expctRs, err = utils.NewRateSlot(0, 1, "1s", "60s", "0s", utils.ROUNDING_UP, 4); err != nil {
if expctRs, err = utils.NewRateSlot(0, 1, "1", "60", "0", utils.ROUNDING_UP, 4); err != nil {
t.Error("Error loading rate: ", rate, err.Error())
} else if !reflect.DeepEqual(rate, expctRs) ||
rate.RateUnitDuration() != expctRs.RateUnitDuration() ||
@@ -354,7 +355,7 @@ func TestLoadRates(t *testing.T) {
t.Error("Error loading rate: ", rate)
}
rate = csvr.rates["LANDLINE_OFFPEAK"].RateSlots[1]
if expctRs, err = utils.NewRateSlot(0, 1, "1s", "1s", "60s", utils.ROUNDING_UP, 4); err != nil {
if expctRs, err = utils.NewRateSlot(0, 1, "1", "1", "60", utils.ROUNDING_UP, 4); err != nil {
t.Error("Error loading rate: ", rate, err.Error())
} else if !reflect.DeepEqual(rate, expctRs) ||
rate.RateUnitDuration() != expctRs.RateUnitDuration() ||
@@ -477,7 +478,7 @@ func TestLoadDestinationRates(t *testing.T) {
}
func TestLoadRatingPlans(t *testing.T) {
if len(csvr.ratingPlans) != 9 {
if len(csvr.ratingPlans) != 10 {
t.Error("Failed to load rating plans: ", len(csvr.ratingPlans))
}
rplan := csvr.ratingPlans["STANDARD"]
@@ -597,7 +598,7 @@ func TestLoadRatingPlans(t *testing.T) {
}
func TestLoadRatingProfiles(t *testing.T) {
if len(csvr.ratingProfiles) != 14 {
if len(csvr.ratingProfiles) != 15 {
t.Error("Failed to load rating profiles: ", len(csvr.ratingProfiles), csvr.ratingProfiles)
}
rp := csvr.ratingProfiles["*out:test:0:trp"]

View File

@@ -317,7 +317,6 @@ a new timespan starting from the end of the received one.
The interval will attach itself to the timespan that overlaps the interval.
*/
func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) {
//Logger.Debug("here: ", ts, " +++ ", i)
// if the span is not in interval return nil
if !(i.Contains(ts.TimeStart, false) || i.Contains(ts.TimeEnd, true)) {
//Logger.Debug("Not in interval")
@@ -328,7 +327,7 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) {
if i.Rating != nil {
i.Rating.Rates.Sort()
for _, rate := range i.Rating.Rates {
// Logger.Debug(fmt.Sprintf("Rate: %+v", rate))
//Logger.Debug(fmt.Sprintf("Rate: %+v", rate))
if ts.GetGroupStart() < rate.GroupIntervalStart && ts.GetGroupEnd() > rate.GroupIntervalStart {
// Logger.Debug(fmt.Sprintf("Splitting"))
ts.SetRateInterval(i)