diff --git a/apier/v1/cdre.go b/apier/v1/cdre.go index 600781b39..92d4b0fe9 100644 --- a/apier/v1/cdre.go +++ b/apier/v1/cdre.go @@ -147,7 +147,6 @@ 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, - self.Config.GeneralCfg().RoundingDecimals, self.Config.GeneralCfg().HttpSkipTlsVerify, self.HTTPPoster, self.FilterS) if err != nil { return utils.NewErrServerError(err) @@ -196,7 +195,6 @@ type ArgExportCDRs struct { FieldSeparator *string ExportID *string // Optional exportid ExportFileName *string // If provided the output filename will be set to this - 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 } @@ -276,10 +274,6 @@ func (self *ApierV1) ExportCDRs(arg ArgExportCDRs, reply *RplExportedCDRs) (err u.Path = path.Join(u.Path, fileName) filePath = u.String() } - roundingDecimals := self.Config.GeneralCfg().RoundingDecimals - if arg.RoundingDecimals != nil { - roundingDecimals = *arg.RoundingDecimals - } cdrsFltr, err := arg.RPCCDRsFilter.AsCDRsFilter(self.Config.GeneralCfg().DefaultTimezone) if err != nil { return utils.NewErrServerError(err) @@ -292,7 +286,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, roundingDecimals, + synchronous, attempts, fieldSep, self.Config.GeneralCfg().HttpSkipTlsVerify, self.HTTPPoster, self.FilterS) if err != nil { diff --git a/apier/v2/cdre.go b/apier/v2/cdre.go index 0de74f4eb..b42f19a03 100644 --- a/apier/v2/cdre.go +++ b/apier/v2/cdre.go @@ -37,7 +37,6 @@ type AttrExportCdrsToFile struct { 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|> - 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 } @@ -112,14 +111,9 @@ func (self *ApierV2) ExportCdrsToFile(attr AttrExportCdrsToFile, reply *Exported *reply = ExportedFileCdrs{ExportedFilePath: ""} return nil } - roundingDecimals := self.Config.GeneralCfg().RoundingDecimals - if attr.RoundingDecimals != nil { - roundingDecimals = *attr.RoundingDecimals - } cdrexp, err := engine.NewCDRExporter(cdrs, exportTemplate, exportFormat, filePath, utils.META_NONE, exportID, exportTemplate.Synchronous, - exportTemplate.Attempts, fieldSep, - roundingDecimals, self.Config.GeneralCfg().HttpSkipTlsVerify, + exportTemplate.Attempts, fieldSep, self.Config.GeneralCfg().HttpSkipTlsVerify, self.HTTPPoster, self.FilterS) if err != nil { return utils.NewErrServerError(err) diff --git a/cdrc/partial_cdr.go b/cdrc/partial_cdr.go index f5d9b6f92..7221159a1 100644 --- a/cdrc/partial_cdr.go +++ b/cdrc/partial_cdr.go @@ -78,7 +78,7 @@ func (prc *PartialRecordsCache) dumpPartialRecords(originID string) { csvWriter.Comma = prc.csvSep for _, cdr := range prc.partialRecords[originID].cdrs { expRec, err := cdr.AsExportRecord(prc.partialRecords[originID].cacheDumpFields, - prc.httpSkipTlsCheck, nil, prc.roundDecimals, prc.filterS) + prc.httpSkipTlsCheck, nil, prc.filterS) if err != nil { return nil, err } diff --git a/data/conf/samples/cdrc_partcsv/cgrates.json b/data/conf/samples/cdrc_partcsv/cgrates.json index 5934a30e6..13fa73ce0 100644 --- a/data/conf/samples/cdrc_partcsv/cgrates.json +++ b/data/conf/samples/cdrc_partcsv/cgrates.json @@ -63,7 +63,7 @@ {"tag": "SetupTime", "type": "*composed", "value": "~SetupTime", "layout": "2006-01-02T15:04:05Z07:00"}, {"tag": "AnswerTime", "type": "*composed", "value": "~AnswerTime", "layout": "2006-01-02T15:04:05Z07:00"}, {"tag": "Usage", "type": "*composed", "value": "~Usage"}, - {"tag": "Cost", "type": "*composed", "value": "~Cost"}, + {"tag": "Cost", "type": "*composed", "value": "~Cost","rounding_decimals":5}, ], }, { diff --git a/engine/cdr.go b/engine/cdr.go index 6edd1ea22..92f474e04 100644 --- a/engine/cdr.go +++ b/engine/cdr.go @@ -332,16 +332,14 @@ func (cdr *CDR) exportFieldValue(cfgCdrFld *config.FCTemplate, filterS *FilterS) cfgCdrFld.RoundingDecimals) case utils.SetupTime: if cfgCdrFld.Layout == "" { - cdrVal = cdr.SetupTime.Format(time.RFC3339) - } else { - cdrVal = cdr.SetupTime.Format(cfgCdrFld.Layout) + cfgCdrFld.Layout = time.RFC3339 } + cdrVal = cdr.SetupTime.Format(cfgCdrFld.Layout) case utils.AnswerTime: // Format time based on layout if cfgCdrFld.Layout == "" { - cdrVal = cdr.AnswerTime.Format(time.RFC3339) - } else { - cdrVal = cdr.AnswerTime.Format(cfgCdrFld.Layout) + cfgCdrFld.Layout = time.RFC3339 } + cdrVal = cdr.AnswerTime.Format(cfgCdrFld.Layout) case utils.Destination: cdrVal, err = cdr.FieldAsString(rsrFld) if err != nil { @@ -379,10 +377,9 @@ func (cdr *CDR) formatField(cfgFld *config.FCTemplate, httpSkipTlsCheck bool, return "", err } else { if cfgFld.Layout == "" { - outVal = dtFld.Format(time.RFC3339) - } else { - outVal = dtFld.Format(cfgFld.Layout) + cfgFld.Layout = time.RFC3339 } + outVal = dtFld.Format(cfgFld.Layout) } case utils.META_HTTP_POST: var outValByte []byte @@ -423,7 +420,7 @@ func (cdr *CDR) formatField(cfgFld *config.FCTemplate, httpSkipTlsCheck bool, // Used in place where we need to export the CDR based on an export template // ExportRecord is a []string to keep it compatible with encoding/csv Writer func (cdr *CDR) AsExportRecord(exportFields []*config.FCTemplate, - httpSkipTlsCheck bool, groupedCDRs []*CDR, roundingDecs int, filterS *FilterS) (expRecord []string, err error) { + httpSkipTlsCheck bool, groupedCDRs []*CDR, filterS *FilterS) (expRecord []string, err error) { for _, cfgFld := range exportFields { if pass, err := filterS.Pass(cdr.Tenant, cfgFld.Filters, config.NewNavigableMap(cdr.AsMapStringIface())); err != nil { @@ -431,12 +428,6 @@ func (cdr *CDR) AsExportRecord(exportFields []*config.FCTemplate, } else if !pass { continue } - if roundingDecs != 0 { - clnFld := new(config.FCTemplate) // Clone so we can modify the rounding decimals without affecting the template - *clnFld = *cfgFld - clnFld.RoundingDecimals = roundingDecs - cfgFld = clnFld - } if fmtOut, err := cdr.formatField(cfgFld, httpSkipTlsCheck, groupedCDRs, filterS); err != nil { utils.Logger.Warning(fmt.Sprintf(" error: %s exporting field: %s, CDR: %s\n", err.Error(), utils.ToJSON(cfgFld), utils.ToJSON(cdr))) @@ -451,7 +442,7 @@ func (cdr *CDR) AsExportRecord(exportFields []*config.FCTemplate, // AsExportMap converts the CDR into a map[string]string based on export template // Used in real-time replication as well as remote exports func (cdr *CDR) AsExportMap(exportFields []*config.FCTemplate, httpSkipTlsCheck bool, - groupedCDRs []*CDR, roundingDecs int, filterS *FilterS) (expMap map[string]string, err error) { + groupedCDRs []*CDR, filterS *FilterS) (expMap map[string]string, err error) { expMap = make(map[string]string) for _, cfgFld := range exportFields { if pass, err := filterS.Pass(cdr.Tenant, @@ -460,12 +451,6 @@ func (cdr *CDR) AsExportMap(exportFields []*config.FCTemplate, httpSkipTlsCheck } else if !pass { continue } - if roundingDecs != 0 { - clnFld := new(config.FCTemplate) // Clone so we can modify the rounding decimals without affecting the template - *clnFld = *cfgFld - clnFld.RoundingDecimals = roundingDecs - cfgFld = clnFld - } if fmtOut, err := cdr.formatField(cfgFld, httpSkipTlsCheck, groupedCDRs, filterS); err != nil { utils.Logger.Warning(fmt.Sprintf(" error: %s exporting field: %s, CDR: %s\n", err.Error(), utils.ToJSON(cfgFld), utils.ToJSON(cdr))) diff --git a/engine/cdr_test.go b/engine/cdr_test.go index 21e91b84e..f9e806df6 100644 --- a/engine/cdr_test.go +++ b/engine/cdr_test.go @@ -614,7 +614,7 @@ func TestCDRAsExportRecord(t *testing.T) { prsr := config.NewRSRParsersMustCompile(utils.DynamicDataPrefix+utils.Destination, true, utils.INFIELD_SEP) cfgCdrFld := &config.FCTemplate{Tag: "destination", Type: utils.META_COMPOSED, FieldId: utils.Destination, Value: prsr, Timezone: "UTC"} - if expRecord, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, 0, nil); err != nil { + if expRecord, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, nil); err != nil { t.Error(err) } else if expRecord[0] != cdr.Destination { t.Errorf("Expecting:\n%s\nReceived:\n%s", cdr.Destination, expRecord) @@ -627,7 +627,7 @@ func TestCDRAsExportRecord(t *testing.T) { cfgCdrFld = &config.FCTemplate{Tag: "Destination", Type: utils.META_COMPOSED, FieldId: utils.Destination, Value: prsr, MaskDestID: "MASKED_DESTINATIONS", MaskLen: 3} eDst := "+4986517174***" - if expRecord, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, 0, nil); err != nil { + if expRecord, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, nil); err != nil { t.Error(err) } else if expRecord[0] != eDst { t.Errorf("Expecting:\n%s\nReceived:\n%s", eDst, expRecord[0]) @@ -635,7 +635,7 @@ func TestCDRAsExportRecord(t *testing.T) { cfgCdrFld = &config.FCTemplate{Tag: "MaskedDest", Type: utils.MetaMaskedDestination, Value: prsr, MaskDestID: "MASKED_DESTINATIONS"} - if expRecord, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, 0, nil); err != nil { + if expRecord, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, nil); err != nil { t.Error(err) } else if expRecord[0] != "1" { t.Errorf("Expecting:\n%s\nReceived:\n%s", "1", expRecord[0]) @@ -649,7 +649,7 @@ func TestCDRAsExportRecord(t *testing.T) { cfgCdrFld = &config.FCTemplate{Tag: "destination", Type: utils.META_COMPOSED, FieldId: utils.Destination, Value: prsr, Filters: []string{"*string:Tenant:itsyscom.com"}, Timezone: "UTC"} - if rcrd, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, 0, &FilterS{dm: dmForCDR, cfg: defaultCfg}); err != nil { + if rcrd, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, &FilterS{dm: dmForCDR, cfg: defaultCfg}); err != nil { t.Error(err) } else if len(rcrd) != 0 { t.Error("failed using filter") @@ -660,7 +660,7 @@ func TestCDRAsExportRecord(t *testing.T) { layout := "2006-01-02 15:04:05" cfgCdrFld = &config.FCTemplate{Tag: "stop_time", Type: utils.MetaDateTime, FieldId: "stop_time", Value: prsr, Layout: layout, Timezone: "UTC"} - if expRecord, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, 0, &FilterS{dm: dmForCDR, cfg: defaultCfg}); err != nil { + if expRecord, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, &FilterS{dm: dmForCDR, cfg: defaultCfg}); err != nil { t.Error(err) } else if expRecord[0] != "2014-06-11 19:19:00" { t.Error("Expecting: 2014-06-11 19:19:00, got: ", expRecord[0]) @@ -670,7 +670,7 @@ func TestCDRAsExportRecord(t *testing.T) { cfgCdrFld = &config.FCTemplate{Tag: "stop_time", Type: utils.MetaDateTime, FieldId: "stop_time", Value: prsr, Filters: []string{"*string:Tenant:itsyscom.com"}, Layout: layout, Timezone: "UTC"} - if rcrd, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, 0, &FilterS{dm: dmForCDR, cfg: defaultCfg}); err != nil { + if rcrd, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, &FilterS{dm: dmForCDR, cfg: defaultCfg}); err != nil { t.Error(err) } else if len(rcrd) != 0 { t.Error("failed using filter") @@ -680,14 +680,14 @@ func TestCDRAsExportRecord(t *testing.T) { cfgCdrFld = &config.FCTemplate{Tag: "stop_time", Type: utils.MetaDateTime, FieldId: "stop_time", Value: prsr, Layout: layout, Timezone: "UTC"} // Test time parse error - if _, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, 0, nil); err == nil { + if _, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, nil); err == nil { t.Error("Should give error here, got none.") } prsr = config.NewRSRParsersMustCompile("~CostDetails.CGRID", true, utils.INFIELD_SEP) cfgCdrFld = &config.FCTemplate{Tag: "CGRIDFromCostDetails", Type: utils.META_COMPOSED, FieldId: "CGRIDFromCostDetails", Value: prsr} - if expRecord, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, 0, nil); err != nil { + if expRecord, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, nil); err != nil { t.Error(err) } else if expRecord[0] != cdr.CostDetails.CGRID { t.Errorf("Expecting:\n%s\nReceived:\n%s", cdr.CostDetails.CGRID, expRecord) @@ -695,7 +695,7 @@ func TestCDRAsExportRecord(t *testing.T) { prsr = config.NewRSRParsersMustCompile("~CostDetails.AccountSummary.ID", true, utils.INFIELD_SEP) cfgCdrFld = &config.FCTemplate{Tag: "AccountID", Type: utils.META_COMPOSED, FieldId: "CustomAccountID", Value: prsr} - if expRecord, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, 0, nil); err != nil { + if expRecord, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, nil); err != nil { t.Error(err) } else if expRecord[0] != cdr.CostDetails.AccountSummary.ID { t.Errorf("Expecting:\n%s\nReceived:\n%s", cdr.CostDetails.AccountSummary.ID, expRecord) @@ -705,7 +705,7 @@ func TestCDRAsExportRecord(t *testing.T) { prsr = config.NewRSRParsersMustCompile("~CostDetails.RatingFilters", true, utils.INFIELD_SEP) cfgCdrFld = &config.FCTemplate{Tag: "DestinationID", Type: utils.META_COMPOSED, FieldId: "CustomDestinationID", Value: prsr} - if expRecord, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, 0, nil); err != nil { + if expRecord, err := cdr.AsExportRecord([]*config.FCTemplate{cfgCdrFld}, false, nil, nil); err != nil { t.Error(err) } else if expRecord[0] != expected { t.Errorf("Expecting: <%q>,\n Received: <%q>", expected, expRecord[0]) @@ -737,7 +737,7 @@ func TestCDRAsExportMap(t *testing.T) { &config.FCTemplate{FieldId: "FieldExtra1", Type: utils.META_COMPOSED, Value: config.NewRSRParsersMustCompile(utils.DynamicDataPrefix+"field_extr1", true, utils.INFIELD_SEP)}, } - if cdrMp, err := cdr.AsExportMap(expFlds, false, nil, 0, nil); err != nil { + if cdrMp, err := cdr.AsExportMap(expFlds, false, nil, nil); err != nil { t.Error(err) } else if !reflect.DeepEqual(eCDRMp, cdrMp) { t.Errorf("Expecting: %+v, received: %+v", eCDRMp, cdrMp) diff --git a/engine/cdre.go b/engine/cdre.go index 16beba3d9..0f9213a0a 100644 --- a/engine/cdre.go +++ b/engine/cdre.go @@ -51,7 +51,7 @@ const ( ) func NewCDRExporter(cdrs []*CDR, exportTemplate *config.CdreCfg, exportFormat, exportPath, fallbackPath, exportID string, - synchronous bool, attempts int, fieldSeparator rune, roundingDecimals int, + synchronous bool, attempts int, fieldSeparator rune, httpSkipTlsCheck bool, httpPoster *HTTPPoster, filterS *FilterS) (*CDRExporter, error) { if len(cdrs) == 0 { // Nothing to export return nil, nil @@ -66,7 +66,6 @@ func NewCDRExporter(cdrs []*CDR, exportTemplate *config.CdreCfg, exportFormat, e synchronous: synchronous, attempts: attempts, fieldSeparator: fieldSeparator, - roundingDecimals: roundingDecimals, httpSkipTlsCheck: httpSkipTlsCheck, httpPoster: httpPoster, negativeExports: make(map[string]string), @@ -86,7 +85,6 @@ type CDRExporter struct { synchronous bool attempts int fieldSeparator rune - roundingDecimals int httpSkipTlsCheck bool httpPoster *HTTPPoster @@ -135,7 +133,7 @@ func (cdre *CDRExporter) metaHandler(tag, arg string) (string, error) { return cdr.FieldAsString(&config.RSRParser{Rules: "~" + utils.Usage, AllFiltersMatch: true}) case META_COSTCDRS: return strconv.FormatFloat(utils.Round(cdre.totalCost, - cdre.roundingDecimals, utils.ROUNDING_MIDDLE), 'f', -1, 64), nil + globalRoundingDecimals, utils.ROUNDING_MIDDLE), 'f', -1, 64), nil default: return "", fmt.Errorf("Unsupported METATAG: %s", tag) } @@ -243,7 +241,7 @@ func (cdre *CDRExporter) postCdr(cdr *CDR) (err error) { } body = jsn case utils.MetaHTTPjsonMap, utils.MetaAMQPjsonMap, utils.MetaAWSjsonMap, utils.MetaSQSjsonMap: - expMp, err := cdr.AsExportMap(cdre.exportTemplate.ContentFields, cdre.httpSkipTlsCheck, nil, cdre.roundingDecimals, cdre.filterS) + expMp, err := cdr.AsExportMap(cdre.exportTemplate.ContentFields, cdre.httpSkipTlsCheck, nil, cdre.filterS) if err != nil { return err } @@ -253,7 +251,7 @@ func (cdre *CDRExporter) postCdr(cdr *CDR) (err error) { } body = jsn case utils.META_HTTP_POST: - expMp, err := cdr.AsExportMap(cdre.exportTemplate.ContentFields, cdre.httpSkipTlsCheck, nil, cdre.roundingDecimals, cdre.filterS) + expMp, err := cdr.AsExportMap(cdre.exportTemplate.ContentFields, cdre.httpSkipTlsCheck, nil, cdre.filterS) if err != nil { return err } @@ -297,7 +295,7 @@ func (cdre *CDRExporter) processCDR(cdr *CDR) (err error) { switch cdre.exportFormat { case utils.MetaFileFWV, utils.MetaFileCSV: var cdrRow []string - cdrRow, err = cdr.AsExportRecord(cdre.exportTemplate.ContentFields, cdre.httpSkipTlsCheck, cdre.cdrs, cdre.roundingDecimals, cdre.filterS) + cdrRow, err = cdr.AsExportRecord(cdre.exportTemplate.ContentFields, cdre.httpSkipTlsCheck, cdre.cdrs, cdre.filterS) if len(cdrRow) == 0 && err == nil { // No CDR data, most likely no configuration fields defined return } else { @@ -339,7 +337,7 @@ func (cdre *CDRExporter) processCDR(cdr *CDR) (err error) { } if cdr.Cost != -1 { cdre.totalCost += cdr.Cost - cdre.totalCost = utils.Round(cdre.totalCost, cdre.roundingDecimals, utils.ROUNDING_MIDDLE) + cdre.totalCost = utils.Round(cdre.totalCost, globalRoundingDecimals, utils.ROUNDING_MIDDLE) } if cdre.firstExpOrderId > cdr.OrderID || cdre.firstExpOrderId == 0 { cdre.firstExpOrderId = cdr.OrderID diff --git a/engine/cdrecsv_test.go b/engine/cdrecsv_test.go index cb5d0a059..2d3d8b644 100644 --- a/engine/cdrecsv_test.go +++ b/engine/cdrecsv_test.go @@ -45,8 +45,7 @@ func TestCsvCdrWriter(t *testing.T) { } cdre, err := NewCDRExporter([]*CDR{storedCdr1}, cfg.CdreProfiles[utils.MetaDefault], utils.MetaFileCSV, "", "", "firstexport", - true, 1, ',', cfg.GeneralCfg().RoundingDecimals, - cfg.GeneralCfg().HttpSkipTlsVerify, nil, nil) + true, 1, ',', cfg.GeneralCfg().HttpSkipTlsVerify, nil, nil) if err != nil { t.Error("Unexpected error received: ", err) } @@ -57,7 +56,7 @@ func TestCsvCdrWriter(t *testing.T) { if err := cdre.writeCsv(csvWriter); err != nil { t.Error("Unexpected error: ", err) } - expected := `dbafe9c8614c785a65aabd116dd3959c3c56f7f6,*default,*voice,dsafdsaf,*rated,cgrates.org,call,1001,1001,1002,2013-11-07T08:42:25Z,2013-11-07T08:42:26Z,10s,1.01000` + expected := `dbafe9c8614c785a65aabd116dd3959c3c56f7f6,*default,*voice,dsafdsaf,*rated,cgrates.org,call,1001,1001,1002,2013-11-07T08:42:25Z,2013-11-07T08:42:26Z,10s,1.0100` result := strings.TrimSpace(writer.String()) if result != expected { t.Errorf("Expected: \n%s \n received: \n%s.", expected, result) @@ -84,7 +83,6 @@ func TestAlternativeFieldSeparator(t *testing.T) { } cdre, err := NewCDRExporter([]*CDR{storedCdr1}, cfg.CdreProfiles[utils.MetaDefault], utils.MetaFileCSV, "", "", "firstexport", true, 1, '|', - cfg.GeneralCfg().RoundingDecimals, cfg.GeneralCfg().HttpSkipTlsVerify, nil, nil) if err != nil { t.Error("Unexpected error received: ", err) @@ -96,7 +94,7 @@ func TestAlternativeFieldSeparator(t *testing.T) { if err := cdre.writeCsv(csvWriter); err != nil { t.Error("Unexpected error: ", err) } - expected := `dbafe9c8614c785a65aabd116dd3959c3c56f7f6|*default|*voice|dsafdsaf|*rated|cgrates.org|call|1001|1001|1002|2013-11-07T08:42:25Z|2013-11-07T08:42:26Z|10s|1.01000` + expected := `dbafe9c8614c785a65aabd116dd3959c3c56f7f6|*default|*voice|dsafdsaf|*rated|cgrates.org|call|1001|1001|1002|2013-11-07T08:42:25Z|2013-11-07T08:42:26Z|10s|1.0100` result := strings.TrimSpace(writer.String()) if result != expected { t.Errorf("Expected: \n%s received: \n%s.", expected, result) @@ -139,7 +137,7 @@ func TestExportVoiceWithConvert(t *testing.T) { Value: config.NewRSRParsersMustCompile(utils.DynamicDataPrefix+"Usage{*duration_nanoseconds}", true, utils.INFIELD_SEP)}, {Tag: "Cost", Type: "*composed", Value: config.NewRSRParsersMustCompile(utils.DynamicDataPrefix+"Cost", true, utils.INFIELD_SEP), - RoundingDecimals: 4}, + RoundingDecimals: 5}, } cdrVoice := &CDR{ CGRID: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), @@ -179,7 +177,7 @@ func TestExportVoiceWithConvert(t *testing.T) { } cdre, err := NewCDRExporter([]*CDR{cdrVoice, cdrData, cdrSMS}, cdreCfg, utils.MetaFileCSV, "", "", "firstexport", - true, 1, '|', 5, true, nil, &FilterS{cfg: cfg}) + true, 1, '|', true, nil, &FilterS{cfg: cfg}) if err != nil { t.Error("Unexpected error received: ", err) } @@ -236,7 +234,7 @@ func TestExportWithFilter(t *testing.T) { Value: config.NewRSRParsersMustCompile(utils.DynamicDataPrefix+"Usage{*duration_nanoseconds}", true, utils.INFIELD_SEP)}, {Tag: "Cost", Type: "*composed", Value: config.NewRSRParsersMustCompile(utils.DynamicDataPrefix+"Cost", true, utils.INFIELD_SEP), - RoundingDecimals: 4}, + RoundingDecimals: 5}, } cdrVoice := &CDR{ CGRID: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), @@ -276,7 +274,7 @@ func TestExportWithFilter(t *testing.T) { } cdre, err := NewCDRExporter([]*CDR{cdrVoice, cdrData, cdrSMS}, cdreCfg, utils.MetaFileCSV, "", "", "firstexport", - true, 1, '|', 5, true, nil, &FilterS{cfg: cfg}) + true, 1, '|', true, nil, &FilterS{cfg: cfg}) if err != nil { t.Error("Unexpected error received: ", err) } @@ -332,7 +330,7 @@ func TestExportWithFilter2(t *testing.T) { Value: config.NewRSRParsersMustCompile(utils.DynamicDataPrefix+"Usage{*duration_nanoseconds}", true, utils.INFIELD_SEP)}, {Tag: "Cost", Type: "*composed", Value: config.NewRSRParsersMustCompile(utils.DynamicDataPrefix+"Cost", true, utils.INFIELD_SEP), - RoundingDecimals: 4}, + RoundingDecimals: 5}, } cdrVoice := &CDR{ CGRID: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), @@ -372,7 +370,7 @@ func TestExportWithFilter2(t *testing.T) { } cdre, err := NewCDRExporter([]*CDR{cdrVoice, cdrData, cdrSMS}, cdreCfg, utils.MetaFileCSV, "", "", "firstexport", - true, 1, '|', 5, true, nil, &FilterS{cfg: cfg}) + true, 1, '|', 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 86c221bd2..24ed500c8 100644 --- a/engine/cdrefwv_test.go +++ b/engine/cdrefwv_test.go @@ -183,11 +183,12 @@ var contentJsnCfgFlds = []*config.FcTemplateJsonCfg{ Strip: utils.StringPointer("right"), Padding: utils.StringPointer("right")}, { - Tag: utils.StringPointer("Cost"), - Type: utils.StringPointer(utils.META_COMPOSED), - Width: utils.IntPointer(9), - Value: utils.StringPointer("~" + utils.COST), - Padding: utils.StringPointer("zeroleft")}, + Tag: utils.StringPointer("Cost"), + Type: utils.StringPointer(utils.META_COMPOSED), + Width: utils.IntPointer(9), + Value: utils.StringPointer("~" + utils.COST), + Padding: utils.StringPointer("zeroleft"), + Rounding_decimals: utils.IntPointer(5)}, { Tag: utils.StringPointer("DestinationPrivacy"), Type: utils.StringPointer(utils.MetaMaskedDestination), @@ -282,8 +283,7 @@ func TestWriteCdr(t *testing.T) { } cdre, err := NewCDRExporter([]*CDR{cdr}, cdreCfg, utils.MetaFileFWV, "", "", "fwv_1", - true, 1, '|', cfg.GeneralCfg().RoundingDecimals, - cfg.GeneralCfg().HttpSkipTlsVerify, nil, nil) + true, 1, '|', cfg.GeneralCfg().HttpSkipTlsVerify, nil, nil) if err != nil { t.Error(err) } @@ -314,7 +314,7 @@ func TestWriteCdr(t *testing.T) { t.Error("Unexpected number of records in the stats: ", cdre.numberOfRecords) } else if cdre.totalDuration != cdr.Usage { t.Error("Unexpected total duration in the stats: ", cdre.totalDuration) - } else if cdre.totalCost != utils.Round(cdr.Cost, cdre.roundingDecimals, utils.ROUNDING_MIDDLE) { + } else if cdre.totalCost != utils.Round(cdr.Cost, 5, utils.ROUNDING_MIDDLE) { t.Error("Unexpected total cost in the stats: ", cdre.totalCost) } @@ -324,7 +324,7 @@ func TestWriteCdr(t *testing.T) { if cdre.LastOrderId() != 1 { t.Error("Unexpected LastOrderId", cdre.LastOrderId()) } - if cdre.TotalCost() != utils.Round(cdr.Cost, cdre.roundingDecimals, utils.ROUNDING_MIDDLE) { + if cdre.TotalCost() != utils.Round(cdr.Cost, 5, utils.ROUNDING_MIDDLE) { t.Error("Unexpected TotalCost: ", cdre.TotalCost()) } } @@ -370,7 +370,6 @@ func TestWriteCdrs(t *testing.T) { cfg, _ := config.NewDefaultCGRConfig() cdre, err := NewCDRExporter([]*CDR{cdr1, cdr2, cdr3, cdr4}, cdreCfg, utils.MetaFileFWV, "", "", "fwv_1", true, 1, ',', - cfg.GeneralCfg().RoundingDecimals, cfg.GeneralCfg().HttpSkipTlsVerify, nil, nil) if err != nil { t.Error(err) diff --git a/engine/cdrs.go b/engine/cdrs.go index ab5891f3b..f6325b2f8 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, cdrS.cgrCfg.GeneralCfg().RoundingDecimals, - cdrS.cgrCfg.GeneralCfg().HttpSkipTlsVerify, cdrS.httpPoster, + expTpl.FieldSeparator, 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())) continue