From 42718617b93d9dc1a74919cfb177450360e601e7 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Thu, 24 Apr 2014 20:01:20 +0300 Subject: [PATCH 01/17] data get cost --- engine/calldesc.go | 17 ++++++++---- engine/calldesc_test.go | 54 ++++++++++++++++++++++++++++++++++----- engine/loader_csv_test.go | 17 ++++++------ engine/timespans.go | 3 +-- 4 files changed, 69 insertions(+), 22 deletions(-) diff --git a/engine/calldesc.go b/engine/calldesc.go index 356417ee7..0966c9adc 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -116,6 +116,7 @@ type CallDescriptor struct { FallbackSubject string // the subject to check for destination if not found on primary subject RatingInfos RatingInfos Increments Increments + Amount float64 account *Account } @@ -296,10 +297,9 @@ func (cd *CallDescriptor) GetKey(subject string) string { } // Splits the received timespan into sub time spans according to the activation periods intervals. -func (cd *CallDescriptor) splitInTimeSpans(firstSpan *TimeSpan) (timespans []*TimeSpan) { - if firstSpan == nil { - firstSpan = &TimeSpan{TimeStart: cd.TimeStart, TimeEnd: cd.TimeEnd, CallDuration: cd.CallDuration} - } +func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) { + firstSpan := &TimeSpan{TimeStart: cd.TimeStart, TimeEnd: cd.TimeEnd, CallDuration: cd.CallDuration} + timespans = append(timespans, firstSpan) if len(cd.RatingInfos) == 0 { return @@ -327,6 +327,12 @@ func (cd *CallDescriptor) splitInTimeSpans(firstSpan *TimeSpan) (timespans []*Ti } } } + if cd.Amount > 0 { + cd.TimeEnd = cd.TimeStart.Add(time.Duration(utils.Round(cd.Amount, 0, utils.ROUNDING_UP)) * time.Second) + cd.CallDuration = cd.TimeEnd.Sub(cd.TimeStart) + //first span should be still the only one + firstSpan.TimeStart, firstSpan.TimeEnd, firstSpan.CallDuration = cd.TimeStart, cd.TimeEnd, cd.CallDuration + } // Logger.Debug(fmt.Sprintf("After SplitByRatingPlan: %+v", timespans)) // split on price intervals for i := 0; i < len(timespans); i++ { @@ -402,7 +408,8 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) { Logger.Err(fmt.Sprintf("error getting cost for key %s: %v", cd.GetKey(cd.Subject), err)) return &CallCost{Cost: -1}, err } - timespans := cd.splitInTimeSpans(nil) + + timespans := cd.splitInTimeSpans() cost := 0.0 for i, ts := range timespans { diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go index d19611387..c43019d4b 100644 --- a/engine/calldesc_test.go +++ b/engine/calldesc_test.go @@ -93,7 +93,7 @@ func TestSplitSpans(t *testing.T) { cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} cd.LoadRatingPlans() - timespans := cd.splitInTimeSpans(nil) + timespans := cd.splitInTimeSpans() if len(timespans) != 2 { t.Log(cd.RatingInfos) t.Error("Wrong number of timespans: ", len(timespans)) @@ -106,7 +106,7 @@ func TestSplitSpansRoundToIncrements(t *testing.T) { cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "test", Subject: "trp", Destination: "0256", TimeStart: t1, TimeEnd: t2, CallDuration: 132 * time.Second} cd.LoadRatingPlans() - timespans := cd.splitInTimeSpans(nil) + timespans := cd.splitInTimeSpans() if len(timespans) != 2 { t.Logf("%+v", cd) t.Log(cd.RatingInfos) @@ -649,16 +649,56 @@ func TestMaxDebitConsumesMinutes(t *testing.T) { func TestCDGetCostANY(t *testing.T) { cd1 := &CallDescriptor{ Direction: "*out", - TOR: "0", - Tenant: "vdf", + TOR: "data", + Tenant: "cgrates.org", Subject: "rif", Destination: utils.ANY, TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), - TimeEnd: time.Date(2014, 3, 4, 6, 0, 5, 0, time.UTC), + TimeEnd: time.Date(2014, 3, 4, 6, 0, 1, 0, time.UTC), LoopIndex: 0, CallDuration: 0} cc, err := cd1.GetCost() - if err != nil || cc.Cost != 6 { + if err != nil || cc.Cost != 60 { + t.Errorf("Error getting *any dest: %+v %v", cc, err) + } +} + +func TestCDSplitInDataSlots(t *testing.T) { + cd := &CallDescriptor{ + Direction: "*out", + TOR: "data", + Tenant: "cgrates.org", + Subject: "rif", + Destination: utils.ANY, + TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), + TimeEnd: time.Date(2014, 3, 4, 6, 0, 1, 0, time.UTC), + LoopIndex: 0, + CallDuration: 0, + Amount: 65, + } + cd.LoadRatingPlans() + timespans := cd.splitInTimeSpans() + if len(timespans) != 2 { + t.Log(cd.RatingInfos[0]) + t.Error("Wrong number of timespans: ", len(timespans)) + } +} + +func TestCDDataGetCost(t *testing.T) { + cd := &CallDescriptor{ + Direction: "*out", + TOR: "data", + Tenant: "cgrates.org", + Subject: "rif", + Destination: utils.ANY, + TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), + TimeEnd: time.Date(2014, 3, 4, 6, 0, 1, 0, time.UTC), + LoopIndex: 0, + CallDuration: 0, + Amount: 65, + } + cc, err := cd.GetCost() + if err != nil || cc.Cost != 65 { t.Errorf("Error getting *any dest: %+v %v", cc, err) } } @@ -705,7 +745,7 @@ func BenchmarkSplitting(b *testing.B) { cd.LoadRatingPlans() b.StartTimer() for i := 0; i < b.N; i++ { - cd.splitInTimeSpans(nil) + cd.splitInTimeSpans() } } diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 2cfa863cc..0ffbd09a9 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -61,8 +61,8 @@ R2,0,0.1,60s,1s,0,*middle,2 R3,0,0.05,60s,1s,0,*middle,2 R4,1,1,1s,1s,0,*up,2 R5,0,0.5,1s,1s,0,*down,2 -LANDLINE_OFFPEAK,0,1,1s,60s,0s,*up,4 -LANDLINE_OFFPEAK,0,1,1s,1s,60s,*up,4 +LANDLINE_OFFPEAK,0,1,1,60,0,*up,4 +LANDLINE_OFFPEAK,0,1,1,1,60,*up,4 GBP_71,0.000000,5.55555,1s,1s,0s,*up,4 GBP_72,0.000000,7.77777,1s,1s,0s,*up,4 GBP_70,0.000000,1,1,1,0,*up,4 @@ -84,7 +84,7 @@ T2,GERMANY_O2,GBP_70 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,R4 +DATA_RATE,*any,LANDLINE_OFFPEAK ` ratingPlans = ` STANDARD,RT_STANDARD,WORKDAYS_00,10 @@ -97,13 +97,13 @@ DEFAULT,RT_DEFAULT,WORKDAYS_00,10 EVENING,P1,WORKDAYS_00,10 EVENING,P2,WORKDAYS_18,10 EVENING,P2,WEEKENDS,10 -EVENING,DATA_RATE,ALWAYS,10 TDRT,T1,WORKDAYS_00,10 TDRT,T2,WORKDAYS_00,10 G,RT_STANDARD,WORKDAYS_00,10 R,P1,WORKDAYS_00,10 RP_UK_Mobile_BIG5_PKG,DR_UK_Mobile_BIG5_PKG,ALWAYS,10 RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10 +RP_DATA,DATA_RATE,ALWAYS,10 ` ratingProfiles = ` CUSTOMER_1,0,*out,rif:from:tm,2012-01-01T00:00:00Z,PREMIUM,danb @@ -124,6 +124,7 @@ vdf,0,*out,fallback1,2013-11-18T13:47:00Z,G,fallback2 vdf,0,*out,fallback2,2013-11-18T13:45:00Z,R,rif cgrates.org,call,*out,*any,2013-01-06T00:00:00Z,RP_UK, cgrates.org,call,*out,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG, +cgrates.org,data,*out,rif,2013-01-06T00:00:00Z,RP_DATA, ` sharedGroups = ` SG1,*any,*lowest, @@ -345,7 +346,7 @@ func TestLoadRates(t *testing.T) { t.Error("Error loading rate: ", rate) } rate = csvr.rates["LANDLINE_OFFPEAK"].RateSlots[0] - if expctRs, err = utils.NewRateSlot(0, 1, "1s", "60s", "0s", utils.ROUNDING_UP, 4); err != nil { + if expctRs, err = utils.NewRateSlot(0, 1, "1", "60", "0", utils.ROUNDING_UP, 4); err != nil { t.Error("Error loading rate: ", rate, err.Error()) } else if !reflect.DeepEqual(rate, expctRs) || rate.RateUnitDuration() != expctRs.RateUnitDuration() || @@ -354,7 +355,7 @@ func TestLoadRates(t *testing.T) { t.Error("Error loading rate: ", rate) } rate = csvr.rates["LANDLINE_OFFPEAK"].RateSlots[1] - if expctRs, err = utils.NewRateSlot(0, 1, "1s", "1s", "60s", utils.ROUNDING_UP, 4); err != nil { + if expctRs, err = utils.NewRateSlot(0, 1, "1", "1", "60", utils.ROUNDING_UP, 4); err != nil { t.Error("Error loading rate: ", rate, err.Error()) } else if !reflect.DeepEqual(rate, expctRs) || rate.RateUnitDuration() != expctRs.RateUnitDuration() || @@ -477,7 +478,7 @@ func TestLoadDestinationRates(t *testing.T) { } func TestLoadRatingPlans(t *testing.T) { - if len(csvr.ratingPlans) != 9 { + if len(csvr.ratingPlans) != 10 { t.Error("Failed to load rating plans: ", len(csvr.ratingPlans)) } rplan := csvr.ratingPlans["STANDARD"] @@ -597,7 +598,7 @@ func TestLoadRatingPlans(t *testing.T) { } func TestLoadRatingProfiles(t *testing.T) { - if len(csvr.ratingProfiles) != 14 { + if len(csvr.ratingProfiles) != 15 { t.Error("Failed to load rating profiles: ", len(csvr.ratingProfiles), csvr.ratingProfiles) } rp := csvr.ratingProfiles["*out:test:0:trp"] diff --git a/engine/timespans.go b/engine/timespans.go index f54026028..6328a4a43 100644 --- a/engine/timespans.go +++ b/engine/timespans.go @@ -317,7 +317,6 @@ a new timespan starting from the end of the received one. The interval will attach itself to the timespan that overlaps the interval. */ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) { - //Logger.Debug("here: ", ts, " +++ ", i) // if the span is not in interval return nil if !(i.Contains(ts.TimeStart, false) || i.Contains(ts.TimeEnd, true)) { //Logger.Debug("Not in interval") @@ -328,7 +327,7 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) { if i.Rating != nil { i.Rating.Rates.Sort() for _, rate := range i.Rating.Rates { - // Logger.Debug(fmt.Sprintf("Rate: %+v", rate)) + //Logger.Debug(fmt.Sprintf("Rate: %+v", rate)) if ts.GetGroupStart() < rate.GroupIntervalStart && ts.GetGroupEnd() > rate.GroupIntervalStart { // Logger.Debug(fmt.Sprintf("Splitting")) ts.SetRateInterval(i) From 4ffc8555a1dd6999126222566ef22b20f81c6cec Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Thu, 24 Apr 2014 22:42:14 +0300 Subject: [PATCH 02/17] new call descryptor type attribute --- engine/account.go | 44 ++++++++++++---------------- engine/account_test.go | 51 ++++++++++++++++++++++----------- engine/balances.go | 14 ++++----- engine/callcost.go | 8 +++--- engine/calldesc.go | 62 ++++++++++++++++++++++------------------ engine/calldesc_test.go | 45 ++++++++++++++--------------- engine/responder.go | 47 ------------------------------ engine/timespans.go | 19 ++++++------ engine/timespans_test.go | 20 ++++++------- 9 files changed, 139 insertions(+), 171 deletions(-) diff --git a/engine/account.go b/engine/account.go index 7f393fdc6..4ed40469e 100644 --- a/engine/account.go +++ b/engine/account.go @@ -34,14 +34,10 @@ const ( INBOUND = "*in" OUTBOUND = "*out" // Balance types - CREDIT = "*monetary" - SMS = "*sms" - DATA = "*data" - DATA_TIME = "*data_time" - MINUTES = "*minutes" - // action price type - PRICE_PERCENT = "*percent" - PRICE_ABSOLUTE = "*absolute" + CREDIT = "*monetary" + SMS = "*sms" + DATA = "*data" + MINUTES = "*minutes" // action trigger threshold types TRIGGER_MIN_COUNTER = "*min_counter" TRIGGER_MAX_COUNTER = "*max_counter" @@ -49,10 +45,6 @@ const ( TRIGGER_MAX_BALANCE = "*max_balance" ) -var ( - AMOUNT_TOO_BIG = errors.New("Amount excedes balance!") -) - /* Structure containing information about user's credit (minutes, cents, sms...).' This can represent a user or a shared group. @@ -70,7 +62,7 @@ type Account struct { func (ub *Account) getCreditForPrefix(cd *CallDescriptor) (duration time.Duration, credit float64, balances BalanceChain) { creditBalances := ub.getBalancesForPrefix(cd.Destination, ub.BalanceMap[CREDIT+cd.Direction], "") - minuteBalances := ub.getBalancesForPrefix(cd.Destination, ub.BalanceMap[MINUTES+cd.Direction], "") + unitBalances := ub.getBalancesForPrefix(cd.Destination, ub.BalanceMap[cd.Type+cd.Direction], "") // gather all balances from shared groups var extendedCreditBalances BalanceChain for _, cb := range creditBalances { @@ -85,10 +77,10 @@ func (ub *Account) getCreditForPrefix(cd *CallDescriptor) (duration time.Duratio } } var extendedMinuteBalances BalanceChain - for _, mb := range minuteBalances { + for _, mb := range unitBalances { if mb.SharedGroup != "" { if sharedGroup, _ := accountingStorage.GetSharedGroup(mb.SharedGroup, false); sharedGroup != nil { - sgb := sharedGroup.GetBalances(cd.Destination, MINUTES+cd.Direction, ub) + sgb := sharedGroup.GetBalances(cd.Destination, cd.Type+cd.Direction, ub) sgb = sharedGroup.SortBalancesByStrategy(mb, sgb) extendedMinuteBalances = append(extendedMinuteBalances, sgb...) } @@ -211,11 +203,11 @@ func (account *Account) getAlldBalancesForPrefix(destination, balanceType string } func (ub *Account) debitCreditBalance(cc *CallCost, count bool) (err error) { - usefulMinuteBalances := ub.getAlldBalancesForPrefix(cc.Destination, MINUTES+cc.Direction) + usefulUnitBalances := ub.getAlldBalancesForPrefix(cc.Destination, cc.Type+cc.Direction) usefulMoneyBalances := ub.getAlldBalancesForPrefix(cc.Destination, CREDIT+cc.Direction) // debit minutes - for _, balance := range usefulMinuteBalances { - balance.DebitMinutes(cc, count, balance.account, usefulMoneyBalances) + for _, balance := range usefulUnitBalances { + balance.DebitUnits(cc, count, balance.account, usefulMoneyBalances) if cc.IsPaid() { goto CONNECT_FEE } @@ -292,7 +284,7 @@ CONNECT_FEE: } // save darty shared balances usefulMoneyBalances.SaveDirtyBalances(ub) - usefulMinuteBalances.SaveDirtyBalances(ub) + usefulUnitBalances.SaveDirtyBalances(ub) return } @@ -308,15 +300,15 @@ func (ub *Account) GetDefaultMoneyBalance(direction string) *Balance { return defaultBalance } -func (ub *Account) refundIncrement(increment *Increment, direction string, count bool) { +func (ub *Account) refundIncrement(increment *Increment, direction, unitType string, count bool) { var balance *Balance - if increment.BalanceInfo.MinuteBalanceUuid != "" { - if balance = ub.BalanceMap[MINUTES+direction].GetBalance(increment.BalanceInfo.MinuteBalanceUuid); balance == nil { + if increment.BalanceInfo.UnitBalanceUuid != "" { + if balance = ub.BalanceMap[unitType+direction].GetBalance(increment.BalanceInfo.UnitBalanceUuid); balance == nil { return } balance.Value += increment.Duration.Seconds() if count { - ub.countUnits(&Action{BalanceType: MINUTES, Direction: direction, Balance: &Balance{Value: -increment.Duration.Seconds()}}) + ub.countUnits(&Action{BalanceType: unitType, Direction: direction, Balance: &Balance{Value: -increment.Duration.Seconds()}}) } } // check money too @@ -477,9 +469,9 @@ func (ub *Account) GetSharedGroups() (groups []string) { return } -func (account *Account) GetUniqueSharedGroupMembers(destination, direction string) ([]string, error) { +func (account *Account) GetUniqueSharedGroupMembers(destination, direction, unitType string) ([]string, error) { creditBalances := account.getBalancesForPrefix(destination, account.BalanceMap[CREDIT+direction], "") - minuteBalances := account.getBalancesForPrefix(destination, account.BalanceMap[MINUTES+direction], "") + unitBalances := account.getBalancesForPrefix(destination, account.BalanceMap[unitType+direction], "") // gather all shared group ids var sharedGroupIds []string for _, cb := range creditBalances { @@ -487,7 +479,7 @@ func (account *Account) GetUniqueSharedGroupMembers(destination, direction strin sharedGroupIds = append(sharedGroupIds, cb.SharedGroup) } } - for _, mb := range minuteBalances { + for _, mb := range unitBalances { if mb.SharedGroup != "" { sharedGroupIds = append(sharedGroupIds, mb.SharedGroup) } diff --git a/engine/account_test.go b/engine/account_test.go index 547b464cb..c4b1ccca4 100644 --- a/engine/account_test.go +++ b/engine/account_test.go @@ -105,6 +105,7 @@ func TestGetSecondsForPrefix(t *testing.T) { CallDuration: 10 * time.Second, Direction: OUTBOUND, Destination: "0723", + Type: MINUTES, } seconds, credit, bucketList := ub1.getCreditForPrefix(cd) expected := 110 * time.Second @@ -133,6 +134,7 @@ func TestGetSpecialPricedSeconds(t *testing.T) { LoopIndex: 0, Direction: OUTBOUND, Destination: "0723", + Type: MINUTES, } seconds, credit, bucketList := ub1.getCreditForPrefix(cd) expected := 20 * time.Second @@ -170,13 +172,14 @@ func TestDebitCreditZeroSecond(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, + Type: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1}, CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}}}} err := rifsBalance.debitCreditBalance(cc, false) if err != nil { t.Error("Error debiting balance: ", err) } - if cc.Timespans[0].Increments[0].BalanceInfo.MinuteBalanceUuid != "testb" { + if cc.Timespans[0].Increments[0].BalanceInfo.UnitBalanceUuid != "testb" { t.Logf("%+v", cc.Timespans[0]) t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) } @@ -199,6 +202,7 @@ func TestDebitCreditZeroMinute(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, + Type: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ MINUTES + OUTBOUND: BalanceChain{b1}, @@ -209,7 +213,7 @@ func TestDebitCreditZeroMinute(t *testing.T) { t.Error("Error debiting balance: ", err) } t.Logf("%+v", cc.Timespans) - if cc.Timespans[0].Increments[0].BalanceInfo.MinuteBalanceUuid != "testb" || + if cc.Timespans[0].Increments[0].BalanceInfo.UnitBalanceUuid != "testb" || cc.Timespans[0].Increments[0].Duration != time.Minute { t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) } @@ -234,6 +238,7 @@ func TestDebitCreditZeroMixedMinute(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, + Type: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ MINUTES + OUTBOUND: BalanceChain{b1, b2}, @@ -243,8 +248,8 @@ func TestDebitCreditZeroMixedMinute(t *testing.T) { if err != nil { t.Error("Error debiting balance: ", err) } - if cc.Timespans[0].Increments[0].BalanceInfo.MinuteBalanceUuid != "tests" || - cc.Timespans[1].Increments[0].BalanceInfo.MinuteBalanceUuid != "testm" { + if cc.Timespans[0].Increments[0].BalanceInfo.UnitBalanceUuid != "tests" || + cc.Timespans[1].Increments[0].BalanceInfo.UnitBalanceUuid != "testm" { t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0], cc.Timespans[1].Increments[0]) } if rifsBalance.BalanceMap[MINUTES+OUTBOUND][1].Value != 0 || @@ -273,6 +278,7 @@ func TestDebitCreditNoCredit(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, + Type: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ MINUTES + OUTBOUND: BalanceChain{b1}, @@ -281,7 +287,7 @@ func TestDebitCreditNoCredit(t *testing.T) { if err == nil { t.Error("Showing no enough credit error ") } - if cc.Timespans[0].Increments[0].BalanceInfo.MinuteBalanceUuid != "testb" || + if cc.Timespans[0].Increments[0].BalanceInfo.UnitBalanceUuid != "testb" || cc.Timespans[0].Increments[0].Duration != time.Minute { t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) } @@ -313,6 +319,7 @@ func TestDebitCreditHasCredit(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, + Type: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ MINUTES + OUTBOUND: BalanceChain{b1}, @@ -322,7 +329,7 @@ func TestDebitCreditHasCredit(t *testing.T) { if err != nil { t.Error("Error debiting balance: ", err) } - if cc.Timespans[0].Increments[0].BalanceInfo.MinuteBalanceUuid != "testb" || + if cc.Timespans[0].Increments[0].BalanceInfo.UnitBalanceUuid != "testb" || cc.Timespans[0].Increments[0].Duration != time.Minute { t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) } @@ -350,6 +357,7 @@ func TestDebitCreditSplitMinutesMoney(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, + Type: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ MINUTES + OUTBOUND: BalanceChain{b1}, @@ -359,7 +367,7 @@ func TestDebitCreditSplitMinutesMoney(t *testing.T) { if err != nil { t.Error("Error debiting balance: ", err) } - if cc.Timespans[0].Increments[0].BalanceInfo.MinuteBalanceUuid != "testb" || + if cc.Timespans[0].Increments[0].BalanceInfo.UnitBalanceUuid != "testb" || cc.Timespans[0].Increments[0].Duration != 10*time.Second { t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) } @@ -392,6 +400,7 @@ func TestDebitCreditMoreTimespans(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, + Type: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ MINUTES + OUTBOUND: BalanceChain{b1}, @@ -400,7 +409,7 @@ func TestDebitCreditMoreTimespans(t *testing.T) { if err != nil { t.Error("Error debiting balance: ", err) } - if cc.Timespans[0].Increments[0].BalanceInfo.MinuteBalanceUuid != "testb" || + if cc.Timespans[0].Increments[0].BalanceInfo.UnitBalanceUuid != "testb" || cc.Timespans[0].Increments[0].Duration != time.Minute { t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) } @@ -430,6 +439,7 @@ func TestDebitCreditMoreTimespansMixed(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, + Type: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ MINUTES + OUTBOUND: BalanceChain{b1, b2}, @@ -438,7 +448,7 @@ func TestDebitCreditMoreTimespansMixed(t *testing.T) { if err != nil { t.Error("Error debiting balance: ", err) } - if cc.Timespans[0].Increments[0].BalanceInfo.MinuteBalanceUuid != "testb" || + if cc.Timespans[0].Increments[0].BalanceInfo.UnitBalanceUuid != "testb" || cc.Timespans[0].Increments[0].Duration != time.Minute { t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) } @@ -468,6 +478,7 @@ func TestDebitCreditNoConectFeeCredit(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, + Type: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ MINUTES + OUTBOUND: BalanceChain{b1}, @@ -501,6 +512,7 @@ func TestDebitCreditMoneyOnly(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, + Type: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "money", Value: 50}}, @@ -541,6 +553,7 @@ func TestDebitCreditSubjectMinutes(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, + Type: MINUTES, deductConnectFee: true, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ @@ -551,7 +564,7 @@ func TestDebitCreditSubjectMinutes(t *testing.T) { if err != nil { t.Error("Error debiting balance: ", err) } - if cc.Timespans[0].Increments[0].BalanceInfo.MinuteBalanceUuid != "testb" || + if cc.Timespans[0].Increments[0].BalanceInfo.UnitBalanceUuid != "testb" || cc.Timespans[0].Increments[0].BalanceInfo.MoneyBalanceUuid != "moneya" || cc.Timespans[0].Increments[0].Duration != time.Second { t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) @@ -583,6 +596,7 @@ func TestDebitCreditSubjectMoney(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, + Type: MINUTES, deductConnectFee: true, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ @@ -620,6 +634,7 @@ func TestDebitCreditSubjectMixed(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, + Type: MINUTES, deductConnectFee: true, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ @@ -630,7 +645,7 @@ func TestDebitCreditSubjectMixed(t *testing.T) { if err != nil { t.Error("Error debiting balance: ", err) } - if cc.Timespans[0].Increments[0].BalanceInfo.MinuteBalanceUuid != "testb" || + if cc.Timespans[0].Increments[0].BalanceInfo.UnitBalanceUuid != "testb" || cc.Timespans[0].Increments[0].BalanceInfo.MoneyBalanceUuid != "moneya" || cc.Timespans[0].Increments[0].Duration != time.Second { t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) @@ -669,6 +684,7 @@ func TestDebitCreditSubjectMixedMoreTS(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, + Type: MINUTES, deductConnectFee: true, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ @@ -680,7 +696,7 @@ func TestDebitCreditSubjectMixedMoreTS(t *testing.T) { t.Error("Error showing debiting balance error: ", err) } //t.Logf("%+v %+v", cc.Timespans[0], cc.Timespans[1]) - if cc.Timespans[0].Increments[0].BalanceInfo.MinuteBalanceUuid != "testb" || + if cc.Timespans[0].Increments[0].BalanceInfo.UnitBalanceUuid != "testb" || cc.Timespans[0].Increments[0].Duration != time.Second { t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) } @@ -720,6 +736,7 @@ func TestDebitCreditSubjectMixedPartPay(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, + Type: MINUTES, deductConnectFee: true, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ @@ -731,7 +748,7 @@ func TestDebitCreditSubjectMixedPartPay(t *testing.T) { t.Error("Error showing debiting balance error: ", err) } //t.Logf("%+v %+v", cc.Timespans[0], cc.Timespans[1]) - if cc.Timespans[0].Increments[0].BalanceInfo.MinuteBalanceUuid != "testb" || + if cc.Timespans[0].Increments[0].BalanceInfo.UnitBalanceUuid != "testb" || cc.Timespans[0].Increments[0].Duration != time.Second { t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) } @@ -940,12 +957,12 @@ func TestAccountRefund(t *testing.T) { }, } increments := Increments{ - &Increment{Cost: 2, BalanceInfo: &BalanceInfo{MinuteBalanceUuid: "", MoneyBalanceUuid: "moneya"}}, - &Increment{Cost: 2, Duration: 3 * time.Second, BalanceInfo: &BalanceInfo{MinuteBalanceUuid: "minutea", MoneyBalanceUuid: "moneya"}}, - &Increment{Duration: 4 * time.Second, BalanceInfo: &BalanceInfo{MinuteBalanceUuid: "minuteb", MoneyBalanceUuid: ""}}, + &Increment{Cost: 2, BalanceInfo: &BalanceInfo{UnitBalanceUuid: "", MoneyBalanceUuid: "moneya"}}, + &Increment{Cost: 2, Duration: 3 * time.Second, BalanceInfo: &BalanceInfo{UnitBalanceUuid: "minutea", MoneyBalanceUuid: "moneya"}}, + &Increment{Duration: 4 * time.Second, BalanceInfo: &BalanceInfo{UnitBalanceUuid: "minuteb", MoneyBalanceUuid: ""}}, } for _, increment := range increments { - ub.refundIncrement(increment, OUTBOUND, false) + ub.refundIncrement(increment, OUTBOUND, MINUTES, false) } if ub.BalanceMap[CREDIT+OUTBOUND][0].Value != 104 || ub.BalanceMap[MINUTES+OUTBOUND][0].Value != 13 || diff --git a/engine/balances.go b/engine/balances.go index 4a1fd7f50..5428eeb3f 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -142,7 +142,7 @@ func (b *Balance) SubstractAmount(amount float64) { b.dirty = true } -func (b *Balance) DebitMinutes(cc *CallCost, count bool, ub *Account, moneyBalances BalanceChain) error { +func (b *Balance) DebitUnits(cc *CallCost, count bool, ub *Account, moneyBalances BalanceChain) error { for tsIndex := 0; tsIndex < len(cc.Timespans); tsIndex++ { if b.Value <= 0 { return nil @@ -202,13 +202,13 @@ func (b *Balance) DebitMinutes(cc *CallCost, count bool, ub *Account, moneyBalan inc = newTs.Increments[0] } b.SubstractAmount(amount) - inc.BalanceInfo.MinuteBalanceUuid = b.Uuid + inc.BalanceInfo.UnitBalanceUuid = b.Uuid inc.BalanceInfo.AccountId = ub.Id - inc.MinuteInfo = &MinuteInfo{cc.Destination, amount} + inc.UnitInfo = &UnitInfo{cc.Destination, amount, cc.Type} inc.Cost = 0 inc.paid = true if count { - ub.countUnits(&Action{BalanceType: MINUTES, Direction: cc.Direction, Balance: &Balance{Value: amount, DestinationId: cc.Destination}}) + ub.countUnits(&Action{BalanceType: cc.Type, Direction: cc.Direction, Balance: &Balance{Value: amount, DestinationId: cc.Destination}}) } } continue @@ -242,9 +242,9 @@ func (b *Balance) DebitMinutes(cc *CallCost, count bool, ub *Account, moneyBalan } if (cost == 0 || moneyBal != nil) && b.Value >= seconds { b.SubstractAmount(seconds) - nInc.BalanceInfo.MinuteBalanceUuid = b.Uuid + nInc.BalanceInfo.UnitBalanceUuid = b.Uuid nInc.BalanceInfo.AccountId = ub.Id - nInc.MinuteInfo = &MinuteInfo{newCC.Destination, seconds} + nInc.UnitInfo = &UnitInfo{newCC.Destination, seconds, cc.Type} if cost != 0 { nInc.BalanceInfo.MoneyBalanceUuid = moneyBal.Uuid moneyBal.Value -= cost @@ -252,7 +252,7 @@ func (b *Balance) DebitMinutes(cc *CallCost, count bool, ub *Account, moneyBalan } nInc.paid = true if count { - ub.countUnits(&Action{BalanceType: MINUTES, Direction: newCC.Direction, Balance: &Balance{Value: seconds, DestinationId: newCC.Destination}}) + ub.countUnits(&Action{BalanceType: newCC.Type, Direction: newCC.Direction, Balance: &Balance{Value: seconds, DestinationId: newCC.Destination}}) if cost != 0 { ub.countUnits(&Action{BalanceType: CREDIT, Direction: newCC.Direction, Balance: &Balance{Value: cost, DestinationId: newCC.Destination}}) } diff --git a/engine/callcost.go b/engine/callcost.go index 3dd1a4aab..1ade50132 100644 --- a/engine/callcost.go +++ b/engine/callcost.go @@ -24,10 +24,10 @@ import ( // The output structure that will be returned with the call cost information. type CallCost struct { - Direction, TOR, Tenant, Subject, Account, Destination string - Cost float64 - Timespans TimeSpans - deductConnectFee bool + Direction, TOR, Tenant, Subject, Account, Destination, Type string + Cost float64 + Timespans TimeSpans + deductConnectFee bool } // Pretty printing for call cost diff --git a/engine/calldesc.go b/engine/calldesc.go index 0966c9adc..48d2537d3 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -116,7 +116,7 @@ type CallDescriptor struct { FallbackSubject string // the subject to check for destination if not found on primary subject RatingInfos RatingInfos Increments Increments - Amount float64 + Type string account *Account } @@ -306,33 +306,30 @@ func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) { } firstSpan.ratingInfo = cd.RatingInfos[0] - // split on rating plans - afterStart, afterEnd := false, false //optimization for multiple activation periods - for _, rp := range cd.RatingInfos { - if !afterStart && !afterEnd && rp.ActivationTime.Before(cd.TimeStart) { - firstSpan.ratingInfo = rp - firstSpan.MatchedSubject = rp.MatchedSubject - firstSpan.MatchedPrefix = rp.MatchedPrefix - firstSpan.MatchedDestId = rp.MatchedDestId - } else { - afterStart = true - for i := 0; i < len(timespans); i++ { - newTs := timespans[i].SplitByRatingPlan(rp) - if newTs != nil { - timespans = append(timespans, newTs) - } else { - afterEnd = true - break + if cd.Type == MINUTES { + // split on rating plans + afterStart, afterEnd := false, false //optimization for multiple activation periods + for _, rp := range cd.RatingInfos { + if !afterStart && !afterEnd && rp.ActivationTime.Before(cd.TimeStart) { + firstSpan.ratingInfo = rp + firstSpan.MatchedSubject = rp.MatchedSubject + firstSpan.MatchedPrefix = rp.MatchedPrefix + firstSpan.MatchedDestId = rp.MatchedDestId + } else { + afterStart = true + for i := 0; i < len(timespans); i++ { + newTs := timespans[i].SplitByRatingPlan(rp) + if newTs != nil { + timespans = append(timespans, newTs) + } else { + afterEnd = true + break + } } } } } - if cd.Amount > 0 { - cd.TimeEnd = cd.TimeStart.Add(time.Duration(utils.Round(cd.Amount, 0, utils.ROUNDING_UP)) * time.Second) - cd.CallDuration = cd.TimeEnd.Sub(cd.TimeStart) - //first span should be still the only one - firstSpan.TimeStart, firstSpan.TimeEnd, firstSpan.CallDuration = cd.TimeStart, cd.TimeEnd, cd.CallDuration - } + // Logger.Debug(fmt.Sprintf("After SplitByRatingPlan: %+v", timespans)) // split on price intervals for i := 0; i < len(timespans); i++ { @@ -403,6 +400,9 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) { if cd.CallDuration < cd.TimeEnd.Sub(cd.TimeStart) { cd.CallDuration = cd.TimeEnd.Sub(cd.TimeStart) } + if cd.Type == "" { + cd.Type = MINUTES + } err := cd.LoadRatingPlans() if err != nil { Logger.Err(fmt.Sprintf("error getting cost for key %s: %v", cd.GetKey(cd.Subject), err)) @@ -432,6 +432,7 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) { Cost: cost, Timespans: timespans, deductConnectFee: cd.LoopIndex == 0, + Type: cd.Type, } //Logger.Info(fmt.Sprintf(" Get Cost: %s => %v", cd.GetKey(), cc)) cc.Timespans.Compress() @@ -447,6 +448,9 @@ func (origCD *CallDescriptor) getMaxSessionDuration(account *Account) (time.Dura if origCD.CallDuration < origCD.TimeEnd.Sub(origCD.TimeStart) { origCD.CallDuration = origCD.TimeEnd.Sub(origCD.TimeStart) } + if origCD.Type == "" { + origCD.Type = MINUTES + } cd := origCD.Clone() //Logger.Debug(fmt.Sprintf("MAX SESSION cd: %+v", cd)) err := cd.LoadRatingPlans() @@ -510,7 +514,7 @@ func (cd *CallDescriptor) GetMaxSessionDuration() (duration time.Duration, err e Logger.Err(fmt.Sprintf("Could not get user balance for %s: %s.", cd.GetAccountKey(), err.Error())) return 0, err } else { - if memberIds, err := account.GetUniqueSharedGroupMembers(cd.Destination, cd.Direction); err == nil { + if memberIds, err := account.GetUniqueSharedGroupMembers(cd.Destination, cd.Direction, cd.Type); err == nil { AccLock.GuardMany(memberIds, func() (float64, error) { duration, err = cd.getMaxSessionDuration(account) return 0, err @@ -560,7 +564,7 @@ func (cd *CallDescriptor) Debit() (cc *CallCost, err error) { Logger.Err(fmt.Sprintf("Could not get user balance for %s: %s.", cd.GetAccountKey(), err.Error())) return nil, err } else { - if memberIds, err := account.GetUniqueSharedGroupMembers(cd.Destination, cd.Direction); err == nil { + if memberIds, err := account.GetUniqueSharedGroupMembers(cd.Destination, cd.Direction, cd.Type); err == nil { AccLock.GuardMany(memberIds, func() (float64, error) { cc, err = cd.debit(account) return 0, err @@ -581,7 +585,7 @@ func (cd *CallDescriptor) MaxDebit() (cc *CallCost, err error) { Logger.Err(fmt.Sprintf("Could not get user balance for %s: %s.", cd.GetAccountKey(), err.Error())) return nil, err } else { - if memberIds, err := account.GetUniqueSharedGroupMembers(cd.Destination, cd.Direction); err == nil { + if memberIds, err := account.GetUniqueSharedGroupMembers(cd.Destination, cd.Direction, cd.Type); err == nil { AccLock.GuardMany(memberIds, func() (float64, error) { remainingDuration, err := cd.getMaxSessionDuration(account) if err != nil || remainingDuration == 0 { @@ -614,7 +618,7 @@ func (cd *CallDescriptor) RefundIncrements() (left float64, err error) { defer accountingStorage.SetAccount(account) } } - account.refundIncrement(increment, cd.Direction, true) + account.refundIncrement(increment, cd.Direction, cd.Type, true) } return 0.0, err } @@ -637,6 +641,7 @@ func (cd *CallDescriptor) CreateCallCost() *CallCost { Subject: cd.Subject, Account: cd.Account, Destination: cd.Destination, + Type: cd.Type, } } @@ -656,5 +661,6 @@ func (cd *CallDescriptor) Clone() *CallDescriptor { FallbackSubject: cd.FallbackSubject, //RatingInfos: cd.RatingInfos, //Increments: cd.Increments, + Type: cd.Type, } } diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go index c43019d4b..da6f54948 100644 --- a/engine/calldesc_test.go +++ b/engine/calldesc_test.go @@ -443,6 +443,7 @@ func TestMaxSessionTimeNoCredit(t *testing.T) { Tenant: "vdf", Subject: "broker", Destination: "0723", + Type: MINUTES, } result, err := cd.GetMaxSessionDuration() if result != time.Minute || err != nil { @@ -463,6 +464,7 @@ func TestMaxSessionModifiesCallDesc(t *testing.T) { Account: "minu", Destination: "0723", CallDuration: t2.Sub(t1), + Type: MINUTES, } initial := cd.Clone() cd.GetMaxSessionDuration() @@ -648,15 +650,15 @@ func TestMaxDebitConsumesMinutes(t *testing.T) { func TestCDGetCostANY(t *testing.T) { cd1 := &CallDescriptor{ - Direction: "*out", - TOR: "data", - Tenant: "cgrates.org", - Subject: "rif", - Destination: utils.ANY, - TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), - TimeEnd: time.Date(2014, 3, 4, 6, 0, 1, 0, time.UTC), - LoopIndex: 0, - CallDuration: 0} + Direction: "*out", + TOR: "data", + Tenant: "cgrates.org", + Subject: "rif", + Destination: utils.ANY, + TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), + TimeEnd: time.Date(2014, 3, 4, 6, 0, 1, 0, time.UTC), + Type: DATA, + } cc, err := cd1.GetCost() if err != nil || cc.Cost != 60 { t.Errorf("Error getting *any dest: %+v %v", cc, err) @@ -671,10 +673,9 @@ func TestCDSplitInDataSlots(t *testing.T) { Subject: "rif", Destination: utils.ANY, TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), - TimeEnd: time.Date(2014, 3, 4, 6, 0, 1, 0, time.UTC), - LoopIndex: 0, - CallDuration: 0, - Amount: 65, + TimeEnd: time.Date(2014, 3, 4, 6, 1, 5, 0, time.UTC), + Type: DATA, + CallDuration: 65 * time.Second, } cd.LoadRatingPlans() timespans := cd.splitInTimeSpans() @@ -686,16 +687,14 @@ func TestCDSplitInDataSlots(t *testing.T) { func TestCDDataGetCost(t *testing.T) { cd := &CallDescriptor{ - Direction: "*out", - TOR: "data", - Tenant: "cgrates.org", - Subject: "rif", - Destination: utils.ANY, - TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), - TimeEnd: time.Date(2014, 3, 4, 6, 0, 1, 0, time.UTC), - LoopIndex: 0, - CallDuration: 0, - Amount: 65, + Direction: "*out", + TOR: "data", + Tenant: "cgrates.org", + Subject: "rif", + Destination: utils.ANY, + TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), + TimeEnd: time.Date(2014, 3, 4, 6, 1, 5, 0, time.UTC), + Type: DATA, } cc, err := cd.GetCost() if err != nil || cc.Cost != 65 { diff --git a/engine/responder.go b/engine/responder.go index b050fb298..7251d8675 100644 --- a/engine/responder.go +++ b/engine/responder.go @@ -152,53 +152,6 @@ func (rs *Responder) Shutdown(arg string, reply *string) (err error) { return } -func (rs *Responder) GetMonetary(arg CallDescriptor, reply *CallCost) (err error) { - err = rs.getBalance(&arg, CREDIT, reply) - return err -} - -func (rs *Responder) GetSMS(arg CallDescriptor, reply *CallCost) (err error) { - err = rs.getBalance(&arg, SMS, reply) - return err -} - -func (rs *Responder) GetInternet(arg CallDescriptor, reply *CallCost) (err error) { - err = rs.getBalance(&arg, DATA, reply) - return err -} - -func (rs *Responder) GetInternetTime(arg CallDescriptor, reply *CallCost) (err error) { - err = rs.getBalance(&arg, DATA_TIME, reply) - return err -} - -func (rs *Responder) GetMinutes(arg CallDescriptor, reply *CallCost) (err error) { - err = rs.getBalance(&arg, MINUTES, reply) - return err -} - -// Get balance -func (rs *Responder) getBalance(arg *CallDescriptor, balanceId string, reply *CallCost) (err error) { - if rs.Bal != nil { - return errors.New("No balancer supported for this command right now") - } - ubKey := arg.Direction + ":" + arg.Tenant + ":" + arg.Account - userBalance, err := accountingStorage.GetAccount(ubKey) - if err != nil { - return err - } - if balance, balExists := userBalance.BalanceMap[balanceId+arg.Direction]; !balExists { - // No match, balanceId not found - return errors.New("-BALANCE_NOT_FOUND") - } else { - reply.Tenant = arg.Tenant - reply.Account = arg.Account - reply.Direction = arg.Direction - reply.Cost = balance.GetTotalValue() - } - return nil -} - /* The function that gets the information from the raters using balancer. */ diff --git a/engine/timespans.go b/engine/timespans.go index 6328a4a43..22fed8d20 100644 --- a/engine/timespans.go +++ b/engine/timespans.go @@ -45,32 +45,33 @@ type Increment struct { Cost float64 BalanceInfo *BalanceInfo // need more than one for minutes with cost BalanceRateInterval *RateInterval - MinuteInfo *MinuteInfo + UnitInfo *UnitInfo CompressFactor int paid bool } // Holds the minute information related to a specified timespan -type MinuteInfo struct { +type UnitInfo struct { DestinationId string Quantity float64 + Type string //Price float64 } -func (mi *MinuteInfo) Equal(other *MinuteInfo) bool { +func (mi *UnitInfo) Equal(other *UnitInfo) bool { return mi.DestinationId == other.DestinationId && mi.Quantity == other.Quantity } // Holds information about the balance that made a specific payment type BalanceInfo struct { - MinuteBalanceUuid string - MoneyBalanceUuid string - AccountId string // used when debited from shared balance + UnitBalanceUuid string + MoneyBalanceUuid string + AccountId string // used when debited from shared balance } func (bi *BalanceInfo) Equal(other *BalanceInfo) bool { - return bi.MinuteBalanceUuid == other.MinuteBalanceUuid && + return bi.UnitBalanceUuid == other.UnitBalanceUuid && bi.MoneyBalanceUuid == other.MoneyBalanceUuid && bi.AccountId == other.AccountId } @@ -191,7 +192,7 @@ func (incr *Increment) Clone() *Increment { Duration: incr.Duration, Cost: incr.Cost, BalanceRateInterval: incr.BalanceRateInterval, - MinuteInfo: incr.MinuteInfo, + UnitInfo: incr.UnitInfo, BalanceInfo: incr.BalanceInfo, } return nIncr @@ -202,7 +203,7 @@ func (incr *Increment) Equal(other *Increment) bool { incr.Cost == other.Cost && ((incr.BalanceInfo == nil && other.BalanceInfo == nil) || incr.BalanceInfo.Equal(other.BalanceInfo)) && ((incr.BalanceRateInterval == nil && other.BalanceRateInterval == nil) || reflect.DeepEqual(incr.BalanceRateInterval, other.BalanceRateInterval)) && - ((incr.MinuteInfo == nil && other.MinuteInfo == nil) || incr.MinuteInfo.Equal(other.MinuteInfo)) + ((incr.UnitInfo == nil && other.UnitInfo == nil) || incr.UnitInfo.Equal(other.UnitInfo)) } func (incr *Increment) GetCompressFactor() int { diff --git a/engine/timespans_test.go b/engine/timespans_test.go index cd4c753b9..5ac42d5c5 100644 --- a/engine/timespans_test.go +++ b/engine/timespans_test.go @@ -1501,35 +1501,35 @@ func TestTSCompressDecompress(t *testing.T) { Cost: 10.4, BalanceInfo: &BalanceInfo{"1", "2", "3"}, BalanceRateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, - MinuteInfo: &MinuteInfo{"1", 2.3}, + UnitInfo: &UnitInfo{"1", 2.3, MINUTES}, }, &Increment{ Duration: time.Minute, Cost: 10.4, BalanceInfo: &BalanceInfo{"1", "2", "3"}, BalanceRateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, - MinuteInfo: &MinuteInfo{"1", 2.3}, + UnitInfo: &UnitInfo{"1", 2.3, MINUTES}, }, &Increment{ Duration: time.Minute, Cost: 10.4, BalanceInfo: &BalanceInfo{"1", "2", "3"}, BalanceRateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, - MinuteInfo: &MinuteInfo{"1", 2.3}, + UnitInfo: &UnitInfo{"1", 2.3, MINUTES}, }, &Increment{ Duration: time.Minute, Cost: 10.4, BalanceInfo: &BalanceInfo{"1", "2", "3"}, BalanceRateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 1111 * time.Second, RateUnit: time.Second}}}}, - MinuteInfo: &MinuteInfo{"1", 2.3}, + UnitInfo: &UnitInfo{"1", 2.3, MINUTES}, }, &Increment{ Duration: time.Minute, Cost: 10.4, BalanceInfo: &BalanceInfo{"1", "2", "3"}, BalanceRateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, - MinuteInfo: &MinuteInfo{"1", 2.3}, + UnitInfo: &UnitInfo{"1", 2.3, MINUTES}, }, }, }, @@ -1553,35 +1553,35 @@ func TestTSMultipleCompressDecompress(t *testing.T) { Cost: 10.4, BalanceInfo: &BalanceInfo{"1", "2", "3"}, BalanceRateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, - MinuteInfo: &MinuteInfo{"1", 2.3}, + UnitInfo: &UnitInfo{"1", 2.3, MINUTES}, }, &Increment{ Duration: time.Minute, Cost: 10.4, BalanceInfo: &BalanceInfo{"1", "2", "3"}, BalanceRateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, - MinuteInfo: &MinuteInfo{"1", 2.3}, + UnitInfo: &UnitInfo{"1", 2.3, MINUTES}, }, &Increment{ Duration: time.Minute, Cost: 10.4, BalanceInfo: &BalanceInfo{"1", "2", "3"}, BalanceRateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, - MinuteInfo: &MinuteInfo{"1", 2.3}, + UnitInfo: &UnitInfo{"1", 2.3, MINUTES}, }, &Increment{ Duration: time.Minute, Cost: 10.4, BalanceInfo: &BalanceInfo{"1", "2", "3"}, BalanceRateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 1111 * time.Second, RateUnit: time.Second}}}}, - MinuteInfo: &MinuteInfo{"1", 2.3}, + UnitInfo: &UnitInfo{"1", 2.3, MINUTES}, }, &Increment{ Duration: time.Minute, Cost: 10.4, BalanceInfo: &BalanceInfo{"1", "2", "3"}, BalanceRateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, - MinuteInfo: &MinuteInfo{"1", 2.3}, + UnitInfo: &UnitInfo{"1", 2.3, MINUTES}, }, }, }, From 61e81ced27dda4e6e4955c8a51fe816c005e2289 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 25 Apr 2014 01:20:38 +0300 Subject: [PATCH 03/17] small go vet fix --- engine/storage_sql.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/storage_sql.go b/engine/storage_sql.go index 51e44ab95..895093848 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -795,7 +795,7 @@ func (self *SQLStorage) GetStoredCdrs(cgrIds, runIds, cdrHosts, cdrSources, reqT return nil, err } if err := json.Unmarshal(extraFields, &extraFieldsMp); err != nil { - return nil, fmt.Errorf("JSON unmarshal error for cgrid: %s, runid: %s, error: %s", cgrid, runid, err.Error()) + return nil, fmt.Errorf("JSON unmarshal error for cgrid: %s, runid: %v, error: %s", cgrid, runid, err.Error()) } storCdr := &utils.StoredCdr{ CgrId: cgrid, OrderId: orderid, AccId: accid, CdrHost: cdrhost, CdrSource: cdrsrc, ReqType: reqtype, Direction: direction, Tenant: tenant, From 4265dff0120c49d312db483e4d857aca82300a3d Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 25 Apr 2014 10:37:42 +0300 Subject: [PATCH 04/17] *minutes is now *call --- engine/account.go | 2 +- engine/loader_csv_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/engine/account.go b/engine/account.go index 4ed40469e..055c4ee25 100644 --- a/engine/account.go +++ b/engine/account.go @@ -37,7 +37,7 @@ const ( CREDIT = "*monetary" SMS = "*sms" DATA = "*data" - MINUTES = "*minutes" + MINUTES = "*call" // action trigger threshold types TRIGGER_MIN_COUNTER = "*min_counter" TRIGGER_MAX_COUNTER = "*max_counter" diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 0ffbd09a9..3b9ed2082 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -134,10 +134,10 @@ SG3,*any,*lowest, actions = ` MINI,*topup_reset,*monetary,*out,10,*unlimited,,,10,,,10 -MINI,*topup,*minutes,*out,100,*unlimited,NAT,test,10,,,10 +MINI,*topup,*call,*out,100,*unlimited,NAT,test,10,,,10 SHARED,*topup,*monetary,*out,100,*unlimited,,,10,SG1,,10 TOPUP10_AC,*topup_reset,*monetary,*out,1,*unlimited,*any,,10,,,10 -TOPUP10_AC1,*topup_reset,*minutes,*out,40,*unlimited,DST_UK_Mobile_BIG5,discounted_minutes,10,,,10 +TOPUP10_AC1,*topup_reset,*call,*out,40,*unlimited,DST_UK_Mobile_BIG5,discounted_minutes,10,,,10 SE0,*topup_reset,*monetary,*out,0,*unlimited,,,10,SG2,,10 SE10,*topup_reset,*monetary,*out,10,*unlimited,,,5,SG2,,10 SE10,*topup,*monetary,*out,10,*unlimited,,,10,,,10 @@ -154,8 +154,8 @@ TOPUP_SHARED10_AT,SE10,ASAP,10 TOPUP_EMPTY_AT,EE0,ASAP,10 ` actionTriggers = ` -STANDARD_TRIGGER,*minutes,*out,*min_counter,10,GERMANY_O2,SOME_1,10 -STANDARD_TRIGGER,*minutes,*out,*max_balance,200,GERMANY,SOME_2,10 +STANDARD_TRIGGER,*call,*out,*min_counter,10,GERMANY_O2,SOME_1,10 +STANDARD_TRIGGER,*call,*out,*max_balance,200,GERMANY,SOME_2,10 STANDARD_TRIGGERS,*monetary,*out,*min_balance,2,,LOG_WARNING,10 STANDARD_TRIGGERS,*monetary,*out,*max_balance,20,,LOG_WARNING,10 STANDARD_TRIGGERS,*monetary,*out,*max_counter,5,FS_USERS,LOG_WARNING,10 From 2013c16b0e5c8323c803409e157826f3111cc6d3 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 25 Apr 2014 10:38:13 +0300 Subject: [PATCH 05/17] small simplification --- utils/map.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/utils/map.go b/utils/map.go index 94aab386d..d996bdb99 100644 --- a/utils/map.go +++ b/utils/map.go @@ -40,9 +40,7 @@ func MirrorMap(mapIn map[string]string) (map[string]string, error) { func MissingMapKeys(inMap map[string]string, requiredKeys []string) []string { missingKeys := []string{} for _, reqKey := range requiredKeys { - if val, hasKey := inMap[reqKey]; !hasKey { - missingKeys = append(missingKeys, reqKey) - } else if val == "" { + if val, hasKey := inMap[reqKey]; !hasKey || val == "" { missingKeys = append(missingKeys, reqKey) } } From c790f59b58c143a99a7679280b680f10e9d7d292 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 25 Apr 2014 13:00:51 +0300 Subject: [PATCH 06/17] initial tests for data rating --- engine/account_test.go | 108 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/engine/account_test.go b/engine/account_test.go index c4b1ccca4..6b62b9502 100644 --- a/engine/account_test.go +++ b/engine/account_test.go @@ -1030,6 +1030,114 @@ func TestDebitShared(t *testing.T) { } } +func TestDebitSMS(t *testing.T) { + cc := &CallCost{ + 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, 48, 1, 0, time.UTC), + ratingInfo: &RatingInfo{}, + CallDuration: 0, + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 1 * time.Second, RateUnit: time.Second}}}}, + }, + }, + Type: SMS, + } + rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ + SMS + OUTBOUND: BalanceChain{&Balance{Uuid: "testm", Value: 100, Weight: 5, DestinationId: "NAT"}}, + CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}}, + }} + err := rifsBalance.debitCreditBalance(cc, false) + if err != nil { + t.Error("Error debiting balance: ", err) + } + if cc.Timespans[0].Increments[0].BalanceInfo.UnitBalanceUuid != "testm" { + t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) + } + if rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value != 99 || + rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value != 21 { + t.Log(cc.Timespans[0].Increments) + t.Error("Error extracting minutes from balance: ", rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value, rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value) + } +} + +func TestDebitDataUnits(t *testing.T) { + cc := &CallCost{ + 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, 20, 0, time.UTC), + ratingInfo: &RatingInfo{}, + CallDuration: 0, + RateInterval: &RateInterval{ + Rating: &RIRate{ + Rates: RateGroups{ + &Rate{GroupIntervalStart: 0, Value: 2, RateIncrement: 1 * time.Second, RateUnit: time.Minute}, + &Rate{GroupIntervalStart: 60, Value: 1, RateIncrement: 1 * time.Second, RateUnit: time.Second}, + }, + }, + }, + }, + }, + Type: DATA, + } + rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ + DATA + OUTBOUND: BalanceChain{&Balance{Uuid: "testm", Value: 100, Weight: 5, DestinationId: "NAT"}}, + CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}}, + }} + err := rifsBalance.debitCreditBalance(cc, false) + if err != nil { + t.Error("Error debiting balance: ", err) + } + if cc.Timespans[0].Increments[0].BalanceInfo.UnitBalanceUuid != "testm" { + t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) + } + if rifsBalance.BalanceMap[DATA+OUTBOUND][0].Value != 20 || + rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value != 21 { + t.Log(cc.Timespans[0].Increments) + t.Error("Error extracting minutes from balance: ", rifsBalance.BalanceMap[DATA+OUTBOUND][0].Value, rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value) + } +} + +func TestDebitDataMoney(t *testing.T) { + cc := &CallCost{ + 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, 20, 0, time.UTC), + ratingInfo: &RatingInfo{}, + CallDuration: 0, + RateInterval: &RateInterval{ + Rating: &RIRate{ + Rates: RateGroups{ + &Rate{GroupIntervalStart: 0, Value: 2, RateIncrement: time.Minute, RateUnit: time.Second}, + }, + }, + }, + }, + }, + Type: DATA, + } + rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ + DATA + OUTBOUND: BalanceChain{&Balance{Uuid: "testm", Value: 0, Weight: 5, DestinationId: "NAT"}}, + CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 160}}, + }} + err := rifsBalance.debitCreditBalance(cc, false) + if err != nil { + t.Error("Error debiting balance: ", err) + } + if rifsBalance.BalanceMap[DATA+OUTBOUND][0].Value != 0 || + rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value != 0 { + t.Error("Error extracting minutes from balance: ", rifsBalance.BalanceMap[DATA+OUTBOUND][0].Value, rifsBalance.BalanceMap[CREDIT+OUTBOUND][0].Value) + } +} + /*********************************** Benchmarks *******************************/ func BenchmarkGetSecondForPrefix(b *testing.B) { From 022e3a8c38662ed4b05181aef370c79d79825d97 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 25 Apr 2014 14:12:17 +0300 Subject: [PATCH 07/17] callcost to datacost conversion method --- console/callcost.go | 2 +- engine/callcost.go | 47 +++++++++++++++++++++++++++++++++++++++++ engine/callcost_test.go | 44 ++++++++++++++++++++++++++++++++++++++ engine/datacost.go | 45 +++++++++++++++++++++++++++++++++++++++ engine/timespans.go | 2 +- 5 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 engine/datacost.go diff --git a/console/callcost.go b/console/callcost.go index 6507f8213..34651b13a 100644 --- a/console/callcost.go +++ b/console/callcost.go @@ -50,7 +50,7 @@ func (self *CmdGetCallCost) RpcMethod() string { } func (self *CmdGetCallCost) RpcParams() interface{} { -if self.rpcParams == nil { + if self.rpcParams == nil { self.rpcParams = &apier.AttrGetCallCost{RunId: utils.DEFAULT_RUNID} } return self.rpcParams diff --git a/engine/callcost.go b/engine/callcost.go index 1ade50132..66d81bd0f 100644 --- a/engine/callcost.go +++ b/engine/callcost.go @@ -18,6 +18,7 @@ along with this program. If not, see package engine import ( + "errors" "reflect" "time" ) @@ -114,3 +115,49 @@ func (cc *CallCost) IsPaid() bool { } return true } + +func (cc *CallCost) ToDataCost() (*DataCost, error) { + if cc.Type == MINUTES { + return nil, errors.New("Not a data call!") + } + dc := &DataCost{ + Direction: cc.Direction, + TOR: cc.TOR, + Tenant: cc.Tenant, + Subject: cc.Subject, + Account: cc.Account, + Destination: cc.Destination, + Type: cc.Type, + Cost: cc.Cost, + deductConnectFee: cc.deductConnectFee, + } + dc.DataSpans = make([]*DataSpan, len(cc.Timespans)) + for i, ts := range cc.Timespans { + length := ts.TimeEnd.Sub(ts.TimeStart).Seconds() + callDuration := ts.CallDuration.Seconds() + dc.DataSpans[i] = &DataSpan{ + DataStart: callDuration - length, + DataEnd: callDuration, + Cost: ts.Cost, + ratingInfo: ts.ratingInfo, + RateInterval: ts.RateInterval, + DataIndex: callDuration, + MatchedSubject: ts.MatchedSubject, + MatchedPrefix: ts.MatchedPrefix, + MatchedDestId: ts.MatchedDestId, + } + dc.DataSpans[i].Increments = make([]*DataIncrement, len(ts.Increments)) + for j, incr := range ts.Increments { + dc.DataSpans[i].Increments[j] = &DataIncrement{ + Amount: incr.Duration.Seconds(), + Cost: incr.Cost, + BalanceInfo: incr.BalanceInfo, + BalanceRateInterval: incr.BalanceRateInterval, + UnitInfo: incr.UnitInfo, + CompressFactor: incr.CompressFactor, + paid: incr.paid, + } + } + } + return dc, nil +} diff --git a/engine/callcost_test.go b/engine/callcost_test.go index 5b8fa78e2..89f4334e4 100644 --- a/engine/callcost_test.go +++ b/engine/callcost_test.go @@ -19,8 +19,11 @@ along with this program. If not, see package engine import ( + "encoding/json" "testing" "time" + + "github.com/cgrates/cgrates/utils" ) func TestSingleResultMerge(t *testing.T) { @@ -161,3 +164,44 @@ func TestCallCostGetDuration(t *testing.T) { t.Error("Wrong call cost duration: ", cc.GetDuration()) } } + +func TestCallCostToDataCostError(t *testing.T) { + cd := &CallDescriptor{ + Direction: "*out", + TOR: "data", + Tenant: "cgrates.org", + Subject: "rif", + Destination: utils.ANY, + TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), + TimeEnd: time.Date(2014, 3, 4, 6, 1, 5, 0, time.UTC), + Type: MINUTES, + } + cc, _ := cd.GetCost() + _, err := cc.ToDataCost() + if err == nil { + t.Error("Failed to throw error on call to datacost!") + } +} + +func TestCallCostToDataCost(t *testing.T) { + cd := &CallDescriptor{ + Direction: "*out", + TOR: "data", + Tenant: "cgrates.org", + Subject: "rif", + Destination: utils.ANY, + TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), + TimeEnd: time.Date(2014, 3, 4, 6, 1, 5, 0, time.UTC), + Type: DATA, + } + cc, _ := cd.GetCost() + dc, err := cc.ToDataCost() + if err != nil { + t.Error("Error convertiong to data cost: ", err) + } + js, _ := json.Marshal(dc) + expected := `{"Direction":"*out","TOR":"data","Tenant":"cgrates.org","Subject":"rif","Account":"","Destination":"*any","Type":"*data","Cost":65,"DataSpans":[{"DataStart":0,"DataEnd":60,"Cost":60,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":0,"Rates":[{"GroupIntervalStart":0,"Value":1,"RateIncrement":60000000000,"RateUnit":1000000000},{"GroupIntervalStart":60000000000,"Value":1,"RateIncrement":1000000000,"RateUnit":1000000000}],"RoundingMethod":"*up","RoundingDecimals":4},"Weight":10},"DataIndex":60,"Increments":[],"MatchedSubject":"","MatchedPrefix":"","MatchedDestId":""},{"DataStart":60,"DataEnd":65,"Cost":5,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":0,"Rates":[{"GroupIntervalStart":0,"Value":1,"RateIncrement":60000000000,"RateUnit":1000000000},{"GroupIntervalStart":60000000000,"Value":1,"RateIncrement":1000000000,"RateUnit":1000000000}],"RoundingMethod":"*up","RoundingDecimals":4},"Weight":10},"DataIndex":65,"Increments":[],"MatchedSubject":"*out:cgrates.org:data:rif","MatchedPrefix":"*any","MatchedDestId":"*any"}]}` + if string(js) != expected { + t.Error("Error coverting to data cost: ", string(js)) + } +} diff --git a/engine/datacost.go b/engine/datacost.go new file mode 100644 index 000000000..bb96a1cea --- /dev/null +++ b/engine/datacost.go @@ -0,0 +1,45 @@ +/* +Rating system designed to be used in VoIP Carriers World +Copyright (C) 2013 ITsysCOM + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ +package engine + +// type used for showing sane data cost +type DataCost struct { + Direction, TOR, Tenant, Subject, Account, Destination, Type string + Cost float64 + DataSpans []*DataSpan + deductConnectFee bool +} +type DataSpan struct { + DataStart, DataEnd float64 + Cost float64 + ratingInfo *RatingInfo + RateInterval *RateInterval + DataIndex float64 // the data transfer so far till DataEnd + Increments []*DataIncrement + MatchedSubject, MatchedPrefix, MatchedDestId string +} + +type DataIncrement struct { + Amount float64 + Cost float64 + BalanceInfo *BalanceInfo // need more than one for units with cost + BalanceRateInterval *RateInterval + UnitInfo *UnitInfo + CompressFactor int + paid bool +} diff --git a/engine/timespans.go b/engine/timespans.go index 22fed8d20..19f876199 100644 --- a/engine/timespans.go +++ b/engine/timespans.go @@ -43,7 +43,7 @@ type TimeSpan struct { type Increment struct { Duration time.Duration Cost float64 - BalanceInfo *BalanceInfo // need more than one for minutes with cost + BalanceInfo *BalanceInfo // need more than one for units with cost BalanceRateInterval *RateInterval UnitInfo *UnitInfo CompressFactor int From 575bcf2434d37bfc10bc9be3cfd76aac8e69cff1 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 25 Apr 2014 17:16:59 +0300 Subject: [PATCH 08/17] 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]) } } From 4fdf80c63389b83c2064d70d4bd3ce23f2d94a2a Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 25 Apr 2014 19:13:14 +0300 Subject: [PATCH 09/17] renamed *call to *call_duration --- engine/account.go | 2 +- engine/loader_csv_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/engine/account.go b/engine/account.go index 055c4ee25..8f0344c9c 100644 --- a/engine/account.go +++ b/engine/account.go @@ -37,7 +37,7 @@ const ( CREDIT = "*monetary" SMS = "*sms" DATA = "*data" - MINUTES = "*call" + MINUTES = "*call_duration" // action trigger threshold types TRIGGER_MIN_COUNTER = "*min_counter" TRIGGER_MAX_COUNTER = "*max_counter" diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index e7f2a060b..916d2f0d8 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -138,10 +138,10 @@ SG3,*any,*lowest, actions = ` MINI,*topup_reset,*monetary,*out,10,*unlimited,,,10,,,10 -MINI,*topup,*call,*out,100,*unlimited,NAT,test,10,,,10 +MINI,*topup,*call_duration,*out,100,*unlimited,NAT,test,10,,,10 SHARED,*topup,*monetary,*out,100,*unlimited,,,10,SG1,,10 TOPUP10_AC,*topup_reset,*monetary,*out,1,*unlimited,*any,,10,,,10 -TOPUP10_AC1,*topup_reset,*call,*out,40,*unlimited,DST_UK_Mobile_BIG5,discounted_minutes,10,,,10 +TOPUP10_AC1,*topup_reset,*call_duration,*out,40,*unlimited,DST_UK_Mobile_BIG5,discounted_minutes,10,,,10 SE0,*topup_reset,*monetary,*out,0,*unlimited,,,10,SG2,,10 SE10,*topup_reset,*monetary,*out,10,*unlimited,,,5,SG2,,10 SE10,*topup,*monetary,*out,10,*unlimited,,,10,,,10 @@ -158,8 +158,8 @@ TOPUP_SHARED10_AT,SE10,ASAP,10 TOPUP_EMPTY_AT,EE0,ASAP,10 ` actionTriggers = ` -STANDARD_TRIGGER,*call,*out,*min_counter,10,GERMANY_O2,SOME_1,10 -STANDARD_TRIGGER,*call,*out,*max_balance,200,GERMANY,SOME_2,10 +STANDARD_TRIGGER,*call_duration,*out,*min_counter,10,GERMANY_O2,SOME_1,10 +STANDARD_TRIGGER,*call_duration,*out,*max_balance,200,GERMANY,SOME_2,10 STANDARD_TRIGGERS,*monetary,*out,*min_balance,2,,LOG_WARNING,10 STANDARD_TRIGGERS,*monetary,*out,*max_balance,20,,LOG_WARNING,10 STANDARD_TRIGGERS,*monetary,*out,*max_counter,5,FS_USERS,LOG_WARNING,10 From 99faa0c11228abe54c3f9e627c362d6e3014e6b0 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 25 Apr 2014 19:23:24 +0300 Subject: [PATCH 10/17] recurrent action trigger --- engine/account.go | 10 ++++++++++ engine/action.go | 16 ++++++++++++++++ engine/action_trigger.go | 3 ++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/engine/account.go b/engine/account.go index 8f0344c9c..6833f249d 100644 --- a/engine/account.go +++ b/engine/account.go @@ -383,6 +383,16 @@ func (ub *Account) ResetActionTriggers(a *Action) { ub.executeActionTriggers(a) } +// Sets/Unsets recurrent flag for action triggers +func (ub *Account) SetRecurrent(a *Action, recurrent bool) { + for _, at := range ub.ActionTriggers { + if !at.Match(a) { + continue + } + at.Recurrent = recurrent + } +} + // Returns the unit counter that matches the specified action type func (ub *Account) getUnitCounter(a *Action) *UnitsCounter { for _, uc := range ub.UnitCounters { diff --git a/engine/action.go b/engine/action.go index 84a016429..32ca17de4 100644 --- a/engine/action.go +++ b/engine/action.go @@ -50,6 +50,8 @@ type Action struct { const ( LOG = "*log" RESET_TRIGGERS = "*reset_triggers" + SET_RECURRENT = "*set_recurrent" + UNSET_RECURRENT = "*unset_recurrent" ALLOW_NEGATIVE = "*allow_negative" DENY_NEGATIVE = "*deny_negative" RESET_ACCOUNT = "*reset_account" @@ -74,6 +76,10 @@ func getActionFunc(typ string) (actionTypeFunc, bool) { return logAction, true case RESET_TRIGGERS: return resetTriggersAction, true + case SET_RECURRENT: + return setRecurrentAction, true + case UNSET_RECURRENT: + return unsetRecurrentAction, true case ALLOW_NEGATIVE: return allowNegativeAction, true case DENY_NEGATIVE: @@ -115,6 +121,16 @@ func resetTriggersAction(ub *Account, a *Action) (err error) { return } +func setRecurrentAction(ub *Account, a *Action) (err error) { + ub.SetRecurrent(a, true) + return +} + +func unsetRecurrentAction(ub *Account, a *Action) (err error) { + ub.SetRecurrent(a, false) + return +} + func allowNegativeAction(ub *Account, a *Action) (err error) { ub.AllowNegative = true return diff --git a/engine/action_trigger.go b/engine/action_trigger.go index 676b08a02..c5b73f75f 100644 --- a/engine/action_trigger.go +++ b/engine/action_trigger.go @@ -36,6 +36,7 @@ type ActionTrigger struct { Weight float64 ActionsId string Executed bool + Recurrent bool } func (at *ActionTrigger) Execute(ub *Account) (err error) { @@ -68,7 +69,7 @@ func (at *ActionTrigger) Execute(ub *Account) (err error) { atLeastOneActionExecuted = true } } - if !atLeastOneActionExecuted { + if !atLeastOneActionExecuted || at.Recurrent { at.Executed = false } storageLogger.LogActionTrigger(ub.Id, RATER_SOURCE, at, aac) From 4934daa6b9afc00e6e781e56589bc8c610651f66 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 25 Apr 2014 20:26:41 +0300 Subject: [PATCH 11/17] modified loader for recurrent flag --- data/tariffplans/prepaid1centpsec/ActionTriggers.csv | 6 +++--- engine/action_trigger.go | 2 +- engine/loader_csv.go | 11 ++++++++--- engine/loader_csv_test.go | 10 +++++----- engine/loader_db.go | 1 + engine/storage_sql.go | 3 ++- utils/apitpdata.go | 1 + utils/consts.go | 2 +- 8 files changed, 22 insertions(+), 14 deletions(-) diff --git a/data/tariffplans/prepaid1centpsec/ActionTriggers.csv b/data/tariffplans/prepaid1centpsec/ActionTriggers.csv index 22d063dfa..9e3929114 100644 --- a/data/tariffplans/prepaid1centpsec/ActionTriggers.csv +++ b/data/tariffplans/prepaid1centpsec/ActionTriggers.csv @@ -1,4 +1,4 @@ #Tag,BalanceType,Direction,ThresholdType,ThresholdValue,DestinationTag,ActionsTag,Weight -STANDARD_TRIGGERS,*monetary,*out,*min_balance,2,,LOG_BALANCE,10 -STANDARD_TRIGGERS,*monetary,*out,*max_balance,20,,LOG_BALANCE,10 -STANDARD_TRIGGERS,*monetary,*out,*max_counter,15,FS_USERS,LOG_BALANCE,10 +STANDARD_TRIGGERS,*monetary,*out,*min_balance,2,false,,LOG_BALANCE,10 +STANDARD_TRIGGERS,*monetary,*out,*max_balance,20,false,,LOG_BALANCE,10 +STANDARD_TRIGGERS,*monetary,*out,*max_counter,15,false,FS_USERS,LOG_BALANCE,10 diff --git a/engine/action_trigger.go b/engine/action_trigger.go index c5b73f75f..bac755d7e 100644 --- a/engine/action_trigger.go +++ b/engine/action_trigger.go @@ -32,11 +32,11 @@ type ActionTrigger struct { Direction string ThresholdType string //*min_counter, *max_counter, *min_balance, *max_balance ThresholdValue float64 + Recurrent bool // reset eexcuted flag each run DestinationId string Weight float64 ActionsId string Executed bool - Recurrent bool } func (at *ActionTrigger) Execute(ub *Account) (err error) { diff --git a/engine/loader_csv.go b/engine/loader_csv.go index f940f2a1e..573886f91 100644 --- a/engine/loader_csv.go +++ b/engine/loader_csv.go @@ -676,7 +676,11 @@ func (csvr *CSVReader) LoadActionTriggers() (err error) { if err != nil { return fmt.Errorf("Could not parse action trigger value: %v", err) } - weight, err := strconv.ParseFloat(record[7], 64) + recurrent, err := strconv.ParseBool(record[5]) + if err != nil { + return fmt.Errorf("Could not parse action trigger recurrent flag: %v", err) + } + weight, err := strconv.ParseFloat(record[8], 64) if err != nil { return fmt.Errorf("Could not parse action trigger weight: %v", err) } @@ -686,8 +690,9 @@ func (csvr *CSVReader) LoadActionTriggers() (err error) { Direction: record[2], ThresholdType: record[3], ThresholdValue: value, - DestinationId: record[5], - ActionsId: record[6], + Recurrent: recurrent, + DestinationId: record[6], + ActionsId: record[7], Weight: weight, } csvr.actionsTriggers[tag] = append(csvr.actionsTriggers[tag], at) diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 916d2f0d8..8d08b2353 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -158,11 +158,11 @@ TOPUP_SHARED10_AT,SE10,ASAP,10 TOPUP_EMPTY_AT,EE0,ASAP,10 ` actionTriggers = ` -STANDARD_TRIGGER,*call_duration,*out,*min_counter,10,GERMANY_O2,SOME_1,10 -STANDARD_TRIGGER,*call_duration,*out,*max_balance,200,GERMANY,SOME_2,10 -STANDARD_TRIGGERS,*monetary,*out,*min_balance,2,,LOG_WARNING,10 -STANDARD_TRIGGERS,*monetary,*out,*max_balance,20,,LOG_WARNING,10 -STANDARD_TRIGGERS,*monetary,*out,*max_counter,5,FS_USERS,LOG_WARNING,10 +STANDARD_TRIGGER,*call_duration,*out,*min_counter,10,false,GERMANY_O2,SOME_1,10 +STANDARD_TRIGGER,*call_duration,*out,*max_balance,200,false,GERMANY,SOME_2,10 +STANDARD_TRIGGERS,*monetary,*out,*min_balance,2,false,,LOG_WARNING,10 +STANDARD_TRIGGERS,*monetary,*out,*max_balance,20,false,,LOG_WARNING,10 +STANDARD_TRIGGERS,*monetary,*out,*max_counter,5,false,FS_USERS,LOG_WARNING,10 ` accountActions = ` vdf,minitsboy;a1;a2,*out,MORE_MINUTES,STANDARD_TRIGGER diff --git a/engine/loader_db.go b/engine/loader_db.go index d5baee716..993454094 100644 --- a/engine/loader_db.go +++ b/engine/loader_db.go @@ -529,6 +529,7 @@ func (dbr *DbReader) LoadActionTriggers() (err error) { DestinationId: apiAtr.DestinationId, Weight: apiAtr.Weight, ActionsId: apiAtr.ActionsId, + Recurrent: apiAtr.Recurrent, } } dbr.actionsTriggers[key] = atrs diff --git a/engine/storage_sql.go b/engine/storage_sql.go index 895093848..ec359b849 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -1137,7 +1137,8 @@ func (self *SQLStorage) GetTpActionTriggers(tpid, tag string) (map[string][]*uti for rows.Next() { var threshold, weight float64 var tpid, tag, balances_type, direction, destinations_tag, actions_tag, thresholdType string - if err := rows.Scan(&tpid, &tag, &balances_type, &direction, &thresholdType, &threshold, &destinations_tag, &actions_tag, &weight); err != nil { + var recurrent bool + if err := rows.Scan(&tpid, &tag, &balances_type, &direction, &thresholdType, &threshold, &recurrent, &destinations_tag, &actions_tag, &weight); err != nil { return nil, err } diff --git a/utils/apitpdata.go b/utils/apitpdata.go index 9ef7beb19..f7571cc3c 100644 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -245,6 +245,7 @@ type TPActionTrigger struct { Direction string // Traffic direction ThresholdType string // This threshold type ThresholdValue float64 // Threshold + Recurrent bool // reset executed flag each run DestinationId string // Id of the destination profile ActionsId string // Actions which will execute on threshold reached Weight float64 // weight diff --git a/utils/consts.go b/utils/consts.go index 612821ca8..5ae710082 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -56,7 +56,7 @@ const ( SHARED_GROUPS_NRCOLS = 4 ACTIONS_NRCOLS = 12 ACTION_PLANS_NRCOLS = 4 - ACTION_TRIGGERS_NRCOLS = 8 + ACTION_TRIGGERS_NRCOLS = 9 ACCOUNT_ACTIONS_NRCOLS = 5 DERIVED_CHARGERS_NRCOLS = 16 ROUNDING_UP = "*up" From bc94fe34d139bb2e9b0892df8e81c1494163495b Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 25 Apr 2014 20:36:40 +0300 Subject: [PATCH 12/17] millisecond for scheduler --- general_tests/ddazmbl1_test.go | 2 +- general_tests/ddazmbl2_test.go | 2 +- general_tests/ddazmbl3_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/general_tests/ddazmbl1_test.go b/general_tests/ddazmbl1_test.go index b9fb9dd1f..c74a2b02e 100644 --- a/general_tests/ddazmbl1_test.go +++ b/general_tests/ddazmbl1_test.go @@ -120,7 +120,7 @@ TOPUP10_AT,TOPUP10_AC1,ASAP,10` func TestExecuteActions(t *testing.T) { scheduler.NewScheduler().LoadActionTimings(acntDb) - time.Sleep(time.Duration(100) * time.Microsecond) // Give time to scheduler to topup the account + time.Sleep(time.Millisecond) // Give time to scheduler to topup the account if acnt, err := acntDb.GetAccount("*out:cgrates.org:12345"); err != nil { t.Error(err) } else if len(acnt.BalanceMap) != 2 { diff --git a/general_tests/ddazmbl2_test.go b/general_tests/ddazmbl2_test.go index 8d5ea7ac0..70bf91ed4 100644 --- a/general_tests/ddazmbl2_test.go +++ b/general_tests/ddazmbl2_test.go @@ -120,7 +120,7 @@ TOPUP10_AT,TOPUP10_AC1,ASAP,10` func TestExecuteActions2(t *testing.T) { scheduler.NewScheduler().LoadActionTimings(acntDb2) - time.Sleep(time.Duration(100) * time.Microsecond) // Give time to scheduler to topup the account + time.Sleep(time.Millisecond) // Give time to scheduler to topup the account if acnt, err := acntDb2.GetAccount("*out:cgrates.org:12345"); err != nil { t.Error(err) } else if len(acnt.BalanceMap) != 2 { diff --git a/general_tests/ddazmbl3_test.go b/general_tests/ddazmbl3_test.go index 98144f3a5..025e38aa3 100644 --- a/general_tests/ddazmbl3_test.go +++ b/general_tests/ddazmbl3_test.go @@ -118,7 +118,7 @@ cgrates.org,call,*out,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_ func TestExecuteActions3(t *testing.T) { scheduler.NewScheduler().LoadActionTimings(acntDb3) - time.Sleep(time.Duration(100) * time.Microsecond) // Give time to scheduler to topup the account + time.Sleep(time.Millisecond) // Give time to scheduler to topup the account if acnt, err := acntDb3.GetAccount("*out:cgrates.org:12345"); err != nil { t.Error(err) } else if len(acnt.BalanceMap) != 1 { From 6526e526034546236aee89f09db193ccecb21eda Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 25 Apr 2014 20:49:44 +0300 Subject: [PATCH 13/17] rating profile order + fix general tests --- .../mysql/create_tariffplan_tables.sql | 5 ++- engine/loader_csv.go | 2 +- engine/loader_csv_test.go | 38 +++++++++---------- engine/storage_sql.go | 2 +- general_tests/ddazmbl1_test.go | 6 +-- general_tests/ddazmbl2_test.go | 6 +-- general_tests/ddazmbl3_test.go | 6 +-- 7 files changed, 33 insertions(+), 32 deletions(-) diff --git a/data/storage/mysql/create_tariffplan_tables.sql b/data/storage/mysql/create_tariffplan_tables.sql index 271bd8e55..edea9fd10 100644 --- a/data/storage/mysql/create_tariffplan_tables.sql +++ b/data/storage/mysql/create_tariffplan_tables.sql @@ -183,6 +183,7 @@ CREATE TABLE `tp_action_triggers` ( `direction` varchar(8) NOT NULL, `threshold_type` char(12) NOT NULL, `threshold_value` double(20,4) NOT NULL, + `recurrent` bool NOT NULL, `destination_id` varchar(64) NOT NULL, `actions_id` varchar(64) NOT NULL, `weight` double(8,2) NOT NULL, @@ -219,9 +220,9 @@ CREATE TABLE tp_derived_chargers ( tbid int(11) NOT NULL AUTO_INCREMENT, tpid varchar(64) NOT NULL, loadid varchar(64) NOT NULL, + direction varchar(8) NOT NULL, tenant varchar(64) NOT NULL, tor varchar(16) NOT NULL, - direction varchar(8) NOT NULL, account varchar(24) NOT NULL, subject varchar(64) NOT NULL, runid_field varchar(24) NOT NULL, @@ -237,4 +238,4 @@ CREATE TABLE tp_derived_chargers ( duration_field varchar(24) NOT NULL, PRIMARY KEY (`tbid`), KEY `tpid` (`tpid`) -); \ No newline at end of file +); diff --git a/engine/loader_csv.go b/engine/loader_csv.go index 573886f91..d7aafd189 100644 --- a/engine/loader_csv.go +++ b/engine/loader_csv.go @@ -483,7 +483,7 @@ func (csvr *CSVReader) LoadRatingProfiles() (err error) { defer fp.Close() } for record, err := csvReader.Read(); err == nil; record, err = csvReader.Read() { - tenant, tor, direction, subject, fallbacksubject := record[0], record[1], record[2], record[3], record[6] + direction, tenant, tor, subject, fallbacksubject := record[0], record[1], record[2], record[3], record[6] at, err := utils.ParseDate(record[4]) if err != nil { return fmt.Errorf("Cannot parse activation time from %v", record[4]) diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 8d08b2353..39769d205 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -110,25 +110,25 @@ RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10 RP_DATA,DATA_RATE,ALWAYS,10 ` ratingProfiles = ` -CUSTOMER_1,0,*out,rif:from:tm,2012-01-01T00:00:00Z,PREMIUM,danb -CUSTOMER_1,0,*out,rif:from:tm,2012-02-28T00:00:00Z,STANDARD,danb -CUSTOMER_2,0,*out,danb:87.139.12.167,2012-01-01T00:00:00Z,STANDARD,danb -CUSTOMER_1,0,*out,danb,2012-01-01T00:00:00Z,PREMIUM, -vdf,0,*out,rif,2012-01-01T00:00:00Z,EVENING, -vdf,0,*out,rif,2012-02-28T00:00:00Z,EVENING, -vdf,0,*out,minu;a1;a2;a3,2012-01-01T00:00:00Z,EVENING, -vdf,0,*out,*any,2012-02-28T00:00:00Z,EVENING, -vdf,0,*out,one,2012-02-28T00:00:00Z,STANDARD, -vdf,0,*out,inf,2012-02-28T00:00:00Z,STANDARD,inf -vdf,0,*out,fall,2012-02-28T00:00:00Z,PREMIUM,rif -test,0,*out,trp,2013-10-01T00:00:00Z,TDRT,rif;danb -vdf,0,*out,fallback1,2013-11-18T13:45:00Z,G,fallback2 -vdf,0,*out,fallback1,2013-11-18T13:46:00Z,G,fallback2 -vdf,0,*out,fallback1,2013-11-18T13:47:00Z,G,fallback2 -vdf,0,*out,fallback2,2013-11-18T13:45:00Z,R,rif -cgrates.org,call,*out,*any,2013-01-06T00:00:00Z,RP_UK, -cgrates.org,call,*out,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG, -cgrates.org,data,*out,rif,2013-01-06T00:00:00Z,RP_DATA, +*out,CUSTOMER_1,0,rif:from:tm,2012-01-01T00:00:00Z,PREMIUM,danb +*out,CUSTOMER_1,0,rif:from:tm,2012-02-28T00:00:00Z,STANDARD,danb +*out,CUSTOMER_2,0,danb:87.139.12.167,2012-01-01T00:00:00Z,STANDARD,danb +*out,CUSTOMER_1,0,danb,2012-01-01T00:00:00Z,PREMIUM, +*out,vdf,0,rif,2012-01-01T00:00:00Z,EVENING, +*out,vdf,0,rif,2012-02-28T00:00:00Z,EVENING, +*out,vdf,0,minu;a1;a2;a3,2012-01-01T00:00:00Z,EVENING, +*out,vdf,0,*any,2012-02-28T00:00:00Z,EVENING, +*out,vdf,0,one,2012-02-28T00:00:00Z,STANDARD, +*out,vdf,0,inf,2012-02-28T00:00:00Z,STANDARD,inf +*out,vdf,0,fall,2012-02-28T00:00:00Z,PREMIUM,rif +*out,test,0,trp,2013-10-01T00:00:00Z,TDRT,rif;danb +*out,vdf,0,fallback1,2013-11-18T13:45:00Z,G,fallback2 +*out,vdf,0,fallback1,2013-11-18T13:46:00Z,G,fallback2 +*out,vdf,0,fallback1,2013-11-18T13:47:00Z,G,fallback2 +*out,vdf,0,fallback2,2013-11-18T13:45:00Z,R,rif +*out,cgrates.org,call,*any,2013-01-06T00:00:00Z,RP_UK, +*out,cgrates.org,call,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG, +*out,cgrates.org,data,rif,2013-01-06T00:00:00Z,RP_DATA, ` sharedGroups = ` SG1,*any,*lowest, diff --git a/engine/storage_sql.go b/engine/storage_sql.go index ec359b849..9a0190bef 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -1004,7 +1004,7 @@ func (self *SQLStorage) GetTpRatingPlans(tpid, tag string) (map[string][]*utils. } func (self *SQLStorage) GetTpRatingProfiles(qryRpf *utils.TPRatingProfile) (map[string]*utils.TPRatingProfile, error) { - q := fmt.Sprintf("SELECT loadid,tenant,tor,direction,subject,activation_time,rating_plan_id,fallback_subjects FROM %s WHERE tpid='%s'", + q := fmt.Sprintf("SELECT loadid,direction,tenant,tor,subject,activation_time,rating_plan_id,fallback_subjects FROM %s WHERE tpid='%s'", utils.TBL_TP_RATE_PROFILES, qryRpf.TPid) if len(qryRpf.LoadId) != 0 { q += fmt.Sprintf(" AND loadid='%s'", qryRpf.LoadId) diff --git a/general_tests/ddazmbl1_test.go b/general_tests/ddazmbl1_test.go index c74a2b02e..7905bfaf2 100644 --- a/general_tests/ddazmbl1_test.go +++ b/general_tests/ddazmbl1_test.go @@ -48,11 +48,11 @@ RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s,*up,8` DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5` ratingPlans := `RP_UK_Mobile_BIG5_PKG,DR_UK_Mobile_BIG5_PKG,ALWAYS,10 RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10` - ratingProfiles := `cgrates.org,call,*out,*any,2013-01-06T00:00:00Z,RP_UK, -cgrates.org,call,*out,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,` + ratingProfiles := `*out,cgrates.org,call,*any,2013-01-06T00:00:00Z,RP_UK, +*out,cgrates.org,call,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,` sharedGroups := `` actions := `TOPUP10_AC,*topup_reset,*monetary,*out,10,*unlimited,*any,,10,,,10 -TOPUP10_AC1,*topup_reset,*minutes,*out,40,*unlimited,DST_UK_Mobile_BIG5,discounted_minutes,10,,,10` +TOPUP10_AC1,*topup_reset,*call_duration,*out,40,*unlimited,DST_UK_Mobile_BIG5,discounted_minutes,10,,,10` actionPlans := `TOPUP10_AT,TOPUP10_AC,ASAP,10 TOPUP10_AT,TOPUP10_AC1,ASAP,10` actionTriggers := `` diff --git a/general_tests/ddazmbl2_test.go b/general_tests/ddazmbl2_test.go index 70bf91ed4..75b52b8a4 100644 --- a/general_tests/ddazmbl2_test.go +++ b/general_tests/ddazmbl2_test.go @@ -48,11 +48,11 @@ RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s,*up,8` DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5` ratingPlans := `RP_UK_Mobile_BIG5_PKG,DR_UK_Mobile_BIG5_PKG,ALWAYS,10 RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10` - ratingProfiles := `cgrates.org,call,*out,*any,2013-01-06T00:00:00Z,RP_UK, -cgrates.org,call,*out,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,` + ratingProfiles := `*out,cgrates.org,call,*any,2013-01-06T00:00:00Z,RP_UK, +*out,cgrates.org,call,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,` sharedGroups := `` actions := `TOPUP10_AC,*topup_reset,*monetary,*out,0,*unlimited,*any,,10,,,10 -TOPUP10_AC1,*topup_reset,*minutes,*out,40,*unlimited,DST_UK_Mobile_BIG5,discounted_minutes,10,,,10` +TOPUP10_AC1,*topup_reset,*call_duration,*out,40,*unlimited,DST_UK_Mobile_BIG5,discounted_minutes,10,,,10` actionPlans := `TOPUP10_AT,TOPUP10_AC,ASAP,10 TOPUP10_AT,TOPUP10_AC1,ASAP,10` actionTriggers := `` diff --git a/general_tests/ddazmbl3_test.go b/general_tests/ddazmbl3_test.go index 025e38aa3..c8958bfa6 100644 --- a/general_tests/ddazmbl3_test.go +++ b/general_tests/ddazmbl3_test.go @@ -48,10 +48,10 @@ RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s,*up,8` DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5` ratingPlans := `RP_UK_Mobile_BIG5_PKG,DR_UK_Mobile_BIG5_PKG,ALWAYS,10 RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10` - ratingProfiles := `cgrates.org,call,*out,*any,2013-01-06T00:00:00Z,RP_UK, -cgrates.org,call,*out,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,` + ratingProfiles := `*out,cgrates.org,call,*any,2013-01-06T00:00:00Z,RP_UK, +*out,cgrates.org,call,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,` sharedGroups := `` - actions := `TOPUP10_AC1,*topup_reset,*minutes,*out,40,*unlimited,DST_UK_Mobile_BIG5,discounted_minutes,10,,,10` + actions := `TOPUP10_AC1,*topup_reset,*call_duration,*out,40,*unlimited,DST_UK_Mobile_BIG5,discounted_minutes,10,,,10` actionPlans := `TOPUP10_AT,TOPUP10_AC1,ASAP,10` actionTriggers := `` accountActions := `cgrates.org,12345,*out,TOPUP10_AT,` From 25cb5be8c012919f8fb4de880de5e5dc74879a2d Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 25 Apr 2014 21:16:21 +0300 Subject: [PATCH 14/17] refactor CallDuration in DurationIndex and TOR in Category --- apier/apier.go | 6 +- apier/apier_local_test.go | 44 ++--- apier/tpratingprofiles.go | 4 +- apier/tutfscsv_local_test.go | 38 ++--- apier/tutfsjson_local_test.go | 12 +- cdrc/cdrc.go | 6 +- cdrc/cdrc_test.go | 2 +- cdre/csv_test.go | 2 +- cdre/fixedwidth_test.go | 8 +- cdrs/fscdr.go | 4 +- cdrs/fscdr_test.go | 4 +- config/config.go | 2 +- config/config_test.go | 2 +- engine/account_test.go | 256 ++++++++++++++--------------- engine/balances.go | 4 +- engine/callcost.go | 14 +- engine/callcost_test.go | 20 +-- engine/calldesc.go | 46 +++--- engine/calldesc_test.go | 172 +++++++++---------- engine/datacost.go | 8 +- engine/loader_db.go | 4 +- engine/ratingplan_test.go | 14 +- engine/ratingprofile_test.go | 4 +- engine/storage_sql.go | 14 +- engine/storage_sql_local_test.go | 16 +- engine/timespans.go | 24 +-- engine/timespans_test.go | 54 +++--- engine/tpimporter_csv.go | 2 +- general_tests/ddazmbl1_test.go | 2 +- general_tests/ddazmbl2_test.go | 2 +- general_tests/ddazmbl3_test.go | 2 +- mediator/mediator.go | 20 +-- sessionmanager/fsevent.go | 4 +- sessionmanager/fssessionmanager.go | 24 +-- sessionmanager/session.go | 10 +- utils/apitpdata.go | 8 +- utils/cgrcdr.go | 6 +- utils/cgrcdr_test.go | 4 +- utils/consts.go | 2 +- utils/rawcdr.go | 2 +- utils/storedcdr.go | 12 +- utils/storedcdr_test.go | 14 +- 42 files changed, 449 insertions(+), 449 deletions(-) diff --git a/apier/apier.go b/apier/apier.go index b1da3d780..266545871 100644 --- a/apier/apier.go +++ b/apier/apier.go @@ -211,7 +211,7 @@ func (self *ApierV1) LoadRatingProfile(attrs utils.TPRatingProfile, reply *strin type AttrSetRatingProfile struct { Tenant string // Tenant's Id - TOR string // TypeOfRecord + Category string // TypeOfRecord Direction string // Traffic direction, OUT is the only one supported for now Subject string // Rating subject, usually the same as account Overwrite bool // Overwrite if exists @@ -228,7 +228,7 @@ func (self *ApierV1) SetRatingProfile(attrs AttrSetRatingProfile, reply *string) return fmt.Errorf("%s:RatingPlanActivation:%v", utils.ERR_MANDATORY_IE_MISSING, missing) } } - tpRpf := utils.TPRatingProfile{Tenant: attrs.Tenant, TOR: attrs.TOR, Direction: attrs.Direction, Subject: attrs.Subject} + tpRpf := utils.TPRatingProfile{Tenant: attrs.Tenant, Category: attrs.Category, Direction: attrs.Direction, Subject: attrs.Subject} keyId := tpRpf.KeyId() if !attrs.Overwrite { if exists, err := self.RatingDb.HasData(engine.RATING_PROFILE_PREFIX, keyId); err != nil { @@ -249,7 +249,7 @@ func (self *ApierV1) SetRatingProfile(attrs AttrSetRatingProfile, reply *string) return fmt.Errorf(fmt.Sprintf("%s:RatingPlanId:%s", utils.ERR_NOT_FOUND, ra.RatingPlanId)) } rpfl.RatingPlanActivations[idx] = &engine.RatingPlanActivation{ActivationTime: at, RatingPlanId: ra.RatingPlanId, - FallbackKeys: utils.FallbackSubjKeys(tpRpf.Direction, tpRpf.Tenant, tpRpf.TOR, ra.FallbackSubjects)} + FallbackKeys: utils.FallbackSubjKeys(tpRpf.Direction, tpRpf.Tenant, tpRpf.Category, ra.FallbackSubjects)} } if err := self.RatingDb.SetRatingProfile(rpfl); err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) diff --git a/apier/apier_local_test.go b/apier/apier_local_test.go index 83c81b50e..481714ad9 100644 --- a/apier/apier_local_test.go +++ b/apier/apier_local_test.go @@ -450,7 +450,7 @@ func TestApierTPRatingProfile(t *testing.T) { return } reply := "" - rpf := &utils.TPRatingProfile{TPid: engine.TEST_SQL, LoadId: engine.TEST_SQL, Tenant: "cgrates.org", TOR: "call", Direction: "*out", Subject: "*any", + rpf := &utils.TPRatingProfile{TPid: engine.TEST_SQL, LoadId: engine.TEST_SQL, Tenant: "cgrates.org", Category: "call", Direction: "*out", Subject: "*any", RatingPlanActivations: []*utils.TPRatingActivation{ &utils.TPRatingActivation{ActivationTime: "2012-01-01T00:00:00Z", RatingPlanId: "RETAIL1", FallbackSubjects: ""}, }} @@ -743,7 +743,7 @@ func TestApierSetRatingProfile(t *testing.T) { } reply := "" rpa := &utils.TPRatingActivation{ActivationTime: "2012-01-01T00:00:00Z", RatingPlanId: "RETAIL1", FallbackSubjects: "dan2"} - rpf := &AttrSetRatingProfile{Tenant: "cgrates.org", TOR: "call", Direction: "*out", Subject: "dan", RatingPlanActivations: []*utils.TPRatingActivation{rpa}} + rpf := &AttrSetRatingProfile{Tenant: "cgrates.org", Category: "call", Direction: "*out", Subject: "dan", RatingPlanActivations: []*utils.TPRatingActivation{rpa}} if err := rater.Call("ApierV1.SetRatingProfile", rpf, &reply); err != nil { t.Error("Got error on ApierV1.SetRatingProfile: ", err.Error()) } else if reply != "OK" { @@ -759,15 +759,15 @@ func TestApierSetRatingProfile(t *testing.T) { tStart, _ := utils.ParseDate("2013-08-07T17:30:00Z") tEnd, _ := utils.ParseDate("2013-08-07T17:31:30Z") cd := engine.CallDescriptor{ - Direction: "*out", - TOR: "call", - Tenant: "cgrates.org", - Subject: "dan", - Account: "dan", - Destination: "+4917621621391", - CallDuration: 90, - TimeStart: tStart, - TimeEnd: tEnd, + Direction: "*out", + Category: "call", + Tenant: "cgrates.org", + Subject: "dan", + Account: "dan", + Destination: "+4917621621391", + DurationIndex: 90, + TimeStart: tStart, + TimeEnd: tEnd, } var cc engine.CallCost // Simple test that command is executed without errors @@ -784,7 +784,7 @@ func TestApierLoadRatingProfile(t *testing.T) { return } reply := "" - rpf := &utils.TPRatingProfile{TPid: engine.TEST_SQL, LoadId: engine.TEST_SQL, Tenant: "cgrates.org", TOR: "call", Direction: "*out", Subject: "*any"} + rpf := &utils.TPRatingProfile{TPid: engine.TEST_SQL, LoadId: engine.TEST_SQL, Tenant: "cgrates.org", Category: "call", Direction: "*out", Subject: "*any"} if err := rater.Call("ApierV1.LoadRatingProfile", rpf, &reply); err != nil { t.Error("Got error on ApierV1.LoadRatingProfile: ", err.Error()) } else if reply != "OK" { @@ -1300,15 +1300,15 @@ func TestResponderGetCost(t *testing.T) { tStart, _ := utils.ParseDate("2013-08-07T17:30:00Z") tEnd, _ := utils.ParseDate("2013-08-07T17:31:30Z") cd := engine.CallDescriptor{ - Direction: "*out", - TOR: "call", - Tenant: "cgrates.org", - Subject: "1001", - Account: "1001", - Destination: "+4917621621391", - CallDuration: 90, - TimeStart: tStart, - TimeEnd: tEnd, + Direction: "*out", + Category: "call", + Tenant: "cgrates.org", + Subject: "1001", + Account: "1001", + Destination: "+4917621621391", + DurationIndex: 90, + TimeStart: tStart, + TimeEnd: tEnd, } var cc engine.CallCost // Simple test that command is executed without errors @@ -1345,7 +1345,7 @@ func TestMaxDebitInexistentAcnt(t *testing.T) { cd := engine.CallDescriptor{ Direction: "*out", Tenant: "cgrates.org", - TOR: "call", + Category: "call", Subject: "INVALID", Account: "INVALID", Destination: "1002", diff --git a/apier/tpratingprofiles.go b/apier/tpratingprofiles.go index fb91b875e..cf5e74a5f 100644 --- a/apier/tpratingprofiles.go +++ b/apier/tpratingprofiles.go @@ -78,7 +78,7 @@ func (self *ApierV1) GetTPRatingProfileLoadIds(attrs utils.AttrTPRatingProfileId } if ids, err := self.StorDb.GetTPTableIds(attrs.TPid, utils.TBL_TP_RATE_PROFILES, "loadid", map[string]string{ "tenant": attrs.Tenant, - "tor": attrs.TOR, + "tor": attrs.Category, "direction": attrs.Direction, "subject": attrs.Subject, }); err != nil { @@ -96,7 +96,7 @@ func (self *ApierV1) RemTPRatingProfile(attrs utils.TPRatingProfile, reply *stri if missing := utils.MissingStructFields(&attrs, []string{"TPid", "LoadId", "Tenant", "TOR", "Direction", "Subject"}); len(missing) != 0 { //Params missing return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) } - if err := self.StorDb.RemTPData(utils.TBL_TP_RATE_PROFILES, attrs.TPid, attrs.LoadId, attrs.Tenant, attrs.TOR, attrs.Direction, attrs.Subject); err != nil { + if err := self.StorDb.RemTPData(utils.TBL_TP_RATE_PROFILES, attrs.TPid, attrs.LoadId, attrs.Tenant, attrs.Category, attrs.Direction, attrs.Subject); err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } else { *reply = "OK" diff --git a/apier/tutfscsv_local_test.go b/apier/tutfscsv_local_test.go index 1205b38e4..a2721457d 100644 --- a/apier/tutfscsv_local_test.go +++ b/apier/tutfscsv_local_test.go @@ -197,15 +197,15 @@ func TestFsCsvCall1(t *testing.T) { tStart := time.Date(2014, 01, 15, 6, 0, 0, 0, time.UTC) tEnd := time.Date(2014, 01, 15, 6, 0, 35, 0, time.UTC) cd := engine.CallDescriptor{ - Direction: "*out", - TOR: "call", - Tenant: "cgrates.org", - Subject: "1001", - Account: "1001", - Destination: "1002", - TimeStart: tStart, - TimeEnd: tEnd, - CallDuration: 35, + Direction: "*out", + Category: "call", + Tenant: "cgrates.org", + Subject: "1001", + Account: "1001", + Destination: "1002", + TimeStart: tStart, + TimeEnd: tEnd, + DurationIndex: 35, } var cc engine.CallCost // Make sure the cost is what we expect it is @@ -232,16 +232,16 @@ func TestFsCsvCall1(t *testing.T) { t.Errorf("Received unexpected UnitCounters: %v", reply.UnitCounters) } cd = engine.CallDescriptor{ - Direction: "*out", - TOR: "call", - Tenant: "cgrates.org", - Subject: "1001", - Account: "1001", - Destination: "1002", - TimeStart: tStart, - TimeEnd: tEnd, - CallDuration: 35, - LoopIndex: 1, // Should not charge ConnectFee + Direction: "*out", + Category: "call", + Tenant: "cgrates.org", + Subject: "1001", + Account: "1001", + Destination: "1002", + TimeStart: tStart, + TimeEnd: tEnd, + DurationIndex: 35, + LoopIndex: 1, // Should not charge ConnectFee } // Make sure debit charges what cost returned if err := rater.Call("Responder.MaxDebit", cd, &cc); err != nil { diff --git a/apier/tutfsjson_local_test.go b/apier/tutfsjson_local_test.go index d5346ba9b..13c0a6b90 100644 --- a/apier/tutfsjson_local_test.go +++ b/apier/tutfsjson_local_test.go @@ -311,7 +311,7 @@ func TestMaxCallDuration(t *testing.T) { cd := engine.CallDescriptor{ Direction: "*out", Tenant: "cgrates.org", - TOR: "call", + Category: "call", Subject: "1001", Account: "1001", Destination: "1002", @@ -330,7 +330,7 @@ func TestMaxCallDuration(t *testing.T) { cd = engine.CallDescriptor{ Direction: "*out", Tenant: "cgrates.org", - TOR: "call", + Category: "call", Subject: "1002", Account: "1002", Destination: "1001", @@ -348,7 +348,7 @@ func TestMaxCallDuration(t *testing.T) { cd = engine.CallDescriptor{ Direction: "*out", Tenant: "cgrates.org", - TOR: "call", + Category: "call", Subject: "1006", Account: "1006", Destination: "1001", @@ -367,7 +367,7 @@ func TestMaxCallDuration(t *testing.T) { cd = engine.CallDescriptor{ Direction: "*out", Tenant: "cgrates.org", - TOR: "call", + Category: "call", Subject: "1007", Account: "1007", Destination: "1001", @@ -393,7 +393,7 @@ func TestMaxDebit1001(t *testing.T) { cd := engine.CallDescriptor{ Direction: "*out", Tenant: "cgrates.org", - TOR: "call", + Category: "call", Subject: "1001", Account: "1001", Destination: "1002", @@ -432,7 +432,7 @@ func TestMaxDebit1007(t *testing.T) { cd := engine.CallDescriptor{ Direction: "*out", Tenant: "cgrates.org", - TOR: "call", + Category: "call", Subject: "1007", Account: "1007", Destination: "1002", diff --git a/cdrc/cdrc.go b/cdrc/cdrc.go index a12e992c5..671feff27 100644 --- a/cdrc/cdrc.go +++ b/cdrc/cdrc.go @@ -86,7 +86,7 @@ func (self *Cdrc) parseFieldsConfig() error { utils.REQTYPE: self.cgrCfg.CdrcReqTypeField, utils.DIRECTION: self.cgrCfg.CdrcDirectionField, utils.TENANT: self.cgrCfg.CdrcTenantField, - utils.TOR: self.cgrCfg.CdrcTorField, + utils.Category: self.cgrCfg.CdrcTorField, utils.ACCOUNT: self.cgrCfg.CdrcAccountField, utils.SUBJECT: self.cgrCfg.CdrcSubjectField, utils.DESTINATION: self.cgrCfg.CdrcDestinationField, @@ -145,8 +145,8 @@ func (self *Cdrc) recordAsStoredCdr(record []string) (*utils.StoredCdr, error) { ratedCdr.Direction = fieldVal case utils.TENANT: ratedCdr.Tenant = fieldVal - case utils.TOR: - ratedCdr.TOR = fieldVal + case utils.Category: + ratedCdr.Category = fieldVal case utils.ACCOUNT: ratedCdr.Account = fieldVal case utils.SUBJECT: diff --git a/cdrc/cdrc_test.go b/cdrc/cdrc_test.go index 8bf6fb028..eb8f8344c 100644 --- a/cdrc/cdrc_test.go +++ b/cdrc/cdrc_test.go @@ -81,7 +81,7 @@ func TestRecordAsStoredCdr(t *testing.T) { ReqType: cdrRow[1], Direction: cdrRow[2], Tenant: cdrRow[3], - TOR: cdrRow[4], + Category: cdrRow[4], Account: cdrRow[5], Subject: cdrRow[6], Destination: cdrRow[7], diff --git a/cdre/csv_test.go b/cdre/csv_test.go index 309413a4a..0824b792d 100644 --- a/cdre/csv_test.go +++ b/cdre/csv_test.go @@ -34,7 +34,7 @@ func TestCsvCdrWriter(t *testing.T) { csvCdrWriter := NewCsvCdrWriter(writer, 0, 4, "", -1, exportedFields) ratedCdr := &utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), AccId: "dsafdsaf", CdrHost: "192.168.1.1", ReqType: "rated", Direction: "*out", Tenant: "cgrates.org", - TOR: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Unix(1383813745, 0).UTC(), AnswerTime: time.Unix(1383813746, 0).UTC(), + Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Unix(1383813745, 0).UTC(), AnswerTime: time.Unix(1383813746, 0).UTC(), Duration: time.Duration(10) * time.Second, MediationRunId: utils.DEFAULT_RUNID, ExtraFields: map[string]string{"extra1": "val_extra1", "extra2": "val_extra2", "extra3": "val_extra3"}, Cost: 1.01, } diff --git a/cdre/fixedwidth_test.go b/cdre/fixedwidth_test.go index 9cfb01597..8cc7ccad1 100644 --- a/cdre/fixedwidth_test.go +++ b/cdre/fixedwidth_test.go @@ -82,7 +82,7 @@ func TestWriteCdr(t *testing.T) { } fwWriter := FixedWidthCdrWriter{writer: wrBuf, exportTemplate: exportTpl, roundDecimals: 4, header: &bytes.Buffer{}, content: &bytes.Buffer{}, trailer: &bytes.Buffer{}} cdr := &utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), OrderId: 1, AccId: "dsafdsaf", CdrHost: "192.168.1.1", ReqType: "rated", Direction: "*out", Tenant: "cgrates.org", - TOR: "call", Account: "1001", Subject: "1001", Destination: "1002", + Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), Duration: time.Duration(10) * time.Second, MediationRunId: utils.DEFAULT_RUNID, Cost: 2.34567, @@ -143,14 +143,14 @@ func TestWriteCdrs(t *testing.T) { } fwWriter := FixedWidthCdrWriter{writer: wrBuf, exportTemplate: exportTpl, roundDecimals: 4, header: &bytes.Buffer{}, content: &bytes.Buffer{}, trailer: &bytes.Buffer{}} cdr1 := &utils.StoredCdr{CgrId: utils.Sha1("aaa1", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), OrderId: 2, AccId: "aaa1", CdrHost: "192.168.1.1", ReqType: "rated", Direction: "*out", Tenant: "cgrates.org", - TOR: "call", Account: "1001", Subject: "1001", Destination: "1010", + Category: "call", Account: "1001", Subject: "1001", Destination: "1010", SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), Duration: time.Duration(10) * time.Second, MediationRunId: utils.DEFAULT_RUNID, Cost: 2.25, ExtraFields: map[string]string{"productnumber": "12341", "fieldextr2": "valextr2"}, } cdr2 := &utils.StoredCdr{CgrId: utils.Sha1("aaa2", time.Date(2013, 11, 7, 7, 42, 20, 0, time.UTC).String()), OrderId: 4, AccId: "aaa2", CdrHost: "192.168.1.2", ReqType: "prepaid", Direction: "*out", Tenant: "cgrates.org", - TOR: "call", Account: "1002", Subject: "1002", Destination: "1011", + Category: "call", Account: "1002", Subject: "1002", Destination: "1011", SetupTime: time.Date(2013, 11, 7, 7, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 7, 42, 26, 0, time.UTC), Duration: time.Duration(5) * time.Minute, MediationRunId: utils.DEFAULT_RUNID, Cost: 1.40001, @@ -158,7 +158,7 @@ func TestWriteCdrs(t *testing.T) { } cdr3 := &utils.StoredCdr{} cdr4 := &utils.StoredCdr{CgrId: utils.Sha1("aaa3", time.Date(2013, 11, 7, 9, 42, 18, 0, time.UTC).String()), OrderId: 3, AccId: "aaa4", CdrHost: "192.168.1.4", ReqType: "postpaid", Direction: "*out", Tenant: "cgrates.org", - TOR: "call", Account: "1004", Subject: "1004", Destination: "1013", + Category: "call", Account: "1004", Subject: "1004", Destination: "1013", SetupTime: time.Date(2013, 11, 7, 9, 42, 18, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 9, 42, 26, 0, time.UTC), Duration: time.Duration(20) * time.Second, MediationRunId: utils.DEFAULT_RUNID, Cost: 2.34567, diff --git a/cdrs/fscdr.go b/cdrs/fscdr.go index ed95d2a00..029ce8694 100644 --- a/cdrs/fscdr.go +++ b/cdrs/fscdr.go @@ -240,8 +240,8 @@ func (fsCdr FSCdr) AsStoredCdr(runId, reqTypeFld, directionFld, tenantFld, torFl return nil, errors.New(fmt.Sprintf("%s:%s", utils.ERR_MANDATORY_IE_MISSING, tenantFld)) } if strings.HasPrefix(torFld, utils.STATIC_VALUE_PREFIX) { - rtCdr.TOR = torFld[1:] - } else if rtCdr.TOR, hasKey = fsCdr.vars[torFld]; !hasKey && fieldsMandatory { + rtCdr.Category = torFld[1:] + } else if rtCdr.Category, hasKey = fsCdr.vars[torFld]; !hasKey && fieldsMandatory { return nil, errors.New(fmt.Sprintf("%s:%s", utils.ERR_MANDATORY_IE_MISSING, torFld)) } if strings.HasPrefix(accountFld, utils.STATIC_VALUE_PREFIX) { diff --git a/cdrs/fscdr_test.go b/cdrs/fscdr_test.go index 4441f5049..f77a6feb0 100644 --- a/cdrs/fscdr_test.go +++ b/cdrs/fscdr_test.go @@ -114,7 +114,7 @@ func TestFsCdrAsStoredCdr(t *testing.T) { } expctRatedCdr := &utils.StoredCdr{CgrId: utils.Sha1("01df56f4-d99a-4ef6-b7fe-b924b2415b7f", time.Date(2013, 8, 4, 9, 50, 54, 0, time.UTC).Local().String()), AccId: "01df56f4-d99a-4ef6-b7fe-b924b2415b7f", CdrHost: "127.0.0.1", CdrSource: FS_CDR_SOURCE, ReqType: utils.RATED, - Direction: "*out", Tenant: "ipbx.itsyscom.com", TOR: "call", Account: "dan", Subject: "dan", Destination: "+4986517174963", + Direction: "*out", Tenant: "ipbx.itsyscom.com", Category: "call", Account: "dan", Subject: "dan", Destination: "+4986517174963", SetupTime: time.Date(2013, 8, 4, 9, 50, 54, 0, time.UTC).Local(), AnswerTime: time.Date(2013, 8, 4, 9, 50, 56, 0, time.UTC).Local(), Duration: time.Duration(4) * time.Second, ExtraFields: map[string]string{"effective_caller_id_number": "+4986517174960"}, MediationRunId: "wholesale_run", Cost: -1} @@ -128,7 +128,7 @@ func TestFsCdrAsStoredCdr(t *testing.T) { } expctRatedCdr2 := &utils.StoredCdr{CgrId: utils.Sha1("01df56f4-d99a-4ef6-b7fe-b924b2415b7f", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()), AccId: "01df56f4-d99a-4ef6-b7fe-b924b2415b7f", CdrHost: "127.0.0.1", CdrSource: FS_CDR_SOURCE, ReqType: "postpaid", - Direction: "*in", Tenant: "cgrates.com", TOR: "premium_call", Account: "first_account", Subject: "first_subject", Destination: "+4986517174963", + Direction: "*in", Tenant: "cgrates.com", Category: "premium_call", Account: "first_account", Subject: "first_subject", Destination: "+4986517174963", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Duration: time.Duration(12) * time.Second, ExtraFields: map[string]string{"effective_caller_id_number": "+4986517174960"}, MediationRunId: "wholesale_run", Cost: -1} diff --git a/config/config.go b/config/config.go index cc033d119..f424f63f0 100644 --- a/config/config.go +++ b/config/config.go @@ -277,7 +277,7 @@ func (self *CGRConfig) setDefaults() error { &utils.RSRField{Id: utils.REQTYPE}, &utils.RSRField{Id: utils.DIRECTION}, &utils.RSRField{Id: utils.TENANT}, - &utils.RSRField{Id: utils.TOR}, + &utils.RSRField{Id: utils.Category}, &utils.RSRField{Id: utils.ACCOUNT}, &utils.RSRField{Id: utils.SUBJECT}, &utils.RSRField{Id: utils.DESTINATION}, diff --git a/config/config_test.go b/config/config_test.go index c5123c8c3..c2969811c 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -159,7 +159,7 @@ func TestDefaults(t *testing.T) { &utils.RSRField{Id: utils.REQTYPE}, &utils.RSRField{Id: utils.DIRECTION}, &utils.RSRField{Id: utils.TENANT}, - &utils.RSRField{Id: utils.TOR}, + &utils.RSRField{Id: utils.Category}, &utils.RSRField{Id: utils.ACCOUNT}, &utils.RSRField{Id: utils.SUBJECT}, &utils.RSRField{Id: utils.DESTINATION}, diff --git a/engine/account_test.go b/engine/account_test.go index 6b62b9502..205fd0b75 100644 --- a/engine/account_test.go +++ b/engine/account_test.go @@ -97,15 +97,15 @@ func TestGetSecondsForPrefix(t *testing.T) { b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET"} ub1 := &Account{Id: "OUT:CUSTOMER_1:rif", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1, b2}, CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 200}}}} cd := &CallDescriptor{ - TOR: "0", - Tenant: "vdf", - TimeStart: time.Date(2013, 10, 4, 15, 46, 0, 0, time.UTC), - TimeEnd: time.Date(2013, 10, 4, 15, 46, 10, 0, time.UTC), - LoopIndex: 0, - CallDuration: 10 * time.Second, - Direction: OUTBOUND, - Destination: "0723", - Type: MINUTES, + Category: "0", + Tenant: "vdf", + TimeStart: time.Date(2013, 10, 4, 15, 46, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 10, 4, 15, 46, 10, 0, time.UTC), + LoopIndex: 0, + DurationIndex: 10 * time.Second, + Direction: OUTBOUND, + Destination: "0723", + Type: MINUTES, } seconds, credit, bucketList := ub1.getCreditForPrefix(cd) expected := 110 * time.Second @@ -127,7 +127,7 @@ func TestGetSpecialPricedSeconds(t *testing.T) { }, } cd := &CallDescriptor{ - TOR: "0", + Category: "0", Tenant: "vdf", TimeStart: time.Date(2013, 10, 4, 15, 46, 0, 0, time.UTC), TimeEnd: time.Date(2013, 10, 4, 15, 46, 60, 0, time.UTC), @@ -166,10 +166,10 @@ func TestDebitCreditZeroSecond(t *testing.T) { 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), - CallDuration: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + 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{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, Type: MINUTES, @@ -196,10 +196,10 @@ func TestDebitCreditZeroMinute(t *testing.T) { 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), - CallDuration: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + 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{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, Type: MINUTES, @@ -231,11 +231,11 @@ func TestDebitCreditZeroMixedMinute(t *testing.T) { 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, 20, 0, time.UTC), - ratingInfo: &RatingInfo{}, - CallDuration: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 48, 20, 0, time.UTC), + ratingInfo: &RatingInfo{}, + DurationIndex: 0, + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, Type: MINUTES, @@ -266,16 +266,16 @@ func TestDebitCreditNoCredit(t *testing.T) { 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), - CallDuration: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + 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{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, &TimeSpan{ - TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), - TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), - CallDuration: 10 * time.Second, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), + DurationIndex: 10 * time.Second, + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, Type: MINUTES, @@ -307,16 +307,16 @@ func TestDebitCreditHasCredit(t *testing.T) { 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), - CallDuration: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + 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{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, &TimeSpan{ - TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), - TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), - CallDuration: 10 * time.Second, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), + DurationIndex: 10 * time.Second, + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, Type: MINUTES, @@ -350,11 +350,11 @@ func TestDebitCreditSplitMinutesMoney(t *testing.T) { 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, 20, 0, time.UTC), - CallDuration: 0, - ratingInfo: &RatingInfo{}, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 48, 20, 0, time.UTC), + DurationIndex: 0, + ratingInfo: &RatingInfo{}, + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, Type: MINUTES, @@ -388,16 +388,16 @@ func TestDebitCreditMoreTimespans(t *testing.T) { 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), - CallDuration: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + 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{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, &TimeSpan{ - TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), - TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), - CallDuration: 10 * time.Second, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), + DurationIndex: 10 * time.Second, + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, Type: MINUTES, @@ -427,16 +427,16 @@ func TestDebitCreditMoreTimespansMixed(t *testing.T) { 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), - CallDuration: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + 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{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, &TimeSpan{ - TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), - TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), - CallDuration: 10 * time.Second, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), + DurationIndex: 10 * time.Second, + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, Type: MINUTES, @@ -466,16 +466,16 @@ func TestDebitCreditNoConectFeeCredit(t *testing.T) { 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), - CallDuration: 0, - RateInterval: &RateInterval{Rating: &RIRate{ConnectFee: 10.0, Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + 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: 10.0, Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, &TimeSpan{ - TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), - TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), - CallDuration: 10 * time.Second, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), + DurationIndex: 10 * time.Second, + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, Type: MINUTES, @@ -499,17 +499,17 @@ func TestDebitCreditMoneyOnly(t *testing.T) { 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), - CallDuration: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + 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{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, &TimeSpan{ - TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), - TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), - CallDuration: 10 * time.Second, - ratingInfo: &RatingInfo{}, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), + DurationIndex: 10 * time.Second, + ratingInfo: &RatingInfo{}, + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, Type: MINUTES, @@ -542,15 +542,15 @@ func TestDebitCreditSubjectMinutes(t *testing.T) { b1 := &Balance{Uuid: "testb", Value: 250, Weight: 10, DestinationId: "NAT", RatingSubject: "minu"} cc := &CallCost{ Tenant: "vdf", - TOR: "0", + Category: "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, 10, 0, time.UTC), - CallDuration: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 49, 10, 0, time.UTC), + DurationIndex: 0, + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, Type: MINUTES, @@ -585,15 +585,15 @@ func TestDebitCreditSubjectMinutes(t *testing.T) { func TestDebitCreditSubjectMoney(t *testing.T) { cc := &CallCost{ Tenant: "vdf", - TOR: "0", + Category: "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, 10, 0, time.UTC), - CallDuration: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 49, 10, 0, time.UTC), + DurationIndex: 0, + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, Type: MINUTES, @@ -623,15 +623,15 @@ func TestDebitCreditSubjectMixed(t *testing.T) { b1 := &Balance{Uuid: "testb", Value: 40, Weight: 10, DestinationId: "NAT", RatingSubject: "minu"} cc := &CallCost{ Tenant: "vdf", - TOR: "0", + Category: "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, 48, 55, 0, time.UTC), - CallDuration: 55 * time.Second, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 48, 55, 0, time.UTC), + DurationIndex: 55 * time.Second, + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, Type: MINUTES, @@ -667,21 +667,21 @@ func TestDebitCreditSubjectMixedMoreTS(t *testing.T) { b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RatingSubject: "minu"} cc := &CallCost{ Tenant: "vdf", - TOR: "0", + Category: "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, 48, 10, 0, time.UTC), - CallDuration: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + 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{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, &TimeSpan{ - TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), - TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), - CallDuration: 10 * time.Second, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), + DurationIndex: 10 * time.Second, + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, Type: MINUTES, @@ -719,21 +719,21 @@ func TestDebitCreditSubjectMixedPartPay(t *testing.T) { b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RatingSubject: "minu"} cc := &CallCost{ Tenant: "vdf", - TOR: "0", + Category: "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, 48, 10, 0, time.UTC), - CallDuration: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + 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{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, &TimeSpan{ - TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), - TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), - CallDuration: 10 * time.Second, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + TimeStart: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), + DurationIndex: 10 * time.Second, + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, Type: MINUTES, @@ -974,15 +974,15 @@ func TestAccountRefund(t *testing.T) { func TestDebitShared(t *testing.T) { cc := &CallCost{ Tenant: "vdf", - TOR: "0", + Category: "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}}}}, + TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 49, 0, 0, time.UTC), + DurationIndex: 55 * time.Second, + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 2, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, deductConnectFee: true, @@ -1036,11 +1036,11 @@ func TestDebitSMS(t *testing.T) { 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, 1, 0, time.UTC), - ratingInfo: &RatingInfo{}, - CallDuration: 0, - RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 1 * time.Second, RateUnit: time.Second}}}}, + TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 48, 1, 0, time.UTC), + ratingInfo: &RatingInfo{}, + DurationIndex: 0, + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 1 * time.Second, RateUnit: time.Second}}}}, }, }, Type: SMS, @@ -1069,10 +1069,10 @@ func TestDebitDataUnits(t *testing.T) { 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, 20, 0, time.UTC), - ratingInfo: &RatingInfo{}, - CallDuration: 0, + TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), + ratingInfo: &RatingInfo{}, + DurationIndex: 0, RateInterval: &RateInterval{ Rating: &RIRate{ Rates: RateGroups{ @@ -1109,10 +1109,10 @@ func TestDebitDataMoney(t *testing.T) { 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, 20, 0, time.UTC), - ratingInfo: &RatingInfo{}, - CallDuration: 0, + TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 24, 10, 49, 20, 0, time.UTC), + ratingInfo: &RatingInfo{}, + DurationIndex: 0, RateInterval: &RateInterval{ Rating: &RIRate{ Rates: RateGroups{ diff --git a/engine/balances.go b/engine/balances.go index 5428eeb3f..7d6a50c0a 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -218,7 +218,7 @@ func (b *Balance) DebitUnits(cc *CallCost, count bool, ub *Account, moneyBalance cd.Subject = b.RatingSubject cd.TimeStart = ts.GetTimeStartForIncrement(incrementIndex) cd.TimeEnd = cc.Timespans[len(cc.Timespans)-1].TimeEnd - cd.CallDuration = cc.Timespans[len(cc.Timespans)-1].CallDuration + cd.DurationIndex = cc.Timespans[len(cc.Timespans)-1].DurationIndex newCC, err := b.GetCost(cd) if err != nil { Logger.Err(fmt.Sprintf("Error getting new cost for balance subject: %v", err)) @@ -327,7 +327,7 @@ func (b *Balance) DebitMoney(cc *CallCost, count bool, ub *Account) error { cd.Subject = b.RatingSubject cd.TimeStart = ts.GetTimeStartForIncrement(incrementIndex) cd.TimeEnd = cc.Timespans[len(cc.Timespans)-1].TimeEnd - cd.CallDuration = cc.Timespans[len(cc.Timespans)-1].CallDuration + cd.DurationIndex = cc.Timespans[len(cc.Timespans)-1].DurationIndex newCC, err := b.GetCost(cd) if err != nil { Logger.Err(fmt.Sprintf("Error getting new cost for balance subject: %v", err)) diff --git a/engine/callcost.go b/engine/callcost.go index 66d81bd0f..53ed08003 100644 --- a/engine/callcost.go +++ b/engine/callcost.go @@ -25,10 +25,10 @@ import ( // The output structure that will be returned with the call cost information. type CallCost struct { - Direction, TOR, Tenant, Subject, Account, Destination, Type string - Cost float64 - Timespans TimeSpans - deductConnectFee bool + Direction, Category, Tenant, Subject, Account, Destination, Type string + Cost float64 + Timespans TimeSpans + deductConnectFee bool } // Pretty printing for call cost @@ -99,7 +99,7 @@ func (cc *CallCost) GetConnectFee() float64 { func (cc *CallCost) CreateCallDescriptor() *CallDescriptor { return &CallDescriptor{ Direction: cc.Direction, - TOR: cc.TOR, + Category: cc.Category, Tenant: cc.Tenant, Subject: cc.Subject, Account: cc.Account, @@ -122,7 +122,7 @@ func (cc *CallCost) ToDataCost() (*DataCost, error) { } dc := &DataCost{ Direction: cc.Direction, - TOR: cc.TOR, + Category: cc.Category, Tenant: cc.Tenant, Subject: cc.Subject, Account: cc.Account, @@ -134,7 +134,7 @@ func (cc *CallCost) ToDataCost() (*DataCost, error) { dc.DataSpans = make([]*DataSpan, len(cc.Timespans)) for i, ts := range cc.Timespans { length := ts.TimeEnd.Sub(ts.TimeStart).Seconds() - callDuration := ts.CallDuration.Seconds() + callDuration := ts.DurationIndex.Seconds() dc.DataSpans[i] = &DataSpan{ DataStart: callDuration - length, DataEnd: callDuration, diff --git a/engine/callcost_test.go b/engine/callcost_test.go index 89f4334e4..cc3ea4c8b 100644 --- a/engine/callcost_test.go +++ b/engine/callcost_test.go @@ -29,7 +29,7 @@ import ( func TestSingleResultMerge(t *testing.T) { t1 := time.Date(2012, time.February, 2, 17, 0, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 17, 1, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: OUTBOUND, TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: OUTBOUND, Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} cc1, _ := cd.GetCost() if cc1.Cost != 61 { t.Errorf("expected 61 was %v", cc1.Cost) @@ -53,7 +53,7 @@ func TestSingleResultMerge(t *testing.T) { func TestMultipleResultMerge(t *testing.T) { t1 := time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 18, 0, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: OUTBOUND, TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: OUTBOUND, Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} cc1, _ := cd.GetCost() if cc1.Cost != 61 { t.Errorf("expected 61 was %v", cc1.Cost) @@ -63,7 +63,7 @@ func TestMultipleResultMerge(t *testing.T) { } t1 = time.Date(2012, time.February, 2, 18, 00, 0, 0, time.UTC) t2 = time.Date(2012, time.February, 2, 18, 01, 0, 0, time.UTC) - cd = &CallDescriptor{Direction: OUTBOUND, TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} + cd = &CallDescriptor{Direction: OUTBOUND, Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} cc2, _ := cd.GetCost() if cc2.Cost != 30 { t.Errorf("expected 30 was %v", cc2.Cost) @@ -83,7 +83,7 @@ func TestMultipleResultMerge(t *testing.T) { func TestMultipleInputLeftMerge(t *testing.T) { t1 := time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 18, 01, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: OUTBOUND, TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: OUTBOUND, Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} cc1, _ := cd.GetCost() if cc1.Cost != 91 { t.Errorf("expected 91 was %v", cc1.Cost) @@ -107,14 +107,14 @@ func TestMultipleInputLeftMerge(t *testing.T) { func TestMultipleInputRightMerge(t *testing.T) { t1 := time.Date(2012, time.February, 2, 17, 58, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: OUTBOUND, TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: OUTBOUND, Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} cc1, _ := cd.GetCost() if cc1.Cost != 61 { t.Errorf("expected 61 was %v", cc1.Cost) } t1 = time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC) t2 = time.Date(2012, time.February, 2, 18, 01, 0, 0, time.UTC) - cd = &CallDescriptor{Direction: OUTBOUND, TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} + cd = &CallDescriptor{Direction: OUTBOUND, Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} cc2, _ := cd.GetCost() if cc2.Cost != 91 { t.Errorf("expected 91 was %v", cc2.Cost) @@ -131,7 +131,7 @@ func TestMultipleInputRightMerge(t *testing.T) { func TestCallCostMergeEmpty(t *testing.T) { t1 := time.Date(2012, time.February, 2, 17, 58, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: OUTBOUND, TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: OUTBOUND, Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} cc1, _ := cd.GetCost() cc2 := &CallCost{} cc1.Merge(cc2) @@ -168,7 +168,7 @@ func TestCallCostGetDuration(t *testing.T) { func TestCallCostToDataCostError(t *testing.T) { cd := &CallDescriptor{ Direction: "*out", - TOR: "data", + Category: "data", Tenant: "cgrates.org", Subject: "rif", Destination: utils.ANY, @@ -186,7 +186,7 @@ func TestCallCostToDataCostError(t *testing.T) { func TestCallCostToDataCost(t *testing.T) { cd := &CallDescriptor{ Direction: "*out", - TOR: "data", + Category: "data", Tenant: "cgrates.org", Subject: "rif", Destination: utils.ANY, @@ -200,7 +200,7 @@ func TestCallCostToDataCost(t *testing.T) { t.Error("Error convertiong to data cost: ", err) } js, _ := json.Marshal(dc) - expected := `{"Direction":"*out","TOR":"data","Tenant":"cgrates.org","Subject":"rif","Account":"","Destination":"*any","Type":"*data","Cost":65,"DataSpans":[{"DataStart":0,"DataEnd":60,"Cost":60,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":0,"Rates":[{"GroupIntervalStart":0,"Value":1,"RateIncrement":60000000000,"RateUnit":1000000000},{"GroupIntervalStart":60000000000,"Value":1,"RateIncrement":1000000000,"RateUnit":1000000000}],"RoundingMethod":"*up","RoundingDecimals":4},"Weight":10},"DataIndex":60,"Increments":[],"MatchedSubject":"","MatchedPrefix":"","MatchedDestId":""},{"DataStart":60,"DataEnd":65,"Cost":5,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":0,"Rates":[{"GroupIntervalStart":0,"Value":1,"RateIncrement":60000000000,"RateUnit":1000000000},{"GroupIntervalStart":60000000000,"Value":1,"RateIncrement":1000000000,"RateUnit":1000000000}],"RoundingMethod":"*up","RoundingDecimals":4},"Weight":10},"DataIndex":65,"Increments":[],"MatchedSubject":"*out:cgrates.org:data:rif","MatchedPrefix":"*any","MatchedDestId":"*any"}]}` + expected := `{"Direction":"*out","Category":"data","Tenant":"cgrates.org","Subject":"rif","Account":"","Destination":"*any","Type":"*data","Cost":65,"DataSpans":[{"DataStart":0,"DataEnd":60,"Cost":60,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":0,"Rates":[{"GroupIntervalStart":0,"Value":1,"RateIncrement":60000000000,"RateUnit":1000000000},{"GroupIntervalStart":60000000000,"Value":1,"RateIncrement":1000000000,"RateUnit":1000000000}],"RoundingMethod":"*up","RoundingDecimals":4},"Weight":10},"DataIndex":60,"Increments":[],"MatchedSubject":"","MatchedPrefix":"","MatchedDestId":""},{"DataStart":60,"DataEnd":65,"Cost":5,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":0,"Rates":[{"GroupIntervalStart":0,"Value":1,"RateIncrement":60000000000,"RateUnit":1000000000},{"GroupIntervalStart":60000000000,"Value":1,"RateIncrement":1000000000,"RateUnit":1000000000}],"RoundingMethod":"*up","RoundingDecimals":4},"Weight":10},"DataIndex":65,"Increments":[],"MatchedSubject":"*out:cgrates.org:data:rif","MatchedPrefix":"*any","MatchedDestId":"*any"}]}` if string(js) != expected { t.Error("Error coverting to data cost: ", string(js)) } diff --git a/engine/calldesc.go b/engine/calldesc.go index f033fbdde..0ca85df9a 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -107,11 +107,11 @@ The input stucture that contains call information. */ type CallDescriptor struct { Direction string - TOR string + Category string Tenant, Subject, Account, Destination string TimeStart, TimeEnd time.Time LoopIndex float64 // indicates the position of this segment in a cost request loop - CallDuration time.Duration // the call duration so far (till TimeEnd) + DurationIndex time.Duration // the call duration so far (till TimeEnd) //Amount float64 FallbackSubject string // the subject to check for destination if not found on primary subject RatingInfos RatingInfos @@ -124,7 +124,7 @@ func (cd *CallDescriptor) ValidateCallData() error { if cd.TimeStart.After(cd.TimeEnd) || cd.TimeStart.Equal(cd.TimeEnd) { return errors.New("TimeStart must be strctly before TimeEnd") } - if cd.TimeEnd.Sub(cd.TimeStart) < cd.CallDuration { + if cd.TimeEnd.Sub(cd.TimeStart) < cd.DurationIndex { return errors.New("CallDuration must be equal or grater than TimeEnd - TimeStart") } return nil @@ -198,7 +198,7 @@ func (cd *CallDescriptor) getRatingPlansForPrefix(key string, recursionDepth int } if len(ri.FallbackKeys) > 0 { tempCD := &CallDescriptor{ - TOR: cd.TOR, + Category: cd.Category, Direction: cd.Direction, Tenant: cd.Tenant, Destination: cd.Destination, @@ -293,12 +293,12 @@ func (cd *CallDescriptor) GetKey(subject string) string { subject = realSubject cd.Subject = realSubject } - return fmt.Sprintf("%s:%s:%s:%s", cd.Direction, cd.Tenant, cd.TOR, subject) + return fmt.Sprintf("%s:%s:%s:%s", cd.Direction, cd.Tenant, cd.Category, subject) } // Splits the received timespan into sub time spans according to the activation periods intervals. func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) { - firstSpan := &TimeSpan{TimeStart: cd.TimeStart, TimeEnd: cd.TimeEnd, CallDuration: cd.CallDuration} + firstSpan := &TimeSpan{TimeStart: cd.TimeStart, TimeEnd: cd.TimeEnd, DurationIndex: cd.DurationIndex} timespans = append(timespans, firstSpan) if len(cd.RatingInfos) == 0 { @@ -379,7 +379,7 @@ func (cd *CallDescriptor) roundTimeSpansToIncrement(timespans TimeSpans) []*Time if rateIncrement > ts.GetDuration() { initialDuration := ts.GetDuration() ts.TimeEnd = ts.TimeStart.Add(rateIncrement) - ts.CallDuration = ts.CallDuration + (rateIncrement - initialDuration) + ts.DurationIndex = ts.DurationIndex + (rateIncrement - initialDuration) timespans.RemoveOverlapedFromIndex(i) } } @@ -397,8 +397,8 @@ func (cd *CallDescriptor) GetDuration() time.Duration { Creates a CallCost structure with the cost information calculated for the received CallDescriptor. */ func (cd *CallDescriptor) GetCost() (*CallCost, error) { - if cd.CallDuration < cd.TimeEnd.Sub(cd.TimeStart) { - cd.CallDuration = cd.TimeEnd.Sub(cd.TimeStart) + if cd.DurationIndex < cd.TimeEnd.Sub(cd.TimeStart) { + cd.DurationIndex = cd.TimeEnd.Sub(cd.TimeStart) } if cd.Type == "" { cd.Type = MINUTES @@ -424,7 +424,7 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) { //startIndex := len(fmt.Sprintf("%s:%s:%s:", cd.Direction, cd.Tenant, cd.TOR)) cc := &CallCost{ Direction: cd.Direction, - TOR: cd.TOR, + Category: cd.Category, Tenant: cd.Tenant, Account: cd.Account, Destination: cd.Destination, @@ -445,8 +445,8 @@ If the user has no credit then it will return 0. If the user has postpayed plan it returns -1. */ func (origCD *CallDescriptor) getMaxSessionDuration(account *Account) (time.Duration, error) { - if origCD.CallDuration < origCD.TimeEnd.Sub(origCD.TimeStart) { - origCD.CallDuration = origCD.TimeEnd.Sub(origCD.TimeStart) + if origCD.DurationIndex < origCD.TimeEnd.Sub(origCD.TimeStart) { + origCD.DurationIndex = origCD.TimeEnd.Sub(origCD.TimeStart) } if origCD.Type == "" { origCD.Type = MINUTES @@ -636,7 +636,7 @@ func (cd *CallDescriptor) FlushCache() (err error) { func (cd *CallDescriptor) CreateCallCost() *CallCost { return &CallCost{ Direction: cd.Direction, - TOR: cd.TOR, + Category: cd.Category, Tenant: cd.Tenant, Subject: cd.Subject, Account: cd.Account, @@ -647,16 +647,16 @@ func (cd *CallDescriptor) CreateCallCost() *CallCost { func (cd *CallDescriptor) Clone() *CallDescriptor { return &CallDescriptor{ - Direction: cd.Direction, - TOR: cd.TOR, - Tenant: cd.Tenant, - Subject: cd.Subject, - Account: cd.Account, - Destination: cd.Destination, - TimeStart: cd.TimeStart, - TimeEnd: cd.TimeEnd, - LoopIndex: cd.LoopIndex, - CallDuration: cd.CallDuration, + Direction: cd.Direction, + Category: cd.Category, + Tenant: cd.Tenant, + Subject: cd.Subject, + Account: cd.Account, + Destination: cd.Destination, + TimeStart: cd.TimeStart, + TimeEnd: cd.TimeEnd, + LoopIndex: cd.LoopIndex, + DurationIndex: cd.DurationIndex, // Amount: cd.Amount, FallbackSubject: cd.FallbackSubject, //RatingInfos: cd.RatingInfos, diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go index 56c890f43..192e7e4dd 100644 --- a/engine/calldesc_test.go +++ b/engine/calldesc_test.go @@ -98,7 +98,7 @@ func populateDB() { func TestSplitSpans(t *testing.T) { t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} cd.LoadRatingPlans() timespans := cd.splitInTimeSpans() @@ -111,7 +111,7 @@ func TestSplitSpans(t *testing.T) { func TestSplitSpansRoundToIncrements(t *testing.T) { t1 := time.Date(2013, time.October, 7, 14, 50, 0, 0, time.UTC) t2 := time.Date(2013, time.October, 7, 14, 52, 12, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "test", Subject: "trp", Destination: "0256", TimeStart: t1, TimeEnd: t2, CallDuration: 132 * time.Second} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "test", Subject: "trp", Destination: "0256", TimeStart: t1, TimeEnd: t2, DurationIndex: 132 * time.Second} cd.LoadRatingPlans() timespans := cd.splitInTimeSpans() @@ -132,7 +132,7 @@ func TestSplitSpansRoundToIncrements(t *testing.T) { func TestGetCost(t *testing.T) { t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2, LoopIndex: 0} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2, LoopIndex: 0} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2701} if result.Cost != expected.Cost || result.GetConnectFee() != 1 { @@ -143,7 +143,7 @@ func TestGetCost(t *testing.T) { func TestGetCostTimespans(t *testing.T) { t1 := time.Date(2013, time.October, 8, 9, 23, 2, 0, time.UTC) t2 := time.Date(2013, time.October, 8, 9, 24, 27, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "test", Subject: "trp", Destination: "0256", TimeStart: t1, TimeEnd: t2, LoopIndex: 0, CallDuration: 85 * time.Second} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "test", Subject: "trp", Destination: "0256", TimeStart: t1, TimeEnd: t2, LoopIndex: 0, DurationIndex: 85 * time.Second} result, _ := cd.GetCost() expected := &CallCost{Tenant: "test", Subject: "trp", Destination: "0256", Cost: 85} if result.Cost != expected.Cost || result.GetConnectFee() != 0 || len(result.Timespans) != 2 { @@ -155,7 +155,7 @@ func TestGetCostTimespans(t *testing.T) { func TestGetCostRatingPlansAndRatingIntervals(t *testing.T) { t1 := time.Date(2012, time.February, 27, 23, 50, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 28, 18, 10, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "CUSTOMER_1", Subject: "rif:from:tm", Destination: "49178", TimeStart: t1, TimeEnd: t2, LoopIndex: 0, CallDuration: t2.Sub(t1)} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "CUSTOMER_1", Subject: "rif:from:tm", Destination: "49178", TimeStart: t1, TimeEnd: t2, LoopIndex: 0, DurationIndex: t2.Sub(t1)} result, _ := cd.GetCost() if len(result.Timespans) != 3 || !result.Timespans[0].TimeEnd.Equal(result.Timespans[1].TimeStart) || @@ -170,7 +170,7 @@ func TestGetCostRatingPlansAndRatingIntervals(t *testing.T) { func TestGetCostRatingPlansAndRatingIntervalsMore(t *testing.T) { t1 := time.Date(2012, time.February, 27, 9, 50, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 28, 18, 10, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "CUSTOMER_1", Subject: "rif:from:tm", Destination: "49178", TimeStart: t1, TimeEnd: t2, LoopIndex: 0, CallDuration: t2.Sub(t1)} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "CUSTOMER_1", Subject: "rif:from:tm", Destination: "49178", TimeStart: t1, TimeEnd: t2, LoopIndex: 0, DurationIndex: t2.Sub(t1)} result, _ := cd.GetCost() if len(result.Timespans) != 4 || !result.Timespans[0].TimeEnd.Equal(result.Timespans[1].TimeStart) || @@ -186,7 +186,7 @@ func TestGetCostRatingPlansAndRatingIntervalsMore(t *testing.T) { func TestGetCostRateGroups(t *testing.T) { t1 := time.Date(2013, time.October, 7, 14, 50, 0, 0, time.UTC) t2 := time.Date(2013, time.October, 7, 14, 52, 12, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "test", Subject: "trp", Destination: "0256", TimeStart: t1, TimeEnd: t2, CallDuration: 132 * time.Second} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "test", Subject: "trp", Destination: "0256", TimeStart: t1, TimeEnd: t2, DurationIndex: 132 * time.Second} result, err := cd.GetCost() if err != nil { @@ -200,7 +200,7 @@ func TestGetCostRateGroups(t *testing.T) { func TestGetCostNoConnectFee(t *testing.T) { t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2, LoopIndex: 1} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2, LoopIndex: 1} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2700} // connect fee is not added because LoopIndex is 1 @@ -212,7 +212,7 @@ func TestGetCostNoConnectFee(t *testing.T) { func TestGetCostAccount(t *testing.T) { t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Account: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "vdf", Subject: "rif", Account: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2701} if result.Cost != expected.Cost || result.GetConnectFee() != 1 { @@ -223,7 +223,7 @@ func TestGetCostAccount(t *testing.T) { func TestFullDestNotFound(t *testing.T) { t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256308200", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256308200", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2701} if result.Cost != expected.Cost || result.GetConnectFee() != 1 { @@ -235,7 +235,7 @@ func TestFullDestNotFound(t *testing.T) { func TestSubjectNotFound(t *testing.T) { t1 := time.Date(2013, time.February, 1, 17, 30, 0, 0, time.UTC) t2 := time.Date(2013, time.February, 1, 18, 30, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "not_exiting", Destination: "025740532", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "vdf", Subject: "not_exiting", Destination: "025740532", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0257", Cost: 2701} if result.Cost != expected.Cost || result.GetConnectFee() != 1 { @@ -247,7 +247,7 @@ func TestSubjectNotFound(t *testing.T) { func TestMultipleRatingPlans(t *testing.T) { t1 := time.Date(2012, time.February, 8, 17, 30, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 8, 18, 30, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0257308200", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0257308200", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0257", Cost: 2701} if result.Cost != expected.Cost || result.GetConnectFee() != 1 { @@ -259,7 +259,7 @@ func TestMultipleRatingPlans(t *testing.T) { func TestSpansMultipleRatingPlans(t *testing.T) { t1 := time.Date(2012, time.February, 7, 23, 50, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 8, 0, 30, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0257308200", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0257308200", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost() if result.Cost != 1200 || result.GetConnectFee() != 0 { t.Errorf("Expected %v was %v", 1200, result) @@ -269,7 +269,7 @@ func TestSpansMultipleRatingPlans(t *testing.T) { func TestLessThanAMinute(t *testing.T) { t1 := time.Date(2012, time.February, 8, 23, 50, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 8, 23, 50, 30, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0257308200", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0257308200", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0257", Cost: 15} if result.Cost != expected.Cost || result.GetConnectFee() != 0 { @@ -280,7 +280,7 @@ func TestLessThanAMinute(t *testing.T) { func TestUniquePrice(t *testing.T) { t1 := time.Date(2012, time.February, 8, 22, 50, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 8, 23, 50, 21, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0723045326", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0723045326", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0723", Cost: 1810.5} if result.Cost != expected.Cost || result.GetConnectFee() != 0 { @@ -291,7 +291,7 @@ func TestUniquePrice(t *testing.T) { func TestMinutesCost(t *testing.T) { t1 := time.Date(2012, time.February, 8, 22, 50, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 8, 22, 51, 50, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0723", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0723", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost() expected := &CallCost{Tenant: "vdf", Subject: "minutosu", Destination: "0723", Cost: 55} if result.Cost != expected.Cost || result.GetConnectFee() != 0 { @@ -304,7 +304,7 @@ func TestMaxSessionTimeNoAccount(t *testing.T) { 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", + Category: "0", Tenant: "vdf", Subject: "ttttttt", Destination: "0723"} @@ -319,7 +319,7 @@ func TestMaxSessionTimeWithAccount(t *testing.T) { 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", + Category: "0", Tenant: "vdf", Subject: "minu", Destination: "0723", @@ -336,7 +336,7 @@ func TestMaxSessionTimeWithAccountAlias(t *testing.T) { 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", + Category: "0", Tenant: "vdf", Subject: "a1", Account: "a1", @@ -363,7 +363,7 @@ func TestMaxSessionTimeWithAccountShared(t *testing.T) { 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", + Category: "0", Tenant: "vdf", Subject: "rif", Account: "empty0", @@ -374,7 +374,7 @@ func TestMaxSessionTimeWithAccountShared(t *testing.T) { 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", + Category: "0", Tenant: "vdf", Subject: "rif", Account: "empty10", @@ -402,7 +402,7 @@ func TestMaxDebitWithAccountShared(t *testing.T) { TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC), TimeEnd: time.Date(2013, 10, 21, 18, 34, 5, 0, time.UTC), Direction: "*out", - TOR: "0", + Category: "0", Tenant: "vdf", Subject: "minu", Account: "empty0", @@ -429,7 +429,7 @@ func TestMaxSessionTimeWithAccountAccount(t *testing.T) { 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", + Category: "0", Tenant: "vdf", Subject: "minu_from_tm", Account: "minu", @@ -447,7 +447,7 @@ func TestMaxSessionTimeNoCredit(t *testing.T) { 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", + Category: "0", Tenant: "vdf", Subject: "broker", Destination: "0723", @@ -463,16 +463,16 @@ func TestMaxSessionModifiesCallDesc(t *testing.T) { t1 := time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC) t2 := time.Date(2013, 10, 21, 18, 35, 0, 0, time.UTC) cd := &CallDescriptor{ - TimeStart: t1, - TimeEnd: t2, - Direction: "*out", - TOR: "0", - Tenant: "vdf", - Subject: "minu_from_tm", - Account: "minu", - Destination: "0723", - CallDuration: t2.Sub(t1), - Type: MINUTES, + TimeStart: t1, + TimeEnd: t2, + Direction: "*out", + Category: "0", + Tenant: "vdf", + Subject: "minu_from_tm", + Account: "minu", + Destination: "0723", + DurationIndex: t2.Sub(t1), + Type: MINUTES, } initial := cd.Clone() cd.GetMaxSessionDuration() @@ -487,7 +487,7 @@ func TestMaxDebitDurationNoGreatherThanInitialDuration(t *testing.T) { 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", + Category: "0", Tenant: "vdf", Subject: "minu_from_tm", Account: "minu", @@ -505,7 +505,7 @@ func TestDebitAndMaxDebit(t *testing.T) { 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", + Category: "0", Tenant: "vdf", Subject: "minu_from_tm", Account: "minu", @@ -527,7 +527,7 @@ func TestMaxSesionTimeEmptyBalance(t *testing.T) { 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", + Category: "0", Tenant: "vdf", Subject: "minu_from_tm", Account: "luna", @@ -545,7 +545,7 @@ func TestMaxSesionTimeEmptyBalanceAndNoCost(t *testing.T) { 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", + Category: "0", Tenant: "vdf", Subject: "one", Account: "luna", @@ -568,7 +568,7 @@ func TestDebitFromShareAndNormal(t *testing.T) { TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC), TimeEnd: time.Date(2013, 10, 21, 18, 34, 5, 0, time.UTC), Direction: "*out", - TOR: "0", + Category: "0", Tenant: "vdf", Subject: "rif", Account: "empty10", @@ -596,7 +596,7 @@ func TestDebitFromEmptyShare(t *testing.T) { TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC), TimeEnd: time.Date(2013, 10, 21, 18, 34, 5, 0, time.UTC), Direction: "*out", - TOR: "0", + Category: "0", Tenant: "vdf", Subject: "rif", Account: "emptyX", @@ -620,16 +620,16 @@ func TestMaxDebitZeroDefinedRate(t *testing.T) { at.Execute() } cd1 := &CallDescriptor{ - Direction: "*out", - TOR: "call", - Tenant: "cgrates.org", - Subject: "12345", - Account: "12345", - Destination: "447956", - TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), - TimeEnd: time.Date(2014, 3, 4, 6, 1, 0, 0, time.UTC), - LoopIndex: 0, - CallDuration: 0} + Direction: "*out", + Category: "call", + Tenant: "cgrates.org", + Subject: "12345", + Account: "12345", + Destination: "447956", + TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), + TimeEnd: time.Date(2014, 3, 4, 6, 1, 0, 0, time.UTC), + LoopIndex: 0, + DurationIndex: 0} cc, err := cd1.MaxDebit() if err != nil { t.Error("Error maxdebiting: ", err) @@ -648,16 +648,16 @@ func TestMaxDebitZeroDefinedRateOnlyMinutes(t *testing.T) { at.Execute() } cd1 := &CallDescriptor{ - Direction: "*out", - TOR: "call", - Tenant: "cgrates.org", - Subject: "12345", - Account: "12345", - Destination: "447956", - TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), - TimeEnd: time.Date(2014, 3, 4, 6, 0, 40, 0, time.UTC), - LoopIndex: 0, - CallDuration: 0} + Direction: "*out", + Category: "call", + Tenant: "cgrates.org", + Subject: "12345", + Account: "12345", + Destination: "447956", + TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), + TimeEnd: time.Date(2014, 3, 4, 6, 0, 40, 0, time.UTC), + LoopIndex: 0, + DurationIndex: 0} cc, err := cd1.MaxDebit() if err != nil { t.Fatal("Error maxdebiting: ", err) @@ -676,16 +676,16 @@ func TestMaxDebitConsumesMinutes(t *testing.T) { at.Execute() } cd1 := &CallDescriptor{ - Direction: "*out", - TOR: "call", - Tenant: "cgrates.org", - Subject: "12345", - Account: "12345", - Destination: "447956", - TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), - TimeEnd: time.Date(2014, 3, 4, 6, 0, 5, 0, time.UTC), - LoopIndex: 0, - CallDuration: 0} + Direction: "*out", + Category: "call", + Tenant: "cgrates.org", + Subject: "12345", + Account: "12345", + Destination: "447956", + TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), + TimeEnd: time.Date(2014, 3, 4, 6, 0, 5, 0, time.UTC), + LoopIndex: 0, + DurationIndex: 0} cd1.MaxDebit() if cd1.account.BalanceMap[MINUTES+OUTBOUND][0].Value != 20 { t.Error("Error using minutes: ", cd1.account.BalanceMap[MINUTES+OUTBOUND][0].Value) @@ -695,7 +695,7 @@ func TestMaxDebitConsumesMinutes(t *testing.T) { func TestCDGetCostANY(t *testing.T) { cd1 := &CallDescriptor{ Direction: "*out", - TOR: "data", + Category: "data", Tenant: "cgrates.org", Subject: "rif", Destination: utils.ANY, @@ -711,15 +711,15 @@ func TestCDGetCostANY(t *testing.T) { func TestCDSplitInDataSlots(t *testing.T) { cd := &CallDescriptor{ - Direction: "*out", - TOR: "data", - Tenant: "cgrates.org", - Subject: "rif", - Destination: utils.ANY, - TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), - TimeEnd: time.Date(2014, 3, 4, 6, 1, 5, 0, time.UTC), - Type: DATA, - CallDuration: 65 * time.Second, + Direction: "*out", + Category: "data", + Tenant: "cgrates.org", + Subject: "rif", + Destination: utils.ANY, + TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), + TimeEnd: time.Date(2014, 3, 4, 6, 1, 5, 0, time.UTC), + Type: DATA, + DurationIndex: 65 * time.Second, } cd.LoadRatingPlans() timespans := cd.splitInTimeSpans() @@ -732,7 +732,7 @@ func TestCDSplitInDataSlots(t *testing.T) { func TestCDDataGetCost(t *testing.T) { cd := &CallDescriptor{ Direction: "*out", - TOR: "data", + Category: "data", Tenant: "cgrates.org", Subject: "rif", Destination: utils.ANY, @@ -751,7 +751,7 @@ func BenchmarkStorageGetting(b *testing.B) { b.StopTimer() t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} b.StartTimer() for i := 0; i < b.N; i++ { dataStorage.GetRatingProfile(cd.GetKey(cd.Subject), false) @@ -762,7 +762,7 @@ func BenchmarkStorageRestoring(b *testing.B) { b.StopTimer() t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} b.StartTimer() for i := 0; i < b.N; i++ { cd.LoadRatingPlans() @@ -773,7 +773,7 @@ func BenchmarkStorageGetCost(b *testing.B) { b.StopTimer() t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} b.StartTimer() for i := 0; i < b.N; i++ { cd.GetCost() @@ -784,7 +784,7 @@ func BenchmarkSplitting(b *testing.B) { b.StopTimer() t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC) - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} cd.LoadRatingPlans() b.StartTimer() for i := 0; i < b.N; i++ { @@ -803,7 +803,7 @@ func BenchmarkStorageSingleGetSessionTime(b *testing.B) { func BenchmarkStorageMultipleGetSessionTime(b *testing.B) { b.StopTimer() - cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "minutosu", Destination: "0723"} + cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "vdf", Subject: "minutosu", Destination: "0723"} b.StartTimer() for i := 0; i < b.N; i++ { cd.GetMaxSessionDuration() diff --git a/engine/datacost.go b/engine/datacost.go index bb96a1cea..d74ab5d2d 100644 --- a/engine/datacost.go +++ b/engine/datacost.go @@ -19,10 +19,10 @@ package engine // type used for showing sane data cost type DataCost struct { - Direction, TOR, Tenant, Subject, Account, Destination, Type string - Cost float64 - DataSpans []*DataSpan - deductConnectFee bool + Direction, Category, Tenant, Subject, Account, Destination, Type string + Cost float64 + DataSpans []*DataSpan + deductConnectFee bool } type DataSpan struct { DataStart, DataEnd float64 diff --git a/engine/loader_db.go b/engine/loader_db.go index 993454094..070a25e5f 100644 --- a/engine/loader_db.go +++ b/engine/loader_db.go @@ -342,7 +342,7 @@ func (dbr *DbReader) LoadRatingProfiles() error { &RatingPlanActivation{ ActivationTime: at, RatingPlanId: tpRa.RatingPlanId, - FallbackKeys: utils.FallbackSubjKeys(tpRpf.Direction, tpRpf.Tenant, tpRpf.TOR, tpRa.FallbackSubjects), + FallbackKeys: utils.FallbackSubjKeys(tpRpf.Direction, tpRpf.Tenant, tpRpf.Category, tpRa.FallbackSubjects), }) } dbr.ratingProfiles[tpRpf.KeyId()] = rpf @@ -431,7 +431,7 @@ func (dbr *DbReader) LoadRatingProfileFiltered(qriedRpf *utils.TPRatingProfile) } resultRatingProfile.RatingPlanActivations = append(resultRatingProfile.RatingPlanActivations, &RatingPlanActivation{at, tpRa.RatingPlanId, - utils.FallbackSubjKeys(tpRpf.Direction, tpRpf.Tenant, tpRpf.TOR, tpRa.FallbackSubjects)}) + utils.FallbackSubjKeys(tpRpf.Direction, tpRpf.Tenant, tpRpf.Category, tpRa.FallbackSubjects)}) } if err := dbr.dataDb.SetRatingProfile(resultRatingProfile); err != nil { return err diff --git a/engine/ratingplan_test.go b/engine/ratingplan_test.go index 46876af3b..002e4f594 100644 --- a/engine/ratingplan_test.go +++ b/engine/ratingplan_test.go @@ -33,7 +33,7 @@ func TestApRestoreFromStorage(t *testing.T) { 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: OUTBOUND, - TOR: "0", + Category: "0", Tenant: "CUSTOMER_1", Subject: "rif:from:tm", Destination: "49"} @@ -76,7 +76,7 @@ func TestFallbackDirect(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), - TOR: "0", + Category: "0", Direction: OUTBOUND, Tenant: "CUSTOMER_2", Subject: "danb:87.139.12.167", @@ -91,7 +91,7 @@ func TestFallbackMultiple(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), - TOR: "0", + Category: "0", Direction: OUTBOUND, Tenant: "vdf", Subject: "fall", @@ -106,7 +106,7 @@ func TestFallbackWithBackTrace(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), - TOR: "0", + Category: "0", Direction: OUTBOUND, Tenant: "CUSTOMER_2", Subject: "danb:87.139.12.167", @@ -121,7 +121,7 @@ func TestFallbackDefault(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), - TOR: "0", + Category: "0", Direction: OUTBOUND, Tenant: "vdf", Subject: "one", @@ -133,7 +133,7 @@ func TestFallbackDefault(t *testing.T) { } func TestFallbackNoInfiniteLoop(t *testing.T) { - cd := &CallDescriptor{TOR: "0", Direction: OUTBOUND, Tenant: "vdf", Subject: "rif", Destination: "0721"} + cd := &CallDescriptor{Category: "0", Direction: OUTBOUND, Tenant: "vdf", Subject: "rif", Destination: "0721"} cd.LoadRatingPlans() if len(cd.RatingInfos) != 0 { t.Error("Error restoring activation periods: ", len(cd.RatingInfos)) @@ -141,7 +141,7 @@ func TestFallbackNoInfiniteLoop(t *testing.T) { } func TestFallbackNoInfiniteLoopSelf(t *testing.T) { - cd := &CallDescriptor{TOR: "0", Direction: OUTBOUND, Tenant: "vdf", Subject: "inf", Destination: "0721"} + cd := &CallDescriptor{Category: "0", Direction: OUTBOUND, Tenant: "vdf", Subject: "inf", Destination: "0721"} cd.LoadRatingPlans() if len(cd.RatingInfos) != 0 { t.Error("Error restoring activation periods: ", len(cd.RatingInfos)) diff --git a/engine/ratingprofile_test.go b/engine/ratingprofile_test.go index 3a12f63c9..8e64ef99b 100644 --- a/engine/ratingprofile_test.go +++ b/engine/ratingprofile_test.go @@ -28,7 +28,7 @@ func TestGetRatingProfileForPrefix(t *testing.T) { TimeStart: time.Date(2013, 11, 18, 13, 45, 1, 0, time.UTC), TimeEnd: time.Date(2013, 11, 18, 13, 47, 30, 0, time.UTC), Tenant: "vdf", - TOR: "0", + Category: "0", Direction: OUTBOUND, Subject: "fallback1", Destination: "0256098", @@ -47,7 +47,7 @@ func TestGetRatingProfileForPrefixFirstEmpty(t *testing.T) { TimeStart: time.Date(2013, 11, 18, 13, 44, 1, 0, time.UTC), TimeEnd: time.Date(2013, 11, 18, 13, 47, 30, 0, time.UTC), Tenant: "vdf", - TOR: "0", + Category: "0", Direction: OUTBOUND, Subject: "fallback1", Destination: "0256098", diff --git a/engine/storage_sql.go b/engine/storage_sql.go index 9a0190bef..555adda4d 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -269,7 +269,7 @@ func (self *SQLStorage) SetTPRatingProfiles(tpid string, rps map[string]*utils.T if i != 0 { //Consecutive values after the first will be prefixed with "," as separator buffer.WriteRune(',') } - buffer.WriteString(fmt.Sprintf("('%s', '%s', '%s', '%s', '%s', '%s', '%s','%s','%s')", tpid, rp.LoadId, rp.Tenant, rp.TOR, rp.Direction, + buffer.WriteString(fmt.Sprintf("('%s', '%s', '%s', '%s', '%s', '%s', '%s','%s','%s')", tpid, rp.LoadId, rp.Tenant, rp.Category, rp.Direction, rp.Subject, rpa.ActivationTime, rpa.RatingPlanId, rpa.FallbackSubjects)) i++ } @@ -476,7 +476,7 @@ func (self *SQLStorage) LogCallCost(cgrid, source, runid string, cc *CallCost) ( cgrid, cc.Direction, cc.Tenant, - cc.TOR, + cc.Category, cc.Account, cc.Subject, cc.Destination, @@ -500,7 +500,7 @@ func (self *SQLStorage) GetCallCostLog(cgrid, source, runid string) (cc *CallCos var src string var timespansJson string cc = &CallCost{Cost: -1} - err = row.Scan(&cgrid, &cc.Direction, &cc.Tenant, &cc.TOR, &cc.Account, &cc.Subject, + err = row.Scan(&cgrid, &cc.Direction, &cc.Tenant, &cc.Category, &cc.Account, &cc.Subject, &cc.Destination, &cc.Cost, ×pansJson, &src) if len(timespansJson) == 0 { // No costs returned return nil, nil @@ -799,7 +799,7 @@ func (self *SQLStorage) GetStoredCdrs(cgrIds, runIds, cdrHosts, cdrSources, reqT } storCdr := &utils.StoredCdr{ CgrId: cgrid, OrderId: orderid, AccId: accid, CdrHost: cdrhost, CdrSource: cdrsrc, ReqType: reqtype, Direction: direction, Tenant: tenant, - TOR: tor, Account: account, Subject: subject, Destination: destination, SetupTime: setupTime, AnswerTime: answerTime, Duration: time.Duration(duration), + Category: tor, Account: account, Subject: subject, Destination: destination, SetupTime: setupTime, AnswerTime: answerTime, Duration: time.Duration(duration), ExtraFields: extraFieldsMp, MediationRunId: runid.String, Cost: cost.Float64, } cdrs = append(cdrs, storCdr) @@ -1012,8 +1012,8 @@ func (self *SQLStorage) GetTpRatingProfiles(qryRpf *utils.TPRatingProfile) (map[ if len(qryRpf.Tenant) != 0 { q += fmt.Sprintf(" AND tenant='%s'", qryRpf.Tenant) } - if len(qryRpf.TOR) != 0 { - q += fmt.Sprintf(" AND tor='%s'", qryRpf.TOR) + if len(qryRpf.Category) != 0 { + q += fmt.Sprintf(" AND tor='%s'", qryRpf.Category) } if len(qryRpf.Direction) != 0 { q += fmt.Sprintf(" AND direction='%s'", qryRpf.Direction) @@ -1032,7 +1032,7 @@ func (self *SQLStorage) GetTpRatingProfiles(qryRpf *utils.TPRatingProfile) (map[ if err := rows.Scan(&rcvLoadId, &tenant, &tor, &direction, &subject, &activation_time, &rating_plan_tag, &fallback_subjects); err != nil { return nil, err } - rp := &utils.TPRatingProfile{TPid: qryRpf.TPid, LoadId: rcvLoadId, Tenant: tenant, TOR: tor, Direction: direction, Subject: subject} + rp := &utils.TPRatingProfile{TPid: qryRpf.TPid, LoadId: rcvLoadId, Tenant: tenant, Category: tor, Direction: direction, Subject: subject} if existingRp, has := rpfs[rp.KeyId()]; !has { rp.RatingPlanActivations = []*utils.TPRatingActivation{ &utils.TPRatingActivation{ActivationTime: activation_time, RatingPlanId: rating_plan_tag, FallbackSubjects: fallback_subjects}} diff --git a/engine/storage_sql_local_test.go b/engine/storage_sql_local_test.go index eca87edf6..3c5b58207 100644 --- a/engine/storage_sql_local_test.go +++ b/engine/storage_sql_local_test.go @@ -92,7 +92,7 @@ func TestRemoveData(t *testing.T) { } // Create RatingProfile ras := []*utils.TPRatingActivation{&utils.TPRatingActivation{ActivationTime: "2012-01-01T00:00:00Z", RatingPlanId: "RETAIL1"}} - rp := &utils.TPRatingProfile{TPid: TEST_SQL, LoadId: TEST_SQL, Tenant: "cgrates.org", TOR: "call", Direction: "*out", Subject: "*any", RatingPlanActivations: ras} + rp := &utils.TPRatingProfile{TPid: TEST_SQL, LoadId: TEST_SQL, Tenant: "cgrates.org", Category: "call", Direction: "*out", Subject: "*any", RatingPlanActivations: ras} if err := mysql.SetTPRatingProfiles(TEST_SQL, map[string]*utils.TPRatingProfile{rp.KeyId(): rp}); err != nil { t.Error(err.Error()) } @@ -102,7 +102,7 @@ func TestRemoveData(t *testing.T) { t.Error("Could not store TPRatingProfile") } // Remove RatingProfile - if err := mysql.RemTPData(utils.TBL_TP_RATE_PROFILES, rp.TPid, rp.LoadId, rp.Tenant, rp.TOR, rp.Direction, rp.Subject); err != nil { + if err := mysql.RemTPData(utils.TBL_TP_RATE_PROFILES, rp.TPid, rp.LoadId, rp.Tenant, rp.Category, rp.Direction, rp.Subject); err != nil { t.Error(err.Error()) } if rps, err := mysql.GetTpRatingProfiles(rp); err != nil { @@ -158,19 +158,19 @@ func TestSetCdr(t *testing.T) { } } strCdr1 := &utils.StoredCdr{AccId: "bbb1", CdrHost: "192.168.1.1", CdrSource: "UNKNOWN", ReqType: "rated", - Direction: "*out", Tenant: "cgrates.org", TOR: "call", Account: "1001", Subject: "1001", Destination: "1002", + Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Duration: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: utils.DEFAULT_RUNID, Cost: 1.201} strCdr1.CgrId = utils.Sha1(strCdr1.AccId, strCdr1.SetupTime.String()) strCdr2 := &utils.StoredCdr{AccId: "bbb2", CdrHost: "192.168.1.2", CdrSource: "UNKNOWN2", ReqType: "prepaid", - Direction: "*out", Tenant: "cgrates.org", TOR: "call", Account: "1001", Subject: "1001", Destination: "1002", + Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Duration: time.Duration(12) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: utils.DEFAULT_RUNID, Cost: 0.201} strCdr2.CgrId = utils.Sha1(strCdr2.AccId, strCdr2.SetupTime.String()) strCdr3 := &utils.StoredCdr{AccId: "bbb3", CdrHost: "192.168.1.1", CdrSource: TEST_SQL, ReqType: "rated", - Direction: "*out", Tenant: "itsyscom.com", TOR: "call", Account: "1002", Subject: "1000", Destination: "+4986517174963", + Direction: "*out", Tenant: "itsyscom.com", Category: "call", Account: "1002", Subject: "1000", Destination: "+4986517174963", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Duration: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: utils.DEFAULT_RUNID, Cost: 1.201} @@ -188,19 +188,19 @@ func TestSetRatedCdr(t *testing.T) { return } strCdr1 := &utils.StoredCdr{AccId: "bbb1", CdrHost: "192.168.1.1", CdrSource: "UNKNOWN", ReqType: "rated", - Direction: "*out", Tenant: "cgrates.org", TOR: "call", Account: "1001", Subject: "1001", Destination: "1002", + Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Duration: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: utils.DEFAULT_RUNID, Cost: 1.201} strCdr1.CgrId = utils.Sha1(strCdr1.AccId, strCdr1.SetupTime.String()) strCdr2 := &utils.StoredCdr{AccId: "bbb2", CdrHost: "192.168.1.2", CdrSource: "UNKNOWN", ReqType: "prepaid", - Direction: "*out", Tenant: "cgrates.org", TOR: "call", Account: "1001", Subject: "1001", Destination: "1002", + Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Duration: time.Duration(12) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: utils.DEFAULT_RUNID, Cost: 0.201} strCdr2.CgrId = utils.Sha1(strCdr2.AccId, strCdr2.SetupTime.String()) strCdr3 := &utils.StoredCdr{AccId: "bbb3", CdrHost: "192.168.1.1", CdrSource: TEST_SQL, ReqType: "rated", - Direction: "*out", Tenant: "itsyscom.com", TOR: "call", Account: "1002", Subject: "1002", Destination: "+4986517174964", + Direction: "*out", Tenant: "itsyscom.com", Category: "call", Account: "1002", Subject: "1002", Destination: "+4986517174964", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Duration: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: "wholesale_run", Cost: 1.201} diff --git a/engine/timespans.go b/engine/timespans.go index 19f876199..dfb148bda 100644 --- a/engine/timespans.go +++ b/engine/timespans.go @@ -35,7 +35,7 @@ type TimeSpan struct { Cost float64 ratingInfo *RatingInfo RateInterval *RateInterval - CallDuration time.Duration // the call duration so far till TimeEnd + DurationIndex time.Duration // the call duration so far till TimeEnd Increments Increments MatchedSubject, MatchedPrefix, MatchedDestId string } @@ -340,7 +340,7 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) { nts.copyRatingInfo(ts) ts.TimeEnd = splitTime nts.SetRateInterval(i) - nts.CallDuration = ts.CallDuration + nts.DurationIndex = ts.DurationIndex ts.SetNewCallDuration(nts) // Logger.Debug(fmt.Sprintf("Group splitting: %+v %+v", ts, nts)) return @@ -368,7 +368,7 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) { } nts.copyRatingInfo(ts) ts.TimeEnd = splitTime - nts.CallDuration = ts.CallDuration + nts.DurationIndex = ts.DurationIndex ts.SetNewCallDuration(nts) // Logger.Debug(fmt.Sprintf("right: %+v %+v", ts, nts)) return @@ -390,7 +390,7 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) { ts.TimeEnd = splitTime nts.SetRateInterval(i) - nts.CallDuration = ts.CallDuration + nts.DurationIndex = ts.DurationIndex ts.SetNewCallDuration(nts) // Logger.Debug(fmt.Sprintf("left: %+v %+v", ts, nts)) return @@ -410,7 +410,7 @@ func (ts *TimeSpan) SplitByIncrement(index int) *TimeSpan { TimeEnd: ts.TimeEnd, } newTs.copyRatingInfo(ts) - newTs.CallDuration = ts.CallDuration + newTs.DurationIndex = ts.DurationIndex ts.TimeEnd = timeStart newTs.Increments = ts.Increments[index:] ts.Increments = ts.Increments[:index] @@ -430,7 +430,7 @@ func (ts *TimeSpan) SplitByDuration(duration time.Duration) *TimeSpan { TimeEnd: ts.TimeEnd, } newTs.copyRatingInfo(ts) - newTs.CallDuration = ts.CallDuration + newTs.DurationIndex = ts.DurationIndex ts.TimeEnd = timeStart // split the increment for incrIndex, incr := range ts.Increments { @@ -463,7 +463,7 @@ func (ts *TimeSpan) SplitByRatingPlan(rp *RatingInfo) (newTs *TimeSpan) { TimeEnd: ts.TimeEnd, } newTs.copyRatingInfo(ts) - newTs.CallDuration = ts.CallDuration + newTs.DurationIndex = ts.DurationIndex ts.TimeEnd = rp.ActivationTime ts.SetNewCallDuration(newTs) // Logger.Debug(fmt.Sprintf("RP SPLITTING: %+v %+v", ts, newTs)) @@ -472,7 +472,7 @@ func (ts *TimeSpan) SplitByRatingPlan(rp *RatingInfo) (newTs *TimeSpan) { // Returns the starting time of this timespan func (ts *TimeSpan) GetGroupStart() time.Duration { - s := ts.CallDuration - ts.GetDuration() + s := ts.DurationIndex - ts.GetDuration() if s < 0 { s = 0 } @@ -480,16 +480,16 @@ func (ts *TimeSpan) GetGroupStart() time.Duration { } func (ts *TimeSpan) GetGroupEnd() time.Duration { - return ts.CallDuration + return ts.DurationIndex } // sets the CallDuration attribute to reflect new timespan func (ts *TimeSpan) SetNewCallDuration(nts *TimeSpan) { - d := ts.CallDuration - nts.GetDuration() + d := ts.DurationIndex - nts.GetDuration() if d < 0 { d = 0 } - ts.CallDuration = d + ts.DurationIndex = d } func (nts *TimeSpan) copyRatingInfo(ts *TimeSpan) { @@ -514,6 +514,6 @@ func (ts *TimeSpan) RoundToDuration(duration time.Duration) { if duration > ts.GetDuration() { initialDuration := ts.GetDuration() ts.TimeEnd = ts.TimeStart.Add(duration) - ts.CallDuration = ts.CallDuration + (duration - initialDuration) + ts.DurationIndex = ts.DurationIndex + (duration - initialDuration) } } diff --git a/engine/timespans_test.go b/engine/timespans_test.go index 5ac42d5c5..78cb78b5d 100644 --- a/engine/timespans_test.go +++ b/engine/timespans_test.go @@ -265,7 +265,7 @@ func TestTimespanSplitGroupedRates(t *testing.T) { } t1 := time.Date(2012, time.February, 3, 17, 30, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 3, 18, 00, 0, 0, time.UTC) - ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, CallDuration: 1800 * time.Second, ratingInfo: &RatingInfo{}} + ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, DurationIndex: 1800 * time.Second, ratingInfo: &RatingInfo{}} oldDuration := ts.GetDuration() nts := ts.SplitByRateInterval(i) splitTime := time.Date(2012, time.February, 3, 17, 45, 00, 0, time.UTC) @@ -313,7 +313,7 @@ func TestTimespanSplitGroupedRatesIncrements(t *testing.T) { } t1 := time.Date(2012, time.February, 3, 17, 30, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 3, 17, 31, 0, 0, time.UTC) - ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, CallDuration: 60 * time.Second, ratingInfo: &RatingInfo{}} + ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, DurationIndex: 60 * time.Second, ratingInfo: &RatingInfo{}} oldDuration := ts.GetDuration() nts := ts.SplitByRateInterval(i) cd := &CallDescriptor{} @@ -395,7 +395,7 @@ func TestTimespanSplitGroupSecondSplit(t *testing.T) { } t1 := time.Date(2012, time.February, 3, 17, 00, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 3, 17, 04, 0, 0, time.UTC) - ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, CallDuration: 240 * time.Second, ratingInfo: &RatingInfo{}} + ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, DurationIndex: 240 * time.Second, ratingInfo: &RatingInfo{}} oldDuration := ts.GetDuration() nts := ts.SplitByRateInterval(i) splitTime := time.Date(2012, time.February, 3, 17, 01, 00, 0, time.UTC) @@ -440,7 +440,7 @@ func TestTimespanSplitLong(t *testing.T) { } t1 := time.Date(2013, time.October, 9, 9, 0, 0, 0, time.UTC) t2 := time.Date(2013, time.October, 10, 20, 0, 0, 0, time.UTC) - ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, CallDuration: t2.Sub(t1), ratingInfo: &RatingInfo{}} + ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, DurationIndex: t2.Sub(t1), ratingInfo: &RatingInfo{}} oldDuration := ts.GetDuration() nts := ts.SplitByRateInterval(i) splitTime := time.Date(2013, time.October, 9, 18, 0, 0, 0, time.UTC) @@ -472,7 +472,7 @@ func TestTimespanSplitMultipleGroup(t *testing.T) { } t1 := time.Date(2012, time.February, 3, 17, 00, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 3, 17, 04, 0, 0, time.UTC) - ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, CallDuration: 240 * time.Second, ratingInfo: &RatingInfo{}} + ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, DurationIndex: 240 * time.Second, ratingInfo: &RatingInfo{}} oldDuration := ts.GetDuration() nts := ts.SplitByRateInterval(i) splitTime := time.Date(2012, time.February, 3, 17, 01, 00, 0, time.UTC) @@ -736,10 +736,10 @@ func TestTimespanCreateIncrements(t *testing.T) { func TestTimespanSplitByIncrement(t *testing.T) { ts := &TimeSpan{ - TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC), - TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC), - CallDuration: 60 * time.Second, - ratingInfo: &RatingInfo{}, + TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC), + DurationIndex: 60 * time.Second, + ratingInfo: &RatingInfo{}, RateInterval: &RateInterval{ Rating: &RIRate{ RoundingMethod: utils.ROUNDING_MIDDLE, @@ -761,8 +761,8 @@ func TestTimespanSplitByIncrement(t *testing.T) { if ts.GetDuration() != 50*time.Second || newTs.GetDuration() != 10*time.Second { t.Error("Error spliting by increment: ", ts.GetDuration(), newTs.GetDuration()) } - if ts.CallDuration != 50*time.Second || newTs.CallDuration != 60*time.Second { - t.Error("Error spliting by increment at setting call duration: ", ts.CallDuration, newTs.CallDuration) + if ts.DurationIndex != 50*time.Second || newTs.DurationIndex != 60*time.Second { + t.Error("Error spliting by increment at setting call duration: ", ts.DurationIndex, newTs.DurationIndex) } if len(ts.Increments) != 5 || len(newTs.Increments) != 1 { t.Error("Error spliting increments: ", ts.Increments, newTs.Increments) @@ -771,9 +771,9 @@ func TestTimespanSplitByIncrement(t *testing.T) { func TestTimespanSplitByIncrementStart(t *testing.T) { ts := &TimeSpan{ - TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC), - TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC), - CallDuration: 60 * time.Second, + TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC), + DurationIndex: 60 * time.Second, RateInterval: &RateInterval{ Rating: &RIRate{ RoundingMethod: utils.ROUNDING_MIDDLE, @@ -795,8 +795,8 @@ func TestTimespanSplitByIncrementStart(t *testing.T) { if ts.GetDuration() != 60*time.Second || newTs != nil { t.Error("Error spliting by increment: ", ts.GetDuration()) } - if ts.CallDuration != 60*time.Second { - t.Error("Error spliting by incrementat setting call duration: ", ts.CallDuration) + if ts.DurationIndex != 60*time.Second { + t.Error("Error spliting by incrementat setting call duration: ", ts.DurationIndex) } if len(ts.Increments) != 6 { t.Error("Error spliting increments: ", ts.Increments) @@ -805,9 +805,9 @@ func TestTimespanSplitByIncrementStart(t *testing.T) { func TestTimespanSplitByIncrementEnd(t *testing.T) { ts := &TimeSpan{ - TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC), - TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC), - CallDuration: 60 * time.Second, + TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC), + DurationIndex: 60 * time.Second, RateInterval: &RateInterval{ Rating: &RIRate{ RoundingMethod: utils.ROUNDING_MIDDLE, @@ -829,8 +829,8 @@ func TestTimespanSplitByIncrementEnd(t *testing.T) { if ts.GetDuration() != 60*time.Second || newTs != nil { t.Error("Error spliting by increment: ", ts.GetDuration()) } - if ts.CallDuration != 60*time.Second { - t.Error("Error spliting by increment at setting call duration: ", ts.CallDuration) + if ts.DurationIndex != 60*time.Second { + t.Error("Error spliting by increment at setting call duration: ", ts.DurationIndex) } if len(ts.Increments) != 6 { t.Error("Error spliting increments: ", ts.Increments) @@ -839,10 +839,10 @@ func TestTimespanSplitByIncrementEnd(t *testing.T) { func TestTimespanSplitByDuration(t *testing.T) { ts := &TimeSpan{ - TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC), - TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC), - CallDuration: 60 * time.Second, - ratingInfo: &RatingInfo{}, + TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC), + DurationIndex: 60 * time.Second, + ratingInfo: &RatingInfo{}, RateInterval: &RateInterval{ Rating: &RIRate{ RoundingMethod: utils.ROUNDING_MIDDLE, @@ -864,8 +864,8 @@ func TestTimespanSplitByDuration(t *testing.T) { if ts.GetDuration() != 46*time.Second || newTs.GetDuration() != 14*time.Second { t.Error("Error spliting by duration: ", ts.GetDuration(), newTs.GetDuration()) } - if ts.CallDuration != 46*time.Second || newTs.CallDuration != 60*time.Second { - t.Error("Error spliting by duration at setting call duration: ", ts.CallDuration, newTs.CallDuration) + if ts.DurationIndex != 46*time.Second || newTs.DurationIndex != 60*time.Second { + t.Error("Error spliting by duration at setting call duration: ", ts.DurationIndex, newTs.DurationIndex) } if len(ts.Increments) != 5 || len(newTs.Increments) != 2 { t.Error("Error spliting increments: ", ts.Increments, newTs.Increments) diff --git a/engine/tpimporter_csv.go b/engine/tpimporter_csv.go index e5e046ef1..616112a2d 100644 --- a/engine/tpimporter_csv.go +++ b/engine/tpimporter_csv.go @@ -273,7 +273,7 @@ func (self *TPCSVImporter) importRatingProfiles(fn string) error { rp := &utils.TPRatingProfile{ LoadId: loadId, Tenant: tenant, - TOR: tor, + Category: tor, Direction: direction, Subject: subject, RatingPlanActivations: []*utils.TPRatingActivation{ diff --git a/general_tests/ddazmbl1_test.go b/general_tests/ddazmbl1_test.go index 7905bfaf2..a8971ac18 100644 --- a/general_tests/ddazmbl1_test.go +++ b/general_tests/ddazmbl1_test.go @@ -135,7 +135,7 @@ func TestExecuteActions(t *testing.T) { func TestDebit(t *testing.T) { cd := &engine.CallDescriptor{ Direction: "*out", - TOR: "call", + Category: "call", Tenant: "cgrates.org", Subject: "12345", Account: "12345", diff --git a/general_tests/ddazmbl2_test.go b/general_tests/ddazmbl2_test.go index 75b52b8a4..a90af17ea 100644 --- a/general_tests/ddazmbl2_test.go +++ b/general_tests/ddazmbl2_test.go @@ -135,7 +135,7 @@ func TestExecuteActions2(t *testing.T) { func TestDebit2(t *testing.T) { cd := &engine.CallDescriptor{ Direction: "*out", - TOR: "call", + Category: "call", Tenant: "cgrates.org", Subject: "12345", Account: "12345", diff --git a/general_tests/ddazmbl3_test.go b/general_tests/ddazmbl3_test.go index c8958bfa6..a5f595ca4 100644 --- a/general_tests/ddazmbl3_test.go +++ b/general_tests/ddazmbl3_test.go @@ -131,7 +131,7 @@ func TestExecuteActions3(t *testing.T) { func TestDebit3(t *testing.T) { cd := &engine.CallDescriptor{ Direction: "*out", - TOR: "call", + Category: "call", Tenant: "cgrates.org", Subject: "12345", Account: "12345", diff --git a/mediator/mediator.go b/mediator/mediator.go index bda8c9589..cf4860f18 100644 --- a/mediator/mediator.go +++ b/mediator/mediator.go @@ -85,16 +85,16 @@ func (self *Mediator) getCostsFromRater(cdr *utils.StoredCdr) (*engine.CallCost, return cc, nil } cd := engine.CallDescriptor{ - Direction: "*out", //record[m.directionFields[runIdx]] TODO: fix me - Tenant: cdr.Tenant, - TOR: cdr.TOR, - Subject: cdr.Subject, - Account: cdr.Account, - Destination: cdr.Destination, - TimeStart: cdr.AnswerTime, - TimeEnd: cdr.AnswerTime.Add(cdr.Duration), - LoopIndex: 0, - CallDuration: cdr.Duration, + Direction: "*out", //record[m.directionFields[runIdx]] TODO: fix me + Tenant: cdr.Tenant, + Category: cdr.Category, + Subject: cdr.Subject, + Account: cdr.Account, + Destination: cdr.Destination, + TimeStart: cdr.AnswerTime, + TimeEnd: cdr.AnswerTime.Add(cdr.Duration), + LoopIndex: 0, + DurationIndex: cdr.Duration, } if cdr.ReqType == utils.PSEUDOPREPAID { err = self.connector.Debit(cd, cc) diff --git a/sessionmanager/fsevent.go b/sessionmanager/fsevent.go index 30b1ecdeb..3f1b229d5 100644 --- a/sessionmanager/fsevent.go +++ b/sessionmanager/fsevent.go @@ -37,7 +37,7 @@ const ( ACCOUNT = "variable_cgr_account" DESTINATION = "variable_cgr_destination" REQTYPE = "variable_cgr_reqtype" //prepaid or postpaid - TOR = "variable_cgr_tor" + Category = "variable_cgr_tor" UUID = "Unique-ID" // -Unique ID for this call leg CSTMID = "variable_cgr_tenant" CALL_DEST_NR = "Caller-Destination-Number" @@ -118,7 +118,7 @@ func (fsev FSEvent) GetTOR(fieldName string) string { if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value return fieldName[len(utils.STATIC_VALUE_PREFIX):] } - return utils.FirstNonEmpty(fsev[fieldName], fsev[TOR], config.CgrConfig().DefaultTOR) + return utils.FirstNonEmpty(fsev[fieldName], fsev[Category], config.CgrConfig().DefaultTOR) } func (fsev FSEvent) GetCgrId() string { setupTime, _ := fsev.GetSetupTime("") diff --git a/sessionmanager/fssessionmanager.go b/sessionmanager/fssessionmanager.go index 69875abb3..43b8f2391 100644 --- a/sessionmanager/fssessionmanager.go +++ b/sessionmanager/fssessionmanager.go @@ -179,7 +179,7 @@ func (sm *FSSessionManager) OnChannelPark(ev Event) { cd := engine.CallDescriptor{ Direction: ev.GetDirection(directionFld), Tenant: ev.GetTenant(tenantFld), - TOR: ev.GetTOR(torFld), + Category: ev.GetTOR(torFld), Subject: ev.GetSubject(subjFld), Account: ev.GetAccount(actFld), Destination: ev.GetDestination(dstFld), @@ -260,16 +260,16 @@ func (sm *FSSessionManager) OnChannelHangupComplete(ev Event) { return } cd := engine.CallDescriptor{ - Direction: ev.GetDirection(directionFld), - Tenant: ev.GetTenant(tenantFld), - TOR: ev.GetTOR(torFld), - Subject: ev.GetSubject(actFld), - Account: ev.GetAccount(subjFld), - LoopIndex: 0, - CallDuration: endTime.Sub(startTime), - Destination: ev.GetDestination(dstFld), - TimeStart: startTime, - TimeEnd: endTime, + Direction: ev.GetDirection(directionFld), + Tenant: ev.GetTenant(tenantFld), + Category: ev.GetTOR(torFld), + Subject: ev.GetSubject(actFld), + Account: ev.GetAccount(subjFld), + LoopIndex: 0, + DurationIndex: endTime.Sub(startTime), + Destination: ev.GetDestination(dstFld), + TimeStart: startTime, + TimeEnd: endTime, } cc := &engine.CallCost{} err = sm.connector.Debit(cd, cc) @@ -324,7 +324,7 @@ func (sm *FSSessionManager) OnChannelHangupComplete(ev Event) { cd := &engine.CallDescriptor{ Direction: lastCC.Direction, Tenant: lastCC.Tenant, - TOR: lastCC.TOR, + Category: lastCC.Category, Subject: lastCC.Subject, Account: lastCC.Account, Destination: lastCC.Destination, diff --git a/sessionmanager/session.go b/sessionmanager/session.go index 6e4d1cb7d..5bdf56d9c 100644 --- a/sessionmanager/session.go +++ b/sessionmanager/session.go @@ -74,7 +74,7 @@ func NewSession(ev Event, sm SessionManager) *Session { cd := &engine.CallDescriptor{ Direction: ev.GetDirection(directionFld), Tenant: ev.GetTenant(tenantFld), - TOR: ev.GetTOR(torFld), + Category: ev.GetTOR(torFld), Subject: ev.GetSubject(subjFld), Account: ev.GetAccount(actFld), Destination: ev.GetDestination(dstFld), @@ -110,7 +110,7 @@ func (s *Session) debitLoop(runIdx int) { } nextCd.TimeEnd = nextCd.TimeStart.Add(debitPeriod) nextCd.LoopIndex = index - nextCd.CallDuration += debitPeriod // first presumed duration + nextCd.DurationIndex += debitPeriod // first presumed duration cc := &engine.CallCost{} if err := s.sessionManager.MaxDebit(&nextCd, cc); err != nil { engine.Logger.Err(fmt.Sprintf("Could not complete debit opperation: %v", err)) @@ -125,8 +125,8 @@ func (s *Session) debitLoop(runIdx int) { s.sessionRuns[runIdx].callCosts = append(s.sessionRuns[runIdx].callCosts, cc) nextCd.TimeEnd = cc.GetEndTime() // set debited timeEnd // update call duration with real debited duration - nextCd.CallDuration -= debitPeriod - nextCd.CallDuration += nextCd.GetDuration() + nextCd.DurationIndex -= debitPeriod + nextCd.DurationIndex += nextCd.GetDuration() time.Sleep(cc.GetDuration()) index++ } @@ -142,7 +142,7 @@ func (s *Session) Close(ev Event) { if _, err := ev.GetEndTime(); err != nil { engine.Logger.Err("Error parsing answer event stop time.") for idx := range s.sessionRuns { - s.sessionRuns[idx].callDescriptor.TimeEnd = s.sessionRuns[idx].callDescriptor.TimeStart.Add(s.sessionRuns[idx].callDescriptor.CallDuration) + s.sessionRuns[idx].callDescriptor.TimeEnd = s.sessionRuns[idx].callDescriptor.TimeStart.Add(s.sessionRuns[idx].callDescriptor.DurationIndex) } } s.SaveOperations() diff --git a/utils/apitpdata.go b/utils/apitpdata.go index f7571cc3c..0536a329a 100644 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -146,14 +146,14 @@ func NewTPRatingProfileFromKeyId(tpid, loadId, keyId string) (*TPRatingProfile, if len(s) != 4 { return nil, fmt.Errorf("Cannot parse key %s into RatingProfile", keyId) } - return &TPRatingProfile{TPid: tpid, LoadId: loadId, Tenant: s[1], TOR: s[2], Direction: s[0], Subject: s[3]}, nil + return &TPRatingProfile{TPid: tpid, LoadId: loadId, Tenant: s[1], Category: s[2], Direction: s[0], Subject: s[3]}, nil } type TPRatingProfile struct { TPid string // Tariff plan id LoadId string // Gives ability to load specific RatingProfile based on load identifier, hence being able to keep history also in stordb Tenant string // Tenant's Id - TOR string // TypeOfRecord + Category string // TypeOfRecord Direction string // Traffic direction, OUT is the only one supported for now Subject string // Rating subject, usually the same as account RatingPlanActivations []*TPRatingActivation // Activate rate profiles at specific time @@ -161,7 +161,7 @@ type TPRatingProfile struct { // Used as key in nosql db (eg: redis) func (self *TPRatingProfile) KeyId() string { - return fmt.Sprintf("%s:%s:%s:%s", self.Direction, self.Tenant, self.TOR, self.Subject) + return fmt.Sprintf("%s:%s:%s:%s", self.Direction, self.Tenant, self.Category, self.Subject) } type TPRatingActivation struct { @@ -196,7 +196,7 @@ func FallbackSubjKeys(direction, tenant, tor, fallbackSubjects string) []string type AttrTPRatingProfileIds struct { TPid string // Tariff plan id Tenant string // Tenant's Id - TOR string // TypeOfRecord + Category string // TypeOfRecord Direction string // Traffic direction Subject string // Rating subject, usually the same as account } diff --git a/utils/cgrcdr.go b/utils/cgrcdr.go index 15b11b560..d62d7d80e 100644 --- a/utils/cgrcdr.go +++ b/utils/cgrcdr.go @@ -78,7 +78,7 @@ func (cgrCdr CgrCdr) GetDestination() string { } func (cgrCdr CgrCdr) GetTOR() string { - return cgrCdr[TOR] + return cgrCdr[Category] } func (cgrCdr CgrCdr) GetTenant() string { @@ -148,8 +148,8 @@ func (cgrCdr CgrCdr) AsStoredCdr(runId, reqTypeFld, directionFld, tenantFld, tor return nil, errors.New(fmt.Sprintf("%s:%s", ERR_MANDATORY_IE_MISSING, tenantFld)) } if strings.HasPrefix(torFld, STATIC_VALUE_PREFIX) { - rtCdr.TOR = torFld[1:] - } else if rtCdr.TOR, hasKey = cgrCdr[torFld]; !hasKey && fieldsMandatory { + rtCdr.Category = torFld[1:] + } else if rtCdr.Category, hasKey = cgrCdr[torFld]; !hasKey && fieldsMandatory { return nil, errors.New(fmt.Sprintf("%s:%s", ERR_MANDATORY_IE_MISSING, torFld)) } if strings.HasPrefix(accountFld, STATIC_VALUE_PREFIX) { diff --git a/utils/cgrcdr_test.go b/utils/cgrcdr_test.go index f9428052b..f003f84e0 100644 --- a/utils/cgrcdr_test.go +++ b/utils/cgrcdr_test.go @@ -95,7 +95,7 @@ func TestCgrCdrAsStoredCdr(t *testing.T) { } setupTime, _ := ParseTimeDetectLayout("2013-11-07T08:42:24Z") expctRatedCdr := &StoredCdr{CgrId: Sha1("dsafdsaf", setupTime.String()), AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "source_test", ReqType: "rated", - Direction: "*out", Tenant: "cgrates.org", TOR: "call", Account: "1001", Subject: "1001", Destination: "1002", + Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Unix(1383813744, 0).UTC(), AnswerTime: time.Unix(1383813746, 0).UTC(), Duration: 10000000000, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: "wholesale_run", Cost: -1} if !reflect.DeepEqual(rtCdrOut, expctRatedCdr) { @@ -107,7 +107,7 @@ func TestCgrCdrAsStoredCdr(t *testing.T) { t.Error("Unexpected error received", err) } expctRatedCdr2 := &StoredCdr{CgrId: Sha1("dsafdsaf", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()), AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "source_test", ReqType: "postpaid", - Direction: "*in", Tenant: "cgrates.com", TOR: "premium_call", Account: "first_account", Subject: "first_subject", Destination: "1002", + Direction: "*in", Tenant: "cgrates.com", Category: "premium_call", Account: "first_account", Subject: "first_subject", Destination: "1002", SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), Duration: time.Duration(12) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: "wholesale_run", Cost: -1} diff --git a/utils/consts.go b/utils/consts.go index 5ae710082..b9b2881db 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -78,7 +78,7 @@ const ( REQTYPE = "reqtype" DIRECTION = "direction" TENANT = "tenant" - TOR = "tor" + Category = "tor" ACCOUNT = "account" SUBJECT = "subject" DESTINATION = "destination" diff --git a/utils/rawcdr.go b/utils/rawcdr.go index efe077c69..7a3c2992a 100644 --- a/utils/rawcdr.go +++ b/utils/rawcdr.go @@ -22,7 +22,7 @@ import ( "time" ) -var PrimaryCdrFields []string = []string{ACCID, CDRHOST, CDRSOURCE, REQTYPE, DIRECTION, TENANT, TOR, ACCOUNT, SUBJECT, DESTINATION, SETUP_TIME, ANSWER_TIME, DURATION} +var PrimaryCdrFields []string = []string{ACCID, CDRHOST, CDRSOURCE, REQTYPE, DIRECTION, TENANT, Category, ACCOUNT, SUBJECT, DESTINATION, SETUP_TIME, ANSWER_TIME, DURATION} // RawCDR is the type containing all the original CDR fields, needs it as it is for later usage type RawCDR interface { diff --git a/utils/storedcdr.go b/utils/storedcdr.go index b6670dd0a..df008da5b 100644 --- a/utils/storedcdr.go +++ b/utils/storedcdr.go @@ -35,7 +35,7 @@ func NewStoredCdrFromRawCDR(rawcdr RawCDR) (*StoredCdr, error) { rtCdr.ReqType = rawcdr.GetReqType() rtCdr.Direction = rawcdr.GetDirection() rtCdr.Tenant = rawcdr.GetTenant() - rtCdr.TOR = rawcdr.GetTOR() + rtCdr.Category = rawcdr.GetTOR() rtCdr.Account = rawcdr.GetAccount() rtCdr.Subject = rawcdr.GetSubject() rtCdr.Destination = rawcdr.GetDestination() @@ -62,7 +62,7 @@ type StoredCdr struct { ReqType string Direction string Tenant string - TOR string + Category string Account string Subject string Destination string @@ -109,7 +109,7 @@ func (storedCdr *StoredCdr) GetDestination() string { } func (storedCdr *StoredCdr) GetTOR() string { - return storedCdr.TOR + return storedCdr.Category } func (storedCdr *StoredCdr) GetTenant() string { @@ -158,7 +158,7 @@ func (storedCdr *StoredCdr) AsRawCdrHttpForm() url.Values { v.Set(REQTYPE, storedCdr.ReqType) v.Set(DIRECTION, storedCdr.Direction) v.Set(TENANT, storedCdr.Tenant) - v.Set(TOR, storedCdr.TOR) + v.Set(Category, storedCdr.Category) v.Set(ACCOUNT, storedCdr.Account) v.Set(SUBJECT, storedCdr.Subject) v.Set(DESTINATION, storedCdr.Destination) @@ -190,8 +190,8 @@ func (storedCdr *StoredCdr) ExportFieldValue(fldName string) string { return storedCdr.Direction case TENANT: return storedCdr.Tenant - case TOR: - return storedCdr.TOR + case Category: + return storedCdr.Category case ACCOUNT: return storedCdr.Account case SUBJECT: diff --git a/utils/storedcdr_test.go b/utils/storedcdr_test.go index 1368efe01..0b9137a06 100644 --- a/utils/storedcdr_test.go +++ b/utils/storedcdr_test.go @@ -35,7 +35,7 @@ func TestNewStoredCdrFromRawCDR(t *testing.T) { "field_extr1": "val_extr1", "fieldextr2": "valextr2"} setupTime, _ := ParseTimeDetectLayout(cgrCdr["setup_time"]) expctRtCdr := &StoredCdr{CgrId: Sha1(cgrCdr["accid"], setupTime.String()), AccId: cgrCdr["accid"], CdrHost: cgrCdr["cdrhost"], CdrSource: cgrCdr["cdrsource"], ReqType: cgrCdr["reqtype"], - Direction: cgrCdr["direction"], Tenant: cgrCdr["tenant"], TOR: cgrCdr["tor"], Account: cgrCdr["account"], Subject: cgrCdr["subject"], + Direction: cgrCdr["direction"], Tenant: cgrCdr["tenant"], Category: cgrCdr["tor"], Account: cgrCdr["account"], Subject: cgrCdr["subject"], Destination: cgrCdr["destination"], SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), Duration: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: DEFAULT_RUNID, Cost: -1} if rt, err := NewStoredCdrFromRawCDR(cgrCdr); err != nil { @@ -47,7 +47,7 @@ func TestNewStoredCdrFromRawCDR(t *testing.T) { func TestStoredCdrFields(t *testing.T) { ratedCdr := StoredCdr{CgrId: Sha1("dsafdsaf", time.Unix(1383813746, 0).String()), AccId: "dsafdsaf", CdrHost: "192.168.1.1", ReqType: "rated", Direction: "*out", Tenant: "cgrates.org", - TOR: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Unix(1383813746, 0), AnswerTime: time.Unix(1383813746, 0), Duration: 10, + Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Unix(1383813746, 0), AnswerTime: time.Unix(1383813746, 0), Duration: 10, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, } if ratedCdr.GetCgrId() != Sha1("dsafdsaf", time.Unix(1383813746, 0).String()) { @@ -107,7 +107,7 @@ func TestStoredCdrFields(t *testing.T) { func TestAsRawCdrHttpForm(t *testing.T) { ratedCdr := StoredCdr{CgrId: Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: "rated", Direction: "*out", Tenant: "cgrates.org", - TOR: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), + Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), Duration: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, } cdrForm := ratedCdr.AsRawCdrHttpForm() @@ -129,8 +129,8 @@ func TestAsRawCdrHttpForm(t *testing.T) { if cdrForm.Get(TENANT) != ratedCdr.Tenant { t.Errorf("Expected: %s, received: %s", ratedCdr.Tenant, cdrForm.Get(TENANT)) } - if cdrForm.Get(TOR) != ratedCdr.TOR { - t.Errorf("Expected: %s, received: %s", ratedCdr.TOR, cdrForm.Get(TOR)) + if cdrForm.Get(Category) != ratedCdr.Category { + t.Errorf("Expected: %s, received: %s", ratedCdr.Category, cdrForm.Get(Category)) } if cdrForm.Get(ACCOUNT) != ratedCdr.Account { t.Errorf("Expected: %s, received: %s", ratedCdr.Account, cdrForm.Get(ACCOUNT)) @@ -160,7 +160,7 @@ func TestAsRawCdrHttpForm(t *testing.T) { func TestExportFieldValue(t *testing.T) { cdr := StoredCdr{CgrId: Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: "rated", Direction: "*out", Tenant: "cgrates.org", - TOR: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: DEFAULT_RUNID, + Category: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: DEFAULT_RUNID, Duration: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, } if cdr.ExportFieldValue(CGRID) != cdr.CgrId || @@ -171,7 +171,7 @@ func TestExportFieldValue(t *testing.T) { cdr.ExportFieldValue(REQTYPE) != cdr.ReqType || cdr.ExportFieldValue(DIRECTION) != cdr.Direction || cdr.ExportFieldValue(TENANT) != cdr.Tenant || - cdr.ExportFieldValue(TOR) != cdr.TOR || + cdr.ExportFieldValue(Category) != cdr.Category || cdr.ExportFieldValue(ACCOUNT) != cdr.Account || cdr.ExportFieldValue(SUBJECT) != cdr.Subject || cdr.ExportFieldValue(DESTINATION) != cdr.Destination || From a95fef496b2139c4da82e18e2ed74ed7bf2e7f60 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 25 Apr 2014 21:22:53 +0300 Subject: [PATCH 15/17] more CallDuration changes --- engine/calldesc.go | 2 +- engine/realcalls_test.go | 4 ++-- engine/timespans.go | 16 ++++++++-------- engine/timespans_test.go | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/engine/calldesc.go b/engine/calldesc.go index 0ca85df9a..e8b64d1f5 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -125,7 +125,7 @@ func (cd *CallDescriptor) ValidateCallData() error { return errors.New("TimeStart must be strctly before TimeEnd") } if cd.TimeEnd.Sub(cd.TimeStart) < cd.DurationIndex { - return errors.New("CallDuration must be equal or grater than TimeEnd - TimeStart") + return errors.New("DurationIndex must be equal or grater than TimeEnd - TimeStart") } return nil } diff --git a/engine/realcalls_test.go b/engine/realcalls_test.go index cf459464b..fbe353f1d 100644 --- a/engine/realcalls_test.go +++ b/engine/realcalls_test.go @@ -25,7 +25,7 @@ import ( var balance1 string = `{"Id":"*out:192.168.56.66:dan","Type":"*prepaid","BalanceMap":{"*monetary*out":[{"Uuid":"7fe5d6e740b6edd180b96274b8bd4123","Value":10,"ExpirationDate":"0001-01-01T00:00:00Z","Weight":10,"GroupIds":null,"DestinationId":"*any","RateSubject":""}]},"UnitCounters":null,"ActionTriggers":[{"Id":"120ea04d40af91c580adb0da11554c88","BalanceId":"*monetary","Direction":"*out","ThresholdType":"*min_balance","ThresholdValue":2,"DestinationId":"","Weight":10,"ActionsId":"LOG_BALANCE","Executed":false},{"Id":"fa217a904059cfd3806239f5ad229f4a","BalanceId":"*monetary","Direction":"*out","ThresholdType":"*max_balance","ThresholdValue":20,"DestinationId":"","Weight":10,"ActionsId":"LOG_BALANCE","Executed":false},{"Id":"f05174b740ab987c802a0a29aa5a2764","BalanceId":"*monetary","Direction":"*out","ThresholdType":"*max_counter","ThresholdValue":15,"DestinationId":"FS_USERS","Weight":10,"ActionsId":"LOG_BALANCE","Executed":false},{"Id":"4d6ebf454048371280100094246163a7","BalanceId":"*monetary","Direction":"*out","ThresholdType":"*min_balance","ThresholdValue":0.1,"DestinationId":"","Weight":10,"ActionsId":"WARN_HTTP","Executed":false}],"Groups":null,"UserIds":null}` -var callCost1 string = `{"Direction":"*out","TOR":"call","Tenant":"192.168.56.66","Subject":"dan","Account":"dan","Destination":"+4986517174963","Cost":0.6,"ConnectFee":0,"Timespans":[{"TimeStart":"2013-12-03T14:36:48+01:00","TimeEnd":"2013-12-03T14:37:48+01:00","Cost":0.6,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":0,"Rates":[{"GroupIntervalStart":0,"Value":0.6,"RateIncrement":60000000000,"RateUnit":60000000000}],"RoundingMethod":"*up","RoundingDecimals":2},"Weight":10},"CallDuration":60000000000,"Increments":null,"MatchedSubject":"*out:192.168.56.66:call:*any","MatchedPrefix":"+49"}]}` +var callCost1 string = `{"Direction":"*out","TOR":"call","Tenant":"192.168.56.66","Subject":"dan","Account":"dan","Destination":"+4986517174963","Cost":0.6,"ConnectFee":0,"Timespans":[{"TimeStart":"2013-12-03T14:36:48+01:00","TimeEnd":"2013-12-03T14:37:48+01:00","Cost":0.6,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":0,"Rates":[{"GroupIntervalStart":0,"Value":0.6,"RateIncrement":60000000000,"RateUnit":60000000000}],"RoundingMethod":"*up","RoundingDecimals":2},"Weight":10},"DurationIndex":60000000000,"Increments":null,"MatchedSubject":"*out:192.168.56.66:call:*any","MatchedPrefix":"+49"}]}` func TestDebitBalanceForCall1(t *testing.T) { b1 := new(Account) @@ -47,7 +47,7 @@ func TestDebitBalanceForCall1(t *testing.T) { var balanceInsufficient = `{"Id":"*out:192.168.56.66:dan","Type":"*prepaid","BalanceMap":{"*monetary*out":[{"Uuid":"de49cb1a40b2740a8087a1d28112e11c","Value":1,"ExpirationDate":"0001-01-01T00:00:00Z","Weight":10,"GroupIds":null,"DestinationId":"*any","RateSubject":""}]},"UnitCounters":[{"Direction":"*out","BalanceId":"*monetary","Balances":[{"Uuid":"","Value":4,"ExpirationDate":"0001-01-01T00:00:00Z","Weight":0,"GroupIds":null,"DestinationId":"","RateSubject":""}]}],"ActionTriggers":[{"Id":"a33f036e402c2b47801f1380c5c82564","BalanceId":"*monetary","Direction":"*out","ThresholdType":"*min_balance","ThresholdValue":2,"DestinationId":"","Weight":10,"ActionsId":"LOG_BALANCE","Executed":true},{"Id":"91776f2d40496c03806cdbc73ae6b5f9","BalanceId":"*monetary","Direction":"*out","ThresholdType":"*max_balance","ThresholdValue":20,"DestinationId":"","Weight":10,"ActionsId":"LOG_BALANCE","Executed":false},{"Id":"e85e933a4045f77c80ef647295ae209b","BalanceId":"*monetary","Direction":"*out","ThresholdType":"*max_counter","ThresholdValue":15,"DestinationId":"FS_USERS","Weight":10,"ActionsId":"LOG_BALANCE","Executed":false},{"Id":"89c178b440a640b6802334b17b63cd4e","BalanceId":"*monetary","Direction":"*out","ThresholdType":"*min_balance","ThresholdValue":2.1,"DestinationId":"","Weight":10,"ActionsId":"WARN_HTTP","Executed":true}],"Groups":null,"UserIds":null}` -var costInsufficient = `{"Direction":"*out","TOR":"call","Tenant":"192.168.56.66","Subject":"dan","Account":"dan","Destination":"+4986517174963","Cost":1,"ConnectFee":3,"Timespans":[{"TimeStart":"2013-12-05T09:52:17+01:00","TimeEnd":"2013-12-05T09:53:17+01:00","Cost":1,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":3,"Rates":[{"GroupIntervalStart":0,"Value":1,"RateIncrement":60000000000,"RateUnit":60000000000}],"RoundingMethod":"*up","RoundingDecimals":2},"Weight":10},"CallDuration":60000000000,"Increments":null,"MatchedSubject":"*out:192.168.56.66:call:*any","MatchedPrefix":"+49"}]}` +var costInsufficient = `{"Direction":"*out","TOR":"call","Tenant":"192.168.56.66","Subject":"dan","Account":"dan","Destination":"+4986517174963","Cost":1,"ConnectFee":3,"Timespans":[{"TimeStart":"2013-12-05T09:52:17+01:00","TimeEnd":"2013-12-05T09:53:17+01:00","Cost":1,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":3,"Rates":[{"GroupIntervalStart":0,"Value":1,"RateIncrement":60000000000,"RateUnit":60000000000}],"RoundingMethod":"*up","RoundingDecimals":2},"Weight":10},"DurationIndex":60000000000,"Increments":null,"MatchedSubject":"*out:192.168.56.66:call:*any","MatchedPrefix":"+49"}]}` func TestDebitInsufficientBalance(t *testing.T) { b1 := new(Account) diff --git a/engine/timespans.go b/engine/timespans.go index dfb148bda..6d2c48809 100644 --- a/engine/timespans.go +++ b/engine/timespans.go @@ -341,7 +341,7 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) { ts.TimeEnd = splitTime nts.SetRateInterval(i) nts.DurationIndex = ts.DurationIndex - ts.SetNewCallDuration(nts) + ts.SetNewDurationIndex(nts) // Logger.Debug(fmt.Sprintf("Group splitting: %+v %+v", ts, nts)) return } @@ -369,7 +369,7 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) { nts.copyRatingInfo(ts) ts.TimeEnd = splitTime nts.DurationIndex = ts.DurationIndex - ts.SetNewCallDuration(nts) + ts.SetNewDurationIndex(nts) // Logger.Debug(fmt.Sprintf("right: %+v %+v", ts, nts)) return } @@ -391,7 +391,7 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) { nts.SetRateInterval(i) nts.DurationIndex = ts.DurationIndex - ts.SetNewCallDuration(nts) + ts.SetNewDurationIndex(nts) // Logger.Debug(fmt.Sprintf("left: %+v %+v", ts, nts)) return } @@ -414,7 +414,7 @@ func (ts *TimeSpan) SplitByIncrement(index int) *TimeSpan { ts.TimeEnd = timeStart newTs.Increments = ts.Increments[index:] ts.Increments = ts.Increments[:index] - ts.SetNewCallDuration(newTs) + ts.SetNewDurationIndex(newTs) return newTs } @@ -449,7 +449,7 @@ func (ts *TimeSpan) SplitByDuration(duration time.Duration) *TimeSpan { break } } - ts.SetNewCallDuration(newTs) + ts.SetNewDurationIndex(newTs) return newTs } @@ -465,7 +465,7 @@ func (ts *TimeSpan) SplitByRatingPlan(rp *RatingInfo) (newTs *TimeSpan) { newTs.copyRatingInfo(ts) newTs.DurationIndex = ts.DurationIndex ts.TimeEnd = rp.ActivationTime - ts.SetNewCallDuration(newTs) + ts.SetNewDurationIndex(newTs) // Logger.Debug(fmt.Sprintf("RP SPLITTING: %+v %+v", ts, newTs)) return } @@ -483,8 +483,8 @@ func (ts *TimeSpan) GetGroupEnd() time.Duration { return ts.DurationIndex } -// sets the CallDuration attribute to reflect new timespan -func (ts *TimeSpan) SetNewCallDuration(nts *TimeSpan) { +// sets the DurationIndex attribute to reflect new timespan +func (ts *TimeSpan) SetNewDurationIndex(nts *TimeSpan) { d := ts.DurationIndex - nts.GetDuration() if d < 0 { d = 0 diff --git a/engine/timespans_test.go b/engine/timespans_test.go index 78cb78b5d..8dfd85d94 100644 --- a/engine/timespans_test.go +++ b/engine/timespans_test.go @@ -533,7 +533,7 @@ func TestTimespanExpandingPastEnd(t *testing.T) { } } -func TestTimespanExpandingCallDuration(t *testing.T) { +func TestTimespanExpandingDurationIndex(t *testing.T) { timespans := []*TimeSpan{ &TimeSpan{ TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC), From 12f91b009badc5d157caad6e36a8fca278c85d26 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 25 Apr 2014 21:45:05 +0300 Subject: [PATCH 16/17] changed TOR in mediator --- mediator/mediator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediator/mediator.go b/mediator/mediator.go index 6726d0096..5fd5d7ce6 100644 --- a/mediator/mediator.go +++ b/mediator/mediator.go @@ -115,7 +115,7 @@ func (self *Mediator) RateCdr(dbcdr utils.RawCDR) error { return err } cdrs := []*utils.StoredCdr{rtCdr} // Start with initial dbcdr, will add here all to be mediated - attrsDC := utils.AttrDerivedChargers{Tenant: rtCdr.Tenant, Tor: rtCdr.TOR, Direction: rtCdr.Direction, + attrsDC := utils.AttrDerivedChargers{Tenant: rtCdr.Tenant, Tor: rtCdr.Category, Direction: rtCdr.Direction, Account: rtCdr.Account, Subject: rtCdr.Subject} var dcs utils.DerivedChargers if err := self.connector.GetDerivedChargers(attrsDC, &dcs); err != nil { From 402a1fbc68dd092aa3f2182b82190b8aaf882f1d Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 25 Apr 2014 21:50:34 +0300 Subject: [PATCH 17/17] Call descriptot Type is now Tor --- engine/account.go | 6 +++--- engine/account_test.go | 40 ++++++++++++++++++++-------------------- engine/balances.go | 8 ++++---- engine/callcost.go | 12 ++++++------ engine/callcost_test.go | 6 +++--- engine/calldesc.go | 26 +++++++++++++------------- engine/calldesc_test.go | 10 +++++----- engine/datacost.go | 8 ++++---- engine/timespans.go | 2 +- 9 files changed, 59 insertions(+), 59 deletions(-) diff --git a/engine/account.go b/engine/account.go index 6833f249d..feb500efb 100644 --- a/engine/account.go +++ b/engine/account.go @@ -62,7 +62,7 @@ type Account struct { func (ub *Account) getCreditForPrefix(cd *CallDescriptor) (duration time.Duration, credit float64, balances BalanceChain) { creditBalances := ub.getBalancesForPrefix(cd.Destination, ub.BalanceMap[CREDIT+cd.Direction], "") - unitBalances := ub.getBalancesForPrefix(cd.Destination, ub.BalanceMap[cd.Type+cd.Direction], "") + unitBalances := ub.getBalancesForPrefix(cd.Destination, ub.BalanceMap[cd.Tor+cd.Direction], "") // gather all balances from shared groups var extendedCreditBalances BalanceChain for _, cb := range creditBalances { @@ -80,7 +80,7 @@ func (ub *Account) getCreditForPrefix(cd *CallDescriptor) (duration time.Duratio for _, mb := range unitBalances { if mb.SharedGroup != "" { if sharedGroup, _ := accountingStorage.GetSharedGroup(mb.SharedGroup, false); sharedGroup != nil { - sgb := sharedGroup.GetBalances(cd.Destination, cd.Type+cd.Direction, ub) + sgb := sharedGroup.GetBalances(cd.Destination, cd.Tor+cd.Direction, ub) sgb = sharedGroup.SortBalancesByStrategy(mb, sgb) extendedMinuteBalances = append(extendedMinuteBalances, sgb...) } @@ -203,7 +203,7 @@ func (account *Account) getAlldBalancesForPrefix(destination, balanceType string } func (ub *Account) debitCreditBalance(cc *CallCost, count bool) (err error) { - usefulUnitBalances := ub.getAlldBalancesForPrefix(cc.Destination, cc.Type+cc.Direction) + usefulUnitBalances := ub.getAlldBalancesForPrefix(cc.Destination, cc.Tor+cc.Direction) usefulMoneyBalances := ub.getAlldBalancesForPrefix(cc.Destination, CREDIT+cc.Direction) // debit minutes for _, balance := range usefulUnitBalances { diff --git a/engine/account_test.go b/engine/account_test.go index 205fd0b75..6ac5d42cd 100644 --- a/engine/account_test.go +++ b/engine/account_test.go @@ -105,7 +105,7 @@ func TestGetSecondsForPrefix(t *testing.T) { DurationIndex: 10 * time.Second, Direction: OUTBOUND, Destination: "0723", - Type: MINUTES, + Tor: MINUTES, } seconds, credit, bucketList := ub1.getCreditForPrefix(cd) expected := 110 * time.Second @@ -134,7 +134,7 @@ func TestGetSpecialPricedSeconds(t *testing.T) { LoopIndex: 0, Direction: OUTBOUND, Destination: "0723", - Type: MINUTES, + Tor: MINUTES, } seconds, credit, bucketList := ub1.getCreditForPrefix(cd) expected := 20 * time.Second @@ -172,7 +172,7 @@ func TestDebitCreditZeroSecond(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, - Type: MINUTES, + Tor: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1}, CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}}}} err := rifsBalance.debitCreditBalance(cc, false) @@ -202,7 +202,7 @@ func TestDebitCreditZeroMinute(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, - Type: MINUTES, + Tor: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ MINUTES + OUTBOUND: BalanceChain{b1}, @@ -238,7 +238,7 @@ func TestDebitCreditZeroMixedMinute(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, - Type: MINUTES, + Tor: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ MINUTES + OUTBOUND: BalanceChain{b1, b2}, @@ -278,7 +278,7 @@ func TestDebitCreditNoCredit(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, - Type: MINUTES, + Tor: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ MINUTES + OUTBOUND: BalanceChain{b1}, @@ -319,7 +319,7 @@ func TestDebitCreditHasCredit(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, - Type: MINUTES, + Tor: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ MINUTES + OUTBOUND: BalanceChain{b1}, @@ -357,7 +357,7 @@ func TestDebitCreditSplitMinutesMoney(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, - Type: MINUTES, + Tor: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ MINUTES + OUTBOUND: BalanceChain{b1}, @@ -400,7 +400,7 @@ func TestDebitCreditMoreTimespans(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, - Type: MINUTES, + Tor: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ MINUTES + OUTBOUND: BalanceChain{b1}, @@ -439,7 +439,7 @@ func TestDebitCreditMoreTimespansMixed(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, - Type: MINUTES, + Tor: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ MINUTES + OUTBOUND: BalanceChain{b1, b2}, @@ -478,7 +478,7 @@ func TestDebitCreditNoConectFeeCredit(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, - Type: MINUTES, + Tor: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ MINUTES + OUTBOUND: BalanceChain{b1}, @@ -512,7 +512,7 @@ func TestDebitCreditMoneyOnly(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, - Type: MINUTES, + Tor: MINUTES, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "money", Value: 50}}, @@ -553,7 +553,7 @@ func TestDebitCreditSubjectMinutes(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, - Type: MINUTES, + Tor: MINUTES, deductConnectFee: true, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ @@ -596,7 +596,7 @@ func TestDebitCreditSubjectMoney(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, - Type: MINUTES, + Tor: MINUTES, deductConnectFee: true, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ @@ -634,7 +634,7 @@ func TestDebitCreditSubjectMixed(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, - Type: MINUTES, + Tor: MINUTES, deductConnectFee: true, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ @@ -684,7 +684,7 @@ func TestDebitCreditSubjectMixedMoreTS(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, - Type: MINUTES, + Tor: MINUTES, deductConnectFee: true, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ @@ -736,7 +736,7 @@ func TestDebitCreditSubjectMixedPartPay(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 1, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, - Type: MINUTES, + Tor: MINUTES, deductConnectFee: true, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ @@ -1043,7 +1043,7 @@ func TestDebitSMS(t *testing.T) { RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 1 * time.Second, RateUnit: time.Second}}}}, }, }, - Type: SMS, + Tor: SMS, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ SMS + OUTBOUND: BalanceChain{&Balance{Uuid: "testm", Value: 100, Weight: 5, DestinationId: "NAT"}}, @@ -1083,7 +1083,7 @@ func TestDebitDataUnits(t *testing.T) { }, }, }, - Type: DATA, + Tor: DATA, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ DATA + OUTBOUND: BalanceChain{&Balance{Uuid: "testm", Value: 100, Weight: 5, DestinationId: "NAT"}}, @@ -1122,7 +1122,7 @@ func TestDebitDataMoney(t *testing.T) { }, }, }, - Type: DATA, + Tor: DATA, } rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{ DATA + OUTBOUND: BalanceChain{&Balance{Uuid: "testm", Value: 0, Weight: 5, DestinationId: "NAT"}}, diff --git a/engine/balances.go b/engine/balances.go index 7d6a50c0a..b2b53c71b 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -204,11 +204,11 @@ func (b *Balance) DebitUnits(cc *CallCost, count bool, ub *Account, moneyBalance b.SubstractAmount(amount) inc.BalanceInfo.UnitBalanceUuid = b.Uuid inc.BalanceInfo.AccountId = ub.Id - inc.UnitInfo = &UnitInfo{cc.Destination, amount, cc.Type} + inc.UnitInfo = &UnitInfo{cc.Destination, amount, cc.Tor} inc.Cost = 0 inc.paid = true if count { - ub.countUnits(&Action{BalanceType: cc.Type, Direction: cc.Direction, Balance: &Balance{Value: amount, DestinationId: cc.Destination}}) + ub.countUnits(&Action{BalanceType: cc.Tor, Direction: cc.Direction, Balance: &Balance{Value: amount, DestinationId: cc.Destination}}) } } continue @@ -244,7 +244,7 @@ func (b *Balance) DebitUnits(cc *CallCost, count bool, ub *Account, moneyBalance b.SubstractAmount(seconds) nInc.BalanceInfo.UnitBalanceUuid = b.Uuid nInc.BalanceInfo.AccountId = ub.Id - nInc.UnitInfo = &UnitInfo{newCC.Destination, seconds, cc.Type} + nInc.UnitInfo = &UnitInfo{newCC.Destination, seconds, cc.Tor} if cost != 0 { nInc.BalanceInfo.MoneyBalanceUuid = moneyBal.Uuid moneyBal.Value -= cost @@ -252,7 +252,7 @@ func (b *Balance) DebitUnits(cc *CallCost, count bool, ub *Account, moneyBalance } nInc.paid = true if count { - ub.countUnits(&Action{BalanceType: newCC.Type, Direction: newCC.Direction, Balance: &Balance{Value: seconds, DestinationId: newCC.Destination}}) + ub.countUnits(&Action{BalanceType: newCC.Tor, Direction: newCC.Direction, Balance: &Balance{Value: seconds, DestinationId: newCC.Destination}}) if cost != 0 { ub.countUnits(&Action{BalanceType: CREDIT, Direction: newCC.Direction, Balance: &Balance{Value: cost, DestinationId: newCC.Destination}}) } diff --git a/engine/callcost.go b/engine/callcost.go index 53ed08003..ac8843b64 100644 --- a/engine/callcost.go +++ b/engine/callcost.go @@ -25,10 +25,10 @@ import ( // The output structure that will be returned with the call cost information. type CallCost struct { - Direction, Category, Tenant, Subject, Account, Destination, Type string - Cost float64 - Timespans TimeSpans - deductConnectFee bool + Direction, Category, Tenant, Subject, Account, Destination, Tor string + Cost float64 + Timespans TimeSpans + deductConnectFee bool } // Pretty printing for call cost @@ -117,7 +117,7 @@ func (cc *CallCost) IsPaid() bool { } func (cc *CallCost) ToDataCost() (*DataCost, error) { - if cc.Type == MINUTES { + if cc.Tor == MINUTES { return nil, errors.New("Not a data call!") } dc := &DataCost{ @@ -127,7 +127,7 @@ func (cc *CallCost) ToDataCost() (*DataCost, error) { Subject: cc.Subject, Account: cc.Account, Destination: cc.Destination, - Type: cc.Type, + Tor: cc.Tor, Cost: cc.Cost, deductConnectFee: cc.deductConnectFee, } diff --git a/engine/callcost_test.go b/engine/callcost_test.go index cc3ea4c8b..2cda0c4f6 100644 --- a/engine/callcost_test.go +++ b/engine/callcost_test.go @@ -174,7 +174,7 @@ func TestCallCostToDataCostError(t *testing.T) { Destination: utils.ANY, TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), TimeEnd: time.Date(2014, 3, 4, 6, 1, 5, 0, time.UTC), - Type: MINUTES, + Tor: MINUTES, } cc, _ := cd.GetCost() _, err := cc.ToDataCost() @@ -192,7 +192,7 @@ func TestCallCostToDataCost(t *testing.T) { Destination: utils.ANY, TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), TimeEnd: time.Date(2014, 3, 4, 6, 1, 5, 0, time.UTC), - Type: DATA, + Tor: DATA, } cc, _ := cd.GetCost() dc, err := cc.ToDataCost() @@ -200,7 +200,7 @@ func TestCallCostToDataCost(t *testing.T) { t.Error("Error convertiong to data cost: ", err) } js, _ := json.Marshal(dc) - expected := `{"Direction":"*out","Category":"data","Tenant":"cgrates.org","Subject":"rif","Account":"","Destination":"*any","Type":"*data","Cost":65,"DataSpans":[{"DataStart":0,"DataEnd":60,"Cost":60,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":0,"Rates":[{"GroupIntervalStart":0,"Value":1,"RateIncrement":60000000000,"RateUnit":1000000000},{"GroupIntervalStart":60000000000,"Value":1,"RateIncrement":1000000000,"RateUnit":1000000000}],"RoundingMethod":"*up","RoundingDecimals":4},"Weight":10},"DataIndex":60,"Increments":[],"MatchedSubject":"","MatchedPrefix":"","MatchedDestId":""},{"DataStart":60,"DataEnd":65,"Cost":5,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":0,"Rates":[{"GroupIntervalStart":0,"Value":1,"RateIncrement":60000000000,"RateUnit":1000000000},{"GroupIntervalStart":60000000000,"Value":1,"RateIncrement":1000000000,"RateUnit":1000000000}],"RoundingMethod":"*up","RoundingDecimals":4},"Weight":10},"DataIndex":65,"Increments":[],"MatchedSubject":"*out:cgrates.org:data:rif","MatchedPrefix":"*any","MatchedDestId":"*any"}]}` + expected := `{"Direction":"*out","Category":"data","Tenant":"cgrates.org","Subject":"rif","Account":"","Destination":"*any","Tor":"*data","Cost":65,"DataSpans":[{"DataStart":0,"DataEnd":60,"Cost":60,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":0,"Rates":[{"GroupIntervalStart":0,"Value":1,"RateIncrement":60000000000,"RateUnit":1000000000},{"GroupIntervalStart":60000000000,"Value":1,"RateIncrement":1000000000,"RateUnit":1000000000}],"RoundingMethod":"*up","RoundingDecimals":4},"Weight":10},"DataIndex":60,"Increments":[],"MatchedSubject":"","MatchedPrefix":"","MatchedDestId":""},{"DataStart":60,"DataEnd":65,"Cost":5,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":0,"Rates":[{"GroupIntervalStart":0,"Value":1,"RateIncrement":60000000000,"RateUnit":1000000000},{"GroupIntervalStart":60000000000,"Value":1,"RateIncrement":1000000000,"RateUnit":1000000000}],"RoundingMethod":"*up","RoundingDecimals":4},"Weight":10},"DataIndex":65,"Increments":[],"MatchedSubject":"*out:cgrates.org:data:rif","MatchedPrefix":"*any","MatchedDestId":"*any"}]}` if string(js) != expected { t.Error("Error coverting to data cost: ", string(js)) } diff --git a/engine/calldesc.go b/engine/calldesc.go index e8b64d1f5..f8ced5fe2 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -116,7 +116,7 @@ type CallDescriptor struct { FallbackSubject string // the subject to check for destination if not found on primary subject RatingInfos RatingInfos Increments Increments - Type string + Tor string account *Account } @@ -306,7 +306,7 @@ func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) { } firstSpan.ratingInfo = cd.RatingInfos[0] - if cd.Type == MINUTES { + if cd.Tor == MINUTES { // split on rating plans afterStart, afterEnd := false, false //optimization for multiple activation periods for _, rp := range cd.RatingInfos { @@ -400,8 +400,8 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) { if cd.DurationIndex < cd.TimeEnd.Sub(cd.TimeStart) { cd.DurationIndex = cd.TimeEnd.Sub(cd.TimeStart) } - if cd.Type == "" { - cd.Type = MINUTES + if cd.Tor == "" { + cd.Tor = MINUTES } err := cd.LoadRatingPlans() if err != nil { @@ -432,7 +432,7 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) { Cost: cost, Timespans: timespans, deductConnectFee: cd.LoopIndex == 0, - Type: cd.Type, + Tor: cd.Tor, } //Logger.Info(fmt.Sprintf(" Get Cost: %s => %v", cd.GetKey(), cc)) cc.Timespans.Compress() @@ -448,8 +448,8 @@ func (origCD *CallDescriptor) getMaxSessionDuration(account *Account) (time.Dura if origCD.DurationIndex < origCD.TimeEnd.Sub(origCD.TimeStart) { origCD.DurationIndex = origCD.TimeEnd.Sub(origCD.TimeStart) } - if origCD.Type == "" { - origCD.Type = MINUTES + if origCD.Tor == "" { + origCD.Tor = MINUTES } cd := origCD.Clone() //Logger.Debug(fmt.Sprintf("MAX SESSION cd: %+v", cd)) @@ -514,7 +514,7 @@ func (cd *CallDescriptor) GetMaxSessionDuration() (duration time.Duration, err e Logger.Err(fmt.Sprintf("Could not get user balance for %s: %s.", cd.GetAccountKey(), err.Error())) return 0, err } else { - if memberIds, err := account.GetUniqueSharedGroupMembers(cd.Destination, cd.Direction, cd.Type); err == nil { + if memberIds, err := account.GetUniqueSharedGroupMembers(cd.Destination, cd.Direction, cd.Tor); err == nil { AccLock.GuardMany(memberIds, func() (float64, error) { duration, err = cd.getMaxSessionDuration(account) return 0, err @@ -564,7 +564,7 @@ func (cd *CallDescriptor) Debit() (cc *CallCost, err error) { Logger.Err(fmt.Sprintf("Could not get user balance for %s: %s.", cd.GetAccountKey(), err.Error())) return nil, err } else { - if memberIds, err := account.GetUniqueSharedGroupMembers(cd.Destination, cd.Direction, cd.Type); err == nil { + if memberIds, err := account.GetUniqueSharedGroupMembers(cd.Destination, cd.Direction, cd.Tor); err == nil { AccLock.GuardMany(memberIds, func() (float64, error) { cc, err = cd.debit(account) return 0, err @@ -585,7 +585,7 @@ func (cd *CallDescriptor) MaxDebit() (cc *CallCost, err error) { Logger.Err(fmt.Sprintf("Could not get user balance for %s: %s.", cd.GetAccountKey(), err.Error())) return nil, err } else { - if memberIds, err := account.GetUniqueSharedGroupMembers(cd.Destination, cd.Direction, cd.Type); err == nil { + if memberIds, err := account.GetUniqueSharedGroupMembers(cd.Destination, cd.Direction, cd.Tor); err == nil { AccLock.GuardMany(memberIds, func() (float64, error) { remainingDuration, err := cd.getMaxSessionDuration(account) if err != nil || remainingDuration == 0 { @@ -618,7 +618,7 @@ func (cd *CallDescriptor) RefundIncrements() (left float64, err error) { defer accountingStorage.SetAccount(account) } } - account.refundIncrement(increment, cd.Direction, cd.Type, true) + account.refundIncrement(increment, cd.Direction, cd.Tor, true) } return 0.0, err } @@ -641,7 +641,7 @@ func (cd *CallDescriptor) CreateCallCost() *CallCost { Subject: cd.Subject, Account: cd.Account, Destination: cd.Destination, - Type: cd.Type, + Tor: cd.Tor, } } @@ -661,6 +661,6 @@ func (cd *CallDescriptor) Clone() *CallDescriptor { FallbackSubject: cd.FallbackSubject, //RatingInfos: cd.RatingInfos, //Increments: cd.Increments, - Type: cd.Type, + Tor: cd.Tor, } } diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go index 192e7e4dd..c7bb2307b 100644 --- a/engine/calldesc_test.go +++ b/engine/calldesc_test.go @@ -451,7 +451,7 @@ func TestMaxSessionTimeNoCredit(t *testing.T) { Tenant: "vdf", Subject: "broker", Destination: "0723", - Type: MINUTES, + Tor: MINUTES, } result, err := cd.GetMaxSessionDuration() if result != time.Minute || err != nil { @@ -472,7 +472,7 @@ func TestMaxSessionModifiesCallDesc(t *testing.T) { Account: "minu", Destination: "0723", DurationIndex: t2.Sub(t1), - Type: MINUTES, + Tor: MINUTES, } initial := cd.Clone() cd.GetMaxSessionDuration() @@ -701,7 +701,7 @@ func TestCDGetCostANY(t *testing.T) { Destination: utils.ANY, TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), TimeEnd: time.Date(2014, 3, 4, 6, 0, 1, 0, time.UTC), - Type: DATA, + Tor: DATA, } cc, err := cd1.GetCost() if err != nil || cc.Cost != 60 { @@ -718,7 +718,7 @@ func TestCDSplitInDataSlots(t *testing.T) { Destination: utils.ANY, TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), TimeEnd: time.Date(2014, 3, 4, 6, 1, 5, 0, time.UTC), - Type: DATA, + Tor: DATA, DurationIndex: 65 * time.Second, } cd.LoadRatingPlans() @@ -738,7 +738,7 @@ func TestCDDataGetCost(t *testing.T) { Destination: utils.ANY, TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC), TimeEnd: time.Date(2014, 3, 4, 6, 1, 5, 0, time.UTC), - Type: DATA, + Tor: DATA, } cc, err := cd.GetCost() if err != nil || cc.Cost != 65 { diff --git a/engine/datacost.go b/engine/datacost.go index d74ab5d2d..d584cab5d 100644 --- a/engine/datacost.go +++ b/engine/datacost.go @@ -19,10 +19,10 @@ package engine // type used for showing sane data cost type DataCost struct { - Direction, Category, Tenant, Subject, Account, Destination, Type string - Cost float64 - DataSpans []*DataSpan - deductConnectFee bool + Direction, Category, Tenant, Subject, Account, Destination, Tor string + Cost float64 + DataSpans []*DataSpan + deductConnectFee bool } type DataSpan struct { DataStart, DataEnd float64 diff --git a/engine/timespans.go b/engine/timespans.go index 6d2c48809..2420a2ce8 100644 --- a/engine/timespans.go +++ b/engine/timespans.go @@ -54,7 +54,7 @@ type Increment struct { type UnitInfo struct { DestinationId string Quantity float64 - Type string + Tor string //Price float64 }