From fb5890ae635334557748ee04cc9bd7574ee0362c Mon Sep 17 00:00:00 2001 From: porosnicuadrian Date: Wed, 12 May 2021 16:59:45 +0300 Subject: [PATCH] Modified Rates field in RateProfileCost + Equals/As methods --- rates/librates.go | 20 +++++-- rates/rates.go | 20 +------ utils/eventcharges.go | 35 ++++++++---- utils/librates.go | 120 ++++++++++++++++++++++++++---------------- 4 files changed, 118 insertions(+), 77 deletions(-) diff --git a/rates/librates.go b/rates/librates.go index 0da12a1dc..920e7eea4 100644 --- a/rates/librates.go +++ b/rates/librates.go @@ -190,8 +190,20 @@ func orderRatesOnIntervals(aRts []*utils.Rate, wghts []float64, sTime time.Time, return } +func getRateIntervalIDFromIncrement(cstRts map[string]*utils.IntervalRate, intRt *utils.IntervalRate) string { + for key, val := range cstRts { + if val.Equals(intRt) { + return key + } + } + key := utils.UUIDSha1Prefix() + cstRts[key] = intRt + return key +} + // computeRateSIntervals will give out the cost projection for the given orderedRates and usage -func computeRateSIntervals(rts []*orderedRate, intervalStart, usage *decimal.Big) (rtIvls []*utils.RateSInterval, err error) { +func computeRateSIntervals(rts []*orderedRate, intervalStart, usage *decimal.Big, + cstRts map[string]*utils.IntervalRate) (rtIvls []*utils.RateSInterval, err error) { totalUsage := usage if intervalStart.Cmp(decimal.New(0, 0)) != 0 { totalUsage = utils.SumBig(usage, intervalStart) @@ -229,7 +241,7 @@ func computeRateSIntervals(rts []*orderedRate, intervalStart, usage *decimal.Big rIcmts = append(rIcmts, &utils.RateSIncrement{ IncrementStart: &utils.Decimal{iRtUsageSIdx}, IntervalRateIndex: j, - RateID: rt.ID, + RateID: getRateIntervalIDFromIncrement(cstRts, rt.IntervalRates[j]), CompressFactor: 1, Usage: utils.NewDecimal(utils.InvalidUsage, 0), }) @@ -258,9 +270,9 @@ func computeRateSIntervals(rts []*orderedRate, intervalStart, usage *decimal.Big } rIcmts = append(rIcmts, &utils.RateSIncrement{ IncrementStart: &utils.Decimal{iRtUsageSIdx}, - IntervalRateIndex: j, - RateID: rt.ID, + RateID: getRateIntervalIDFromIncrement(cstRts, rt.IntervalRates[j]), CompressFactor: cmpFactorInt, + IntervalRateIndex: j, Usage: &utils.Decimal{iRtUsage}, }) iRtUsageSIdx = utils.SumBig(iRtUsageSIdx, iRtUsage) diff --git a/rates/rates.go b/rates/rates.go index fc4b124d9..5fad2b40f 100644 --- a/rates/rates.go +++ b/rates/rates.go @@ -195,26 +195,10 @@ func (rS *RateS) rateProfileCostForEvent(ctx *context.Context, rtPfl *utils.Rate if ivalStart, err = args.IntervalStart(); err != nil { return } - rpCost.Rates = make(map[string]*utils.Rate) - for _, val := range ordRts { - //rpCost.Rates[utils.UUIDSha1Prefix()] = val.Rate - rpCost.Rates[val.Rate.ID] = val.Rate - } - if rpCost.RateSIntervals, err = computeRateSIntervals(ordRts, ivalStart, usage); err != nil { + rpCost.Rates = make(map[string]*utils.IntervalRate) + if rpCost.RateSIntervals, err = computeRateSIntervals(ordRts, ivalStart, usage, rpCost.Rates); err != nil { return nil, err } - /* - for key, rt := range rpCost.Rates { - for _, intvl := range rpCost.RateSIntervals { - for _, incr := range intvl.Increments { - if incr.RateID == rt.ID { - incr.RateID = key - } - } - } - } - - */ // in case we have error it is returned in the function from above // this came to light in coverage tests rpCst, err := utils.CostForIntervals(rpCost.RateSIntervals, rpCost.Rates) diff --git a/utils/eventcharges.go b/utils/eventcharges.go index 90c4cc42b..dac09fb75 100644 --- a/utils/eventcharges.go +++ b/utils/eventcharges.go @@ -124,7 +124,7 @@ func (ec *EventCharges) SyncIDs(eCs ...*EventCharges) { // Rating if nEcAcntChrg.RatingID != EmptyString { - if rtID := ec.ratingID(nEc.Rating[nEcAcntChrg.RatingID]); rtID != EmptyString && + if rtID := ec.ratingID(nEc.Rating[nEcAcntChrg.RatingID], nEc.IntervalRates); rtID != EmptyString && rtID != nEcAcntChrg.RatingID { nEc.Rating[rtID] = ec.Rating[rtID] delete(nEc.Rating, nEcAcntChrg.RatingID) @@ -206,6 +206,16 @@ func (ec *EventCharges) AsExtEventCharges() (eEc *ExtEventCharges, err error) { } } } + if ec.IntervalRates != nil { + eEc.IntervalRates = make(map[string]*ExtIntervalRate, len(ec.IntervalRates)) + for key, val := range ec.IntervalRates { + if extIntRate, err := val.AsExtIntervalRate(); err != nil { + return nil, err + } else { + eEc.IntervalRates[key] = extIntRate + } + } + } if ec.Accounts != nil { eEc.Accounts = make(map[string]*ExtAccount, len(ec.Accounts)) for acntID, acnt := range ec.Accounts { @@ -239,6 +249,9 @@ func (eEc *ExtEventCharges) Equals(exCh *ExtEventCharges) (eq bool) { (eEc.Rating == nil && exCh.Rating != nil || eEc.Rating != nil && exCh.Rating == nil || len(eEc.Rating) != len(exCh.Rating)) || + (eEc.IntervalRates == nil && exCh.IntervalRates != nil || + eEc.IntervalRates != nil && exCh.IntervalRates == nil || + len(eEc.IntervalRates) != len(exCh.IntervalRates)) || (eEc.Accounts == nil && exCh.Accounts != nil || eEc.Accounts != nil && exCh.Accounts == nil || len(eEc.Accounts) != len(exCh.Accounts)) { @@ -260,7 +273,7 @@ func (eEc *ExtEventCharges) Equals(exCh *ExtEventCharges) (eq bool) { } } for key, val := range eEc.Rating { - if ok := val.Equals(exCh.Rating[key]); !ok { + if ok := val.Equals(exCh.Rating[key], eEc.IntervalRates, exCh.IntervalRates); !ok { return } } @@ -294,6 +307,9 @@ func (eC *EventCharges) Equals(evCh *EventCharges) (eq bool) { (eC.Rating == nil && evCh.Rating != nil || eC.Rating != nil && evCh.Rating == nil || len(eC.Rating) != len(evCh.Rating)) || + (eC.IntervalRates == nil && evCh.IntervalRates != nil || + eC.IntervalRates != nil && evCh.IntervalRates == nil || + len(eC.IntervalRates) != len(evCh.IntervalRates)) || (eC.Accounts == nil && evCh.Accounts != nil || eC.Accounts != nil && evCh.Accounts == nil || len(eC.Accounts) != len(evCh.Accounts)) { @@ -315,7 +331,7 @@ func (eC *EventCharges) Equals(evCh *EventCharges) (eq bool) { } } for key, val := range eC.Rating { - if ok := val.Equals(evCh.Rating[key]); !ok { + if ok := val.Equals(evCh.Rating[key], eC.IntervalRates, evCh.IntervalRates); !ok { return } } @@ -338,9 +354,9 @@ func (ec *EventCharges) unitFactorID(uF *UnitFactor) (ufID string) { } // ratingID returns the ID of the matching RateSInterval within ec.Rating -func (ec *EventCharges) ratingID(rIl *RateSInterval) (rID string) { +func (ec *EventCharges) ratingID(rIl *RateSInterval, nIrRef map[string]*IntervalRate) (rID string) { for ecID, ecRtIl := range ec.Rating { - if ecRtIl.Equals(rIl) { + if ecRtIl.Equals(rIl, ec.IntervalRates, nIrRef) { return ecID } } @@ -364,10 +380,11 @@ type ExtEventCharges struct { Charges []*ChargeEntry - Accounting map[string]*ExtAccountCharge - UnitFactors map[string]*ExtUnitFactor - Rating map[string]*ExtRateSInterval - Accounts map[string]*ExtAccount + Accounting map[string]*ExtAccountCharge + UnitFactors map[string]*ExtUnitFactor + Rating map[string]*ExtRateSInterval + IntervalRates map[string]*ExtIntervalRate + Accounts map[string]*ExtAccount } type ExtChargingIncrement struct { diff --git a/utils/librates.go b/utils/librates.go index 19a9d874d..5adead759 100644 --- a/utils/librates.go +++ b/utils/librates.go @@ -266,16 +266,18 @@ func (eIr *ExtIntervalRate) Equals(extIr *ExtIntervalRate) (eq bool) { // Equals returns the equality between two IntervalRate func (iR *IntervalRate) Equals(inRt *IntervalRate) (eq bool) { - if iR.RecurrentFee == nil && inRt.RecurrentFee != nil || - iR.RecurrentFee != nil && inRt.RecurrentFee == nil || - iR.FixedFee == nil && inRt.FixedFee != nil || - iR.FixedFee != nil && inRt.FixedFee == nil || - iR.Increment == nil && inRt.Increment != nil || - iR.Increment != nil && inRt.Increment == nil || - iR.Unit == nil && inRt.Unit != nil || - iR.Unit != nil && inRt.Unit == nil || - iR.IntervalStart == nil && inRt.IntervalStart != nil || - iR.IntervalStart != nil && inRt.IntervalStart == nil { + if ((iR != nil || inRt != nil) && + (iR == nil || inRt == nil)) || + (iR.RecurrentFee == nil && inRt.RecurrentFee != nil) || + (iR.RecurrentFee != nil && inRt.RecurrentFee == nil) || + (iR.FixedFee == nil && inRt.FixedFee != nil) || + (iR.FixedFee != nil && inRt.FixedFee == nil) || + (iR.Increment == nil && inRt.Increment != nil) || + (iR.Increment != nil && inRt.Increment == nil) || + (iR.Unit == nil && inRt.Unit != nil) || + (iR.Unit != nil && inRt.Unit == nil) || + (iR.IntervalStart == nil && inRt.IntervalStart != nil) || + (iR.IntervalStart != nil && inRt.IntervalStart == nil) { return } if iR.RecurrentFee != nil && inRt.RecurrentFee != nil && @@ -392,7 +394,7 @@ func (rI *RateSInterval) AsExtRateSInterval() (eRi *ExtRateSInterval, err error) } // Equals compares two ExtRateSInterval -func (rIl *ExtRateSInterval) Equals(nRil *ExtRateSInterval) (eq bool) { +func (rIl *ExtRateSInterval) Equals(nRil *ExtRateSInterval, exInRt, exInRtRef map[string]*ExtIntervalRate) (eq bool) { if !((rIl.IntervalStart == nil && nRil.IntervalStart == nil) || (rIl.IntervalStart != nil && nRil.IntervalStart != nil && *rIl.IntervalStart == *nRil.IntervalStart)) || (rIl.Increments == nil && nRil.Increments != nil || @@ -402,7 +404,7 @@ func (rIl *ExtRateSInterval) Equals(nRil *ExtRateSInterval) (eq bool) { return } for i, rtIn := range rIl.Increments { - if !rtIn.Equals(nRil.Increments[i]) { + if !rtIn.Equals(nRil.Increments[i], exInRt, exInRtRef) { return } } @@ -422,6 +424,7 @@ type RateSIncrement struct { type ExtRateSIncrement struct { IncrementStart *float64 IntervalRateIndex int + RateID string CompressFactor int64 Usage *float64 @@ -433,6 +436,7 @@ func (rI *RateSIncrement) AsExtRateSIncrement() (eRi *ExtRateSIncrement, err err eRi = &ExtRateSIncrement{ IntervalRateIndex: rI.IntervalRateIndex, CompressFactor: rI.CompressFactor, + RateID: rI.RateID, } if rI.IncrementStart != nil { if fltIncrStart, ok := rI.IncrementStart.Big.Float64(); !ok { @@ -459,19 +463,18 @@ func (rI *RateSIncrement) AsExtRateSIncrement() (eRi *ExtRateSIncrement, err err } // Equals returns the equality between twoExt RateSIncrement -func (eRI *ExtRateSIncrement) Equals(extRI *ExtRateSIncrement) (eq bool) { - if !((eRI.Usage == nil && extRI.Usage == nil) || - (eRI.Usage != nil && extRI.Usage != nil && *eRI.Usage == *extRI.Usage)) || - !((eRI.IncrementStart == nil && extRI.IncrementStart == nil) || - (eRI.IncrementStart != nil && extRI.IncrementStart != nil && *eRI.IncrementStart == *extRI.IncrementStart)) { - return - } - return eRI.CompressFactor == extRI.CompressFactor && - eRI.IntervalRateIndex == extRI.IntervalRateIndex +func (eRI *ExtRateSIncrement) Equals(extRI *ExtRateSIncrement, exInRt, exInRtRef map[string]*ExtIntervalRate) (eq bool) { + return ((eRI.Usage == nil && extRI.Usage == nil) || + (eRI.Usage != nil && extRI.Usage != nil && *eRI.Usage == *extRI.Usage)) && + ((eRI.IncrementStart == nil && extRI.IncrementStart == nil) || + (eRI.IncrementStart != nil && extRI.IncrementStart != nil && *eRI.IncrementStart == *extRI.IncrementStart)) && + (eRI.CompressFactor == extRI.CompressFactor) && + (eRI.IntervalRateIndex == extRI.IntervalRateIndex) && + exInRt[eRI.RateID].Equals(exInRtRef[extRI.RateID]) } // Equals compares two RateSIntervals -func (rIl *RateSInterval) Equals(nRil *RateSInterval) (eq bool) { +func (rIl *RateSInterval) Equals(nRil *RateSInterval, rIlRef, nRilRef map[string]*IntervalRate) (eq bool) { if rIl.IntervalStart == nil && nRil.IntervalStart != nil || rIl.IntervalStart != nil && nRil.IntervalStart == nil || (rIl.IntervalStart != nil && nRil.IntervalStart != nil && @@ -484,7 +487,7 @@ func (rIl *RateSInterval) Equals(nRil *RateSInterval) (eq bool) { } if rIl.Increments != nil && nRil.Increments != nil { for i, rtIn := range rIl.Increments { - if !rtIn.Equals(nRil.Increments[i]) { + if !rtIn.Equals(nRil.Increments[i], rIlRef, nRilRef) { return } } @@ -493,20 +496,18 @@ func (rIl *RateSInterval) Equals(nRil *RateSInterval) (eq bool) { } // Equals returns the equality between two RateSIncrement -func (rI *RateSIncrement) Equals(rtIn *RateSIncrement) (eq bool) { - if (rI.Usage == nil && rtIn.Usage != nil || - rI.Usage != nil && rtIn.Usage == nil || +func (rI *RateSIncrement) Equals(rtIn *RateSIncrement, rIRef, rtInRef map[string]*IntervalRate) (eq bool) { + return !((rI.Usage == nil && rtIn.Usage != nil) || + (rI.Usage != nil && rtIn.Usage == nil) || (rI.Usage != nil && rtIn.Usage != nil && - rI.Usage.Compare(rtIn.Usage) != 0)) || + rI.Usage.Compare(rtIn.Usage) != 0) || (rI.IncrementStart == nil && rtIn.IncrementStart != nil || rI.IncrementStart != nil && rtIn.IncrementStart == nil || (rI.IncrementStart != nil && rtIn.IncrementStart != nil && rI.IncrementStart.Compare(rtIn.IncrementStart) != 0)) || rI.CompressFactor != rtIn.CompressFactor || - rI.IntervalRateIndex != rtIn.IntervalRateIndex { - return - } - return true + rI.IntervalRateIndex != rtIn.IntervalRateIndex || + !rIRef[rI.RateID].Equals(rtInRef[rtIn.RateID])) } // RateProfileCost is the cost returned by RateS at cost queries @@ -517,7 +518,7 @@ type RateProfileCost struct { MaxCost float64 MaxCostStrategy string RateSIntervals []*RateSInterval - Rates map[string]*Rate + Rates map[string]*IntervalRate Altered []string } @@ -529,7 +530,7 @@ type ExtRateProfileCost struct { MaxCost float64 MaxCostStrategy string RateSIntervals []*ExtRateSInterval - Rates map[string]*ExtRate + Rates map[string]*ExtIntervalRate Altered []string } @@ -553,9 +554,9 @@ func (rpC *RateProfileCost) AsExtRateProfileCost() (exRt *ExtRateProfileCost, er } } if rpC.Rates != nil { - exRt.Rates = make(map[string]*ExtRate, len(rpC.Rates)) + exRt.Rates = make(map[string]*ExtIntervalRate, len(rpC.Rates)) for key, val := range rpC.Rates { - if rcvRts, err := val.AsExtRate(); err != nil { + if rcvRts, err := val.AsExtIntervalRate(); err != nil { return nil, err } else { exRt.Rates[key] = rcvRts @@ -571,6 +572,31 @@ func (rpC *RateProfileCost) AsExtRateProfileCost() (exRt *ExtRateProfileCost, er return } +/* +func (rpC *RateProfileCost) SynchronizeRateKeys(nRpCt *RateProfileCost) { + rts := make(map[string]*IntervalRate) + reverse := make(map[string]string) + for key, val := range rpC.Rates { + reverseKey := key + for newKey, newVal := range nRpCt.Rates { + if val.Equals(newVal) { + reverseKey = newKey + break + } + } + rts[reverseKey] = val + reverse[key] = reverseKey + } + rpC.Rates = rts + for _, val := range rpC.RateSIntervals { + for _, incrVal := range val.Increments { + incrVal.RateID = reverse[incrVal.RateID] + } + } +} + +*/ + // Equals returns the equality between two RateProfileCost func (rpC *RateProfileCost) Equals(nRpCt *RateProfileCost) (eq bool) { if rpC.ID != nRpCt.ID || @@ -590,15 +616,18 @@ func (rpC *RateProfileCost) Equals(nRpCt *RateProfileCost) (eq bool) { return } for idx, val := range rpC.RateSIntervals { - if ok := val.Equals(nRpCt.RateSIntervals[idx]); !ok { + if ok := val.Equals(nRpCt.RateSIntervals[idx], rpC.Rates, nRpCt.Rates); !ok { return } } - for key, val := range rpC.Rates { - if ok := val.Equals(nRpCt.Rates[key]); !ok { - return + /* + for key, val := range rpC.Rates { + if ok := val.Equals(nRpCt.Rates[key]); !ok { + return + } } - } + + */ for idx, val := range rpC.Altered { if val != nRpCt.Altered[idx] { return @@ -626,7 +655,7 @@ func (rpC *ExtRateProfileCost) Equals(nRpCt *ExtRateProfileCost) (eq bool) { return } for idx, val := range rpC.RateSIntervals { - if ok := val.Equals(nRpCt.RateSIntervals[idx]); !ok { + if ok := val.Equals(nRpCt.RateSIntervals[idx], rpC.Rates, nRpCt.Rates); !ok { return } } @@ -682,7 +711,7 @@ func (rIv *RateSInterval) CompressEquals(rIv2 *RateSInterval) (eq bool) { return true } -func (rIv *RateSInterval) Cost(rts map[string]*Rate) (cost *decimal.Big, err error) { +func (rIv *RateSInterval) Cost(rts map[string]*IntervalRate) (cost *decimal.Big, err error) { if rIv.cost == nil { rIv.cost = new(decimal.Big) for _, incrm := range rIv.Increments { @@ -704,13 +733,12 @@ func (rIcr *RateSIncrement) CompressEquals(rIcr2 *RateSIncrement) (eq bool) { } // Cost computes the Cost on RateSIncrement -func (rIcr *RateSIncrement) Cost(rts map[string]*Rate) (cost *decimal.Big, err error) { +func (rIcr *RateSIncrement) Cost(rts map[string]*IntervalRate) (cost *decimal.Big, err error) { if rIcr.cost == nil { - rt, has := rts[rIcr.RateID] + icrRt, has := rts[rIcr.RateID] if !has { return nil, fmt.Errorf("Cannot get the IntervalRate with this RateID: %s", rIcr.RateID) } - icrRt := rt.IntervalRates[rIcr.IntervalRateIndex] if rIcr.Usage.Compare(NewDecimal(-1, 0)) == 0 { // FixedFee rIcr.cost = icrRt.FixedFee.Big } else { @@ -731,7 +759,7 @@ func (rIcr *RateSIncrement) Cost(rts map[string]*Rate) (cost *decimal.Big, err e } // CostForIntervals sums the costs for all intervals -func CostForIntervals(rtIvls []*RateSInterval, rts map[string]*Rate) (cost *decimal.Big, err error) { +func CostForIntervals(rtIvls []*RateSInterval, rts map[string]*IntervalRate) (cost *decimal.Big, err error) { cost = new(decimal.Big) for _, rtIvl := range rtIvls { rtCst, err := rtIvl.Cost(rts)