diff --git a/engine/account.go b/engine/account.go index fa7de7369..866668e1e 100644 --- a/engine/account.go +++ b/engine/account.go @@ -478,10 +478,18 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo utils.Logger.Err(fmt.Sprintf("Error getting new cost for balance subject: %v", err)) } if leftCC.Cost == 0 && len(leftCC.Timespans) > 0 { + // put AccountID ubformation in increments + for _, ts := range leftCC.Timespans { + for _, inc := range ts.Increments { + if inc.BalanceInfo == nil { + inc.BalanceInfo = &DebitInfo{} + } + inc.BalanceInfo.AccountID = ub.ID + } + } cc.Timespans = append(cc.Timespans, leftCC.Timespans...) } - //log.Printf("HERE: %+v", leftCC) if leftCC.Cost > 0 && goNegative { initialLength := len(cc.Timespans) cc.Timespans = append(cc.Timespans, leftCC.Timespans...) diff --git a/engine/account_test.go b/engine/account_test.go index ba3e3a0c7..21a6b07ea 100644 --- a/engine/account_test.go +++ b/engine/account_test.go @@ -244,6 +244,47 @@ func TestDebitCreditBlocker(t *testing.T) { } } +func TestDebitFreeEmpty(t *testing.T) { + cc := &CallCost{ + Direction: utils.OUT, + Destination: "112", + 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, Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 0, 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, + Tenant: "CUSTOMER_1", + Subject: "rif:from:tm", + Destination: "112", + Category: "0", + TOR: utils.VOICE, + testCallcost: cc, + } + // empty account + rifsBalance := &Account{ID: "other", BalanceMap: map[string]Balances{utils.MONETARY: Balances{}}} + 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 || cc.Cost != 0 { + t.Error("Wrong call cost: ", utils.ToIJSON(cc)) + } + if len(rifsBalance.BalanceMap[utils.MONETARY]) != 0 { + 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/calldesc.go b/engine/calldesc.go index b2e804ce1..d6a0e8ceb 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -796,7 +796,9 @@ func (cd *CallDescriptor) RefundIncrements() error { accMap := make(utils.StringMap) cd.Increments.Decompress() for _, increment := range cd.Increments { - accMap[increment.BalanceInfo.AccountID] = true + if increment.BalanceInfo.Monetary != nil || increment.BalanceInfo.Unit != nil { + accMap[increment.BalanceInfo.AccountID] = true + } } // start increment refunding loop _, err := Guardian.Guard(func() (interface{}, error) { diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go index 8ecf80774..ab3bb981d 100644 --- a/engine/calldesc_test.go +++ b/engine/calldesc_test.go @@ -1587,6 +1587,35 @@ func TestCDRefundIncrements(t *testing.T) { } } +func TestCDRefundIncrementsZeroValue(t *testing.T) { + ub := &Account{ + ID: "test:ref", + BalanceMap: map[string]Balances{ + utils.MONETARY: Balances{ + &Balance{Uuid: "moneya", Value: 100}, + }, + utils.VOICE: Balances{ + &Balance{Uuid: "minutea", Value: 10, Weight: 20, DestinationIDs: utils.StringMap{"NAT": true}}, + &Balance{Uuid: "minuteb", Value: 10, DestinationIDs: utils.StringMap{"RET": true}}, + }, + }, + } + accountingStorage.SetAccount(ub) + increments := Increments{ + &Increment{Cost: 0, BalanceInfo: &DebitInfo{AccountID: ub.ID}}, + &Increment{Cost: 0, Duration: 3 * time.Second, BalanceInfo: &DebitInfo{AccountID: ub.ID}}, + &Increment{Cost: 0, Duration: 4 * time.Second, BalanceInfo: &DebitInfo{AccountID: ub.ID}}, + } + cd := &CallDescriptor{TOR: utils.VOICE, Increments: increments} + cd.RefundIncrements() + ub, _ = accountingStorage.GetAccount(ub.ID) + if ub.BalanceMap[utils.MONETARY][0].GetValue() != 100 || + ub.BalanceMap[utils.VOICE][0].GetValue() != 10 || + ub.BalanceMap[utils.VOICE][1].GetValue() != 10 { + t.Error("Error refunding money: ", utils.ToIJSON(ub.BalanceMap)) + } +} + /*************** BENCHMARKS ********************/ func BenchmarkStorageGetting(b *testing.B) { b.StopTimer()