This commit is contained in:
DanB
2014-02-27 17:38:49 +01:00
8 changed files with 126 additions and 30 deletions

View File

@@ -355,27 +355,25 @@ func (ub *Account) GetDefaultMoneyBalance(direction string) *Balance {
return defaultBalance
}
func (ub *Account) refundIncrements(increments Increments, direction string, count bool) {
for _, increment := range increments {
var balance *Balance
if increment.BalanceInfo.MinuteBalanceUuid != "" {
if balance = ub.BalanceMap[MINUTES+direction].GetBalance(increment.BalanceInfo.MinuteBalanceUuid); balance == nil {
continue
}
balance.Value += increment.Duration.Seconds()
if count {
ub.countUnits(&Action{BalanceType: MINUTES, Direction: direction, Balance: &Balance{Value: -increment.Duration.Seconds()}})
}
func (ub *Account) refundIncrement(increment *Increment, direction string, count bool) {
var balance *Balance
if increment.BalanceInfo.MinuteBalanceUuid != "" {
if balance = ub.BalanceMap[MINUTES+direction].GetBalance(increment.BalanceInfo.MinuteBalanceUuid); balance == nil {
return
}
// check money too
if increment.BalanceInfo.MoneyBalanceUuid != "" {
if balance = ub.BalanceMap[CREDIT+direction].GetBalance(increment.BalanceInfo.MoneyBalanceUuid); balance == nil {
continue
}
balance.Value += increment.Cost
if count {
ub.countUnits(&Action{BalanceType: CREDIT, Direction: direction, Balance: &Balance{Value: -increment.Cost}})
}
balance.Value += increment.Duration.Seconds()
if count {
ub.countUnits(&Action{BalanceType: MINUTES, Direction: direction, Balance: &Balance{Value: -increment.Duration.Seconds()}})
}
}
// check money too
if increment.BalanceInfo.MoneyBalanceUuid != "" {
if balance = ub.BalanceMap[CREDIT+direction].GetBalance(increment.BalanceInfo.MoneyBalanceUuid); balance == nil {
return
}
balance.Value += increment.Cost
if count {
ub.countUnits(&Action{BalanceType: CREDIT, Direction: direction, Balance: &Balance{Value: -increment.Cost}})
}
}
}

View File

@@ -21,6 +21,8 @@ package engine
import (
"testing"
"time"
"github.com/cgrates/cgrates/cache2go"
)
var (
@@ -1023,8 +1025,9 @@ func TestAccountRefund(t *testing.T) {
&Increment{Cost: 2, Duration: 3 * time.Second, BalanceInfo: &BalanceInfo{MinuteBalanceUuid: "minutea", MoneyBalanceUuid: "moneya"}},
&Increment{Duration: 4 * time.Second, BalanceInfo: &BalanceInfo{MinuteBalanceUuid: "minuteb", MoneyBalanceUuid: ""}},
}
ub.refundIncrements(increments, OUTBOUND, false)
for _, increment := range increments {
ub.refundIncrement(increment, OUTBOUND, false)
}
if ub.BalanceMap[CREDIT+OUTBOUND][0].Value != 104 ||
ub.BalanceMap[MINUTES+OUTBOUND][0].Value != 13 ||
ub.BalanceMap[MINUTES+OUTBOUND][1].Value != 14 {
@@ -1033,7 +1036,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 *******************************/

View File

@@ -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}})

View File

@@ -546,9 +546,21 @@ func (cd *CallDescriptor) MaxDebit() (cc *CallCost, err error) {
}
func (cd *CallDescriptor) RefundIncrements() (left float64, err error) {
accountsCache := make(map[string]*Account)
for _, increment := range cd.Increments {
account, found := accountsCache[increment.BalanceInfo.AccountId]
if !found {
if acc, err := accountingStorage.GetAccount(increment.BalanceInfo.AccountId); err == nil && acc != nil {
account = acc
accountsCache[increment.BalanceInfo.AccountId] = account
defer accountingStorage.SetAccount(account)
}
}
account.refundIncrement(increment, cd.Direction, true)
}
if userBalance, err := cd.getAccount(); err == nil && userBalance != nil {
defer accountingStorage.SetAccount(userBalance)
userBalance.refundIncrements(cd.Increments, cd.Direction, true)
}
return 0.0, err
}

View File

@@ -633,10 +633,11 @@ func TestLoadActions(t *testing.T) {
}
}
func TestSharedGroups(t *testing.T) {
func TestLoadSharedGroups(t *testing.T) {
if len(csvr.sharedGroups) != 2 {
t.Error("Failed to load actions: ", csvr.sharedGroups)
}
sg1 := csvr.sharedGroups["SG1"]
expected := &SharedGroup{
Id: "SG1",
@@ -663,6 +664,20 @@ func TestSharedGroups(t *testing.T) {
if !reflect.DeepEqual(sg2, expected) {
t.Error("Error loading shared group: ", sg2.AccountParameters)
}
sg, _ := accountingStorage.GetSharedGroup("SG1", false)
if len(sg.Members) != 0 {
t.Errorf("Memebers should be empty: %+v", sg)
}
// execute action timings to fill memebers
atm := csvr.actionsTimings["MORE_MINUTES"][1]
atm.Execute()
atm.actions, atm.stCache = nil, time.Time{}
sg, _ = accountingStorage.GetSharedGroup("SG1", false)
if len(sg.Members) != 1 {
t.Errorf("Memebers should not be empty: %+v", sg)
}
}
func TestLoadActionTimings(t *testing.T) {
@@ -687,7 +702,7 @@ func TestLoadActionTimings(t *testing.T) {
ActionsId: "MINI",
}
if !reflect.DeepEqual(atm, expected) {
t.Error("Error loading action timing: ", atm, expected)
t.Errorf("Error loading action timing:\n%+v\n%+v", atm, expected)
}
}

View File

@@ -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))

View File

@@ -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
}

View File

@@ -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