diff --git a/engine/storage_cdrs_it_test.go b/engine/storage_cdrs_it_test.go index ae9b10d7d..e5a336af8 100644 --- a/engine/storage_cdrs_it_test.go +++ b/engine/storage_cdrs_it_test.go @@ -753,6 +753,13 @@ func testGetCDRs(cfg *config.CGRConfig) error { } else if len(CDRs) != 7 { return fmt.Errorf("testGetCDRs #94, unexpected number of CDRs returned: %+v", len(CDRs)) } + // Filter OrderBy + // if CDRs, _, err := cdrStorage.GetCDRs(&utils.CDRsFilter{MinUsage: "12s", OrderBy: "orderid"}, false); err != nil { + // return fmt.Errorf("testGetCDRs #95, err: %v", err) + // } else { + // for _, cdr := range CDRs { + // } + // } return nil } diff --git a/engine/storage_mongo_stordb.go b/engine/storage_mongo_stordb.go index 5cb67f75d..f21e2ef6e 100644 --- a/engine/storage_mongo_stordb.go +++ b/engine/storage_mongo_stordb.go @@ -1119,6 +1119,11 @@ func (ms *MongoStorage) GetCDRs(qryFltr *utils.CDRsFilter, remove bool) ([]*CDR, if qryFltr.Paginator.Offset != nil { q = q.Skip(*qryFltr.Paginator.Offset) } + // need to check if it's descencent + // after that make a switch to make the parameter compatible + if qryFltr.OrderBy != "" { + q = q.Sort(qryFltr.OrderBy) + } if qryFltr.Count { cnt, err := q.Count() if err != nil { diff --git a/engine/storage_sql.go b/engine/storage_sql.go index 1e5c630a5..48d139e8c 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -1042,6 +1042,11 @@ func (self *SQLStorage) GetCDRs(qryFltr *utils.CDRsFilter, remove bool) ([]*CDR, if qryFltr.UpdatedAtEnd != nil && !qryFltr.UpdatedAtEnd.IsZero() { q = q.Where("updated_at < ?", qryFltr.UpdatedAtEnd) } + // need to check if it's descencent + // after that make a switch to make the parameter compatible + if qryFltr.OrderBy != "" { + q = q.Order(qryFltr.OrderBy) + } if len(qryFltr.MinUsage) != 0 { minUsage, err := utils.ParseDurationWithNanosecs(qryFltr.MinUsage) if err != nil { diff --git a/utils/apitpdata.go b/utils/apitpdata.go index 3c4986d83..1ac663997 100755 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -849,6 +849,7 @@ type AttrGetCdrs struct { TimeEnd string // If provided, it will represent the end of the CDRs interval (<) SkipErrors bool // Do not export errored CDRs SkipRated bool // Do not export rated CDRs + OrderBy string // Ascendent/Descendent Paginator } @@ -868,6 +869,7 @@ func (self *AttrGetCdrs) AsCDRsFilter(timezone string) (*CDRsFilter, error) { OrderIDStart: self.OrderIdStart, OrderIDEnd: self.OrderIdEnd, Paginator: self.Paginator, + OrderBy: self.OrderBy, } if len(self.TimeStart) != 0 { if answerTimeStart, err := ParseTimeDetectLayout(self.TimeStart, timezone); err != nil { @@ -1067,8 +1069,8 @@ type CDRsFilter struct { MaxCost *float64 // End of the usage interval (<) Unscoped bool // Include soft-deleted records in results Count bool // If true count the items instead of returning data + OrderBy string // Can be ordered by OrderID,AnswerTime,SetupTime,Cost,Usage Paginator - //OrderBy asc/desc } // RPCCDRsFilter is a filter used in Rpc calls @@ -1116,6 +1118,7 @@ type RPCCDRsFilter struct { MaxUsage string // End of the usage interval (<) MinCost *float64 // Start of the cost interval (>=) MaxCost *float64 // End of the usage interval (<) + OrderBy string // Ascendent/Descendent Paginator // Add pagination } @@ -1156,6 +1159,7 @@ func (self *RPCCDRsFilter) AsCDRsFilter(timezone string) (*CDRsFilter, error) { MinCost: self.MinCost, MaxCost: self.MaxCost, Paginator: self.Paginator, + OrderBy: self.OrderBy, } if len(self.SetupTimeStart) != 0 { if sTimeStart, err := ParseTimeDetectLayout(self.SetupTimeStart, timezone); err != nil {