From f5e7c522bfff0c1604050d10ec3936d38e82a4b2 Mon Sep 17 00:00:00 2001 From: porosnicuadrian Date: Fri, 12 Feb 2021 18:07:09 +0200 Subject: [PATCH] New fields in accountProfile - Opts and Weights as DynamicWeights --- apier/v1/accountprofiles_it_test.go | 107 ++++++++------- apier/v1/accountsv1_it_test.go | 122 +++++++++++------- apier/v1/full_remote_it_test.go | 111 +++++++++------- apier/v1/tpaccountprofiles_it_test.go | 40 +++--- console/accounts_profile_set.go | 2 +- data/tariffplans/testit/AccountProfiles.csv | 6 +- .../tutaccounts/AccountProfiles.csv | 10 +- engine/libtest.go | 6 +- engine/loader_csv_test.go | 24 ++-- engine/model_helpers.go | 31 +++-- engine/model_helpers_test.go | 84 +++++++----- engine/models.go | 27 ++-- engine/z_onstor_it_test.go | 14 +- engine/z_stordb_it_test.go | 14 +- general_tests/export_it_test.go | 16 ++- utils/accountprofile.go | 37 ++++-- utils/accountprofile_test.go | 60 ++++++--- utils/apitpdata.go | 4 +- 18 files changed, 425 insertions(+), 290 deletions(-) diff --git a/apier/v1/accountprofiles_it_test.go b/apier/v1/accountprofiles_it_test.go index 604aba3c4..1232243f2 100644 --- a/apier/v1/accountprofiles_it_test.go +++ b/apier/v1/accountprofiles_it_test.go @@ -133,10 +133,14 @@ func testAccountSGetAccountProfile(t *testing.T) { FilterIDs: []string{"*string:~*req.Account:1001"}, Balances: map[string]*utils.Balance{ "GenericBalance1": &utils.Balance{ - ID: "GenericBalance1", - Weight: 20, - Type: utils.MetaAbstract, - Units: &utils.Decimal{decimal.New(int64(time.Hour), 0)}, + ID: "GenericBalance1", + Weights: []*utils.DynamicWeight{ + { + Weight: 20, + }, + }, + Type: utils.MetaAbstract, + Units: &utils.Decimal{decimal.New(int64(time.Hour), 0)}, UnitFactors: []*utils.UnitFactor{ &utils.UnitFactor{ FilterIDs: []string{"*string:~*req.ToR:*data"}, @@ -159,10 +163,14 @@ func testAccountSGetAccountProfile(t *testing.T) { }, }, "MonetaryBalance1": &utils.Balance{ - ID: "MonetaryBalance1", - Weight: 30, - Type: utils.MetaConcrete, - Units: &utils.Decimal{decimal.New(5, 0)}, + ID: "MonetaryBalance1", + Weights: utils.DynamicWeights{ + { + Weight: 30, + }, + }, + Type: utils.MetaConcrete, + Units: &utils.Decimal{decimal.New(5, 0)}, CostIncrements: []*utils.CostIncrement{ &utils.CostIncrement{ FilterIDs: []string{"*string:~*req.ToR:*voice"}, @@ -179,10 +187,14 @@ func testAccountSGetAccountProfile(t *testing.T) { }, }, "MonetaryBalance2": &utils.Balance{ - ID: "MonetaryBalance2", - Weight: 10, - Type: utils.MetaConcrete, - Units: &utils.Decimal{decimal.New(3, 0)}, + ID: "MonetaryBalance2", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, + Type: utils.MetaConcrete, + Units: &utils.Decimal{decimal.New(3, 0)}, CostIncrements: []*utils.CostIncrement{ &utils.CostIncrement{ FilterIDs: []string{"*string:~*req.ToR:*voice"}, @@ -215,47 +227,44 @@ func testAccountSPing(t *testing.T) { func testAccountSSettAccountProfile(t *testing.T) { apiAccPrf = &APIAccountProfileWithCache{ - APIAccountProfileWithOpts: &utils.APIAccountProfileWithOpts{ - APIAccountProfile: &utils.APIAccountProfile{ - Tenant: "cgrates.org", - ID: "id_test", - Weight: 10, - Balances: map[string]*utils.APIBalance{ - "MonetaryBalance": &utils.APIBalance{ - ID: "MonetaryBalance", - Weight: 10, - Type: utils.MetaMonetary, - CostIncrements: []*utils.APICostIncrement{ - { - FilterIDs: []string{"fltr1", "fltr2"}, - Increment: utils.Float64Pointer(1.3), - FixedFee: utils.Float64Pointer(2.3), - RecurrentFee: utils.Float64Pointer(3.3), - }, + APIAccountProfile: &utils.APIAccountProfile{ + Tenant: "cgrates.org", + ID: "id_test", + Weights: ";10", + Balances: map[string]*utils.APIBalance{ + "MonetaryBalance": &utils.APIBalance{ + ID: "MonetaryBalance", + Weights: ";10", + Type: utils.MetaMonetary, + CostIncrements: []*utils.APICostIncrement{ + { + FilterIDs: []string{"fltr1", "fltr2"}, + Increment: utils.Float64Pointer(1.3), + FixedFee: utils.Float64Pointer(2.3), + RecurrentFee: utils.Float64Pointer(3.3), }, - AttributeIDs: []string{"attr1", "attr2"}, - UnitFactors: []*utils.APIUnitFactor{ - { - FilterIDs: []string{"fltr1", "fltr2"}, - Factor: 100, - }, - { - FilterIDs: []string{"fltr3"}, - Factor: 200, - }, + }, + AttributeIDs: []string{"attr1", "attr2"}, + UnitFactors: []*utils.APIUnitFactor{ + { + FilterIDs: []string{"fltr1", "fltr2"}, + Factor: 100, + }, + { + FilterIDs: []string{"fltr3"}, + Factor: 200, }, - Units: 14, - }, - "VoiceBalance": &utils.APIBalance{ - ID: "VoiceBalance", - Weight: 10, - Type: utils.MetaVoice, - Units: 3600000000000, }, + Units: 14, + }, + "VoiceBalance": &utils.APIBalance{ + ID: "VoiceBalance", + Weights: ";10", + Type: utils.MetaVoice, + Units: 3600000000000, }, - ThresholdIDs: []string{utils.MetaNone}, }, - Opts: map[string]interface{}{}, + ThresholdIDs: []string{utils.MetaNone}, }, } var result string @@ -321,7 +330,7 @@ func testAccountSGetAccountProfileIDsCount(t *testing.T) { func testAccountSUpdateAccountProfile(t *testing.T) { var reply string - apiAccPrf.Weight = 2 + apiAccPrf.Weights = ";2" apiAccPrf.Balances["MonetaryBalance"].CostIncrements[0].FixedFee = utils.Float64Pointer(123.5) if err := accSRPC.Call(utils.APIerSv1SetAccountProfile, apiAccPrf, &reply); err != nil { t.Error(err) diff --git a/apier/v1/accountsv1_it_test.go b/apier/v1/accountsv1_it_test.go index 1b9d417c7..0eba76ab5 100644 --- a/apier/v1/accountsv1_it_test.go +++ b/apier/v1/accountsv1_it_test.go @@ -123,14 +123,16 @@ func testAccountSv1AccountProfileForEvent(t *testing.T) { Tenant: "cgrates.org", ID: "1001", FilterIDs: []string{"*string:~*req.Account:1001"}, - Opts: make(map[string]interface{}), Balances: map[string]*utils.Balance{ "GenericBalance1": &utils.Balance{ - ID: "GenericBalance1", - Weight: 20, - Type: utils.MetaAbstract, - Units: &utils.Decimal{decimal.New(int64(time.Hour), 0)}, - Opts: make(map[string]interface{}), + ID: "GenericBalance1", + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, + Type: utils.MetaAbstract, + Units: &utils.Decimal{decimal.New(int64(time.Hour), 0)}, UnitFactors: []*utils.UnitFactor{ &utils.UnitFactor{ FilterIDs: []string{"*string:~*req.ToR:*data"}, @@ -153,11 +155,14 @@ func testAccountSv1AccountProfileForEvent(t *testing.T) { }, }, "MonetaryBalance1": &utils.Balance{ - ID: "MonetaryBalance1", - Weight: 30, - Type: utils.MetaConcrete, - Opts: make(map[string]interface{}), - Units: &utils.Decimal{decimal.New(5, 0)}, + ID: "MonetaryBalance1", + Weights: utils.DynamicWeights{ + { + Weight: 30, + }, + }, + Type: utils.MetaConcrete, + Units: &utils.Decimal{decimal.New(5, 0)}, CostIncrements: []*utils.CostIncrement{ &utils.CostIncrement{ FilterIDs: []string{"*string:~*req.ToR:*voice"}, @@ -174,11 +179,14 @@ func testAccountSv1AccountProfileForEvent(t *testing.T) { }, }, "MonetaryBalance2": &utils.Balance{ - ID: "MonetaryBalance2", - Weight: 10, - Type: utils.MetaConcrete, - Opts: make(map[string]interface{}), - Units: &utils.Decimal{decimal.New(3, 0)}, + ID: "MonetaryBalance2", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, + Type: utils.MetaConcrete, + Units: &utils.Decimal{decimal.New(3, 0)}, CostIncrements: []*utils.CostIncrement{ &utils.CostIncrement{ FilterIDs: []string{"*string:~*req.ToR:*voice"}, @@ -226,14 +234,16 @@ func testAccountSv1MaxUsage(t *testing.T) { Tenant: "cgrates.org", ID: "1001", FilterIDs: []string{"*string:~*req.Account:1001"}, - Opts: make(map[string]interface{}), Balances: map[string]*utils.Balance{ "GenericBalance1": &utils.Balance{ - ID: "GenericBalance1", - Weight: 20, - Type: utils.MetaAbstract, - Opts: make(map[string]interface{}), - Units: &utils.Decimal{decimal.New(int64(time.Hour), 0)}, + ID: "GenericBalance1", + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, + Type: utils.MetaAbstract, + Units: &utils.Decimal{decimal.New(int64(time.Hour), 0)}, UnitFactors: []*utils.UnitFactor{ &utils.UnitFactor{ FilterIDs: []string{"*string:~*req.ToR:*data"}, @@ -256,11 +266,14 @@ func testAccountSv1MaxUsage(t *testing.T) { }, }, "MonetaryBalance1": &utils.Balance{ - ID: "MonetaryBalance1", - Weight: 30, - Type: utils.MetaConcrete, - Opts: make(map[string]interface{}), - Units: &utils.Decimal{decimal.New(5, 0)}, + ID: "MonetaryBalance1", + Weights: utils.DynamicWeights{ + { + Weight: 30, + }, + }, + Type: utils.MetaConcrete, + Units: &utils.Decimal{decimal.New(5, 0)}, CostIncrements: []*utils.CostIncrement{ &utils.CostIncrement{ FilterIDs: []string{"*string:~*req.ToR:*voice"}, @@ -277,11 +290,14 @@ func testAccountSv1MaxUsage(t *testing.T) { }, }, "MonetaryBalance2": &utils.Balance{ - ID: "MonetaryBalance2", - Weight: 10, - Type: utils.MetaConcrete, - Opts: make(map[string]interface{}), - Units: &utils.Decimal{decimal.New(3, 0)}, + ID: "MonetaryBalance2", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, + Type: utils.MetaConcrete, + Units: &utils.Decimal{decimal.New(3, 0)}, CostIncrements: []*utils.CostIncrement{ &utils.CostIncrement{ FilterIDs: []string{"*string:~*req.ToR:*voice"}, @@ -317,7 +333,7 @@ func testAccountSv1DebitUsage(t *testing.T) { }}}, &eEc); err != nil { t.Error(err) } else if eEc.Usage == nil || *eEc.Usage != 800000000000.0 { // 500s from first monetary + 300s from last monetary - t.Errorf("received usage: %v", *eEc.Usage) + t.Fatalf("received usage: %v", *eEc.Usage) } // Make sure we did not Debit anything from Account @@ -325,14 +341,16 @@ func testAccountSv1DebitUsage(t *testing.T) { Tenant: "cgrates.org", ID: "1001", FilterIDs: []string{"*string:~*req.Account:1001"}, - Opts: make(map[string]interface{}), Balances: map[string]*utils.Balance{ "GenericBalance1": &utils.Balance{ - ID: "GenericBalance1", - Weight: 20, - Type: utils.MetaAbstract, - Opts: make(map[string]interface{}), - Units: &utils.Decimal{decimal.New(int64(3300*time.Second), 0)}, + ID: "GenericBalance1", + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, + Type: utils.MetaAbstract, + Units: &utils.Decimal{decimal.New(int64(3300*time.Second), 0)}, UnitFactors: []*utils.UnitFactor{ &utils.UnitFactor{ FilterIDs: []string{"*string:~*req.ToR:*data"}, @@ -355,11 +373,14 @@ func testAccountSv1DebitUsage(t *testing.T) { }, }, "MonetaryBalance1": &utils.Balance{ - ID: "MonetaryBalance1", - Weight: 30, - Type: utils.MetaConcrete, - Opts: make(map[string]interface{}), - Units: &utils.Decimal{decimal.New(0, 0)}, + ID: "MonetaryBalance1", + Weights: utils.DynamicWeights{ + { + Weight: 30, + }, + }, + Type: utils.MetaConcrete, + Units: &utils.Decimal{decimal.New(0, 0)}, CostIncrements: []*utils.CostIncrement{ &utils.CostIncrement{ FilterIDs: []string{"*string:~*req.ToR:*voice"}, @@ -376,11 +397,14 @@ func testAccountSv1DebitUsage(t *testing.T) { }, }, "MonetaryBalance2": &utils.Balance{ - ID: "MonetaryBalance2", - Weight: 10, - Type: utils.MetaConcrete, - Opts: make(map[string]interface{}), - Units: &utils.Decimal{decimal.New(0, 0)}, + ID: "MonetaryBalance2", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, + Type: utils.MetaConcrete, + Units: &utils.Decimal{decimal.New(0, 0)}, CostIncrements: []*utils.CostIncrement{ &utils.CostIncrement{ FilterIDs: []string{"*string:~*req.ToR:*voice"}, diff --git a/apier/v1/full_remote_it_test.go b/apier/v1/full_remote_it_test.go index 64023d311..2737d005a 100644 --- a/apier/v1/full_remote_it_test.go +++ b/apier/v1/full_remote_it_test.go @@ -27,12 +27,9 @@ import ( "testing" "time" - "github.com/ericlagergren/decimal" - + "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" - - "github.com/cgrates/cgrates/config" ) var ( @@ -51,7 +48,6 @@ var ( testFullRemoteITDataFlush, testFullRemoteITStartEngine, testFullRemoteITRPCConn, - testFullRemoteITAttribute, testFullRemoteITStatQueue, testFullRemoteITThreshold, @@ -63,7 +59,6 @@ var ( testFullRemoteITRate, testFullRemoteITAction, testFullRemoteITAccount, - testFullRemoteITKillEngine, } ) @@ -764,73 +759,95 @@ func testFullRemoteITAccount(t *testing.T) { t.Fatal(err) } - var replySet string - accPrf := &utils.AccountProfile{ - Tenant: "cgrates.org", - ID: "1001", - Weight: 20, - Balances: map[string]*utils.Balance{ - "MonetaryBalance": &utils.Balance{ - ID: "MonetaryBalance", - Weight: 10, - Type: utils.MetaMonetary, - CostIncrements: []*utils.CostIncrement{ - &utils.CostIncrement{ - FilterIDs: []string{"fltr1", "fltr2"}, - Increment: &utils.Decimal{decimal.New(13, 1)}, - FixedFee: &utils.Decimal{decimal.New(23, 1)}, - RecurrentFee: &utils.Decimal{decimal.New(33, 1)}, - }, - }, - AttributeIDs: []string{"attr1", "attr2"}, - UnitFactors: []*utils.UnitFactor{ - &utils.UnitFactor{ - FilterIDs: []string{"fltr1", "fltr2"}, - Factor: &utils.Decimal{decimal.New(100, 0)}, - }, - &utils.UnitFactor{ - FilterIDs: []string{"fltr3"}, - Factor: &utils.Decimal{decimal.New(200, 0)}, - }, - }, - Units: &utils.Decimal{decimal.New(14, 0)}, + apiAccPrf := &APIAccountProfileWithCache{ + APIAccountProfile: &utils.APIAccountProfile{ + Tenant: "cgrates.org", + ID: "1001", + Weights: ";20", + Opts: map[string]interface{}{ + "TEST0": 2., }, - "VoiceBalance": &utils.Balance{ - ID: "VoiceBalance", - Weight: 10, - Type: utils.MetaVoice, - Units: &utils.Decimal{decimal.New(3600000000000, 0)}, + Balances: map[string]*utils.APIBalance{ + "MonetaryBalance": { + ID: "MonetaryBalance", + Weights: ";10", + Type: utils.MetaMonetary, + Opts: map[string]interface{}{ + "TEST1": 5., + }, + CostIncrements: []*utils.APICostIncrement{ + { + FilterIDs: []string{"fltr1", "fltr2"}, + Increment: utils.Float64Pointer(1.3), + FixedFee: utils.Float64Pointer(2.3), + RecurrentFee: utils.Float64Pointer(3.3), + }, + }, + AttributeIDs: []string{"attr1", "attr2"}, + UnitFactors: []*utils.APIUnitFactor{ + { + FilterIDs: []string{"fltr1", "fltr2"}, + Factor: 100, + }, + { + FilterIDs: []string{"fltr3"}, + Factor: 200, + }, + }, + Units: 14, + }, + "VoiceBalance": { + ID: "VoiceBalance", + Weights: ";10", + Type: utils.MetaVoice, + Opts: map[string]interface{}{}, + Units: 3600000000000, + }, }, + ThresholdIDs: []string{utils.MetaNone}, }, - ThresholdIDs: []string{utils.MetaNone}, } + var replySet string + // add a threshold profile in engine1 and verify it internal - if err := fullRemEngineOneRPC.Call(utils.APIerSv1SetAccountProfile, accPrf, &replySet); err != nil { + if err := fullRemEngineOneRPC.Call(utils.APIerSv1SetAccountProfile, apiAccPrf, &replySet); err != nil { t.Error(err) } else if replySet != utils.OK { t.Error("Unexpected reply returned", replySet) } + accPrf, err := apiAccPrf.AsAccountProfile() + if err != nil { + t.Error(err) + } + if err := fullRemInternalRPC.Call(utils.APIerSv1GetAccountProfile, utils.TenantIDWithOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "1001"}}, &reply); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(accPrf, reply) { - t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(accPrf), utils.ToJSON(reply)) + t.Errorf("Expecting : %+v \n, received: %+v", utils.ToJSON(accPrf), utils.ToJSON(reply)) } + // update the threshold profile and verify it to be updated - accPrf.FilterIDs = []string{"*string:~*req.Account:1001", "*string:~*req.Destination:1002"} - if err := fullRemEngineOneRPC.Call(utils.APIerSv1SetAccountProfile, accPrf, &replySet); err != nil { + apiAccPrf.FilterIDs = []string{"*string:~*req.Account:1001", "*string:~*req.Destination:1002"} + if err := fullRemEngineOneRPC.Call(utils.APIerSv1SetAccountProfile, apiAccPrf, &replySet); err != nil { t.Error(err) } else if replySet != utils.OK { t.Error("Unexpected reply returned", replySet) } + + accPrf, err = apiAccPrf.AsAccountProfile() + if err != nil { + t.Error(err) + } + if err := fullRemInternalRPC.Call(utils.APIerSv1GetAccountProfile, utils.TenantIDWithOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "1001"}}, &reply); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(accPrf, reply) { - t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(accPrf), utils.ToJSON(reply)) + t.Errorf("Expecting : %+v \n, received: %+v", utils.ToJSON(accPrf), utils.ToJSON(reply)) } } diff --git a/apier/v1/tpaccountprofiles_it_test.go b/apier/v1/tpaccountprofiles_it_test.go index c36b3cfee..24680ab3b 100644 --- a/apier/v1/tpaccountprofiles_it_test.go +++ b/apier/v1/tpaccountprofiles_it_test.go @@ -120,16 +120,16 @@ func testTPAcctPrfGetTPAcctPrfBeforeSet(t *testing.T) { func testTPAcctPrfSetTPAcctPrf(t *testing.T) { tpAcctPrf = &utils.TPAccountProfile{ - TPid: "TP1", - Tenant: "cgrates.org", - ID: "1001", - Weight: 20, + TPid: "TP1", + Tenant: "cgrates.org", + ID: "1001", + Weights: ";20", Balances: map[string]*utils.TPAccountBalance{ "MonetaryBalance": { - ID: "MonetaryBalance", - Weight: 10, - Type: utils.MetaMonetary, - Units: 14, + ID: "MonetaryBalance", + Weights: ";10", + Type: utils.MetaMonetary, + Units: 14, }, }, ThresholdIDs: []string{utils.MetaNone}, @@ -167,10 +167,10 @@ func testTPAcctPrfGetTPAcctPrfIDs(t *testing.T) { func testTPAcctPrfUpdateTPAcctBal(t *testing.T) { tpAcctPrf.Balances = map[string]*utils.TPAccountBalance{ "MonetaryBalance2": { - ID: "MonetaryBalance2", - Weight: 12, - Type: utils.MetaMonetary, - Units: 16, + ID: "MonetaryBalance2", + Weights: ";12", + Type: utils.MetaMonetary, + Units: 16, }, } var result string @@ -184,16 +184,16 @@ func testTPAcctPrfUpdateTPAcctBal(t *testing.T) { func testTPAcctPrfGetTPAcctBalAfterUpdate(t *testing.T) { var reply *utils.TPAccountProfile revTPAcctPrf := &utils.TPAccountProfile{ - TPid: "TP1", - Tenant: "cgrates.org", - ID: "1001", - Weight: 20, + TPid: "TP1", + Tenant: "cgrates.org", + ID: "1001", + Weights: ";20", Balances: map[string]*utils.TPAccountBalance{ "MonetaryBalance2": { - ID: "MonetaryBalance2", - Weight: 12, - Type: utils.MetaMonetary, - Units: 16, + ID: "MonetaryBalance2", + Weights: ";12", + Type: utils.MetaMonetary, + Units: 16, }, }, ThresholdIDs: []string{utils.MetaNone}, diff --git a/console/accounts_profile_set.go b/console/accounts_profile_set.go index 9b605a8a3..5d64dba8d 100644 --- a/console/accounts_profile_set.go +++ b/console/accounts_profile_set.go @@ -50,7 +50,7 @@ func (self *CmdSetAccountProfile) RpcMethod() string { func (self *CmdSetAccountProfile) RpcParams(reset bool) interface{} { if reset || self.rpcParams == nil { - self.rpcParams = &v1.APIAccountProfileWithCache{APIAccountProfileWithOpts: new(utils.APIAccountProfileWithOpts)} + self.rpcParams = &v1.APIAccountProfileWithCache{APIAccountProfile: new(utils.APIAccountProfile)} } return self.rpcParams } diff --git a/data/tariffplans/testit/AccountProfiles.csv b/data/tariffplans/testit/AccountProfiles.csv index ad39191b5..d6947c49a 100644 --- a/data/tariffplans/testit/AccountProfiles.csv +++ b/data/tariffplans/testit/AccountProfiles.csv @@ -1,3 +1,3 @@ -#Tenant,ID,FilterIDs,ActivationInterval,Weight,BalanceID,BalanceFilterIDs,BalanceWeight,BalanceBlocker,BalanceType,BalanceUnits,BalanceUnitFactors,BalanceOpts,BalanceCostIncrements,BalanceAttributeIDs,BalanceRateProfileIDs,ThresholdIDs -cgrates.org,ACC_PRF_1,,,20,MonetaryBalance,,10,,*monetary,14,fltr1&fltr2;100;fltr3;200,,fltr1&fltr2;1.3;2.3;3.3,attr1;attr2,,*none -cgrates.org,1001,,,,VoiceBalance,,10,,*voice,3600000000000,,,,,, \ No newline at end of file +#Tenant,ID,FilterIDs,ActivationInterval,Weights,Opts,BalanceID,BalanceFilterIDs,BalanceWeights,BalanceBlocker,BalanceType,BalanceUnits,BalanceUnitFactors,BalanceOpts,BalanceCostIncrements,BalanceAttributeIDs,BalanceRateProfileIDs,ThresholdIDs +cgrates.org,ACC_PRF_1,,,;20,,MonetaryBalance,,;10,,*monetary,14,fltr1&fltr2;100;fltr3;200,,fltr1&fltr2;1.3;2.3;3.3,attr1;attr2,,*none +cgrates.org,1001,,,,,VoiceBalance,,;10,,*voice,3600000000000,,,,,, \ No newline at end of file diff --git a/data/tariffplans/tutaccounts/AccountProfiles.csv b/data/tariffplans/tutaccounts/AccountProfiles.csv index 37f09fbdd..81ee2e41f 100644 --- a/data/tariffplans/tutaccounts/AccountProfiles.csv +++ b/data/tariffplans/tutaccounts/AccountProfiles.csv @@ -1,5 +1,5 @@ -#Tenant,ID,FilterIDs,ActivationInterval,Weight,BalanceID,BalanceFilterIDs,BalanceWeight,BalanceBlocker,BalanceType,BalanceUnits,BalanceUnitFactors,BalanceOpts,BalanceCostIncrements,BalanceAttributeIDs,BalanceRateProfileIDs,ThresholdIDs -cgrates.org,1001,*string:~*req.Account:1001,,,MonetaryBalance1,,30,,*concrete,5,,,*string:~*req.ToR:*voice;1000000000;0;0.01;*string:~*req.ToR:*data;1024;0;0.01,,,*none -cgrates.org,1001,,,,GenericBalance1,,20,,*abstract,3600000000000,*string:~*req.ToR:*data;1.024,,*string:~*req.ToR:*voice;1000000000;0;0.01;*string:~*req.ToR:*data;1024;0;0.01,,, -cgrates.org,1001,,,,MonetaryBalance2,,10,,*concrete,3,,,*string:~*req.ToR:*voice;1000000000;0;1,,, -cgrates.org,1002,*string:~*req.Account:1002,,10,MonetaryBalance1,,,,*concrete,10,,,*string:~*req.ToR:*voice;1000000000;0;0.01;;1;0;1,,,*none +#Tenant,ID,FilterIDs,ActivationInterval,Weights,Opts,BalanceID,BalanceFilterIDs,BalanceWeights,BalanceBlocker,BalanceType,BalanceUnits,BalanceUnitFactors,BalanceOpts,BalanceCostIncrements,BalanceAttributeIDs,BalanceRateProfileIDs,ThresholdIDs +cgrates.org,1001,*string:~*req.Account:1001,,,,MonetaryBalance1,,;30,,*concrete,5,,,*string:~*req.ToR:*voice;1000000000;0;0.01;*string:~*req.ToR:*data;1024;0;0.01,,,*none +cgrates.org,1001,,,,,GenericBalance1,,;20,,*abstract,3600000000000,*string:~*req.ToR:*data;1.024,,*string:~*req.ToR:*voice;1000000000;0;0.01;*string:~*req.ToR:*data;1024;0;0.01,,, +cgrates.org,1001,,,,,MonetaryBalance2,,;10,,*concrete,3,,,*string:~*req.ToR:*voice;1000000000;0;1,,, +cgrates.org,1002,*string:~*req.Account:1002,,;10,,MonetaryBalance1,,,,*concrete,10,,,*string:~*req.ToR:*voice;1000000000;0;0.01;;1;0;1,,,*none diff --git a/engine/libtest.go b/engine/libtest.go index 1ccf2f165..7bbad59e6 100644 --- a/engine/libtest.go +++ b/engine/libtest.go @@ -298,9 +298,9 @@ cgrates.org,ONE_TIME_ACT,,,,,,,TOPUP_TEST_VOICE,,false,0s,*topup,,~*balance.Test ` AccountProfileCSVContent = ` -#Tenant,ID,FilterIDs,ActivationInterval,Weight,BalanceID,BalanceFilterIDs,BalanceWeight,BalanceBlocker,BalanceType,BalanceUnits,BalanceUnitFactors,BalanceOpts,BalanceCostIncrements,BalanceAttributeIDs,BalanceRateProfileIDs,ThresholdIDs -cgrates.org,1001,,,20,MonetaryBalance,,10,,*monetary,14,fltr1&fltr2;100;fltr3;200,,fltr1&fltr2;1.3;2.3;3.3,attr1;attr2,,*none -cgrates.org,1001,,,,VoiceBalance,,10,,*voice,3600000000000,,,,,, +#Tenant,ID,FilterIDs,ActivationInterval,Weights,Opts,BalanceID,BalanceFilterIDs,BalanceWeights,BalanceBlocker,BalanceType,BalanceUnits,BalanceUnitFactors,BalanceOpts,BalanceCostIncrements,BalanceAttributeIDs,BalanceRateProfileIDs,ThresholdIDs +cgrates.org,1001,,,;20,,MonetaryBalance,,;10,,*monetary,14,fltr1&fltr2;100;fltr3;200,,fltr1&fltr2;1.3;2.3;3.3,attr1;attr2,,*none +cgrates.org,1001,,,,,VoiceBalance,,;10,,*voice,3600000000000,,,,,, ` ) diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 7743a48b4..fffbd3d1f 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -116,7 +116,7 @@ func init() { log.Print("error in LoadActionProfiles: ", err) } if err := csvr.WriteToDatabase(false, false); err != nil { - log.Print("error when writing into database", err) + log.Print("error when writing into database ", err) } } @@ -1603,15 +1603,15 @@ func TestLoadThresholds(t *testing.T) { func TestLoadAccountProfiles(t *testing.T) { expected := &utils.TPAccountProfile{ - TPid: testTPID, - Tenant: "cgrates.org", - ID: "1001", - Weight: 20, + TPid: testTPID, + Tenant: "cgrates.org", + ID: "1001", + Weights: ";20", Balances: map[string]*utils.TPAccountBalance{ "MonetaryBalance": { - ID: "MonetaryBalance", - Weight: 10, - Type: utils.MetaMonetary, + ID: "MonetaryBalance", + Weights: ";10", + Type: utils.MetaMonetary, CostIncrement: []*utils.TPBalanceCostIncrement{ { FilterIDs: []string{"fltr1", "fltr2"}, @@ -1634,10 +1634,10 @@ func TestLoadAccountProfiles(t *testing.T) { Units: 14, }, "VoiceBalance": { - ID: "VoiceBalance", - Weight: 10, - Type: utils.MetaVoice, - Units: 3600000000000, + ID: "VoiceBalance", + Weights: ";10", + Type: utils.MetaVoice, + Units: 3600000000000, }, }, ThresholdIDs: []string{utils.MetaNone}, diff --git a/engine/model_helpers.go b/engine/model_helpers.go index f7b4b716b..4cabc4d8d 100644 --- a/engine/model_helpers.go +++ b/engine/model_helpers.go @@ -3433,6 +3433,7 @@ func (tps AccountProfileMdls) AsTPAccountProfile() (result []*utils.TPAccountPro TPid: tp.Tpid, Tenant: tp.Tenant, ID: tp.ID, + Weights: tp.Weights, Balances: make(map[string]*utils.TPAccountBalance), } } @@ -3458,14 +3459,10 @@ func (tps AccountProfileMdls) AsTPAccountProfile() (result []*utils.TPAccountPro aPrf.ActivationInterval.ActivationTime = aiSplt[0] } } - if tp.Weight != 0 { - aPrf.Weight = tp.Weight - } - if tp.BalanceID != utils.EmptyString { aPrf.Balances[tp.BalanceID] = &utils.TPAccountBalance{ ID: tp.BalanceID, - Weight: tp.BalanceWeight, + Weights: tp.BalanceWeights, Blocker: tp.BalanceBlocker, Type: tp.BalanceType, Opts: tp.BalanceOpts, @@ -3565,7 +3562,7 @@ func APItoModelTPAccountProfile(tPrf *utils.TPAccountProfile) (mdls AccountProfi mdl.ActivationInterval += utils.InfieldSep + tPrf.ActivationInterval.ExpiryTime } } - mdl.Weight = tPrf.Weight + mdl.Weights = tPrf.Weights } mdl.BalanceID = balance.ID for i, val := range balance.FilterIDs { @@ -3575,7 +3572,7 @@ func APItoModelTPAccountProfile(tPrf *utils.TPAccountProfile) (mdls AccountProfi mdl.BalanceFilterIDs += val } mdl.BalanceBlocker = balance.Blocker - mdl.BalanceWeight = balance.Weight + mdl.BalanceWeights = balance.Weights mdl.BalanceType = balance.Type mdl.BalanceOpts = balance.Opts for i, costIncr := range balance.CostIncrement { @@ -3614,10 +3611,16 @@ func APItoAccountProfile(tpAp *utils.TPAccountProfile, timezone string) (ap *uti Tenant: tpAp.Tenant, ID: tpAp.ID, FilterIDs: make([]string, len(tpAp.FilterIDs)), - Weight: tpAp.Weight, Balances: make(map[string]*utils.Balance, len(tpAp.Balances)), ThresholdIDs: make([]string, len(tpAp.ThresholdIDs)), } + if tpAp.Weights != utils.EmptyString { + weight, err := utils.NewDynamicWeightsFromString(tpAp.Weights, ";", "&") + if err != nil { + return nil, err + } + ap.Weights = weight + } for i, stp := range tpAp.FilterIDs { ap.FilterIDs[i] = stp } @@ -3631,7 +3634,6 @@ func APItoAccountProfile(tpAp *utils.TPAccountProfile, timezone string) (ap *uti ap.Balances[id] = &utils.Balance{ ID: bal.ID, FilterIDs: bal.FilterIDs, - Weight: bal.Weight, Blocker: bal.Blocker, Type: bal.Type, Units: utils.NewDecimalFromFloat64(bal.Units), @@ -3647,6 +3649,13 @@ func APItoAccountProfile(tpAp *utils.TPAccountProfile, timezone string) (ap *uti ap.Balances[id].Opts[keyValSls[0]] = keyValSls[1] } } + if bal.Weights != utils.EmptyString { + weight, err := utils.NewDynamicWeightsFromString(bal.Weights, ";", "&") + if err != nil { + return nil, err + } + ap.Balances[id].Weights = weight + } if bal.CostIncrement != nil { ap.Balances[id].CostIncrements = make([]*utils.CostIncrement, len(bal.CostIncrement)) for j, costIncrement := range bal.CostIncrement { @@ -3696,9 +3705,9 @@ func AccountProfileToAPI(ap *utils.AccountProfile) (tpAp *utils.TPAccountProfile tpAp = &utils.TPAccountProfile{ Tenant: ap.Tenant, ID: ap.ID, + Weights: ap.Weights.String(";", "&"), FilterIDs: make([]string, len(ap.FilterIDs)), ActivationInterval: new(utils.TPActivationInterval), - Weight: ap.Weight, Balances: make(map[string]*utils.TPAccountBalance, len(ap.Balances)), ThresholdIDs: make([]string, len(ap.ThresholdIDs)), } @@ -3718,7 +3727,7 @@ func AccountProfileToAPI(ap *utils.AccountProfile) (tpAp *utils.TPAccountProfile tpAp.Balances[i] = &utils.TPAccountBalance{ ID: bal.ID, FilterIDs: make([]string, len(bal.FilterIDs)), - Weight: bal.Weight, + Weights: bal.Weights.String(";", "&"), Blocker: bal.Blocker, Type: bal.Type, CostIncrement: make([]*utils.TPBalanceCostIncrement, len(bal.CostIncrements)), diff --git a/engine/model_helpers_test.go b/engine/model_helpers_test.go index 824e16a3e..209bc4534 100644 --- a/engine/model_helpers_test.go +++ b/engine/model_helpers_test.go @@ -6852,7 +6852,7 @@ func TestAccountProfileMdlsCSVHeader(t *testing.T) { ID: "ResGroup1", FilterIDs: "FLTR_RES_GR1", ActivationInterval: "2014-07-29T15:00:00Z", - Weight: 10.0, + Weights: "10.0", ThresholdIDs: "WARN_RES1;WARN_RES1", }, } @@ -6874,10 +6874,10 @@ func TestAccountProfileMdlsAsTPAccountProfile(t *testing.T) { ID: "ResGroup1", FilterIDs: "FLTR_RES_GR1", ActivationInterval: "2014-07-24T15:00:00Z;2014-07-25T15:00:00Z", - Weight: 10.0, + Weights: "10.0", BalanceID: "VoiceBalance", BalanceFilterIDs: "FLTR_RES_GR2", - BalanceWeight: 10, + BalanceWeights: "10", BalanceBlocker: false, BalanceType: utils.MetaVoice, BalanceUnits: 3600000000000, @@ -6894,12 +6894,12 @@ func TestAccountProfileMdlsAsTPAccountProfile(t *testing.T) { ActivationTime: "2014-07-24T15:00:00Z", ExpiryTime: "2014-07-25T15:00:00Z", }, - Weight: 10.0, + Weights: "10.0", Balances: map[string]*utils.TPAccountBalance{ "VoiceBalance": { ID: "VoiceBalance", FilterIDs: []string{"FLTR_RES_GR2"}, - Weight: 10, + Weights: "10", Type: utils.MetaVoice, Units: 3600000000000, }, @@ -6923,10 +6923,10 @@ func TestAccountProfileMdlsAsTPAccountProfileCase2(t *testing.T) { ID: "ResGroup1", FilterIDs: "FLTR_RES_GR1", ActivationInterval: "2014-07-24T15:00:00Z", - Weight: 10.0, + Weights: "10.0", BalanceID: "VoiceBalance", BalanceFilterIDs: "FLTR_RES_GR2", - BalanceWeight: 10, + BalanceWeights: "10", BalanceBlocker: false, BalanceType: utils.MetaVoice, BalanceUnits: 3600000000000, @@ -6942,12 +6942,12 @@ func TestAccountProfileMdlsAsTPAccountProfileCase2(t *testing.T) { ActivationInterval: &utils.TPActivationInterval{ ActivationTime: "2014-07-24T15:00:00Z", }, - Weight: 10.0, + Weights: "10.0", Balances: map[string]*utils.TPAccountBalance{ "VoiceBalance": { ID: "VoiceBalance", FilterIDs: []string{"FLTR_RES_GR2"}, - Weight: 10, + Weights: "10", Type: utils.MetaVoice, Units: 3600000000000, }, @@ -7009,12 +7009,12 @@ func TestAPItoModelTPAccountProfile(t *testing.T) { ActivationTime: "2014-07-24T15:00:00Z", ExpiryTime: "2014-07-25T15:00:00Z", }, - Weight: 10.0, + Weights: "10.0", Balances: map[string]*utils.TPAccountBalance{ "VoiceBalance": { ID: "VoiceBalance", FilterIDs: []string{"FLTR_RES_GR2"}, - Weight: 10, + Weights: "10", Type: utils.MetaVoice, Units: 3600000000000, CostIncrement: []*utils.TPBalanceCostIncrement{}, @@ -7028,10 +7028,10 @@ func TestAPItoModelTPAccountProfile(t *testing.T) { ID: "ResGroup1", FilterIDs: "FLTR_RES_GR1", ActivationInterval: "2014-07-24T15:00:00Z;2014-07-25T15:00:00Z", - Weight: 10.0, + Weights: "10.0", BalanceID: "VoiceBalance", BalanceFilterIDs: "FLTR_RES_GR2", - BalanceWeight: 10, + BalanceWeights: "10", BalanceBlocker: false, BalanceType: utils.MetaVoice, BalanceUnits: 3600000000000, @@ -7053,7 +7053,7 @@ func TestAPItoModelTPAccountProfileNoBalance(t *testing.T) { ActivationTime: "2014-07-24T15:00:00Z", ExpiryTime: "2014-07-25T15:00:00Z", }, - Weight: 10.0, + Weights: "10.0", ThresholdIDs: []string{"WARN_RES1"}, } exp := AccountProfileMdls{} @@ -7074,12 +7074,12 @@ func TestAPItoModelTPAccountProfileCase2(t *testing.T) { ActivationTime: "2014-07-24T15:00:00Z", ExpiryTime: "2014-07-25T15:00:00Z", }, - Weight: 10.0, + Weights: "10.0", Balances: map[string]*utils.TPAccountBalance{ "VoiceBalance": { ID: "VoiceBalance", FilterIDs: []string{"FLTR_RES_GR1", "FLTR_RES_GR2"}, - Weight: 10, + Weights: "10", Type: utils.MetaVoice, Units: 3600000000000, CostIncrement: []*utils.TPBalanceCostIncrement{ @@ -7117,10 +7117,10 @@ func TestAPItoModelTPAccountProfileCase2(t *testing.T) { ID: "ResGroup1", FilterIDs: "FLTR_RES_GR1;FLTR_RES_GR2", ActivationInterval: "2014-07-24T15:00:00Z;2014-07-25T15:00:00Z", - Weight: 10.0, + Weights: "10.0", BalanceID: "VoiceBalance", BalanceFilterIDs: "FLTR_RES_GR1;FLTR_RES_GR2", - BalanceWeight: 10, + BalanceWeights: "10", BalanceBlocker: false, BalanceType: utils.MetaVoice, BalanceCostIncrements: "*string:*~req.Account:100;1;20;5;*string:*~req.Destination:10;2;10;7", @@ -7147,12 +7147,12 @@ func TestApitoAccountProfileCase2(t *testing.T) { ActivationTime: "2014-07-14T14:25:00Z", ExpiryTime: "2014-07-15T14:25:00Z", }, - Weight: 10.0, + Weights: ";10", Balances: map[string]*utils.TPAccountBalance{ "VoiceBalance": { ID: "VoiceBalance", FilterIDs: []string{"FLTR_RES_GR2"}, - Weight: 10, + Weights: ";10", Type: utils.MetaVoice, Units: 3600000000000, Opts: "key1:val1", @@ -7168,14 +7168,22 @@ func TestApitoAccountProfileCase2(t *testing.T) { ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), ExpiryTime: time.Date(2014, 7, 15, 14, 25, 0, 0, time.UTC), }, - Weight: 10.0, + Weights: utils.DynamicWeights{ + { + Weight: 10.0, + }, + }, Balances: map[string]*utils.Balance{ "VoiceBalance": { ID: "VoiceBalance", FilterIDs: []string{"FLTR_RES_GR2"}, - Weight: 10, - Type: utils.MetaVoice, - Units: &utils.Decimal{decimal.New(3600000000000, 0)}, + Weights: utils.DynamicWeights{ + { + Weight: 10.0, + }, + }, + Type: utils.MetaVoice, + Units: &utils.Decimal{decimal.New(3600000000000, 0)}, Opts: map[string]interface{}{ "key1": "val1", }, @@ -7200,12 +7208,12 @@ func TestApitoAccountProfileCaseTimeError(t *testing.T) { ActivationTime: "test_time", ExpiryTime: "test_time2", }, - Weight: 10.0, + Weights: ";10", Balances: map[string]*utils.TPAccountBalance{ "VoiceBalance": { ID: "VoiceBalance", FilterIDs: []string{"FLTR_RES_GR2"}, - Weight: 10, + Weights: "10", Type: utils.MetaVoice, Units: 3600000000000, }, @@ -7227,12 +7235,12 @@ func TestApitoAccountProfileCaseTimeError2(t *testing.T) { ActivationTime: "2014-07-14T14:25:00Z", ExpiryTime: "2014-07-15T14:25:00Z", }, - Weight: 10.0, + Weights: ";10.0", Balances: map[string]*utils.TPAccountBalance{ "VoiceBalance": { ID: "VoiceBalance", FilterIDs: []string{"FLTR_RES_GR2"}, - Weight: 10, + Weights: "10", Type: utils.MetaVoice, Units: 3600000000000, Opts: "22:22:4fs", @@ -7323,14 +7331,22 @@ func TestModelHelpersAccountProfileToAPI(t *testing.T) { ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), ExpiryTime: time.Date(2014, 7, 15, 14, 25, 0, 0, time.UTC), }, - Weight: 2, + Weights: utils.DynamicWeights{ + { + Weight: 2, + }, + }, Balances: map[string]*utils.Balance{ "VoiceBalance": { ID: "VoiceBalance", FilterIDs: []string{"FLTR_RES_GR2"}, - Weight: 10, - Type: utils.MetaVoice, - Units: &utils.Decimal{decimal.New(3600000000000, 0)}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, + Type: utils.MetaVoice, + Units: &utils.Decimal{decimal.New(3600000000000, 0)}, CostIncrements: []*utils.CostIncrement{ { FilterIDs: []string{"*string:*~req.Account:100"}, @@ -7360,12 +7376,12 @@ func TestModelHelpersAccountProfileToAPI(t *testing.T) { ActivationTime: "2014-07-14T14:25:00Z", ExpiryTime: "2014-07-15T14:25:00Z", }, - Weight: 2, + Weights: ";2", Balances: map[string]*utils.TPAccountBalance{ "VoiceBalance": { ID: "VoiceBalance", FilterIDs: []string{"FLTR_RES_GR2"}, - Weight: 10, + Weights: ";10", Type: utils.MetaVoice, Units: 3600000000000, Opts: "key1:val1", diff --git a/engine/models.go b/engine/models.go index 655fab8df..0f309d4bd 100644 --- a/engine/models.go +++ b/engine/models.go @@ -573,19 +573,20 @@ type AccountProfileMdl struct { ID string `index:"1" re:""` FilterIDs string `index:"2" re:""` ActivationInterval string `index:"3" re:""` - Weight float64 `index:"4" re:"\d+\.?\d*"` - BalanceID string `index:"5" re:""` - BalanceFilterIDs string `index:"6" re:""` - BalanceWeight float64 `index:"7" re:"\d+\.?\d*"` - BalanceBlocker bool `index:"8" re:""` - BalanceType string `index:"9" re:""` - BalanceUnits float64 `index:"10" re:"\d+\.?\d*"` - BalanceUnitFactors string `index:"11" re:""` - BalanceOpts string `index:"12" re:""` - BalanceCostIncrements string `index:"13" re:""` - BalanceAttributeIDs string `index:"14" re:""` - BalanceRateProfileIDs string `index:"15" re:""` - ThresholdIDs string `index:"16" re:""` + Weights string `index:"4" re:""` + Opts string `index:"5" re:""` + BalanceID string `index:"6" re:""` + BalanceFilterIDs string `index:"7" re:""` + BalanceWeights string `index:"8" re:""` + BalanceBlocker bool `index:"9" re:""` + BalanceType string `index:"10" re:""` + BalanceUnits float64 `index:"11" re:"\d+\.?\d*"` + BalanceUnitFactors string `index:"12" re:""` + BalanceOpts string `index:"13" re:""` + BalanceCostIncrements string `index:"14" re:""` + BalanceAttributeIDs string `index:"15" re:""` + BalanceRateProfileIDs string `index:"16" re:""` + ThresholdIDs string `index:"17" re:""` CreatedAt time.Time } diff --git a/engine/z_onstor_it_test.go b/engine/z_onstor_it_test.go index 99342d096..af5f28236 100644 --- a/engine/z_onstor_it_test.go +++ b/engine/z_onstor_it_test.go @@ -2307,13 +2307,21 @@ func testOnStorITAccountProfile(t *testing.T) { ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), ExpiryTime: time.Date(2014, 7, 15, 14, 25, 0, 0, time.UTC), }, - Weight: 2, + Weights: utils.DynamicWeights{ + { + Weight: 2, + }, + }, Balances: map[string]*utils.Balance{ "VoiceBalance": { ID: "VoiceBalance", FilterIDs: []string{"FLTR_RES_GR2"}, - Weight: 10, - Type: utils.MetaVoice, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, + Type: utils.MetaVoice, Units: &utils.Decimal{ new(decimal.Big).SetUint64(10), }, diff --git a/engine/z_stordb_it_test.go b/engine/z_stordb_it_test.go index 275322c44..0f054d980 100644 --- a/engine/z_stordb_it_test.go +++ b/engine/z_stordb_it_test.go @@ -158,15 +158,15 @@ func testStorDBitCRUDTPAccountProfiles(t *testing.T) { //WRITE var actPrf = []*utils.TPAccountProfile{ { - TPid: testTPID, - Tenant: "cgrates.org", - ID: "1001", - Weight: 20, + TPid: testTPID, + Tenant: "cgrates.org", + ID: "1001", + Weights: ";20", Balances: map[string]*utils.TPAccountBalance{ "MonetaryBalance": { - ID: "MonetaryBalance", - Weight: 10, - Type: utils.MetaMonetary, + ID: "MonetaryBalance", + Weights: ";10", + Type: utils.MetaMonetary, CostIncrement: []*utils.TPBalanceCostIncrement{ { FilterIDs: []string{"fltr1", "fltr2"}, diff --git a/general_tests/export_it_test.go b/general_tests/export_it_test.go index cf25becfb..0d1a09251 100644 --- a/general_tests/export_it_test.go +++ b/general_tests/export_it_test.go @@ -487,12 +487,20 @@ func testExpVerifyAccountProfiles(t *testing.T) { Tenant: "cgrates.org", ID: "ACC_PRF_1", FilterIDs: []string{}, - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, Balances: map[string]*utils.Balance{ "MonetaryBalance": { - ID: "MonetaryBalance", - Weight: 10, - Type: "*monetary", + ID: "MonetaryBalance", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, + Type: "*monetary", CostIncrements: []*utils.CostIncrement{ { FilterIDs: []string{"fltr1", "fltr2"}, diff --git a/utils/accountprofile.go b/utils/accountprofile.go index 222f61cfa..a4f817650 100644 --- a/utils/accountprofile.go +++ b/utils/accountprofile.go @@ -19,7 +19,6 @@ along with this program. If not, see package utils import ( - "sort" "time" ) @@ -29,7 +28,7 @@ type AccountProfile struct { ID string // Account identificator, unique within the tenant FilterIDs []string ActivationInterval *ActivationInterval - Weight float64 + Weights DynamicWeights Opts map[string]interface{} Balances map[string]*Balance ThresholdIDs []string @@ -39,7 +38,7 @@ type AccountProfile struct { type Balance struct { ID string // Balance identificator, unique within an Account FilterIDs []string - Weight float64 + Weights DynamicWeights Blocker bool Type string Opts map[string]interface{} @@ -109,7 +108,7 @@ func (aP *AccountProfile) Clone() (acnt *AccountProfile) { acnt = &AccountProfile{ Tenant: aP.Tenant, ID: aP.ID, - Weight: aP.Weight, + Weights: aP.Weights.Clone(), ActivationInterval: aP.ActivationInterval.Clone(), } if aP.FilterIDs != nil { @@ -154,8 +153,8 @@ func (aI *ActivationInterval) Clone() *ActivationInterval { func (bL *Balance) Clone() (blnc *Balance) { blnc = &Balance{ ID: bL.ID, - Weight: bL.Weight, Blocker: bL.Blocker, + Weights: bL.Weights.Clone(), Type: bL.Type, } if bL.FilterIDs != nil { @@ -209,11 +208,14 @@ type AccountProfileWithWeight struct { // AccountProfilesWithWeight is a sortable list of AccountProfileWithWeight type AccountProfilesWithWeight []*AccountProfileWithWeight +/* // Sort is part of sort interface, sort based on Weight func (aps AccountProfilesWithWeight) Sort() { sort.Slice(aps, func(i, j int) bool { return aps[i].Weight > aps[j].Weight }) } +*/ + // AccountProfiles returns the list of AccountProfiles func (apWws AccountProfilesWithWeight) AccountProfiles() (aps []*AccountProfile) { if apWws != nil { @@ -234,10 +236,13 @@ type BalanceWithWeight struct { // Balances is a sortable list of Balances type BalancesWithWeight []*BalanceWithWeight +/* // Sort is part of sort interface, sort based on Weight func (blcs BalancesWithWeight) Sort() { sort.Slice(blcs, func(i, j int) bool { return blcs[i].Weight > blcs[j].Weight }) } +` +*/ // Balances returns the list of Balances func (bWws BalancesWithWeight) Balances() (blncs []*Balance) { @@ -280,7 +285,7 @@ type APIAccountProfile struct { ID string FilterIDs []string ActivationInterval *ActivationInterval - Weight float64 + Weights string Opts map[string]interface{} Balances map[string]*APIBalance ThresholdIDs []string @@ -293,14 +298,20 @@ func (ext *APIAccountProfile) AsAccountProfile() (profile *AccountProfile, err e ID: ext.ID, FilterIDs: ext.FilterIDs, ActivationInterval: ext.ActivationInterval, - Weight: ext.Weight, Opts: ext.Opts, ThresholdIDs: ext.ThresholdIDs, } + if ext.Weights != EmptyString { + if profile.Weights, err = NewDynamicWeightsFromString(ext.Weights, ";", "&"); err != nil { + return nil, err + } + } if len(ext.Balances) != 0 { profile.Balances = make(map[string]*Balance, len(ext.Balances)) for i, bal := range ext.Balances { - profile.Balances[i] = bal.AsBalance() + if profile.Balances[i], err = bal.AsBalance(); err != nil { + return nil, err + } } } return @@ -310,7 +321,7 @@ func (ext *APIAccountProfile) AsAccountProfile() (profile *AccountProfile, err e type APIBalance struct { ID string // Balance identificator, unique within an Account FilterIDs []string - Weight float64 + Weights string Blocker bool Type string Opts map[string]interface{} @@ -322,11 +333,10 @@ type APIBalance struct { } // AsBalance convert APIBalance struct to Balance struct -func (ext *APIBalance) AsBalance() (balance *Balance) { +func (ext *APIBalance) AsBalance() (balance *Balance, err error) { balance = &Balance{ ID: ext.ID, FilterIDs: ext.FilterIDs, - Weight: ext.Weight, Blocker: ext.Blocker, Type: ext.Type, Opts: ext.Opts, @@ -334,6 +344,11 @@ func (ext *APIBalance) AsBalance() (balance *Balance) { RateProfileIDs: ext.RateProfileIDs, Units: NewDecimalFromFloat64(ext.Units), } + if ext.Weights != EmptyString { + if balance.Weights, err = NewDynamicWeightsFromString(ext.Weights, ";", "&"); err != nil { + return nil, err + } + } if len(ext.CostIncrements) != 0 { balance.CostIncrements = make([]*CostIncrement, len(ext.CostIncrements)) for i, cIncr := range ext.CostIncrements { diff --git a/utils/accountprofile_test.go b/utils/accountprofile_test.go index 2fc0f35a3..df27b139d 100644 --- a/utils/accountprofile_test.go +++ b/utils/accountprofile_test.go @@ -30,9 +30,13 @@ func TestCloneBalance(t *testing.T) { expBlc := &Balance{ ID: "TEST_ID1", FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 1.1, - Blocker: true, - Type: "*abstract", + Weights: DynamicWeights{ + { + Weight: 1.1, + }, + }, + Blocker: true, + Type: "*abstract", Opts: map[string]interface{}{ "Destination": 10, }, @@ -73,7 +77,11 @@ func TestCloneAccountProfile(t *testing.T) { ActivationTime: time.Date(2020, 7, 21, 10, 0, 0, 0, time.UTC), ExpiryTime: time.Date(2020, 7, 22, 10, 0, 0, 0, time.UTC), }, - Weight: 2.4, + Weights: DynamicWeights{ + { + Weight: 2.4, + }, + }, Opts: map[string]interface{}{ "Destination": 10, }, @@ -81,9 +89,13 @@ func TestCloneAccountProfile(t *testing.T) { "VoiceBalance": { ID: "VoiceBalance", FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 1.1, - Blocker: true, - Type: "*abstract", + Weights: DynamicWeights{ + { + Weight: 1.1, + }, + }, + Blocker: true, + Type: "*abstract", Opts: map[string]interface{}{ "Destination": 10, }, @@ -133,11 +145,12 @@ func TestAccountProfileAsAccountProfile(t *testing.T) { apiAccPrf := &APIAccountProfile{ Tenant: "cgrates.org", ID: "test_ID1", + Opts: map[string]interface{}{}, Balances: map[string]*APIBalance{ "VoiceBalance": { ID: "VoiceBalance", FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 1.1, + Weights: ";1.2", Blocker: true, Type: "*abstract", Opts: map[string]interface{}{ @@ -146,25 +159,34 @@ func TestAccountProfileAsAccountProfile(t *testing.T) { Units: 0, }, }, - Weight: 10, + Weights: ";10", } expected := &AccountProfile{ Tenant: "cgrates.org", ID: "test_ID1", + Opts: map[string]interface{}{}, Balances: map[string]*Balance{ "VoiceBalance": { ID: "VoiceBalance", FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 1.1, - Blocker: true, - Type: "*abstract", + Weights: DynamicWeights{ + { + Weight: 1.2, + }, + }, + Blocker: true, + Type: "*abstract", Opts: map[string]interface{}{ "Destination": 10, }, Units: NewDecimal(0, 0), }, }, - Weight: 10, + Weights: DynamicWeights{ + { + Weight: 10, + }, + }, } if rcv, err := apiAccPrf.AsAccountProfile(); err != nil { t.Error(err) @@ -184,7 +206,7 @@ func TestAPIBalanceAsBalance(t *testing.T) { RecurrentFee: Float64Pointer(35), }, }, - Weight: 10, + Weights: ";10", UnitFactors: []*APIUnitFactor{ { FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -202,7 +224,11 @@ func TestAPIBalanceAsBalance(t *testing.T) { RecurrentFee: NewDecimal(35, 0), }, }, - Weight: 10, + Weights: DynamicWeights{ + { + Weight: 10, + }, + }, UnitFactors: []*UnitFactor{ { FilterIDs: []string{"*string:~*req.Account:1001"}, @@ -211,7 +237,9 @@ func TestAPIBalanceAsBalance(t *testing.T) { }, Units: NewDecimal(0, 0), } - if rcv := blc.AsBalance(); !reflect.DeepEqual(rcv, expected) { + if rcv, err := blc.AsBalance(); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(rcv, expected) { t.Errorf("Expected %+v \n, received %+v", ToJSON(expected), ToJSON(rcv)) } diff --git a/utils/apitpdata.go b/utils/apitpdata.go index 77e09587e..e1165195b 100755 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -1546,7 +1546,7 @@ type TPAccountProfile struct { ID string FilterIDs []string ActivationInterval *TPActivationInterval - Weight float64 + Weights string Balances map[string]*TPAccountBalance ThresholdIDs []string } @@ -1554,7 +1554,7 @@ type TPAccountProfile struct { type TPAccountBalance struct { ID string FilterIDs []string - Weight float64 + Weights string Blocker bool Type string Opts string