diff --git a/utils/account.go b/utils/account.go index 55258e76b..dbeec1162 100644 --- a/utils/account.go +++ b/utils/account.go @@ -241,6 +241,88 @@ func (bL *Balance) AsExtBalance() (eBl *ExtBalance, err error) { return } +func (bL *Balance) Equals(bal *Balance) (eq bool) { + if bL.ID != bal.ID || bL.Type != bal.Type { + return + } + if bL.FilterIDs == nil && bal.FilterIDs != nil || + bL.FilterIDs != nil && bal.FilterIDs == nil || + len(bL.FilterIDs) != len(bal.FilterIDs) { + return + } + for i, val := range bL.FilterIDs { + if val != bal.FilterIDs[i] { + return + } + } + if bL.Weights == nil && bal.Weights != nil || + bL.Weights != nil && bal.Weights == nil || + len(bL.Weights) != len(bal.Weights) { + return + } + for idx, val := range bL.Weights { + if ok := val.Equals(bal.Weights[idx]); !ok { + return + } + } + if bL.Units == nil && bal.Units != nil || + bL.Units != nil && bal.Units == nil || + bL.Units.Compare(bal.Units) != 0 { + return + } + if bL.UnitFactors == nil && bal.UnitFactors != nil || + bL.UnitFactors != nil && bal.UnitFactors == nil || + len(bL.UnitFactors) != len(bal.UnitFactors) { + return + } + for idx, val := range bL.UnitFactors { + if ok := val.Equals(bal.UnitFactors[idx]); !ok { + return + } + } + if bL.Opts == nil && bal.Opts != nil || + bL.Opts != nil && bal.Opts == nil || + len(bL.Opts) != len(bal.Opts) { + return + } + for key, val := range bL.Opts { + if val != bal.Opts[key] { + return + } + } + if bL.CostIncrements == nil && bal.CostIncrements != nil || + bL.CostIncrements != nil && bal.CostIncrements == nil || + len(bL.CostIncrements) != len(bal.CostIncrements) { + return + } + for idx, val := range bL.CostIncrements { + if ok := val.Equals(bal.CostIncrements[idx]); !ok { + return + } + } + if bL.AttributeIDs == nil && bal.AttributeIDs != nil || + bL.AttributeIDs != nil && bal.AttributeIDs == nil || + len(bL.AttributeIDs) != len(bal.AttributeIDs) { + return + } + for i, val := range bL.AttributeIDs { + if val != bal.AttributeIDs[i] { + return + } + } + if bL.RateProfileIDs == nil && bal.RateProfileIDs != nil || + bL.RateProfileIDs != nil && bal.RateProfileIDs == nil || + len(bL.RateProfileIDs) != len(bal.RateProfileIDs) { + return + } + for i, val := range bL.RateProfileIDs { + if val != bal.RateProfileIDs[i] { + return + } + } + return true +} + // CostIncrement enforces cost calculation to specific balance increments type CostIncrement struct { FilterIDs []string @@ -288,6 +370,31 @@ func (cI *CostIncrement) AsExtCostIncrement() (eCi *ExtCostIncrement, err error) return } +// Equals returns the equality between two CostIncrement +func (cI *CostIncrement) Equals(ctIn *CostIncrement) (eq bool) { + if cI.FilterIDs == nil && ctIn.FilterIDs != nil || + cI.FilterIDs != nil && ctIn.FilterIDs == nil || + len(cI.FilterIDs) != len(ctIn.FilterIDs) { + return + } + for i, val := range cI.FilterIDs { + if val != ctIn.FilterIDs[i] { + return + } + } + if cI.Increment == nil && ctIn.Increment != nil || + cI.Increment != nil && ctIn.Increment == nil || + cI.RecurrentFee == nil && ctIn.RecurrentFee != nil || + cI.RecurrentFee != nil && ctIn.RecurrentFee == nil || + cI.FixedFee == nil && ctIn.FixedFee != nil || + cI.FixedFee != nil && ctIn.FixedFee == nil { + return + } + return cI.Increment.Compare(ctIn.Increment) == 0 && + cI.FixedFee.Compare(ctIn.FixedFee) == 0 && + cI.RecurrentFee.Compare(ctIn.RecurrentFee) == 0 +} + // Clone returns a copy of the CostIncrement func (cI *CostIncrement) Clone() (cIcln *CostIncrement) { cIcln = new(CostIncrement) @@ -380,6 +487,72 @@ func (aP *Account) TenantID() string { return ConcatenatedKey(aP.Tenant, aP.ID) } +// Equals return the equality between two Accounts +func (aC *Account) Equals(acnt *Account) (eq bool) { + if aC.Tenant != acnt.Tenant || + aC.ID != acnt.ID { + return + } + if aC.FilterIDs == nil && acnt.FilterIDs != nil || + aC.FilterIDs != nil && acnt.FilterIDs == nil || + len(aC.FilterIDs) != len(acnt.FilterIDs) { + return + } + for idx, val := range aC.FilterIDs { + if val != acnt.FilterIDs[idx] { + return + } + } + if aC.ActivationInterval == nil && acnt.ActivationInterval != nil || + aC.ActivationInterval != nil && acnt.ActivationInterval != nil { + return + } + if ok := aC.ActivationInterval.Equals(acnt.ActivationInterval); !ok { + return + } + if aC.Weights == nil && acnt.Weights != nil || + aC.Weights != nil && acnt.Weights == nil || + len(aC.Weights) != len(acnt.Weights) { + return + } + for idx, val := range aC.Weights { + if ok := val.Equals(acnt.Weights[idx]); !ok { + return + } + } + if aC.Opts == nil && acnt.Opts != nil || + aC.Opts != nil && acnt.Opts == nil || + len(aC.Opts) != len(acnt.Opts) { + return + } + for key := range aC.Opts { + if aC.Opts[key] != acnt.Opts[key] { + return + } + } + if aC.Balances == nil && acnt.Balances != nil || + aC.Balances != nil && acnt.Balances == nil || + len(aC.Balances) != len(acnt.Balances) { + return + } + for key, val := range aC.Balances { + if ok := val.Equals(acnt.Balances[key]); !ok { + return + } + } + if aC.ThresholdIDs == nil && acnt.ThresholdIDs != nil || + aC.ThresholdIDs != nil && acnt.ThresholdIDs == nil || + len(aC.ThresholdIDs) != len(acnt.ThresholdIDs) { + return + } + for idx, val := range aC.ThresholdIDs { + if val != acnt.ThresholdIDs[idx] { + return + } + } + return true +} + // Clone returns a clone of the Account func (aP *Account) Clone() (acnt *Account) { acnt = &Account{ diff --git a/utils/apitpdata.go b/utils/apitpdata.go index 699727754..d2d46342a 100644 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -599,6 +599,17 @@ func (ai *ActivationInterval) IsActiveAtTime(atTime time.Time) bool { (ai.ExpiryTime.IsZero() || ai.ExpiryTime.After(atTime)) } +func (aI *ActivationInterval) Equals(actInt *ActivationInterval) (eq bool) { + if aI.ActivationTime.IsZero() && !actInt.ActivationTime.IsZero() || + !aI.ActivationTime.IsZero() && actInt.ActivationTime.IsZero() || + aI.ExpiryTime.IsZero() && !actInt.ExpiryTime.IsZero() || + !aI.ExpiryTime.IsZero() && actInt.ExpiryTime.IsZero() { + return + } + return aI.ActivationTime.Equal(actInt.ActivationTime) && + aI.ExpiryTime.Equal(actInt.ExpiryTime) +} + // Attributes to send on SessionDisconnect by SMG type AttrDisconnectSession struct { EventStart map[string]interface{} diff --git a/utils/dynamicweight.go b/utils/dynamicweight.go index 6ab35e779..372750ee4 100644 --- a/utils/dynamicweight.go +++ b/utils/dynamicweight.go @@ -66,6 +66,20 @@ func (dW DynamicWeight) String(dWSep, fltrsep string) (out string) { return strings.Join(dW.FilterIDs, fltrsep) + dWSep + strconv.FormatFloat(dW.Weight, 'f', -1, 64) } +func (dW *DynamicWeight) Equals(dnWg *DynamicWeight) (eq bool) { + if dW.FilterIDs == nil && dnWg.FilterIDs != nil || + dW.FilterIDs != nil && dnWg.FilterIDs == nil || + len(dW.FilterIDs) != len(dnWg.FilterIDs) { + return + } + for i := range dW.FilterIDs { + if dW.FilterIDs[i] != dnWg.FilterIDs[i] { + return + } + } + return dW.Weight == dnWg.Weight +} + // DynamicWeight returns Weight based on Filters type DynamicWeight struct { FilterIDs []string diff --git a/utils/eventcharges.go b/utils/eventcharges.go index cadf9159a..d981dc940 100644 --- a/utils/eventcharges.go +++ b/utils/eventcharges.go @@ -94,10 +94,17 @@ func (ec *EventCharges) appendChargeEntry(cIls ...*ChargeEntry) { } } +// Equals return the equality between two ChargeEntry ignoring CompressFactor func (cE *ChargeEntry) CompressEquals(chEn *ChargeEntry) bool { return cE.ChargingID == chEn.ChargingID } +// Equals return the equality between two ChargeEntry +func (cE *ChargeEntry) Equals(chEn *ChargeEntry) (eq bool) { + return cE.ChargingID == chEn.ChargingID && + cE.CompressFactor == chEn.CompressFactor +} + // SyncIDs will repopulate Accounting, UnitFactors and Rating IDs if they equal the references in ec func (ec *EventCharges) SyncIDs(eCs ...*EventCharges) { for _, nEc := range eCs { @@ -211,6 +218,69 @@ func (ec *EventCharges) AsExtEventCharges() (eEc *ExtEventCharges, err error) { return } +// Equals returns the equality between two EventChargers +func (eC *EventCharges) Equals(evCh *EventCharges) (eq bool) { + if eC.Abstracts == nil && evCh.Abstracts != nil || + eC.Abstracts != nil && evCh.Abstracts == nil || + eC.Concretes == nil && evCh.Concretes != nil || + eC.Concretes != nil && evCh.Concretes == nil || + eC.Abstracts.Compare(evCh.Abstracts) != 0 || + eC.Concretes.Compare(evCh.Concretes) != 0 { + return + } + if eC.Charges == nil && evCh.Charges != nil || + eC.Charges != nil && evCh.Charges == nil || + len(eC.Charges) != len(evCh.Charges) { + return + } + for idx, val := range eC.Charges { + if ok := val.Equals(evCh.Charges[idx]); !ok { + return + } + } + if eC.Accounting == nil && evCh.Accounting != nil || + eC.Accounting != nil && evCh.Accounting == nil || + len(eC.Accounting) != len(evCh.Accounting) { + return + } + for key, val := range eC.Accounting { + if ok := val.Equals(evCh.Accounting[key]); !ok { + return + } + } + if eC.UnitFactors == nil && evCh.UnitFactors != nil || + eC.UnitFactors != nil && evCh.UnitFactors == nil || + len(eC.UnitFactors) != len(evCh.UnitFactors) { + return + } + for key, val := range eC.UnitFactors { + if ok := val.Equals(evCh.UnitFactors[key]); !ok { + return + } + } + if eC.Rating == nil && evCh.Rating != nil || + eC.Rating != nil && evCh.Rating == nil || + len(eC.Rating) != len(evCh.Rating) { + return + } + for key, val := range eC.Rating { + if ok := val.Equals(evCh.Rating[key]); !ok { + return + } + } + if eC.Accounts == nil && evCh.Accounts != nil || + eC.Accounts != nil && evCh.Accounts == nil || + len(eC.Accounts) != len(evCh.Accounts) { + return + } + for key, val := range eC.Accounts { + if ok := val.Equals(evCh.Accounts[key]); !ok { + return + } + } + return true +} + // unitFactorID returns the ID of the matching UnitFactor within ec.UnitFactors func (ec *EventCharges) unitFactorID(uF *UnitFactor) (ufID string) { for ecUfID, ecUf := range ec.UnitFactors { diff --git a/utils/librates.go b/utils/librates.go index 6c2ef9a4c..591974812 100644 --- a/utils/librates.go +++ b/utils/librates.go @@ -337,6 +337,7 @@ func (rIl *RateSInterval) Equals(nRil *RateSInterval) (eq bool) { return true } +// 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 ||