diff --git a/engine/account_test.go b/engine/account_test.go index 88b79e836..36a013a5d 100644 --- a/engine/account_test.go +++ b/engine/account_test.go @@ -21,6 +21,8 @@ package engine import ( "testing" "time" + + "github.com/cgrates/cgrates/cache2go" ) var ( @@ -1033,7 +1035,62 @@ func TestAccountRefund(t *testing.T) { } func TestDebitShared(t *testing.T) { + cc := &CallCost{ + Tenant: "vdf", + TOR: "0", + Direction: OUTBOUND, + Destination: "0723045326", + Timespans: []*TimeSpan{ + &TimeSpan{ + TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 49, 0, 0, time.UTC), + CallDuration: 55 * time.Second, + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 2, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + }, + }, + deductConnectFee: true, + } + rif := &Account{Id: "rif", BalanceMap: map[string]BalanceChain{ + CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 60, SharedGroup: "SG_TEST"}}, + }} + groupie := &Account{Id: "groupie", BalanceMap: map[string]BalanceChain{ + CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneyc", Value: 70, SharedGroup: "SG_TEST"}}, + }} + sg := &SharedGroup{Id: "SG_TEST", Members: []string{rif.Id, groupie.Id}, AccountParameters: map[string]*SharingParameters{"*any": &SharingParameters{Strategy: STRATEGY_RANDOM}}} + + accountingStorage.SetAccount(groupie) + accountingStorage.SetSharedGroup("SG_TEST", sg) + cache2go.Cache(SHARED_GROUP_PREFIX+"SG_TEST", sg) + err := rif.debitCreditBalance(cc, false) + if err != nil { + t.Error("Error debiting balance: ", err) + } + if rif.BalanceMap[CREDIT+OUTBOUND][0].Value != 0 { + t.Errorf("Error debiting from shared group: %+v", rif.BalanceMap[CREDIT+OUTBOUND][0]) + } + groupie, _ = accountingStorage.GetAccount("groupie") + if groupie.BalanceMap[CREDIT+OUTBOUND][0].Value != 10 { + t.Errorf("Error debiting from shared group: %+v", groupie.BalanceMap[CREDIT+OUTBOUND][0]) + } + + if len(cc.Timespans) != 1 { + t.Errorf("Wrong number of timespans: %v", cc.Timespans) + } + if len(cc.Timespans[0].Increments) != 6 { + t.Errorf("Wrong number of increments: %v", cc.Timespans[0].Increments) + for index, incr := range cc.Timespans[0].Increments { + t.Errorf("I%d: %+v (%+v)", index, incr, incr.BalanceInfo) + } + } + if cc.Timespans[0].Increments[0].BalanceInfo.AccountId != "rif" || + cc.Timespans[0].Increments[1].BalanceInfo.AccountId != "rif" || + cc.Timespans[0].Increments[2].BalanceInfo.AccountId != "rif" || + cc.Timespans[0].Increments[3].BalanceInfo.AccountId != "groupie" || + cc.Timespans[0].Increments[4].BalanceInfo.AccountId != "groupie" || + cc.Timespans[0].Increments[5].BalanceInfo.AccountId != "groupie" { + t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) + } } /*********************************** Benchmarks *******************************/ diff --git a/engine/balances.go b/engine/balances.go index 2d726e3a6..57f64b098 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -180,6 +180,7 @@ func (b *Balance) DebitMinutes(cc *CallCost, count bool, ub *Account, moneyBalan b.Value -= amount b.Value = utils.Round(b.Value, roundingDecimals, utils.ROUNDING_MIDDLE) inc.BalanceInfo.MinuteBalanceUuid = b.Uuid + inc.BalanceInfo.AccountId = ub.Id inc.MinuteInfo = &MinuteInfo{cc.Destination, amount} inc.Cost = 0 inc.paid = true @@ -222,6 +223,7 @@ func (b *Balance) DebitMinutes(cc *CallCost, count bool, ub *Account, moneyBalan moneyBal.Value -= cost nInc.BalanceInfo.MinuteBalanceUuid = b.Uuid nInc.BalanceInfo.MoneyBalanceUuid = moneyBal.Uuid + nInc.BalanceInfo.AccountId = ub.Id nInc.MinuteInfo = &MinuteInfo{newCC.Destination, seconds} nInc.paid = true if count { @@ -287,6 +289,7 @@ func (b *Balance) DebitMoney(cc *CallCost, count bool, ub *Account) error { b.Value -= amount b.Value = utils.Round(b.Value, roundingDecimals, utils.ROUNDING_MIDDLE) increment.BalanceInfo.MoneyBalanceUuid = b.Uuid + increment.BalanceInfo.AccountId = ub.Id increment.paid = true if count { ub.countUnits(&Action{BalanceType: CREDIT, Direction: cc.Direction, Balance: &Balance{Value: amount, DestinationId: cc.Destination}}) @@ -316,6 +319,7 @@ func (b *Balance) DebitMoney(cc *CallCost, count bool, ub *Account) error { b.Value -= amount b.Value = utils.Round(b.Value, roundingDecimals, utils.ROUNDING_MIDDLE) nInc.BalanceInfo.MoneyBalanceUuid = b.Uuid + nInc.BalanceInfo.AccountId = ub.Id nInc.paid = true if count { ub.countUnits(&Action{BalanceType: CREDIT, Direction: newCC.Direction, Balance: &Balance{Value: amount, DestinationId: newCC.Destination}}) diff --git a/engine/sharedgroup.go b/engine/sharedgroup.go index de4bf738a..5643d2c8e 100644 --- a/engine/sharedgroup.go +++ b/engine/sharedgroup.go @@ -22,6 +22,8 @@ import ( "math" "math/rand" "time" + + "github.com/cgrates/cgrates/utils" ) const ( @@ -59,8 +61,15 @@ func (sg *SharedGroup) PopBalanceByStrategy(account string, balanceChain *Balanc return } index := 0 - sharingParameters := sg.AccountParameters[account] - switch sharingParameters.Strategy { + sharingParameters := sg.AccountParameters[utils.ANY] + if sp, hasParamsForAccount := sg.AccountParameters[account]; hasParamsForAccount { + sharingParameters = sp + } + strategy := STRATEGY_RANDOM + if sharingParameters != nil { + strategy = sharingParameters.Strategy + } + switch strategy { case STRATEGY_RANDOM: rand.Seed(time.Now().Unix()) index = rand.Intn(len(bc)) diff --git a/engine/storage_map.go b/engine/storage_map.go index a40161021..834447619 100644 --- a/engine/storage_map.go +++ b/engine/storage_map.go @@ -278,7 +278,7 @@ func (ms *MapStorage) GetSharedGroup(key string, checkDb bool) (sg *SharedGroup, func (ms *MapStorage) SetSharedGroup(key string, sg *SharedGroup) (err error) { result, err := ms.ms.Marshal(sg) ms.dict[SHARED_GROUP_PREFIX+key] = result - //cache2go.Cache(ACTION_PREFIX+key, sg) + //cache2go.Cache(SHARED_GROUP_PREFIX+key, sg) return } diff --git a/engine/timespans.go b/engine/timespans.go index 2712fee9f..1c5d528ff 100644 --- a/engine/timespans.go +++ b/engine/timespans.go @@ -59,7 +59,7 @@ type MinuteInfo struct { type BalanceInfo struct { MinuteBalanceUuid string MoneyBalanceUuid string - UserBalanceId string // used when debited from shared balance + AccountId string // used when debited from shared balance } type TimeSpans []*TimeSpan