mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
@@ -84,6 +84,8 @@ func TestMultipleInputLeftMerge(t *testing.T) {
|
||||
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()
|
||||
//log.Printf("Timing: %+v", cc1.Timespans[1].RateInterval.Timing)
|
||||
//log.Printf("Rating: %+v", cc1.Timespans[1].RateInterval.Rating)
|
||||
if cc1.Cost != 91 {
|
||||
t.Errorf("expected 91 was %v", cc1.Cost)
|
||||
}
|
||||
|
||||
@@ -302,7 +302,6 @@ func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) {
|
||||
if len(cd.RatingInfos) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
firstSpan.setRatingInfo(cd.RatingInfos[0])
|
||||
if cd.TOR == utils.VOICE {
|
||||
// split on rating plans
|
||||
@@ -335,11 +334,14 @@ func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) {
|
||||
//timespans[i].RatingPlan = nil
|
||||
rp.RateIntervals.Sort()
|
||||
for _, interval := range rp.RateIntervals {
|
||||
//log.Printf("\tINTERVAL: %+v %v", interval, len(rp.RateIntervals))
|
||||
if timespans[i].RateInterval != nil && timespans[i].RateInterval.Weight < interval.Weight {
|
||||
//log.Printf("\tINTERVAL: %+v", interval.Timing)
|
||||
if timespans[i].hasBetterRateIntervalThan(interval) {
|
||||
//log.Print("continue")
|
||||
continue // if the timespan has an interval than it already has a heigher weight
|
||||
}
|
||||
newTs := timespans[i].SplitByRateInterval(interval, cd.TOR != utils.VOICE)
|
||||
//utils.PrintFull(timespans[i])
|
||||
//utils.PrintFull(newTs)
|
||||
if newTs != nil {
|
||||
newTs.setRatingInfo(rp)
|
||||
// insert the new timespan
|
||||
@@ -347,7 +349,9 @@ func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) {
|
||||
timespans = append(timespans, nil)
|
||||
copy(timespans[index+1:], timespans[index:])
|
||||
timespans[index] = newTs
|
||||
break
|
||||
if timespans[i].RateInterval != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,6 +116,87 @@ func TestSplitSpans(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitSpansWeekend(t *testing.T) {
|
||||
cd := &CallDescriptor{Direction: OUTBOUND,
|
||||
Category: "postpaid",
|
||||
TOR: utils.VOICE,
|
||||
Tenant: "foehn",
|
||||
Subject: "foehn",
|
||||
Account: "foehn",
|
||||
Destination: "0034678096720",
|
||||
TimeStart: time.Date(2015, 4, 24, 7, 59, 4, 0, time.UTC),
|
||||
TimeEnd: time.Date(2015, 4, 24, 8, 2, 0, 0, time.UTC),
|
||||
LoopIndex: 0,
|
||||
DurationIndex: 176 * time.Second,
|
||||
FallbackSubject: "",
|
||||
RatingInfos: RatingInfos{
|
||||
&RatingInfo{
|
||||
MatchedSubject: "*out:foehn:postpaid:foehn",
|
||||
MatchedPrefix: "0034678",
|
||||
MatchedDestId: "SPN_MOB",
|
||||
ActivationTime: time.Date(2015, 4, 23, 0, 0, 0, 0, time.UTC),
|
||||
RateIntervals: []*RateInterval{
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
WeekDays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
|
||||
StartTime: "08:00:00",
|
||||
},
|
||||
Rating: &RIRate{
|
||||
ConnectFee: 0,
|
||||
RoundingMethod: "*up",
|
||||
RoundingDecimals: 6,
|
||||
Rates: RateGroups{
|
||||
&Rate{Value: 1, RateIncrement: 1 * time.Second, RateUnit: 1 * time.Second},
|
||||
},
|
||||
},
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
WeekDays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
Rating: &RIRate{
|
||||
ConnectFee: 0,
|
||||
RoundingMethod: "*up",
|
||||
RoundingDecimals: 6,
|
||||
Rates: RateGroups{
|
||||
&Rate{Value: 1, RateIncrement: 1 * time.Second, RateUnit: 1 * time.Second},
|
||||
},
|
||||
},
|
||||
},
|
||||
&RateInterval{
|
||||
Timing: &RITiming{
|
||||
WeekDays: []time.Weekday{time.Saturday, time.Sunday},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
Rating: &RIRate{
|
||||
ConnectFee: 0,
|
||||
RoundingMethod: "*up",
|
||||
RoundingDecimals: 6,
|
||||
Rates: RateGroups{
|
||||
&Rate{Value: 1, RateIncrement: 1 * time.Second, RateUnit: 1 * time.Second},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
//log.Print("=============================")
|
||||
timespans := cd.splitInTimeSpans()
|
||||
if len(timespans) != 2 {
|
||||
t.Log(cd.RatingInfos)
|
||||
t.Error("Wrong number of timespans: ", len(timespans))
|
||||
}
|
||||
if timespans[0].RateInterval == nil ||
|
||||
timespans[0].RateInterval.Timing.StartTime != "00:00:00" ||
|
||||
timespans[1].RateInterval == nil ||
|
||||
timespans[1].RateInterval.Timing.StartTime != "08:00:00" {
|
||||
t.Errorf("Error setting rateinterval: %+v %+v", timespans[0].RateInterval.Timing.StartTime, timespans[1].RateInterval.Timing.StartTime)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitSpansRoundToIncrements(t *testing.T) {
|
||||
t1 := time.Date(2013, time.October, 7, 14, 50, 0, 0, time.UTC)
|
||||
t2 := time.Date(2013, time.October, 7, 14, 52, 12, 0, time.UTC)
|
||||
|
||||
@@ -108,17 +108,8 @@ func (ris RatingInfos) Sort() {
|
||||
}
|
||||
|
||||
func (ris RatingInfos) String() string {
|
||||
result := "Rating Infos:\n"
|
||||
for _, ri := range ris {
|
||||
result += fmt.Sprintf("%+v\n", ri)
|
||||
result += "Rate Intervals:\n"
|
||||
for _, interval := range ri.RateIntervals {
|
||||
result += fmt.Sprintf("%+v\n", interval.Timing)
|
||||
result += fmt.Sprintf("%+v\n", interval.Rating)
|
||||
result += fmt.Sprintf("%+v\n", interval.Weight)
|
||||
}
|
||||
}
|
||||
return result
|
||||
b, _ := json.MarshalIndent(ris, "", " ")
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (rp *RatingProfile) GetRatingPlansForPrefix(cd *CallDescriptor) (err error) {
|
||||
|
||||
@@ -331,8 +331,9 @@ The interval will attach itself to the timespan that overlaps the interval.
|
||||
*/
|
||||
func (ts *TimeSpan) SplitByRateInterval(i *RateInterval, data bool) (nts *TimeSpan) {
|
||||
// if the span is not in interval return nil
|
||||
//log.Printf("Checking: %+v (%v,%v)", i.Timing, ts.TimeStart, ts.TimeEnd)
|
||||
if !(i.Contains(ts.TimeStart, false) || i.Contains(ts.TimeEnd, true)) {
|
||||
//Logger.Debug("Not in interval")
|
||||
//log.Print("Not in interval")
|
||||
return
|
||||
}
|
||||
//Logger.Debug(fmt.Sprintf("TS: %+v", ts))
|
||||
@@ -374,7 +375,7 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval, data bool) (nts *TimeSp
|
||||
}
|
||||
// if only the start time is in the interval split the interval to the right
|
||||
if i.Contains(ts.TimeStart, false) {
|
||||
//Logger.Debug("Start in interval")
|
||||
//log.Print("Start in interval")
|
||||
splitTime := i.getRightMargin(ts.TimeStart)
|
||||
|
||||
ts.SetRateInterval(i)
|
||||
@@ -394,7 +395,7 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval, data bool) (nts *TimeSp
|
||||
}
|
||||
// if only the end time is in the interval split the interval to the left
|
||||
if i.Contains(ts.TimeEnd, true) {
|
||||
//Logger.Debug("End in interval")
|
||||
//log.Print("End in interval")
|
||||
//tmpTime := time.Date(ts.TimeStart.)
|
||||
splitTime := i.getLeftMargin(ts.TimeEnd)
|
||||
splitTime = utils.CopyHour(splitTime, ts.TimeStart)
|
||||
@@ -538,3 +539,29 @@ func (ts *TimeSpan) AddIncrement(inc *Increment) {
|
||||
ts.Increments = append(ts.Increments, inc)
|
||||
ts.TimeEnd.Add(inc.Duration)
|
||||
}
|
||||
|
||||
func (ts *TimeSpan) hasBetterRateIntervalThan(interval *RateInterval) bool {
|
||||
if ts.RateInterval == nil {
|
||||
return false
|
||||
}
|
||||
//log.Print("StartTime: ", ts.TimeStart)
|
||||
//log.Printf("OWN: %+v", ts.RateInterval.Timing)
|
||||
//log.Printf("OTHER: %+v", interval.Timing)
|
||||
if ts.RateInterval != nil &&
|
||||
ts.RateInterval.Weight < interval.Weight {
|
||||
return true
|
||||
}
|
||||
// check interval is closer
|
||||
ownLeftMargin := ts.RateInterval.getLeftMargin(ts.TimeStart)
|
||||
otherLeftMargin := interval.getLeftMargin(ts.TimeStart)
|
||||
ownDistance := ts.TimeStart.Sub(ownLeftMargin)
|
||||
otherDistance := ts.TimeStart.Sub(otherLeftMargin)
|
||||
endOtherDistance := ts.TimeEnd.Sub(otherLeftMargin)
|
||||
if otherDistance < 0 && endOtherDistance < 0 {
|
||||
return true
|
||||
}
|
||||
if ownDistance <= otherDistance {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -1597,3 +1597,87 @@ func TestTSMultipleCompressDecompress(t *testing.T) {
|
||||
t.Error("Error decompressing timespans: ", tss[0].Increments)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTSBetterIntervalZero(t *testing.T) {
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2015, 4, 27, 8, 0, 0, 0, time.UTC),
|
||||
RateInterval: &RateInterval{Timing: &RITiming{StartTime: "08:00:00"}},
|
||||
}
|
||||
|
||||
interval := &RateInterval{Timing: &RITiming{StartTime: "00:00:00"}}
|
||||
if !ts.hasBetterRateIntervalThan(interval) {
|
||||
t.Error("Wrong better rate interval!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTSBetterIntervalBefore(t *testing.T) {
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2015, 4, 27, 8, 0, 0, 0, time.UTC),
|
||||
RateInterval: &RateInterval{Timing: &RITiming{StartTime: "08:00:00"}},
|
||||
}
|
||||
|
||||
interval := &RateInterval{Timing: &RITiming{StartTime: "07:00:00"}}
|
||||
if !ts.hasBetterRateIntervalThan(interval) {
|
||||
t.Error("Wrong better rate interval!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTSBetterIntervalEqual(t *testing.T) {
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2015, 4, 27, 8, 0, 0, 0, time.UTC),
|
||||
RateInterval: &RateInterval{Timing: &RITiming{StartTime: "08:00:00"}},
|
||||
}
|
||||
|
||||
interval := &RateInterval{Timing: &RITiming{StartTime: "08:00:00"}}
|
||||
if !ts.hasBetterRateIntervalThan(interval) {
|
||||
t.Error("Wrong better rate interval!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTSBetterIntervalAfter(t *testing.T) {
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2015, 4, 27, 8, 0, 0, 0, time.UTC),
|
||||
RateInterval: &RateInterval{Timing: &RITiming{StartTime: "08:00:00"}},
|
||||
}
|
||||
|
||||
interval := &RateInterval{Timing: &RITiming{StartTime: "13:00:00"}}
|
||||
if !ts.hasBetterRateIntervalThan(interval) {
|
||||
t.Error("Wrong better rate interval!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTSBetterIntervalBetter(t *testing.T) {
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2015, 4, 27, 8, 0, 0, 0, time.UTC),
|
||||
RateInterval: &RateInterval{Timing: &RITiming{StartTime: "00:00:00"}},
|
||||
}
|
||||
|
||||
interval := &RateInterval{Timing: &RITiming{StartTime: "08:00:00"}}
|
||||
if ts.hasBetterRateIntervalThan(interval) {
|
||||
t.Error("Wrong better rate interval!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTSBetterIntervalBetterHour(t *testing.T) {
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2015, 4, 27, 8, 0, 0, 0, time.UTC),
|
||||
RateInterval: &RateInterval{Timing: &RITiming{StartTime: "00:00:00"}},
|
||||
}
|
||||
|
||||
interval := &RateInterval{Timing: &RITiming{StartTime: "06:00:00"}}
|
||||
if ts.hasBetterRateIntervalThan(interval) {
|
||||
t.Error("Wrong better rate interval!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTSBetterIntervalAgainAfter(t *testing.T) {
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2015, 4, 27, 8, 0, 0, 0, time.UTC),
|
||||
RateInterval: &RateInterval{Timing: &RITiming{StartTime: "00:00:00"}},
|
||||
}
|
||||
|
||||
interval := &RateInterval{Timing: &RITiming{StartTime: "13:00:00"}}
|
||||
if !ts.hasBetterRateIntervalThan(interval) {
|
||||
t.Error("Wrong better rate interval!")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,3 +373,8 @@ func ReflectFuncLocation(handler interface{}) (file string, line int) {
|
||||
entry := f.Entry()
|
||||
return f.FileLine(entry)
|
||||
}
|
||||
|
||||
func PrintFull(v interface{}) {
|
||||
b, _ := json.MarshalIndent(v, "", " ")
|
||||
log.Print(string(b))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user