mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-12 02:26:26 +05:00
using time.Duration for rateincrements and groupinterval
This commit is contained in:
@@ -40,7 +40,7 @@ func (self *ApierV1) SetTPRate(attrs utils.TPRate, reply *string) error {
|
||||
rts := make([]*engine.Rate, len(attrs.RateSlots))
|
||||
for idx, rtSlot := range attrs.RateSlots {
|
||||
rts[idx] = &engine.Rate{attrs.RateId, rtSlot.ConnectFee, rtSlot.Rate, float64(rtSlot.RatedUnits),
|
||||
float64(rtSlot.RateIncrements), float64(rtSlot.GroupInterval), rtSlot.RoundingMethod, rtSlot.RoundingDecimals, rtSlot.Weight}
|
||||
rtSlot.RateIncrements, rtSlot.GroupInterval, rtSlot.RoundingMethod, rtSlot.RoundingDecimals, rtSlot.Weight}
|
||||
}
|
||||
if err := self.StorDb.SetTPRates(attrs.TPid, map[string][]*engine.Rate{attrs.RateId: rts}); err != nil {
|
||||
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
|
||||
|
||||
@@ -42,8 +42,8 @@ CREATE TABLE `tp_rates` (
|
||||
`connect_fee` decimal(5,4) NOT NULL,
|
||||
`rate` decimal(5,4) NOT NULL,
|
||||
`rated_units` int(11) NOT NULL,
|
||||
`rate_increments` int(11) NOT NULL,
|
||||
`group_interval` int(11) NOT NULL,
|
||||
`rate_increments` varchar(24) NOT NULL,
|
||||
`group_interval` varchar(24) NOT NULL,
|
||||
`rounding_method` varchar(255) NOT NULL,
|
||||
`rounding_decimals` tinyint(4) NOT NULL,
|
||||
`weight` decimal(5,2) NOT NULL,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#Tag,ConnectFee,Rate,RatedUnits,RateIncrements,GroupInterval,RoundingMethod,RoundingDecimals,Weight
|
||||
LANDLINE_PEAK,0.02,0.02,60,60,0,*up,4,10
|
||||
LANDLINE_PEAK,0.02,0.01,1,1,60,*up,4,10
|
||||
MOBILE_PEAK,0.02,0.14,60,60,0,*up,4,10
|
||||
LANDLINE_OFFPEAK,1,0,60,60,0,*up,4,10
|
||||
MOBILE_OFFPEAK,0.02,0.1,60,60,0,*up,4,10
|
||||
RT_FS_USERS,0,0,60,60,0,*up,0,10
|
||||
LANDLINE_PEAK,0.02,0.02,60,60s,0,*up,4,10
|
||||
LANDLINE_PEAK,0.02,0.01,1,1s,60s,*up,4,10
|
||||
MOBILE_PEAK,0.02,0.14,60,60s,0,*up,4,10
|
||||
LANDLINE_OFFPEAK,1,0,60,60s,0,*up,4,10
|
||||
MOBILE_OFFPEAK,0.02,0.1,60,60s,0,*up,4,10
|
||||
RT_FS_USERS,0,0,60,60s,0,*up,0,10
|
||||
|
||||
|
@@ -188,7 +188,7 @@ Splits the received timespan into sub time spans according to the activation per
|
||||
*/
|
||||
func (cd *CallDescriptor) splitInTimeSpans(firstSpan *TimeSpan) (timespans []*TimeSpan) {
|
||||
if firstSpan == nil {
|
||||
firstSpan = &TimeSpan{TimeStart: cd.TimeStart, TimeEnd: cd.TimeEnd, CallDuration: cd.CallDuration.Seconds()}
|
||||
firstSpan = &TimeSpan{TimeStart: cd.TimeStart, TimeEnd: cd.TimeEnd, CallDuration: cd.CallDuration}
|
||||
}
|
||||
timespans = append(timespans, firstSpan)
|
||||
// split on (free) minute buckets
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -45,9 +45,9 @@ type Interval struct {
|
||||
}
|
||||
|
||||
type Price struct {
|
||||
StartSecond float64
|
||||
StartSecond time.Duration
|
||||
Value float64
|
||||
RateIncrements float64
|
||||
RateIncrements time.Duration
|
||||
}
|
||||
|
||||
func (p *Price) Equal(o *Price) bool {
|
||||
@@ -193,19 +193,20 @@ func (i *Interval) Equal(o *Interval) bool {
|
||||
i.EndTime == o.EndTime
|
||||
}
|
||||
|
||||
func (i *Interval) GetCost(duration, startSecond float64) (cost float64) {
|
||||
func (i *Interval) GetCost(duration, startSecond time.Duration) (cost float64) {
|
||||
price := i.GetPrice(startSecond)
|
||||
rateIncrements := i.GetRateIncrements(startSecond)
|
||||
rateIncrements := i.GetRateIncrements(startSecond).Seconds()
|
||||
d := float64(duration.Seconds())
|
||||
if i.PricedUnits != 0 {
|
||||
cost = math.Ceil(duration/rateIncrements) * rateIncrements * (price / i.PricedUnits)
|
||||
cost = math.Ceil(d/rateIncrements) * rateIncrements * (price / i.PricedUnits)
|
||||
} else {
|
||||
cost = math.Ceil(duration/rateIncrements) * rateIncrements * price
|
||||
cost = math.Ceil(d/rateIncrements) * rateIncrements * price
|
||||
}
|
||||
return utils.Round(cost, i.RoundingDecimals, i.RoundingMethod)
|
||||
}
|
||||
|
||||
// Gets the price for a the provided start second
|
||||
func (i *Interval) GetPrice(startSecond float64) float64 {
|
||||
func (i *Interval) GetPrice(startSecond time.Duration) float64 {
|
||||
i.Prices.Sort()
|
||||
for index, price := range i.Prices {
|
||||
if price.StartSecond <= startSecond && (index == len(i.Prices)-1 ||
|
||||
@@ -216,7 +217,7 @@ func (i *Interval) GetPrice(startSecond float64) float64 {
|
||||
return -1
|
||||
}
|
||||
|
||||
func (i *Interval) GetRateIncrements(startSecond float64) float64 {
|
||||
func (i *Interval) GetRateIncrements(startSecond time.Duration) time.Duration {
|
||||
i.Prices.Sort()
|
||||
for index, price := range i.Prices {
|
||||
if price.StartSecond <= startSecond && (index == len(i.Prices)-1 ||
|
||||
|
||||
@@ -45,11 +45,11 @@ WEEKENDS,*any,*any,*any,6;7,00:00:00
|
||||
ONE_TIME_RUN,2012,,,,*asap
|
||||
`
|
||||
rates = `
|
||||
R1,0,0.2,60,1,0,*middle,2,10
|
||||
R2,0,0.1,60,1,0,*middle,2,10
|
||||
R3,0,0.05,60,1,0,*middle,2,10
|
||||
R4,1,1,1,1,0,*up,2,10
|
||||
R5,0,0.5,1,1,0,*down,2,10
|
||||
R1,0,0.2,60,1s,0,*middle,2,10
|
||||
R2,0,0.1,60,1s,0,*middle,2,10
|
||||
R3,0,0.05,60,1s,0,*middle,2,10
|
||||
R4,1,1,1,1s,0,*up,2,10
|
||||
R5,0,0.5,1,1s,0,*down,2,10
|
||||
`
|
||||
destinationRates = `
|
||||
RT_STANDARD,GERMANY,R1
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TPLoader interface {
|
||||
@@ -46,11 +47,12 @@ type TPLoader interface {
|
||||
}
|
||||
|
||||
type Rate struct {
|
||||
Tag string
|
||||
ConnectFee, Price, PricedUnits, RateIncrements, GroupInterval float64
|
||||
RoundingMethod string
|
||||
RoundingDecimals int
|
||||
Weight float64
|
||||
Tag string
|
||||
ConnectFee, Price, PricedUnits float64
|
||||
RateIncrements, GroupInterval time.Duration
|
||||
RoundingMethod string
|
||||
RoundingDecimals int
|
||||
Weight float64
|
||||
}
|
||||
|
||||
func NewRate(tag, connectFee, price, pricedUnits, rateIncrements, groupInterval, roundingMethod, roundingDecimals, weight string) (r *Rate, err error) {
|
||||
@@ -64,7 +66,7 @@ func NewRate(tag, connectFee, price, pricedUnits, rateIncrements, groupInterval,
|
||||
log.Printf("Error parsing price from: %v", price)
|
||||
return
|
||||
}
|
||||
gi, err := strconv.ParseFloat(groupInterval, 64)
|
||||
gi, err := time.ParseDuration(groupInterval)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing group interval from: %v", price)
|
||||
return
|
||||
@@ -74,7 +76,7 @@ func NewRate(tag, connectFee, price, pricedUnits, rateIncrements, groupInterval,
|
||||
log.Printf("Error parsing priced units from: %v", pricedUnits)
|
||||
return
|
||||
}
|
||||
ri, err := strconv.ParseFloat(rateIncrements, 64)
|
||||
ri, err := time.ParseDuration(rateIncrements)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing rates increments from: %v", rateIncrements)
|
||||
return
|
||||
|
||||
@@ -462,9 +462,9 @@ 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) +
|
||||
result += p.StartSecond.String() +
|
||||
":" + strconv.FormatFloat(p.Value, 'f', -1, 64) +
|
||||
":" + strconv.FormatFloat(p.RateIncrements, 'f', -1, 64) +
|
||||
":" + p.RateIncrements.String() +
|
||||
","
|
||||
}
|
||||
result = strings.TrimRight(result, ",")
|
||||
@@ -478,7 +478,7 @@ func (pg *PriceGroups) Restore(input string) error {
|
||||
if len(priceElements) != 3 {
|
||||
continue
|
||||
}
|
||||
ss, err := strconv.ParseFloat(priceElements[0], 64)
|
||||
ss, err := time.ParseDuration(priceElements[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -486,7 +486,7 @@ func (pg *PriceGroups) Restore(input string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ri, err := strconv.ParseFloat(priceElements[2], 64)
|
||||
ri, err := time.ParseDuration(priceElements[2])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -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:0.2:1;60;1;\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:1s;60;1;\n"
|
||||
ap := &ActivationPeriod{}
|
||||
err := ap.Restore(s)
|
||||
if err != nil || len(ap.Intervals) != 1 {
|
||||
@@ -142,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:1;60;0;"
|
||||
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:1s;60;0;"
|
||||
i := Interval{}
|
||||
err := i.Restore(s)
|
||||
if err != nil || !i.Prices.Equal(PriceGroups{&Price{0, 0.2, 1}}) {
|
||||
if err != nil || !i.Prices.Equal(PriceGroups{&Price{0, 0.2, 1 * time.Second}}) {
|
||||
t.Errorf("Error restoring inteval period from string %+v", i)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SQLStorage struct {
|
||||
@@ -242,13 +243,14 @@ func (self *SQLStorage) GetTPRate(tpid, rtId string) (*utils.TPRate, error) {
|
||||
for rows.Next() {
|
||||
i++ //Keep here a reference so we know we got at least one prefix
|
||||
var connectFee, rate, weight float64
|
||||
var ratedUnits, rateIncrements, roundingDecimals, groupInterval int
|
||||
var ratedUnits, roundingDecimals int
|
||||
var rateIncrements, groupInterval time.Duration
|
||||
var roundingMethod string
|
||||
err = rows.Scan(&connectFee, &rate, &ratedUnits, &rateIncrements, &groupInterval, &roundingMethod, &roundingDecimals, &weight)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rt.RateSlots = append(rt.RateSlots, utils.RateSlot{connectFee, rate, ratedUnits, rateIncrements, groupInterval,
|
||||
rt.RateSlots = append(rt.RateSlots, utils.RateSlot{connectFee, rate, ratedUnits, rateIncrements * time.Second, groupInterval * time.Second,
|
||||
roundingMethod, roundingDecimals, weight})
|
||||
}
|
||||
if i == 0 {
|
||||
@@ -974,7 +976,8 @@ func (self *SQLStorage) GetTpRates(tpid, tag string) (map[string]*Rate, error) {
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var tag, roundingMethod string
|
||||
var connect_fee, rate, priced_units, rate_increments, group_interval, weight float64
|
||||
var connect_fee, rate, priced_units, weight float64
|
||||
var rate_increments, group_interval time.Duration
|
||||
var roundingDecimals int
|
||||
if err := rows.Scan(&tag, &connect_fee, &rate, &priced_units, &rate_increments, &group_interval, &roundingMethod, &roundingDecimals, &weight); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -20,7 +20,6 @@ package engine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -33,7 +32,7 @@ type TimeSpan struct {
|
||||
ActivationPeriod *ActivationPeriod
|
||||
Interval *Interval
|
||||
MinuteInfo *MinuteInfo
|
||||
CallDuration float64 // the call duration so far till TimeEnd
|
||||
CallDuration time.Duration // the call duration so far till TimeEnd
|
||||
}
|
||||
|
||||
// Holds the bonus minute information related to a specified timespan
|
||||
@@ -60,9 +59,8 @@ func (ts *TimeSpan) getCost(cd *CallDescriptor) (cost float64) {
|
||||
if ts.Interval == nil {
|
||||
return 0
|
||||
}
|
||||
duration := ts.GetDuration().Seconds()
|
||||
i := ts.Interval
|
||||
cost = i.GetCost(duration, ts.GetGroupStart())
|
||||
cost = i.GetCost(ts.GetDuration(), ts.GetGroupStart())
|
||||
// if userBalance, err := cd.getUserBalance(); err == nil && userBalance != nil {
|
||||
// userBalance.mux.RLock()
|
||||
// if percentageDiscount, err := userBalance.getVolumeDiscount(cd.Destination, INBOUND); err == nil && percentageDiscount > 0 {
|
||||
@@ -113,7 +111,7 @@ func (ts *TimeSpan) SplitByInterval(i *Interval) (nts *TimeSpan) {
|
||||
for _, price := range i.Prices {
|
||||
if ts.GetGroupStart() < price.StartSecond && ts.GetGroupEnd() >= price.StartSecond {
|
||||
ts.SetInterval(i)
|
||||
splitTime := ts.TimeStart.Add(time.Duration(price.StartSecond-ts.GetGroupStart()) * time.Second)
|
||||
splitTime := ts.TimeStart.Add(price.StartSecond - ts.GetGroupStart())
|
||||
nts = &TimeSpan{TimeStart: splitTime, TimeEnd: ts.TimeEnd}
|
||||
ts.TimeEnd = splitTime
|
||||
nts.SetInterval(i)
|
||||
@@ -215,14 +213,22 @@ func (ts *TimeSpan) SplitByMinuteBucket(mb *MinuteBucket) (newTs *TimeSpan) {
|
||||
return
|
||||
}
|
||||
|
||||
func (ts *TimeSpan) GetGroupStart() float64 {
|
||||
return math.Max(0, ts.CallDuration-ts.GetDuration().Seconds())
|
||||
func (ts *TimeSpan) GetGroupStart() time.Duration {
|
||||
s := ts.CallDuration - ts.GetDuration()
|
||||
if s < 0 {
|
||||
s = 0
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (ts *TimeSpan) GetGroupEnd() float64 {
|
||||
func (ts *TimeSpan) GetGroupEnd() time.Duration {
|
||||
return ts.CallDuration
|
||||
}
|
||||
|
||||
func (ts *TimeSpan) SetNewCallDuration(nts *TimeSpan) {
|
||||
ts.CallDuration = math.Max(0, ts.CallDuration-nts.GetDuration().Seconds())
|
||||
d := ts.CallDuration - nts.GetDuration()
|
||||
if d < 0 {
|
||||
d = 0
|
||||
}
|
||||
ts.CallDuration = d
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ 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, 1}}}
|
||||
ts1.Interval = &Interval{Prices: PriceGroups{&Price{0, 1.0, 1 * time.Second}}}
|
||||
if ts1.getCost(cd) != 600 {
|
||||
t.Error("Expected 10 got ", ts1.getCost(cd))
|
||||
}
|
||||
@@ -203,9 +203,9 @@ func TestTimespanGetCost(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSetInterval(t *testing.T) {
|
||||
i1 := &Interval{Prices: PriceGroups{&Price{0, 1.0, 1}}}
|
||||
i1 := &Interval{Prices: PriceGroups{&Price{0, 1.0, 1 * time.Second}}}
|
||||
ts1 := TimeSpan{Interval: i1}
|
||||
i2 := &Interval{Prices: PriceGroups{&Price{0, 2.0, 1}}}
|
||||
i2 := &Interval{Prices: PriceGroups{&Price{0, 2.0, 1 * time.Second}}}
|
||||
ts1.SetInterval(i2)
|
||||
if ts1.Interval != i1 {
|
||||
t.Error("Smaller price interval should win")
|
||||
@@ -332,16 +332,16 @@ func TestTimespanSplitByMinuteBucketScarceExpiringDifferentScarceFirst(t *testin
|
||||
func TestTimespanSplitGroupedRates(t *testing.T) {
|
||||
i := &Interval{
|
||||
EndTime: "17:59:00",
|
||||
Prices: PriceGroups{&Price{0, 2, 1}, &Price{900, 1, 1}},
|
||||
Prices: PriceGroups{&Price{0, 2, 1 * time.Second}, &Price{900 * time.Second, 1, 1 * time.Second}},
|
||||
}
|
||||
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)
|
||||
ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, CallDuration: 1800}
|
||||
ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, CallDuration: 1800 * time.Second}
|
||||
oldDuration := ts.GetDuration()
|
||||
nts := ts.SplitByInterval(i)
|
||||
splitTime := time.Date(2012, time.February, 3, 17, 45, 00, 0, time.UTC)
|
||||
if ts.TimeStart != t1 || ts.TimeEnd != splitTime {
|
||||
t.Error("Incorrect first half", ts)
|
||||
t.Error("Incorrect first half", ts.TimeStart, ts.TimeEnd)
|
||||
}
|
||||
if nts.TimeStart != splitTime || nts.TimeEnd != t2 {
|
||||
t.Error("Incorrect second half", nts)
|
||||
@@ -349,8 +349,8 @@ func TestTimespanSplitGroupedRates(t *testing.T) {
|
||||
if ts.Interval != i {
|
||||
t.Error("Interval not attached correctly")
|
||||
}
|
||||
c1 := ts.Interval.GetCost(ts.GetDuration().Seconds(), ts.GetGroupStart())
|
||||
c2 := nts.Interval.GetCost(nts.GetDuration().Seconds(), nts.GetGroupStart())
|
||||
c1 := ts.Interval.GetCost(ts.GetDuration(), ts.GetGroupStart())
|
||||
c2 := nts.Interval.GetCost(nts.GetDuration(), nts.GetGroupStart())
|
||||
if c1 != 1800 || c2 != 900 {
|
||||
t.Error("Wrong costs: ", c1, c2)
|
||||
}
|
||||
@@ -366,11 +366,11 @@ func TestTimespanSplitGroupedRates(t *testing.T) {
|
||||
func TestTimespanSplitGroupedRatesIncrements(t *testing.T) {
|
||||
i := &Interval{
|
||||
EndTime: "17:59:00",
|
||||
Prices: PriceGroups{&Price{0, 2, 1}, &Price{30, 1, 60}},
|
||||
Prices: PriceGroups{&Price{0, 2, 1 * time.Second}, &Price{30 * time.Second, 1, 60 * time.Second}},
|
||||
}
|
||||
t1 := time.Date(2012, time.February, 3, 17, 30, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 3, 17, 31, 0, 0, time.UTC)
|
||||
ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, CallDuration: 60}
|
||||
ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, CallDuration: 60 * time.Second}
|
||||
oldDuration := ts.GetDuration()
|
||||
nts := ts.SplitByInterval(i)
|
||||
splitTime := time.Date(2012, time.February, 3, 17, 30, 30, 0, time.UTC)
|
||||
@@ -383,8 +383,8 @@ func TestTimespanSplitGroupedRatesIncrements(t *testing.T) {
|
||||
if ts.Interval != i {
|
||||
t.Error("Interval not attached correctly")
|
||||
}
|
||||
c1 := ts.Interval.GetCost(ts.GetDuration().Seconds(), ts.GetGroupStart())
|
||||
c2 := nts.Interval.GetCost(nts.GetDuration().Seconds(), nts.GetGroupStart())
|
||||
c1 := ts.Interval.GetCost(ts.GetDuration(), ts.GetGroupStart())
|
||||
c2 := nts.Interval.GetCost(nts.GetDuration(), nts.GetGroupStart())
|
||||
if c1 != 60 || c2 != 60 {
|
||||
t.Error("Wrong costs: ", c1, c2)
|
||||
}
|
||||
@@ -400,7 +400,7 @@ func TestTimespanSplitGroupedRatesIncrements(t *testing.T) {
|
||||
func TestTimespanSplitRightHourMarginBeforeGroup(t *testing.T) {
|
||||
i := &Interval{
|
||||
EndTime: "17:00:30",
|
||||
Prices: PriceGroups{&Price{0, 2, 1}, &Price{60, 1, 60}},
|
||||
Prices: PriceGroups{&Price{0, 2, 1 * time.Second}, &Price{60 * time.Second, 1, 60 * time.Second}},
|
||||
}
|
||||
t1 := time.Date(2012, time.February, 3, 17, 00, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 3, 17, 01, 0, 0, time.UTC)
|
||||
@@ -433,11 +433,11 @@ func TestTimespanSplitRightHourMarginBeforeGroup(t *testing.T) {
|
||||
func TestTimespanSplitGroupSecondSplit(t *testing.T) {
|
||||
i := &Interval{
|
||||
EndTime: "17:03:30",
|
||||
Prices: PriceGroups{&Price{0, 2, 1}, &Price{60, 1, 1}},
|
||||
Prices: PriceGroups{&Price{0, 2, 1 * time.Second}, &Price{60 * time.Second, 1, 1 * time.Second}},
|
||||
}
|
||||
t1 := time.Date(2012, time.February, 3, 17, 00, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 3, 17, 04, 0, 0, time.UTC)
|
||||
ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, CallDuration: 240}
|
||||
ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, CallDuration: 240 * time.Second}
|
||||
oldDuration := ts.GetDuration()
|
||||
nts := ts.SplitByInterval(i)
|
||||
splitTime := time.Date(2012, time.February, 3, 17, 01, 00, 0, time.UTC)
|
||||
@@ -477,11 +477,11 @@ func TestTimespanSplitGroupSecondSplit(t *testing.T) {
|
||||
func TestTimespanSplitMultipleGroup(t *testing.T) {
|
||||
i := &Interval{
|
||||
EndTime: "17:05:00",
|
||||
Prices: PriceGroups{&Price{0, 2, 1}, &Price{60, 1, 1}, &Price{180, 1, 1}},
|
||||
Prices: PriceGroups{&Price{0, 2, 1 * time.Second}, &Price{60 * time.Second, 1, 1 * time.Second}, &Price{180 * time.Second, 1, 1 * time.Second}},
|
||||
}
|
||||
t1 := time.Date(2012, time.February, 3, 17, 00, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 3, 17, 04, 0, 0, time.UTC)
|
||||
ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, CallDuration: 240}
|
||||
ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, CallDuration: 240 * time.Second}
|
||||
oldDuration := ts.GetDuration()
|
||||
nts := ts.SplitByInterval(i)
|
||||
splitTime := time.Date(2012, time.February, 3, 17, 01, 00, 0, time.UTC)
|
||||
|
||||
@@ -18,6 +18,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// This file deals with tp_* data definition
|
||||
|
||||
type TPRate struct {
|
||||
@@ -27,14 +31,14 @@ type TPRate struct {
|
||||
}
|
||||
|
||||
type RateSlot struct {
|
||||
ConnectFee float64 // ConnectFee applied once the call is answered
|
||||
Rate float64 // Rate applied
|
||||
RatedUnits int // Number of billing units this rate applies to
|
||||
RateIncrements int // This rate will apply in increments of duration
|
||||
GroupInterval int // Group position
|
||||
RoundingMethod string // Use this method to round the cost
|
||||
RoundingDecimals int // Round the cost number of decimals
|
||||
Weight float64 // Rate's priority when dealing with grouped rates
|
||||
ConnectFee float64 // ConnectFee applied once the call is answered
|
||||
Rate float64 // Rate applied
|
||||
RatedUnits int // Number of billing units this rate applies to
|
||||
RateIncrements time.Duration // This rate will apply in increments of duration
|
||||
GroupInterval time.Duration // Group position
|
||||
RoundingMethod string // Use this method to round the cost
|
||||
RoundingDecimals int // Round the cost number of decimals
|
||||
Weight float64 // Rate's priority when dealing with grouped rates
|
||||
}
|
||||
|
||||
type TPDestinationRate struct {
|
||||
|
||||
Reference in New Issue
Block a user