diff --git a/apier/v1/cdre.go b/apier/v1/cdre.go index dff707651..329e3c719 100644 --- a/apier/v1/cdre.go +++ b/apier/v1/cdre.go @@ -133,19 +133,6 @@ func (self *ApierV1) ExportCdrsToFile(attr utils.AttrExpFileCdrs, reply *utils.E if exportFormat == utils.DRYRUN { filePath = utils.DRYRUN } - usageMultiplyFactor := exportTemplate.UsageMultiplyFactor - if attr.DataUsageMultiplyFactor != nil && *attr.DataUsageMultiplyFactor != 0.0 { - usageMultiplyFactor[utils.DATA] = *attr.DataUsageMultiplyFactor - } - if attr.SmsUsageMultiplyFactor != nil && *attr.SmsUsageMultiplyFactor != 0.0 { - usageMultiplyFactor[utils.SMS] = *attr.SmsUsageMultiplyFactor - } - if attr.MmsUsageMultiplyFactor != nil && *attr.MmsUsageMultiplyFactor != 0.0 { - usageMultiplyFactor[utils.MMS] = *attr.MmsUsageMultiplyFactor - } - if attr.GenericUsageMultiplyFactor != nil && *attr.GenericUsageMultiplyFactor != 0.0 { - usageMultiplyFactor[utils.GENERIC] = *attr.GenericUsageMultiplyFactor - } costMultiplyFactor := exportTemplate.CostMultiplyFactor if attr.CostMultiplyFactor != nil && *attr.CostMultiplyFactor != 0.0 { costMultiplyFactor = *attr.CostMultiplyFactor @@ -163,7 +150,7 @@ func (self *ApierV1) ExportCdrsToFile(attr utils.AttrExpFileCdrs, reply *utils.E } cdrexp, err := engine.NewCDRExporter(cdrs, exportTemplate, exportFormat, filePath, utils.META_NONE, exportID, exportTemplate.Synchronous, - exportTemplate.Attempts, fieldSep, usageMultiplyFactor, costMultiplyFactor, + exportTemplate.Attempts, fieldSep, costMultiplyFactor, self.Config.GeneralCfg().RoundingDecimals, self.Config.GeneralCfg().HttpSkipTlsVerify, self.HTTPPoster, self.FilterS) if err != nil { @@ -211,7 +198,6 @@ type ArgExportCDRs struct { Synchronous *bool Attempts *int FieldSeparator *string - UsageMultiplyFactor utils.FieldMultiplyFactor CostMultiplyFactor *float64 ExportID *string // Optional exportid ExportFileName *string // If provided the output filename will be set to this @@ -295,10 +281,6 @@ func (self *ApierV1) ExportCDRs(arg ArgExportCDRs, reply *RplExportedCDRs) (err u.Path = path.Join(u.Path, fileName) filePath = u.String() } - usageMultiplyFactor := exportTemplate.UsageMultiplyFactor - for k, v := range arg.UsageMultiplyFactor { - usageMultiplyFactor[k] = v - } costMultiplyFactor := exportTemplate.CostMultiplyFactor if arg.CostMultiplyFactor != nil && *arg.CostMultiplyFactor != 0.0 { costMultiplyFactor = *arg.CostMultiplyFactor @@ -319,7 +301,7 @@ func (self *ApierV1) ExportCDRs(arg ArgExportCDRs, reply *RplExportedCDRs) (err } cdrexp, err := engine.NewCDRExporter(cdrs, exportTemplate, exportFormat, filePath, utils.META_NONE, exportID, - synchronous, attempts, fieldSep, usageMultiplyFactor, + synchronous, attempts, fieldSep, costMultiplyFactor, roundingDecimals, self.Config.GeneralCfg().HttpSkipTlsVerify, self.HTTPPoster, self.FilterS) diff --git a/apier/v2/cdre.go b/apier/v2/cdre.go index 44f025650..0d978bbeb 100644 --- a/apier/v2/cdre.go +++ b/apier/v2/cdre.go @@ -31,20 +31,16 @@ import ( ) type AttrExportCdrsToFile struct { - CdrFormat *string // Cdr output file format - FieldSeparator *string // Separator used between fields - ExportID *string // Optional exportid - ExportDirectory *string // If provided it overwrites the configured export directory - ExportFileName *string // If provided the output filename will be set to this - ExportTemplate *string // Exported fields template <""|fld1,fld2|> - DataUsageMultiplyFactor *float64 // Multiply data usage before export (eg: convert from KBytes to Bytes) - SMSUsageMultiplyFactor *float64 // Multiply sms usage before export (eg: convert from SMS unit to call duration for some billing systems) - MMSUsageMultiplyFactor *float64 // Multiply mms usage before export (eg: convert from MMS unit to call duration for some billing systems) - GenericUsageMultiplyFactor *float64 // Multiply generic usage before export (eg: convert from GENERIC unit to call duration for some billing systems) - CostMultiplyFactor *float64 // Multiply the cost before export, eg: apply VAT - RoundingDecimals *int // force rounding to this value - Verbose bool // Disable CgrIds reporting in reply/ExportedCgrIds and reply/UnexportedCgrIds - utils.RPCCDRsFilter // Inherit the CDR filter attributes + CdrFormat *string // Cdr output file format + FieldSeparator *string // Separator used between fields + ExportID *string // Optional exportid + ExportDirectory *string // If provided it overwrites the configured export directory + ExportFileName *string // If provided the output filename will be set to this + ExportTemplate *string // Exported fields template <""|fld1,fld2|> + CostMultiplyFactor *float64 // Multiply the cost before export, eg: apply VAT + RoundingDecimals *int // force rounding to this value + Verbose bool // Disable CgrIds reporting in reply/ExportedCgrIds and reply/UnexportedCgrIds + utils.RPCCDRsFilter // Inherit the CDR filter attributes } type ExportedFileCdrs struct { @@ -106,19 +102,6 @@ func (self *ApierV2) ExportCdrsToFile(attr AttrExportCdrsToFile, reply *Exported if exportFormat == utils.DRYRUN { filePath = utils.DRYRUN } - usageMultiplyFactor := exportTemplate.UsageMultiplyFactor - if attr.DataUsageMultiplyFactor != nil && *attr.DataUsageMultiplyFactor != 0.0 { - usageMultiplyFactor[utils.DATA] = *attr.DataUsageMultiplyFactor - } - if attr.SMSUsageMultiplyFactor != nil && *attr.SMSUsageMultiplyFactor != 0.0 { - usageMultiplyFactor[utils.SMS] = *attr.SMSUsageMultiplyFactor - } - if attr.MMSUsageMultiplyFactor != nil && *attr.MMSUsageMultiplyFactor != 0.0 { - usageMultiplyFactor[utils.MMS] = *attr.MMSUsageMultiplyFactor - } - if attr.GenericUsageMultiplyFactor != nil && *attr.GenericUsageMultiplyFactor != 0.0 { - usageMultiplyFactor[utils.GENERIC] = *attr.GenericUsageMultiplyFactor - } costMultiplyFactor := exportTemplate.CostMultiplyFactor if attr.CostMultiplyFactor != nil && *attr.CostMultiplyFactor != 0.0 { costMultiplyFactor = *attr.CostMultiplyFactor @@ -140,7 +123,7 @@ func (self *ApierV2) ExportCdrsToFile(attr AttrExportCdrsToFile, reply *Exported } cdrexp, err := engine.NewCDRExporter(cdrs, exportTemplate, exportFormat, filePath, utils.META_NONE, exportID, exportTemplate.Synchronous, - exportTemplate.Attempts, fieldSep, usageMultiplyFactor, costMultiplyFactor, + exportTemplate.Attempts, fieldSep, costMultiplyFactor, roundingDecimals, self.Config.GeneralCfg().HttpSkipTlsVerify, self.HTTPPoster, self.FilterS) if err != nil { @@ -153,7 +136,8 @@ func (self *ApierV2) ExportCdrsToFile(attr AttrExportCdrsToFile, reply *Exported *reply = ExportedFileCdrs{ExportedFilePath: ""} return nil } - *reply = ExportedFileCdrs{ExportedFilePath: filePath, TotalRecords: len(cdrs), TotalCost: cdrexp.TotalCost(), FirstOrderId: cdrexp.FirstOrderId(), LastOrderId: cdrexp.LastOrderId()} + *reply = ExportedFileCdrs{ExportedFilePath: filePath, TotalRecords: len(cdrs), + TotalCost: cdrexp.TotalCost(), FirstOrderId: cdrexp.FirstOrderId(), LastOrderId: cdrexp.LastOrderId()} if !attr.Verbose { reply.ExportedCgrIds = cdrexp.PositiveExports() reply.UnexportedCgrIds = cdrexp.NegativeExports() diff --git a/config/cdrecfg.go b/config/cdrecfg.go index 5149b5781..f12aa32d1 100644 --- a/config/cdrecfg.go +++ b/config/cdrecfg.go @@ -18,24 +18,19 @@ along with this program. If not, see package config -import ( - "github.com/cgrates/cgrates/utils" -) - // One instance of CdrExporter type CdreCfg struct { - ExportFormat string - ExportPath string - Filters []string - Tenant string - Synchronous bool - Attempts int - FieldSeparator rune - UsageMultiplyFactor utils.FieldMultiplyFactor - CostMultiplyFactor float64 - HeaderFields []*FCTemplate - ContentFields []*FCTemplate - TrailerFields []*FCTemplate + ExportFormat string + ExportPath string + Filters []string + Tenant string + Synchronous bool + Attempts int + FieldSeparator rune + CostMultiplyFactor float64 + HeaderFields []*FCTemplate + ContentFields []*FCTemplate + TrailerFields []*FCTemplate } func (self *CdreCfg) loadFromJsonCfg(jsnCfg *CdreJsonCfg, separator string) (err error) { @@ -67,14 +62,6 @@ func (self *CdreCfg) loadFromJsonCfg(jsnCfg *CdreJsonCfg, separator string) (err sepStr := *jsnCfg.Field_separator self.FieldSeparator = rune(sepStr[0]) } - if jsnCfg.Usage_multiply_factor != nil { - if self.UsageMultiplyFactor == nil { // not yet initialized - self.UsageMultiplyFactor = make(map[string]float64, len(*jsnCfg.Usage_multiply_factor)) - } - for k, v := range *jsnCfg.Usage_multiply_factor { - self.UsageMultiplyFactor[k] = v - } - } if jsnCfg.Cost_multiply_factor != nil { self.CostMultiplyFactor = *jsnCfg.Cost_multiply_factor } @@ -105,10 +92,6 @@ func (self *CdreCfg) Clone() *CdreCfg { clnCdre.Attempts = self.Attempts clnCdre.FieldSeparator = self.FieldSeparator clnCdre.Tenant = self.Tenant - clnCdre.UsageMultiplyFactor = make(map[string]float64, len(self.UsageMultiplyFactor)) - for k, v := range self.UsageMultiplyFactor { - clnCdre.UsageMultiplyFactor[k] = v - } clnCdre.Filters = make([]string, len(self.Filters)) for i, fltr := range self.Filters { clnCdre.Filters[i] = fltr diff --git a/config/cdrecfg_test.go b/config/cdrecfg_test.go index 7a7b0635b..7bdfee6fb 100644 --- a/config/cdrecfg_test.go +++ b/config/cdrecfg_test.go @@ -40,15 +40,11 @@ func TestCdreCfgClone(t *testing.T) { Value: runIdRsrs}, } initCdreCfg := &CdreCfg{ - ExportFormat: utils.MetaFileCSV, - ExportPath: "/var/spool/cgrates/cdre", - Synchronous: true, - Attempts: 2, - FieldSeparator: rune(','), - UsageMultiplyFactor: map[string]float64{ - utils.ANY: 1.0, - utils.DATA: 1024, - }, + ExportFormat: utils.MetaFileCSV, + ExportPath: "/var/spool/cgrates/cdre", + Synchronous: true, + Attempts: 2, + FieldSeparator: rune(','), CostMultiplyFactor: 1.0, ContentFields: initContentFlds, } @@ -63,16 +59,12 @@ func TestCdreCfgClone(t *testing.T) { Value: runIdRsrs}, } eClnCdreCfg := &CdreCfg{ - ExportFormat: utils.MetaFileCSV, - ExportPath: "/var/spool/cgrates/cdre", - Synchronous: true, - Attempts: 2, - Filters: []string{}, - FieldSeparator: rune(','), - UsageMultiplyFactor: map[string]float64{ - utils.ANY: 1.0, - utils.DATA: 1024.0, - }, + ExportFormat: utils.MetaFileCSV, + ExportPath: "/var/spool/cgrates/cdre", + Synchronous: true, + Attempts: 2, + Filters: []string{}, + FieldSeparator: rune(','), CostMultiplyFactor: 1.0, HeaderFields: emptyFields, ContentFields: eClnContentFlds, @@ -82,10 +74,6 @@ func TestCdreCfgClone(t *testing.T) { if !reflect.DeepEqual(eClnCdreCfg, clnCdreCfg) { t.Errorf("Cloned result: %+v", clnCdreCfg) } - initCdreCfg.UsageMultiplyFactor[utils.DATA] = 2048.0 - if !reflect.DeepEqual(eClnCdreCfg, clnCdreCfg) { // MOdifying a field after clone should not affect cloned instance - t.Errorf("Cloned result: %+v", clnCdreCfg) - } initContentFlds[0].Tag = "Destination" if !reflect.DeepEqual(eClnCdreCfg, clnCdreCfg) { // MOdifying a field after clone should not affect cloned instance t.Errorf("Cloned result: %+v", clnCdreCfg) @@ -119,9 +107,6 @@ func TestCdreCfgloadFromJsonCfg(t *testing.T) { "synchronous": false, // block processing until export has a result "attempts": 1, // Number of attempts if not success "field_separator": ",", // used field separator in some export formats, eg: *file_csv - "usage_multiply_factor": { - "*any": 1 // multiply usage based on ToR field or *any for all - }, "cost_multiply_factor": 1, // multiply cost before export, eg: add VAT "header_fields": [], // template of the exported header fields "content_fields": [ // template of the exported content fields @@ -136,15 +121,14 @@ func TestCdreCfgloadFromJsonCfg(t *testing.T) { t.Error(err) } expected = CdreCfg{ - ExportFormat: "*file_csv", - ExportPath: "/var/spool/cgrates/cdre", - Filters: []string{}, - Tenant: "cgrates.org", - Attempts: 1, - FieldSeparator: ',', - UsageMultiplyFactor: map[string]float64{"*any": 1}, - CostMultiplyFactor: 1, - HeaderFields: []*FCTemplate{}, + ExportFormat: "*file_csv", + ExportPath: "/var/spool/cgrates/cdre", + Filters: []string{}, + Tenant: "cgrates.org", + Attempts: 1, + FieldSeparator: ',', + CostMultiplyFactor: 1, + HeaderFields: []*FCTemplate{}, ContentFields: []*FCTemplate{{ Tag: "CGRID", Type: "*composed", diff --git a/config/config_defaults.go b/config/config_defaults.go index 5f05ece83..15993bfe2 100755 --- a/config/config_defaults.go +++ b/config/config_defaults.go @@ -212,9 +212,6 @@ const CGRATES_CFG_JSON = ` "synchronous": false, // block processing until export has a result "attempts": 1, // export attempts "field_separator": ",", // used field separator in some export formats, eg: *file_csv - "usage_multiply_factor": { - "*any": 1 // multiply usage based on ToR field or *any for all - }, "cost_multiply_factor": 1, // multiply cost before export, eg: add VAT "header_fields": [], // template of the exported header fields "content_fields": [ // template of the exported content fields diff --git a/config/config_json_test.go b/config/config_json_test.go index f4f9cd89c..44e12f4b2 100755 --- a/config/config_json_test.go +++ b/config/config_json_test.go @@ -344,18 +344,17 @@ func TestDfCdreJsonCfgs(t *testing.T) { } eCfg := map[string]*CdreJsonCfg{ utils.META_DEFAULT: { - Export_format: utils.StringPointer(utils.MetaFileCSV), - Export_path: utils.StringPointer("/var/spool/cgrates/cdre"), - Synchronous: utils.BoolPointer(false), - Attempts: utils.IntPointer(1), - Tenant: utils.StringPointer(""), - Field_separator: utils.StringPointer(","), - Usage_multiply_factor: &map[string]float64{utils.ANY: 1.0}, - Cost_multiply_factor: utils.Float64Pointer(1.0), - Header_fields: &eFields, - Content_fields: &eContentFlds, - Trailer_fields: &eFields, - Filters: &[]string{}, + Export_format: utils.StringPointer(utils.MetaFileCSV), + Export_path: utils.StringPointer("/var/spool/cgrates/cdre"), + Synchronous: utils.BoolPointer(false), + Attempts: utils.IntPointer(1), + Tenant: utils.StringPointer(""), + Field_separator: utils.StringPointer(","), + Cost_multiply_factor: utils.Float64Pointer(1.0), + Header_fields: &eFields, + Content_fields: &eContentFlds, + Trailer_fields: &eFields, + Filters: &[]string{}, }, } if cfg, err := dfCgrJsonCfg.CdreJsonCfgs(); err != nil { diff --git a/config/config_test.go b/config/config_test.go index edaae42ec..50b5faa31 100755 --- a/config/config_test.go +++ b/config/config_test.go @@ -600,17 +600,16 @@ func TestCgrCfgJSONDefaultsCdreProfiles(t *testing.T) { } eCdreCfg := map[string]*CdreCfg{ utils.MetaDefault: { - ExportFormat: utils.MetaFileCSV, - ExportPath: "/var/spool/cgrates/cdre", - Filters: []string{}, - Synchronous: false, - Attempts: 1, - FieldSeparator: ',', - UsageMultiplyFactor: map[string]float64{utils.ANY: 1.0}, - CostMultiplyFactor: 1.0, - HeaderFields: eFields, - ContentFields: eContentFlds, - TrailerFields: eFields, + ExportFormat: utils.MetaFileCSV, + ExportPath: "/var/spool/cgrates/cdre", + Filters: []string{}, + Synchronous: false, + Attempts: 1, + FieldSeparator: ',', + CostMultiplyFactor: 1.0, + HeaderFields: eFields, + ContentFields: eContentFlds, + TrailerFields: eFields, }, } if !reflect.DeepEqual(cgrCfg.CdreProfiles, eCdreCfg) { diff --git a/config/libconfig_json.go b/config/libconfig_json.go index 18922f13d..1a328477e 100755 --- a/config/libconfig_json.go +++ b/config/libconfig_json.go @@ -164,18 +164,17 @@ type CdrFieldJsonCfg struct { // Cdre config section type CdreJsonCfg struct { - Export_format *string - Export_path *string - Filters *[]string - Tenant *string - Synchronous *bool - Attempts *int - Field_separator *string - Usage_multiply_factor *map[string]float64 - Cost_multiply_factor *float64 - Header_fields *[]*FcTemplateJsonCfg - Content_fields *[]*FcTemplateJsonCfg - Trailer_fields *[]*FcTemplateJsonCfg + Export_format *string + Export_path *string + Filters *[]string + Tenant *string + Synchronous *bool + Attempts *int + Field_separator *string + Cost_multiply_factor *float64 + Header_fields *[]*FcTemplateJsonCfg + Content_fields *[]*FcTemplateJsonCfg + Trailer_fields *[]*FcTemplateJsonCfg } // Cdrc config section diff --git a/engine/cdr.go b/engine/cdr.go index 2a9566ce3..537ba7867 100644 --- a/engine/cdr.go +++ b/engine/cdr.go @@ -140,11 +140,6 @@ func (cdr *CDR) ComputeCGRID() { cdr.CGRID = utils.Sha1(cdr.OriginID, cdr.OriginHost) } -// Used to multiply usage on export -func (cdr *CDR) UsageMultiply(multiplyFactor float64, roundDecimals int) { - cdr.Usage = time.Duration(int(utils.Round(float64(cdr.Usage.Nanoseconds())*multiplyFactor, roundDecimals, utils.ROUNDING_MIDDLE))) // Rounding down could introduce a slight loss here but only at nanoseconds level -} - // Used to multiply cost on export func (cdr *CDR) CostMultiply(multiplyFactor float64, roundDecimals int) { cdr.Cost = utils.Round(cdr.Cost*multiplyFactor, roundDecimals, utils.ROUNDING_MIDDLE) diff --git a/engine/cdr_test.go b/engine/cdr_test.go index f9027c94d..b4b99e54c 100644 --- a/engine/cdr_test.go +++ b/engine/cdr_test.go @@ -286,18 +286,6 @@ func TestFieldAsStringForCostDetails(t *testing.T) { } } -func TestUsageMultiply(t *testing.T) { - cdr := CDR{Usage: time.Duration(10) * time.Second} - if cdr.UsageMultiply(1024.0, 0); cdr.Usage != time.Duration(10240)*time.Second { - t.Errorf("Unexpected usage after multiply: %v", cdr.Usage.Nanoseconds()) - } - cdr = CDR{Usage: time.Duration(10240) * time.Second} // Simulate conversion back, gives out a bit odd result but this can be rounded on export - expectDuration, _ := time.ParseDuration("10.000005120s") - if cdr.UsageMultiply(0.000976563, 0); cdr.Usage != expectDuration { - t.Errorf("Unexpected usage after multiply: %v", cdr.Usage.Nanoseconds()) - } -} - func TestCostMultiply(t *testing.T) { cdr := CDR{Cost: 1.01} if cdr.CostMultiply(1.19, 4); cdr.Cost != 1.2019 { diff --git a/engine/cdre.go b/engine/cdre.go index 068d5bbc3..df7437c13 100644 --- a/engine/cdre.go +++ b/engine/cdre.go @@ -51,48 +51,46 @@ const ( ) func NewCDRExporter(cdrs []*CDR, exportTemplate *config.CdreCfg, exportFormat, exportPath, fallbackPath, exportID string, - synchronous bool, attempts int, fieldSeparator rune, usageMultiplyFactor utils.FieldMultiplyFactor, - costMultiplyFactor float64, roundingDecimals int, httpSkipTlsCheck bool, httpPoster *HTTPPoster, filterS *FilterS) (*CDRExporter, error) { + synchronous bool, attempts int, fieldSeparator rune, costMultiplyFactor float64, roundingDecimals int, + httpSkipTlsCheck bool, httpPoster *HTTPPoster, filterS *FilterS) (*CDRExporter, error) { if len(cdrs) == 0 { // Nothing to export return nil, nil } cdre := &CDRExporter{ - cdrs: cdrs, - exportTemplate: exportTemplate, - exportFormat: exportFormat, - exportPath: exportPath, - fallbackPath: fallbackPath, - exportID: exportID, - synchronous: synchronous, - attempts: attempts, - fieldSeparator: fieldSeparator, - usageMultiplyFactor: usageMultiplyFactor, - costMultiplyFactor: costMultiplyFactor, - roundingDecimals: roundingDecimals, - httpSkipTlsCheck: httpSkipTlsCheck, - httpPoster: httpPoster, - negativeExports: make(map[string]string), - filterS: filterS, + cdrs: cdrs, + exportTemplate: exportTemplate, + exportFormat: exportFormat, + exportPath: exportPath, + fallbackPath: fallbackPath, + exportID: exportID, + synchronous: synchronous, + attempts: attempts, + fieldSeparator: fieldSeparator, + costMultiplyFactor: costMultiplyFactor, + roundingDecimals: roundingDecimals, + httpSkipTlsCheck: httpSkipTlsCheck, + httpPoster: httpPoster, + negativeExports: make(map[string]string), + filterS: filterS, } return cdre, nil } type CDRExporter struct { sync.RWMutex - cdrs []*CDR - exportTemplate *config.CdreCfg - exportFormat string - exportPath string - fallbackPath string // folder where we save failed CDRs - exportID string // Unique identifier or this export - synchronous bool - attempts int - fieldSeparator rune - usageMultiplyFactor utils.FieldMultiplyFactor - costMultiplyFactor float64 - roundingDecimals int - httpSkipTlsCheck bool - httpPoster *HTTPPoster + cdrs []*CDR + exportTemplate *config.CdreCfg + exportFormat string + exportPath string + fallbackPath string // folder where we save failed CDRs + exportID string // Unique identifier or this export + synchronous bool + attempts int + fieldSeparator rune + costMultiplyFactor float64 + roundingDecimals int + httpSkipTlsCheck bool + httpPoster *HTTPPoster header, trailer []string // Header and Trailer fields content [][]string // Rows of cdr fields @@ -298,13 +296,6 @@ func (cdre *CDRExporter) processCDR(cdr *CDR) (err error) { if cdr.ExtraFields == nil { // Avoid assignment in nil map if not initialized cdr.ExtraFields = make(map[string]string) } - // Usage multiply, find config based on ToR field or *any - for _, key := range []string{cdr.ToR, utils.ANY} { - if uM, hasIt := cdre.usageMultiplyFactor[key]; hasIt && uM != 1.0 { - cdr.UsageMultiply(uM, cdre.roundingDecimals) - break - } - } if cdre.costMultiplyFactor != 0.0 { cdr.CostMultiply(cdre.costMultiplyFactor, cdre.roundingDecimals) } diff --git a/engine/cdrecsv_test.go b/engine/cdrecsv_test.go index 9e5dbfa62..cc5388a87 100644 --- a/engine/cdrecsv_test.go +++ b/engine/cdrecsv_test.go @@ -45,7 +45,7 @@ func TestCsvCdrWriter(t *testing.T) { } cdre, err := NewCDRExporter([]*CDR{storedCdr1}, cfg.CdreProfiles[utils.MetaDefault], utils.MetaFileCSV, "", "", "firstexport", - true, 1, ',', map[string]float64{}, 0.0, cfg.GeneralCfg().RoundingDecimals, + true, 1, ',', 0.0, cfg.GeneralCfg().RoundingDecimals, cfg.GeneralCfg().HttpSkipTlsVerify, nil, nil) if err != nil { t.Error("Unexpected error received: ", err) @@ -84,7 +84,7 @@ func TestAlternativeFieldSeparator(t *testing.T) { } cdre, err := NewCDRExporter([]*CDR{storedCdr1}, cfg.CdreProfiles[utils.MetaDefault], utils.MetaFileCSV, "", "", "firstexport", true, 1, '|', - map[string]float64{}, 0.0, cfg.GeneralCfg().RoundingDecimals, + 0.0, cfg.GeneralCfg().RoundingDecimals, cfg.GeneralCfg().HttpSkipTlsVerify, nil, nil) if err != nil { t.Error("Unexpected error received: ", err) @@ -179,7 +179,7 @@ func TestExportVoiceWithConvert(t *testing.T) { } cdre, err := NewCDRExporter([]*CDR{cdrVoice, cdrData, cdrSMS}, cdreCfg, utils.MetaFileCSV, "", "", "firstexport", - true, 1, '|', map[string]float64{}, 0.0, + true, 1, '|', 0.0, 5, true, nil, &FilterS{cfg: cfg}) if err != nil { t.Error("Unexpected error received: ", err) @@ -277,7 +277,7 @@ func TestExportWithFilter(t *testing.T) { } cdre, err := NewCDRExporter([]*CDR{cdrVoice, cdrData, cdrSMS}, cdreCfg, utils.MetaFileCSV, "", "", "firstexport", - true, 1, '|', map[string]float64{}, 0.0, + true, 1, '|', 0.0, 5, true, nil, &FilterS{cfg: cfg}) if err != nil { t.Error("Unexpected error received: ", err) @@ -374,7 +374,7 @@ func TestExportWithFilter2(t *testing.T) { } cdre, err := NewCDRExporter([]*CDR{cdrVoice, cdrData, cdrSMS}, cdreCfg, utils.MetaFileCSV, "", "", "firstexport", - true, 1, '|', map[string]float64{}, 0.0, + true, 1, '|', 0.0, 5, true, nil, &FilterS{cfg: cfg}) if err != nil { t.Error("Unexpected error received: ", err) diff --git a/engine/cdrefwv_test.go b/engine/cdrefwv_test.go index 1a186e073..5d4b35c6b 100644 --- a/engine/cdrefwv_test.go +++ b/engine/cdrefwv_test.go @@ -282,7 +282,7 @@ func TestWriteCdr(t *testing.T) { } cdre, err := NewCDRExporter([]*CDR{cdr}, cdreCfg, utils.MetaFileFWV, "", "", "fwv_1", - true, 1, '|', map[string]float64{}, 0.0, cfg.GeneralCfg().RoundingDecimals, + true, 1, '|', 0.0, cfg.GeneralCfg().RoundingDecimals, cfg.GeneralCfg().HttpSkipTlsVerify, nil, nil) if err != nil { t.Error(err) @@ -369,7 +369,7 @@ func TestWriteCdrs(t *testing.T) { } cfg, _ := config.NewDefaultCGRConfig() cdre, err := NewCDRExporter([]*CDR{cdr1, cdr2, cdr3, cdr4}, cdreCfg, - utils.MetaFileFWV, "", "", "fwv_1", true, 1, ',', map[string]float64{}, + utils.MetaFileFWV, "", "", "fwv_1", true, 1, ',', 0.0, cfg.GeneralCfg().RoundingDecimals, cfg.GeneralCfg().HttpSkipTlsVerify, nil, nil) if err != nil { diff --git a/engine/cdrs.go b/engine/cdrs.go index eecfba9ac..a5beba0ed 100644 --- a/engine/cdrs.go +++ b/engine/cdrs.go @@ -387,8 +387,7 @@ func (cdrS *CDRServer) exportCDRs(cdrs []*CDR) (err error) { if cdre, err = NewCDRExporter(cdrs, expTpl, expTpl.ExportFormat, expTpl.ExportPath, cdrS.cgrCfg.GeneralCfg().FailedPostsDir, "CDRSReplication", expTpl.Synchronous, expTpl.Attempts, - expTpl.FieldSeparator, expTpl.UsageMultiplyFactor, - expTpl.CostMultiplyFactor, cdrS.cgrCfg.GeneralCfg().RoundingDecimals, + expTpl.FieldSeparator, expTpl.CostMultiplyFactor, cdrS.cgrCfg.GeneralCfg().RoundingDecimals, cdrS.cgrCfg.GeneralCfg().HttpSkipTlsVerify, cdrS.httpPoster, cdrS.filterS); err != nil { utils.Logger.Err(fmt.Sprintf(" Building CDRExporter for online exports got error: <%s>", err.Error())) diff --git a/utils/apitpdata.go b/utils/apitpdata.go index 8319d7b18..e1afa54a9 100755 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -524,35 +524,31 @@ type CacheKeys struct { } type AttrExpFileCdrs struct { - CdrFormat *string // Cdr output file format - FieldSeparator *string // Separator used between fields - ExportId *string // Optional exportid - ExportDir *string // If provided it overwrites the configured export directory - ExportFileName *string // If provided the output filename will be set to this - ExportTemplate *string // Exported fields template <""|fld1,fld2|*xml:instance_name> - DataUsageMultiplyFactor *float64 // Multiply data usage before export (eg: convert from KBytes to Bytes) - SmsUsageMultiplyFactor *float64 // Multiply sms usage before export (eg: convert from SMS unit to call duration for some billing systems) - MmsUsageMultiplyFactor *float64 // Multiply mms usage before export (eg: convert from MMS unit to call duration for some billing systems) - GenericUsageMultiplyFactor *float64 // Multiply generic usage before export (eg: convert from GENERIC unit to call duration for some billing systems) - CostMultiplyFactor *float64 // Multiply the cost before export, eg: apply VAT - CgrIds []string // If provided, it will filter based on the cgrids present in list - MediationRunIds []string // If provided, it will filter on mediation runid - TORs []string // If provided, filter on TypeOfRecord - CdrHosts []string // If provided, it will filter cdrhost - CdrSources []string // If provided, it will filter cdrsource - ReqTypes []string // If provided, it will fiter reqtype - Tenants []string // If provided, it will filter tenant - Categories []string // If provided, it will filter çategory - 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 - 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 (>=) - 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 - SuppressCgrIds bool // Disable CgrIds reporting in reply/ExportedCgrIds and reply/UnexportedCgrIds + CdrFormat *string // Cdr output file format + FieldSeparator *string // Separator used between fields + ExportId *string // Optional exportid + ExportDir *string // If provided it overwrites the configured export directory + ExportFileName *string // If provided the output filename will be set to this + ExportTemplate *string // Exported fields template <""|fld1,fld2|*xml:instance_name> + CostMultiplyFactor *float64 // Multiply the cost before export, eg: apply VAT + CgrIds []string // If provided, it will filter based on the cgrids present in list + MediationRunIds []string // If provided, it will filter on mediation runid + TORs []string // If provided, filter on TypeOfRecord + CdrHosts []string // If provided, it will filter cdrhost + CdrSources []string // If provided, it will filter cdrsource + ReqTypes []string // If provided, it will fiter reqtype + Tenants []string // If provided, it will filter tenant + Categories []string // If provided, it will filter çategory + 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 + 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 (>=) + 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 + SuppressCgrIds bool // Disable CgrIds reporting in reply/ExportedCgrIds and reply/UnexportedCgrIds Paginator }