mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Merge branch 'master' of https://github.com/cgrates/cgrates
This commit is contained in:
@@ -1,23 +1,23 @@
|
||||
cgrates (0.9.1-rc6) UNRELEASED; urgency=low
|
||||
cgrates (0.9.1~rc6) UNRELEASED; urgency=low
|
||||
|
||||
* RC6.
|
||||
|
||||
-- DanB <danb@cgrates.org> Wednesday, 10 September 2014 13:30:00 +0100
|
||||
|
||||
cgrates (0.9.1-rc5) UNRELEASED; urgency=low
|
||||
cgrates (0.9.1~rc5) UNRELEASED; urgency=low
|
||||
|
||||
* RC5.
|
||||
|
||||
-- DanB <danb@cgrates.org> Monday, 18 August 2014 13:30:00 +0100
|
||||
|
||||
|
||||
cgrates (0.9.1-rc4) UNRELEASED; urgency=low
|
||||
cgrates (0.9.1~rc4) UNRELEASED; urgency=low
|
||||
|
||||
* RC4.
|
||||
|
||||
-- DanB <danb@cgrates.org> Thursday, 25 March 2014 17:30:00 +0100
|
||||
|
||||
cgrates (0.9.1-rc3) UNRELEASED; urgency=low
|
||||
cgrates (0.9.1~rc3) UNRELEASED; urgency=low
|
||||
|
||||
* RC3.
|
||||
|
||||
|
||||
@@ -44,9 +44,7 @@ CREATE TABLE `tp_rates` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`tpid` varchar(64) NOT NULL,
|
||||
`tag` varchar(64) NOT NULL,
|
||||
`connect_fee` decimal(7,4) NOT NULL,
|
||||
`max_cost` decimal(7,4) NOT NULL,
|
||||
`max_cost_strategy` varchar(16) NOT NULL,
|
||||
`connect_fee` decimal(7,4) NOT NULL,
|
||||
`rate` decimal(7,4) NOT NULL,
|
||||
`rate_unit` varchar(16) NOT NULL,
|
||||
`rate_increment` varchar(16) NOT NULL,
|
||||
@@ -71,7 +69,9 @@ CREATE TABLE `tp_destination_rates` (
|
||||
`rates_tag` varchar(64) NOT NULL,
|
||||
`rounding_method` varchar(255) NOT NULL,
|
||||
`rounding_decimals` tinyint(4) NOT NULL,
|
||||
`created_at` TIMESTAMP,
|
||||
`max_cost` decimal(7,4) NOT NULL,
|
||||
`max_cost_strategy` varchar(16) NOT NULL,
|
||||
`created_at` TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `tpid` (`tpid`),
|
||||
KEY `tpid_drid` (`tpid`,`tag`),
|
||||
|
||||
@@ -40,9 +40,7 @@ CREATE TABLE tp_rates (
|
||||
id SERIAL PRIMARY KEY,
|
||||
tpid VARCHAR(64) NOT NULL,
|
||||
tag VARCHAR(64) NOT NULL,
|
||||
connect_fee NUMERIC(7,4) NOT NULL,
|
||||
max_cost NUMERIC(7,4) NOT NULL,
|
||||
max_cost_strategy VARCHAR(16) NOT NULL,
|
||||
connect_fee NUMERIC(7,4) NOT NULL,
|
||||
rate NUMERIC(7,4) NOT NULL,
|
||||
rate_unit VARCHAR(16) NOT NULL,
|
||||
rate_increment VARCHAR(16) NOT NULL,
|
||||
@@ -65,6 +63,8 @@ CREATE TABLE tp_destination_rates (
|
||||
rates_tag VARCHAR(64) NOT NULL,
|
||||
rounding_method VARCHAR(255) NOT NULL,
|
||||
rounding_decimals SMALLINT NOT NULL,
|
||||
max_cost NUMERIC(7,4) NOT NULL,
|
||||
max_cost_strategy VARCHAR(16) NOT NULL,
|
||||
created_at TIMESTAMP,
|
||||
UNIQUE (tpid, tag , destinations_tag)
|
||||
);
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
#Tag,DestinationsTag,RatesTag,RoundingMethod,RoundingDecimals
|
||||
DR_RETAIL,GERMANY,RT_1CENT,*up,4
|
||||
#Tag,DestinationsTag,RatesTag,RoundingMethod,RoundingDecimals,MaxCost,MaxCostStrategy
|
||||
DR_RETAIL,GERMANY,RT_1CENT,*up,4,0,
|
||||
|
||||
|
@@ -1,2 +1,2 @@
|
||||
#Tag,ConnectFee,Rate,RateUnit,RateIncrement,GroupIntervalStart
|
||||
RT_1CENT,0,0,,1,1s,1s,0s
|
||||
RT_1CENT,0,1,1s,1s,0s
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#Tag,DestinationsTag,RatesTag,RoundingMethod,RoundingDecimals
|
||||
DR_RETAIL,GERMANY,RT_1CENT,*up,4
|
||||
DR_RETAIL,GERMANY_MOBILE,RT_1CENT,*up,4
|
||||
DR_DATA_1,*any,RT_DATA_2c,*up,4
|
||||
DR_SMS_1,*any,RT_SMS_5c,*up,4
|
||||
#Tag,DestinationsTag,RatesTag,RoundingMethod,RoundingDecimals,MaxCost,MaxCostStrategy
|
||||
DR_RETAIL,GERMANY,RT_1CENT,*up,4,0,
|
||||
DR_RETAIL,GERMANY_MOBILE,RT_1CENT,*up,4,0,
|
||||
DR_DATA_1,*any,RT_DATA_2c,*up,4,0,
|
||||
DR_SMS_1,*any,RT_SMS_5c,*up,4,0,
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
#Tag,ConnectFee,Rate,RateUnit,RateIncrement,GroupIntervalStart
|
||||
RT_1CENT,0,0,,1,1s,1s,0s
|
||||
RT_DATA_2c,0,0,,0.002,10,10,0
|
||||
RT_SMS_5c,0,0,,0.005,1,1,0
|
||||
RT_1CENT,0,1,1s,1s,0s
|
||||
RT_DATA_2c,0,0.002,10,10,0
|
||||
RT_SMS_5c,0,0.005,1,1,0
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
#Tag,DestinationsTag,RatesTag,RoundingMethod,RoundingDecimals
|
||||
DR_1002_20CNT,DST_1002,RT_20CNT,*up,4
|
||||
DR_1002_10CNT,DST_1002,RT_10CNT,*up,4
|
||||
DR_1003_20CNT,DST_1003,RT_40CNT,*up,4
|
||||
DR_1003_10CNT,DST_1003,RT_10CNT,*up,4
|
||||
DR_FS_40CNT,DST_FS,RT_40CNT,*up,4
|
||||
DR_FS_10CNT,DST_FS,RT_10CNT,*up,4
|
||||
DR_SPECIAL_1002,DST_1002,RT_1CNT,*up,4
|
||||
#Tag,DestinationsTag,RatesTag,RoundingMethod,RoundingDecimals,MaxCost,MaxCostStrategy
|
||||
DR_1002_20CNT,DST_1002,RT_20CNT,*up,4,0,
|
||||
DR_1002_10CNT,DST_1002,RT_10CNT,*up,4,0,
|
||||
DR_1003_20CNT,DST_1003,RT_40CNT,*up,4,0,
|
||||
DR_1003_10CNT,DST_1003,RT_10CNT,*up,4,0,
|
||||
DR_FS_40CNT,DST_FS,RT_40CNT,*up,4,0,
|
||||
DR_FS_10CNT,DST_FS,RT_10CNT,*up,4,0,
|
||||
DR_SPECIAL_1002,DST_1002,RT_1CNT,*up,4,0,
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
#Tag,ConnectFee,Rate,RateUnit,RateIncrement,GroupIntervalStart
|
||||
RT_10CNT,0.2,0,,0.1,60s,60s,0s
|
||||
RT_10CNT,0,0,,0.05,60s,1s,60s
|
||||
RT_20CNT,0,0,.4,0.2,60s,60s,0s
|
||||
RT_20CNT,0,0,,0.1,60s,1s,60s
|
||||
RT_40CNT,0,0,.8,0.4,60s,30s,0s
|
||||
RT_40CNT,0,0,,0.2,60s,10s,60s
|
||||
RT_1CNT,0,0,,0.01,60s,60s,0s
|
||||
RT_10CNT,0.2,0.1,60s,60s,0s
|
||||
RT_10CNT,0,0.05,60s,1s,60s
|
||||
RT_20CNT,0,.4,0.2,60s,60s,0s
|
||||
RT_20CNT,0,0.1,60s,1s,60s
|
||||
RT_40CNT,0,.8,0.4,60s,30s,0s
|
||||
RT_40CNT,0,0.2,60s,10s,60s
|
||||
RT_1CNT,0,0.01,60s,60s,0s
|
||||
|
||||
|
@@ -256,7 +256,7 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo
|
||||
unitBalanceChecker = true
|
||||
generalBalanceChecker = true
|
||||
// check for max cost disconnect
|
||||
if dryRun && cc.maxCostDisconect {
|
||||
if dryRun && partCC.maxCostDisconect {
|
||||
// only return if we are in dry run (max call duration)
|
||||
return
|
||||
}
|
||||
@@ -294,7 +294,7 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo
|
||||
}
|
||||
moneyBalanceChecker = true
|
||||
generalBalanceChecker = true
|
||||
if dryRun && cc.maxCostDisconect {
|
||||
if dryRun && partCC.maxCostDisconect {
|
||||
// only return if we are in dry run (max call duration)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -325,20 +325,26 @@ func (b *Balance) DebitUnits(cd *CallDescriptor, ub *Account, moneyBalances Bala
|
||||
}
|
||||
//log.Printf("TS: %+v", ts)
|
||||
maxCost, strategy := ts.RateInterval.GetMaxCost()
|
||||
if strategy == utils.MAX_COST_DISCONNECT && cd.MaxCostSoFar >= maxCost {
|
||||
// cat the entire current timespan
|
||||
cc.maxCostDisconect = true
|
||||
if dryRun {
|
||||
cc.Timespans = cc.Timespans[:tsIndex]
|
||||
return cc, nil
|
||||
}
|
||||
}
|
||||
for incIndex, inc := range ts.Increments {
|
||||
// debit minutes and money
|
||||
seconds := inc.Duration.Seconds()
|
||||
cost := inc.Cost
|
||||
//log.Printf("INC: %+v", inc)
|
||||
inc.paid = false
|
||||
if strategy == utils.MAX_COST_DISCONNECT && cd.MaxCostSoFar >= maxCost {
|
||||
// cat the entire current timespan
|
||||
cc.maxCostDisconect = true
|
||||
if dryRun {
|
||||
if incIndex == 0 {
|
||||
// cat the entire current timespan
|
||||
cc.Timespans = cc.Timespans[:tsIndex]
|
||||
} else {
|
||||
ts.SplitByIncrement(incIndex)
|
||||
cc.Timespans = cc.Timespans[:tsIndex+1]
|
||||
}
|
||||
return cc, nil
|
||||
}
|
||||
}
|
||||
if strategy == utils.MAX_COST_FREE && cd.MaxCostSoFar >= maxCost {
|
||||
cost, inc.Cost = 0.0, 0.0
|
||||
inc.BalanceInfo.MoneyBalanceUuid = b.Uuid
|
||||
@@ -415,19 +421,27 @@ func (b *Balance) DebitMoney(cd *CallDescriptor, ub *Account, count bool, dryRun
|
||||
}
|
||||
//log.Printf("TS: %+v", ts)
|
||||
maxCost, strategy := ts.RateInterval.GetMaxCost()
|
||||
if strategy == utils.MAX_COST_DISCONNECT && cd.MaxCostSoFar >= maxCost {
|
||||
// cat the entire current timespan
|
||||
cc.maxCostDisconect = true
|
||||
if dryRun {
|
||||
cc.Timespans = cc.Timespans[:tsIndex]
|
||||
return cc, nil
|
||||
}
|
||||
}
|
||||
//log.Printf("Timing: %+v", ts.RateInterval.Timing)
|
||||
//log.Printf("Rate: %+v", ts.RateInterval.Rating)
|
||||
for incIndex, inc := range ts.Increments {
|
||||
// check standard subject tags
|
||||
//log.Printf("INC: %+v", inc)
|
||||
amount := inc.Cost
|
||||
inc.paid = false
|
||||
if strategy == utils.MAX_COST_DISCONNECT && cd.MaxCostSoFar >= maxCost {
|
||||
// cat the entire current timespan
|
||||
cc.maxCostDisconect = true
|
||||
if dryRun {
|
||||
if incIndex == 0 {
|
||||
// cat the entire current timespan
|
||||
cc.Timespans = cc.Timespans[:tsIndex]
|
||||
} else {
|
||||
ts.SplitByIncrement(incIndex)
|
||||
cc.Timespans = cc.Timespans[:tsIndex+1]
|
||||
}
|
||||
return cc, nil
|
||||
}
|
||||
}
|
||||
if strategy == utils.MAX_COST_FREE && cd.MaxCostSoFar >= maxCost {
|
||||
amount, inc.Cost = 0.0, 0.0
|
||||
inc.BalanceInfo.MoneyBalanceUuid = b.Uuid
|
||||
|
||||
@@ -360,10 +360,10 @@ func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) {
|
||||
}
|
||||
|
||||
//Logger.Debug(fmt.Sprintf("After SplitByRateInterval: %+v", timespans))
|
||||
//log.Printf("After SplitByRateInterval: %+v", timespans)
|
||||
//log.Printf("After SplitByRateInterval: %+v", timespans[0].RateInterval.Timing)
|
||||
timespans = cd.roundTimeSpansToIncrement(timespans)
|
||||
// Logger.Debug(fmt.Sprintf("After round: %+v", timespans))
|
||||
//log.Printf("After round: %+v", timespans)
|
||||
//log.Printf("After round: %+v", timespans[0].RateInterval.Timing)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -417,6 +417,7 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) {
|
||||
|
||||
for i, ts := range timespans {
|
||||
// only add connect fee if this is the first/only call cost request
|
||||
//log.Printf("Interval: %+v", ts.RateInterval.Timing)
|
||||
if cd.LoopIndex == 0 && i == 0 && ts.RateInterval != nil {
|
||||
cost += ts.RateInterval.Rating.ConnectFee
|
||||
}
|
||||
|
||||
@@ -83,6 +83,13 @@ func populateDB() {
|
||||
},
|
||||
},
|
||||
}
|
||||
max := &Account{
|
||||
Id: "*out:cgrates.org:max",
|
||||
BalanceMap: map[string]BalanceChain{
|
||||
CREDIT + OUTBOUND: BalanceChain{
|
||||
&Balance{Value: 11, Weight: 20},
|
||||
}},
|
||||
}
|
||||
if accountingStorage != nil {
|
||||
accountingStorage.SetActions("TEST_ACTIONS", ats)
|
||||
accountingStorage.SetActions("TEST_ACTIONS_ORDER", ats1)
|
||||
@@ -90,6 +97,7 @@ func populateDB() {
|
||||
accountingStorage.SetAccount(minu)
|
||||
accountingStorage.SetAccount(minitsboy)
|
||||
accountingStorage.SetAccount(luna)
|
||||
accountingStorage.SetAccount(max)
|
||||
} else {
|
||||
log.Fatal("Could not connect to db!")
|
||||
}
|
||||
@@ -355,8 +363,6 @@ func TestMaxSessionTimeWithMaxRate(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
func TestMaxSessionTimeWithMaxCost(t *testing.T) {
|
||||
ap, _ := accountingStorage.GetActionTimings("TOPUP10_AT")
|
||||
for _, at := range ap {
|
||||
@@ -366,20 +372,42 @@ func TestMaxSessionTimeWithMaxCost(t *testing.T) {
|
||||
Direction: "*out",
|
||||
Category: "call",
|
||||
Tenant: "cgrates.org",
|
||||
Subject: "12345",
|
||||
Account: "12345",
|
||||
Destination: "447956",
|
||||
TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2014, 3, 4, 6, 1, 0, 0, time.UTC),
|
||||
Subject: "max",
|
||||
Account: "max",
|
||||
Destination: "0723123113",
|
||||
TimeStart: time.Date(2015, 3, 23, 6, 0, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2015, 3, 23, 6, 30, 0, 0, time.UTC),
|
||||
MaxCostSoFar: 0,
|
||||
}
|
||||
result, err := cd.GetMaxSessionDuration()
|
||||
expected := 45 * time.Second
|
||||
expected := 10 * time.Second
|
||||
if result != expected || err != nil {
|
||||
t.Errorf("Expected %v was %v", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMaxSessionTimeWithMaxCostFree(t *testing.T) {
|
||||
ap, _ := accountingStorage.GetActionTimings("TOPUP10_AT")
|
||||
for _, at := range ap {
|
||||
at.Execute()
|
||||
}
|
||||
cd := &CallDescriptor{
|
||||
Direction: "*out",
|
||||
Category: "call",
|
||||
Tenant: "cgrates.org",
|
||||
Subject: "max",
|
||||
Account: "max",
|
||||
Destination: "0723123113",
|
||||
TimeStart: time.Date(2015, 3, 23, 19, 0, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2015, 3, 23, 19, 30, 0, 0, time.UTC),
|
||||
MaxCostSoFar: 0,
|
||||
}
|
||||
result, err := cd.GetMaxSessionDuration()
|
||||
expected := 30 * time.Minute
|
||||
if result != expected || err != nil {
|
||||
t.Errorf("Expected %v was %v", expected, result)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func TestMaxSessionTimeWithAccountAlias(t *testing.T) {
|
||||
cd := &CallDescriptor{
|
||||
|
||||
@@ -398,7 +398,7 @@ func (csvr *CSVReader) LoadRates() (err error) {
|
||||
for record, err := csvReader.Read(); err == nil; record, err = csvReader.Read() {
|
||||
tag := record[0]
|
||||
var r *utils.TPRate
|
||||
r, err = NewLoadRate(record[0], record[1], record[2], record[3], record[4], record[5], record[6], record[7])
|
||||
r, err = NewLoadRate(record[0], record[1], record[2], record[3], record[4], record[5])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -438,6 +438,11 @@ func (csvr *CSVReader) LoadDestinationRates() (err error) {
|
||||
log.Printf("Error parsing rounding decimals: %s", record[4])
|
||||
return err
|
||||
}
|
||||
maxCost, err := strconv.ParseFloat(record[5], 64)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing max cost from: %v", record[5])
|
||||
return err
|
||||
}
|
||||
destinationExists := record[1] == utils.ANY
|
||||
if !destinationExists {
|
||||
_, destinationExists = csvr.destinations[record[1]]
|
||||
@@ -458,6 +463,8 @@ func (csvr *CSVReader) LoadDestinationRates() (err error) {
|
||||
Rate: r,
|
||||
RoundingMethod: record[3],
|
||||
RoundingDecimals: roundingDecimals,
|
||||
MaxCost: maxCost,
|
||||
MaxCostStrategy: record[6],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -55,37 +55,40 @@ ALWAYS,*any,*any,*any,*any,00:00:00
|
||||
ASAP,*any,*any,*any,*any,*asap
|
||||
`
|
||||
rates = `
|
||||
R1,0,0,,0.2,60,1,0
|
||||
R2,0,0,,0.1,60s,1s,0
|
||||
R3,0,0,,0.05,60s,1s,0
|
||||
R4,1,0,,1,1s,1s,0
|
||||
R5,0,0,,0.5,1s,1s,0
|
||||
LANDLINE_OFFPEAK,0,0,,1,1,60,0
|
||||
LANDLINE_OFFPEAK,0,0,,1,1,1,60
|
||||
GBP_71,0.000000,0,,5.55555,1s,1s,0s
|
||||
GBP_72,0.000000,0,,7.77777,1s,1s,0s
|
||||
GBP_70,0.000000,0,,1,1,1,0
|
||||
RT_UK_Mobile_BIG5_PKG,0.01,0,,0,20s,20s,0s
|
||||
RT_UK_Mobile_BIG5,0.01,0,,0.10,1s,1s,0s
|
||||
R_URG,0,0,,0,1,1,0
|
||||
R1,0,0.2,60,1,0
|
||||
R2,0,0.1,60s,1s,0
|
||||
R3,0,0.05,60s,1s,0
|
||||
R4,1,1,1s,1s,0
|
||||
R5,0,0.5,1s,1s,0
|
||||
LANDLINE_OFFPEAK,0,1,1,60,0
|
||||
LANDLINE_OFFPEAK,0,1,1,1,60
|
||||
GBP_71,0.000000,5.55555,1s,1s,0s
|
||||
GBP_72,0.000000,7.77777,1s,1s,0s
|
||||
GBP_70,0.000000,1,1,1,0
|
||||
RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s
|
||||
RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s
|
||||
R_URG,0,0,1,1,0
|
||||
MX,0,1,1s,1s,0
|
||||
`
|
||||
destinationRates = `
|
||||
RT_STANDARD,GERMANY,R1,*middle,4
|
||||
RT_STANDARD,GERMANY_O2,R2,*middle,4
|
||||
RT_STANDARD,GERMANY_PREMIUM,R2,*middle,4
|
||||
RT_DEFAULT,ALL,R2,*middle,4
|
||||
RT_STD_WEEKEND,GERMANY,R2,*middle,4
|
||||
RT_STD_WEEKEND,GERMANY_O2,R3,*middle,4
|
||||
P1,NAT,R4,*middle,4
|
||||
P2,NAT,R5,*middle,4
|
||||
T1,NAT,LANDLINE_OFFPEAK,*middle,4
|
||||
T2,GERMANY,GBP_72,*middle,4
|
||||
T2,GERMANY_O2,GBP_70,*middle,4
|
||||
T2,GERMANY_PREMIUM,GBP_71,*middle,4
|
||||
DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG,*middle,4
|
||||
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5,*middle,4
|
||||
DATA_RATE,*any,LANDLINE_OFFPEAK,*middle,4
|
||||
RT_URG,URG,R_URG,*middle,4
|
||||
RT_STANDARD,GERMANY,R1,*middle,4,0,
|
||||
RT_STANDARD,GERMANY_O2,R2,*middle,4,0,
|
||||
RT_STANDARD,GERMANY_PREMIUM,R2,*middle,4,0,
|
||||
RT_DEFAULT,ALL,R2,*middle,4,0,
|
||||
RT_STD_WEEKEND,GERMANY,R2,*middle,4,0,
|
||||
RT_STD_WEEKEND,GERMANY_O2,R3,*middle,4,0,
|
||||
P1,NAT,R4,*middle,4,0,
|
||||
P2,NAT,R5,*middle,4,0,
|
||||
T1,NAT,LANDLINE_OFFPEAK,*middle,4,0,
|
||||
T2,GERMANY,GBP_72,*middle,4,0,
|
||||
T2,GERMANY_O2,GBP_70,*middle,4,0,
|
||||
T2,GERMANY_PREMIUM,GBP_71,*middle,4,0,
|
||||
DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG,*middle,4,0,
|
||||
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5,*middle,4,0,
|
||||
DATA_RATE,*any,LANDLINE_OFFPEAK,*middle,4,0,
|
||||
RT_URG,URG,R_URG,*middle,4,0,
|
||||
MX_FREE,RET,MX,*middle,4,10,*free
|
||||
MX_DISC,RET,MX,*middle,4,10,*disconnect
|
||||
`
|
||||
ratingPlans = `
|
||||
STANDARD,RT_STANDARD,WORKDAYS_00,10
|
||||
@@ -106,6 +109,8 @@ 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
|
||||
RP_MX,MX_DISC,WORKDAYS_00,10
|
||||
RP_MX,MX_FREE,WORKDAYS_18,10
|
||||
`
|
||||
ratingProfiles = `
|
||||
*out,CUSTOMER_1,0,rif:from:tm,2012-01-01T00:00:00Z,PREMIUM,danb
|
||||
@@ -127,6 +132,7 @@ RP_DATA,DATA_RATE,ALWAYS,10
|
||||
*out,cgrates.org,call,*any,2013-01-06T00:00:00Z,RP_UK,
|
||||
*out,cgrates.org,call,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,
|
||||
*out,cgrates.org,data,rif,2013-01-06T00:00:00Z,RP_DATA,
|
||||
*out,cgrates.org,call,max,2013-03-23T00:00:00Z,RP_MX,
|
||||
`
|
||||
sharedGroups = `
|
||||
SG1,*any,*lowest,
|
||||
@@ -319,11 +325,11 @@ func TestLoadTimimgs(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLoadRates(t *testing.T) {
|
||||
if len(csvr.rates) != 12 {
|
||||
t.Error("Failed to load rates: ", csvr.rates)
|
||||
if len(csvr.rates) != 13 {
|
||||
t.Error("Failed to load rates: ", len(csvr.rates))
|
||||
}
|
||||
rate := csvr.rates["R1"].RateSlots[0]
|
||||
expctRs, err := utils.NewRateSlot(0, 0, "", 0.2, "60", "1", "0")
|
||||
expctRs, err := utils.NewRateSlot(0, 0.2, "60", "1", "0")
|
||||
if err != nil {
|
||||
t.Error("Error loading rate: ", rate, err.Error())
|
||||
} else if !reflect.DeepEqual(rate, expctRs) ||
|
||||
@@ -333,7 +339,7 @@ func TestLoadRates(t *testing.T) {
|
||||
t.Error("Error loading rate: ", rate, expctRs)
|
||||
}
|
||||
rate = csvr.rates["R2"].RateSlots[0]
|
||||
if expctRs, err = utils.NewRateSlot(0, 0, "", 0.1, "60s", "1s", "0"); err != nil {
|
||||
if expctRs, err = utils.NewRateSlot(0, 0.1, "60s", "1s", "0"); err != nil {
|
||||
t.Error("Error loading rate: ", rate, err.Error())
|
||||
} else if !reflect.DeepEqual(rate, expctRs) ||
|
||||
rate.RateUnitDuration() != expctRs.RateUnitDuration() ||
|
||||
@@ -342,7 +348,7 @@ func TestLoadRates(t *testing.T) {
|
||||
t.Error("Error loading rate: ", rate)
|
||||
}
|
||||
rate = csvr.rates["R3"].RateSlots[0]
|
||||
if expctRs, err = utils.NewRateSlot(0, 0, "", 0.05, "60s", "1s", "0"); err != nil {
|
||||
if expctRs, err = utils.NewRateSlot(0, 0.05, "60s", "1s", "0"); err != nil {
|
||||
t.Error("Error loading rate: ", rate, err.Error())
|
||||
} else if !reflect.DeepEqual(rate, expctRs) ||
|
||||
rate.RateUnitDuration() != expctRs.RateUnitDuration() ||
|
||||
@@ -351,7 +357,7 @@ func TestLoadRates(t *testing.T) {
|
||||
t.Error("Error loading rate: ", rate)
|
||||
}
|
||||
rate = csvr.rates["R4"].RateSlots[0]
|
||||
if expctRs, err = utils.NewRateSlot(1, 0, "", 1.0, "1s", "1s", "0"); err != nil {
|
||||
if expctRs, err = utils.NewRateSlot(1, 1.0, "1s", "1s", "0"); err != nil {
|
||||
t.Error("Error loading rate: ", rate, err.Error())
|
||||
} else if !reflect.DeepEqual(rate, expctRs) ||
|
||||
rate.RateUnitDuration() != expctRs.RateUnitDuration() ||
|
||||
@@ -360,7 +366,7 @@ func TestLoadRates(t *testing.T) {
|
||||
t.Error("Error loading rate: ", rate)
|
||||
}
|
||||
rate = csvr.rates["R5"].RateSlots[0]
|
||||
if expctRs, err = utils.NewRateSlot(0, 0, "", 0.5, "1s", "1s", "0"); err != nil {
|
||||
if expctRs, err = utils.NewRateSlot(0, 0.5, "1s", "1s", "0"); err != nil {
|
||||
t.Error("Error loading rate: ", rate, err.Error())
|
||||
} else if !reflect.DeepEqual(rate, expctRs) ||
|
||||
rate.RateUnitDuration() != expctRs.RateUnitDuration() ||
|
||||
@@ -369,7 +375,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, 0, "", 1, "1", "60", "0"); err != nil {
|
||||
if expctRs, err = utils.NewRateSlot(0, 1, "1", "60", "0"); err != nil {
|
||||
t.Error("Error loading rate: ", rate, err.Error())
|
||||
} else if !reflect.DeepEqual(rate, expctRs) ||
|
||||
rate.RateUnitDuration() != expctRs.RateUnitDuration() ||
|
||||
@@ -378,7 +384,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, 0, "", 1, "1", "1", "60"); err != nil {
|
||||
if expctRs, err = utils.NewRateSlot(0, 1, "1", "1", "60"); err != nil {
|
||||
t.Error("Error loading rate: ", rate, err.Error())
|
||||
} else if !reflect.DeepEqual(rate, expctRs) ||
|
||||
rate.RateUnitDuration() != expctRs.RateUnitDuration() ||
|
||||
@@ -389,8 +395,8 @@ func TestLoadRates(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLoadDestinationRates(t *testing.T) {
|
||||
if len(csvr.destinationRates) != 11 {
|
||||
t.Error("Failed to load destinationrates: ", csvr.destinationRates)
|
||||
if len(csvr.destinationRates) != 13 {
|
||||
t.Error("Failed to load destinationrates: ", len(csvr.destinationRates))
|
||||
}
|
||||
drs := csvr.destinationRates["RT_STANDARD"]
|
||||
dr := &utils.TPDestinationRate{
|
||||
@@ -525,7 +531,7 @@ func TestLoadDestinationRates(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLoadRatingPlans(t *testing.T) {
|
||||
if len(csvr.ratingPlans) != 10 {
|
||||
if len(csvr.ratingPlans) != 11 {
|
||||
t.Error("Failed to load rating plans: ", len(csvr.ratingPlans))
|
||||
}
|
||||
rplan := csvr.ratingPlans["STANDARD"]
|
||||
@@ -562,7 +568,7 @@ func TestLoadRatingPlans(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Ratings: map[string]*RIRate{
|
||||
"822a5aef": &RIRate{
|
||||
"b457f86d": &RIRate{
|
||||
ConnectFee: 0,
|
||||
Rates: []*Rate{
|
||||
&Rate{
|
||||
@@ -575,7 +581,7 @@ func TestLoadRatingPlans(t *testing.T) {
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
"4a25c533": &RIRate{
|
||||
"16e9ee19": &RIRate{
|
||||
ConnectFee: 0,
|
||||
Rates: []*Rate{
|
||||
&Rate{
|
||||
@@ -588,7 +594,7 @@ func TestLoadRatingPlans(t *testing.T) {
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
"b05c5f6b": &RIRate{
|
||||
"638dc1ab": &RIRate{
|
||||
ConnectFee: 0,
|
||||
Rates: []*Rate{
|
||||
&Rate{
|
||||
@@ -601,7 +607,7 @@ func TestLoadRatingPlans(t *testing.T) {
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
"9f49ef8e": &RIRate{
|
||||
"3913037f": &RIRate{
|
||||
ConnectFee: 0,
|
||||
Rates: []*Rate{
|
||||
&Rate{
|
||||
@@ -619,60 +625,60 @@ func TestLoadRatingPlans(t *testing.T) {
|
||||
"GERMANY": []*RPRate{
|
||||
&RPRate{
|
||||
Timing: "4c954a4f",
|
||||
Rating: "822a5aef",
|
||||
Rating: "b457f86d",
|
||||
Weight: 10,
|
||||
},
|
||||
&RPRate{
|
||||
Timing: "4d593287",
|
||||
Rating: "4a25c533",
|
||||
Rating: "16e9ee19",
|
||||
Weight: 10,
|
||||
},
|
||||
&RPRate{
|
||||
Timing: "a60bfb13",
|
||||
Rating: "4a25c533",
|
||||
Rating: "16e9ee19",
|
||||
Weight: 10,
|
||||
},
|
||||
},
|
||||
"GERMANY_O2": []*RPRate{
|
||||
&RPRate{
|
||||
Timing: "4c954a4f",
|
||||
Rating: "4a25c533",
|
||||
Rating: "16e9ee19",
|
||||
Weight: 10,
|
||||
},
|
||||
&RPRate{
|
||||
Timing: "4d593287",
|
||||
Rating: "b05c5f6b",
|
||||
Rating: "638dc1ab",
|
||||
Weight: 10,
|
||||
},
|
||||
&RPRate{
|
||||
Timing: "a60bfb13",
|
||||
Rating: "b05c5f6b",
|
||||
Rating: "638dc1ab",
|
||||
Weight: 10,
|
||||
},
|
||||
},
|
||||
"GERMANY_PREMIUM": []*RPRate{
|
||||
&RPRate{
|
||||
Timing: "4c954a4f",
|
||||
Rating: "4a25c533",
|
||||
Rating: "16e9ee19",
|
||||
Weight: 10,
|
||||
},
|
||||
},
|
||||
"URG": []*RPRate{
|
||||
&RPRate{
|
||||
Timing: "30eab300",
|
||||
Rating: "9f49ef8e",
|
||||
Rating: "3913037f",
|
||||
Weight: 20,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
if !reflect.DeepEqual(rplan, expected) {
|
||||
t.Errorf("Error loading destination rate timing: %+v", rplan.DestinationRates["GERMANY_O2"][0])
|
||||
t.Errorf("Error loading destination rate timing: %+v", rplan.Ratings)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadRatingProfiles(t *testing.T) {
|
||||
if len(csvr.ratingProfiles) != 15 {
|
||||
if len(csvr.ratingProfiles) != 16 {
|
||||
t.Error("Failed to load rating profiles: ", len(csvr.ratingProfiles), csvr.ratingProfiles)
|
||||
}
|
||||
rp := csvr.ratingProfiles["*out:test:0:trp"]
|
||||
|
||||
@@ -95,24 +95,19 @@ type TPLoader interface {
|
||||
WriteToDatabase(bool, bool) error
|
||||
}
|
||||
|
||||
func NewLoadRate(tag, connectFee, maxCost, maxCostStrategy, price, ratedUnits, rateIncrements, groupInterval string) (r *utils.TPRate, err error) {
|
||||
func NewLoadRate(tag, connectFee, price, ratedUnits, rateIncrements, groupInterval string) (r *utils.TPRate, err error) {
|
||||
cf, err := strconv.ParseFloat(connectFee, 64)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing connect fee from: %v", connectFee)
|
||||
return
|
||||
}
|
||||
mc, err := strconv.ParseFloat(maxCost, 64)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing max cost from: %v", maxCost)
|
||||
return
|
||||
}
|
||||
p, err := strconv.ParseFloat(price, 64)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing price from: %v", price)
|
||||
return
|
||||
}
|
||||
|
||||
rs, err := utils.NewRateSlot(cf, mc, maxCostStrategy, p, ratedUnits, rateIncrements, groupInterval)
|
||||
rs, err := utils.NewRateSlot(cf, p, ratedUnits, rateIncrements, groupInterval)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -312,6 +307,8 @@ func GetRateInterval(rpl *utils.TPRatingPlanBinding, dr *utils.DestinationRate)
|
||||
ConnectFee: dr.Rate.RateSlots[0].ConnectFee,
|
||||
RoundingMethod: dr.RoundingMethod,
|
||||
RoundingDecimals: dr.RoundingDecimals,
|
||||
MaxCost: dr.MaxCost,
|
||||
MaxCostStrategy: dr.MaxCostStrategy,
|
||||
},
|
||||
}
|
||||
for _, rl := range dr.Rate.RateSlots {
|
||||
@@ -371,10 +368,10 @@ var FileValidators = map[string]*FileLineRegexValidator{
|
||||
regexp.MustCompile(`(?:\w+\s*,\s*){1}(?:\*any\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;]|*any|<empty>),Months([0-9;]|*any|<empty>),MonthDays([0-9;]|*any|<empty>),WeekDays([0-9;]|*any|<empty>),Time([0-9:]|*asap)"},
|
||||
utils.RATES_CSV: &FileLineRegexValidator{utils.RATES_NRCOLS,
|
||||
regexp.MustCompile(`(?:\w+\s*),(?:\d+\.*\d*s*),(?:\d+\.*\d*s*),(?:\*free|\*diconnect)?,(?:\d+\.*\d*s*),(?:\d+\.*\d*(ns|us|µs|ms|s|m|h)*\s*),(?:\d+\.*\d*(ns|us|µs|ms|s|m|h)*\s*),(?:\d+\.*\d*(ns|us|µs|ms|s|m|h)*\s*)$`),
|
||||
regexp.MustCompile(`(?:\w+\s*),(?:\d+\.*\d*s*),(?:\d+\.*\d*s*),(?:\d+\.*\d*(ns|us|µs|ms|s|m|h)*\s*),(?:\d+\.*\d*(ns|us|µs|ms|s|m|h)*\s*),(?:\d+\.*\d*(ns|us|µs|ms|s|m|h)*\s*)$`),
|
||||
"Tag([0-9A-Za-z_]),ConnectFee([0-9.]),Rate([0-9.]),RateUnit([0-9.]ns|us|µs|ms|s|m|h),RateIncrementStart([0-9.]ns|us|µs|ms|s|m|h),GroupIntervalStart([0-9.]ns|us|µs|ms|s|m|h)"},
|
||||
utils.DESTINATION_RATES_CSV: &FileLineRegexValidator{utils.DESTINATION_RATES_NRCOLS,
|
||||
regexp.MustCompile(`^(?:\w+\s*),(?:\w+\s*|\*any),(?:\w+\s*),(?:\*up|\*down|\*middle),(?:\d+)$`),
|
||||
regexp.MustCompile(`^(?:\w+\s*),(?:\w+\s*|\*any),(?:\w+\s*),(?:\*up|\*down|\*middle),(?:\d+),(?:\d+\.*\d*s*),(?:\*free|\*diconnect)?$`),
|
||||
"Tag([0-9A-Za-z_]),DestinationsTag([0-9A-Za-z_]|*any),RatesTag([0-9A-Za-z_]),RoundingMethod(*up|*middle|*down),RoundingDecimals([0-9.])"},
|
||||
utils.RATING_PLANS_CSV: &FileLineRegexValidator{utils.DESTRATE_TIMINGS_NRCOLS,
|
||||
regexp.MustCompile(`(?:\w+\s*,\s*){3}(?:\d+.?\d*){1}$`),
|
||||
|
||||
@@ -40,15 +40,15 @@ DUMMY,INVALID;DATA
|
||||
GERMANY_MOBILE,+4915
|
||||
`
|
||||
var ratesSample = `#Tag,DestinationRatesTag,TimingTag,Weight
|
||||
RT_1CENT,0,0,,1,1s,1s,0s
|
||||
RT_1CENT,0,1,1s,1s,0s
|
||||
DUMMY,INVALID;DATA
|
||||
RT_DATA_2c,0,0,,0.002,10,10,0
|
||||
RT_DATA_2c,0,0.002,10,10,0
|
||||
`
|
||||
|
||||
var destRatesSample = `#Tag,DestinationsTag,RatesTag
|
||||
DR_RETAIL,GERMANY,RT_1CENT,*up,0
|
||||
var destRatesSample = `#Tag,DestinationsTag,RatesTag,MaxCost,MaxCostStrategy
|
||||
DR_RETAIL,GERMANY,RT_1CENT,*up,0,0,
|
||||
DUMMY,INVALID;DATA
|
||||
DR_DATA_1,*any,RT_DATA_2c,*up,2
|
||||
DR_DATA_1,*any,RT_DATA_2c,*up,2,0,
|
||||
`
|
||||
var ratingPlansSample = `#Tag,DestinationRatesTag,TimingTag,Weight
|
||||
RP_RETAIL,DR_RETAIL,ALWAYS,10
|
||||
@@ -415,7 +415,7 @@ func TestTPCSVFileParser(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !reflect.DeepEqual(record, []string{"RT_1CENT", "0", "0", "", "1", "1s", "1s", "0s"}) {
|
||||
if !reflect.DeepEqual(record, []string{"RT_1CENT", "0", "1", "1s", "1s", "0s"}) {
|
||||
t.Error("Unexpected record extracted", record)
|
||||
}
|
||||
case 3:
|
||||
|
||||
@@ -54,8 +54,6 @@ type TpRate struct {
|
||||
Tpid string
|
||||
Tag string
|
||||
ConnectFee float64
|
||||
MaxCost float64
|
||||
MaxCostStrategy string
|
||||
Rate float64
|
||||
RateUnit string
|
||||
RateIncrement string
|
||||
@@ -71,6 +69,8 @@ type TpDestinationRate struct {
|
||||
RatesTag string
|
||||
RoundingMethod string
|
||||
RoundingDecimals int
|
||||
MaxCost float64
|
||||
MaxCostStrategy string
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ type RIRate struct {
|
||||
}
|
||||
|
||||
func (rir *RIRate) Stringify() string {
|
||||
str := fmt.Sprintf("%v %v %v", rir.ConnectFee, rir.RoundingMethod, rir.RoundingDecimals)
|
||||
str := fmt.Sprintf("%v %v %v %v %v", rir.ConnectFee, rir.RoundingMethod, rir.RoundingDecimals, rir.MaxCost, rir.MaxCostStrategy)
|
||||
for _, r := range rir.Rates {
|
||||
str += r.Stringify()
|
||||
}
|
||||
|
||||
@@ -83,7 +83,6 @@ func (rp *RatingPlan) AddRateInterval(dId string, ris ...*RateInterval) {
|
||||
}
|
||||
if ri.Rating != nil {
|
||||
ratingTag := ri.Rating.Stringify()
|
||||
|
||||
rp.Ratings[ratingTag] = ri.Rating
|
||||
rpr.Rating = ratingTag
|
||||
}
|
||||
|
||||
@@ -1085,7 +1085,7 @@ func (self *SQLStorage) GetTpRates(tpid, tag string) (map[string]*utils.TPRate,
|
||||
}
|
||||
|
||||
for _, tr := range tpRates {
|
||||
rs, err := utils.NewRateSlot(tr.ConnectFee, tr.MaxCost, tr.MaxCostStrategy, tr.Rate, tr.RateUnit, tr.RateIncrement, tr.GroupIntervalStart)
|
||||
rs, err := utils.NewRateSlot(tr.ConnectFee, tr.Rate, tr.RateUnit, tr.RateIncrement, tr.GroupIntervalStart)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1138,6 +1138,8 @@ func (self *SQLStorage) GetTpDestinationRates(tpid, tag string, pagination *util
|
||||
RateId: tpDr.RatesTag,
|
||||
RoundingMethod: tpDr.RoundingMethod,
|
||||
RoundingDecimals: tpDr.RoundingDecimals,
|
||||
MaxCost: tpDr.MaxCost,
|
||||
MaxCostStrategy: tpDr.MaxCostStrategy,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -247,15 +247,18 @@ Will set the interval as spans's interval if new Weight is lower then span's int
|
||||
or if the Weights are equal and new price is lower then spans's interval price
|
||||
*/
|
||||
func (ts *TimeSpan) SetRateInterval(i *RateInterval) {
|
||||
//log.Printf("SETRATEINTERVAL: %+v", i.Timing)
|
||||
if ts.RateInterval == nil || ts.RateInterval.Weight < i.Weight {
|
||||
ts.RateInterval = i
|
||||
//log.Printf("RET TS: %+v", ts.RateInterval.Timing)
|
||||
return
|
||||
}
|
||||
iPrice, _, _ := i.GetRateParameters(ts.GetGroupStart())
|
||||
tsPrice, _, _ := ts.RateInterval.GetRateParameters(ts.GetGroupStart())
|
||||
if ts.RateInterval.Weight == i.Weight && iPrice < tsPrice {
|
||||
if ts.RateInterval.Weight == i.Weight && iPrice <= tsPrice {
|
||||
ts.RateInterval = i
|
||||
}
|
||||
//log.Printf("END TS: %+v", ts.RateInterval.Timing)
|
||||
}
|
||||
|
||||
// Returns the cost of the timespan according to the relevant cost interval.
|
||||
@@ -363,8 +366,9 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval, data bool) (nts *TimeSp
|
||||
return
|
||||
}
|
||||
// if the span is enclosed in the interval try to set as new interval and return nil
|
||||
//log.Printf("Timing: %+v", i.Timing)
|
||||
if i.Contains(ts.TimeStart, false) && i.Contains(ts.TimeEnd, true) {
|
||||
//Logger.Debug("All in interval")
|
||||
//log.Print("All in interval")
|
||||
ts.SetRateInterval(i)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ func (self *TPCSVImporter) importRates(fn string) error {
|
||||
}
|
||||
continue
|
||||
}
|
||||
newRt, err := NewLoadRate(record[0], record[1], record[2], record[3], record[4], record[5], record[6], record[7])
|
||||
newRt, err := NewLoadRate(record[0], record[1], record[2], record[3], record[4], record[5])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -200,6 +200,11 @@ func (self *TPCSVImporter) importDestinationRates(fn string) error {
|
||||
log.Printf("Error parsing rounding decimals: %s", record[4])
|
||||
return err
|
||||
}
|
||||
maxCost, err := strconv.ParseFloat(record[5], 64)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing max cost from: %v", record[5])
|
||||
return err
|
||||
}
|
||||
if _, hasIt := drs[record[0]]; !hasIt {
|
||||
drs[record[0]] = make([]*utils.DestinationRate, 0)
|
||||
}
|
||||
@@ -208,6 +213,8 @@ func (self *TPCSVImporter) importDestinationRates(fn string) error {
|
||||
RateId: record[2],
|
||||
RoundingMethod: record[3],
|
||||
RoundingDecimals: roundingDecimals,
|
||||
MaxCost: maxCost,
|
||||
MaxCostStrategy: record[6],
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -40,13 +40,13 @@ ASAP,*any,*any,*any,*any,*asap`
|
||||
GERMANY_MOBILE,+4915
|
||||
GERMANY_MOBILE,+4916
|
||||
GERMANY_MOBILE,+4917`
|
||||
rates := `RT_1CENT,0,0,,1,1s,1s,0s
|
||||
RT_DATA_2c,0,0,,0.002,10,10,0
|
||||
RT_SMS_5c,0,0,,0.005,1,1,0`
|
||||
destinationRates := `DR_RETAIL,GERMANY,RT_1CENT,*up,4
|
||||
DR_RETAIL,GERMANY_MOBILE,RT_1CENT,*up,4
|
||||
DR_DATA_1,*any,RT_DATA_2c,*up,4
|
||||
DR_SMS_1,*any,RT_SMS_5c,*up,4`
|
||||
rates := `RT_1CENT,0,1,1s,1s,0s
|
||||
RT_DATA_2c,0,0.002,10,10,0
|
||||
RT_SMS_5c,0,0.005,1,1,0`
|
||||
destinationRates := `DR_RETAIL,GERMANY,RT_1CENT,*up,4,0,
|
||||
DR_RETAIL,GERMANY_MOBILE,RT_1CENT,*up,4,0,
|
||||
DR_DATA_1,*any,RT_DATA_2c,*up,4,0,
|
||||
DR_SMS_1,*any,RT_SMS_5c,*up,4,0,`
|
||||
ratingPlans := `RP_RETAIL,DR_RETAIL,ALWAYS,10
|
||||
RP_DATA1,DR_DATA_1,ALWAYS,10
|
||||
RP_SMS1,DR_SMS_1,ALWAYS,10`
|
||||
|
||||
@@ -37,10 +37,10 @@ func TestSetStorageDtChrg1(t *testing.T) {
|
||||
func TestLoadCsvTpDtChrg1(t *testing.T) {
|
||||
timings := `TM1,*any,*any,*any,*any,00:00:00
|
||||
TM2,*any,*any,*any,*any,01:00:00`
|
||||
rates := `RT_DATA_2c,0,0,,0.002,10,10,0
|
||||
RT_DATA_1c,0,0,,0.001,10,10,0`
|
||||
destinationRates := `DR_DATA_1,*any,RT_DATA_2c,*up,4
|
||||
DR_DATA_2,*any,RT_DATA_1c,*up,4`
|
||||
rates := `RT_DATA_2c,0,0.002,10,10,0
|
||||
RT_DATA_1c,0,0.001,10,10,0`
|
||||
destinationRates := `DR_DATA_1,*any,RT_DATA_2c,*up,4,0,
|
||||
DR_DATA_2,*any,RT_DATA_1c,*up,4,0,`
|
||||
ratingPlans := `RP_DATA1,DR_DATA_1,TM1,10
|
||||
RP_DATA1,DR_DATA_2,TM2,10`
|
||||
ratingProfiles := `*out,cgrates.org,data,*any,2012-01-01T00:00:00Z,RP_DATA1,`
|
||||
|
||||
@@ -42,10 +42,10 @@ func TestLoadCsvTp(t *testing.T) {
|
||||
ASAP,*any,*any,*any,*any,*asap`
|
||||
destinations := `DST_UK_Mobile_BIG5,447596
|
||||
DST_UK_Mobile_BIG5,447956`
|
||||
rates := `RT_UK_Mobile_BIG5_PKG,0.01,0,,0,20s,20s,0s
|
||||
RT_UK_Mobile_BIG5,0.01,0,,0.10,1s,1s,0s`
|
||||
destinationRates := `DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG,*up,8
|
||||
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5,*up,8`
|
||||
rates := `RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s
|
||||
RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s`
|
||||
destinationRates := `DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG,*up,8,0,
|
||||
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5,*up,8,0,`
|
||||
ratingPlans := `RP_UK_Mobile_BIG5_PKG,DR_UK_Mobile_BIG5_PKG,ALWAYS,10
|
||||
RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10`
|
||||
ratingProfiles := `*out,cgrates.org,call,*any,2013-01-06T00:00:00Z,RP_UK,
|
||||
|
||||
@@ -42,10 +42,10 @@ func TestLoadCsvTp2(t *testing.T) {
|
||||
ASAP,*any,*any,*any,*any,*asap`
|
||||
destinations := `DST_UK_Mobile_BIG5,447596
|
||||
DST_UK_Mobile_BIG5,447956`
|
||||
rates := `RT_UK_Mobile_BIG5_PKG,0.01,0,,0,20s,20s,0s
|
||||
RT_UK_Mobile_BIG5,0.01,0,,0.10,1s,1s,0s`
|
||||
destinationRates := `DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG,*up,8
|
||||
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5,*up,8`
|
||||
rates := `RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s
|
||||
RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s`
|
||||
destinationRates := `DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG,*up,8,0,
|
||||
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5,*up,8,0,`
|
||||
ratingPlans := `RP_UK_Mobile_BIG5_PKG,DR_UK_Mobile_BIG5_PKG,ALWAYS,10
|
||||
RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10`
|
||||
ratingProfiles := `*out,cgrates.org,call,*any,2013-01-06T00:00:00Z,RP_UK,
|
||||
|
||||
@@ -42,10 +42,10 @@ func TestLoadCsvTp3(t *testing.T) {
|
||||
ASAP,*any,*any,*any,*any,*asap`
|
||||
destinations := `DST_UK_Mobile_BIG5,447596
|
||||
DST_UK_Mobile_BIG5,447956`
|
||||
rates := `RT_UK_Mobile_BIG5_PKG,0.01,0,,0,20s,20s,0s
|
||||
RT_UK_Mobile_BIG5,0.01,0,,0.10,1s,1s,0s`
|
||||
destinationRates := `DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG,*up,8
|
||||
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5,*up,8`
|
||||
rates := `RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s
|
||||
RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s`
|
||||
destinationRates := `DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG,*up,8,0,
|
||||
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5,*up,8,0,`
|
||||
ratingPlans := `RP_UK_Mobile_BIG5_PKG,DR_UK_Mobile_BIG5_PKG,ALWAYS,10
|
||||
RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10`
|
||||
ratingProfiles := `*out,cgrates.org,call,*any,2013-01-06T00:00:00Z,RP_UK,
|
||||
|
||||
@@ -36,8 +36,8 @@ func TestSMSSetStorageSmsChrg1(t *testing.T) {
|
||||
|
||||
func TestSMSLoadCsvTpSmsChrg1(t *testing.T) {
|
||||
timings := `ALWAYS,*any,*any,*any,*any,00:00:00`
|
||||
rates := `RT_SMS_5c,0,0,,0.005,1,1,0`
|
||||
destinationRates := `DR_SMS_1,*any,RT_SMS_5c,*up,4`
|
||||
rates := `RT_SMS_5c,0,0.005,1,1,0`
|
||||
destinationRates := `DR_SMS_1,*any,RT_SMS_5c,*up,4,0,`
|
||||
ratingPlans := `RP_SMS1,DR_SMS_1,ALWAYS,10`
|
||||
ratingProfiles := `*out,cgrates.org,sms,*any,2012-01-01T00:00:00Z,RP_SMS1,`
|
||||
csvr := engine.NewStringCSVReader(ratingDb, acntDb, ',', "", timings, rates, destinationRates, ratingPlans, ratingProfiles,
|
||||
|
||||
@@ -101,6 +101,7 @@ func (s *Session) debitLoop(runIdx int) {
|
||||
// update call duration with real debited duration
|
||||
nextCd.DurationIndex -= debitPeriod
|
||||
nextCd.DurationIndex += nextCd.GetDuration()
|
||||
nextCd.MaxCostSoFar += cc.Cost
|
||||
time.Sleep(cc.GetDuration())
|
||||
index++
|
||||
}
|
||||
|
||||
@@ -86,8 +86,8 @@ func (self *TPRate) AsExportSlice() [][]string {
|
||||
}
|
||||
|
||||
// Needed so we make sure we always use SetDurations() on a newly created value
|
||||
func NewRateSlot(connectFee, maxCost float64, maxCostStrategy string, rate float64, rateUnit, rateIncrement, grpInterval string) (*RateSlot, error) {
|
||||
rs := &RateSlot{ConnectFee: connectFee, Rate: rate, RateUnit: rateUnit, RateIncrement: rateIncrement, MaxCost: maxCost, MaxCostStrategy: maxCostStrategy,
|
||||
func NewRateSlot(connectFee, rate float64, rateUnit, rateIncrement, grpInterval string) (*RateSlot, error) {
|
||||
rs := &RateSlot{ConnectFee: connectFee, Rate: rate, RateUnit: rateUnit, RateIncrement: rateIncrement,
|
||||
GroupIntervalStart: grpInterval}
|
||||
if err := rs.SetDurations(); err != nil {
|
||||
return nil, err
|
||||
@@ -103,8 +103,6 @@ type RateSlot struct {
|
||||
GroupIntervalStart string // Group position
|
||||
rateUnitDur time.Duration
|
||||
rateIncrementDur time.Duration
|
||||
MaxCost float64
|
||||
MaxCostStrategy string
|
||||
groupIntervalStartDur time.Duration
|
||||
}
|
||||
|
||||
@@ -153,6 +151,8 @@ type DestinationRate struct {
|
||||
Rate *TPRate
|
||||
RoundingMethod string
|
||||
RoundingDecimals int
|
||||
MaxCost float64
|
||||
MaxCostStrategy string
|
||||
}
|
||||
|
||||
type ApierTPTiming struct {
|
||||
|
||||
@@ -60,8 +60,8 @@ const (
|
||||
CDR_STATS_CSV = "CdrStats.csv"
|
||||
TIMINGS_NRCOLS = 6
|
||||
DESTINATIONS_NRCOLS = 2
|
||||
RATES_NRCOLS = 8
|
||||
DESTINATION_RATES_NRCOLS = 5
|
||||
RATES_NRCOLS = 6
|
||||
DESTINATION_RATES_NRCOLS = 7
|
||||
DESTRATE_TIMINGS_NRCOLS = 4
|
||||
RATE_PROFILES_NRCOLS = 7
|
||||
SHARED_GROUPS_NRCOLS = 4
|
||||
|
||||
Reference in New Issue
Block a user