From 575bcf2434d37bfc10bc9be3cfd76aac8e69cff1 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 25 Apr 2014 17:16:59 +0300 Subject: [PATCH] debit zero cost calls even for no credit --- engine/calldesc.go | 8 +++---- engine/calldesc_test.go | 44 +++++++++++++++++++++++++++++++++++++++ engine/history_test.go | 1 + engine/loader_csv_test.go | 39 ++++++++++++++++++++++++++++++---- 4 files changed, 84 insertions(+), 8 deletions(-) diff --git a/engine/calldesc.go b/engine/calldesc.go index 48d2537d3..f033fbdde 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -472,10 +472,6 @@ func (origCD *CallDescriptor) getMaxSessionDuration(account *Account) (time.Dura // there are enough minutes for requested interval return initialDuration, nil } - // check for zero balance - if availableCredit == 0 { - return utils.MinDuration(initialDuration, availableDuration), nil - } //Logger.Debug(fmt.Sprintf("initial Duration: %v", initialDuration)) // we must move the timestart for the interval with the available duration because // that was already checked @@ -486,6 +482,10 @@ func (origCD *CallDescriptor) getMaxSessionDuration(account *Account) (time.Dura if availableDuration == 0 && cc.deductConnectFee { // only if we did not already used minutes availableCredit -= cc.GetConnectFee() } + // check for zero balance + if (availableCredit < 0) || (availableCredit == 0 && cc.Cost > 0) { + return utils.MinDuration(initialDuration, availableDuration), nil + } if err != nil { Logger.Err(fmt.Sprintf("Could not get cost for %s: %s.", cd.GetKey(cd.Subject), err.Error())) return 0, err diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go index da6f54948..56c890f43 100644 --- a/engine/calldesc_test.go +++ b/engine/calldesc_test.go @@ -63,6 +63,13 @@ func populateDB() { &Balance{Value: 100, DestinationId: "RET", Weight: 20}, }}, } + luna := &Account{ + Id: "*out:vdf:luna", + BalanceMap: map[string]BalanceChain{ + CREDIT + OUTBOUND: BalanceChain{ + &Balance{Value: 0, Weight: 20}, + }}, + } // this is added to test if csv load tests account will not overwrite balances minitsboy := &Account{ Id: "*out:vdf:minitsboy", @@ -82,6 +89,7 @@ func populateDB() { accountingStorage.SetAccount(broker) accountingStorage.SetAccount(minu) accountingStorage.SetAccount(minitsboy) + accountingStorage.SetAccount(luna) } else { log.Fatal("Could not connect to db!") } @@ -514,6 +522,42 @@ func TestDebitAndMaxDebit(t *testing.T) { } } +func TestMaxSesionTimeEmptyBalance(t *testing.T) { + cd := &CallDescriptor{ + TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 10, 21, 18, 35, 0, 0, time.UTC), + Direction: "*out", + TOR: "0", + Tenant: "vdf", + Subject: "minu_from_tm", + Account: "luna", + Destination: "0723", + } + acc, _ := accountingStorage.GetAccount("*out:vdf:luna") + allowedTime, err := cd.getMaxSessionDuration(acc) + if err != nil || allowedTime != 0 { + t.Error("Error get max session for 0 acount") + } +} + +func TestMaxSesionTimeEmptyBalanceAndNoCost(t *testing.T) { + cd := &CallDescriptor{ + TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 10, 21, 18, 35, 0, 0, time.UTC), + Direction: "*out", + TOR: "0", + Tenant: "vdf", + Subject: "one", + Account: "luna", + Destination: "112", + } + acc, _ := accountingStorage.GetAccount("*out:vdf:luna") + allowedTime, err := cd.getMaxSessionDuration(acc) + if err != nil || allowedTime == 0 { + t.Error("Error get max session for 0 acount") + } +} + func TestDebitFromShareAndNormal(t *testing.T) { ap, _ := accountingStorage.GetActionTimings("TOPUP_SHARED10_AT") for _, at := range ap { diff --git a/engine/history_test.go b/engine/history_test.go index bcaac39b6..daf5e628a 100644 --- a/engine/history_test.go +++ b/engine/history_test.go @@ -47,6 +47,7 @@ func TestHistoryDestinations(t *testing.T) { {"Id":"PSTN_71","Prefixes":["+4971"]}, {"Id":"PSTN_72","Prefixes":["+4972"]}, {"Id":"RET","Prefixes":["0723","0724"]}, +{"Id":"URG","Prefixes":["112"]}, {"Id":"nat","Prefixes":["0257","0256","0723"]}]` if buf.String() != expected { t.Error("Error in destination history content:", buf.String()) diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 3b9ed2082..e7f2a060b 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -45,6 +45,7 @@ PSTN_71,+4971 PSTN_72,+4972 PSTN_70,+4970 DST_UK_Mobile_BIG5,447956 +URG,112 *any, ` timings = ` @@ -68,6 +69,7 @@ GBP_72,0.000000,7.77777,1s,1s,0s,*up,4 GBP_70,0.000000,1,1,1,0,*up,4 RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s,*up,8 RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s,*up,8 +R_URG,0,0,1,1,0,*down,2 ` destinationRates = ` RT_STANDARD,GERMANY,R1 @@ -85,11 +87,13 @@ T2,GERMANY_PREMIUM,GBP_71 DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5 DATA_RATE,*any,LANDLINE_OFFPEAK +RT_URG,URG,R_URG ` ratingPlans = ` STANDARD,RT_STANDARD,WORKDAYS_00,10 STANDARD,RT_STD_WEEKEND,WORKDAYS_18,10 STANDARD,RT_STD_WEEKEND,WEEKENDS,10 +STANDARD,RT_URG,ALWAYS,20 PREMIUM,RT_STANDARD,WORKDAYS_00,10 PREMIUM,RT_STD_WEEKEND,WORKDAYS_18,10 PREMIUM,RT_STD_WEEKEND,WEEKENDS,10 @@ -200,7 +204,7 @@ func init() { } func TestLoadDestinations(t *testing.T) { - if len(csvr.destinations) != 11 { + if len(csvr.destinations) != 12 { t.Error("Failed to load destinations: ", len(csvr.destinations)) } for _, d := range csvr.destinations { @@ -296,7 +300,7 @@ func TestLoadTimimgs(t *testing.T) { } func TestLoadRates(t *testing.T) { - if len(csvr.rates) != 11 { + if len(csvr.rates) != 12 { t.Error("Failed to load rates: ", csvr.rates) } rate := csvr.rates["R1"].RateSlots[0] @@ -366,7 +370,7 @@ func TestLoadRates(t *testing.T) { } func TestLoadDestinationRates(t *testing.T) { - if len(csvr.destinationRates) != 10 { + if len(csvr.destinationRates) != 11 { t.Error("Failed to load destinationrates: ", csvr.destinationRates) } drs := csvr.destinationRates["RT_STANDARD"] @@ -506,6 +510,13 @@ func TestLoadRatingPlans(t *testing.T) { WeekDays: utils.WeekDays{time.Saturday, time.Sunday}, StartTime: "00:00:00", }, + "96c78ff5": &RITiming{ + Years: utils.Years{}, + Months: utils.Months{}, + MonthDays: utils.MonthDays{}, + WeekDays: utils.WeekDays{}, + StartTime: "00:00:00", + }, }, Ratings: map[string]*RIRate{ "d54545c1": &RIRate{ @@ -547,6 +558,19 @@ func TestLoadRatingPlans(t *testing.T) { RoundingMethod: utils.ROUNDING_MIDDLE, RoundingDecimals: 2, }, + "2efe78aa": &RIRate{ + ConnectFee: 0, + Rates: []*Rate{ + &Rate{ + GroupIntervalStart: 0, + Value: 0, + RateIncrement: time.Second, + RateUnit: time.Second, + }, + }, + RoundingMethod: utils.ROUNDING_DOWN, + RoundingDecimals: 2, + }, }, DestinationRates: map[string]RPRateList{ "GERMANY": []*RPRate{ @@ -590,10 +614,17 @@ func TestLoadRatingPlans(t *testing.T) { Weight: 10, }, }, + "URG": []*RPRate{ + &RPRate{ + Timing: "96c78ff5", + Rating: "2efe78aa", + Weight: 20, + }, + }, }, } if !reflect.DeepEqual(rplan, expected) { - t.Errorf("Error loading destination rate timing: %+v", rplan.Ratings["e06c337f"]) + t.Errorf("Error loading destination rate timing: %+v", rplan.DestinationRates["URG"][0]) } }