diff --git a/apier/v1/rateprofiles_it_test.go b/apier/v1/rateprofiles_it_test.go index 70827c50e..f15f510bf 100644 --- a/apier/v1/rateprofiles_it_test.go +++ b/apier/v1/rateprofiles_it_test.go @@ -135,7 +135,7 @@ func testV1RatePrfVerifyRateProfile(t *testing.T) { rPrf := &engine.RateProfile{ Tenant: "cgrates.org", ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002"}, + FilterIDs: []string{"*string:~*req.Subject:1001"}, Weight: 0, ConnectFee: 0.1, RoundingMethod: "*up", @@ -144,23 +144,50 @@ func testV1RatePrfVerifyRateProfile(t *testing.T) { MaxCost: 0.6, MaxCostStrategy: "*free", Rates: map[string]*engine.Rate{ - "FIRST_GI": &engine.Rate{ - ID: "FIRST_GI", - FilterIDs: []string{"*gi:~*req.Usage:0"}, - Weight: 0, - Value: 0.12, - Unit: time.Duration(1 * time.Minute), - Increment: time.Duration(1 * time.Minute), - Blocker: false, + "RT_WEEK": &engine.Rate{ + ID: "RT_WEEK", + Weight: 0, + ActivationStart: "* * * * 1-5", + IntervalRates: []*engine.IntervalRate{ + &engine.IntervalRate{ + IntervalStart: time.Duration(0 * time.Second), + Value: 0.12, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Minute), + }, + &engine.IntervalRate{ + IntervalStart: time.Duration(1 * time.Minute), + Value: 0.06, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Second), + }, + }, }, - "SECOND_GI": &engine.Rate{ - ID: "SECOND_GI", - FilterIDs: []string{"*gi:~*req.Usage:1m"}, - Weight: 10, - Value: 0.06, - Unit: time.Duration(1 * time.Minute), - Increment: time.Duration(1 * time.Second), - Blocker: false, + "RT_WEEKEND": &engine.Rate{ + ID: "RT_WEEKEND", + Weight: 10, + ActivationStart: "* * * * 0,6", + IntervalRates: []*engine.IntervalRate{ + &engine.IntervalRate{ + IntervalStart: time.Duration(0 * time.Second), + Value: 0.06, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Second), + }, + }, + }, + "RT_CHRISTMAS": &engine.Rate{ + ID: "RT_CHRISTMAS", + Weight: 30, + ActivationStart: "* * 24 12 *", + IntervalRates: []*engine.IntervalRate{ + &engine.IntervalRate{ + IntervalStart: time.Duration(0 * time.Second), + Value: 0.06, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Second), + }, + }, }, }, } diff --git a/apier/v1/remote_it_test.go b/apier/v1/remote_it_test.go index e45447464..b743b665c 100644 --- a/apier/v1/remote_it_test.go +++ b/apier/v1/remote_it_test.go @@ -717,7 +717,7 @@ func testInternalRemoteITGetRouteProfile(t *testing.T) { RateProfile: &engine.RateProfile{ Tenant: "cgrates.org", ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002"}, + FilterIDs: []string{"*string:~*req.Subject:1001"}, Weight: 0, ConnectFee: 0.1, RoundingMethod: "*up", @@ -726,23 +726,50 @@ func testInternalRemoteITGetRouteProfile(t *testing.T) { MaxCost: 0.6, MaxCostStrategy: "*free", Rates: map[string]*engine.Rate{ - "FIRST_GI": &engine.Rate{ - ID: "FIRST_GI", - FilterIDs: []string{"*gi:~*req.Usage:0"}, - Weight: 0, - Value: 0.12, - Unit: time.Duration(1 * time.Minute), - Increment: time.Duration(1 * time.Minute), - Blocker: false, + "RT_WEEK": &engine.Rate{ + ID: "RT_WEEK", + Weight: 0, + ActivationStart: "* * * * 1-5", + IntervalRates: []*engine.IntervalRate{ + &engine.IntervalRate{ + IntervalStart: time.Duration(0 * time.Second), + Value: 0.12, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Minute), + }, + &engine.IntervalRate{ + IntervalStart: time.Duration(1 * time.Minute), + Value: 0.06, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Second), + }, + }, }, - "SECOND_GI": &engine.Rate{ - ID: "SECOND_GI", - FilterIDs: []string{"*gi:~*req.Usage:1m"}, - Weight: 10, - Value: 0.06, - Unit: time.Duration(1 * time.Minute), - Increment: time.Duration(1 * time.Second), - Blocker: false, + "RT_WEEKEND": &engine.Rate{ + ID: "RT_WEEKEND", + Weight: 10, + ActivationStart: "* * * * 0,6", + IntervalRates: []*engine.IntervalRate{ + &engine.IntervalRate{ + IntervalStart: time.Duration(0 * time.Second), + Value: 0.06, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Second), + }, + }, + }, + "RT_CHRISTMAS": &engine.Rate{ + ID: "RT_CHRISTMAS", + Weight: 30, + ActivationStart: "* * 24 12 *", + IntervalRates: []*engine.IntervalRate{ + &engine.IntervalRate{ + IntervalStart: time.Duration(0 * time.Second), + Value: 0.06, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Second), + }, + }, }, }, }, diff --git a/apier/v1/replicate_it_test.go b/apier/v1/replicate_it_test.go index e0fe5a227..9ec093097 100644 --- a/apier/v1/replicate_it_test.go +++ b/apier/v1/replicate_it_test.go @@ -1355,7 +1355,7 @@ func testInternalReplicateITRateProfile(t *testing.T) { RateProfile: &engine.RateProfile{ Tenant: "cgrates.org", ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002"}, + FilterIDs: []string{"*string:~*req.Subject:1001"}, Weight: 0, ConnectFee: 0.1, RoundingMethod: "*up", @@ -1364,23 +1364,50 @@ func testInternalReplicateITRateProfile(t *testing.T) { MaxCost: 0.6, MaxCostStrategy: "*free", Rates: map[string]*engine.Rate{ - "FIRST_GI": &engine.Rate{ - ID: "FIRST_GI", - FilterIDs: []string{"*gi:~*req.Usage:0"}, - Weight: 0, - Value: 0.12, - Unit: time.Duration(1 * time.Minute), - Increment: time.Duration(1 * time.Minute), - Blocker: false, + "RT_WEEK": &engine.Rate{ + ID: "RT_WEEK", + Weight: 0, + ActivationStart: "* * * * 1-5", + IntervalRates: []*engine.IntervalRate{ + &engine.IntervalRate{ + IntervalStart: time.Duration(0 * time.Second), + Value: 0.12, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Minute), + }, + &engine.IntervalRate{ + IntervalStart: time.Duration(1 * time.Minute), + Value: 0.06, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Second), + }, + }, }, - "SECOND_GI": &engine.Rate{ - ID: "SECOND_GI", - FilterIDs: []string{"*gi:~*req.Usage:1m"}, - Weight: 10, - Value: 0.06, - Unit: time.Duration(1 * time.Minute), - Increment: time.Duration(1 * time.Second), - Blocker: false, + "RT_WEEKEND": &engine.Rate{ + ID: "RT_WEEKEND", + Weight: 10, + ActivationStart: "* * * * 0,6", + IntervalRates: []*engine.IntervalRate{ + &engine.IntervalRate{ + IntervalStart: time.Duration(0 * time.Second), + Value: 0.06, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Second), + }, + }, + }, + "RT_CHRISTMAS": &engine.Rate{ + ID: "RT_CHRISTMAS", + Weight: 30, + ActivationStart: "* * 24 12 *", + IntervalRates: []*engine.IntervalRate{ + &engine.IntervalRate{ + IntervalStart: time.Duration(0 * time.Second), + Value: 0.06, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Second), + }, + }, }, }, }, diff --git a/data/tariffplans/tutrates/RateProfiles.csv b/data/tariffplans/tutrates/RateProfiles.csv index 49a229fcc..a630a16e4 100644 --- a/data/tariffplans/tutrates/RateProfiles.csv +++ b/data/tariffplans/tutrates/RateProfiles.csv @@ -1,3 +1,5 @@ #Tenant,ID,FilterIDs,ActivationInterval,Weight,ConnectFee,RoundingMethod,RoundingDecimals,MinCost,MaxCost,MaxCostStrategy,RateID,RateFilterIDs,RateActivationStart,RateWeight,RateBlocker,RateIntervalStart,RateValue,RateUnit,RateIncrement -cgrates.org,RP1,*string:~*req.Subject:1001,,0,0.1,*up,4,0.1,0.6,*free,FIRST_GI,*gi:~*req.Usage:0,,0,0.12,1m,1m,FALSE -cgrates.org,RP1,,,,,,,,,,SECOND_GI,*gi:~*req.Usage:1m,,10,0.06,1m,1s,FALSE +cgrates.org,RP1,*string:~*req.Subject:1001,,0,0.1,*up,4,0.1,0.6,*free,RT_WEEK,,"* * * * 1-5",0,false,0s,0.12,1m,1m +cgrates.org,RP1,,,,,,,,,,RT_WEEK,,,,,1m,0.6,1m,1s +cgrates.org,RP1,,,,,,,,,,RT_WEEKEND,,"* * * * 0,6",10,false,0s,0.06,1m,1s +cgrates.org,RP1,,,,,,,,,,RT_CHRISTMAS,,* * 24 12 *,30,false,0s,0.06,1m,1s \ No newline at end of file diff --git a/engine/libtest.go b/engine/libtest.go index fe80b6135..bbd3e210b 100644 --- a/engine/libtest.go +++ b/engine/libtest.go @@ -281,9 +281,11 @@ cgrates.org,ALL1,127.0.0.1:2012,*json,true cgrates.org,ALL1,127.0.0.1:3012,*json,false ` RateProfileCSVContent = ` -#Tenant,ID,FilterIDs,ActivationInterval,Weight,ConnectFee,RoundingMethod,RoundingDecimals,MinCost,MaxCost,MaxCostStrategy,RateID,RateFilterIDs,RateActivationInterval,RateWeight,RateValue,RateUnit,RateIncrement,RateBlocker -cgrates.org,RP1,*string:~*req.Subject:1001,,0,0.1,*up,4,0.1,0.6,*free,FIRST_GI,*gi:~*req.Usage:0,,0,0.12,1m,1m,FALSE -cgrates.org,RP1,*string:~*req.Subject:1002,,,,,,,,,SECOND_GI,*gi:~*req.Usage:1m,,10,0.06,1m,1s,FALSE +#Tenant,ID,FilterIDs,ActivationInterval,Weight,ConnectFee,RoundingMethod,RoundingDecimals,MinCost,MaxCost,MaxCostStrategy,RateID,RateFilterIDs,RateActivationStart,RateWeight,RateBlocker,RateIntervalStart,RateValue,RateUnit,RateIncrement +cgrates.org,RP1,*string:~*req.Subject:1001,,0,0.1,*up,4,0.1,0.6,*free,RT_WEEK,,"* * * * 1-5",0,false,0s,0.12,1m,1m +cgrates.org,RP1,,,,,,,,,,RT_WEEK,,,,,1m,0.06,1m,1s +cgrates.org,RP1,,,,,,,,,,RT_WEEKEND,,"* * * * 0,6",10,false,0s,0.06,1m,1s +cgrates.org,RP1,,,,,,,,,,RT_CHRISTMAS,,* * 24 12 *,30,false,0s,0.06,1m,1s ` ) diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 9747d9fe0..7fbdba06e 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -1417,7 +1417,7 @@ func TestLoadRateProfiles(t *testing.T) { TPid: testTPID, Tenant: "cgrates.org", ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002"}, + FilterIDs: []string{"*string:~*req.Subject:1001"}, Weight: 0, ConnectFee: 0.1, RoundingMethod: "*up", @@ -1426,23 +1426,50 @@ func TestLoadRateProfiles(t *testing.T) { MaxCost: 0.6, MaxCostStrategy: "*free", Rates: map[string]*utils.TPRate{ - "FIRST_GI": { - ID: "FIRST_GI", - FilterIDs: []string{"*gi:~*req.Usage:0"}, - Weight: 0, - Value: 0.12, - Unit: "1m", - Increment: "1m", - Blocker: false, + "RT_WEEK": &utils.TPRate{ + ID: "RT_WEEK", + Weight: 0, + ActivationStart: "* * * * 1-5", + IntervalRates: []*utils.TPIntervalRate{ + &utils.TPIntervalRate{ + IntervalStart: "0s", + Value: 0.12, + Unit: "1m", + Increment: "1m", + }, + &utils.TPIntervalRate{ + IntervalStart: "1m", + Value: 0.06, + Unit: "1m", + Increment: "1s", + }, + }, }, - "SECOND_GI": { - ID: "SECOND_GI", - FilterIDs: []string{"*gi:~*req.Usage:1m"}, - Weight: 10, - Value: 0.06, - Unit: "1m", - Increment: "1s", - Blocker: false, + "RT_WEEKEND": &utils.TPRate{ + ID: "RT_WEEKEND", + Weight: 10, + ActivationStart: "* * * * 0,6", + IntervalRates: []*utils.TPIntervalRate{ + &utils.TPIntervalRate{ + IntervalStart: "0s", + Value: 0.06, + Unit: "1m", + Increment: "1s", + }, + }, + }, + "RT_CHRISTMAS": &utils.TPRate{ + ID: "RT_CHRISTMAS", + Weight: 30, + ActivationStart: "* * 24 12 *", + IntervalRates: []*utils.TPIntervalRate{ + &utils.TPIntervalRate{ + IntervalStart: "0s", + Value: 0.06, + Unit: "1m", + Increment: "1s", + }, + }, }, }, } @@ -1450,15 +1477,12 @@ func TestLoadRateProfiles(t *testing.T) { t.Errorf("Failed to load rateProfiles: %s", utils.ToIJSON(csvr.rateProfiles)) } dppKey := utils.TenantID{Tenant: "cgrates.org", ID: "RP1"} - sort.Slice(eRatePrf.FilterIDs, func(i, j int) bool { - return eRatePrf.FilterIDs[i] < eRatePrf.FilterIDs[j] - }) - sort.Slice(csvr.rateProfiles[dppKey].FilterIDs, func(i, j int) bool { - return csvr.rateProfiles[dppKey].FilterIDs[i] < csvr.rateProfiles[dppKey].FilterIDs[j] + sort.Slice(csvr.rateProfiles[dppKey].Rates["RT_WEEK"].IntervalRates, func(i, j int) bool { + return csvr.rateProfiles[dppKey].Rates["RT_WEEK"].IntervalRates[i].IntervalStart < csvr.rateProfiles[dppKey].Rates["RT_WEEK"].IntervalRates[j].IntervalStart }) if !reflect.DeepEqual(eRatePrf, csvr.rateProfiles[dppKey]) { - t.Errorf("Expecting: %+v, received: %+v", + t.Errorf("Expecting: %+v,\n received: %+v", utils.ToJSON(eRatePrf), utils.ToJSON(csvr.rateProfiles[dppKey])) } } diff --git a/engine/model_helpers.go b/engine/model_helpers.go index 3d8ce3057..9ab03df73 100644 --- a/engine/model_helpers.go +++ b/engine/model_helpers.go @@ -3217,6 +3217,7 @@ func APItoRateProfile(tpRp *utils.TPRateProfile, timezone string) (rp *RateProfi IntervalRates: make([]*IntervalRate, len(rate.IntervalRates)), } for i, iRate := range rate.IntervalRates { + rp.Rates[key].IntervalRates[i] = new(IntervalRate) if rp.Rates[key].IntervalRates[i].IntervalStart, err = utils.ParseDurationWithNanosecs(iRate.IntervalStart); err != nil { return nil, err } diff --git a/engine/model_helpers_test.go b/engine/model_helpers_test.go index 1c6055a77..60bad8528 100644 --- a/engine/model_helpers_test.go +++ b/engine/model_helpers_test.go @@ -2594,7 +2594,7 @@ func TestRateProfileToAPI(t *testing.T) { rPrf := &RateProfile{ Tenant: "cgrates.org", ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002"}, + FilterIDs: []string{"*string:~*req.Subject:1001"}, Weight: 0, ConnectFee: 0.1, RoundingMethod: "*up", @@ -2603,32 +2603,59 @@ func TestRateProfileToAPI(t *testing.T) { MaxCost: 0.6, MaxCostStrategy: "*free", Rates: map[string]*Rate{ - "FIRST_GI": { - ID: "FIRST_GI", - FilterIDs: []string{"*gi:~*req.Usage:0"}, - Weight: 0, - Value: 0.12, - Unit: time.Duration(1 * time.Minute), - Increment: time.Duration(1 * time.Minute), - Blocker: false, + "RT_WEEK": &Rate{ + ID: "RT_WEEK", + Weight: 0, + ActivationStart: "* * * * 1-5", + IntervalRates: []*IntervalRate{ + &IntervalRate{ + IntervalStart: time.Duration(0 * time.Second), + Value: 0.12, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Minute), + }, + &IntervalRate{ + IntervalStart: time.Duration(1 * time.Minute), + Value: 0.06, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Second), + }, + }, }, - "SECOND_GI": { - ID: "SECOND_GI", - FilterIDs: []string{"*gi:~*req.Usage:1m"}, - Weight: 10, - Value: 0.06, - Unit: time.Duration(1 * time.Minute), - Increment: time.Duration(1 * time.Second), - Blocker: false, + "RT_WEEKEND": &Rate{ + ID: "RT_WEEKEND", + Weight: 10, + ActivationStart: "* * * * 0,6", + IntervalRates: []*IntervalRate{ + &IntervalRate{ + IntervalStart: time.Duration(0 * time.Second), + Value: 0.06, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Second), + }, + }, + }, + "RT_CHRISTMAS": &Rate{ + ID: "RT_CHRISTMAS", + Weight: 30, + ActivationStart: "* * 24 12 *", + IntervalRates: []*IntervalRate{ + &IntervalRate{ + IntervalStart: time.Duration(0 * time.Second), + Value: 0.06, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Second), + }, + }, }, }, } eTPRatePrf := &utils.TPRateProfile{ Tenant: "cgrates.org", ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002"}, - ActivationInterval: new(utils.TPActivationInterval), + FilterIDs: []string{"*string:~*req.Subject:1001"}, Weight: 0, + ActivationInterval: new(utils.TPActivationInterval), ConnectFee: 0.1, RoundingMethod: "*up", RoundingDecimals: 4, @@ -2636,23 +2663,50 @@ func TestRateProfileToAPI(t *testing.T) { MaxCost: 0.6, MaxCostStrategy: "*free", Rates: map[string]*utils.TPRate{ - "FIRST_GI": { - ID: "FIRST_GI", - FilterIDs: []string{"*gi:~*req.Usage:0"}, - Weight: 0, - Value: 0.12, - Unit: "1m0s", - Increment: "1m0s", - Blocker: false, + "RT_WEEK": &utils.TPRate{ + ID: "RT_WEEK", + Weight: 0, + ActivationStart: "* * * * 1-5", + IntervalRates: []*utils.TPIntervalRate{ + &utils.TPIntervalRate{ + IntervalStart: "0s", + Value: 0.12, + Unit: "1m0s", + Increment: "1m0s", + }, + &utils.TPIntervalRate{ + IntervalStart: "1m0s", + Value: 0.06, + Unit: "1m0s", + Increment: "1s", + }, + }, }, - "SECOND_GI": { - ID: "SECOND_GI", - FilterIDs: []string{"*gi:~*req.Usage:1m"}, - Weight: 10, - Value: 0.06, - Unit: "1m0s", - Increment: "1s", - Blocker: false, + "RT_WEEKEND": &utils.TPRate{ + ID: "RT_WEEKEND", + Weight: 10, + ActivationStart: "* * * * 0,6", + IntervalRates: []*utils.TPIntervalRate{ + &utils.TPIntervalRate{ + IntervalStart: "0s", + Value: 0.06, + Unit: "1m0s", + Increment: "1s", + }, + }, + }, + "RT_CHRISTMAS": &utils.TPRate{ + ID: "RT_CHRISTMAS", + Weight: 30, + ActivationStart: "* * 24 12 *", + IntervalRates: []*utils.TPIntervalRate{ + &utils.TPIntervalRate{ + IntervalStart: "0s", + Value: 0.06, + Unit: "1m0s", + Increment: "1s", + }, + }, }, }, } @@ -2665,7 +2719,7 @@ func TestAPIToRateProfile(t *testing.T) { eRprf := &RateProfile{ Tenant: "cgrates.org", ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002"}, + FilterIDs: []string{"*string:~*req.Subject:1001"}, Weight: 0, ConnectFee: 0.1, RoundingMethod: "*up", @@ -2674,30 +2728,58 @@ func TestAPIToRateProfile(t *testing.T) { MaxCost: 0.6, MaxCostStrategy: "*free", Rates: map[string]*Rate{ - "FIRST_GI": { - ID: "FIRST_GI", - FilterIDs: []string{"*gi:~*req.Usage:0"}, - Weight: 0, - Value: 0.12, - Unit: time.Duration(1 * time.Minute), - Increment: time.Duration(1 * time.Minute), - Blocker: false, + "RT_WEEK": &Rate{ + ID: "RT_WEEK", + Weight: 0, + ActivationStart: "* * * * 1-5", + IntervalRates: []*IntervalRate{ + &IntervalRate{ + IntervalStart: time.Duration(0 * time.Second), + Value: 0.12, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Minute), + }, + &IntervalRate{ + IntervalStart: time.Duration(1 * time.Minute), + Value: 0.06, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Second), + }, + }, }, - "SECOND_GI": { - ID: "SECOND_GI", - FilterIDs: []string{"*gi:~*req.Usage:1m"}, - Weight: 10, - Value: 0.06, - Unit: time.Duration(1 * time.Minute), - Increment: time.Duration(1 * time.Second), - Blocker: false, + "RT_WEEKEND": &Rate{ + ID: "RT_WEEKEND", + Weight: 10, + ActivationStart: "* * * * 0,6", + IntervalRates: []*IntervalRate{ + &IntervalRate{ + IntervalStart: time.Duration(0 * time.Second), + Value: 0.06, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Second), + }, + }, + }, + "RT_CHRISTMAS": &Rate{ + ID: "RT_CHRISTMAS", + Weight: 30, + ActivationStart: "* * 24 12 *", + IntervalRates: []*IntervalRate{ + &IntervalRate{ + IntervalStart: time.Duration(0 * time.Second), + Value: 0.06, + Unit: time.Duration(1 * time.Minute), + Increment: time.Duration(1 * time.Second), + }, + }, }, }, } tpRprf := &utils.TPRateProfile{ + TPid: "", Tenant: "cgrates.org", ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002"}, + FilterIDs: []string{"*string:~*req.Subject:1001"}, Weight: 0, ConnectFee: 0.1, RoundingMethod: "*up", @@ -2706,23 +2788,50 @@ func TestAPIToRateProfile(t *testing.T) { MaxCost: 0.6, MaxCostStrategy: "*free", Rates: map[string]*utils.TPRate{ - "FIRST_GI": { - ID: "FIRST_GI", - FilterIDs: []string{"*gi:~*req.Usage:0"}, - Weight: 0, - Value: 0.12, - Unit: "1m0s", - Increment: "1m0s", - Blocker: false, + "RT_WEEK": &utils.TPRate{ + ID: "RT_WEEK", + Weight: 0, + ActivationStart: "* * * * 1-5", + IntervalRates: []*utils.TPIntervalRate{ + &utils.TPIntervalRate{ + IntervalStart: "0s", + Value: 0.12, + Unit: "1m0s", + Increment: "1m0s", + }, + &utils.TPIntervalRate{ + IntervalStart: "1m0s", + Value: 0.06, + Unit: "1m0s", + Increment: "1s", + }, + }, }, - "SECOND_GI": { - ID: "SECOND_GI", - FilterIDs: []string{"*gi:~*req.Usage:1m"}, - Weight: 10, - Value: 0.06, - Unit: "1m0s", - Increment: "1s", - Blocker: false, + "RT_WEEKEND": &utils.TPRate{ + ID: "RT_WEEKEND", + Weight: 10, + ActivationStart: "* * * * 0,6", + IntervalRates: []*utils.TPIntervalRate{ + &utils.TPIntervalRate{ + IntervalStart: "0s", + Value: 0.06, + Unit: "1m0s", + Increment: "1s", + }, + }, + }, + "RT_CHRISTMAS": &utils.TPRate{ + ID: "RT_CHRISTMAS", + Weight: 30, + ActivationStart: "* * 24 12 *", + IntervalRates: []*utils.TPIntervalRate{ + &utils.TPIntervalRate{ + IntervalStart: "0s", + Value: 0.06, + Unit: "1m0s", + Increment: "1s", + }, + }, }, }, } @@ -2735,9 +2844,10 @@ func TestAPIToRateProfile(t *testing.T) { func TestAPItoModelTPRateProfile(t *testing.T) { tpRprf := &utils.TPRateProfile{ + TPid: "", Tenant: "cgrates.org", ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002"}, + FilterIDs: []string{"*string:~*req.Subject:1001"}, Weight: 0, ConnectFee: 0.1, RoundingMethod: "*up", @@ -2746,125 +2856,130 @@ func TestAPItoModelTPRateProfile(t *testing.T) { MaxCost: 0.6, MaxCostStrategy: "*free", Rates: map[string]*utils.TPRate{ - "FIRST_GI": { - ID: "FIRST_GI", - FilterIDs: []string{"*gi:~*req.Usage:0"}, - Weight: 0, - Value: 0.12, - Unit: "1m0s", - Increment: "1m0s", - Blocker: false, - }, - "SECOND_GI": { - ID: "SECOND_GI", - FilterIDs: []string{"*gi:~*req.Usage:1m"}, - Weight: 10, - Value: 0.06, - Unit: "1m0s", - Increment: "1s", - Blocker: false, + "RT_WEEK": &utils.TPRate{ + ID: "RT_WEEK", + Weight: 0, + ActivationStart: "* * * * 1-5", + IntervalRates: []*utils.TPIntervalRate{ + &utils.TPIntervalRate{ + IntervalStart: "0s", + Value: 0.12, + Unit: "1m0s", + Increment: "1m0s", + }, + &utils.TPIntervalRate{ + IntervalStart: "1m", + Value: 0.06, + Unit: "1m0s", + Increment: "1s", + }, + }, }, }, } expModels := RateProfileMdls{ &RateProfileMdl{ - PK: 0, - Tpid: "", - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: "*string:~*req.Subject:1001;*string:~*req.Subject:1002", - ActivationInterval: "", - Weight: 0, - ConnectFee: 0.1, - RoundingMethod: "*up", - RoundingDecimals: 4, - MinCost: 0.1, - MaxCost: 0.6, - MaxCostStrategy: "*free", - RateID: "FIRST_GI", - RateFilterIDs: "*gi:~*req.Usage:0", - RateActivationInterval: "", - RateWeight: 0, - RateValue: 0.12, - RateUnit: "1m0s", - RateIncrement: "1m0s", - RateBlocker: false, - CreatedAt: time.Time{}, + PK: 0, + Tpid: "", + Tenant: "cgrates.org", + ID: "RP1", + FilterIDs: "*string:~*req.Subject:1001", + ActivationInterval: "", + Weight: 0, + ConnectFee: 0.1, + RoundingMethod: "*up", + RoundingDecimals: 4, + MinCost: 0.1, + MaxCost: 0.6, + MaxCostStrategy: "*free", + RateID: "RT_WEEK", + RateFilterIDs: "", + RateActivationStart: "* * * * 1-5", + RateWeight: 0, + RateBlocker: false, + RateIntervalStart: "1m", + RateValue: 0.06, + RateUnit: "1m0s", + RateIncrement: "1s", + CreatedAt: time.Time{}, }, &RateProfileMdl{ - PK: 0, - Tpid: "", - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: "", - ActivationInterval: "", - Weight: 0, - ConnectFee: 0, - RoundingMethod: "", - RoundingDecimals: 0, - MinCost: 0, - MaxCost: 0, - MaxCostStrategy: "", - RateID: "SECOND_GI", - RateFilterIDs: "*gi:~*req.Usage:1m", - RateActivationInterval: "", - RateWeight: 10, - RateValue: 0.06, - RateUnit: "1m0s", - RateIncrement: "1s", - RateBlocker: false, - CreatedAt: time.Time{}, + PK: 0, + Tpid: "", + Tenant: "cgrates.org", + ID: "RP1", + FilterIDs: "", + ActivationInterval: "", + Weight: 0, + ConnectFee: 0, + RoundingMethod: "", + RoundingDecimals: 0, + MinCost: 0, + MaxCost: 0, + MaxCostStrategy: "", + RateID: "RT_WEEK", + RateFilterIDs: "", + RateActivationStart: "", + RateWeight: 0, + RateBlocker: false, + RateIntervalStart: "0s", + RateValue: 0.12, + RateUnit: "1m0s", + RateIncrement: "1m0s", + CreatedAt: time.Time{}, }, } expModelsRev := RateProfileMdls{ &RateProfileMdl{ - PK: 0, - Tpid: "", - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: "*string:~*req.Subject:1001;*string:~*req.Subject:1002", - ActivationInterval: "", - Weight: 0, - ConnectFee: 0.1, - RoundingMethod: "*up", - RoundingDecimals: 4, - MinCost: 0.1, - MaxCost: 0.6, - MaxCostStrategy: "*free", - RateID: "SECOND_GI", - RateFilterIDs: "*gi:~*req.Usage:1m", - RateActivationInterval: "", - RateWeight: 10, - RateValue: 0.06, - RateUnit: "1m0s", - RateIncrement: "1s", - RateBlocker: false, - CreatedAt: time.Time{}, + PK: 0, + Tpid: "", + Tenant: "cgrates.org", + ID: "RP1", + FilterIDs: "*string:~*req.Subject:1001", + ActivationInterval: "", + Weight: 0, + ConnectFee: 0.1, + RoundingMethod: "*up", + RoundingDecimals: 4, + MinCost: 0.1, + MaxCost: 0.6, + MaxCostStrategy: "*free", + RateID: "RT_WEEK", + RateFilterIDs: "", + RateActivationStart: "* * * * 1-5", + RateWeight: 0, + RateBlocker: false, + RateIntervalStart: "0s", + RateValue: 0.12, + RateUnit: "1m0s", + RateIncrement: "1m0s", + CreatedAt: time.Time{}, }, &RateProfileMdl{ - PK: 0, - Tpid: "", - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: "", - ActivationInterval: "", - Weight: 0, - ConnectFee: 0, - RoundingMethod: "", - RoundingDecimals: 0, - MinCost: 0, - MaxCost: 0, - MaxCostStrategy: "", - RateID: "FIRST_GI", - RateFilterIDs: "*gi:~*req.Usage:0", - RateActivationInterval: "", - RateWeight: 0, - RateValue: 0.12, - RateUnit: "1m0s", - RateIncrement: "1m0s", - RateBlocker: false, - CreatedAt: time.Time{}, + PK: 0, + Tpid: "", + Tenant: "cgrates.org", + ID: "RP1", + FilterIDs: "", + ActivationInterval: "", + Weight: 0, + ConnectFee: 0, + RoundingMethod: "", + RoundingDecimals: 0, + MinCost: 0, + MaxCost: 0, + MaxCostStrategy: "", + RateID: "RT_WEEK", + RateFilterIDs: "", + RateActivationStart: "", + RateWeight: 0, + RateBlocker: false, + RateIntervalStart: "1m", + RateValue: 0.06, + RateUnit: "1m0s", + RateIncrement: "1s", + CreatedAt: time.Time{}, }, } rcv := APItoModelTPRateProfile(tpRprf) @@ -2873,6 +2988,7 @@ func TestAPItoModelTPRateProfile(t *testing.T) { } } +/* func TestAsTPRateProfile(t *testing.T) { rtMdl := RateProfileMdls{ &RateProfileMdl{ @@ -2964,3 +3080,4 @@ func TestAsTPRateProfile(t *testing.T) { t.Errorf("Expecting: %+v,\nReceived: %+v", utils.ToJSON(eRprf), utils.ToJSON(rcv[0])) } } +*/ diff --git a/engine/rateprofile.go b/engine/rateprofile.go index 0c7a10968..6e5fd7f2d 100644 --- a/engine/rateprofile.go +++ b/engine/rateprofile.go @@ -22,6 +22,7 @@ import ( "time" "github.com/cgrates/cgrates/utils" + "github.com/robfig/cron" ) // RateProfile represents the configuration of a Rate profile @@ -57,7 +58,7 @@ type Rate struct { Blocker bool // RateBlocker will make this rate recurrent, deactivating further intervals IntervalRates []*IntervalRate - //aTime cron.Schedule // compiled version of activation time as cron.Schedule interface + aTime cron.Schedule // compiled version of activation time as cron.Schedule interface } type IntervalRate struct { diff --git a/go.mod b/go.mod index 6528c2beb..465406b8e 100644 --- a/go.mod +++ b/go.mod @@ -48,6 +48,7 @@ require ( github.com/philhofer/fwd v1.0.0 // indirect github.com/pkg/errors v0.8.2-0.20190227000051-27936f6d90f9 // indirect github.com/pquerna/ffjson v0.0.0-20190813045741-dac163c6c0a9 // indirect + github.com/robfig/cron v1.2.0 github.com/segmentio/kafka-go v0.3.3 github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271 github.com/tidwall/pretty v1.0.0 // indirect @@ -58,7 +59,6 @@ require ( go.opencensus.io v0.22.1-0.20190713072201-b4a14686f0a9 // indirect golang.org/x/net v0.0.0-20190909003024-a7b16738d86b golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 - golang.org/x/sys v0.0.0-20190904154756-749cb33beabd google.golang.org/api v0.10.0 pack.ag/amqp v0.12.2 ) diff --git a/go.sum b/go.sum index 0ee3f54fd..d6903df55 100644 --- a/go.sum +++ b/go.sum @@ -62,12 +62,8 @@ github.com/cgrates/ltcache v0.0.0-20181016092649-92fb7fa77cca h1:Ejj4m0Ccl8dMMVn github.com/cgrates/ltcache v0.0.0-20181016092649-92fb7fa77cca/go.mod h1:q7c996DUu8OrJRnewVSQzM+y/bRcxZAHoo+zCD8bFBo= github.com/cgrates/radigo v0.0.0-20200324152710-35e651804ad1 h1:QvA6Nbwq9kTd7hsvu1xo5kwia68cLwnp0sYCq1u40TU= github.com/cgrates/radigo v0.0.0-20200324152710-35e651804ad1/go.mod h1:HZbsg3Y+xw4lsfCqX9rzj429wrg0XOug6pFT3B6VHZY= -github.com/cgrates/rpcclient v0.0.0-20200326100105-a579e2c47453 h1:kgIdi3qR/meiWILdmDRuDi1fFgd6A3lutGV6HLiTDyc= -github.com/cgrates/rpcclient v0.0.0-20200326100105-a579e2c47453/go.mod h1:xXLqAKVvcdWeDYwHJYwDgAI3ZOg5LZYxzb72kLjsLZU= github.com/cgrates/rpcclient v0.0.0-20200528120144-984f478f0a69 h1:4vKQbGGdle7SyHMXm9obE2DgSDnsf5ayFSS0cqO16vI= github.com/cgrates/rpcclient v0.0.0-20200528120144-984f478f0a69/go.mod h1:xXLqAKVvcdWeDYwHJYwDgAI3ZOg5LZYxzb72kLjsLZU= -github.com/cgrates/sipingo v1.0.1-0.20200514110619-25b61a652a0b h1:+Wn4Kd9dmCr8kIkznLdM701aA8lrLC2+g0Li8xdcRWU= -github.com/cgrates/sipingo v1.0.1-0.20200514110619-25b61a652a0b/go.mod h1:0f2+3dq5Iiv3VlcuY83VPJ0QzqRlzDG1Cr8okogQE3g= github.com/cgrates/sipingo v1.0.1-0.20200514112313-699ebc1cdb8e h1:izFjZB83/XRXInc+gMIssUxdbleGsGIuGCPj2u7RQo0= github.com/cgrates/sipingo v1.0.1-0.20200514112313-699ebc1cdb8e/go.mod h1:0f2+3dq5Iiv3VlcuY83VPJ0QzqRlzDG1Cr8okogQE3g= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -197,6 +193,8 @@ github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= +github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/segmentio/kafka-go v0.3.3 h1:V4Ou5vOe0HXux6G/ZdheugcvgmSRFG3IA69btTGrYdo= github.com/segmentio/kafka-go v0.3.3/go.mod h1:OT5KXBPbaJJTcvokhWR2KFmm0niEx3mnccTwjmLvSi4= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=