mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
cdr AsStoredCdr() -> ForkCdr(), fixup ForkCdr in StoredCdr type
This commit is contained in:
@@ -118,7 +118,7 @@ func (self *Cdrc) parseFieldsConfig() error {
|
||||
}
|
||||
|
||||
// Takes the record out of csv and turns it into http form which can be posted
|
||||
func (self *Cdrc) recordAsStoredCdr(record []string) (*utils.StoredCdr, error) {
|
||||
func (self *Cdrc) recordForkCdr(record []string) (*utils.StoredCdr, error) {
|
||||
ratedCdr := &utils.StoredCdr{CdrSource: self.cgrCfg.CdrcSourceId, ExtraFields: map[string]string{}, Cost: -1}
|
||||
var err error
|
||||
for cfgFieldName, cfgFieldVal := range self.cfgCdrFields {
|
||||
@@ -233,7 +233,7 @@ func (self *Cdrc) processFile(filePath string) error {
|
||||
engine.Logger.Err(fmt.Sprintf("<Cdrc> Error in csv file: %s", err.Error()))
|
||||
continue // Other csv related errors, ignore
|
||||
}
|
||||
rawCdr, err := self.recordAsStoredCdr(record)
|
||||
rawCdr, err := self.recordForkCdr(record)
|
||||
if err != nil {
|
||||
engine.Logger.Err(fmt.Sprintf("<Cdrc> Error in csv file: %s", err.Error()))
|
||||
continue
|
||||
|
||||
@@ -56,7 +56,7 @@ func TestParseFieldsConfig(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecordAsStoredCdr(t *testing.T) {
|
||||
func TestRecordForkCdr(t *testing.T) {
|
||||
cgrConfig, _ := config.NewDefaultCGRConfig()
|
||||
cgrConfig.CdrcExtraFields = []string{"supplier:11"}
|
||||
cdrc := &Cdrc{cgrCfg: cgrConfig}
|
||||
@@ -64,13 +64,13 @@ func TestRecordAsStoredCdr(t *testing.T) {
|
||||
t.Error("Failed parsing default fieldIndexesFromConfig", err)
|
||||
}
|
||||
cdrRow := []string{"firstField", "secondField"}
|
||||
_, err := cdrc.recordAsStoredCdr(cdrRow)
|
||||
_, err := cdrc.recordForkCdr(cdrRow)
|
||||
if err == nil {
|
||||
t.Error("Failed to corectly detect missing fields from record")
|
||||
}
|
||||
cdrRow = []string{"acc1", "prepaid", "*out", "cgrates.org", "call", "1001", "1001", "+4986517174963", "2013-02-03 19:50:00", "2013-02-03 19:54:00", "62",
|
||||
"supplier1", "172.16.1.1"}
|
||||
rtCdr, err := cdrc.recordAsStoredCdr(cdrRow)
|
||||
rtCdr, err := cdrc.recordForkCdr(cdrRow)
|
||||
if err != nil {
|
||||
t.Error("Failed to parse CDR in rated cdr", err)
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ func (fsCdr FSCdr) Restore(input string) error {
|
||||
}
|
||||
|
||||
// Used in extra mediation
|
||||
func (fsCdr FSCdr) AsStoredCdr(runId, reqTypeFld, directionFld, tenantFld, torFld, accountFld, subjectFld, destFld, setupTimeFld, answerTimeFld, durationFld string, extraFlds []string, fieldsMandatory bool) (*utils.StoredCdr, error) {
|
||||
func (fsCdr FSCdr) ForkCdr(runId, reqTypeFld, directionFld, tenantFld, torFld, accountFld, subjectFld, destFld, setupTimeFld, answerTimeFld, durationFld string, extraFlds []string, fieldsMandatory bool) (*utils.StoredCdr, error) {
|
||||
if utils.IsSliceMember([]string{runId, reqTypeFld, directionFld, tenantFld, torFld, accountFld, subjectFld, destFld, answerTimeFld, durationFld}, "") {
|
||||
return nil, errors.New(fmt.Sprintf("%s:FieldName", utils.ERR_MANDATORY_IE_MISSING)) // All input field names are mandatory
|
||||
}
|
||||
|
||||
@@ -102,13 +102,13 @@ func TestCDRFields(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestFsCdrAsStoredCdr(t *testing.T) {
|
||||
func TestFsCdrForkCdr(t *testing.T) {
|
||||
cfg, _ = config.NewDefaultCGRConfig()
|
||||
fsCdr, err := new(FSCdr).New(body)
|
||||
if err != nil {
|
||||
t.Errorf("Error loading cdr: %v", err)
|
||||
}
|
||||
rtCdrOut, err := fsCdr.AsStoredCdr("wholesale_run", "^"+utils.RATED, "^*out", "cgr_tenant", "cgr_tor", "cgr_account", "cgr_subject", "cgr_destination", "start_epoch",
|
||||
rtCdrOut, err := fsCdr.ForkCdr("wholesale_run", "^"+utils.RATED, "^*out", "cgr_tenant", "cgr_tor", "cgr_account", "cgr_subject", "cgr_destination", "start_epoch",
|
||||
"answer_epoch", "billsec", []string{"effective_caller_id_number"}, true)
|
||||
if err != nil {
|
||||
t.Error("Unexpected error received", err)
|
||||
@@ -122,7 +122,7 @@ func TestFsCdrAsStoredCdr(t *testing.T) {
|
||||
if !reflect.DeepEqual(rtCdrOut, expctRatedCdr) {
|
||||
t.Errorf("Received: %v, expected: %v", rtCdrOut, expctRatedCdr)
|
||||
}
|
||||
rtCdrOut2, err := fsCdr.AsStoredCdr("wholesale_run", "^postpaid", "^*in", "^cgrates.com", "^premium_call", "^first_account", "^first_subject", "cgr_destination",
|
||||
rtCdrOut2, err := fsCdr.ForkCdr("wholesale_run", "^postpaid", "^*in", "^cgrates.com", "^premium_call", "^first_account", "^first_subject", "cgr_destination",
|
||||
"^2013-12-07T08:42:24Z", "^2013-12-07T08:42:26Z", "^12s", []string{"effective_caller_id_number"}, true)
|
||||
if err != nil {
|
||||
t.Error("Unexpected error received", err)
|
||||
@@ -136,7 +136,7 @@ func TestFsCdrAsStoredCdr(t *testing.T) {
|
||||
if !reflect.DeepEqual(rtCdrOut2, expctRatedCdr2) {
|
||||
t.Errorf("Received: %v, expected: %v", rtCdrOut2, expctRatedCdr2)
|
||||
}
|
||||
_, err = fsCdr.AsStoredCdr("wholesale_run", "dummy_header", "direction", "tenant", "tor", "account", "subject", "destination", "setup_time", "answer_time", "duration", []string{"field_extr1", "fieldextr2"}, true)
|
||||
_, err = fsCdr.ForkCdr("wholesale_run", "dummy_header", "direction", "tenant", "tor", "account", "subject", "destination", "setup_time", "answer_time", "duration", []string{"field_extr1", "fieldextr2"}, true)
|
||||
if err == nil {
|
||||
t.Error("Failed to detect missing header")
|
||||
}
|
||||
|
||||
32
data/conf/samples/derived_charging1.cfg
Normal file
32
data/conf/samples/derived_charging1.cfg
Normal file
@@ -0,0 +1,32 @@
|
||||
# CGRateS Configuration file
|
||||
#
|
||||
# Used in mediator_local_test
|
||||
# Starts rater, cdrs and mediator connecting over internal channel
|
||||
|
||||
[rater]
|
||||
enabled = true # Enable RaterCDRSExportPath service: <true|false>.
|
||||
|
||||
[cdrs]
|
||||
enabled = true # Start the CDR Server service: <true|false>.
|
||||
mediator = internal # Address where to reach the Mediator. Empty for disabling mediation. <""|internal>
|
||||
|
||||
[cdre]
|
||||
export_dir = /tmp/cgrates/cdr/cdrexport/csv # Path where the exported CDRs will be placed
|
||||
|
||||
[mediator]
|
||||
enabled = true # Starts Mediator service: <true|false>.
|
||||
rater = internal # Address where to reach the Rater: <internal|x.y.z.y:1234>
|
||||
|
||||
[derived_charging]
|
||||
run_ids = run2 # Identifiers of additional sessions control.
|
||||
reqtype_fields = *default # Name of request type fields to be used during additional sessions control <""|*default|field_name>.
|
||||
direction_fields = *default # Name of direction fields to be used during additional sessions control <""|*default|field_name>.
|
||||
tenant_fields = *default # Name of tenant fields to be used during additional sessions control <""|*default|field_name>.
|
||||
tor_fields = *default # Name of tor fields to be used during additional sessions control <""|*default|field_name>.
|
||||
account_fields = ^dc2 # Name of account fields to be used during additional sessions control <""|*default|field_name>.
|
||||
subject_fields = ^dc2 # Name of fields to be used during additional sessions control <""|*default|field_name>.
|
||||
destination_fields = *default # Name of destination fields to be used during additional sessions control <""|*default|field_name>.
|
||||
# setup_time_fields = # Name of setup_time fields to be used during additional sessions control <""|*default|field_name>.
|
||||
# answer_time_fields = # Name of answer_time fields to be used during additional sessions control <""|*default|field_name>.
|
||||
# duration_fields = # Name of duration fields to be used during additional sessions control <""|*default|field_name>.
|
||||
# combined_chargers = true # Combine accounts specific derived_chargers with server configured ones <true|false>.
|
||||
@@ -17,4 +17,18 @@ export_dir = /tmp/cgrates/cdr/cdrexport/csv # Path where the exported CDRs will
|
||||
enabled = true # Starts Mediator service: <true|false>.
|
||||
rater = internal # Address where to reach the Rater: <internal|x.y.z.y:1234>
|
||||
|
||||
[derived_charging]
|
||||
run_ids = run2 # Identifiers of additional sessions control.
|
||||
reqtype_fields = *default # Name of request type fields to be used during additional sessions control <""|*default|field_name>.
|
||||
direction_fields = *default # Name of direction fields to be used during additional sessions control <""|*default|field_name>.
|
||||
tenant_fields = *default # Name of tenant fields to be used during additional sessions control <""|*default|field_name>.
|
||||
tor_fields = *default # Name of tor fields to be used during additional sessions control <""|*default|field_name>.
|
||||
account_fields = ^dc2 # Name of account fields to be used during additional sessions control <""|*default|field_name>.
|
||||
subject_fields = ^dc2 # Name of fields to be used during additional sessions control <""|*default|field_name>.
|
||||
destination_fields = *default # Name of destination fields to be used during additional sessions control <""|*default|field_name>.
|
||||
setup_time_fields = *default # Name of setup_time fields to be used during additional sessions control <""|*default|field_name>.
|
||||
answer_time_fields = *default # Name of answer_time fields to be used during additional sessions control <""|*default|field_name>.
|
||||
duration_fields = *default # Name of duration fields to be used during additional sessions control <""|*default|field_name>.
|
||||
# combined_chargers = true # Combine accounts specific derived_chargers with server configured ones <true|false>.
|
||||
|
||||
|
||||
|
||||
@@ -124,8 +124,9 @@ func (self *Mediator) RateCdr(dbcdr utils.RawCDR) error {
|
||||
return errors.New(errText)
|
||||
}
|
||||
for _, dc := range dcs {
|
||||
forkedCdr, err := dbcdr.AsStoredCdr(dc.RunId, dc.ReqTypeField, dc.DirectionField,
|
||||
forkedCdr, err := dbcdr.ForkCdr(dc.RunId, dc.ReqTypeField, dc.DirectionField,
|
||||
dc.TenantField, dc.TorField, dc.AccountField, dc.SubjectField, dc.DestinationField, dc.SetupTimeField, dc.AnswerTimeField, dc.DurationField, []string{}, true)
|
||||
engine.Logger.Debug(fmt.Sprintf("Forked CDR for dc: %v, is: %v", dc, forkedCdr))
|
||||
if err != nil { // Errors on fork, cannot calculate further, write that into db for later analysis
|
||||
self.cdrDb.SetRatedCdr(&utils.StoredCdr{CgrId: dbcdr.GetCgrId(), MediationRunId: dc.RunId, Cost: -1.0}, err.Error()) // Cannot fork CDR, important just runid and error
|
||||
continue
|
||||
|
||||
@@ -237,6 +237,38 @@ func TestRateCdrs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDerivedCharging(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
var reply string
|
||||
if err := cgrRpc.Call("MediatorV1.RateCdrs", utils.AttrRateCdrs{}, &reply); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if reply != utils.OK {
|
||||
t.Errorf("Unexpected reply: %s", reply)
|
||||
}
|
||||
if nonRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, true, true); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(nonRatedCdrs) != 0 { // Just two of them should be non-rated
|
||||
t.Error(fmt.Sprintf("Unexpected number of CDRs non-rated: %d", len(nonRatedCdrs)))
|
||||
}
|
||||
if errRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, true); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(errRatedCdrs) != 2 { // The first 2 with errors should be still there before rerating
|
||||
t.Error(fmt.Sprintf("Unexpected number of CDRs with errors: %d", len(errRatedCdrs)))
|
||||
}
|
||||
if err := cgrRpc.Call("MediatorV1.RateCdrs", utils.AttrRateCdrs{RerateErrors: true}, &reply); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if reply != utils.OK {
|
||||
t.Errorf("Unexpected reply: %s", reply)
|
||||
}
|
||||
if errRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, time.Time{}, time.Time{}, false, true); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(errRatedCdrs) != 1 { // One CDR with errors should be fixed now by rerating
|
||||
t.Error(fmt.Sprintf("Unexpected number of CDRs with errors: %d", len(errRatedCdrs)))
|
||||
}
|
||||
}
|
||||
|
||||
// Simply kill the engine after we are done with tests within this file
|
||||
func TestStopEngine(t *testing.T) {
|
||||
if !*testLocal {
|
||||
|
||||
@@ -110,7 +110,7 @@ func (cgrCdr CgrCdr) GetDuration() (time.Duration, error) {
|
||||
|
||||
// Used in mediation, fieldsMandatory marks whether missing field out of request represents error or can be ignored
|
||||
// If the fields in parameters start with ^ their value is considered instead of dynamically retrieving it from CDR
|
||||
func (cgrCdr CgrCdr) AsStoredCdr(runId, reqTypeFld, directionFld, tenantFld, torFld, accountFld, subjectFld, destFld, setupTimeFld, answerTimeFld, durationFld string, extraFlds []string, fieldsMandatory bool) (*StoredCdr, error) {
|
||||
func (cgrCdr CgrCdr) ForkCdr(runId, reqTypeFld, directionFld, tenantFld, torFld, accountFld, subjectFld, destFld, setupTimeFld, answerTimeFld, durationFld string, extraFlds []string, fieldsMandatory bool) (*StoredCdr, error) {
|
||||
if IsSliceMember([]string{runId, reqTypeFld, directionFld, tenantFld, torFld, accountFld, subjectFld, destFld, answerTimeFld, durationFld}, "") {
|
||||
return nil, errors.New(fmt.Sprintf("%s:FieldName", ERR_MANDATORY_IE_MISSING)) // All input field names are mandatory
|
||||
}
|
||||
|
||||
@@ -85,11 +85,27 @@ func TestCgrCdrFields(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCgrCdrAsStoredCdr(t *testing.T) {
|
||||
func TestCgrCdrForkCdr(t *testing.T) {
|
||||
sampleCdr1 := &CgrCdr{"accid": "dsafdsaf", "cdrhost": "192.168.1.1", "cdrsource": "source_test", "reqtype": "rated", "direction": "*out", "tenant": "cgrates.org", "tor": "call",
|
||||
"account": "1001", "subject": "1001", "destination": "1002", "setup_time": "2013-11-07T08:42:24Z", "answer_time": "2013-11-07T08:42:26Z", "duration": "10",
|
||||
"field_extr1": "val_extr1", "fieldextr2": "valextr2"}
|
||||
rtSampleCdrOut, err := sampleCdr1.ForkCdr("sample_run1", "reqtype", "direction", "tenant", "tor", "account", "subject", "destination", "setup_time", "answer_time", "duration",
|
||||
[]string{}, true)
|
||||
if err != nil {
|
||||
t.Error("Unexpected error received", err)
|
||||
}
|
||||
setupTime1 := time.Date(2013, 11, 7, 8, 42, 24, 0, time.UTC)
|
||||
expctSplRatedCdr := &StoredCdr{CgrId: Sha1("dsafdsaf", setupTime1.String()), AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "source_test", ReqType: "rated",
|
||||
Direction: "*out", Tenant: "cgrates.org", TOR: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: setupTime1, AnswerTime: time.Unix(1383813746, 0).UTC(),
|
||||
Duration: 10000000000, ExtraFields: map[string]string{}, MediationRunId: "sample_run1", Cost: -1}
|
||||
if !reflect.DeepEqual(expctSplRatedCdr, rtSampleCdrOut) {
|
||||
t.Errorf("Expected: %v, received: %v", expctSplRatedCdr, rtSampleCdrOut)
|
||||
}
|
||||
cgrCdr := &CgrCdr{"accid": "dsafdsaf", "cdrhost": "192.168.1.1", "cdrsource": "source_test", "reqtype": "rated", "direction": "*out", "tenant": "cgrates.org", "tor": "call",
|
||||
"account": "1001", "subject": "1001", "destination": "1002", "setup_time": "2013-11-07T08:42:24Z", "answer_time": "2013-11-07T08:42:26Z", "duration": "10",
|
||||
"field_extr1": "val_extr1", "fieldextr2": "valextr2"}
|
||||
rtCdrOut, err := cgrCdr.AsStoredCdr("wholesale_run", "reqtype", "direction", "tenant", "tor", "account", "subject", "destination", "setup_time", "answer_time", "duration",
|
||||
rtCdrOut, err := cgrCdr.ForkCdr("wholesale_run", "reqtype", "direction", "tenant", "tor", "account", "subject", "destination", "setup_time", "answer_time", "duration",
|
||||
[]string{"field_extr1", "fieldextr2"}, true)
|
||||
if err != nil {
|
||||
t.Error("Unexpected error received", err)
|
||||
@@ -102,7 +118,7 @@ func TestCgrCdrAsStoredCdr(t *testing.T) {
|
||||
if !reflect.DeepEqual(rtCdrOut, expctRatedCdr) {
|
||||
t.Errorf("Received: %v, expected: %v", rtCdrOut, expctRatedCdr)
|
||||
}
|
||||
rtCdrOut2, err := cgrCdr.AsStoredCdr("wholesale_run", "^postpaid", "^*in", "^cgrates.com", "^premium_call", "^first_account", "^first_subject", "destination",
|
||||
rtCdrOut2, err := cgrCdr.ForkCdr("wholesale_run", "^postpaid", "^*in", "^cgrates.com", "^premium_call", "^first_account", "^first_subject", "destination",
|
||||
"^2013-12-07T08:42:24Z", "^2013-12-07T08:42:26Z", "^12s", []string{"field_extr1", "fieldextr2"}, true)
|
||||
if err != nil {
|
||||
t.Error("Unexpected error received", err)
|
||||
@@ -115,14 +131,14 @@ func TestCgrCdrAsStoredCdr(t *testing.T) {
|
||||
if !reflect.DeepEqual(rtCdrOut2, expctRatedCdr2) {
|
||||
t.Errorf("Received: %v, expected: %v", rtCdrOut2, expctRatedCdr2)
|
||||
}
|
||||
_, err = cgrCdr.AsStoredCdr("wholesale_run", "dummy_header", "direction", "tenant", "tor", "account", "subject", "destination", "setup_time", "answer_time", "duration",
|
||||
_, err = cgrCdr.ForkCdr("wholesale_run", "dummy_header", "direction", "tenant", "tor", "account", "subject", "destination", "setup_time", "answer_time", "duration",
|
||||
[]string{"field_extr1", "fieldextr2"}, true)
|
||||
if err == nil {
|
||||
t.Error("Failed to detect missing header")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCgrCdrAsStoredCdrFromMetaDefaults(t *testing.T) {
|
||||
func TestCgrCdrForkCdrFromMetaDefaults(t *testing.T) {
|
||||
cgrCdr := &CgrCdr{"accid": "dsafdsaf", "cdrhost": "192.168.1.1", "cdrsource": "source_test", "reqtype": "rated", "direction": "*out", "tenant": "cgrates.org", "tor": "call",
|
||||
"account": "1001", "subject": "1001", "destination": "1002", "setup_time": "2013-11-07T08:42:24Z", "answer_time": "2013-11-07T08:42:26Z", "duration": "10",
|
||||
"field_extr1": "val_extr1", "fieldextr2": "valextr2"}
|
||||
@@ -132,7 +148,7 @@ func TestCgrCdrAsStoredCdrFromMetaDefaults(t *testing.T) {
|
||||
SetupTime: setupTime, AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC),
|
||||
Duration: time.Duration(10) * time.Second,
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: "wholesale_run", Cost: -1}
|
||||
cdrOut, err := cgrCdr.AsStoredCdr("wholesale_run", META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT,
|
||||
cdrOut, err := cgrCdr.ForkCdr("wholesale_run", META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT, META_DEFAULT,
|
||||
META_DEFAULT, META_DEFAULT, META_DEFAULT, []string{"field_extr1", "fieldextr2"}, true)
|
||||
if err != nil {
|
||||
t.Fatal("Unexpected error received", err)
|
||||
|
||||
@@ -100,6 +100,7 @@ const (
|
||||
MASK_CHAR = "*"
|
||||
CONCATENATED_KEY_SEP = ":"
|
||||
META_DEFAULT = "*default"
|
||||
FORKED_CDR = "forked_cdr"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@@ -40,6 +40,6 @@ type RawCDR interface {
|
||||
GetSetupTime() (time.Time, error) // Time when the call was set-up
|
||||
GetAnswerTime() (time.Time, error) // Time when the call was answered
|
||||
GetDuration() (time.Duration, error)
|
||||
GetExtraFields() map[string]string //Stores extra CDR Fields
|
||||
AsStoredCdr(string, string, string, string, string, string, string, string, string, string, string, []string, bool) (*StoredCdr, error) // Based on fields queried will return a particular instance of RatedCDR
|
||||
GetExtraFields() map[string]string //Stores extra CDR Fields
|
||||
ForkCdr(string, string, string, string, string, string, string, string, string, string, string, []string, bool) (*StoredCdr, error) // Based on fields queried will return a particular instance of RatedCDR
|
||||
}
|
||||
|
||||
@@ -27,29 +27,29 @@ import (
|
||||
|
||||
func NewStoredCdrFromRawCDR(rawcdr RawCDR) (*StoredCdr, error) {
|
||||
var err error
|
||||
rtCdr := new(StoredCdr)
|
||||
rtCdr.CgrId = rawcdr.GetCgrId()
|
||||
rtCdr.AccId = rawcdr.GetAccId()
|
||||
rtCdr.CdrHost = rawcdr.GetCdrHost()
|
||||
rtCdr.CdrSource = rawcdr.GetCdrSource()
|
||||
rtCdr.ReqType = rawcdr.GetReqType()
|
||||
rtCdr.Direction = rawcdr.GetDirection()
|
||||
rtCdr.Tenant = rawcdr.GetTenant()
|
||||
rtCdr.TOR = rawcdr.GetTOR()
|
||||
rtCdr.Account = rawcdr.GetAccount()
|
||||
rtCdr.Subject = rawcdr.GetSubject()
|
||||
rtCdr.Destination = rawcdr.GetDestination()
|
||||
if rtCdr.SetupTime, err = rawcdr.GetSetupTime(); err != nil {
|
||||
strCdr := new(StoredCdr)
|
||||
strCdr.CgrId = rawcdr.GetCgrId()
|
||||
strCdr.AccId = rawcdr.GetAccId()
|
||||
strCdr.CdrHost = rawcdr.GetCdrHost()
|
||||
strCdr.CdrSource = rawcdr.GetCdrSource()
|
||||
strCdr.ReqType = rawcdr.GetReqType()
|
||||
strCdr.Direction = rawcdr.GetDirection()
|
||||
strCdr.Tenant = rawcdr.GetTenant()
|
||||
strCdr.TOR = rawcdr.GetTOR()
|
||||
strCdr.Account = rawcdr.GetAccount()
|
||||
strCdr.Subject = rawcdr.GetSubject()
|
||||
strCdr.Destination = rawcdr.GetDestination()
|
||||
if strCdr.SetupTime, err = rawcdr.GetSetupTime(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rtCdr.AnswerTime, err = rawcdr.GetAnswerTime(); err != nil {
|
||||
if strCdr.AnswerTime, err = rawcdr.GetAnswerTime(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rtCdr.Duration, _ = rawcdr.GetDuration()
|
||||
rtCdr.ExtraFields = rawcdr.GetExtraFields()
|
||||
rtCdr.MediationRunId = DEFAULT_RUNID
|
||||
rtCdr.Cost = -1
|
||||
return rtCdr, nil
|
||||
strCdr.Duration, _ = rawcdr.GetDuration()
|
||||
strCdr.ExtraFields = rawcdr.GetExtraFields()
|
||||
strCdr.MediationRunId = DEFAULT_RUNID
|
||||
strCdr.Cost = -1
|
||||
return strCdr, nil
|
||||
}
|
||||
|
||||
// Rated CDR as extracted from StorDb. Kinda standard of internal CDR, complies to CDR interface also
|
||||
@@ -145,10 +145,6 @@ func (storedCdr *StoredCdr) FormatCost(shiftDecimals, roundDecimals int) string
|
||||
return strconv.FormatFloat(cost, 'f', roundDecimals, 64)
|
||||
}
|
||||
|
||||
func (storedCdr *StoredCdr) AsStoredCdr(runId, reqTypeFld, directionFld, tenantFld, torFld, accountFld, subjectFld, destFld, setupTimeFld, answerTimeFld, durationFld string, extraFlds []string, fieldsMandatory bool) (*StoredCdr, error) {
|
||||
return storedCdr, nil
|
||||
}
|
||||
|
||||
// Converts part of the rated Cdr as httpForm used to post remotely to CDRS
|
||||
func (storedCdr *StoredCdr) AsRawCdrHttpForm() url.Values {
|
||||
v := url.Values{}
|
||||
@@ -212,3 +208,18 @@ func (storedCdr *StoredCdr) ExportFieldValue(fldName string) string {
|
||||
return storedCdr.ExtraFields[fldName]
|
||||
}
|
||||
}
|
||||
|
||||
// Converts to CgrCdr, so we can fork with less code
|
||||
func (storedCdr *StoredCdr) AsCgrCdr() CgrCdr {
|
||||
cgrCdr := make(CgrCdr)
|
||||
for _, fldName := range PrimaryCdrFields {
|
||||
cgrCdr[fldName] = storedCdr.ExportFieldValue(fldName)
|
||||
}
|
||||
return cgrCdr
|
||||
}
|
||||
|
||||
func (storedCdr *StoredCdr) ForkCdr(runId, reqTypeFld, directionFld, tenantFld, torFld, accountFld, subjectFld, destFld,
|
||||
setupTimeFld, answerTimeFld, durationFld string, extraFlds []string, fieldsMandatory bool) (*StoredCdr, error) {
|
||||
return storedCdr.AsCgrCdr().ForkCdr(runId, reqTypeFld, directionFld, tenantFld, torFld, accountFld, subjectFld, destFld,
|
||||
setupTimeFld, answerTimeFld, durationFld, extraFlds, fieldsMandatory)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user