diff --git a/accounts/concretebalance.go b/accounts/concretebalance.go
index 8a7577d64..8566529ab 100644
--- a/accounts/concretebalance.go
+++ b/accounts/concretebalance.go
@@ -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
}
diff --git a/accounts/concretebalance_test.go b/accounts/concretebalance_test.go
index 5107bd583..13bfae8e2 100644
--- a/accounts/concretebalance_test.go
+++ b/accounts/concretebalance_test.go
@@ -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)
}
}
diff --git a/apier/v1/accountprofiles.go b/apier/v1/accountprofiles.go
index 941ba1e2f..30fb23e4f 100644
--- a/apier/v1/accountprofiles.go
+++ b/apier/v1/accountprofiles.go
@@ -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
diff --git a/apier/v1/accountprofiles_it_test.go b/apier/v1/accountprofiles_it_test.go
index aceb5b505..acb493bce 100644
--- a/apier/v1/accountprofiles_it_test.go
+++ b/apier/v1/accountprofiles_it_test.go
@@ -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)
}
}
diff --git a/console/accounts_profile.go b/console/accounts_profile.go
new file mode 100644
index 000000000..6b96e885a
--- /dev/null
+++ b/console/accounts_profile.go
@@ -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
+*/
+
+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
+}
diff --git a/console/accounts_profile_ids.go b/console/accounts_profile_ids.go
new file mode 100644
index 000000000..658cd3e67
--- /dev/null
+++ b/console/accounts_profile_ids.go
@@ -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
+*/
+
+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
+}
diff --git a/console/accounts_profile_rem.go b/console/accounts_profile_rem.go
new file mode 100644
index 000000000..05dbb4e1e
--- /dev/null
+++ b/console/accounts_profile_rem.go
@@ -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
+*/
+
+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
+}
diff --git a/console/accounts_profile_set.go b/console/accounts_profile_set.go
new file mode 100644
index 000000000..9b605a8a3
--- /dev/null
+++ b/console/accounts_profile_set.go
@@ -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
+*/
+
+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
+}
diff --git a/engine/model_helpers.go b/engine/model_helpers.go
index 1a87f7157..3403e8f8c 100644
--- a/engine/model_helpers.go
+++ b/engine/model_helpers.go
@@ -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)))
diff --git a/engine/model_helpers_test.go b/engine/model_helpers_test.go
index fcf4ed0a5..dc2102b9c 100644
--- a/engine/model_helpers_test.go
+++ b/engine/model_helpers_test.go
@@ -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",
},
diff --git a/utils/accountprofile.go b/utils/accountprofile.go
index e7f3b94b8..9d17428ef 100644
--- a/utils/accountprofile.go
+++ b/utils/accountprofile.go
@@ -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
+
+}
diff --git a/utils/accountprofile_test.go b/utils/accountprofile_test.go
index 55ac78845..ccf439068 100644
--- a/utils/accountprofile_test.go
+++ b/utils/accountprofile_test.go
@@ -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"},