mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Merge branch 'master' of https://github.com/cgrates/cgrates
This commit is contained in:
@@ -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}})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 *******************************/
|
||||
|
||||
@@ -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}})
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user