moved max cost and strategy at destination rate level

This commit is contained in:
Radu Ioan Fericean
2015-03-23 14:41:25 +02:00
parent 9b68022110
commit 643636872e
24 changed files with 147 additions and 134 deletions

View File

@@ -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`),

View File

@@ -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)
);

View File

@@ -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 #Tag DestinationsTag RatesTag RoundingMethod RoundingDecimals MaxCost MaxCostStrategy
2 DR_RETAIL GERMANY RT_1CENT *up 4 0

View File

@@ -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 #Tag,ConnectFee,Rate,RateUnit,RateIncrement,GroupIntervalStart #Tag ConnectFee Rate RateUnit RateIncrement GroupIntervalStart
2 RT_1CENT,0,0,,1,1s,1s,0s RT_1CENT 0 1 1s 1s 0s

View File

@@ -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 #Tag DestinationsTag RatesTag RoundingMethod RoundingDecimals MaxCost MaxCostStrategy
2 DR_RETAIL GERMANY RT_1CENT *up 4 0
3 DR_RETAIL GERMANY_MOBILE RT_1CENT *up 4 0
4 DR_DATA_1 *any RT_DATA_2c *up 4 0
5 DR_SMS_1 *any RT_SMS_5c *up 4 0

View File

@@ -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 #Tag,ConnectFee,Rate,RateUnit,RateIncrement,GroupIntervalStart #Tag ConnectFee Rate RateUnit RateIncrement GroupIntervalStart
2 RT_1CENT,0,0,,1,1s,1s,0s RT_1CENT 0 1 1s 1s 0s
3 RT_DATA_2c,0,0,,0.002,10,10,0 RT_DATA_2c 0 0.002 10 10 0
4 RT_SMS_5c,0,0,,0.005,1,1,0 RT_SMS_5c 0 0.005 1 1 0

View File

@@ -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 #Tag DestinationsTag RatesTag RoundingMethod RoundingDecimals MaxCost MaxCostStrategy
2 DR_1002_20CNT DST_1002 RT_20CNT *up 4 0
3 DR_1002_10CNT DST_1002 RT_10CNT *up 4 0
4 DR_1003_20CNT DST_1003 RT_40CNT *up 4 0
5 DR_1003_10CNT DST_1003 RT_10CNT *up 4 0
6 DR_FS_40CNT DST_FS RT_40CNT *up 4 0
7 DR_FS_10CNT DST_FS RT_10CNT *up 4 0
8 DR_SPECIAL_1002 DST_1002 RT_1CNT *up 4 0

View File

@@ -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
1 #Tag,ConnectFee,Rate,RateUnit,RateIncrement,GroupIntervalStart
2 RT_10CNT,0.2,0,,0.1,60s,60s,0s RT_10CNT,0.2,0.1,60s,60s,0s
3 RT_10CNT,0,0,,0.05,60s,1s,60s RT_10CNT,0,0.05,60s,1s,60s
4 RT_20CNT,0,0,.4,0.2,60s,60s,0s RT_20CNT,0,.4,0.2,60s,60s,0s
5 RT_20CNT,0,0,,0.1,60s,1s,60s RT_20CNT,0,0.1,60s,1s,60s
6 RT_40CNT,0,0,.8,0.4,60s,30s,0s RT_40CNT,0,.8,0.4,60s,30s,0s
7 RT_40CNT,0,0,,0.2,60s,10s,60s RT_40CNT,0,0.2,60s,10s,60s
8 RT_1CNT,0,0,,0.01,60s,60s,0s RT_1CNT,0,0.01,60s,60s,0s

View File

@@ -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],
},
},
}

View File

@@ -55,37 +55,37 @@ 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
`
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,
`
ratingPlans = `
STANDARD,RT_STANDARD,WORKDAYS_00,10
@@ -323,7 +323,7 @@ func TestLoadRates(t *testing.T) {
t.Error("Failed to load rates: ", 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 +333,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 +342,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 +351,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 +360,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 +369,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 +378,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() ||
@@ -562,7 +562,7 @@ func TestLoadRatingPlans(t *testing.T) {
},
},
Ratings: map[string]*RIRate{
"822a5aef": &RIRate{
"b457f86d": &RIRate{
ConnectFee: 0,
Rates: []*Rate{
&Rate{
@@ -575,7 +575,7 @@ func TestLoadRatingPlans(t *testing.T) {
RoundingMethod: utils.ROUNDING_MIDDLE,
RoundingDecimals: 4,
},
"4a25c533": &RIRate{
"16e9ee19": &RIRate{
ConnectFee: 0,
Rates: []*Rate{
&Rate{
@@ -588,7 +588,7 @@ func TestLoadRatingPlans(t *testing.T) {
RoundingMethod: utils.ROUNDING_MIDDLE,
RoundingDecimals: 4,
},
"b05c5f6b": &RIRate{
"638dc1ab": &RIRate{
ConnectFee: 0,
Rates: []*Rate{
&Rate{
@@ -601,7 +601,7 @@ func TestLoadRatingPlans(t *testing.T) {
RoundingMethod: utils.ROUNDING_MIDDLE,
RoundingDecimals: 4,
},
"9f49ef8e": &RIRate{
"3913037f": &RIRate{
ConnectFee: 0,
Rates: []*Rate{
&Rate{
@@ -619,55 +619,55 @@ 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)
}
}

View File

@@ -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}$`),

View File

@@ -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:

View File

@@ -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
}

View File

@@ -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()
}

View File

@@ -1073,7 +1073,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
}
@@ -1126,6 +1126,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,
},
},
}

View File

@@ -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],
})
}

View File

@@ -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`

View File

@@ -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,`

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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 {

View File

@@ -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