From 88cc0cf370565cf61d947bbb8e3c646c56ca39bf Mon Sep 17 00:00:00 2001 From: rbarrabe Date: Tue, 29 Nov 2016 14:22:32 +0100 Subject: [PATCH 1/4] Update account.go --- engine/account.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/account.go b/engine/account.go index 1e34d2e3c..499db1318 100644 --- a/engine/account.go +++ b/engine/account.go @@ -823,7 +823,7 @@ func (acc *Account) Clone() *Account { return newAcc } -func (acc *Account) DebitConnectionFee(cc *CallCost, usefulMoneyBalances Balances, count bool, block bool) bool { +func (acc *Account) DebitConnectionFee(cc *CallCost, usefulMoneyBalances Balances, count bool, block bool) (bool, Balance) { if cc.deductConnectFee { connectFee := cc.GetConnectFee() //log.Print("CONNECT FEE: %f", connectFee) From a78fea2f0a2a38735c06608ea8746e83eb7e48a4 Mon Sep 17 00:00:00 2001 From: Regis Date: Tue, 29 Nov 2016 17:46:17 +0100 Subject: [PATCH 2/4] connect fee in first increment --- engine/account.go | 43 ++++++++++++++++++++++++++--- engine/balances.go | 61 +++++++++++++++++++++++++++++++++++++++-- engine/callcost.go | 6 ++-- engine/calldesc.go | 3 ++ engine/calldesc_test.go | 1 + engine/timespans.go | 10 ++++++- 6 files changed, 114 insertions(+), 10 deletions(-) diff --git a/engine/account.go b/engine/account.go index 499db1318..db6df337c 100644 --- a/engine/account.go +++ b/engine/account.go @@ -416,6 +416,7 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo if debitErr != nil { return nil, debitErr } + //utils.Logger.Info(fmt.Sprintf("CD AFTER UNIT: %+v", cd)) if partCC != nil { //log.Printf("partCC: %+v", partCC.Timespans[0]) @@ -511,9 +512,13 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo if leftCC.Cost > 0 && goNegative { initialLength := len(cc.Timespans) cc.Timespans = append(cc.Timespans, leftCC.Timespans...) + + var debitedConnectFeeBalance Balance + var ok bool + if initialLength == 0 { // this is the first add, debit the connect fee - ub.DebitConnectionFee(cc, usefulMoneyBalances, count, true) + ok, debitedConnectFeeBalance = ub.DebitConnectionFee(cc, usefulMoneyBalances, count, true) } //log.Printf("Left CC: %+v ", leftCC) // get the default money balanance @@ -526,7 +531,33 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo if ts.Increments == nil { ts.createIncrementsSlice() } - for _, increment := range ts.Increments { + + if ts.RateInterval.Rating.ConnectFee > 0 && ok { + + inc := &Increment{ + Duration: 0, + Cost: ts.RateInterval.Rating.ConnectFee, + BalanceInfo: &DebitInfo{ + Monetary: &MonetaryInfo{ + UUID: debitedConnectFeeBalance.Uuid, + ID: debitedConnectFeeBalance.ID, + Value: debitedConnectFeeBalance.Value, + }, + AccountID: ub.ID, + }, + } + + incs := []*Increment{inc} + ts.Increments = append(incs, ts.Increments...) + } + + for incIndex, increment := range ts.Increments { + + if incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && ok { + // go to nextincrement + continue + } + cost := increment.Cost defaultBalance := ub.GetDefaultMoneyBalance() defaultBalance.SubstractValue(cost) @@ -824,6 +855,8 @@ func (acc *Account) Clone() *Account { } func (acc *Account) DebitConnectionFee(cc *CallCost, usefulMoneyBalances Balances, count bool, block bool) (bool, Balance) { + var debitedBalance Balance + if cc.deductConnectFee { connectFee := cc.GetConnectFee() //log.Print("CONNECT FEE: %f", connectFee) @@ -836,10 +869,11 @@ func (acc *Account) DebitConnectionFee(cc *CallCost, usefulMoneyBalances Balance acc.countUnits(connectFee, utils.MONETARY, cc, b) } connectFeePaid = true + debitedBalance = *b break } if b.Blocker && block { // stop here - return false + return false, debitedBalance } } // debit connect fee @@ -848,13 +882,14 @@ func (acc *Account) DebitConnectionFee(cc *CallCost, usefulMoneyBalances Balance // there are no money for the connect fee; go negative b := acc.GetDefaultMoneyBalance() b.SubstractValue(connectFee) + debitedBalance = *b // the conect fee is not refundable! if count { acc.countUnits(connectFee, utils.MONETARY, cc, b) } } } - return true + return true, debitedBalance } func (acc *Account) matchActionFilter(condition string) (bool, error) { diff --git a/engine/balances.go b/engine/balances.go index b96be9b56..b3d046aab 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -385,13 +385,15 @@ func (b *Balance) debitUnits(cd *CallDescriptor, ub *Account, moneyBalances Bala } else { // get the cost from balance //log.Printf("::::::: %+v", cd) + var debitedConnectFeeBalance Balance + var ok bool cc, err = b.GetCost(cd, true) if err != nil { return nil, err } if debitConnectFee { // this is the first add, debit the connect fee - if ub.DebitConnectionFee(cc, moneyBalances, count, true) == false { + if ok, debitedConnectFeeBalance = ub.DebitConnectionFee(cc, moneyBalances, count, true); !ok { // found blocker balance return nil, nil } @@ -408,8 +410,34 @@ func (b *Balance) debitUnits(cd *CallDescriptor, ub *Account, moneyBalances Bala utils.Logger.Err(fmt.Sprintf("Nil RateInterval ERROR on TS: %+v, CC: %+v, from CD: %+v", ts, cc, cd)) return nil, errors.New("timespan with no rate interval assigned") } + + if ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee { + + inc := &Increment{ + Duration: 0, + Cost: ts.RateInterval.Rating.ConnectFee, + BalanceInfo: &DebitInfo{ + Monetary: &MonetaryInfo{ + UUID: debitedConnectFeeBalance.Uuid, + ID: debitedConnectFeeBalance.ID, + Value: debitedConnectFeeBalance.Value, + }, + AccountID: ub.ID, + }, + } + + incs := []*Increment{inc} + ts.Increments = append(incs, ts.Increments...) + } + maxCost, strategy := ts.RateInterval.GetMaxCost() for incIndex, inc := range ts.Increments { + + if incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee { + // go to nextincrement + continue + } + // debit minutes and money amount := inc.Duration.Seconds() if b.Factor != nil { @@ -513,10 +541,13 @@ func (b *Balance) debitMoney(cd *CallDescriptor, ub *Account, moneyBalances Bala if err != nil { return nil, err } + + var debitedConnectFeeBalance Balance + var ok bool //log.Print("cc: " + utils.ToJSON(cc)) if debitConnectFee { // this is the first add, debit the connect fee - if ub.DebitConnectionFee(cc, moneyBalances, count, true) == false { + if ok, debitedConnectFeeBalance = ub.DebitConnectionFee(cc, moneyBalances, count, true); !ok { // balance is blocker return nil, nil } @@ -536,12 +567,38 @@ func (b *Balance) debitMoney(cd *CallDescriptor, ub *Account, moneyBalances Bala utils.Logger.Err(fmt.Sprintf("Nil RateInterval ERROR on TS: %+v, CC: %+v, from CD: %+v", ts, cc, cd)) return nil, errors.New("timespan with no rate interval assigned") } + + if ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee { + + inc := &Increment{ + Duration: 0, + Cost: ts.RateInterval.Rating.ConnectFee, + BalanceInfo: &DebitInfo{ + Monetary: &MonetaryInfo{ + UUID: debitedConnectFeeBalance.Uuid, + ID: debitedConnectFeeBalance.ID, + Value: debitedConnectFeeBalance.Value, + }, + AccountID: ub.ID, + }, + } + + incs := []*Increment{inc} + ts.Increments = append(incs, ts.Increments...) + } + maxCost, strategy := ts.RateInterval.GetMaxCost() //log.Printf("Timing: %+v", ts.RateInterval.Timing) //log.Printf("Rate: %+v", ts.RateInterval.Rating) for incIndex, inc := range ts.Increments { // check standard subject tags //log.Printf("INC: %+v", inc) + + if incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && ok { + // go to nextincrement + continue + } + amount := inc.Cost inc.paid = false if strategy == utils.MAX_COST_DISCONNECT && cd.MaxCostSoFar >= maxCost { diff --git a/engine/callcost.go b/engine/callcost.go index 5e4ee8c75..b0899d32b 100644 --- a/engine/callcost.go +++ b/engine/callcost.go @@ -169,9 +169,9 @@ func (cc *CallCost) UpdateCost() { func (cc *CallCost) updateCost() { cost := 0.0 - if cc.deductConnectFee { // add back the connectFee - cost += cc.GetConnectFee() - } + //if cc.deductConnectFee { // add back the connectFee + // cost += cc.GetConnectFee() + //} for _, ts := range cc.Timespans { ts.Cost = ts.CalculateCost() cost += ts.Cost diff --git a/engine/calldesc.go b/engine/calldesc.go index 9df42331d..66ea9d1f0 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -370,6 +370,7 @@ func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) { } //log.Printf("After SplitByRatingPlan: %+v", utils.ToJSON(timespans)) // split on days + for i := 0; i < len(timespans); i++ { rp := timespans[i].ratingInfo newTs := timespans[i].SplitByDay() @@ -386,6 +387,7 @@ func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) { } //log.Printf("After SplitByDay: %+v", utils.ToJSON(timespans)) // split on rate intervals + for i := 0; i < len(timespans); i++ { //log.Printf("==============%v==================", i) //log.Printf("TS: %+v", timespans[i]) @@ -501,6 +503,7 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) { } func (cd *CallDescriptor) getCost() (*CallCost, error) { + // check for 0 duration if cd.GetDuration() == 0 { cc := cd.CreateCallCost() diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go index 777134d9d..9326306d9 100644 --- a/engine/calldesc_test.go +++ b/engine/calldesc_test.go @@ -1425,6 +1425,7 @@ func TestMaxDebitZeroDefinedRate(t *testing.T) { if cc.GetDuration() != 49*time.Second { t.Error("Error obtaining max debit duration: ", cc.GetDuration()) } + if cc.Cost != 0.91 { t.Error("Error in max debit cost: ", cc.Cost) } diff --git a/engine/timespans.go b/engine/timespans.go index 4d18af209..6e65ca21a 100644 --- a/engine/timespans.go +++ b/engine/timespans.go @@ -696,7 +696,15 @@ func (nts *TimeSpan) copyRatingInfo(ts *TimeSpan) { // returns a time for the specified second in the time span func (ts *TimeSpan) GetTimeStartForIncrement(index int) time.Time { - return ts.TimeStart.Add(time.Duration(int64(index) * ts.Increments[0].Duration.Nanoseconds())) + + start := ts.TimeStart + for incIndex, inc := range ts.Increments { + if incIndex < index { + start = start.Add(time.Duration(inc.Duration.Nanoseconds())) + } + } + return start + //return ts.TimeStart.Add(time.Duration(int64(index) * ts.Increments[0].Duration.Nanoseconds())) } func (ts *TimeSpan) RoundToDuration(duration time.Duration) { From c056d1b5bf17fa01f8ca6d6145f67ca50a3cc7f2 Mon Sep 17 00:00:00 2001 From: Regis Date: Wed, 30 Nov 2016 15:52:54 +0100 Subject: [PATCH 3/4] adding connect fee only in first timestamp --- engine/account.go | 6 +++--- engine/balances.go | 9 +++++---- sessionmanager/smg_session.go | 5 +++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/engine/account.go b/engine/account.go index db6df337c..b8cbf9a6b 100644 --- a/engine/account.go +++ b/engine/account.go @@ -527,12 +527,12 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo utils.Logger.Err(fmt.Sprintf(" Going negative on account %s with AllowNegative: false", cd.GetAccountKey())) } leftCC.Timespans.Decompress() - for _, ts := range leftCC.Timespans { + for tsIndex, ts := range leftCC.Timespans { if ts.Increments == nil { ts.createIncrementsSlice() } - if ts.RateInterval.Rating.ConnectFee > 0 && ok { + if tsIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && ok { inc := &Increment{ Duration: 0, @@ -553,7 +553,7 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo for incIndex, increment := range ts.Increments { - if incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && ok { + if tsIndex == 0 && incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && ok { // go to nextincrement continue } diff --git a/engine/balances.go b/engine/balances.go index b3d046aab..3e677e690 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -411,7 +411,7 @@ func (b *Balance) debitUnits(cd *CallDescriptor, ub *Account, moneyBalances Bala return nil, errors.New("timespan with no rate interval assigned") } - if ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee { + if tsIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee && ok { inc := &Increment{ Duration: 0, @@ -433,7 +433,7 @@ func (b *Balance) debitUnits(cd *CallDescriptor, ub *Account, moneyBalances Bala maxCost, strategy := ts.RateInterval.GetMaxCost() for incIndex, inc := range ts.Increments { - if incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee { + if tsIndex == 0 && incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee && ok { // go to nextincrement continue } @@ -546,6 +546,7 @@ func (b *Balance) debitMoney(cd *CallDescriptor, ub *Account, moneyBalances Bala var ok bool //log.Print("cc: " + utils.ToJSON(cc)) if debitConnectFee { + // this is the first add, debit the connect fee if ok, debitedConnectFeeBalance = ub.DebitConnectionFee(cc, moneyBalances, count, true); !ok { // balance is blocker @@ -568,7 +569,7 @@ func (b *Balance) debitMoney(cd *CallDescriptor, ub *Account, moneyBalances Bala return nil, errors.New("timespan with no rate interval assigned") } - if ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee { + if tsIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee && ok { inc := &Increment{ Duration: 0, @@ -594,7 +595,7 @@ func (b *Balance) debitMoney(cd *CallDescriptor, ub *Account, moneyBalances Bala // check standard subject tags //log.Printf("INC: %+v", inc) - if incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && ok { + if tsIndex == 0 && incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && ok { // go to nextincrement continue } diff --git a/sessionmanager/smg_session.go b/sessionmanager/smg_session.go index 0b1619f2c..5eb69a971 100644 --- a/sessionmanager/smg_session.go +++ b/sessionmanager/smg_session.go @@ -141,6 +141,7 @@ func (self *SMGSession) debit(dur time.Duration, lastUsed *time.Duration) (time. // Attempts to refund a duration, error on failure func (self *SMGSession) refund(refundDuration time.Duration) error { + if refundDuration == 0 { // Nothing to refund return nil } @@ -154,12 +155,16 @@ func (self *SMGSession) refund(refundDuration time.Duration) error { if refundDuration <= tsDuration { lastRefundedIncrementIndex := -1 + for j := len(ts.Increments) - 1; j >= 0; j-- { increment := ts.Increments[j] + if increment.Duration <= refundDuration { + refundIncrements = append(refundIncrements, increment) refundDuration -= increment.Duration lastRefundedIncrementIndex = j + } else { break //increment duration is larger, cannot refund increment } From 1c6b5d6a8f0e43159608ccbbc287b49ec8851039 Mon Sep 17 00:00:00 2001 From: Regis Date: Fri, 16 Dec 2016 14:46:33 +0100 Subject: [PATCH 4/4] Adding deductConnectFee in test to create an increment for the connect fee --- engine/account.go | 4 ++-- engine/balances.go | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/engine/account.go b/engine/account.go index b8cbf9a6b..386bfd32d 100644 --- a/engine/account.go +++ b/engine/account.go @@ -532,7 +532,7 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo ts.createIncrementsSlice() } - if tsIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && ok { + if tsIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && cc.deductConnectFee && ok { inc := &Increment{ Duration: 0, @@ -553,7 +553,7 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo for incIndex, increment := range ts.Increments { - if tsIndex == 0 && incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && ok { + if tsIndex == 0 && incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && cc.deductConnectFee && ok { // go to nextincrement continue } diff --git a/engine/balances.go b/engine/balances.go index 3e677e690..7db4de777 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -411,7 +411,7 @@ func (b *Balance) debitUnits(cd *CallDescriptor, ub *Account, moneyBalances Bala return nil, errors.New("timespan with no rate interval assigned") } - if tsIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee && ok { + if tsIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee && cc.deductConnectFee && ok { inc := &Increment{ Duration: 0, @@ -433,7 +433,7 @@ func (b *Balance) debitUnits(cd *CallDescriptor, ub *Account, moneyBalances Bala maxCost, strategy := ts.RateInterval.GetMaxCost() for incIndex, inc := range ts.Increments { - if tsIndex == 0 && incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee && ok { + if tsIndex == 0 && incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee && cc.deductConnectFee && ok { // go to nextincrement continue } @@ -569,7 +569,7 @@ func (b *Balance) debitMoney(cd *CallDescriptor, ub *Account, moneyBalances Bala return nil, errors.New("timespan with no rate interval assigned") } - if tsIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee && ok { + if tsIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee && cc.deductConnectFee && ok { inc := &Increment{ Duration: 0, @@ -595,7 +595,7 @@ func (b *Balance) debitMoney(cd *CallDescriptor, ub *Account, moneyBalances Bala // check standard subject tags //log.Printf("INC: %+v", inc) - if tsIndex == 0 && incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && ok { + if tsIndex == 0 && incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && cc.deductConnectFee && ok { // go to nextincrement continue }