Add FieldAsInterface implementation for EventCharges

and for types within EventCharges that are required for this
functionality.
This commit is contained in:
ionutboangiu
2023-12-15 11:47:20 -05:00
committed by Dan Christian Bogos
parent d698e8db9d
commit 37578d3743
8 changed files with 1453 additions and 1 deletions

View File

@@ -800,6 +800,22 @@ func (ap *Account) FieldAsInterface(fldPath []string) (_ any, err error) {
if idx < len(ap.FilterIDs) {
return ap.FilterIDs[idx], nil
}
case Weights:
var idx int
if idx, err = strconv.Atoi(*idxStr); err != nil {
return nil, err
}
if idx < len(ap.Weights) {
return ap.Weights[idx], nil
}
case Blockers:
var idx int
if idx, err = strconv.Atoi(*idxStr); err != nil {
return nil, err
}
if idx < len(ap.Blockers) {
return ap.Blockers[idx], nil
}
case ThresholdIDs:
var idx int
if idx, err = strconv.Atoi(*idxStr); err != nil {
@@ -861,6 +877,24 @@ func (ap *Account) FieldAsInterface(fldPath []string) (_ any, err error) {
return bl, nil
}
return bl.FieldAsInterface(fldPath[1:])
case Weights:
var idx int
if idx, err = strconv.Atoi(*idxStr); err != nil {
return
}
if idx >= len(ap.Weights) {
return nil, fmt.Errorf("invalid index for '%s' field", Weights)
}
return ap.Weights[idx].FieldAsInterface(fldPath[1:])
case Blockers:
var idx int
if idx, err = strconv.Atoi(*idxStr); err != nil {
return
}
if idx >= len(ap.Blockers) {
return nil, fmt.Errorf("invalid index for '%s' field", Blockers)
}
return ap.Blockers[idx].FieldAsInterface(fldPath[1:])
}
}
@@ -887,6 +921,22 @@ func (bL *Balance) FieldAsInterface(fldPath []string) (_ any, err error) {
if idx < len(bL.FilterIDs) {
return bL.FilterIDs[idx], nil
}
case Weights:
var idx int
if idx, err = strconv.Atoi(*idxStr); err != nil {
return nil, err
}
if idx < len(bL.Weights) {
return bL.Weights[idx], nil
}
case Blockers:
var idx int
if idx, err = strconv.Atoi(*idxStr); err != nil {
return nil, err
}
if idx < len(bL.Blockers) {
return bL.Blockers[idx], nil
}
case AttributeIDs:
var idx int
if idx, err = strconv.Atoi(*idxStr); err != nil {
@@ -955,6 +1005,24 @@ func (bL *Balance) FieldAsInterface(fldPath []string) (_ any, err error) {
switch fld {
default:
return nil, ErrNotFound
case Weights:
var idx int
if idx, err = strconv.Atoi(*idxStr); err != nil {
return
}
if idx >= len(bL.Weights) {
return nil, fmt.Errorf("invalid index for '%s' field", Weights)
}
return bL.Weights[idx].FieldAsInterface(fldPath[1:])
case Blockers:
var idx int
if idx, err = strconv.Atoi(*idxStr); err != nil {
return
}
if idx >= len(bL.Blockers) {
return nil, fmt.Errorf("invalid index for '%s' field", Blockers)
}
return bL.Blockers[idx].FieldAsInterface(fldPath[1:])
case Opts:
path := fldPath[1:]
if idxStr != nil {

View File

@@ -78,6 +78,27 @@ func (blckr DynamicBlocker) String(blkSep, fltrSep string) (out string) {
return strings.Join(blckr.FilterIDs, fltrSep) + blkSep + blocker
}
func (dB *DynamicBlocker) FieldAsInterface(fldPath []string) (any, error) {
if len(fldPath) != 1 {
return nil, ErrNotFound
}
switch fldPath[0] {
case FilterIDs:
return dB.FilterIDs, nil
case Blocker:
return dB.Blocker, nil
default:
fld, idx := GetPathIndex(fldPath[0])
if idx != nil &&
fld == FilterIDs {
if *idx < len(dB.FilterIDs) {
return dB.FilterIDs[*idx], nil
}
}
}
return nil, ErrNotFound
}
// Clone will clone the Blockers
func (blckrs DynamicBlockers) Clone() (clBlkrs DynamicBlockers) {
if blckrs == nil {

View File

@@ -396,6 +396,7 @@ const (
UnitCounters = "UnitCounters"
UpdateTime = "UpdateTime"
Rates = "Rates"
RateField = "Rate"
Format = "Format"
Conn = "Conn"
Level = "Level"
@@ -526,8 +527,12 @@ const (
RateIncrement = "RateIncrement"
RateUnit = "RateUnit"
BalanceUUID = "BalanceUUID"
ChargingID = "ChargingID"
RatingID = "RatingID"
JoinedChargeIDs = "JoinedChargeIDs"
UnitFactorID = "UnitFactorID"
ExtraChargeID = "ExtraChargeID"
BalanceLimit = "BalanceLimit"
ConnectFee = "ConnectFee"
RoundingMethod = "RoundingMethod"
RoundingDecimals = "RoundingDecimals"
@@ -761,6 +766,7 @@ const (
MetaRounding = "*rounding"
StatsNA = -1.0
InvalidUsage = -1
Abstracts = "Abstracts"
Concretes = "Concretes"
ActionS = "ActionS"
Schedule = "Schedule"
@@ -807,12 +813,16 @@ const (
Unit = "Unit"
Targets = "Targets"
Balances = "Balances"
UnitFactorField = "UnitFactor"
UnitFactors = "UnitFactors"
JoinedCharge = "JoinedCharge"
CostIncrements = "CostIncrements"
Factor = "Factor"
Increment = "Increment"
FixedFee = "FixedFee"
RecurrentFee = "RecurrentFee"
IncrementStart = "IncrementStart"
RateIntervalIndex = "RateIntervalIndex"
Diktats = "Diktats"
BalanceIDs = "BalanceIDs"
MetaCostIncrement = "*costIncrement"

View File

@@ -144,6 +144,8 @@ func SubstractDecimal(x, y *Decimal) *Decimal {
// NewDecimalFromFloat64 is a constructor for Decimal out of float64
// passing through string is necessary due to differences between decimal and binary representation of float64
func NewDecimalFromFloat64(f float64) *Decimal {
// Might want to use SetFloat here.
d, _ := decimal.WithContext(DecimalContext).SetString(strconv.FormatFloat(f, 'f', -1, 64))
return &Decimal{d}
}

View File

@@ -100,6 +100,27 @@ func (dW *DynamicWeight) Clone() (cln *DynamicWeight) {
return cln
}
func (dW *DynamicWeight) FieldAsInterface(fldPath []string) (any, error) {
if len(fldPath) != 1 {
return nil, ErrNotFound
}
switch fldPath[0] {
case FilterIDs:
return dW.FilterIDs, nil
case Weight:
return dW.Weight, nil
default:
fld, idx := GetPathIndex(fldPath[0])
if idx != nil &&
fld == FilterIDs {
if *idx < len(dW.FilterIDs) {
return dW.FilterIDs[*idx], nil
}
}
}
return nil, ErrNotFound
}
func (dW DynamicWeights) Clone() (dinWeight DynamicWeights) {
if dW == nil {
return

View File

@@ -18,7 +18,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package utils
import "slices"
import (
"fmt"
"slices"
)
// NewEventChargers instantiates the EventChargers in a central place
func NewEventCharges() (ec *EventCharges) {
@@ -109,6 +112,19 @@ func (ce *ChargeEntry) Clone() *ChargeEntry {
}
}
func (ce *ChargeEntry) FieldAsInterface(fldPath []string) (_ any, err error) {
if len(fldPath) != 1 {
return nil, ErrNotFound
}
switch fldPath[0] {
case CompressFactor:
return ce.CompressFactor, nil
case ChargingID:
return ce.ChargingID, nil
}
return nil, fmt.Errorf("unsupported field prefix: <%s>", fldPath[0])
}
// Merge will merge the event charges into existing
func (ec *EventCharges) Merge(eCs ...*EventCharges) {
//ec.SyncIDs(eCs...) // so we can compare properly
@@ -317,6 +333,46 @@ type AccountCharge struct {
JoinedChargeIDs []string // identificator of extra account charges
}
func (ac *AccountCharge) FieldAsInterface(fldPath []string) (any, error) {
if len(fldPath) != 1 {
return nil, ErrNotFound
}
switch fldPath[0] {
case AccountID:
return ac.AccountID, nil
case BalanceID:
return ac.BalanceID, nil
case Units:
return ac.Units, nil
case BalanceLimit:
return ac.BalanceLimit, nil
case UnitFactorID:
return ac.UnitFactorID, nil
case AttributeIDs:
return ac.AttributeIDs, nil
case RatingID:
return ac.RatingID, nil
case JoinedChargeIDs:
return ac.JoinedChargeIDs, nil
default:
opath, indx := GetPathIndex(fldPath[0])
if indx != nil {
switch opath {
case AttributeIDs:
if *indx < len(ac.AttributeIDs) {
return ac.AttributeIDs[*indx], nil
}
case JoinedChargeIDs:
if *indx < len(ac.JoinedChargeIDs) {
return ac.JoinedChargeIDs[*indx], nil
}
}
return nil, ErrNotFound
}
}
return nil, fmt.Errorf("unsupported field prefix: <%s>", fldPath[0])
}
// Clone returns a copy of ac
func (ac *AccountCharge) Clone() *AccountCharge {
cln := &AccountCharge{
@@ -379,3 +435,236 @@ type APIEventCharges struct {
APIOpts map[string]any
*EventCharges
}
// String returns the string representation of an *EventCharges value. Needed
// in order to satisfy the DataProvider interface.
func (ec *EventCharges) String() string {
return ToJSON(ec)
}
// FieldAsInterface retrieves a value of a field based on its path from within an *EventCharges
// value. Needed in order to satisfy the DataProvider interface.
func (ec *EventCharges) FieldAsInterface(fldPath []string) (any, error) {
switch fldPath[0] {
default: // "e.g. Charges[1]"
opath, indx := GetPathIndex(fldPath[0])
if opath != Charges {
return nil, fmt.Errorf("unsupported field prefix: <%s>", opath)
}
if indx == nil {
return nil, fmt.Errorf("invalid index for '%s' field", Charges)
}
if len(ec.Charges) <= *indx {
return nil, ErrNotFound
}
return ec.getChargesForPath(fldPath[1:], ec.Charges[*indx])
case Abstracts:
if len(fldPath) != 1 {
return nil, ErrNotFound
}
return ec.Abstracts, nil
case Concretes:
if len(fldPath) != 1 {
return nil, ErrNotFound
}
return ec.Concretes, nil
case Charges:
if len(fldPath) != 1 { // slice has no members
return nil, ErrNotFound
}
return ec.Charges, nil
case Accounting:
if len(fldPath) == 1 {
return ec.Accounting, nil
}
if ec.Accounting == nil {
return nil, ErrNotFound
}
accCharge, has := ec.Accounting[fldPath[1]]
if !has || accCharge == nil {
return nil, ErrNotFound
}
if len(fldPath) == 2 {
return accCharge, nil
}
return accCharge.FieldAsInterface(fldPath[2:])
case UnitFactorField:
if len(fldPath) == 1 {
return ec.UnitFactors, nil
}
if ec.UnitFactors == nil {
return nil, ErrNotFound
}
unitFactor, has := ec.UnitFactors[fldPath[1]]
if !has || unitFactor == nil {
return nil, ErrNotFound
}
if len(fldPath) == 2 {
return unitFactor, nil
}
return unitFactor.FieldAsInterface(fldPath[2:])
case Rating:
if len(fldPath) == 1 {
return ec.Rating, nil
}
if ec.Rating == nil {
return nil, ErrNotFound
}
rtInterval, has := ec.Rating[fldPath[1]]
if !has || rtInterval == nil {
return nil, ErrNotFound
}
if len(fldPath) == 2 {
return rtInterval, nil
}
return rtInterval.FieldAsInterface(fldPath[2:])
case RateField:
if len(fldPath) == 1 {
return ec.Rates, nil
}
if ec.Rates == nil {
return nil, ErrNotFound
}
rate, has := ec.Rates[fldPath[1]]
if !has || rate == nil {
return nil, ErrNotFound
}
if len(fldPath) == 2 {
return rate, nil
}
return rate.FieldAsInterface(fldPath[2:])
case AccountField:
if len(fldPath) == 1 {
return ec.Accounts, nil
}
if ec.Accounts == nil {
return nil, ErrNotFound
}
acc, has := ec.Accounts[fldPath[1]]
if !has || acc == nil {
return nil, ErrNotFound
}
if len(fldPath) == 2 {
return acc, nil
}
return acc.FieldAsInterface(fldPath[2:])
}
}
func (ec *EventCharges) FieldAsString(fldPath []string) (string, error) {
val, err := ec.FieldAsInterface(fldPath)
if err != nil {
return "", nil
}
return IfaceAsString(val), nil
}
func (ec *EventCharges) getChargesForPath(fldPath []string, chr *ChargeEntry) (val any, err error) {
if chr == nil {
return nil, ErrNotFound
}
if len(fldPath) == 0 {
return chr, nil
}
switch fldPath[0] {
case Rating:
return ec.getRatingForPath(fldPath[1:], ec.Rating[chr.ChargingID])
case Accounting:
return ec.getAccountingForPath(fldPath[1:], ec.Accounting[chr.ChargingID])
}
return chr.FieldAsInterface(fldPath)
}
func (ec *EventCharges) getAccountingForPath(fldPath []string, accCharge *AccountCharge) (val any, err error) {
if accCharge == nil {
return nil, ErrNotFound
}
if len(fldPath) == 0 {
return accCharge, nil
}
switch fldPath[0] {
case AccountField:
acc := ec.Accounts[accCharge.AccountID]
if acc == nil {
return nil, ErrNotFound
}
if len(fldPath) == 1 {
return acc, nil
}
return acc.FieldAsInterface(fldPath[1:])
case BalanceField:
acc := ec.Accounts[accCharge.AccountID]
if acc == nil {
return nil, ErrNotFound
}
balance := acc.Balances[accCharge.BalanceID]
if balance == nil {
return nil, ErrNotFound
}
if len(fldPath) == 1 {
return balance, nil
}
return balance.FieldAsInterface(fldPath[1:])
case UnitFactorField:
unitFactor := ec.UnitFactors[accCharge.UnitFactorID]
if unitFactor == nil {
return nil, ErrNotFound
}
if len(fldPath) == 1 {
return unitFactor, nil
}
return unitFactor.FieldAsInterface(fldPath[1:])
case Rating:
return ec.getRatingForPath(fldPath[1:], ec.Rating[accCharge.RatingID])
default: // JoinedCharge[0]
opath, indx := GetPathIndex(fldPath[0])
if opath != JoinedCharge {
break
}
if indx == nil {
return nil, fmt.Errorf("invalid index for '%s' field", JoinedCharge)
}
if len(accCharge.JoinedChargeIDs) <= *indx {
return nil, ErrNotFound
}
return ec.getAccountingForPath(fldPath[1:], ec.Accounting[accCharge.JoinedChargeIDs[*indx]])
}
return accCharge.FieldAsInterface(fldPath)
}
func (ec *EventCharges) getRatingForPath(fldPath []string, rtInterval *RateSInterval) (val any, err error) {
if rtInterval == nil {
return nil, ErrNotFound
}
if len(fldPath) == 0 {
return rtInterval, nil
}
opath, indx := GetPathIndex(fldPath[0])
if opath != Increments || indx == nil {
return rtInterval.FieldAsInterface(fldPath)
}
if len(rtInterval.Increments) <= *indx {
return nil, ErrNotFound
}
incr := rtInterval.Increments[*indx]
if len(fldPath) == 1 {
return incr, nil
}
if incr == nil {
return nil, ErrNotFound
}
if fldPath[1] == RateField {
rate := ec.Rates[incr.RateID]
if rate == nil {
return nil, ErrNotFound
}
if len(fldPath) == 2 {
return rate, nil
}
return rate.FieldAsInterface(fldPath[2:])
}
return incr.FieldAsInterface(fldPath[1:])
}

View File

@@ -2029,3 +2029,989 @@ func TestEqualsAccounting(t *testing.T) {
equalsAccounting(acc1, acc2, accM1, accM2, uf1, uf2, rat1, rat2, rts1, rts2)
equalsAccounting(acc10, acc20, accM10, accM20, uf1, uf2, rat1, rat2, rts1, rts2)
}
func TestEventChargesFieldAsInterface(t *testing.T) {
// ToDo: Replace the randomly assigned values with ones resulted from a real charge. For
// the moment this is enough to test the field retrieval functionality with FieldAsInterface.
ec := &EventCharges{
Concretes: &Decimal{decimal.New(152, 1)},
Abstracts: &Decimal{decimal.New(145, 1)},
Charges: []*ChargeEntry{
{
ChargingID: "accounting1",
CompressFactor: 1,
},
{
ChargingID: "rating1",
CompressFactor: 2,
},
},
Accounting: map[string]*AccountCharge{
"accounting1": {
AccountID: "acc1",
BalanceID: "balance1",
Units: &Decimal{decimal.New(10, 0)},
BalanceLimit: &Decimal{decimal.New(0, 0)},
UnitFactorID: "unit_factor1",
AttributeIDs: []string{"attr1", "attr2"},
RatingID: "rating2",
JoinedChargeIDs: []string{"joined_charge"},
},
"joined_charge": {
AccountID: "acc2",
BalanceID: "balance2",
Units: &Decimal{decimal.New(10, 0)},
BalanceLimit: &Decimal{decimal.New(0, 0)},
UnitFactorID: "unit_factor2",
AttributeIDs: []string{"attr3", "attr4"},
RatingID: "rating3",
JoinedChargeIDs: []string{},
},
},
UnitFactors: map[string]*UnitFactor{
"unit_factor1": {
FilterIDs: []string{"fltr1", "fltr2"},
Factor: &Decimal{decimal.New(2, 0)},
},
"unit_factor2": {
FilterIDs: []string{"fltr3", "fltr4"},
Factor: &Decimal{decimal.New(3, 0)},
},
},
Rating: map[string]*RateSInterval{
"rating1": {
IntervalStart: &Decimal{decimal.New(4, 0)},
Increments: []*RateSIncrement{
{
IncrementStart: &Decimal{decimal.New(5, 0)},
RateIntervalIndex: 1,
RateID: "rate1",
CompressFactor: 1,
Usage: &Decimal{decimal.New(6, 0)},
},
{
IncrementStart: &Decimal{decimal.New(7, 0)},
RateIntervalIndex: 2,
RateID: "rate2",
CompressFactor: 1,
Usage: &Decimal{decimal.New(8, 0)},
},
},
CompressFactor: 3,
},
"rating2": {
IntervalStart: &Decimal{decimal.New(5, 0)},
Increments: []*RateSIncrement{
{
IncrementStart: &Decimal{decimal.New(9, 0)},
RateIntervalIndex: 3,
RateID: "rate1",
CompressFactor: 1,
Usage: &Decimal{decimal.New(10, 0)},
},
},
CompressFactor: 3,
},
"rating3": {
IntervalStart: &Decimal{},
Increments: []*RateSIncrement{
{
IncrementStart: &Decimal{decimal.New(11, 0)},
RateIntervalIndex: 4,
RateID: "rate2",
CompressFactor: 5,
Usage: &Decimal{decimal.New(12, 0)},
},
},
CompressFactor: 3,
},
},
Rates: map[string]*IntervalRate{
"rate1": {
IntervalStart: &Decimal{decimal.New(1, 0)},
FixedFee: &Decimal{decimal.New(2, 0)},
RecurrentFee: &Decimal{decimal.New(3, 0)},
Unit: &Decimal{decimal.New(4, 0)},
Increment: &Decimal{decimal.New(5, 0)},
},
"rate2": {
IntervalStart: &Decimal{decimal.New(6, 0)},
FixedFee: &Decimal{decimal.New(7, 0)},
RecurrentFee: &Decimal{decimal.New(8, 0)},
Unit: &Decimal{decimal.New(9, 0)},
Increment: &Decimal{decimal.New(10, 0)},
},
},
Accounts: map[string]*Account{
"acc1": {
Tenant: "cgrates.org",
FilterIDs: []string{"fltr1"},
ID: "acc1",
Weights: DynamicWeights{
{
FilterIDs: []string{"fltr2"},
Weight: 10,
},
},
Blockers: DynamicBlockers{
{
FilterIDs: []string{"fltr3"},
Blocker: true,
},
},
Opts: map[string]any{
"opt1": "value1",
},
Balances: map[string]*Balance{
"balance1": {
ID: "balance1",
FilterIDs: []string{"fltr4"},
Weights: DynamicWeights{
{
FilterIDs: []string{"fltr3"},
Weight: 20,
},
},
Blockers: DynamicBlockers{
{
FilterIDs: []string{"fltr3"},
Blocker: true,
},
},
Type: MetaMonetary,
Units: &Decimal{decimal.New(1, 0)},
UnitFactors: []*UnitFactor{
{
FilterIDs: []string{"fltr1", "fltr2"},
Factor: &Decimal{decimal.New(2, 0)},
},
},
Opts: map[string]any{
"opt1": "value1",
},
CostIncrements: []*CostIncrement{
{
FilterIDs: []string{"fltr3"},
Increment: &Decimal{decimal.New(3, 0)},
FixedFee: &Decimal{decimal.New(1, 0)},
RecurrentFee: &Decimal{decimal.New(2, 0)},
},
},
AttributeIDs: []string{"attr1"},
RateProfileIDs: []string{"rate_prf1"},
},
"balance2": {
ID: "balance2",
FilterIDs: []string{"fltr3"},
Weights: DynamicWeights{
{
FilterIDs: []string{"fltr5"},
Weight: 20,
},
},
Blockers: DynamicBlockers{
{
FilterIDs: []string{"fltr5"},
Blocker: true,
},
},
Type: MetaVoice,
Units: &Decimal{decimal.New(5, 0)},
UnitFactors: []*UnitFactor{
{
FilterIDs: []string{"fltr3", "fltr4"},
Factor: &Decimal{decimal.New(1, 0)},
},
},
Opts: map[string]any{
"opts1": "value1",
},
CostIncrements: []*CostIncrement{
{
FilterIDs: []string{"fltr2"},
Increment: &Decimal{decimal.New(1, 0)},
FixedFee: &Decimal{decimal.New(2, 0)},
RecurrentFee: &Decimal{decimal.New(3, 0)},
},
},
AttributeIDs: []string{"attr2"},
RateProfileIDs: []string{"rate_prf2"},
},
},
},
"acc2": {
Tenant: "cgrates.org",
FilterIDs: []string{"fltr2"},
ID: "acc2",
Weights: DynamicWeights{
{
FilterIDs: []string{"fltr2"},
Weight: 10,
},
},
Blockers: DynamicBlockers{
{
FilterIDs: []string{"fltr3"},
Blocker: true,
},
},
Opts: map[string]any{
"opt2": "value2",
},
Balances: map[string]*Balance{
"balance1": {
ID: "balance1",
FilterIDs: []string{"fltr4"},
Weights: DynamicWeights{
{
FilterIDs: []string{"fltr1"},
Weight: 20,
},
},
Blockers: DynamicBlockers{
{
FilterIDs: []string{"fltr3"},
Blocker: false,
},
},
Type: MetaMonetary,
Units: &Decimal{decimal.New(11, 0)},
UnitFactors: []*UnitFactor{
{
FilterIDs: []string{"fltr3", "fltr4"},
Factor: &Decimal{},
},
},
Opts: map[string]any{
"opts2": "value2",
},
CostIncrements: []*CostIncrement{
{
FilterIDs: []string{"fltr3"},
Increment: &Decimal{decimal.New(12, 0)},
FixedFee: &Decimal{decimal.New(13, 0)},
RecurrentFee: &Decimal{decimal.New(14, 0)},
},
},
AttributeIDs: []string{"attr3"},
RateProfileIDs: []string{"rate_prf3"},
},
},
},
},
}
testcases := []struct {
name string
fields []string
exp any
}{
{
name: "Concretes",
fields: []string{"Concretes"},
exp: "15.2",
},
{
name: "Abstracts",
fields: []string{"Abstracts"},
exp: "14.5",
},
{
name: "Charges",
fields: []string{"Charges"},
exp: `[{"ChargingID":"accounting1","CompressFactor":1},{"ChargingID":"rating1","CompressFactor":2}]`,
},
{
name: "Charges[1]",
fields: []string{"Charges[1]"},
exp: `{"ChargingID":"rating1","CompressFactor":2}`,
},
{
name: "Charges[1].ChargingID",
fields: []string{"Charges[1]", "ChargingID"},
exp: "rating1",
},
{
name: "Charges[1].CompressFactor",
fields: []string{"Charges[1]", "CompressFactor"},
exp: "2",
},
{
name: "Charges[0].Accounting",
fields: []string{"Charges[0]", "Accounting"},
exp: `{"AccountID":"acc1","BalanceID":"balance1","Units":10,"BalanceLimit":0,"UnitFactorID":"unit_factor1","AttributeIDs":["attr1","attr2"],"RatingID":"rating2","JoinedChargeIDs":["joined_charge"]}`,
},
{
name: "Charges[0].Accounting.AccountID",
fields: []string{"Charges[0]", "Accounting", "AccountID"},
exp: "acc1",
},
{
name: "Charges[0].Accounting.BalanceID",
fields: []string{"Charges[0]", "Accounting", "BalanceID"},
exp: "balance1",
},
{
name: "Charges[0].Accounting.Units",
fields: []string{"Charges[0]", "Accounting", "Units"},
exp: "10",
},
{
name: "Charges[0].Accounting.BalanceLimit",
fields: []string{"Charges[0]", "Accounting", "BalanceLimit"},
exp: "0",
},
{
name: "Charges[0].Accounting.UnitFactorID",
fields: []string{"Charges[0]", "Accounting", "UnitFactorID"},
exp: "unit_factor1",
},
{
name: "Charges[0].Accounting.AttributeIDs",
fields: []string{"Charges[0]", "Accounting", "AttributeIDs"},
exp: `["attr1","attr2"]`,
},
{
name: "Charges[0].Accounting.AttributeIDs[1]",
fields: []string{"Charges[0]", "Accounting", "AttributeIDs[1]"},
exp: "attr2",
},
{
name: "Charges[0].Accounting.RatingID",
fields: []string{"Charges[0]", "Accounting", "RatingID"},
exp: "rating2",
},
{
name: "Charges[0].Accounting.JoinedChargeIDs",
fields: []string{"Charges[0]", "Accounting", "JoinedChargeIDs"},
exp: `["joined_charge"]`,
},
{
name: "Charges[0].Accounting.JoinedChargeIDs[0]",
fields: []string{"Charges[0]", "Accounting", "JoinedChargeIDs[0]"},
exp: "joined_charge",
},
{
name: "Charges[0].Accounting.Account",
fields: []string{"Charges[0]", "Accounting", "Account"},
exp: `{"Tenant":"cgrates.org","ID":"acc1","FilterIDs":["fltr1"],"Weights":[{"FilterIDs":["fltr2"],"Weight":10}],"Blockers":[{"FilterIDs":["fltr3"],"Blocker":true}],"Opts":{"opt1":"value1"},"Balances":{"balance1":{"ID":"balance1","FilterIDs":["fltr4"],"Weights":[{"FilterIDs":["fltr3"],"Weight":20}],"Blockers":[{"FilterIDs":["fltr3"],"Blocker":true}],"Type":"*monetary","Units":1,"UnitFactors":[{"FilterIDs":["fltr1","fltr2"],"Factor":2}],"Opts":{"opt1":"value1"},"CostIncrements":[{"FilterIDs":["fltr3"],"Increment":3,"FixedFee":1,"RecurrentFee":2}],"AttributeIDs":["attr1"],"RateProfileIDs":["rate_prf1"]},"balance2":{"ID":"balance2","FilterIDs":["fltr3"],"Weights":[{"FilterIDs":["fltr5"],"Weight":20}],"Blockers":[{"FilterIDs":["fltr5"],"Blocker":true}],"Type":"*voice","Units":5,"UnitFactors":[{"FilterIDs":["fltr3","fltr4"],"Factor":1}],"Opts":{"opts1":"value1"},"CostIncrements":[{"FilterIDs":["fltr2"],"Increment":1,"FixedFee":2,"RecurrentFee":3}],"AttributeIDs":["attr2"],"RateProfileIDs":["rate_prf2"]}},"ThresholdIDs":null}`,
},
{
name: "Charges[0].Accounting.Account.Tenant",
fields: []string{"Charges[0]", "Accounting", "Account", "Tenant"},
exp: "cgrates.org",
},
{
name: "Charges[0].Accounting.Account.FilterIDs",
fields: []string{"Charges[0]", "Accounting", "Account", "FilterIDs"},
exp: `["fltr1"]`,
},
{
name: "Charges[0].Accounting.Account.FilterIDs[0]",
fields: []string{"Charges[0]", "Accounting", "Account", "FilterIDs[0]"},
exp: "fltr1",
},
{
name: "Charges[0].Accounting.Account.ID",
fields: []string{"Charges[0]", "Accounting", "Account", "ID"},
exp: "acc1",
},
{
name: "Charges[0].Accounting.Account.Weights",
fields: []string{"Charges[0]", "Accounting", "Account", "Weights"},
exp: "fltr2;10",
},
{
name: "Charges[0].Accounting.Account.Weights[0]",
fields: []string{"Charges[0]", "Accounting", "Account", "Weights[0]"},
exp: `{"FilterIDs":["fltr2"],"Weight":10}`,
},
{
name: "Charges[0].Accounting.Account.Weights[0].FilterIDs",
fields: []string{"Charges[0]", "Accounting", "Account", "Weights[0]", "FilterIDs"},
exp: `["fltr2"]`,
},
{
name: "Charges[0].Accounting.Account.Weights[0].FilterIDs[0]",
fields: []string{"Charges[0]", "Accounting", "Account", "Weights[0]", "FilterIDs[0]"},
exp: "fltr2",
},
{
name: "Charges[0].Accounting.Account.Weights[0].Weight",
fields: []string{"Charges[0]", "Accounting", "Account", "Weights[0]", "Weight"},
exp: "10",
},
{
name: "Charges[0].Accounting.Account.Blockers",
fields: []string{"Charges[0]", "Accounting", "Account", "Blockers"},
exp: "fltr3;true",
},
{
name: "Charges[0].Accounting.Account.Blockers[0]",
fields: []string{"Charges[0]", "Accounting", "Account", "Blockers[0]"},
exp: `{"FilterIDs":["fltr3"],"Blocker":true}`,
},
{
name: "Charges[0].Accounting.Account.Blockers[0].FilterIDs",
fields: []string{"Charges[0]", "Accounting", "Account", "Blockers[0]", "FilterIDs"},
exp: `["fltr3"]`,
},
{
name: "Charges[0].Accounting.Account.Blockers[0].FilterIDs[0]",
fields: []string{"Charges[0]", "Accounting", "Account", "Blockers[0]", "FilterIDs[0]"},
exp: "fltr3",
},
{
name: "Charges[0].Accounting.Account.Blockers[0].Blocker",
fields: []string{"Charges[0]", "Accounting", "Account", "Blockers[0]", "Blocker"},
exp: "true",
},
{
name: "Charges[0].Accounting.Account.Opts",
fields: []string{"Charges[0]", "Accounting", "Account", "Opts"},
exp: `{"opt1":"value1"}`,
},
{
name: "Charges[0].Accounting.Account.Opts.opt1",
fields: []string{"Charges[0]", "Accounting", "Account", "Opts", "opt1"},
exp: "value1",
},
{
name: "Charges[0].Accounting.Account.Balances",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances"},
exp: `{"balance1":{"ID":"balance1","FilterIDs":["fltr4"],"Weights":[{"FilterIDs":["fltr3"],"Weight":20}],"Blockers":[{"FilterIDs":["fltr3"],"Blocker":true}],"Type":"*monetary","Units":1,"UnitFactors":[{"FilterIDs":["fltr1","fltr2"],"Factor":2}],"Opts":{"opt1":"value1"},"CostIncrements":[{"FilterIDs":["fltr3"],"Increment":3,"FixedFee":1,"RecurrentFee":2}],"AttributeIDs":["attr1"],"RateProfileIDs":["rate_prf1"]},"balance2":{"ID":"balance2","FilterIDs":["fltr3"],"Weights":[{"FilterIDs":["fltr5"],"Weight":20}],"Blockers":[{"FilterIDs":["fltr5"],"Blocker":true}],"Type":"*voice","Units":5,"UnitFactors":[{"FilterIDs":["fltr3","fltr4"],"Factor":1}],"Opts":{"opts1":"value1"},"CostIncrements":[{"FilterIDs":["fltr2"],"Increment":1,"FixedFee":2,"RecurrentFee":3}],"AttributeIDs":["attr2"],"RateProfileIDs":["rate_prf2"]}}`,
},
{
name: "Charges[0].Accounting.Account.Balances.balance1",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1"},
exp: `{"ID":"balance1","FilterIDs":["fltr4"],"Weights":[{"FilterIDs":["fltr3"],"Weight":20}],"Blockers":[{"FilterIDs":["fltr3"],"Blocker":true}],"Type":"*monetary","Units":1,"UnitFactors":[{"FilterIDs":["fltr1","fltr2"],"Factor":2}],"Opts":{"opt1":"value1"},"CostIncrements":[{"FilterIDs":["fltr3"],"Increment":3,"FixedFee":1,"RecurrentFee":2}],"AttributeIDs":["attr1"],"RateProfileIDs":["rate_prf1"]}`,
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.ID",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "ID"},
exp: "balance1",
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.FilterIDs",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "FilterIDs"},
exp: `["fltr4"]`,
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.FilterIDs[0]",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "FilterIDs[0]"},
exp: "fltr4",
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.Weights",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "Weights"},
exp: "fltr3;20",
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.Weights[0]",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "Weights[0]"},
exp: `{"FilterIDs":["fltr3"],"Weight":20}`,
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.Weights[0].FilterIDs",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "Weights[0]", "FilterIDs"},
exp: `["fltr3"]`,
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.Weights[0].FilterIDs[0]",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "Weights[0]", "FilterIDs[0]"},
exp: "fltr3",
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.Weights[0].Weight",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "Weights[0]", "Weight"},
exp: "20",
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.Blockers",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "Blockers"},
exp: "fltr3;true",
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.Blockers[0]",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "Blockers[0]"},
exp: `{"FilterIDs":["fltr3"],"Blocker":true}`,
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.Blockers[0].FilterIDs",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "Blockers[0]", "FilterIDs"},
exp: `["fltr3"]`,
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.Blockers[0].FilterIDs[0]",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "Blockers[0]", "FilterIDs[0]"},
exp: "fltr3",
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.Blockers[0].Blocker",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "Blockers[0]", "Blocker"},
exp: "true",
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.Type",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "Type"},
exp: MetaMonetary,
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.Units",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "Units"},
exp: "1",
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.UnitFactors",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "UnitFactors"},
exp: `[{"FilterIDs":["fltr1","fltr2"],"Factor":2}]`,
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.UnitFactors[0]",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "UnitFactors[0]"},
exp: `{"FilterIDs":["fltr1","fltr2"],"Factor":2}`,
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.UnitFactors[0].FilterIDs",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "UnitFactors[0]", "FilterIDs"},
exp: `["fltr1","fltr2"]`,
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.UnitFactors[0].FilterIDs[1]",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "UnitFactors[0]", "FilterIDs[1]"},
exp: "fltr2",
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.UnitFactors[0].Factor",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "UnitFactors[0]", "Factor"},
exp: "2",
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.Opts",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "Opts"},
exp: `{"opt1":"value1"}`,
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.Opts.opt1",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "Opts", "opt1"},
exp: "value1",
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.CostIncrements",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "CostIncrements"},
exp: `[{"FilterIDs":["fltr3"],"Increment":3,"FixedFee":1,"RecurrentFee":2}]`,
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.CostIncrements[0]",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "CostIncrements[0]"},
exp: `{"FilterIDs":["fltr3"],"Increment":3,"FixedFee":1,"RecurrentFee":2}`,
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.CostIncrements[0].FilterIDs",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "CostIncrements[0]", "FilterIDs"},
exp: `["fltr3"]`,
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.CostIncrements[0].FilterIDs[0]",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "CostIncrements[0]", "FilterIDs[0]"},
exp: "fltr3",
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.CostIncrements[0].Increment",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "CostIncrements[0]", "Increment"},
exp: "3",
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.CostIncrements[0].FixedFee",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "CostIncrements[0]", "FixedFee"},
exp: "1",
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.CostIncrements[0].RecurrentFee",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "CostIncrements[0]", "RecurrentFee"},
exp: "2",
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.AttributeIDs",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "AttributeIDs"},
exp: `["attr1"]`,
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.AttributeIDs[0]",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "AttributeIDs[0]"},
exp: "attr1",
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.RateProfileIDs",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "RateProfileIDs"},
exp: `["rate_prf1"]`,
},
{
name: "Charges[0].Accounting.Account.Balances.balance1.RateProfileIDs[0]",
fields: []string{"Charges[0]", "Accounting", "Account", "Balances", "balance1", "RateProfileIDs[0]"},
exp: "rate_prf1",
},
{
name: "Charges[0].Accounting.Balance",
fields: []string{"Charges[0]", "Accounting", "Balance"},
exp: `{"ID":"balance1","FilterIDs":["fltr4"],"Weights":[{"FilterIDs":["fltr3"],"Weight":20}],"Blockers":[{"FilterIDs":["fltr3"],"Blocker":true}],"Type":"*monetary","Units":1,"UnitFactors":[{"FilterIDs":["fltr1","fltr2"],"Factor":2}],"Opts":{"opt1":"value1"},"CostIncrements":[{"FilterIDs":["fltr3"],"Increment":3,"FixedFee":1,"RecurrentFee":2}],"AttributeIDs":["attr1"],"RateProfileIDs":["rate_prf1"]}`,
},
{
name: "Charges[0].Accounting.Balance.ID",
fields: []string{"Charges[0]", "Accounting", "Balance", "ID"},
exp: "balance1",
},
{
name: "Charges[0].Accounting.Balance.FilterIDs",
fields: []string{"Charges[0]", "Accounting", "Balance", "FilterIDs"},
exp: `["fltr4"]`,
},
{
name: "Charges[0].Accounting.Balance.FilterIDs[0]",
fields: []string{"Charges[0]", "Accounting", "Balance", "FilterIDs[0]"},
exp: "fltr4",
},
{
name: "Charges[0].Accounting.Balance.Weights",
fields: []string{"Charges[0]", "Accounting", "Balance", "Weights"},
exp: "fltr3;20",
},
{
name: "Charges[0].Accounting.Balance.Weights[0]",
fields: []string{"Charges[0]", "Accounting", "Balance", "Weights[0]"},
exp: `{"FilterIDs":["fltr3"],"Weight":20}`,
},
{
name: "Charges[0].Accounting.Balance.Weights[0].FilterIDs",
fields: []string{"Charges[0]", "Accounting", "Balance", "Weights[0]", "FilterIDs"},
exp: `["fltr3"]`,
},
{
name: "Charges[0].Accounting.Balance.Weights[0].FilterIDs[0]",
fields: []string{"Charges[0]", "Accounting", "Balance", "Weights[0]", "FilterIDs[0]"},
exp: "fltr3",
},
{
name: "Charges[0].Accounting.Balance.Weights[0].Weight",
fields: []string{"Charges[0]", "Accounting", "Balance", "Weights[0]", "Weight"},
exp: "20",
},
{
name: "Charges[0].Accounting.Balance.Blockers",
fields: []string{"Charges[0]", "Accounting", "Balance", "Blockers"},
exp: "fltr3;true",
},
{
name: "Charges[0].Accounting.Balance.Blockers[0]",
fields: []string{"Charges[0]", "Accounting", "Balance", "Blockers[0]"},
exp: `{"FilterIDs":["fltr3"],"Blocker":true}`,
},
{
name: "Charges[0].Accounting.Balance.Blockers[0].FilterIDs",
fields: []string{"Charges[0]", "Accounting", "Balance", "Blockers[0]", "FilterIDs"},
exp: `["fltr3"]`,
},
{
name: "Charges[0].Accounting.Balance.Blockers[0].FilterIDs[0]",
fields: []string{"Charges[0]", "Accounting", "Balance", "Blockers[0]", "FilterIDs[0]"},
exp: "fltr3",
},
{
name: "Charges[0].Accounting.Balance.Blockers[0].Blocker",
fields: []string{"Charges[0]", "Accounting", "Balance", "Blockers[0]", "Blocker"},
exp: "true",
},
{
name: "Charges[0].Accounting.Balance.Type",
fields: []string{"Charges[0]", "Accounting", "Balance", "Type"},
exp: MetaMonetary,
},
{
name: "Charges[0].Accounting.Balance.Units",
fields: []string{"Charges[0]", "Accounting", "Balance", "Units"},
exp: "1",
},
{
name: "Charges[0].Accounting.Balance.UnitFactors",
fields: []string{"Charges[0]", "Accounting", "Balance", "UnitFactors"},
exp: `[{"FilterIDs":["fltr1","fltr2"],"Factor":2}]`,
},
{
name: "Charges[0].Accounting.Balance.UnitFactors[0]",
fields: []string{"Charges[0]", "Accounting", "Balance", "UnitFactors[0]"},
exp: `{"FilterIDs":["fltr1","fltr2"],"Factor":2}`,
},
{
name: "Charges[0].Accounting.Balance.UnitFactors[0].FilterIDs",
fields: []string{"Charges[0]", "Accounting", "Balance", "UnitFactors[0]", "FilterIDs"},
exp: `["fltr1","fltr2"]`,
},
{
name: "Charges[0].Accounting.Balance.UnitFactors[0].FilterIDs[1]",
fields: []string{"Charges[0]", "Accounting", "Balance", "UnitFactors[0]", "FilterIDs[1]"},
exp: "fltr2",
},
{
name: "Charges[0].Accounting.Balance.UnitFactors[0].Factor",
fields: []string{"Charges[0]", "Accounting", "Balance", "UnitFactors[0]", "Factor"},
exp: "2",
},
{
name: "Charges[0].Accounting.Balance.Opts",
fields: []string{"Charges[0]", "Accounting", "Balance", "Opts"},
exp: `{"opt1":"value1"}`,
},
{
name: "Charges[0].Accounting.Balance.Opts.opt1",
fields: []string{"Charges[0]", "Accounting", "Balance", "Opts", "opt1"},
exp: "value1",
},
{
name: "Charges[0].Accounting.Balance.CostIncrements",
fields: []string{"Charges[0]", "Accounting", "Balance", "CostIncrements"},
exp: `[{"FilterIDs":["fltr3"],"Increment":3,"FixedFee":1,"RecurrentFee":2}]`,
},
{
name: "Charges[0].Accounting.Balance.CostIncrements[0]",
fields: []string{"Charges[0]", "Accounting", "Balance", "CostIncrements[0]"},
exp: `{"FilterIDs":["fltr3"],"Increment":3,"FixedFee":1,"RecurrentFee":2}`,
},
{
name: "Charges[0].Accounting.Balance.CostIncrements[0].FilterIDs",
fields: []string{"Charges[0]", "Accounting", "Balance", "CostIncrements[0]", "FilterIDs"},
exp: `["fltr3"]`,
},
{
name: "Charges[0].Accounting.Balance.CostIncrements[0].FilterIDs[0]",
fields: []string{"Charges[0]", "Accounting", "Balance", "CostIncrements[0]", "FilterIDs[0]"},
exp: "fltr3",
},
{
name: "Charges[0].Accounting.Balance.CostIncrements[0].Increment",
fields: []string{"Charges[0]", "Accounting", "Balance", "CostIncrements[0]", "Increment"},
exp: "3",
},
{
name: "Charges[0].Accounting.Balance.CostIncrements[0].FixedFee",
fields: []string{"Charges[0]", "Accounting", "Balance", "CostIncrements[0]", "FixedFee"},
exp: "1",
},
{
name: "Charges[0].Accounting.Balance.CostIncrements[0].RecurrentFee",
fields: []string{"Charges[0]", "Accounting", "Balance", "CostIncrements[0]", "RecurrentFee"},
exp: "2",
},
{
name: "Charges[0].Accounting.Balance.AttributeIDs",
fields: []string{"Charges[0]", "Accounting", "Balance", "AttributeIDs"},
exp: `["attr1"]`,
},
{
name: "Charges[0].Accounting.Balance.AttributeIDs[0]",
fields: []string{"Charges[0]", "Accounting", "Balance", "AttributeIDs[0]"},
exp: "attr1",
},
{
name: "Charges[0].Accounting.Balance.RateProfileIDs",
fields: []string{"Charges[0]", "Accounting", "Balance", "RateProfileIDs"},
exp: `["rate_prf1"]`,
},
{
name: "Charges[0].Accounting.Balance.RateProfileIDs[0]",
fields: []string{"Charges[0]", "Accounting", "Balance", "RateProfileIDs[0]"},
exp: "rate_prf1",
},
{
name: "Charges[0].Accounting.UnitFactor",
fields: []string{"Charges[0]", "Accounting", "UnitFactor"},
exp: `{"FilterIDs":["fltr1","fltr2"],"Factor":2}`,
},
{
name: "Charges[0].Accounting.UnitFactor.FilterIDs",
fields: []string{"Charges[0]", "Accounting", "UnitFactor", "FilterIDs"},
exp: `["fltr1","fltr2"]`,
},
{
name: "Charges[0].Accounting.UnitFactor.FilterIDs[0]",
fields: []string{"Charges[0]", "Accounting", "UnitFactor", "FilterIDs[0]"},
exp: "fltr1",
},
{
name: "Charges[0].Accounting.UnitFactor.Factor",
fields: []string{"Charges[0]", "Accounting", "UnitFactor", "Factor"},
exp: "2",
},
{
name: "Charges[0].Accounting.Rating",
fields: []string{"Charges[0]", "Accounting", "Rating"},
exp: `{"IntervalStart":5,"Increments":[{"IncrementStart":9,"RateIntervalIndex":3,"RateID":"rate1","CompressFactor":1,"Usage":10}],"CompressFactor":3}`,
},
{
name: "Charges[0].Accounting.Rating.IntervalStart",
fields: []string{"Charges[0]", "Accounting", "Rating", "IntervalStart"},
exp: "5",
},
{
name: "Charges[0].Accounting.Rating.Increments",
fields: []string{"Charges[0]", "Accounting", "Rating", "Increments"},
exp: `[{"IncrementStart":9,"RateIntervalIndex":3,"RateID":"rate1","CompressFactor":1,"Usage":10}]`,
},
{
name: "Charges[0].Accounting.Rating.Increments[0]",
fields: []string{"Charges[0]", "Accounting", "Rating", "Increments[0]"},
exp: `{"IncrementStart":9,"RateIntervalIndex":3,"RateID":"rate1","CompressFactor":1,"Usage":10}`,
},
{
name: "Charges[0].Accounting.Rating.Increments[0].IncrementStart",
fields: []string{"Charges[0]", "Accounting", "Rating", "Increments[0]", "IncrementStart"},
exp: "9",
},
{
name: "Charges[0].Accounting.Rating.Increments[0].RateIntervalIndex",
fields: []string{"Charges[0]", "Accounting", "Rating", "Increments[0]", "RateIntervalIndex"},
exp: "3",
},
{
name: "Charges[0].Accounting.Rating.Increments[0].RateID",
fields: []string{"Charges[0]", "Accounting", "Rating", "Increments[0]", "RateID"},
exp: "rate1",
},
{
name: "Charges[0].Accounting.Rating.Increments[0].CompressFactor",
fields: []string{"Charges[0]", "Accounting", "Rating", "Increments[0]", "CompressFactor"},
exp: "1",
},
{
name: "Charges[0].Accounting.Rating.Increments[0].Usage",
fields: []string{"Charges[0]", "Accounting", "Rating", "Increments[0]", "Usage"},
exp: "10",
},
{
name: "Charges[0].Accounting.Rating.Increments[0].Rate",
fields: []string{"Charges[0]", "Accounting", "Rating", "Increments[0]", "Rate"},
exp: `{"IntervalStart":1,"FixedFee":2,"RecurrentFee":3,"Unit":4,"Increment":5}`,
},
{
name: "Charges[0].Accounting.Rating.Increments[0].Rate.IntervalStart",
fields: []string{"Charges[0]", "Accounting", "Rating", "Increments[0]", "Rate", "IntervalStart"},
exp: "1",
},
{
name: "Charges[0].Accounting.Rating.Increments[0].Rate.FixedFee",
fields: []string{"Charges[0]", "Accounting", "Rating", "Increments[0]", "Rate", "FixedFee"},
exp: "2",
},
{
name: "Charges[0].Accounting.Rating.Increments[0].Rate.RecurrentFee",
fields: []string{"Charges[0]", "Accounting", "Rating", "Increments[0]", "Rate", "RecurrentFee"},
exp: "3",
},
{
name: "Charges[0].Accounting.Rating.Increments[0].Rate.Unit",
fields: []string{"Charges[0]", "Accounting", "Rating", "Increments[0]", "Rate", "Unit"},
exp: "4",
},
{
name: "Charges[0].Accounting.Rating.Increments[0].Rate.Increment",
fields: []string{"Charges[0]", "Accounting", "Rating", "Increments[0]", "Rate", "Increment"},
exp: "5",
},
{
name: "Charges[0].Accounting.Rating.CompressFactor",
fields: []string{"Charges[0]", "Accounting", "Rating", "CompressFactor"},
exp: "3",
},
{
name: "Charges[1].Rating",
fields: []string{"Charges[1]", "Rating"},
exp: `{"IntervalStart":4,"Increments":[{"IncrementStart":5,"RateIntervalIndex":1,"RateID":"rate1","CompressFactor":1,"Usage":6},{"IncrementStart":7,"RateIntervalIndex":2,"RateID":"rate2","CompressFactor":1,"Usage":8}],"CompressFactor":3}`,
},
{
name: "Charges[1].Rating.IntervalStart",
fields: []string{"Charges[1]", "Rating", "IntervalStart"},
exp: "4",
},
{
name: "Charges[1].Rating.Increments",
fields: []string{"Charges[1]", "Rating", "Increments"},
exp: `[{"IncrementStart":5,"RateIntervalIndex":1,"RateID":"rate1","CompressFactor":1,"Usage":6},{"IncrementStart":7,"RateIntervalIndex":2,"RateID":"rate2","CompressFactor":1,"Usage":8}]`,
},
{
name: "Charges[1].Rating.Increments[1]",
fields: []string{"Charges[1]", "Rating", "Increments[1]"},
exp: `{"IncrementStart":7,"RateIntervalIndex":2,"RateID":"rate2","CompressFactor":1,"Usage":8}`,
},
{
name: "Charges[1].Rating.Increments[1].IncrementStart",
fields: []string{"Charges[1]", "Rating", "Increments[1]", "IncrementStart"},
exp: "7",
},
{
name: "Charges[1].Rating.Increments[1].RateIntervalIndex",
fields: []string{"Charges[1]", "Rating", "Increments[1]", "RateIntervalIndex"},
exp: "2",
},
{
name: "Charges[1].Rating.Increments[1].RateID",
fields: []string{"Charges[1]", "Rating", "Increments[1]", "RateID"},
exp: "rate2",
},
{
name: "Charges[1].Rating.Increments[1].CompressFactor",
fields: []string{"Charges[1]", "Rating", "Increments[1]", "CompressFactor"},
exp: "1",
},
{
name: "Charges[1].Rating.Increments[1].Usage",
fields: []string{"Charges[1]", "Rating", "Increments[1]", "Usage"},
exp: "8",
},
{
name: "Charges[1].Rating.Increments[1].Rate",
fields: []string{"Charges[1]", "Rating", "Increments[1]", "Rate"},
exp: `{"IntervalStart":6,"FixedFee":7,"RecurrentFee":8,"Unit":9,"Increment":10}`,
},
{
name: "Charges[1].Rating.Increments[1].Rate.IntervalStart",
fields: []string{"Charges[1]", "Rating", "Increments[1]", "Rate", "IntervalStart"},
exp: "6",
},
{
name: "Charges[1].Rating.Increments[1].Rate.FixedFee",
fields: []string{"Charges[1]", "Rating", "Increments[1]", "Rate", "FixedFee"},
exp: "7",
},
{
name: "Charges[1].Rating.Increments[1].Rate.RecurrentFee",
fields: []string{"Charges[1]", "Rating", "Increments[1]", "Rate", "RecurrentFee"},
exp: "8",
},
{
name: "Charges[1].Rating.Increments[1].Rate.Unit",
fields: []string{"Charges[1]", "Rating", "Increments[1]", "Rate", "Unit"},
exp: "9",
},
{
name: "Charges[1].Rating.Increments[1].Rate.Increment",
fields: []string{"Charges[1]", "Rating", "Increments[1]", "Rate", "Increment"},
exp: "10",
},
{
name: "Charges[1].Rating.CompressFactor",
fields: []string{"Charges[1]", "Rating", "CompressFactor"},
exp: "3",
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
if val, err := ec.FieldAsString(tc.fields); err != nil {
t.Error(err)
} else if tc.exp != val {
t.Errorf("expected: %s,\nreceived: %s", tc.exp, val)
}
})
}
}

View File

@@ -247,6 +247,42 @@ func (rI *RateSInterval) AsRatesIntervalsCost() (rIc *RateSIntervalCost) {
return
}
func (rI *RateSInterval) FieldAsInterface(fldPath []string) (any, error) {
switch fldPath[0] {
case IntervalStart:
if len(fldPath) != 1 {
return nil, ErrNotFound
}
return rI.IntervalStart, nil
case CompressFactor:
if len(fldPath) != 1 {
return nil, ErrNotFound
}
return rI.CompressFactor, nil
case Increments:
if len(fldPath) != 1 {
return nil, ErrNotFound
}
return rI.Increments, nil
}
opath, indx := GetPathIndex(fldPath[0])
if opath != Increments {
return nil, fmt.Errorf("unsupported field prefix: <%s>", opath)
}
if indx == nil {
return nil, fmt.Errorf("invalid index for '%s' field", JoinedCharge)
}
if len(rI.Increments) <= *indx {
return nil, ErrNotFound
}
incr := rI.Increments[*indx]
if len(fldPath) == 1 {
return incr, nil
}
return incr.FieldAsInterface(fldPath[1:])
}
type RateSIncrement struct {
IncrementStart *Decimal
RateIntervalIndex int
@@ -319,6 +355,25 @@ func (rI *RateSIncrement) Equals(rtIn *RateSIncrement, rIRef, rtInRef map[string
!rIRef[rI.RateID].Equals(rtInRef[rtIn.RateID])))
}
func (rI *RateSIncrement) FieldAsInterface(fldPath []string) (_ any, err error) {
if len(fldPath) != 1 {
return nil, ErrNotFound
}
switch fldPath[0] {
case IncrementStart:
return rI.IncrementStart, nil
case RateIntervalIndex:
return rI.RateIntervalIndex, nil
case RateID:
return rI.RateID, nil
case CompressFactor:
return rI.CompressFactor, nil
case Usage:
return rI.Usage, nil
}
return nil, fmt.Errorf("unsupported field prefix: <%s>", fldPath[0])
}
// RateProfileCost is the cost returned by RateS at cost queries
type RateProfileCost struct {
ID string // RateProfileID