diff --git a/engine/account.go b/engine/account.go index 1570272e9..532e74cde 100644 --- a/engine/account.go +++ b/engine/account.go @@ -378,7 +378,7 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo //log.Printf("%+v, %+v", usefulMoneyBalances, usefulUnitBalances) var leftCC *CallCost cc = cd.CreateCallCost() - + var hadBalanceSubj bool generalBalanceChecker := true for generalBalanceChecker { generalBalanceChecker = false @@ -397,7 +397,9 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo if debitErr != nil { return nil, debitErr } - + if balance.RatingSubject != "" && !strings.HasPrefix(balance.RatingSubject, utils.ZERO_RATING_SUBJECT_PREFIX) { + hadBalanceSubj = true + } //utils.Logger.Info(fmt.Sprintf("CD AFTER UNIT: %+v", cd)) if partCC != nil { //log.Printf("partCC: %+v", partCC.Timespans[0]) @@ -473,6 +475,9 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo //log.Print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") } //log.Printf("After balances CD: %+v", cd) + if hadBalanceSubj { + cd.RatingInfos = nil + } leftCC, err = cd.getCost() if err != nil { utils.Logger.Err(fmt.Sprintf("Error getting new cost for balance subject: %v", err)) diff --git a/engine/balances.go b/engine/balances.go index ff6b85c63..007e211cb 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -302,6 +302,8 @@ func (b *Balance) SetDirty() { b.dirty = true } +// debitUnits will debit units for call descriptor. +// returns the amount debited within cc func (b *Balance) debitUnits(cd *CallDescriptor, ub *Account, moneyBalances Balances, count bool, dryRun, debitConnectFee bool) (cc *CallCost, err error) { if !b.IsActiveAt(cd.TimeStart) || b.GetValue() <= 0 { return @@ -405,7 +407,6 @@ func (b *Balance) debitUnits(cd *CallDescriptor, ub *Account, moneyBalances Bala if ts.Increments == nil { ts.createIncrementsSlice() } - if ts.RateInterval == nil { utils.Logger.Err(fmt.Sprintf("Nil RateInterval ERROR on TS: %+v, CC: %+v, from CD: %+v", ts, cc, cd)) return nil, errors.New("timespan with no rate interval assigned") @@ -432,7 +433,6 @@ func (b *Balance) debitUnits(cd *CallDescriptor, ub *Account, moneyBalances Bala maxCost, strategy := ts.RateInterval.GetMaxCost() for incIndex, inc := range ts.Increments { - if tsIndex == 0 && incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee && cc.deductConnectFee && ok { // go to nextincrement continue @@ -486,7 +486,7 @@ func (b *Balance) debitUnits(cd *CallDescriptor, ub *Account, moneyBalances Bala utils.Logger.Warning(fmt.Sprintf(" Going negative on account %s with AllowNegative: false", cd.GetAccountKey())) moneyBal = ub.GetDefaultMoneyBalance() } - if (cost == 0 || moneyBal != nil) && b.GetValue() >= amount { + if b.GetValue() >= amount && (moneyBal != nil || cost == 0) { b.SubstractValue(amount) inc.BalanceInfo.Unit = &UnitInfo{ UUID: b.Uuid, diff --git a/engine/calldesc.go b/engine/calldesc.go index 000bd41f9..96781ee1b 100755 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -494,7 +494,6 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) { } func (cd *CallDescriptor) getCost() (*CallCost, error) { - // check for 0 duration if cd.GetDuration() == 0 { cc := cd.CreateCallCost() diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go index 93ea4fd70..5ccf35c90 100644 --- a/engine/calldesc_test.go +++ b/engine/calldesc_test.go @@ -1713,7 +1713,6 @@ func TestCDRefundIncrementsZeroValue(t *testing.T) { } } -/* func TestCDDebitBalanceSubjectWithFallback(t *testing.T) { acnt := &Account{ ID: "TCDDBSWF:account1", @@ -1815,11 +1814,10 @@ func TestCDDebitBalanceSubjectWithFallback(t *testing.T) { for _, rpf := range []*RatingProfile{rpfTCDDBSWF, rpfAny} { dataStorage.SetRatingProfile(rpf, utils.NonTransactional) } - cd1 := &CallDescriptor{ + cd1 := &CallDescriptor{ // test the cost for subject within balance setup Direction: "*out", Category: "call", Tenant: "TCDDBSWF", - Account: "account1", Subject: "SubjTCDDBSWF", Destination: "1716", TimeStart: time.Date(2015, 01, 01, 9, 0, 0, 0, time.UTC), @@ -1842,9 +1840,20 @@ func TestCDDebitBalanceSubjectWithFallback(t *testing.T) { if cc, err := cd2.GetCost(); err != nil || cc.Cost != 0.6 { t.Errorf("Error getting *any dest: %+v %v", cc, err) } - if cc, err := cd1.Debit(); err != nil { + cd := &CallDescriptor{ // test the cost + Direction: "*out", + Category: "call", + Tenant: "TCDDBSWF", + Account: "account1", + Subject: "account1", + Destination: "1716", + TimeStart: time.Date(2015, 01, 01, 9, 0, 0, 0, time.UTC), + TimeEnd: time.Date(2015, 01, 01, 9, 2, 0, 0, time.UTC), + TOR: utils.VOICE, + } + if cc, err := cd.Debit(); err != nil { t.Error(err) - } else if cc.Cost != 0 { + } else if cc.Cost != 0.6 { t.Errorf("CallCost: %v", cc) } if resAcnt, err := dataStorage.GetAccount(acnt.ID); err != nil { @@ -1853,12 +1862,11 @@ func TestCDDebitBalanceSubjectWithFallback(t *testing.T) { resAcnt.BalanceMap[utils.VOICE][0].Value != 0 { t.Errorf("Account: %v", resAcnt) } else if len(resAcnt.BalanceMap[utils.MONETARY]) == 0 || - resAcnt.BalanceMap[utils.VOICE][0].ID != utils.META_DEFAULT || - resAcnt.BalanceMap[utils.VOICE][0].Value != -0.60 { + resAcnt.BalanceMap[utils.MONETARY][0].ID != utils.META_DEFAULT || + resAcnt.BalanceMap[utils.MONETARY][0].Value != -0.600013 { // rounding issue t.Errorf("Account: %s", utils.ToIJSON(resAcnt)) } } -*/ /*************** BENCHMARKS ********************/ func BenchmarkStorageGetting(b *testing.B) { diff --git a/engine/history_test.go b/engine/history_test.go index b3e8f5400..4d9b6d25c 100644 --- a/engine/history_test.go +++ b/engine/history_test.go @@ -35,7 +35,9 @@ func TestHistoryRatinPlans(t *testing.T) { func TestHistoryDestinations(t *testing.T) { scribe := historyScribe.(*history.MockScribe) buf := scribe.GetBuffer(history.DESTINATIONS_FN) - expected := `{"Id":"ALL","Prefixes":["49","41","43"]}, + expected := `{"Id":"*ddc_test","Prefixes":["333","666"]}, +{"Id":"ALL","Prefixes":["49","41","43"]}, +{"Id":"DST_TCDDBSWF","Prefixes":["1716"]}, {"Id":"DST_UK_Mobile_BIG5","Prefixes":["447956"]}, {"Id":"EU_LANDLINE","Prefixes":["444"]}, {"Id":"EXOTIC","Prefixes":["999"]}, diff --git a/general_tests/acntacts_test.go b/general_tests/acntacts_test.go old mode 100755 new mode 100644 diff --git a/general_tests/auth_test.go b/general_tests/auth_test.go old mode 100755 new mode 100644 diff --git a/general_tests/smschrg1_test.go b/general_tests/smschrg1_test.go old mode 100755 new mode 100644 diff --git a/utils/coreutils.go b/utils/coreutils.go index 2475ceb64..90175336a 100644 --- a/utils/coreutils.go +++ b/utils/coreutils.go @@ -284,6 +284,9 @@ func MinDuration(d1, d2 time.Duration) time.Duration { return d2 } +// ParseZeroRatingSubject will parse the subject in the balance +// returns duration if able to extract it from subject +// returns error if not able to parse duration (ie: if ratingSubject is standard one) func ParseZeroRatingSubject(rateSubj string) (time.Duration, error) { rateSubj = strings.TrimSpace(rateSubj) if rateSubj == "" || rateSubj == ANY {