From 643636872e02457aee48d03a84baf5fbed6f517f Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Mon, 23 Mar 2015 14:41:25 +0200 Subject: [PATCH] moved max cost and strategy at destination rate level --- .../mysql/create_tariffplan_tables.sql | 8 +- .../postgres/create_tariffplan_tables.sql | 6 +- .../tariffplans/cdrstats/DestinationRates.csv | 4 +- data/tariffplans/cdrstats/Rates.csv | 2 +- .../prepaid1centpsec/DestinationRates.csv | 10 +- data/tariffplans/prepaid1centpsec/Rates.csv | 6 +- .../tariffplans/tutorial/DestinationRates.csv | 16 +-- data/tariffplans/tutorial/Rates.csv | 14 +-- engine/loader_csv.go | 9 +- engine/loader_csv_test.go | 98 +++++++++---------- engine/loader_helpers.go | 15 ++- engine/loader_helpers_test.go | 12 +-- engine/models.go | 4 +- engine/rateinterval.go | 2 +- engine/storage_sql.go | 4 +- engine/tpimporter_csv.go | 9 +- general_tests/costs1_test.go | 14 +-- general_tests/datachrg1_test.go | 8 +- general_tests/ddazmbl1_test.go | 8 +- general_tests/ddazmbl2_test.go | 8 +- general_tests/ddazmbl3_test.go | 8 +- general_tests/smschrg1_test.go | 4 +- utils/apitpdata.go | 8 +- utils/consts.go | 4 +- 24 files changed, 147 insertions(+), 134 deletions(-) diff --git a/data/storage/mysql/create_tariffplan_tables.sql b/data/storage/mysql/create_tariffplan_tables.sql index 0728fa7ea..a24329fe3 100644 --- a/data/storage/mysql/create_tariffplan_tables.sql +++ b/data/storage/mysql/create_tariffplan_tables.sql @@ -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`), diff --git a/data/storage/postgres/create_tariffplan_tables.sql b/data/storage/postgres/create_tariffplan_tables.sql index 178802b85..085682dcc 100644 --- a/data/storage/postgres/create_tariffplan_tables.sql +++ b/data/storage/postgres/create_tariffplan_tables.sql @@ -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) ); diff --git a/data/tariffplans/cdrstats/DestinationRates.csv b/data/tariffplans/cdrstats/DestinationRates.csv index 9dbe6e9a9..2749b9e4e 100644 --- a/data/tariffplans/cdrstats/DestinationRates.csv +++ b/data/tariffplans/cdrstats/DestinationRates.csv @@ -1,2 +1,2 @@ -#Tag,DestinationsTag,RatesTag,RoundingMethod,RoundingDecimals -DR_RETAIL,GERMANY,RT_1CENT,*up,4 \ No newline at end of file +#Tag,DestinationsTag,RatesTag,RoundingMethod,RoundingDecimals,MaxCost,MaxCostStrategy +DR_RETAIL,GERMANY,RT_1CENT,*up,4,0, diff --git a/data/tariffplans/cdrstats/Rates.csv b/data/tariffplans/cdrstats/Rates.csv index c4f0e9c63..2afc7701b 100644 --- a/data/tariffplans/cdrstats/Rates.csv +++ b/data/tariffplans/cdrstats/Rates.csv @@ -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 diff --git a/data/tariffplans/prepaid1centpsec/DestinationRates.csv b/data/tariffplans/prepaid1centpsec/DestinationRates.csv index 64164f62b..b5d2474b3 100644 --- a/data/tariffplans/prepaid1centpsec/DestinationRates.csv +++ b/data/tariffplans/prepaid1centpsec/DestinationRates.csv @@ -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 \ No newline at end of file +#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, diff --git a/data/tariffplans/prepaid1centpsec/Rates.csv b/data/tariffplans/prepaid1centpsec/Rates.csv index 02365a72c..991ce0720 100644 --- a/data/tariffplans/prepaid1centpsec/Rates.csv +++ b/data/tariffplans/prepaid1centpsec/Rates.csv @@ -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 diff --git a/data/tariffplans/tutorial/DestinationRates.csv b/data/tariffplans/tutorial/DestinationRates.csv index b902c0601..8a4e10c34 100644 --- a/data/tariffplans/tutorial/DestinationRates.csv +++ b/data/tariffplans/tutorial/DestinationRates.csv @@ -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, diff --git a/data/tariffplans/tutorial/Rates.csv b/data/tariffplans/tutorial/Rates.csv index f66af1735..a1b758e7a 100644 --- a/data/tariffplans/tutorial/Rates.csv +++ b/data/tariffplans/tutorial/Rates.csv @@ -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 diff --git a/engine/loader_csv.go b/engine/loader_csv.go index e787426de..d7cf74186 100644 --- a/engine/loader_csv.go +++ b/engine/loader_csv.go @@ -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], }, }, } diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 75daefa19..5c0901c01 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -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) } } diff --git a/engine/loader_helpers.go b/engine/loader_helpers.go index b69d7e345..49369358e 100644 --- a/engine/loader_helpers.go +++ b/engine/loader_helpers.go @@ -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|),Months([0-9;]|*any|),MonthDays([0-9;]|*any|),WeekDays([0-9;]|*any|),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}$`), diff --git a/engine/loader_helpers_test.go b/engine/loader_helpers_test.go index aef61c6b6..438e8abd3 100644 --- a/engine/loader_helpers_test.go +++ b/engine/loader_helpers_test.go @@ -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: diff --git a/engine/models.go b/engine/models.go index dae967889..4b4277b7a 100644 --- a/engine/models.go +++ b/engine/models.go @@ -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 } diff --git a/engine/rateinterval.go b/engine/rateinterval.go index b8255259a..5a2f8e273 100644 --- a/engine/rateinterval.go +++ b/engine/rateinterval.go @@ -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() } diff --git a/engine/storage_sql.go b/engine/storage_sql.go index af1f18925..206bc975f 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -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, }, }, } diff --git a/engine/tpimporter_csv.go b/engine/tpimporter_csv.go index e02dd60c3..a9e343081 100644 --- a/engine/tpimporter_csv.go +++ b/engine/tpimporter_csv.go @@ -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], }) } diff --git a/general_tests/costs1_test.go b/general_tests/costs1_test.go index 055c07d35..35cd81004 100644 --- a/general_tests/costs1_test.go +++ b/general_tests/costs1_test.go @@ -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` diff --git a/general_tests/datachrg1_test.go b/general_tests/datachrg1_test.go index ca4984a20..ce14ec326 100644 --- a/general_tests/datachrg1_test.go +++ b/general_tests/datachrg1_test.go @@ -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,` diff --git a/general_tests/ddazmbl1_test.go b/general_tests/ddazmbl1_test.go index 7c393d9cb..1508ac91c 100644 --- a/general_tests/ddazmbl1_test.go +++ b/general_tests/ddazmbl1_test.go @@ -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, diff --git a/general_tests/ddazmbl2_test.go b/general_tests/ddazmbl2_test.go index ea4c3e0b8..64d97f1ef 100644 --- a/general_tests/ddazmbl2_test.go +++ b/general_tests/ddazmbl2_test.go @@ -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, diff --git a/general_tests/ddazmbl3_test.go b/general_tests/ddazmbl3_test.go index 4905f32fe..4333ec064 100644 --- a/general_tests/ddazmbl3_test.go +++ b/general_tests/ddazmbl3_test.go @@ -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, diff --git a/general_tests/smschrg1_test.go b/general_tests/smschrg1_test.go index d9d02a8f9..2e8442092 100644 --- a/general_tests/smschrg1_test.go +++ b/general_tests/smschrg1_test.go @@ -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, diff --git a/utils/apitpdata.go b/utils/apitpdata.go index 31610756b..2cc0a783c 100644 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -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 { diff --git a/utils/consts.go b/utils/consts.go index cd700a5c2..3c28c4705 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -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