mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Add APIAccountProfile struct + commands in cgr-console
This commit is contained in:
committed by
Dan Christian Bogos
parent
d7d7a4f914
commit
9c32b2310a
@@ -138,7 +138,7 @@ func (cB *concreteBalance) debitUnits(dUnts *decimal.Big, incrm *decimal.Big,
|
||||
hasUF = true
|
||||
}
|
||||
|
||||
blcVal := new(decimal.Big).SetFloat64(cB.blnCfg.Units) // FixMe without float64
|
||||
blcVal := cB.blnCfg.Units.Big
|
||||
|
||||
// balanceLimit
|
||||
var hasLmt bool
|
||||
@@ -166,6 +166,6 @@ func (cB *concreteBalance) debitUnits(dUnts *decimal.Big, incrm *decimal.Big,
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("failed representing decimal <%s> as float64", rmain)
|
||||
}
|
||||
cB.blnCfg.Units = rmainFlt64
|
||||
cB.blnCfg.Units, err = utils.NewDecimalFromFloat64(rmainFlt64)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ func TestCBDebitUnits(t *testing.T) {
|
||||
Factor: &utils.Decimal{decimal.New(100, 0)}, // EuroCents
|
||||
},
|
||||
},
|
||||
Units: 500, // 500 EURcents
|
||||
Units: &utils.Decimal{decimal.New(500, 0)}, // 500 EURcents
|
||||
},
|
||||
fltrS: new(engine.FilterS),
|
||||
}
|
||||
@@ -53,7 +53,7 @@ func TestCBDebitUnits(t *testing.T) {
|
||||
t.Errorf("received unit factor: %+v", uFctr)
|
||||
} else if dbted.Cmp(toDebit) != 0 {
|
||||
t.Errorf("debited: %s", dbted)
|
||||
} else if cb.blnCfg.Units != -100.0 {
|
||||
} else if cb.blnCfg.Units.String() != "-100" {
|
||||
t.Errorf("balance remaining: %f", cb.blnCfg.Units)
|
||||
}
|
||||
//with increment and not enough balance
|
||||
@@ -64,7 +64,7 @@ func TestCBDebitUnits(t *testing.T) {
|
||||
Opts: map[string]interface{}{
|
||||
utils.MetaBalanceLimit: decimal.New(-1, 0),
|
||||
},
|
||||
Units: 1.25,
|
||||
Units: &utils.Decimal{decimal.New(125, 2)},
|
||||
},
|
||||
fltrS: new(engine.FilterS),
|
||||
}
|
||||
@@ -75,7 +75,7 @@ func TestCBDebitUnits(t *testing.T) {
|
||||
t.Error(err)
|
||||
} else if dbted.Cmp(decimal.New(22, 1)) != 0 { // only 1.2 is possible due to increment
|
||||
t.Errorf("debited: %s, cmp: %v", dbted, dbted.Cmp(new(decimal.Big).SetFloat64(1.2)))
|
||||
} else if cb.blnCfg.Units != -0.95 {
|
||||
} else if cb.blnCfg.Units.String() != "-0.95" {
|
||||
t.Errorf("balance remaining: %f", cb.blnCfg.Units)
|
||||
}
|
||||
//with increment and unlimited balance
|
||||
@@ -86,7 +86,7 @@ func TestCBDebitUnits(t *testing.T) {
|
||||
Opts: map[string]interface{}{
|
||||
utils.MetaBalanceUnlimited: true,
|
||||
},
|
||||
Units: 1.25,
|
||||
Units: &utils.Decimal{decimal.New(125, 2)},
|
||||
},
|
||||
fltrS: new(engine.FilterS),
|
||||
}
|
||||
@@ -97,7 +97,7 @@ func TestCBDebitUnits(t *testing.T) {
|
||||
t.Error(err)
|
||||
} else if dbted.Cmp(decimal.New(25, 1)) != 0 { // only 1.2 is possible due to increment
|
||||
t.Errorf("debited: %s, cmp: %v", dbted, dbted.Cmp(new(decimal.Big).SetFloat64(1.2)))
|
||||
} else if cb.blnCfg.Units != -1.25 {
|
||||
} else if cb.blnCfg.Units.String() != "-1.25" {
|
||||
t.Errorf("balance remaining: %f", cb.blnCfg.Units)
|
||||
}
|
||||
//with increment and positive limit
|
||||
@@ -108,7 +108,7 @@ func TestCBDebitUnits(t *testing.T) {
|
||||
Opts: map[string]interface{}{
|
||||
utils.MetaBalanceLimit: decimal.New(5, 1), // 0.5 as limit
|
||||
},
|
||||
Units: 1.25,
|
||||
Units: &utils.Decimal{decimal.New(125, 2)},
|
||||
},
|
||||
fltrS: new(engine.FilterS),
|
||||
}
|
||||
@@ -119,7 +119,7 @@ func TestCBDebitUnits(t *testing.T) {
|
||||
t.Error(err)
|
||||
} else if dbted.Cmp(decimal.New(7, 1)) != 0 { // only 1.2 is possible due to increment
|
||||
t.Errorf("debited: %s, cmp: %v", dbted, dbted.Cmp(new(decimal.Big).SetFloat64(1.2)))
|
||||
} else if cb.blnCfg.Units != 0.55 {
|
||||
} else if cb.blnCfg.Units.String() != "0.55" {
|
||||
t.Errorf("balance remaining: %f", cb.blnCfg.Units)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,21 +87,24 @@ func (apierSv1 *APIerSv1) GetAccountProfileIDsCount(args *utils.TenantWithOpts,
|
||||
return
|
||||
}
|
||||
|
||||
type AccountProfileWithCache struct {
|
||||
*utils.AccountProfileWithOpts
|
||||
type APIAccountProfileWithCache struct {
|
||||
*utils.APIAccountProfileWithOpts
|
||||
Cache *string
|
||||
}
|
||||
|
||||
//SetAccountProfile add/update a new Account Profile
|
||||
func (apierSv1 *APIerSv1) SetAccountProfile(ap *AccountProfileWithCache, reply *string) error {
|
||||
if missing := utils.MissingStructFields(ap.AccountProfile, []string{utils.ID}); len(missing) != 0 {
|
||||
func (apierSv1 *APIerSv1) SetAccountProfile(extAp *APIAccountProfileWithCache, reply *string) error {
|
||||
if missing := utils.MissingStructFields(extAp.APIAccountProfile, []string{utils.ID}); len(missing) != 0 {
|
||||
return utils.NewErrMandatoryIeMissing(missing...)
|
||||
}
|
||||
if ap.Tenant == utils.EmptyString {
|
||||
ap.Tenant = apierSv1.Config.GeneralCfg().DefaultTenant
|
||||
if extAp.Tenant == utils.EmptyString {
|
||||
extAp.Tenant = apierSv1.Config.GeneralCfg().DefaultTenant
|
||||
}
|
||||
|
||||
if err := apierSv1.DataManager.SetAccountProfile(ap.AccountProfile, true); err != nil {
|
||||
ap, err := extAp.AsAccountProfile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := apierSv1.DataManager.SetAccountProfile(ap, true); err != nil {
|
||||
return utils.APIErrorHandler(err)
|
||||
}
|
||||
//generate a loadID for CacheAccountProfiles and store it in database
|
||||
|
||||
@@ -39,7 +39,8 @@ var (
|
||||
accPrfCfg *config.CGRConfig
|
||||
accSRPC *rpc.Client
|
||||
accPrfDataDir = "/usr/share/cgrates"
|
||||
accPrf *AccountProfileWithCache
|
||||
apiAccPrf *APIAccountProfileWithCache
|
||||
accPrf *utils.AccountProfile
|
||||
accPrfConfigDIR string //run tests for specific configuration
|
||||
|
||||
sTestsAccPrf = []func(t *testing.T){
|
||||
@@ -157,7 +158,7 @@ func testAccountSGetAccountProfile(t *testing.T) {
|
||||
Factor: &utils.Decimal{decimal.New(200, 0)},
|
||||
},
|
||||
},
|
||||
Units: 14,
|
||||
Units: &utils.Decimal{decimal.New(14, 0)},
|
||||
},
|
||||
&utils.Balance{
|
||||
ID: "VoiceBalance",
|
||||
@@ -167,7 +168,7 @@ func testAccountSGetAccountProfile(t *testing.T) {
|
||||
CostIncrements: []*utils.CostIncrement{},
|
||||
CostAttributes: []string{},
|
||||
UnitFactors: []*utils.UnitFactor{},
|
||||
Units: 3600000000000,
|
||||
Units: &utils.Decimal{decimal.New(3600000000000, 0)},
|
||||
},
|
||||
},
|
||||
ThresholdIDs: []string{utils.META_NONE},
|
||||
@@ -197,48 +198,45 @@ func testAccountSPing(t *testing.T) {
|
||||
}
|
||||
|
||||
func testAccountSSettAccountProfile(t *testing.T) {
|
||||
accPrf = &AccountProfileWithCache{
|
||||
AccountProfileWithOpts: &utils.AccountProfileWithOpts{
|
||||
AccountProfile: &utils.AccountProfile{
|
||||
apiAccPrf = &APIAccountProfileWithCache{
|
||||
APIAccountProfileWithOpts: &utils.APIAccountProfileWithOpts{
|
||||
APIAccountProfile: &utils.APIAccountProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "id_test",
|
||||
Weight: 10,
|
||||
Balances: []*utils.Balance{
|
||||
&utils.Balance{
|
||||
Balances: []*utils.APIBalance{
|
||||
&utils.APIBalance{
|
||||
ID: "MonetaryBalance",
|
||||
FilterIDs: []string{},
|
||||
Weight: 10,
|
||||
Type: utils.MONETARY,
|
||||
CostIncrements: []*utils.CostIncrement{
|
||||
&utils.CostIncrement{
|
||||
CostIncrements: []*utils.APICostIncrement{
|
||||
&utils.APICostIncrement{
|
||||
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)},
|
||||
Increment: utils.Float64Pointer(1.3),
|
||||
FixedFee: utils.Float64Pointer(2.3),
|
||||
RecurrentFee: utils.Float64Pointer(3.3),
|
||||
},
|
||||
},
|
||||
CostAttributes: []string{"attr1", "attr2"},
|
||||
UnitFactors: []*utils.UnitFactor{
|
||||
&utils.UnitFactor{
|
||||
UnitFactors: []*utils.APIUnitFactor{
|
||||
&utils.APIUnitFactor{
|
||||
FilterIDs: []string{"fltr1", "fltr2"},
|
||||
Factor: &utils.Decimal{decimal.New(100, 0)},
|
||||
Factor: 100,
|
||||
},
|
||||
&utils.UnitFactor{
|
||||
&utils.APIUnitFactor{
|
||||
FilterIDs: []string{"fltr3"},
|
||||
Factor: &utils.Decimal{decimal.New(200, 0)},
|
||||
Factor: 200,
|
||||
},
|
||||
},
|
||||
Units: 14,
|
||||
},
|
||||
&utils.Balance{
|
||||
ID: "VoiceBalance",
|
||||
FilterIDs: []string{},
|
||||
Weight: 10,
|
||||
Type: utils.VOICE,
|
||||
CostIncrements: []*utils.CostIncrement{},
|
||||
CostAttributes: []string{},
|
||||
UnitFactors: []*utils.UnitFactor{},
|
||||
Units: 3600000000000,
|
||||
&utils.APIBalance{
|
||||
ID: "VoiceBalance",
|
||||
FilterIDs: []string{},
|
||||
Weight: 10,
|
||||
Type: utils.VOICE,
|
||||
Units: 3600000000000,
|
||||
},
|
||||
},
|
||||
ThresholdIDs: []string{utils.META_NONE},
|
||||
@@ -253,17 +251,21 @@ func testAccountSSettAccountProfile(t *testing.T) {
|
||||
t.Errorf("Expected error: %v received: %v", expErr, err)
|
||||
}
|
||||
var reply string
|
||||
if err := accSRPC.Call(utils.APIerSv1SetAccountProfile, accPrf, &reply); err != nil {
|
||||
if err := accSRPC.Call(utils.APIerSv1SetAccountProfile, apiAccPrf, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if reply != utils.OK {
|
||||
t.Error("Unexpected reply returned", reply)
|
||||
}
|
||||
var err error
|
||||
if accPrf, err = apiAccPrf.AsAccountProfile(); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
var reply2 *utils.AccountProfile
|
||||
if err := accSRPC.Call(utils.APIerSv1GetAccountProfile, &utils.TenantIDWithOpts{
|
||||
TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "id_test"}}, &reply2); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(accPrf.AccountProfile, reply2) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", accPrf.AccountProfile, reply2)
|
||||
} else if !reflect.DeepEqual(accPrf, reply2) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", accPrf, reply2)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -305,19 +307,23 @@ func testAccountSGetAccountProfileIDsCount(t *testing.T) {
|
||||
|
||||
func testAccountSUpdateAccountProfile(t *testing.T) {
|
||||
var reply string
|
||||
accPrf.Weight = 2
|
||||
accPrf.Balances[0].CostIncrements[0].FixedFee = &utils.Decimal{decimal.New(1234, 1)}
|
||||
if err := accSRPC.Call(utils.APIerSv1SetAccountProfile, accPrf, &reply); err != nil {
|
||||
apiAccPrf.Weight = 2
|
||||
apiAccPrf.Balances[0].CostIncrements[0].FixedFee = utils.Float64Pointer(123.5)
|
||||
if err := accSRPC.Call(utils.APIerSv1SetAccountProfile, apiAccPrf, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if reply != utils.OK {
|
||||
t.Error("Unexpected reply returned", reply)
|
||||
}
|
||||
var err error
|
||||
if accPrf, err = apiAccPrf.AsAccountProfile(); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
var reply2 *utils.AccountProfile
|
||||
if err := accSRPC.Call(utils.APIerSv1GetAccountProfile, &utils.TenantIDWithOpts{
|
||||
TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "id_test"}}, &reply2); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(accPrf.AccountProfile, reply2) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", accPrf.AccountProfile, reply2)
|
||||
} else if !reflect.DeepEqual(accPrf, reply2) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", accPrf, reply2)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
65
console/accounts_profile.go
Normal file
65
console/accounts_profile.go
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
Copyright (C) ITsysCOM GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package console
|
||||
|
||||
import (
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
c := &CmdGetAccountsProfile{
|
||||
name: "accounts_profile",
|
||||
rpcMethod: utils.APIerSv1GetAccountProfile,
|
||||
rpcParams: &utils.TenantID{},
|
||||
}
|
||||
commands[c.Name()] = c
|
||||
c.CommandExecuter = &CommandExecuter{c}
|
||||
}
|
||||
|
||||
// Commander implementation
|
||||
type CmdGetAccountsProfile struct {
|
||||
name string
|
||||
rpcMethod string
|
||||
rpcParams *utils.TenantID
|
||||
*CommandExecuter
|
||||
}
|
||||
|
||||
func (self *CmdGetAccountsProfile) Name() string {
|
||||
return self.name
|
||||
}
|
||||
|
||||
func (self *CmdGetAccountsProfile) RpcMethod() string {
|
||||
return self.rpcMethod
|
||||
}
|
||||
|
||||
func (self *CmdGetAccountsProfile) RpcParams(reset bool) interface{} {
|
||||
if reset || self.rpcParams == nil {
|
||||
self.rpcParams = &utils.TenantID{}
|
||||
}
|
||||
return self.rpcParams
|
||||
}
|
||||
|
||||
func (self *CmdGetAccountsProfile) PostprocessRpcParams() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *CmdGetAccountsProfile) RpcResult() interface{} {
|
||||
var atr utils.AccountProfile
|
||||
return &atr
|
||||
}
|
||||
65
console/accounts_profile_ids.go
Normal file
65
console/accounts_profile_ids.go
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
Copyright (C) ITsysCOM GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package console
|
||||
|
||||
import (
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
c := &CmdGetAccountsProfileIDs{
|
||||
name: "accounts_profile_ids",
|
||||
rpcMethod: utils.APIerSv1GetAccountProfileIDs,
|
||||
rpcParams: &utils.PaginatorWithTenant{},
|
||||
}
|
||||
commands[c.Name()] = c
|
||||
c.CommandExecuter = &CommandExecuter{c}
|
||||
}
|
||||
|
||||
// Commander implementation
|
||||
type CmdGetAccountsProfileIDs struct {
|
||||
name string
|
||||
rpcMethod string
|
||||
rpcParams *utils.PaginatorWithTenant
|
||||
*CommandExecuter
|
||||
}
|
||||
|
||||
func (self *CmdGetAccountsProfileIDs) Name() string {
|
||||
return self.name
|
||||
}
|
||||
|
||||
func (self *CmdGetAccountsProfileIDs) RpcMethod() string {
|
||||
return self.rpcMethod
|
||||
}
|
||||
|
||||
func (self *CmdGetAccountsProfileIDs) RpcParams(reset bool) interface{} {
|
||||
if reset || self.rpcParams == nil {
|
||||
self.rpcParams = &utils.PaginatorWithTenant{}
|
||||
}
|
||||
return self.rpcParams
|
||||
}
|
||||
|
||||
func (self *CmdGetAccountsProfileIDs) PostprocessRpcParams() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *CmdGetAccountsProfileIDs) RpcResult() interface{} {
|
||||
var atr []string
|
||||
return &atr
|
||||
}
|
||||
62
console/accounts_profile_rem.go
Normal file
62
console/accounts_profile_rem.go
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
Copyright (C) ITsysCOM GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package console
|
||||
|
||||
import "github.com/cgrates/cgrates/utils"
|
||||
|
||||
func init() {
|
||||
c := &CmdRemoveAccountsProfile{
|
||||
name: "accounts_profile_remove",
|
||||
rpcMethod: utils.APIerSv1RemoveAccountProfile,
|
||||
rpcParams: &utils.TenantIDWithCache{},
|
||||
}
|
||||
commands[c.Name()] = c
|
||||
c.CommandExecuter = &CommandExecuter{c}
|
||||
}
|
||||
|
||||
type CmdRemoveAccountsProfile struct {
|
||||
name string
|
||||
rpcMethod string
|
||||
rpcParams *utils.TenantIDWithCache
|
||||
*CommandExecuter
|
||||
}
|
||||
|
||||
func (self *CmdRemoveAccountsProfile) Name() string {
|
||||
return self.name
|
||||
}
|
||||
|
||||
func (self *CmdRemoveAccountsProfile) RpcMethod() string {
|
||||
return self.rpcMethod
|
||||
}
|
||||
|
||||
func (self *CmdRemoveAccountsProfile) RpcParams(reset bool) interface{} {
|
||||
if reset || self.rpcParams == nil {
|
||||
self.rpcParams = &utils.TenantIDWithCache{Opts: make(map[string]interface{})}
|
||||
}
|
||||
return self.rpcParams
|
||||
}
|
||||
|
||||
func (self *CmdRemoveAccountsProfile) PostprocessRpcParams() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *CmdRemoveAccountsProfile) RpcResult() interface{} {
|
||||
var s string
|
||||
return &s
|
||||
}
|
||||
65
console/accounts_profile_set.go
Normal file
65
console/accounts_profile_set.go
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
Copyright (C) ITsysCOM GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package console
|
||||
|
||||
import (
|
||||
v1 "github.com/cgrates/cgrates/apier/v1"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
c := &CmdSetAccountProfile{
|
||||
name: "accounts_profile_set",
|
||||
rpcMethod: utils.APIerSv1SetAccountProfile,
|
||||
rpcParams: &v1.APIAccountProfileWithCache{},
|
||||
}
|
||||
commands[c.Name()] = c
|
||||
c.CommandExecuter = &CommandExecuter{c}
|
||||
}
|
||||
|
||||
type CmdSetAccountProfile struct {
|
||||
name string
|
||||
rpcMethod string
|
||||
rpcParams *v1.APIAccountProfileWithCache
|
||||
*CommandExecuter
|
||||
}
|
||||
|
||||
func (self *CmdSetAccountProfile) Name() string {
|
||||
return self.name
|
||||
}
|
||||
|
||||
func (self *CmdSetAccountProfile) RpcMethod() string {
|
||||
return self.rpcMethod
|
||||
}
|
||||
|
||||
func (self *CmdSetAccountProfile) RpcParams(reset bool) interface{} {
|
||||
if reset || self.rpcParams == nil {
|
||||
self.rpcParams = &v1.APIAccountProfileWithCache{APIAccountProfileWithOpts: new(utils.APIAccountProfileWithOpts)}
|
||||
}
|
||||
return self.rpcParams
|
||||
}
|
||||
|
||||
func (self *CmdSetAccountProfile) PostprocessRpcParams() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *CmdSetAccountProfile) RpcResult() interface{} {
|
||||
var s string
|
||||
return &s
|
||||
}
|
||||
@@ -3726,7 +3726,9 @@ func APItoAccountProfile(tpAp *utils.TPAccountProfile, timezone string) (ap *uti
|
||||
Weight: bal.Weight,
|
||||
Blocker: bal.Blocker,
|
||||
Type: bal.Type,
|
||||
Units: bal.Units,
|
||||
}
|
||||
if ap.Balances[i].Units, err = utils.NewDecimalFromFloat64(bal.Units); err != nil {
|
||||
return
|
||||
}
|
||||
if bal.Opts != utils.EmptyString {
|
||||
ap.Balances[i].Opts = make(map[string]interface{})
|
||||
@@ -3815,9 +3817,8 @@ func AccountProfileToAPI(ap *utils.AccountProfile) (tpAp *utils.TPAccountProfile
|
||||
Weight: bal.Weight,
|
||||
Blocker: bal.Blocker,
|
||||
Type: bal.Type,
|
||||
Units: bal.Units,
|
||||
}
|
||||
|
||||
tpAp.Balances[i].Units, _ = bal.Units.Float64()
|
||||
elems := make([]string, 0, len(bal.Opts))
|
||||
for k, v := range bal.Opts {
|
||||
elems = append(elems, utils.ConcatenatedKey(k, utils.IfaceAsString(v)))
|
||||
|
||||
@@ -25,6 +25,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ericlagergren/decimal"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
@@ -7230,7 +7232,7 @@ func TestApitoAccountProfileCase2(t *testing.T) {
|
||||
FilterIDs: []string{"FLTR_RES_GR2"},
|
||||
Weight: 10,
|
||||
Type: utils.VOICE,
|
||||
Units: 3600000000000,
|
||||
Units: &utils.Decimal{decimal.New(3600000000000, 0)},
|
||||
Opts: map[string]interface{}{
|
||||
"key1": "val1",
|
||||
},
|
||||
@@ -7388,7 +7390,7 @@ func TestModelHelpersAccountProfileToAPI(t *testing.T) {
|
||||
FilterIDs: []string{"FLTR_RES_GR2"},
|
||||
Weight: 10,
|
||||
Type: utils.VOICE,
|
||||
Units: 3600000000000,
|
||||
Units: &utils.Decimal{decimal.New(3600000000000, 0)},
|
||||
Opts: map[string]interface{}{
|
||||
"key1": "val1",
|
||||
},
|
||||
|
||||
@@ -46,7 +46,7 @@ type Balance struct {
|
||||
CostIncrements []*CostIncrement
|
||||
CostAttributes []string
|
||||
UnitFactors []*UnitFactor
|
||||
Units float64
|
||||
Units *Decimal
|
||||
}
|
||||
|
||||
// CostIncrement enforces cost calculation to specific balance increments
|
||||
@@ -152,7 +152,6 @@ func (bL *Balance) Clone() (blnc *Balance) {
|
||||
Blocker: bL.Blocker,
|
||||
Type: bL.Type,
|
||||
Opts: make(map[string]interface{}),
|
||||
Units: bL.Units,
|
||||
}
|
||||
if bL.FilterIDs != nil {
|
||||
blnc.FilterIDs = make([]string, len(bL.FilterIDs))
|
||||
@@ -181,6 +180,9 @@ func (bL *Balance) Clone() (blnc *Balance) {
|
||||
blnc.UnitFactors[i] = value.Clone()
|
||||
}
|
||||
}
|
||||
if bL.Units != nil {
|
||||
blnc.Units = new(Decimal).Copy(bL.Units)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -200,6 +202,12 @@ func (blcs Balances) Sort() {
|
||||
sort.Slice(blcs, func(i, j int) bool { return blcs[i].Weight > blcs[j].Weight })
|
||||
}
|
||||
|
||||
// APIAccountProfileWithOpts is used in API calls
|
||||
type APIAccountProfileWithOpts struct {
|
||||
*APIAccountProfile
|
||||
Opts map[string]interface{}
|
||||
}
|
||||
|
||||
// AccountProfileWithOpts is used in API calls
|
||||
type AccountProfileWithOpts struct {
|
||||
*AccountProfile
|
||||
@@ -217,3 +225,130 @@ type ReplyMaxUsage struct {
|
||||
MaxUsage time.Duration
|
||||
Cost *EventCharges
|
||||
}
|
||||
|
||||
// APIAccountProfile represents one APIAccount on a Tenant
|
||||
type APIAccountProfile struct {
|
||||
Tenant string
|
||||
ID string
|
||||
FilterIDs []string
|
||||
ActivationInterval *ActivationInterval
|
||||
Weight float64
|
||||
Opts map[string]interface{}
|
||||
Balances []*APIBalance
|
||||
ThresholdIDs []string
|
||||
}
|
||||
|
||||
func (ext *APIAccountProfile) AsAccountProfile() (profile *AccountProfile, err error) {
|
||||
profile = &AccountProfile{
|
||||
Tenant: ext.Tenant,
|
||||
ID: ext.ID,
|
||||
FilterIDs: ext.FilterIDs,
|
||||
ActivationInterval: ext.ActivationInterval,
|
||||
Weight: ext.Weight,
|
||||
Opts: ext.Opts,
|
||||
ThresholdIDs: ext.ThresholdIDs,
|
||||
}
|
||||
if len(ext.Balances) != 0 {
|
||||
profile.Balances = make([]*Balance, len(ext.Balances))
|
||||
for i, bal := range ext.Balances {
|
||||
if profile.Balances[i], err = bal.AsBalance(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// APIBalance represents one APIBalance inside an APIAccount
|
||||
type APIBalance struct {
|
||||
ID string // Balance identificator, unique within an Account
|
||||
FilterIDs []string
|
||||
Weight float64
|
||||
Blocker bool
|
||||
Type string
|
||||
Opts map[string]interface{}
|
||||
CostIncrements []*APICostIncrement
|
||||
CostAttributes []string
|
||||
UnitFactors []*APIUnitFactor
|
||||
Units float64
|
||||
}
|
||||
|
||||
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,
|
||||
CostAttributes: ext.CostAttributes,
|
||||
}
|
||||
if len(ext.CostIncrements) != 0 {
|
||||
balance.CostIncrements = make([]*CostIncrement, len(ext.CostIncrements))
|
||||
for i, cIncr := range ext.CostIncrements {
|
||||
if balance.CostIncrements[i], err = cIncr.AsCostIncrement(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(ext.UnitFactors) != 0 {
|
||||
balance.UnitFactors = make([]*UnitFactor, len(ext.UnitFactors))
|
||||
for i, uFct := range ext.UnitFactors {
|
||||
if balance.UnitFactors[i], err = uFct.AsUnitFactor(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
if balance.Units, err = NewDecimalFromFloat64(ext.Units); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
// APICostIncrement represent one CostIncrement inside an APIBalance
|
||||
type APICostIncrement struct {
|
||||
FilterIDs []string
|
||||
Increment *float64
|
||||
FixedFee *float64
|
||||
RecurrentFee *float64
|
||||
}
|
||||
|
||||
func (ext *APICostIncrement) AsCostIncrement() (cIncr *CostIncrement, err error) {
|
||||
cIncr = &CostIncrement{
|
||||
FilterIDs: ext.FilterIDs,
|
||||
}
|
||||
if ext.Increment != nil {
|
||||
if cIncr.Increment, err = NewDecimalFromFloat64(*ext.Increment); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if ext.FixedFee != nil {
|
||||
if cIncr.FixedFee, err = NewDecimalFromFloat64(*ext.FixedFee); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if ext.RecurrentFee != nil {
|
||||
if cIncr.RecurrentFee, err = NewDecimalFromFloat64(*ext.RecurrentFee); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// APIUnitFactor represent one UnitFactor inside an APIBalance
|
||||
type APIUnitFactor struct {
|
||||
FilterIDs []string
|
||||
Factor float64
|
||||
}
|
||||
|
||||
func (ext *APIUnitFactor) AsUnitFactor() (uFac *UnitFactor, err error) {
|
||||
uFac = &UnitFactor{
|
||||
FilterIDs: ext.FilterIDs,
|
||||
}
|
||||
if uFac.Factor, err = NewDecimalFromFloat64(ext.Factor); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ func TestCloneBalance(t *testing.T) {
|
||||
Factor: &Decimal{decimal.New(20, 2)},
|
||||
},
|
||||
},
|
||||
Units: 1.25,
|
||||
Units: &Decimal{decimal.New(125, 3)},
|
||||
}
|
||||
if rcv := expBlc.Clone(); !reflect.DeepEqual(rcv, expBlc) {
|
||||
t.Errorf("Expected %+v \n, received %+v", ToJSON(expBlc), ToJSON(rcv))
|
||||
@@ -96,7 +96,7 @@ func TestCloneAccountProfile(t *testing.T) {
|
||||
Factor: &Decimal{decimal.New(20, 2)},
|
||||
},
|
||||
},
|
||||
Units: 1.25,
|
||||
Units: &Decimal{decimal.New(125, 3)},
|
||||
},
|
||||
},
|
||||
ThresholdIDs: []string{"*none"},
|
||||
|
||||
Reference in New Issue
Block a user