mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
EventCost.SyncKeys method with tests
This commit is contained in:
@@ -53,6 +53,7 @@ var sTestsAlsPrf = []func(t *testing.T){
|
||||
testAttributeSGetAttributeForEventNotFound,
|
||||
testAttributeSGetAttributeForEventWithMetaAnyContext,
|
||||
testAttributeSProcessEvent,
|
||||
testAttributeSProcessEventNotFound,
|
||||
testAttributeSProcessEventMissing,
|
||||
testAttributeSProcessEventWithNoneSubstitute,
|
||||
testAttributeSProcessEventWithNoneSubstitute2,
|
||||
@@ -356,6 +357,26 @@ func testAttributeSProcessEvent(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func testAttributeSProcessEventNotFound(t *testing.T) {
|
||||
ev := &engine.AttrArgsProcessEvent{
|
||||
Context: utils.StringPointer(utils.MetaSessionS),
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "testAttributeSProcessEventNotFound",
|
||||
Event: map[string]interface{}{
|
||||
utils.Account: "Inexistent",
|
||||
utils.Destination: "+491511231234",
|
||||
},
|
||||
},
|
||||
}
|
||||
var rplyEv engine.AttrSProcessEventReply
|
||||
if err := attrSRPC.Call(utils.AttributeSv1ProcessEvent,
|
||||
ev, &rplyEv); err == nil ||
|
||||
err.Error() != utils.ErrNotFound.Error() {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func testAttributeSProcessEventMissing(t *testing.T) {
|
||||
ev := &engine.AttrArgsProcessEvent{
|
||||
Context: utils.StringPointer(utils.MetaSessionS),
|
||||
@@ -369,10 +390,10 @@ func testAttributeSProcessEventMissing(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var rplyEv engine.AttrSProcessEventReply
|
||||
if err := attrSRPC.Call(utils.AttributeSv1ProcessEvent,
|
||||
ev, &rplyEv); err == nil && err != utils.ErrMandatoryIeMissing {
|
||||
ev, &rplyEv); err == nil ||
|
||||
err.Error() != utils.ErrMandatoryIeMissing.Error() {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
@@ -652,7 +673,8 @@ func testAttributeSProcessEventWithHeader(t *testing.T) {
|
||||
func testAttributeSGetAttPrfIDs(t *testing.T) {
|
||||
expected := []string{"ATTR_2", "ATTR_1", "ATTR_3", "ATTR_Header", "AttributeWithNonSubstitute"}
|
||||
var result []string
|
||||
if err := attrSRPC.Call("ApierV1.GetAttributeProfileIDs", "", &result); err == nil || err.Error() != utils.NewErrMandatoryIeMissing("Tenant").Error() {
|
||||
if err := attrSRPC.Call("ApierV1.GetAttributeProfileIDs", "", &result); err == nil ||
|
||||
err.Error() != utils.NewErrMandatoryIeMissing("Tenant").Error() {
|
||||
t.Errorf("Expected error recived reply %+v with err=%v", result, err)
|
||||
}
|
||||
if err := attrSRPC.Call("ApierV1.GetAttributeProfileIDs", "cgrates.org", &result); err != nil {
|
||||
|
||||
@@ -397,6 +397,107 @@ func (ec *EventCost) appendChargingIntervalFromEventCost(oEC *EventCost, cIlIdx
|
||||
}
|
||||
}
|
||||
|
||||
// SyncKeys will sync the keys present into ec with the ones in refEC
|
||||
func (ec *EventCost) SyncKeys(refEC *EventCost) {
|
||||
// sync RatingFilters
|
||||
sncedRFilterIDs := make(map[string]string)
|
||||
for key, rf := range ec.RatingFilters {
|
||||
for refKey, refRf := range refEC.RatingFilters {
|
||||
if rf.Equals(refRf) {
|
||||
delete(ec.RatingFilters, key)
|
||||
sncedRFilterIDs[key] = refKey
|
||||
ec.RatingFilters[refKey] = rf
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// sync Rates
|
||||
sncedRateIDs := make(map[string]string)
|
||||
for key, rt := range ec.Rates {
|
||||
for refKey, refRt := range refEC.Rates {
|
||||
if rt.Equals(refRt) {
|
||||
delete(ec.Rates, key)
|
||||
sncedRateIDs[key] = refKey
|
||||
ec.Rates[refKey] = rt
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// sync Timings
|
||||
sncedTimingIDs := make(map[string]string)
|
||||
for key, tm := range ec.Timings {
|
||||
for refKey, refTm := range refEC.Timings {
|
||||
if tm.Equals(refTm) {
|
||||
delete(ec.Timings, key)
|
||||
sncedTimingIDs[key] = refKey
|
||||
ec.Timings[refKey] = tm
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// sync Rating
|
||||
sncedRatingIDs := make(map[string]string)
|
||||
for key, ru := range ec.Rating {
|
||||
if tmRefKey, has := sncedTimingIDs[ru.TimingID]; has {
|
||||
ru.TimingID = tmRefKey
|
||||
}
|
||||
if rtRefID, has := sncedRateIDs[ru.RatesID]; has {
|
||||
ru.RatesID = rtRefID
|
||||
}
|
||||
if rfRefID, has := sncedRFilterIDs[ru.RatingFiltersID]; has {
|
||||
ru.RatingFiltersID = rfRefID
|
||||
}
|
||||
for refKey, refRU := range refEC.Rating {
|
||||
if ru.Equals(refRU) {
|
||||
delete(ec.Rating, key)
|
||||
sncedRatingIDs[key] = refKey
|
||||
ec.Rating[refKey] = ru
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// sync Accounting
|
||||
sncedAcntIDs := make(map[string]string)
|
||||
for key, acnt := range ec.Accounting {
|
||||
for refKey, refAcnt := range refEC.Accounting {
|
||||
if acnt.Equals(refAcnt) {
|
||||
delete(ec.Accounting, key)
|
||||
sncedAcntIDs[key] = refKey
|
||||
ec.Accounting[refKey] = acnt
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// correct the ExtraCharge
|
||||
for _, acnt := range ec.Accounting {
|
||||
if acntRefID, has := sncedAcntIDs[acnt.ExtraChargeID]; has {
|
||||
acnt.ExtraChargeID = acntRefID
|
||||
}
|
||||
}
|
||||
// need another sync for the corrected ExtraChargeIDs
|
||||
for key, acnt := range ec.Accounting {
|
||||
for refKey, refAcnt := range refEC.Accounting {
|
||||
if acnt.Equals(refAcnt) {
|
||||
delete(ec.Accounting, key)
|
||||
sncedAcntIDs[key] = refKey
|
||||
ec.Accounting[refKey] = acnt
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// sync Charges
|
||||
for _, ci := range ec.Charges {
|
||||
if refRatingID, has := sncedRatingIDs[ci.RatingID]; has {
|
||||
ci.RatingID = refRatingID
|
||||
}
|
||||
for _, cIcrmt := range ci.Increments {
|
||||
if refAcntID, has := sncedAcntIDs[cIcrmt.AccountingID]; has {
|
||||
cIcrmt.AccountingID = refAcntID
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Merge will merge a list of EventCosts into this one
|
||||
func (ec *EventCost) Merge(ecs ...*EventCost) {
|
||||
for _, newEC := range ecs {
|
||||
|
||||
@@ -2030,3 +2030,244 @@ func TestECAppendCIlFromEC(t *testing.T) {
|
||||
t.Errorf("expecting: %s, received: %s", utils.ToJSON(eEC), utils.ToJSON(ec))
|
||||
}
|
||||
}
|
||||
|
||||
func TestECSyncKeys(t *testing.T) {
|
||||
ec := testEC.Clone()
|
||||
|
||||
refEC := &EventCost{
|
||||
Rating: Rating{
|
||||
"21a5ab9": &RatingUnit{
|
||||
ConnectFee: 0.1,
|
||||
RoundingMethod: "*up",
|
||||
RoundingDecimals: 5,
|
||||
TimingID: "2f324ab",
|
||||
RatesID: "2c1a177",
|
||||
RatingFiltersID: "23e77dc",
|
||||
},
|
||||
},
|
||||
Accounting: Accounting{
|
||||
"2012888": &BalanceCharge{
|
||||
AccountID: "cgrates.org:dan",
|
||||
BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
|
||||
Units: 0.01,
|
||||
},
|
||||
"288bfa6": &BalanceCharge{
|
||||
AccountID: "cgrates.org:dan",
|
||||
BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
|
||||
Units: 0.005,
|
||||
},
|
||||
"24d6c02": &BalanceCharge{
|
||||
AccountID: "cgrates.org:dan",
|
||||
BalanceUUID: "7a54a9e9-d610-4c82-bcb5-a315b9a65010",
|
||||
RatingID: "3cd6425",
|
||||
Units: 1,
|
||||
ExtraChargeID: "288bfa6",
|
||||
},
|
||||
},
|
||||
RatingFilters: RatingFilters{
|
||||
"23e77dc": RatingMatchedFilters{
|
||||
"DestinationID": "GERMANY",
|
||||
"DestinationPrefix": "+49",
|
||||
"RatingPlanID": "RPL_RETAIL1",
|
||||
"Subject": "*out:cgrates.org:call:*any",
|
||||
},
|
||||
},
|
||||
Timings: ChargedTimings{
|
||||
"2f324ab": &ChargedTiming{
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
},
|
||||
Rates: ChargedRates{
|
||||
"2c1a177": RateGroups{
|
||||
&Rate{
|
||||
GroupIntervalStart: time.Duration(0),
|
||||
Value: 0.01,
|
||||
RateIncrement: time.Duration(1 * time.Minute),
|
||||
RateUnit: time.Duration(1 * time.Second)},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
eEC := &EventCost{
|
||||
CGRID: "164b0422fdc6a5117031b427439482c6a4f90e41",
|
||||
RunID: utils.META_DEFAULT,
|
||||
StartTime: time.Date(2017, 1, 9, 16, 18, 21, 0, time.UTC),
|
||||
Charges: []*ChargingInterval{
|
||||
&ChargingInterval{
|
||||
RatingID: "21a5ab9",
|
||||
Increments: []*ChargingIncrement{
|
||||
&ChargingIncrement{
|
||||
Usage: time.Duration(0),
|
||||
Cost: 0.1,
|
||||
AccountingID: "9bdad10",
|
||||
CompressFactor: 1,
|
||||
},
|
||||
&ChargingIncrement{
|
||||
Usage: time.Duration(1 * time.Second),
|
||||
Cost: 0,
|
||||
AccountingID: "3455b83",
|
||||
CompressFactor: 10,
|
||||
},
|
||||
&ChargingIncrement{
|
||||
Usage: time.Duration(10 * time.Second),
|
||||
Cost: 0.01,
|
||||
AccountingID: "2012888",
|
||||
CompressFactor: 2,
|
||||
},
|
||||
&ChargingIncrement{
|
||||
Usage: time.Duration(1 * time.Second),
|
||||
Cost: 0.005,
|
||||
AccountingID: "24d6c02",
|
||||
CompressFactor: 30,
|
||||
},
|
||||
},
|
||||
CompressFactor: 1,
|
||||
},
|
||||
&ChargingInterval{
|
||||
RatingID: "21a5ab9",
|
||||
Increments: []*ChargingIncrement{
|
||||
&ChargingIncrement{
|
||||
Usage: time.Duration(1 * time.Second),
|
||||
Cost: 0.01,
|
||||
AccountingID: "2012888",
|
||||
CompressFactor: 60,
|
||||
},
|
||||
},
|
||||
CompressFactor: 4,
|
||||
},
|
||||
&ChargingInterval{
|
||||
RatingID: "21a5ab9",
|
||||
Increments: []*ChargingIncrement{
|
||||
&ChargingIncrement{
|
||||
Usage: time.Duration(1 * time.Second),
|
||||
Cost: 0,
|
||||
AccountingID: "3455b83",
|
||||
CompressFactor: 10,
|
||||
},
|
||||
&ChargingIncrement{
|
||||
Usage: time.Duration(10 * time.Second),
|
||||
Cost: 0.01,
|
||||
AccountingID: "2012888",
|
||||
CompressFactor: 2,
|
||||
},
|
||||
&ChargingIncrement{
|
||||
Usage: time.Duration(1 * time.Second),
|
||||
Cost: 0.005,
|
||||
AccountingID: "24d6c02",
|
||||
CompressFactor: 30,
|
||||
},
|
||||
},
|
||||
CompressFactor: 5,
|
||||
},
|
||||
},
|
||||
AccountSummary: &AccountSummary{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "dan",
|
||||
BalanceSummaries: []*BalanceSummary{
|
||||
&BalanceSummary{
|
||||
Type: "*monetary",
|
||||
Value: 50,
|
||||
Disabled: false},
|
||||
&BalanceSummary{
|
||||
ID: "4b8b53d7-c1a1-4159-b845-4623a00a0165",
|
||||
Type: "*monetary",
|
||||
Value: 25,
|
||||
Disabled: false},
|
||||
&BalanceSummary{
|
||||
Type: "*voice",
|
||||
Value: 200,
|
||||
Disabled: false,
|
||||
},
|
||||
},
|
||||
AllowNegative: false,
|
||||
Disabled: false,
|
||||
},
|
||||
Rating: Rating{
|
||||
"3cd6425": &RatingUnit{
|
||||
RoundingMethod: "*up",
|
||||
RoundingDecimals: 5,
|
||||
TimingID: "2f324ab",
|
||||
RatesID: "4910ecf",
|
||||
RatingFiltersID: "23e77dc",
|
||||
},
|
||||
"21a5ab9": &RatingUnit{
|
||||
ConnectFee: 0.1,
|
||||
RoundingMethod: "*up",
|
||||
RoundingDecimals: 5,
|
||||
TimingID: "2f324ab",
|
||||
RatesID: "2c1a177",
|
||||
RatingFiltersID: "23e77dc",
|
||||
},
|
||||
},
|
||||
Accounting: Accounting{
|
||||
"2012888": &BalanceCharge{
|
||||
AccountID: "cgrates.org:dan",
|
||||
BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
|
||||
Units: 0.01,
|
||||
},
|
||||
"288bfa6": &BalanceCharge{
|
||||
AccountID: "cgrates.org:dan",
|
||||
BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
|
||||
Units: 0.005,
|
||||
},
|
||||
"9bdad10": &BalanceCharge{
|
||||
AccountID: "cgrates.org:dan",
|
||||
BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
|
||||
Units: 0.1,
|
||||
},
|
||||
"24d6c02": &BalanceCharge{
|
||||
AccountID: "cgrates.org:dan",
|
||||
BalanceUUID: "7a54a9e9-d610-4c82-bcb5-a315b9a65010",
|
||||
RatingID: "3cd6425",
|
||||
Units: 1,
|
||||
ExtraChargeID: "288bfa6",
|
||||
},
|
||||
"3455b83": &BalanceCharge{
|
||||
AccountID: "cgrates.org:dan",
|
||||
BalanceUUID: "9d54a9e9-d610-4c82-bcb5-a315b9a65089",
|
||||
Units: 1,
|
||||
ExtraChargeID: "*none",
|
||||
},
|
||||
},
|
||||
RatingFilters: RatingFilters{
|
||||
"23e77dc": RatingMatchedFilters{
|
||||
"DestinationID": "GERMANY",
|
||||
"DestinationPrefix": "+49",
|
||||
"RatingPlanID": "RPL_RETAIL1",
|
||||
"Subject": "*out:cgrates.org:call:*any",
|
||||
},
|
||||
},
|
||||
Rates: ChargedRates{
|
||||
"2c1a177": RateGroups{
|
||||
&Rate{
|
||||
GroupIntervalStart: time.Duration(0),
|
||||
Value: 0.01,
|
||||
RateIncrement: time.Duration(1 * time.Minute),
|
||||
RateUnit: time.Duration(1 * time.Second)},
|
||||
},
|
||||
"4910ecf": RateGroups{
|
||||
&Rate{
|
||||
GroupIntervalStart: time.Duration(0),
|
||||
Value: 0.005,
|
||||
RateIncrement: time.Duration(1 * time.Second),
|
||||
RateUnit: time.Duration(1 * time.Second)},
|
||||
&Rate{
|
||||
GroupIntervalStart: time.Duration(60 * time.Second),
|
||||
Value: 0.005,
|
||||
RateIncrement: time.Duration(1 * time.Second),
|
||||
RateUnit: time.Duration(1 * time.Second)},
|
||||
},
|
||||
},
|
||||
Timings: ChargedTimings{
|
||||
"2f324ab": &ChargedTiming{
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ec.SyncKeys(refEC)
|
||||
if !reflect.DeepEqual(eEC, ec) {
|
||||
t.Errorf("expecting: %s \nreceived: %s",
|
||||
utils.ToIJSON(eEC), utils.ToIJSON(ec))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,7 +460,7 @@ func (sS *SessionS) debitSession(s *Session, sRunIdx int, dur time.Duration,
|
||||
cd := sr.CD.Clone()
|
||||
s.Unlock()
|
||||
cc := new(engine.CallCost)
|
||||
if err := sS.ralS.Call("Responder.MaxDebit", cd, cc); err != nil {
|
||||
if err := sS.ralS.Call(utils.ResponderMaxDebit, cd, cc); err != nil {
|
||||
s.Lock()
|
||||
sr.ExtraDuration += dbtRsrv
|
||||
s.Unlock()
|
||||
@@ -489,6 +489,7 @@ func (sS *SessionS) debitSession(s *Session, sRunIdx int, dur time.Duration,
|
||||
sr.EventCost = ec
|
||||
}
|
||||
} else {
|
||||
ec.SyncKeys(sr.EventCost)
|
||||
sr.EventCost.Merge(ec)
|
||||
}
|
||||
maxDur = sr.LastUsage
|
||||
|
||||
@@ -785,6 +785,7 @@ const (
|
||||
ResponderRefundIncrements = "Responder.RefundIncrements"
|
||||
ResponderGetMaxSessionTime = "Responder.GetMaxSessionTime"
|
||||
ResponderStatus = "Responder.Status"
|
||||
ResponderMaxDebit = "Responder.MaxDebit"
|
||||
)
|
||||
|
||||
// DispatcherS APIs
|
||||
|
||||
Reference in New Issue
Block a user