mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Remove RoundingDecimals from CDRC ( can be set explicit for the field you want)
This commit is contained in:
committed by
Dan Christian Bogos
parent
a5f9be607e
commit
89bf087bc6
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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("<CDR> 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("<CDR> error: %s exporting field: %s, CDR: %s\n",
|
||||
err.Error(), utils.ToJSON(cfgFld), utils.ToJSON(cdr)))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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("<CDRS> Building CDRExporter for online exports got error: <%s>", err.Error()))
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user