mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-19 22:28:45 +05:00
RateS computeRateSIntervals accepting usageStart
This commit is contained in:
@@ -236,3 +236,7 @@ func CostForIntervals(rtIvls []*RateSInterval) (cost *utils.Decimal) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// CompressIntervals will compress intervals which equal
|
||||
func CompressIntervals(rtIvls []*RateSInterval) {
|
||||
}
|
||||
|
||||
@@ -178,8 +178,7 @@ func orderRatesOnIntervals(aRts []*engine.Rate, sTime time.Time, usage time.Dura
|
||||
}
|
||||
|
||||
// computeRateSIntervals will give out the cost projection for the given orderedRates and usage
|
||||
func computeRateSIntervals(rts []*orderedRate, usage time.Duration) (rtIvls []*engine.RateSInterval, err error) {
|
||||
var rtUsageSIdx time.Duration // rtUsageSIdx for one rate
|
||||
func computeRateSIntervals(rts []*orderedRate, usageStart, usage time.Duration) (rtIvls []*engine.RateSInterval, err error) {
|
||||
for i, rt := range rts {
|
||||
isLastRt := i == len(rts)-1
|
||||
var rtUsageEIdx time.Duration
|
||||
@@ -189,7 +188,7 @@ func computeRateSIntervals(rts []*orderedRate, usage time.Duration) (rtIvls []*e
|
||||
rtUsageEIdx = usage
|
||||
}
|
||||
var rIcmts []*engine.RateSIncrement
|
||||
iRtUsageSIdx := rtUsageSIdx
|
||||
iRtUsageSIdx := usageStart
|
||||
iRtUsageEIdx := rtUsageEIdx
|
||||
for j, iRt := range rt.IntervalRates {
|
||||
if iRtUsageSIdx >= rtUsageEIdx { // charged enough for interval
|
||||
@@ -201,9 +200,10 @@ func computeRateSIntervals(rts []*orderedRate, usage time.Duration) (rtIvls []*e
|
||||
rt.UID(), iRtUsageSIdx)
|
||||
}
|
||||
isLastIRt := j == len(rt.IntervalRates)-1
|
||||
if iRt.IntervalStart > iRtUsageSIdx ||
|
||||
(!isLastIRt && rt.IntervalRates[j+1].IntervalStart <= iRtUsageSIdx) {
|
||||
break // the rates should be already ordered, break here
|
||||
if iRt.IntervalStart > iRtUsageSIdx {
|
||||
break
|
||||
} else if !isLastIRt && rt.IntervalRates[j+1].IntervalStart <= iRtUsageSIdx {
|
||||
continue // the rates should be already ordered, break here
|
||||
}
|
||||
if !isLastIRt {
|
||||
iRtUsageEIdx = rt.IntervalRates[j+1].IntervalStart
|
||||
@@ -236,13 +236,13 @@ func computeRateSIntervals(rts []*orderedRate, usage time.Duration) (rtIvls []*e
|
||||
}
|
||||
rtIvls = append(rtIvls,
|
||||
&engine.RateSInterval{
|
||||
UsageStart: rtUsageSIdx,
|
||||
UsageStart: usageStart,
|
||||
Increments: rIcmts,
|
||||
CompressFactor: 1})
|
||||
if iRtUsageSIdx >= usage { // charged enough for the usage
|
||||
break
|
||||
}
|
||||
rtUsageSIdx = rtUsageEIdx // continue for the next interval
|
||||
usageStart = rtUsageEIdx // continue for the next interval
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1669,9 +1669,63 @@ func TestComputeRateSIntervals(t *testing.T) {
|
||||
CompressFactor: 1,
|
||||
},
|
||||
}
|
||||
if rtIvls, err := computeRateSIntervals(rts, time.Duration(130*time.Second)); err != nil {
|
||||
if rtIvls, err := computeRateSIntervals(rts,
|
||||
time.Duration(0), time.Duration(130*time.Second)); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eRtIvls, rtIvls) {
|
||||
t.Errorf("expecting: %+v, received: %+v", eRtIvls, rtIvls)
|
||||
}
|
||||
|
||||
rts = []*orderedRate{
|
||||
{
|
||||
time.Duration(0),
|
||||
rt0,
|
||||
},
|
||||
{
|
||||
time.Duration(90 * time.Second),
|
||||
rt1,
|
||||
},
|
||||
}
|
||||
|
||||
eRtIvls = []*engine.RateSInterval{
|
||||
{
|
||||
UsageStart: time.Duration(time.Minute),
|
||||
Increments: []*engine.RateSIncrement{
|
||||
{
|
||||
UsageStart: time.Duration(time.Minute),
|
||||
Usage: time.Duration(30 * time.Second),
|
||||
Rate: rt0,
|
||||
IntervalRateIndex: 1,
|
||||
CompressFactor: 30,
|
||||
},
|
||||
},
|
||||
CompressFactor: 1,
|
||||
},
|
||||
{
|
||||
UsageStart: time.Duration(90 * time.Second),
|
||||
Increments: []*engine.RateSIncrement{
|
||||
{
|
||||
UsageStart: time.Duration(90 * time.Second),
|
||||
Usage: time.Duration(30 * time.Second),
|
||||
Rate: rt1,
|
||||
IntervalRateIndex: 0,
|
||||
CompressFactor: 30,
|
||||
},
|
||||
{
|
||||
UsageStart: time.Duration(2 * time.Minute),
|
||||
Usage: time.Duration(10 * time.Second),
|
||||
Rate: rt1,
|
||||
IntervalRateIndex: 1,
|
||||
CompressFactor: 10,
|
||||
},
|
||||
},
|
||||
CompressFactor: 1,
|
||||
},
|
||||
}
|
||||
if rtIvls, err := computeRateSIntervals(rts,
|
||||
time.Duration(time.Minute), time.Duration(130*time.Second)); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eRtIvls, rtIvls) {
|
||||
t.Errorf("expecting: %+v, received: %+v", utils.ToIJSON(eRtIvls), utils.ToIJSON(rtIvls))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,30 +133,43 @@ func (rS *RateS) matchingRateProfileForEvent(tnt string, args *ArgsCostForEvent,
|
||||
func (rS *RateS) rateProfileCostForEvent(rtPfl *engine.RateProfile, args *ArgsCostForEvent) (rts []*engine.RateSInterval, err error) {
|
||||
var rtIDs utils.StringSet
|
||||
if rtIDs, err = engine.MatchingItemIDsForEvent(
|
||||
args.CGRevent.Event,
|
||||
args.CGREventWithOpts.CGREvent.Event,
|
||||
rS.cfg.RateSCfg().RateStringIndexedFields,
|
||||
rS.cfg.RateSCfg().RatePrefixIndexedFields,
|
||||
rS.cfg.RateSCfg().RateSuffixIndexedFields,
|
||||
rS.dm,
|
||||
utils.CacheRateFilterIndexes,
|
||||
utils.ConcatenatedKey(args.CGRevent.Tenant, rtPfl.ID),
|
||||
utils.ConcatenatedKey(args.CGREventWithOpts.CGREvent.Tenant, rtPfl.ID),
|
||||
rS.cfg.RateSCfg().RateIndexedSelects,
|
||||
rS.cfg.RateSCfg().RateNestedFields,
|
||||
); err != nil {
|
||||
return
|
||||
}
|
||||
aRates := make([]*engine.Rate, len(rtIDs))
|
||||
evNm := utils.MapStorage{utils.MetaReq: cgrEv.Event}
|
||||
evNm := utils.MapStorage{utils.MetaReq: args.CGREventWithOpts.CGREvent.Event}
|
||||
for rtID := range rtIDs {
|
||||
rt := rtPfl.Rates[rtID] // pick the rate directly from map based on matched ID
|
||||
var pass bool
|
||||
if pass, err = rS.filterS.Pass(cgrEv.Tenant, rt.FilterIDs, evNm); err != nil {
|
||||
if pass, err = rS.filterS.Pass(args.CGREventWithOpts.CGREvent.Tenant, rt.FilterIDs, evNm); err != nil {
|
||||
return
|
||||
} else if !pass {
|
||||
continue
|
||||
}
|
||||
aRates = append(aRates, rt)
|
||||
}
|
||||
ordRts := orderRatesOnIntervals(aRates)
|
||||
var sTime time.Time
|
||||
if sTime, err = args.StartTime(rS.cfg.GeneralCfg().DefaultTimezone); err != nil {
|
||||
return
|
||||
}
|
||||
var usage time.Duration
|
||||
if usage, err = args.Usage(); err != nil {
|
||||
return
|
||||
}
|
||||
var ordRts []*orderedRate
|
||||
if ordRts, err = orderRatesOnIntervals(aRates, sTime, usage, true, 1000000); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
*/
|
||||
@@ -191,6 +204,19 @@ func (args *ArgsCostForEvent) StartTime(tmz string) (sTime time.Time, err error)
|
||||
return time.Now(), nil
|
||||
}
|
||||
|
||||
// usage returns the event time used to check active rate profiles
|
||||
func (args *ArgsCostForEvent) Usage() (usage time.Duration, err error) {
|
||||
if uIface, has := args.Opts[utils.OptsRatesUsage]; has {
|
||||
return utils.IfaceAsDuration(uIface)
|
||||
}
|
||||
if usage, err = args.CGREvent.FieldAsDuration(utils.Usage); err != nil {
|
||||
if err != utils.ErrNotFound {
|
||||
return
|
||||
}
|
||||
}
|
||||
return time.Duration(time.Minute), nil
|
||||
}
|
||||
|
||||
// V1CostForEvent will be called to calculate the cost for an event
|
||||
func (rS *RateS) V1CostForEvent(args *ArgsCostForEvent, cC *utils.ChargedCost) (err error) {
|
||||
return
|
||||
|
||||
@@ -2343,7 +2343,7 @@ var (
|
||||
)
|
||||
|
||||
// CGROptionsSet the possible cgr options
|
||||
var CGROptionsSet = NewStringSet([]string{OptsRatesStartTime, OptsSessionTTL, OptsSessionTTLMaxDelay,
|
||||
var CGROptionsSet = NewStringSet([]string{OptsRatesStartTime, OptsRatesUsage, OptsSessionTTL, OptsSessionTTLMaxDelay,
|
||||
OptsSessionTTLLastUsed, OptsSessionTTLLastUsage, OptsSessionTTLUsage, OptsDebitInterval, OptsStirATest,
|
||||
OptsStirPayloadMaxDuration, OptsStirIdentity, OptsStirOriginatorTn, OptsStirOriginatorURI,
|
||||
OptsStirDestinationTn, OptsStirDestinationURI, OptsStirPublicKeyPath, OptsStirPrivateKeyPath,
|
||||
@@ -2372,6 +2372,7 @@ const (
|
||||
OptsRoutesLimit = "*routes_limit"
|
||||
OptsRoutesOffset = "*routes_offset"
|
||||
OptsRatesStartTime = "*ratesStartTime"
|
||||
OptsRatesUsage = "*ratesUsage"
|
||||
OptsSessionTTL = "*sessionTTL"
|
||||
OptsSessionTTLMaxDelay = "*sessionTTLMaxDelay"
|
||||
OptsSessionTTLLastUsed = "*sessionTTLLastUsed"
|
||||
|
||||
Reference in New Issue
Block a user