mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
fix for not enough credit on max debit
This commit is contained in:
@@ -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}})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
})
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user