fix for not enough credit on max debit

This commit is contained in:
Radu Ioan Fericean
2015-03-10 13:38:07 +02:00
parent c20fb69986
commit 5679258f0e
4 changed files with 53 additions and 45 deletions

View File

@@ -208,7 +208,7 @@ func (account *Account) getAlldBalancesForPrefix(destination, category, balanceT
return
}
func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun bool) (cc *CallCost, err error) {
func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun bool, goNegative bool) (cc *CallCost, err error) {
usefulUnitBalances := ub.getAlldBalancesForPrefix(cd.Destination, cd.Category, cd.TOR+cd.Direction)
usefulMoneyBalances := ub.getAlldBalancesForPrefix(cd.Destination, cd.Category, CREDIT+cd.Direction)
//log.Print(usefulMoneyBalances, usefulUnitBalances)
@@ -240,7 +240,7 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo
ub.DebitConnectionFee(cc, usefulMoneyBalances, count)
}
// for i, ts := range cc.Timespans {
// log.Printf("cc.times[an[%d]: %+v\n", i, ts)
// log.Printf("cc.times[an[%d]: %+v\n", i, ts)
// }
cd.TimeStart = cc.GetEndTime()
//log.Printf("CD: %+v", cd)
@@ -302,25 +302,27 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo
// this is the first add, debit the connect fee
ub.DebitConnectionFee(cc, usefulMoneyBalances, count)
}
//log.Printf("Left CC: %+v", leftCC)
// get the default money balanance
// and go negative on it with the amount still unpaid
for _, ts := range leftCC.Timespans {
if ts.Increments == nil {
ts.createIncrementsSlice()
if leftCC.Cost == 0 || goNegative {
//log.Printf("Left CC: %+v", leftCC)
// get the default money balanance
// and go negative on it with the amount still unpaid
if len(leftCC.Timespans) > 0 && leftCC.Cost > 0 && !ub.AllowNegative {
err = errors.New("not enough credit")
}
for _, increment := range ts.Increments {
cost := increment.Cost
defaultBalance := ub.GetDefaultMoneyBalance(leftCC.Direction)
defaultBalance.SubstractAmount(cost)
increment.BalanceInfo.MoneyBalanceUuid = defaultBalance.Uuid
increment.BalanceInfo.AccountId = ub.Id
increment.paid = true
if count {
ub.countUnits(&Action{BalanceType: CREDIT, Direction: leftCC.Direction, Balance: &Balance{Value: cost, DestinationId: leftCC.Destination}})
for _, ts := range leftCC.Timespans {
if ts.Increments == nil {
ts.createIncrementsSlice()
}
if !ub.AllowNegative {
err = errors.New("not enough credit")
for _, increment := range ts.Increments {
cost := increment.Cost
defaultBalance := ub.GetDefaultMoneyBalance(leftCC.Direction)
defaultBalance.SubstractAmount(cost)
increment.BalanceInfo.MoneyBalanceUuid = defaultBalance.Uuid
increment.BalanceInfo.AccountId = ub.Id
increment.paid = true
if count {
ub.countUnits(&Action{BalanceType: CREDIT, Direction: leftCC.Direction, Balance: &Balance{Value: cost, DestinationId: leftCC.Destination}})
}
}
}
}

View File

@@ -185,7 +185,7 @@ func TestDebitCreditZeroSecond(t *testing.T) {
}
rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1}, CREDIT + OUTBOUND: BalanceChain{&Balance{Category: "0", Value: 21}}}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err != nil {
t.Error("Error debiting balance: ", err)
}
@@ -228,7 +228,7 @@ func TestDebitCreditZeroMinute(t *testing.T) {
CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}},
}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err != nil {
t.Error("Error debiting balance: ", err)
}
@@ -275,7 +275,7 @@ func TestDebitCreditZeroMixedMinute(t *testing.T) {
CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}},
}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err != nil {
t.Error("Error debiting balance: ", err)
}
@@ -326,7 +326,7 @@ func TestDebitCreditNoCredit(t *testing.T) {
MINUTES + OUTBOUND: BalanceChain{b1},
}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err == nil {
t.Error("Showing no enough credit error ")
}
@@ -378,7 +378,7 @@ func TestDebitCreditHasCredit(t *testing.T) {
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 110}},
}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err != nil {
t.Error("Error debiting balance: ", err)
}
@@ -426,7 +426,7 @@ func TestDebitCreditSplitMinutesMoney(t *testing.T) {
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 50}},
}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err != nil {
t.Error("Error debiting balance: ", err)
}
@@ -478,7 +478,7 @@ func TestDebitCreditMoreTimespans(t *testing.T) {
MINUTES + OUTBOUND: BalanceChain{b1},
}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err != nil {
t.Error("Error debiting balance: ", err)
}
@@ -527,7 +527,7 @@ func TestDebitCreditMoreTimespansMixed(t *testing.T) {
MINUTES + OUTBOUND: BalanceChain{b1, b2},
}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err != nil {
t.Error("Error debiting balance: ", err)
}
@@ -577,7 +577,7 @@ func TestDebitCreditNoConectFeeCredit(t *testing.T) {
MINUTES + OUTBOUND: BalanceChain{b1},
}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err == nil {
t.Error("Error showing debiting balance error: ", err)
}
@@ -621,7 +621,7 @@ func TestDebitCreditMoneyOnly(t *testing.T) {
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "money", Value: 50}},
}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err == nil {
t.Error("Missing noy enough credit error ")
}
@@ -675,7 +675,7 @@ func TestDebitCreditSubjectMinutes(t *testing.T) {
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 350}},
}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err != nil {
t.Error("Error debiting balance: ", err)
}
@@ -729,7 +729,7 @@ func TestDebitCreditSubjectMoney(t *testing.T) {
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 75, DestinationId: "NAT", RatingSubject: "minu"}},
}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err != nil {
t.Error("Error debiting balance: ", err)
}
@@ -780,7 +780,7 @@ func TestDebitCreditSubjectMoney(t *testing.T) {
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 19500, RatingSubject: "minu"}},
}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err != nil {
t.Error("Error debiting balance: ", err)
}
@@ -842,7 +842,7 @@ func TestDebitCreditSubjectMixedMoreTS(t *testing.T) {
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 50, RatingSubject: "minu"}},
}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err == nil {
t.Error("Error showing debiting balance error: ", err)
}
@@ -906,7 +906,7 @@ func TestDebitCreditSubjectMixedPartPay(t *testing.T) {
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 75, RatingSubject: "minu"}},
}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err == nil {
t.Error("Error showing debiting balance error: ", err)
}
@@ -1173,7 +1173,7 @@ func TestDebitShared(t *testing.T) {
accountingStorage.SetAccount(groupie)
accountingStorage.SetSharedGroup(sg)
cache2go.Cache(SHARED_GROUP_PREFIX+"SG_TEST", sg)
cc, err := rif.debitCreditBalance(cd, false, false)
cc, err := rif.debitCreditBalance(cd, false, false, true)
if err != nil {
t.Error("Error debiting balance: ", err)
}
@@ -1233,7 +1233,7 @@ func TestDebitSMS(t *testing.T) {
CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}},
}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err != nil {
t.Error("Error debiting balance: ", err)
}
@@ -1283,7 +1283,7 @@ func TestDebitDataUnits(t *testing.T) {
CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}},
}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err != nil {
t.Error("Error debiting balance: ", err)
}
@@ -1332,7 +1332,7 @@ func TestDebitDataMoney(t *testing.T) {
CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 160}},
}}
var err error
cc, err = rifsBalance.debitCreditBalance(cd, false, false)
cc, err = rifsBalance.debitCreditBalance(cd, false, false, true)
if err != nil {
t.Error("Error debiting balance: ", err)
}

View File

@@ -464,7 +464,7 @@ func (origCD *CallDescriptor) getMaxSessionDuration(origAcc *Account) (time.Dura
}
cd := origCD.Clone()
initialDuration := cd.TimeEnd.Sub(cd.TimeStart)
cc, _ := cd.debit(account, true)
cc, _ := cd.debit(account, true, false)
//log.Printf("CC: %+v", cc)
@@ -526,7 +526,7 @@ func (cd *CallDescriptor) GetMaxSessionDuration() (duration time.Duration, err e
// Interface method used to add/substract an amount of cents or bonus seconds (as returned by GetCost method)
// from user's money balance.
func (cd *CallDescriptor) debit(account *Account, dryRun bool) (cc *CallCost, err error) {
func (cd *CallDescriptor) debit(account *Account, dryRun bool, goNegative bool) (cc *CallCost, err error) {
if !dryRun {
defer accountingStorage.SetAccount(account)
}
@@ -534,7 +534,7 @@ func (cd *CallDescriptor) debit(account *Account, dryRun bool) (cc *CallCost, er
cd.TOR = MINUTES
}
//log.Printf("Debit CD: %+v", cd)
cc, err = account.debitCreditBalance(cd, !dryRun, dryRun)
cc, err = account.debitCreditBalance(cd, !dryRun, dryRun, goNegative)
//log.Print("HERE: ", cc, err)
if err != nil {
Logger.Err(fmt.Sprintf("<Rater> Error getting cost for account key %v: %v", cd.GetAccountKey(), err))
@@ -563,7 +563,7 @@ func (cd *CallDescriptor) Debit() (cc *CallCost, err error) {
} else {
if memberIds, err := account.GetUniqueSharedGroupMembers(cd.Destination, cd.Direction, cd.Category, cd.TOR); err == nil {
AccLock.GuardMany(memberIds, func() (float64, error) {
cc, err = cd.debit(account, false)
cc, err = cd.debit(account, false, true)
return 0, err
})
} else {
@@ -597,7 +597,7 @@ func (cd *CallDescriptor) MaxDebit() (cc *CallCost, err error) {
cd.TimeEnd = cd.TimeStart.Add(remainingDuration)
cd.DurationIndex -= initialDuration - remainingDuration
}
cc, err = cd.debit(account, false)
cc, err = cd.debit(account, false, true)
//log.Print(balanceMap[0].Value, balanceMap[1].Value)
return 0, err
})

View File

@@ -523,7 +523,10 @@ func TestMaxSessionModifiesCallDesc(t *testing.T) {
TOR: MINUTES,
}
initial := cd.Clone()
cd.GetMaxSessionDuration()
_, err := cd.GetMaxSessionDuration()
if err != nil {
t.Error("Got error from max duration: ", err)
}
cd.account = nil // it's OK to cache the account
if !reflect.DeepEqual(cd, initial) {
t.Errorf("GetMaxSessionDuration is changing the call descriptor %+v != %+v", cd, initial)
@@ -542,7 +545,10 @@ func TestMaxDebitDurationNoGreatherThanInitialDuration(t *testing.T) {
Destination: "0723",
}
initialDuration := cd.TimeEnd.Sub(cd.TimeStart)
result, _ := cd.GetMaxSessionDuration()
result, err := cd.GetMaxSessionDuration()
if err != nil {
t.Error("Got error from max duration: ", err)
}
if result > initialDuration {
t.Error("max session duration greather than initial duration", initialDuration, result)
}