From 8fa986d8a9f65c065de0b0f14feddb9d26a919ef Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Wed, 9 Mar 2016 16:55:23 +0200 Subject: [PATCH] Balance values in callcost increments --- engine/account.go | 3 +- engine/account_test.go | 12 ++-- engine/balances.go | 16 ++++-- engine/calldesc.go | 20 +++---- engine/calldesc_test.go | 23 ++++---- engine/timespans.go | 16 ++++-- engine/timespans_test.go | 120 ++++++++++++++++++++++++++------------- 7 files changed, 132 insertions(+), 78 deletions(-) diff --git a/engine/account.go b/engine/account.go index 87c1f9e3c..046a95c57 100644 --- a/engine/account.go +++ b/engine/account.go @@ -487,7 +487,8 @@ func (ub *Account) debitCreditBalance(cd *CallDescriptor, count bool, dryRun boo defaultBalance := ub.GetDefaultMoneyBalance() defaultBalance.SubstractValue(cost) increment.BalanceInfo.MoneyBalanceUuid = defaultBalance.Uuid - increment.BalanceInfo.AccountId = ub.ID + increment.BalanceInfo.MoneyBalanceValue = defaultBalance.Value + increment.BalanceInfo.AccountID = ub.ID increment.paid = true if count { ub.countUnits( diff --git a/engine/account_test.go b/engine/account_test.go index cb87a69af..0e6cecede 100644 --- a/engine/account_test.go +++ b/engine/account_test.go @@ -1187,12 +1187,12 @@ func TestDebitShared(t *testing.T) { t.Errorf("I%d: %+v (%+v)", index, incr, incr.BalanceInfo) } } - if cc.Timespans[0].Increments[0].BalanceInfo.AccountId != "groupie" || - cc.Timespans[0].Increments[1].BalanceInfo.AccountId != "groupie" || - cc.Timespans[0].Increments[2].BalanceInfo.AccountId != "groupie" || - cc.Timespans[0].Increments[3].BalanceInfo.AccountId != "groupie" || - cc.Timespans[0].Increments[4].BalanceInfo.AccountId != "groupie" || - cc.Timespans[0].Increments[5].BalanceInfo.AccountId != "groupie" { + if cc.Timespans[0].Increments[0].BalanceInfo.AccountID != "groupie" || + cc.Timespans[0].Increments[1].BalanceInfo.AccountID != "groupie" || + cc.Timespans[0].Increments[2].BalanceInfo.AccountID != "groupie" || + cc.Timespans[0].Increments[3].BalanceInfo.AccountID != "groupie" || + cc.Timespans[0].Increments[4].BalanceInfo.AccountID != "groupie" || + cc.Timespans[0].Increments[5].BalanceInfo.AccountID != "groupie" { t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) } } diff --git a/engine/balances.go b/engine/balances.go index f089c6253..c74855c51 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -356,7 +356,8 @@ func (b *Balance) debitUnits(cd *CallDescriptor, ub *Account, moneyBalances Bala if b.GetValue() >= amount { b.SubstractValue(amount) inc.BalanceInfo.UnitBalanceUuid = b.Uuid - inc.BalanceInfo.AccountId = ub.ID + inc.BalanceInfo.UnitBalanceValue = b.Value + inc.BalanceInfo.AccountID = ub.ID inc.BalanceInfo.RateInterval = nil inc.UnitInfo = &UnitInfo{cc.Destination, amount, cc.TOR} inc.Cost = 0 @@ -428,7 +429,8 @@ func (b *Balance) debitUnits(cd *CallDescriptor, ub *Account, moneyBalances Bala if strategy == utils.MAX_COST_FREE && cd.MaxCostSoFar >= maxCost { cost, inc.Cost = 0.0, 0.0 inc.BalanceInfo.MoneyBalanceUuid = b.Uuid - inc.BalanceInfo.AccountId = ub.ID + inc.BalanceInfo.MoneyBalanceValue = b.Value + inc.BalanceInfo.AccountID = ub.ID inc.BalanceInfo.RateInterval = ts.RateInterval inc.paid = true if count { @@ -447,11 +449,13 @@ func (b *Balance) debitUnits(cd *CallDescriptor, ub *Account, moneyBalances Bala if (cost == 0 || moneyBal != nil) && b.GetValue() >= amount { b.SubstractValue(amount) inc.BalanceInfo.UnitBalanceUuid = b.Uuid - inc.BalanceInfo.AccountId = ub.ID + inc.BalanceInfo.UnitBalanceValue = b.Value + inc.BalanceInfo.AccountID = ub.ID inc.BalanceInfo.RateInterval = nil inc.UnitInfo = &UnitInfo{cc.Destination, amount, cc.TOR} if cost != 0 { inc.BalanceInfo.MoneyBalanceUuid = moneyBal.Uuid + inc.BalanceInfo.MoneyBalanceValue = moneyBal.Value moneyBal.SubstractValue(cost) cd.MaxCostSoFar += cost } @@ -537,7 +541,8 @@ func (b *Balance) debitMoney(cd *CallDescriptor, ub *Account, moneyBalances Bala if strategy == utils.MAX_COST_FREE && cd.MaxCostSoFar >= maxCost { amount, inc.Cost = 0.0, 0.0 inc.BalanceInfo.MoneyBalanceUuid = b.Uuid - inc.BalanceInfo.AccountId = ub.ID + inc.BalanceInfo.MoneyBalanceValue = b.Value + inc.BalanceInfo.AccountID = ub.ID if b.RatingSubject != "" { inc.BalanceInfo.RateInterval = ts.RateInterval } @@ -555,7 +560,8 @@ func (b *Balance) debitMoney(cd *CallDescriptor, ub *Account, moneyBalances Bala b.SubstractValue(amount) cd.MaxCostSoFar += amount inc.BalanceInfo.MoneyBalanceUuid = b.Uuid - inc.BalanceInfo.AccountId = ub.ID + inc.BalanceInfo.MoneyBalanceValue = b.Value + inc.BalanceInfo.AccountID = ub.ID if b.RatingSubject != "" { inc.BalanceInfo.RateInterval = ts.RateInterval } diff --git a/engine/calldesc.go b/engine/calldesc.go index d45312e01..b82772bb5 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -783,23 +783,23 @@ func (cd *CallDescriptor) RefundIncrements() error { accMap := make(utils.StringMap) cd.Increments.Decompress() for _, increment := range cd.Increments { - accMap[increment.BalanceInfo.AccountId] = true + accMap[increment.BalanceInfo.AccountID] = true } // start increment refunding loop _, err := Guardian.Guard(func() (interface{}, error) { accountsCache := make(map[string]*Account) for _, increment := range cd.Increments { - account, found := accountsCache[increment.BalanceInfo.AccountId] + account, found := accountsCache[increment.BalanceInfo.AccountID] if !found { - if acc, err := accountingStorage.GetAccount(increment.BalanceInfo.AccountId); err == nil && acc != nil { + if acc, err := accountingStorage.GetAccount(increment.BalanceInfo.AccountID); err == nil && acc != nil { account = acc - accountsCache[increment.BalanceInfo.AccountId] = account + accountsCache[increment.BalanceInfo.AccountID] = account // will save the account only once at the end of the function defer accountingStorage.SetAccount(account) } } if account == nil { - utils.Logger.Warning(fmt.Sprintf("Could not get the account to be refunded: %s", increment.BalanceInfo.AccountId)) + utils.Logger.Warning(fmt.Sprintf("Could not get the account to be refunded: %s", increment.BalanceInfo.AccountID)) continue } //utils.Logger.Info(fmt.Sprintf("Refunding increment %+v", increment)) @@ -832,23 +832,23 @@ func (cd *CallDescriptor) RefundRounding() error { // all must be locked in order to use cache accMap := make(utils.StringMap) for _, inc := range cd.Increments { - accMap[inc.BalanceInfo.AccountId] = true + accMap[inc.BalanceInfo.AccountID] = true } // start increment refunding loop _, err := Guardian.Guard(func() (interface{}, error) { accountsCache := make(map[string]*Account) for _, increment := range cd.Increments { - account, found := accountsCache[increment.BalanceInfo.AccountId] + account, found := accountsCache[increment.BalanceInfo.AccountID] if !found { - if acc, err := accountingStorage.GetAccount(increment.BalanceInfo.AccountId); err == nil && acc != nil { + if acc, err := accountingStorage.GetAccount(increment.BalanceInfo.AccountID); err == nil && acc != nil { account = acc - accountsCache[increment.BalanceInfo.AccountId] = account + accountsCache[increment.BalanceInfo.AccountID] = account // will save the account only once at the end of the function defer accountingStorage.SetAccount(account) } } if account == nil { - utils.Logger.Warning(fmt.Sprintf("Could not get the account to be refunded: %s", increment.BalanceInfo.AccountId)) + utils.Logger.Warning(fmt.Sprintf("Could not get the account to be refunded: %s", increment.BalanceInfo.AccountID)) continue } cc := cd.CreateCallCost() diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go index 49b6cc26a..c6f92e450 100644 --- a/engine/calldesc_test.go +++ b/engine/calldesc_test.go @@ -1096,15 +1096,16 @@ func TestDebitAndMaxDebit(t *testing.T) { if err1 != nil || err2 != nil { t.Error("Error debiting and/or maxdebiting: ", err1, err2) } + if cc1.Timespans[0].Increments[0].BalanceInfo.UnitBalanceValue != 90 || + cc2.Timespans[0].Increments[0].BalanceInfo.UnitBalanceValue != 80 { + t.Error("Error setting the UnitBalanceValue: ", cc1.Timespans[0].Increments[0].BalanceInfo.UnitBalanceValue, cc2.Timespans[0].Increments[0].BalanceInfo.UnitBalanceValue) + } + // make UnitBalanceValues have the same value + cc1.Timespans[0].Increments[0].BalanceInfo.UnitBalanceValue = 0 + cc2.Timespans[0].Increments[0].BalanceInfo.UnitBalanceValue = 0 if !reflect.DeepEqual(cc1, cc2) { - t.Logf("CC1: %+v", cc1) - for _, ts := range cc1.Timespans { - t.Logf("TS: %+v", ts) - } - t.Logf("CC2: %+v", cc2) - for _, ts := range cc2.Timespans { - t.Logf("TS: %+v", ts) - } + t.Log("CC1: ", utils.ToIJSON(cc1)) + t.Log("CC2: ", utils.ToIJSON(cc2)) t.Error("Debit and MaxDebit differ") } } @@ -1454,9 +1455,9 @@ func TestCDRefundIncrements(t *testing.T) { } accountingStorage.SetAccount(ub) increments := Increments{ - &Increment{Cost: 2, BalanceInfo: &BalanceInfo{UnitBalanceUuid: "", MoneyBalanceUuid: "moneya", AccountId: ub.ID}}, - &Increment{Cost: 2, Duration: 3 * time.Second, BalanceInfo: &BalanceInfo{UnitBalanceUuid: "minutea", MoneyBalanceUuid: "moneya", AccountId: ub.ID}}, - &Increment{Duration: 4 * time.Second, BalanceInfo: &BalanceInfo{UnitBalanceUuid: "minuteb", MoneyBalanceUuid: "", AccountId: ub.ID}}, + &Increment{Cost: 2, BalanceInfo: &BalanceInfo{UnitBalanceUuid: "", MoneyBalanceUuid: "moneya", AccountID: ub.ID}}, + &Increment{Cost: 2, Duration: 3 * time.Second, BalanceInfo: &BalanceInfo{UnitBalanceUuid: "minutea", MoneyBalanceUuid: "moneya", AccountID: ub.ID}}, + &Increment{Duration: 4 * time.Second, BalanceInfo: &BalanceInfo{UnitBalanceUuid: "minuteb", MoneyBalanceUuid: "", AccountID: ub.ID}}, } cd := &CallDescriptor{TOR: utils.VOICE, Increments: increments} cd.RefundIncrements() diff --git a/engine/timespans.go b/engine/timespans.go index 34aec558b..c8532fe2e 100644 --- a/engine/timespans.go +++ b/engine/timespans.go @@ -67,17 +67,19 @@ func (mi *UnitInfo) Equal(other *UnitInfo) bool { // Holds information about the balance that made a specific payment type BalanceInfo struct { - UnitBalanceUuid string - MoneyBalanceUuid string - RateInterval *RateInterval - AccountId string // used when debited from shared balance + UnitBalanceUuid string + MoneyBalanceUuid string + UnitBalanceValue float64 + MoneyBalanceValue float64 + RateInterval *RateInterval + AccountID string // used when debited from shared balance } func (bi *BalanceInfo) Equal(other *BalanceInfo) bool { return bi.UnitBalanceUuid == other.UnitBalanceUuid && bi.MoneyBalanceUuid == other.MoneyBalanceUuid && reflect.DeepEqual(bi.RateInterval, other.RateInterval) && - bi.AccountId == other.AccountId + bi.AccountID == other.AccountID } type TimeSpans []*TimeSpan @@ -260,6 +262,10 @@ func (incs *Increments) Compress() { // must be pointer receiver cIncrs = append(cIncrs, incr) } else { cIncrs[len(cIncrs)-1].CompressFactor++ + if cIncrs[len(cIncrs)-1].BalanceInfo != nil && incr.BalanceInfo != nil { + cIncrs[len(cIncrs)-1].BalanceInfo.MoneyBalanceValue = incr.BalanceInfo.MoneyBalanceValue + cIncrs[len(cIncrs)-1].BalanceInfo.UnitBalanceValue = incr.BalanceInfo.UnitBalanceValue + } } } *incs = cIncrs diff --git a/engine/timespans_test.go b/engine/timespans_test.go index b797dff86..cd96c37fa 100644 --- a/engine/timespans_test.go +++ b/engine/timespans_test.go @@ -1510,34 +1510,54 @@ func TestTSIncrementsCompressDecompress(t *testing.T) { &TimeSpan{ Increments: Increments{ &Increment{ - Duration: time.Minute, - Cost: 10.4, - BalanceInfo: &BalanceInfo{"1", "2", &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, "3"}, - UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, + Duration: time.Minute, + Cost: 10.4, + BalanceInfo: &BalanceInfo{ + UnitBalanceUuid: "1", + MoneyBalanceUuid: "2", + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + AccountID: "3"}, + UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, }, &Increment{ - Duration: time.Minute, - Cost: 10.4, - BalanceInfo: &BalanceInfo{"1", "2", &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, "3"}, - UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, + Duration: time.Minute, + Cost: 10.4, + BalanceInfo: &BalanceInfo{ + UnitBalanceUuid: "1", + MoneyBalanceUuid: "2", + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + AccountID: "3"}, + UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, }, &Increment{ - Duration: time.Minute, - Cost: 10.4, - BalanceInfo: &BalanceInfo{"1", "2", &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, "3"}, - UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, + Duration: time.Minute, + Cost: 10.4, + BalanceInfo: &BalanceInfo{ + UnitBalanceUuid: "1", + MoneyBalanceUuid: "2", + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + AccountID: "3"}, + UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, }, &Increment{ - Duration: time.Minute, - Cost: 10.4, - BalanceInfo: &BalanceInfo{"1", "2", &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 1111 * time.Second, RateUnit: time.Second}}}}, "3"}, - UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, + Duration: time.Minute, + Cost: 10.4, + BalanceInfo: &BalanceInfo{ + UnitBalanceUuid: "1", + MoneyBalanceUuid: "2", + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 1111 * time.Second, RateUnit: time.Second}}}}, + AccountID: "3"}, + UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, }, &Increment{ - Duration: time.Minute, - Cost: 10.4, - BalanceInfo: &BalanceInfo{"1", "2", &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, "3"}, - UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, + Duration: time.Minute, + Cost: 10.4, + BalanceInfo: &BalanceInfo{ + UnitBalanceUuid: "1", + MoneyBalanceUuid: "2", + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + AccountID: "3"}, + UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, }, }, }, @@ -1557,34 +1577,54 @@ func TestTSMultipleIncrementsCompressDecompress(t *testing.T) { &TimeSpan{ Increments: Increments{ &Increment{ - Duration: time.Minute, - Cost: 10.4, - BalanceInfo: &BalanceInfo{"1", "2", &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, "3"}, - UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, + Duration: time.Minute, + Cost: 10.4, + BalanceInfo: &BalanceInfo{ + UnitBalanceUuid: "1", + MoneyBalanceUuid: "2", + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + AccountID: "3"}, + UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, }, &Increment{ - Duration: time.Minute, - Cost: 10.4, - BalanceInfo: &BalanceInfo{"1", "2", &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, "3"}, - UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, + Duration: time.Minute, + Cost: 10.4, + BalanceInfo: &BalanceInfo{ + UnitBalanceUuid: "1", + MoneyBalanceUuid: "2", + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + AccountID: "3"}, + UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, }, &Increment{ - Duration: time.Minute, - Cost: 10.4, - BalanceInfo: &BalanceInfo{"1", "2", &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, "3"}, - UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, + Duration: time.Minute, + Cost: 10.4, + BalanceInfo: &BalanceInfo{ + UnitBalanceUuid: "1", + MoneyBalanceUuid: "2", + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + AccountID: "3"}, + UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, }, &Increment{ - Duration: time.Minute, - Cost: 10.4, - BalanceInfo: &BalanceInfo{"1", "2", &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 1111 * time.Second, RateUnit: time.Second}}}}, "3"}, - UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, + Duration: time.Minute, + Cost: 10.4, + BalanceInfo: &BalanceInfo{ + UnitBalanceUuid: "1", + MoneyBalanceUuid: "2", + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 1111 * time.Second, RateUnit: time.Second}}}}, + AccountID: "3"}, + UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, }, &Increment{ - Duration: time.Minute, - Cost: 10.4, - BalanceInfo: &BalanceInfo{"1", "2", &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, "3"}, - UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, + Duration: time.Minute, + Cost: 10.4, + BalanceInfo: &BalanceInfo{ + UnitBalanceUuid: "1", + MoneyBalanceUuid: "2", + RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, + AccountID: "3"}, + UnitInfo: &UnitInfo{"1", 2.3, utils.VOICE}, }, }, },