diff --git a/apier/v1/cdrsv1.go b/apier/v1/cdrsv1.go
index cfefdcaef..db5681a03 100644
--- a/apier/v1/cdrsv1.go
+++ b/apier/v1/cdrsv1.go
@@ -19,8 +19,6 @@ along with this program. If not, see
package v1
import (
- "time"
-
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
@@ -50,23 +48,11 @@ func (self *CdrsV1) ProcessExternalCdr(cdr *engine.ExternalCDR, reply *string) e
// Remotely start mediation with specific runid, runs asynchronously, it's status will be displayed in syslog
func (self *CdrsV1) RateCdrs(attrs utils.AttrRateCdrs, reply *string) error {
- var tStart, tEnd time.Time
- var err error
- if len(attrs.TimeStart) != 0 {
- if tStart, err = utils.ParseTimeDetectLayout(attrs.TimeStart, self.CdrSrv.Timezone()); err != nil {
- return err
- }
+ cdrsFltr, err := attrs.AsCDRsFilter(self.CdrSrv.Timezone())
+ if err != nil {
+ return utils.NewErrServerError(err)
}
- if len(attrs.TimeEnd) != 0 {
- if tEnd, err = utils.ParseTimeDetectLayout(attrs.TimeEnd, self.CdrSrv.Timezone()); err != nil {
- return err
- }
- }
- //RateCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources, reqTypes, directions, tenants, categories, accounts, subjects, destPrefixes []string,
- //orderIdStart, orderIdEnd int64, timeStart, timeEnd time.Time, rerateErrors, rerateRated bool)
- if err := self.CdrSrv.RateCDRs(attrs.CgrIds, attrs.MediationRunIds, attrs.TORs, attrs.CdrHosts, attrs.CdrSources, attrs.ReqTypes, attrs.Directions,
- attrs.Tenants, attrs.Categories, attrs.Accounts, attrs.Subjects, attrs.DestinationPrefixes, attrs.RatedAccounts, attrs.RatedSubjects,
- attrs.OrderIdStart, attrs.OrderIdEnd, tStart, tEnd, attrs.RerateErrors, attrs.RerateRated, attrs.SendToStats); err != nil {
+ if err := self.CdrSrv.RateCDRs(cdrsFltr, attrs.SendToStats); err != nil {
return utils.NewErrServerError(err)
}
*reply = utils.OK
diff --git a/engine/cdrs.go b/engine/cdrs.go
index cb27892ca..393d9225c 100644
--- a/engine/cdrs.go
+++ b/engine/cdrs.go
@@ -124,25 +124,12 @@ func (self *CdrServer) LogCallCost(ccl *CallCostLog) error {
}
// Called by rate/re-rate API
-func (self *CdrServer) RateCDRs(cgrIds, runIds, tors, cdrHosts, cdrSources, RequestTypes, directions, tenants, categories, accounts, subjects, destPrefixes, ratedAccounts, ratedSubjects []string,
- orderIdStart, orderIdEnd *int64, timeStart, timeEnd time.Time, rerateErrors, rerateRated, sendToStats bool) error {
- var costStart, costEnd *float64
- if rerateErrors {
- costStart = utils.Float64Pointer(-1.0)
- if !rerateRated {
- costEnd = utils.Float64Pointer(0.0)
- }
- } else if rerateRated {
- costStart = utils.Float64Pointer(0.0)
- }
- cdrs, _, err := self.cdrDb.GetCDRs(&utils.CDRsFilter{CGRIDs: cgrIds, RunIDs: runIds, ToRs: tors, Sources: cdrSources,
- RequestTypes: RequestTypes, Directions: directions, Tenants: tenants, Categories: categories, Accounts: accounts,
- Subjects: subjects, DestinationPrefixes: destPrefixes,
- OrderIDStart: orderIdStart, OrderIDEnd: orderIdEnd, AnswerTimeStart: &timeStart, AnswerTimeEnd: &timeEnd,
- MinCost: costStart, MaxCost: costEnd})
+func (self *CdrServer) RateCDRs(cdrFltr *utils.CDRsFilter, sendToStats bool) error {
+ cdrs, _, err := self.cdrDb.GetCDRs(cdrFltr)
if err != nil {
return err
}
+ utils.Logger.Debug(fmt.Sprintf("CDRServer.RateCDRs, got CDRs: %+v", cdrs))
for _, cdr := range cdrs {
// replace aliases for cases they were loaded after CDR received
if err := LoadAlias(&AttrMatchingAlias{
@@ -160,7 +147,7 @@ func (self *CdrServer) RateCDRs(cgrIds, runIds, tors, cdrHosts, cdrSources, Requ
if err := LoadUserProfile(cdr, utils.EXTRA_FIELDS); err != nil {
return err
}
- if err := self.rateStoreStatsReplicate(cdr); err != nil {
+ if err := self.rateStoreStatsReplicate(cdr, sendToStats); err != nil {
utils.Logger.Err(fmt.Sprintf(" Processing CDR %+v, got error: %s", cdr, err.Error()))
}
}
@@ -204,14 +191,14 @@ func (self *CdrServer) deriveRateStoreStatsReplicate(cdr *CDR) error {
return err
}
for _, cdrRun := range cdrRuns {
- if err := self.rateStoreStatsReplicate(cdrRun); err != nil {
+ if err := self.rateStoreStatsReplicate(cdrRun, true); err != nil {
return err
}
}
return nil
}
-func (self *CdrServer) rateStoreStatsReplicate(cdr *CDR) error {
+func (self *CdrServer) rateStoreStatsReplicate(cdr *CDR, sendToStats bool) error {
if cdr.RunID == utils.MetaRaw { // Overwrite *raw with *default for rating
cdr.RunID = utils.META_DEFAULT
}
@@ -249,7 +236,7 @@ func (self *CdrServer) rateStoreStatsReplicate(cdr *CDR) error {
}
}
// Attach CDR to stats
- if self.stats != nil { // Send CDR to stats
+ if self.stats != nil && sendToStats { // Send CDR to stats
if err := self.stats.AppendCDR(cdr, nil); err != nil {
utils.Logger.Err(fmt.Sprintf(" Could not append CDR to stats: %s", err.Error()))
}
diff --git a/engine/storage_cdrs_it_test.go b/engine/storage_cdrs_it_test.go
index dbbbf74f8..5f886aa4e 100644
--- a/engine/storage_cdrs_it_test.go
+++ b/engine/storage_cdrs_it_test.go
@@ -43,14 +43,12 @@ func TestITCDRsMySQL(t *testing.T) {
if err := testGetCDRs(cfg); err != nil {
t.Error(err)
}
- /*
- if err := testSetCDR(cfg); err != nil {
- t.Error(err)
- }
- if err := testSMCosts(cfg); err != nil {
- t.Error(err)
- }
- */
+ if err := testSetCDR(cfg); err != nil {
+ t.Error(err)
+ }
+ if err := testSMCosts(cfg); err != nil {
+ t.Error(err)
+ }
}
func TestITCDRsPSQL(t *testing.T) {
@@ -83,14 +81,12 @@ func TestITCDRsMongo(t *testing.T) {
if err := testGetCDRs(cfg); err != nil {
t.Error(err)
}
- /*
- if err := testSetCDR(cfg); err != nil {
- t.Error(err)
- }
- if err := testSMCosts(cfg); err != nil {
- t.Error(err)
- }
- */
+ if err := testSetCDR(cfg); err != nil {
+ t.Error(err)
+ }
+ if err := testSMCosts(cfg); err != nil {
+ t.Error(err)
+ }
}
// helper function to populate CDRs and check if they were stored in storDb
diff --git a/utils/apitpdata.go b/utils/apitpdata.go
index 073689f46..629d8d7f3 100644
--- a/utils/apitpdata.go
+++ b/utils/apitpdata.go
@@ -754,8 +754,6 @@ type AttrRateCdrs struct {
Accounts []string // If provided, it will filter account
Subjects []string // If provided, it will filter the rating subject
DestinationPrefixes []string // If provided, it will filter on destination prefix
- RatedAccounts []string // If provided, it will filter ratedaccount
- RatedSubjects []string // If provided, it will filter the ratedsubject
OrderIdStart *int64 // Export from this order identifier
OrderIdEnd *int64 // Export smaller than this order identifier
TimeStart string // If provided, it will represent the starting of the CDRs interval (>=)
@@ -765,6 +763,44 @@ type AttrRateCdrs struct {
SendToStats bool // Set to true if the CDRs should be sent to stats server
}
+func (attrRateCDRs *AttrRateCdrs) AsCDRsFilter(timezone string) (*CDRsFilter, error) {
+ cdrFltr := &CDRsFilter{
+ CGRIDs: attrRateCDRs.CgrIds,
+ RunIDs: attrRateCDRs.MediationRunIds,
+ OriginHosts: attrRateCDRs.CdrHosts,
+ Sources: attrRateCDRs.CdrSources,
+ ToRs: attrRateCDRs.TORs,
+ RequestTypes: attrRateCDRs.ReqTypes,
+ Directions: attrRateCDRs.Directions,
+ Tenants: attrRateCDRs.Tenants,
+ Categories: attrRateCDRs.Categories,
+ Accounts: attrRateCDRs.Accounts,
+ Subjects: attrRateCDRs.Subjects,
+ DestinationPrefixes: attrRateCDRs.DestinationPrefixes,
+ OrderIDStart: attrRateCDRs.OrderIdStart,
+ OrderIDEnd: attrRateCDRs.OrderIdEnd,
+ }
+ if aTime, err := ParseTimeDetectLayout(attrRateCDRs.TimeStart, timezone); err != nil {
+ return nil, err
+ } else {
+ cdrFltr.AnswerTimeStart = &aTime
+ }
+ if aTimeEnd, err := ParseTimeDetectLayout(attrRateCDRs.TimeEnd, timezone); err != nil {
+ return nil, err
+ } else {
+ cdrFltr.AnswerTimeEnd = &aTimeEnd
+ }
+ if attrRateCDRs.RerateErrors {
+ cdrFltr.MinCost = Float64Pointer(-1.0)
+ if !attrRateCDRs.RerateRated {
+ cdrFltr.MaxCost = Float64Pointer(0.0)
+ }
+ } else if attrRateCDRs.RerateRated {
+ cdrFltr.MinCost = Float64Pointer(0.0)
+ }
+ return cdrFltr, nil
+}
+
type AttrLoadTpFromFolder struct {
FolderPath string // Take files from folder absolute path
DryRun bool // Do not write to database but parse only
@@ -879,7 +915,6 @@ type CDRsFilter struct {
MaxPDD string // End of the pdd interval (<)
MinCost *float64 // Start of the cost interval (>=)
MaxCost *float64 // End of the usage interval (<)
- FilterOnRated bool // Do not consider rated CDRs but raw one
Unscoped bool // Include soft-deleted records in results
Count bool // If true count the items instead of returning data
Paginator