Add BalanceFactor value to Increments

For both the Increment and ChargingIncrement types.
This commit is contained in:
ionutboangiu
2024-03-27 18:25:06 +02:00
committed by Dan Christian Bogos
parent 22fb6236b1
commit a7ca167039
9 changed files with 70 additions and 13 deletions

View File

@@ -918,6 +918,7 @@ func (b *Balance) debit(cd *CallDescriptor, ub *Account, moneyBalances Balances,
Value: b.Value,
DestinationID: cc.Destination,
Consumed: amount,
Factor: bFactor,
Category: cd.Category,
ToR: tor,
RateInterval: nil,
@@ -1088,6 +1089,7 @@ func (b *Balance) debit(cd *CallDescriptor, ub *Account, moneyBalances Balances,
Value: b.Value,
DestinationID: cc.Destination,
Consumed: amount,
Factor: bFactor,
Category: cc.Category,
ToR: cc.ToR,
RateInterval: ts.RateInterval,

View File

@@ -877,8 +877,9 @@ func (cd *CallDescriptor) refundIncrements(fltrS *FilterS) (acnt *Account, err e
utils.Logger.Warning(fmt.Sprintf("Could not get the balnce: <%s> to be refunded for account: <%s>", increment.BalanceInfo.Unit.UUID, increment.BalanceInfo.AccountID))
continue
}
balance.AddValue(float64(increment.Duration.Nanoseconds()))
account.countUnits(-float64(increment.Duration.Nanoseconds()), unitType, cc, balance, fltrS)
refundAmount := float64(increment.Duration.Nanoseconds()) * increment.BalanceInfo.Unit.Factor
balance.AddValue(refundAmount)
account.countUnits(-refundAmount, unitType, cc, balance, fltrS)
}
// check money too
if increment.BalanceInfo.Monetary != nil && increment.BalanceInfo.Monetary.UUID != "" {

View File

@@ -1652,13 +1652,39 @@ func TestCDRefundIncrements(t *testing.T) {
}
dm.SetAccount(ub)
increments := Increments{
&Increment{Cost: 2, BalanceInfo: &DebitInfo{
Monetary: &MonetaryInfo{UUID: "moneya"}, AccountID: ub.ID}},
&Increment{Cost: 2, Duration: 3 * time.Second, BalanceInfo: &DebitInfo{
Unit: &UnitInfo{UUID: "minutea"},
Monetary: &MonetaryInfo{UUID: "moneya"}, AccountID: ub.ID}},
&Increment{Duration: 4 * time.Second, BalanceInfo: &DebitInfo{
Unit: &UnitInfo{UUID: "minuteb"}, AccountID: ub.ID}},
&Increment{
Cost: 2,
BalanceInfo: &DebitInfo{
Monetary: &MonetaryInfo{
UUID: "moneya",
},
AccountID: ub.ID,
},
},
&Increment{
Cost: 2,
Duration: 3 * time.Second,
BalanceInfo: &DebitInfo{
Unit: &UnitInfo{
UUID: "minutea",
Factor: 1,
},
Monetary: &MonetaryInfo{
UUID: "moneya",
},
AccountID: ub.ID,
},
},
&Increment{
Duration: 4 * time.Second,
BalanceInfo: &DebitInfo{
Unit: &UnitInfo{
UUID: "minuteb",
Factor: 1,
},
AccountID: ub.ID,
},
},
}
cd := &CallDescriptor{ToR: utils.MetaVoice, Increments: increments}
cd.RefundIncrements(nil)

View File

@@ -81,6 +81,7 @@ func (ec *EventCost) newChargingIncrement(incr *Increment, rf RatingMatchedFilte
cIt = &ChargingIncrement{
Usage: incr.Duration,
Cost: incr.Cost,
BalanceFactor: 1,
CompressFactor: incr.CompressFactor,
}
if incr.BalanceInfo == nil {
@@ -92,6 +93,7 @@ func (ec *EventCost) newChargingIncrement(incr *Increment, rf RatingMatchedFilte
rateID := utils.MetaRounding
//AccountingID
if incr.BalanceInfo.Unit != nil {
cIt.BalanceFactor = incr.BalanceInfo.Unit.Factor
// 2 balances work-around
ecUUID := utils.MetaNone // populate no matter what due to Unit not nil
if incr.BalanceInfo.Monetary != nil {
@@ -374,7 +376,10 @@ func (ec *EventCost) AsRefundIncrements(tor string) (cd *CallDescriptor) {
if blncSmry.Type == utils.MetaMonetary {
cd.Increments[iIdx].BalanceInfo.Monetary = &MonetaryInfo{UUID: blncSmry.UUID}
} else if utils.NonMonetaryBalances.Has(blncSmry.Type) {
cd.Increments[iIdx].BalanceInfo.Unit = &UnitInfo{UUID: blncSmry.UUID}
cd.Increments[iIdx].BalanceInfo.Unit = &UnitInfo{
UUID: blncSmry.UUID,
Factor: cIcrm.BalanceFactor,
}
}
if ec.Accounting[cIcrm.AccountingID].ExtraChargeID == utils.MetaNone ||
ec.Accounting[cIcrm.AccountingID].ExtraChargeID == utils.EmptyString {
@@ -387,7 +392,10 @@ func (ec *EventCost) AsRefundIncrements(tor string) (cd *CallDescriptor) {
if extraSmry.Type == utils.MetaMonetary {
cd.Increments[iIdx].BalanceInfo.Monetary = &MonetaryInfo{UUID: extraSmry.UUID}
} else if utils.NonMonetaryBalances.Has(blncSmry.Type) {
cd.Increments[iIdx].BalanceInfo.Unit = &UnitInfo{UUID: extraSmry.UUID}
cd.Increments[iIdx].BalanceInfo.Unit = &UnitInfo{
UUID: extraSmry.UUID,
Factor: cIcrm.BalanceFactor,
}
}
}
iIdx++
@@ -478,7 +486,11 @@ func (ec *EventCost) newIntervalFromCharge(cInc *ChargingIncrement) (incr *Incre
if cBC.ExtraChargeID != "" { // have both monetary and data
// Work around, enforce logic with 2 balances for *voice/*monetary combination
// so we can stay compatible with CallCost
incr.BalanceInfo.Unit = &UnitInfo{UUID: cBC.BalanceUUID, Consumed: cBC.Units}
incr.BalanceInfo.Unit = &UnitInfo{
UUID: cBC.BalanceUUID,
Consumed: cBC.Units,
Factor: cInc.BalanceFactor,
}
incr.BalanceInfo.Unit.RateInterval = ec.rateIntervalForRatingID(cBC.RatingID)
if cBC.ExtraChargeID != utils.MetaNone {
cBC = ec.Accounting[cBC.ExtraChargeID] // overwrite original balance so we can process it in one place

View File

@@ -520,22 +520,26 @@ func TestNewEventCostFromCallCost(t *testing.T) {
{
Usage: 0,
Cost: 0.1,
BalanceFactor: 1,
AccountingID: "44e97dec-8a7e-43d0-8b0a-736d46b5613e",
CompressFactor: 1,
},
{
Usage: time.Second,
Cost: 0,
BalanceFactor: 1,
AccountingID: "a555cde8-4bd0-408a-afbc-c3ba64888927",
CompressFactor: 30,
},
{
Usage: time.Second,
Cost: 0.005,
BalanceFactor: 1,
AccountingID: "906bfd0f-035c-40a3-93a8-46f71627983e",
CompressFactor: 30,
},
{
BalanceFactor: 1,
Cost: -0.1,
AccountingID: "44e97dec-8a7e-43d0-8b0a-e34a152",
CompressFactor: 1,
@@ -4141,6 +4145,7 @@ func TestECnewChargingIncrementMissingBalanceInfo(t *testing.T) {
Usage: incr.Duration,
Cost: incr.Cost,
CompressFactor: incr.CompressFactor,
BalanceFactor: 1,
}
rcv := ec.newChargingIncrement(incr, rf, false, false)
@@ -4190,6 +4195,7 @@ func TestECnewChargingIncrementNoUnitInfo(t *testing.T) {
Cost: incr.Cost,
CompressFactor: incr.CompressFactor,
AccountingID: utils.MetaPause,
BalanceFactor: 1,
}
expEC := &EventCost{
Accounting: Accounting{

View File

@@ -128,6 +128,7 @@ func (cIl *ChargingInterval) Clone() (cln *ChargingInterval) {
type ChargingIncrement struct {
Usage time.Duration
Cost float64
BalanceFactor float64
AccountingID string
CompressFactor int
}
@@ -135,6 +136,7 @@ type ChargingIncrement struct {
// Equals returns if the structure has the same value
func (cIt *ChargingIncrement) Equals(oCIt *ChargingIncrement) bool {
return cIt.Usage == oCIt.Usage &&
cIt.BalanceFactor == oCIt.BalanceFactor &&
cIt.Cost == oCIt.Cost &&
cIt.AccountingID == oCIt.AccountingID &&
cIt.CompressFactor == oCIt.CompressFactor
@@ -143,6 +145,7 @@ func (cIt *ChargingIncrement) Equals(oCIt *ChargingIncrement) bool {
// PartiallyEquals ignores the CompressFactor when comparing
func (cIt *ChargingIncrement) PartiallyEquals(oCIt *ChargingIncrement) bool {
return cIt.Usage == oCIt.Usage &&
cIt.BalanceFactor == oCIt.BalanceFactor &&
cIt.Cost == oCIt.Cost &&
cIt.AccountingID == oCIt.AccountingID
}
@@ -161,7 +164,7 @@ func (cIt *ChargingIncrement) TotalUsage() time.Duration {
// TotalCost returns the cost of the increment
func (cIt *ChargingIncrement) TotalCost() float64 {
return cIt.Cost * float64(cIt.CompressFactor)
return cIt.Cost * cIt.BalanceFactor * float64(cIt.CompressFactor)
}
// FieldAsInterface func to help EventCost FieldAsInterface
@@ -176,6 +179,8 @@ func (cIt *ChargingIncrement) FieldAsInterface(fldPath []string) (val any, err e
return cIt.Usage, nil
case utils.Cost:
return cIt.Cost, nil
case utils.BalanceFactor:
return cIt.BalanceFactor, nil
case utils.AccountingID:
return cIt.AccountingID, nil
case utils.CompressFactor:
@@ -636,6 +641,7 @@ func NewFreeEventCost(cgrID, runID, account string, tStart time.Time, usage time
Increments: []*ChargingIncrement{
{
Usage: usage,
BalanceFactor: 1,
AccountingID: utils.MetaPause,
CompressFactor: 1,
},

View File

@@ -404,6 +404,7 @@ func TestChargingIncrementTotalCost(t *testing.T) {
ch1 := &ChargingIncrement{
AccountingID: "Acc1",
CompressFactor: 2,
BalanceFactor: 1,
Cost: 2.345,
Usage: 2 * time.Second,
}

View File

@@ -108,6 +108,7 @@ type UnitInfo struct {
Value float64
DestinationID string
Consumed float64
Factor float64
Category string
ToR string
RateInterval *RateInterval
@@ -128,6 +129,7 @@ func (ui *UnitInfo) Equal(other *UnitInfo) bool {
return ui.UUID == other.UUID &&
ui.DestinationID == other.DestinationID &&
ui.Consumed == other.Consumed &&
ui.Factor == other.Factor &&
ui.ToR == other.ToR &&
ui.Category == other.Category &&
reflect.DeepEqual(ui.RateInterval, other.RateInterval)

View File

@@ -598,6 +598,7 @@ const (
TimingID = "TimingID"
RatesID = "RatesID"
RatingFiltersID = "RatingFiltersID"
BalanceFactor = "BalanceFactor"
AccountingID = "AccountingID"
MetaSessionS = "*sessions"
MetaDefault = "*default"