From 23781cbca402368797dac12b5d6e13021b59e0d8 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Thu, 16 Jun 2016 22:52:40 +0300 Subject: [PATCH] better handling of blocker balances vs connect fee --- engine/account.go | 9 +++++++-- engine/account_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ engine/balances.go | 13 ++++++++++--- 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/engine/account.go b/engine/account.go index 69598ed6e..62df7a0f1 100644 --- a/engine/account.go +++ b/engine/account.go @@ -377,6 +377,7 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo usefulMoneyBalances := ub.getAlldBalancesForPrefix(cd.Destination, cd.Category, cd.Direction, utils.MONETARY) //utils.Logger.Info(fmt.Sprintf("%+v, %+v", usefulMoneyBalances, usefulUnitBalances)) //utils.Logger.Info(fmt.Sprintf("STARTCD: %+v", cd)) + //log.Printf("%+v, %+v", usefulMoneyBalances, usefulUnitBalances) var leftCC *CallCost cc = cd.CreateCallCost() @@ -487,7 +488,7 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo cc.Timespans = append(cc.Timespans, leftCC.Timespans...) if initialLength == 0 { // this is the first add, debit the connect fee - ub.DebitConnectionFee(cc, usefulMoneyBalances, count) + ub.DebitConnectionFee(cc, usefulMoneyBalances, count, true) } //log.Printf("Left CC: %+v ", leftCC) // get the default money balanance @@ -797,7 +798,7 @@ func (acc *Account) Clone() *Account { return newAcc } -func (acc *Account) DebitConnectionFee(cc *CallCost, usefulMoneyBalances Balances, count bool) { +func (acc *Account) DebitConnectionFee(cc *CallCost, usefulMoneyBalances Balances, count bool, block bool) bool { if cc.deductConnectFee { connectFee := cc.GetConnectFee() //log.Print("CONNECT FEE: %f", connectFee) @@ -812,6 +813,9 @@ func (acc *Account) DebitConnectionFee(cc *CallCost, usefulMoneyBalances Balance connectFeePaid = true break } + if b.Blocker && block { // stop here + return false + } } // debit connect fee if connectFee > 0 && !connectFeePaid { @@ -825,6 +829,7 @@ func (acc *Account) DebitConnectionFee(cc *CallCost, usefulMoneyBalances Balance } } } + return true } func (acc *Account) matchActionFilter(condition string) (bool, error) { diff --git a/engine/account_test.go b/engine/account_test.go index 6cedc5995..e5f8a6d1b 100644 --- a/engine/account_test.go +++ b/engine/account_test.go @@ -204,6 +204,47 @@ func TestDebitCreditZeroSecond(t *testing.T) { } } +func TestDebitCreditBlocker(t *testing.T) { + b1 := &Balance{Uuid: "testa", Value: 0.1152, Weight: 20, DestinationIDs: utils.StringMap{"NAT": true}, RatingSubject: "passmonde", Blocker: true} + b2 := &Balance{Uuid: "*default", Value: 1.5, Weight: 0} + cc := &CallCost{ + Direction: utils.OUT, + Destination: "0723045326", + Timespans: []*TimeSpan{ + &TimeSpan{ + TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), + DurationIndex: 0, + RateInterval: &RateInterval{Rating: &RIRate{ConnectFee: 0.15, Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 0.1, RateIncrement: time.Second, RateUnit: time.Second}}}}, + }, + }, + deductConnectFee: true, + TOR: utils.VOICE, + } + cd := &CallDescriptor{ + TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), + Direction: utils.OUT, + Destination: "0723045326", + Category: "0", + TOR: utils.VOICE, + testCallcost: cc, + } + rifsBalance := &Account{ID: "other", BalanceMap: map[string]Balances{utils.MONETARY: Balances{b1, b2}}} + var err error + cc, err = rifsBalance.debitCreditBalance(cd, false, true, true) + if err != nil { + t.Error("Error debiting balance: ", err) + } + if len(cc.Timespans) != 0 { + t.Error("Wrong call cost: ", utils.ToIJSON(cc)) + } + if rifsBalance.BalanceMap[utils.MONETARY][0].GetValue() != 0.1152 || + rifsBalance.BalanceMap[utils.MONETARY][1].GetValue() != 1.5 { + t.Error("should not have touched the balances: ", utils.ToIJSON(rifsBalance.BalanceMap[utils.MONETARY])) + } +} + func TestDebitCreditZeroMinute(t *testing.T) { b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationIDs: utils.StringMap{"NAT": true}, RatingSubject: "*zero1m"} cc := &CallCost{ diff --git a/engine/balances.go b/engine/balances.go index ce7704f96..9f3c36e67 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -394,7 +394,10 @@ func (b *Balance) debitUnits(cd *CallDescriptor, ub *Account, moneyBalances Bala } if debitConnectFee { // this is the first add, debit the connect fee - ub.DebitConnectionFee(cc, moneyBalances, count) + if ub.DebitConnectionFee(cc, moneyBalances, count, true) == false { + // found blocker balance + return nil, nil + } } cc.Timespans.Decompress() //log.Printf("CC: %+v", cc) @@ -507,15 +510,19 @@ func (b *Balance) debitMoney(cd *CallDescriptor, ub *Account, moneyBalances Bala if !b.IsActiveAt(cd.TimeStart) || b.GetValue() <= 0 { return } + //log.Print("B: ", utils.ToJSON(b)) //log.Printf("}}}}}}} %+v", cd.testCallcost) cc, err = b.GetCost(cd, true) if err != nil { return nil, err } - + //log.Print("cc: " + utils.ToJSON(cc)) if debitConnectFee { // this is the first add, debit the connect fee - ub.DebitConnectionFee(cc, moneyBalances, count) + if ub.DebitConnectionFee(cc, moneyBalances, count, true) == false { + // balance is blocker + return nil, nil + } } cc.Timespans.Decompress()