mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-23 08:08:45 +05:00
This commit is contained in:
@@ -41,12 +41,12 @@ type CallCostLog struct {
|
||||
|
||||
// Handler for generic cgr cdr http
|
||||
func cgrCdrHandler(w http.ResponseWriter, r *http.Request) {
|
||||
cgrCdr, err := NewCgrCdrFromHttpReq(r)
|
||||
cgrCdr, err := NewCgrCdrFromHttpReq(r, cdrServer.cgrCfg.DefaultTimezone)
|
||||
if err != nil {
|
||||
Logger.Err(fmt.Sprintf("<CDRS> Could not create CDR entry: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
if err := cdrServer.processCdr(cgrCdr.AsStoredCdr()); err != nil {
|
||||
if err := cdrServer.processCdr(cgrCdr.AsStoredCdr(cdrServer.cgrCfg.DefaultTimezone)); err != nil {
|
||||
Logger.Err(fmt.Sprintf("<CDRS> Errors when storing CDR entry: %s", err.Error()))
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,7 @@ func fsCdrHandler(w http.ResponseWriter, r *http.Request) {
|
||||
Logger.Err(fmt.Sprintf("<CDRS> Could not create CDR entry: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
if err := cdrServer.processCdr(fsCdr.AsStoredCdr()); err != nil {
|
||||
if err := cdrServer.processCdr(fsCdr.AsStoredCdr(cdrServer.Timezone())); err != nil {
|
||||
Logger.Err(fmt.Sprintf("<CDRS> Errors when storing CDR entry: %s", err.Error()))
|
||||
}
|
||||
}
|
||||
@@ -76,6 +76,10 @@ type CdrServer struct {
|
||||
guard *GuardianLock
|
||||
}
|
||||
|
||||
func (self *CdrServer) Timezone() string {
|
||||
return self.cgrCfg.DefaultTimezone
|
||||
}
|
||||
|
||||
func (self *CdrServer) RegisterHanlersToServer(server *Server) {
|
||||
cdrServer = self // Share the server object for handlers
|
||||
server.RegisterHttpFunc("/cdr_http", cgrCdrHandler)
|
||||
@@ -92,7 +96,7 @@ func (self *CdrServer) ProcessExternalCdr(cdr *ExternalCdr) error {
|
||||
if cdr.Subject == "" { // Use account information as rating subject if missing
|
||||
cdr.Subject = cdr.Account
|
||||
}
|
||||
storedCdr, err := NewStoredCdrFromExternalCdr(cdr)
|
||||
storedCdr, err := NewStoredCdrFromExternalCdr(cdr, self.cgrCfg.DefaultTimezone)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -246,7 +250,7 @@ func (self *CdrServer) deriveCdrs(storedCdr *StoredCdr) ([]*StoredCdr, error) {
|
||||
dcSupplFld, _ := utils.NewRSRField(dc.SupplierField)
|
||||
dcDCausseld, _ := utils.NewRSRField(dc.DisconnectCauseField)
|
||||
forkedCdr, err := storedCdr.ForkCdr(dc.RunId, dcReqTypeFld, dcDirFld, dcTenantFld, dcCategoryFld, dcAcntFld, dcSubjFld, dcDstFld,
|
||||
dcSTimeFld, dcPddFld, dcATimeFld, dcDurFld, dcSupplFld, dcDCausseld, []*utils.RSRField{}, true)
|
||||
dcSTimeFld, dcPddFld, dcATimeFld, dcDurFld, dcSupplFld, dcDCausseld, []*utils.RSRField{}, true, self.cgrCfg.DefaultTimezone)
|
||||
if err != nil {
|
||||
Logger.Err(fmt.Sprintf("Could not fork CGR with cgrid %s, run: %s, error: %s", storedCdr.CgrId, dc.RunId, err.Error()))
|
||||
continue // do not add it to the forked CDR list
|
||||
|
||||
@@ -115,8 +115,8 @@ func TestCdrsHttpCdrReplication(t *testing.T) {
|
||||
} else if len(rcvedCdrs) != 1 {
|
||||
t.Error("Unexpected number of CDRs returned: ", len(rcvedCdrs))
|
||||
} else {
|
||||
rcvSetupTime, _ := utils.ParseTimeDetectLayout(rcvedCdrs[0].SetupTime)
|
||||
rcvAnswerTime, _ := utils.ParseTimeDetectLayout(rcvedCdrs[0].AnswerTime)
|
||||
rcvSetupTime, _ := utils.ParseTimeDetectLayout(rcvedCdrs[0].SetupTime, "")
|
||||
rcvAnswerTime, _ := utils.ParseTimeDetectLayout(rcvedCdrs[0].AnswerTime, "")
|
||||
//rcvUsage, _ := utils.ParseDurationWithSecs(rcvedCdrs[0].Usage)
|
||||
if rcvedCdrs[0].CgrId != testCdr1.CgrId ||
|
||||
rcvedCdrs[0].TOR != testCdr1.TOR ||
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func NewCgrCdrFromHttpReq(req *http.Request) (CgrCdr, error) {
|
||||
func NewCgrCdrFromHttpReq(req *http.Request, timezone string) (CgrCdr, error) {
|
||||
if req.Form == nil {
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, err
|
||||
@@ -40,11 +40,11 @@ func NewCgrCdrFromHttpReq(req *http.Request) (CgrCdr, error) {
|
||||
|
||||
type CgrCdr map[string]string
|
||||
|
||||
func (cgrCdr CgrCdr) getCgrId() string {
|
||||
func (cgrCdr CgrCdr) getCgrId(timezone string) string {
|
||||
if cgrId, hasIt := cgrCdr[utils.CGRID]; hasIt {
|
||||
return cgrId
|
||||
}
|
||||
setupTime, _ := utils.ParseTimeDetectLayout(cgrCdr[utils.SETUP_TIME])
|
||||
setupTime, _ := utils.ParseTimeDetectLayout(cgrCdr[utils.SETUP_TIME], timezone)
|
||||
return utils.Sha1(cgrCdr[utils.ACCID], setupTime.UTC().String())
|
||||
}
|
||||
|
||||
@@ -58,9 +58,9 @@ func (cgrCdr CgrCdr) getExtraFields() map[string]string {
|
||||
return extraFields
|
||||
}
|
||||
|
||||
func (cgrCdr CgrCdr) AsStoredCdr() *StoredCdr {
|
||||
func (cgrCdr CgrCdr) AsStoredCdr(timezone string) *StoredCdr {
|
||||
storCdr := new(StoredCdr)
|
||||
storCdr.CgrId = cgrCdr.getCgrId()
|
||||
storCdr.CgrId = cgrCdr.getCgrId(timezone)
|
||||
storCdr.TOR = cgrCdr[utils.TOR]
|
||||
storCdr.AccId = cgrCdr[utils.ACCID]
|
||||
storCdr.CdrHost = cgrCdr[utils.CDRHOST]
|
||||
@@ -72,9 +72,9 @@ func (cgrCdr CgrCdr) AsStoredCdr() *StoredCdr {
|
||||
storCdr.Account = cgrCdr[utils.ACCOUNT]
|
||||
storCdr.Subject = cgrCdr[utils.SUBJECT]
|
||||
storCdr.Destination = cgrCdr[utils.DESTINATION]
|
||||
storCdr.SetupTime, _ = utils.ParseTimeDetectLayout(cgrCdr[utils.SETUP_TIME]) // Not interested to process errors, should do them if necessary in a previous step
|
||||
storCdr.SetupTime, _ = utils.ParseTimeDetectLayout(cgrCdr[utils.SETUP_TIME], timezone) // Not interested to process errors, should do them if necessary in a previous step
|
||||
storCdr.Pdd, _ = utils.ParseDurationWithSecs(cgrCdr[utils.PDD])
|
||||
storCdr.AnswerTime, _ = utils.ParseTimeDetectLayout(cgrCdr[utils.ANSWER_TIME])
|
||||
storCdr.AnswerTime, _ = utils.ParseTimeDetectLayout(cgrCdr[utils.ANSWER_TIME], timezone)
|
||||
storCdr.Usage, _ = utils.ParseDurationWithSecs(cgrCdr[utils.USAGE])
|
||||
storCdr.Supplier = cgrCdr[utils.SUPPLIER]
|
||||
storCdr.DisconnectCause = cgrCdr[utils.DISCONNECT_CAUSE]
|
||||
|
||||
@@ -39,14 +39,14 @@ func TestCgrCdrAsStoredCdr(t *testing.T) {
|
||||
utils.TENANT: "cgrates.org", utils.CATEGORY: "call",
|
||||
utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "1002", utils.SETUP_TIME: "2013-11-07T08:42:20Z", utils.ANSWER_TIME: "2013-11-07T08:42:26Z",
|
||||
utils.USAGE: "10", utils.SUPPLIER: "SUPPL1", "field_extr1": "val_extr1", "fieldextr2": "valextr2"}
|
||||
setupTime, _ := utils.ParseTimeDetectLayout(cgrCdr["setup_time"])
|
||||
setupTime, _ := utils.ParseTimeDetectLayout(cgrCdr["setup_time"], "")
|
||||
expctRtCdr := &StoredCdr{CgrId: utils.Sha1(cgrCdr["accid"], setupTime.String()), TOR: utils.VOICE, AccId: cgrCdr["accid"], CdrHost: cgrCdr["cdrhost"], CdrSource: cgrCdr["cdrsource"],
|
||||
ReqType: cgrCdr["reqtype"],
|
||||
Direction: cgrCdr[utils.DIRECTION], Tenant: cgrCdr["tenant"], Category: cgrCdr[utils.CATEGORY], Account: cgrCdr["account"], Subject: cgrCdr["subject"],
|
||||
Destination: cgrCdr["destination"], SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: -1}
|
||||
if storedCdr := cgrCdr.AsStoredCdr(); !reflect.DeepEqual(expctRtCdr, storedCdr) {
|
||||
if storedCdr := cgrCdr.AsStoredCdr(""); !reflect.DeepEqual(expctRtCdr, storedCdr) {
|
||||
t.Errorf("Expecting %v, received: %v", expctRtCdr, storedCdr)
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@ func TestReplicatedCgrCdrAsStoredCdr(t *testing.T) {
|
||||
Cost: 0.12,
|
||||
Rated: true,
|
||||
}
|
||||
if storedCdr := cgrCdr.AsStoredCdr(); !reflect.DeepEqual(expctRtCdr, storedCdr) {
|
||||
if storedCdr := cgrCdr.AsStoredCdr(""); !reflect.DeepEqual(expctRtCdr, storedCdr) {
|
||||
t.Errorf("Expecting %v, received: %v", expctRtCdr, storedCdr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
|
||||
type Event interface {
|
||||
GetName() string
|
||||
GetCgrId() string
|
||||
GetCgrId(timezone string) string
|
||||
GetUUID() string
|
||||
GetSessionIds() []string // Returns identifiers needed to control a session (eg disconnect)
|
||||
GetDirection(string) string
|
||||
@@ -36,8 +36,8 @@ type Event interface {
|
||||
GetCategory(string) string
|
||||
GetTenant(string) string
|
||||
GetReqType(string) string
|
||||
GetSetupTime(string) (time.Time, error)
|
||||
GetAnswerTime(string) (time.Time, error)
|
||||
GetSetupTime(string, string) (time.Time, error)
|
||||
GetAnswerTime(string, string) (time.Time, error)
|
||||
GetEndTime() (time.Time, error)
|
||||
GetDuration(string) (time.Duration, error)
|
||||
GetPdd(string) (time.Duration, error)
|
||||
@@ -46,9 +46,9 @@ type Event interface {
|
||||
GetOriginatorIP(string) string
|
||||
GetExtraFields() map[string]string
|
||||
MissingParameter() bool
|
||||
ParseEventValue(*utils.RSRField) string
|
||||
ParseEventValue(*utils.RSRField, string) string
|
||||
PassesFieldFilter(*utils.RSRField) (bool, string)
|
||||
AsStoredCdr() *StoredCdr
|
||||
AsStoredCdr(timezone string) *StoredCdr
|
||||
String() string
|
||||
AsEvent(string) Event
|
||||
ComputeLcr() bool
|
||||
|
||||
@@ -76,8 +76,8 @@ type FSCdr struct {
|
||||
body map[string]interface{} // keeps the loaded body for extra field search
|
||||
}
|
||||
|
||||
func (fsCdr FSCdr) getCgrId() string {
|
||||
setupTime, _ := utils.ParseTimeDetectLayout(fsCdr.vars[FS_SETUP_TIME])
|
||||
func (fsCdr FSCdr) getCgrId(timezone string) string {
|
||||
setupTime, _ := utils.ParseTimeDetectLayout(fsCdr.vars[FS_SETUP_TIME], timezone)
|
||||
return utils.Sha1(fsCdr.vars[FS_UUID], setupTime.UTC().String())
|
||||
}
|
||||
|
||||
@@ -124,10 +124,10 @@ func (fsCdr FSCdr) searchExtraField(field string, body map[string]interface{}) (
|
||||
return
|
||||
}
|
||||
|
||||
func (fsCdr FSCdr) AsStoredCdr() *StoredCdr {
|
||||
func (fsCdr FSCdr) AsStoredCdr(timezone string) *StoredCdr {
|
||||
|
||||
storCdr := new(StoredCdr)
|
||||
storCdr.CgrId = fsCdr.getCgrId()
|
||||
storCdr.CgrId = fsCdr.getCgrId(timezone)
|
||||
storCdr.TOR = utils.VOICE
|
||||
storCdr.AccId = fsCdr.vars[FS_UUID]
|
||||
storCdr.CdrHost = fsCdr.vars[FS_IP]
|
||||
@@ -139,11 +139,11 @@ func (fsCdr FSCdr) AsStoredCdr() *StoredCdr {
|
||||
storCdr.Account = utils.FirstNonEmpty(fsCdr.vars[FS_ACCOUNT], fsCdr.vars[FS_USERNAME])
|
||||
storCdr.Subject = utils.FirstNonEmpty(fsCdr.vars[FS_SUBJECT], fsCdr.vars[FS_USERNAME])
|
||||
storCdr.Destination = utils.FirstNonEmpty(fsCdr.vars[FS_DESTINATION], fsCdr.vars[FS_CALL_DEST_NR], fsCdr.vars[FS_SIP_REQUSER])
|
||||
storCdr.SetupTime, _ = utils.ParseTimeDetectLayout(fsCdr.vars[FS_SETUP_TIME]) // Not interested to process errors, should do them if necessary in a previous step
|
||||
storCdr.SetupTime, _ = utils.ParseTimeDetectLayout(fsCdr.vars[FS_SETUP_TIME], timezone) // Not interested to process errors, should do them if necessary in a previous step
|
||||
pddStr := utils.FirstNonEmpty(fsCdr.vars[FS_PROGRESS_MEDIAMSEC], fsCdr.vars[FS_PROGRESSMS])
|
||||
pddStr = pddStr + "ms"
|
||||
storCdr.Pdd, _ = time.ParseDuration(pddStr)
|
||||
storCdr.AnswerTime, _ = utils.ParseTimeDetectLayout(fsCdr.vars[FS_ANSWER_TIME])
|
||||
storCdr.AnswerTime, _ = utils.ParseTimeDetectLayout(fsCdr.vars[FS_ANSWER_TIME], timezone)
|
||||
storCdr.Usage, _ = utils.ParseDurationWithSecs(fsCdr.vars[FS_DURATION])
|
||||
storCdr.Supplier = fsCdr.vars[utils.CGR_SUPPLIER]
|
||||
storCdr.DisconnectCause = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_DISCONNECT_CAUSE], fsCdr.vars["hangup_cause"])
|
||||
|
||||
@@ -53,13 +53,13 @@ func TestCDRFields(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Errorf("Error loading cdr: %v", err)
|
||||
}
|
||||
setupTime, _ := utils.ParseTimeDetectLayout("1436280728")
|
||||
answerTime, _ := utils.ParseTimeDetectLayout("1436280728")
|
||||
setupTime, _ := utils.ParseTimeDetectLayout("1436280728", "")
|
||||
answerTime, _ := utils.ParseTimeDetectLayout("1436280728", "")
|
||||
expctStoredCdr := &StoredCdr{CgrId: "164b0422fdc6a5117031b427439482c6a4f90e41", TOR: utils.VOICE, AccId: "e3133bf7-dcde-4daf-9663-9a79ffcef5ad",
|
||||
CdrHost: "127.0.0.1", CdrSource: "freeswitch_json", Direction: utils.OUT, Category: "call", ReqType: utils.META_PREPAID, Tenant: "cgrates.org", Account: "1001", Subject: "1001",
|
||||
Destination: "1003", SetupTime: setupTime, Pdd: time.Duration(28) * time.Millisecond, AnswerTime: answerTime, Usage: time.Duration(66) * time.Second, Supplier: "supplier1",
|
||||
DisconnectCause: "NORMAL_CLEARING", ExtraFields: map[string]string{"sip_user_agent": "PJSUA v2.3 Linux-3.2.0.4/x86_64/glibc-2.13"}, Cost: -1}
|
||||
if storedCdr := fsCdr.AsStoredCdr(); !reflect.DeepEqual(expctStoredCdr, storedCdr) {
|
||||
if storedCdr := fsCdr.AsStoredCdr(""); !reflect.DeepEqual(expctStoredCdr, storedCdr) {
|
||||
t.Errorf("Expecting: %v, received: %v", expctStoredCdr, storedCdr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ type LcrRequest struct {
|
||||
*utils.Paginator
|
||||
}
|
||||
|
||||
func (self *LcrRequest) AsCallDescriptor() (*CallDescriptor, error) {
|
||||
func (self *LcrRequest) AsCallDescriptor(timezone string) (*CallDescriptor, error) {
|
||||
if len(self.Account) == 0 || len(self.Destination) == 0 {
|
||||
return nil, utils.ErrMandatoryIeMissing
|
||||
}
|
||||
@@ -81,7 +81,7 @@ func (self *LcrRequest) AsCallDescriptor() (*CallDescriptor, error) {
|
||||
var err error
|
||||
if len(self.SetupTime) == 0 {
|
||||
timeStart = time.Now()
|
||||
} else if timeStart, err = utils.ParseTimeDetectLayout(self.SetupTime); err != nil {
|
||||
} else if timeStart, err = utils.ParseTimeDetectLayout(self.SetupTime, timezone); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var callDur time.Duration
|
||||
|
||||
@@ -216,7 +216,7 @@ func TestLcrRequestAsCallDescriptor(t *testing.T) {
|
||||
sTime := time.Date(2015, 04, 06, 17, 40, 0, 0, time.UTC)
|
||||
callDur := time.Duration(1) * time.Minute
|
||||
lcrReq := &LcrRequest{Account: "2001", SetupTime: sTime.String()}
|
||||
if _, err := lcrReq.AsCallDescriptor(); err == nil || err != utils.ErrMandatoryIeMissing {
|
||||
if _, err := lcrReq.AsCallDescriptor(""); err == nil || err != utils.ErrMandatoryIeMissing {
|
||||
t.Error("Unexpected error received: %v", err)
|
||||
}
|
||||
lcrReq = &LcrRequest{Account: "2001", Destination: "2002", SetupTime: sTime.String()}
|
||||
@@ -230,7 +230,7 @@ func TestLcrRequestAsCallDescriptor(t *testing.T) {
|
||||
TimeStart: sTime,
|
||||
TimeEnd: sTime.Add(callDur),
|
||||
}
|
||||
if cd, err := lcrReq.AsCallDescriptor(); err != nil {
|
||||
if cd, err := lcrReq.AsCallDescriptor(""); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eCd, cd) {
|
||||
t.Errorf("Expected: %+v, received: %+v", eCd, cd)
|
||||
|
||||
@@ -90,7 +90,7 @@ func StopStartEngine(cfgPath string, waitEngine int) (*exec.Cmd, error) {
|
||||
return StartEngine(cfgPath, waitEngine)
|
||||
}
|
||||
|
||||
func LoadTariffPlanFromFolder(tpPath string, ratingDb RatingStorage, accountingDb AccountingStorage) error {
|
||||
func LoadTariffPlanFromFolder(tpPath, timezone string, ratingDb RatingStorage, accountingDb AccountingStorage) error {
|
||||
loader := NewTpReader(ratingDb, accountingDb, NewFileCSVStorage(utils.CSV_SEP,
|
||||
path.Join(tpPath, utils.DESTINATIONS_CSV),
|
||||
path.Join(tpPath, utils.TIMINGS_CSV),
|
||||
@@ -106,7 +106,7 @@ func LoadTariffPlanFromFolder(tpPath string, ratingDb RatingStorage, accountingD
|
||||
path.Join(tpPath, utils.ACCOUNT_ACTIONS_CSV),
|
||||
path.Join(tpPath, utils.DERIVED_CHARGERS_CSV),
|
||||
path.Join(tpPath, utils.CDR_STATS_CSV),
|
||||
path.Join(tpPath, utils.USERS_CSV)), "")
|
||||
path.Join(tpPath, utils.USERS_CSV)), "", timezone)
|
||||
if err := loader.LoadAll(); err != nil {
|
||||
return utils.NewErrServerError(err)
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ var csvr *TpReader
|
||||
|
||||
func init() {
|
||||
csvr = NewTpReader(ratingStorage, accountingStorage, NewStringCSVStorage(',', destinations, timings, rates, destinationRates, ratingPlans, ratingProfiles,
|
||||
sharedGroups, lcrs, actions, actionTimings, actionTriggers, accountActions, derivedCharges, cdrStats, users), "")
|
||||
sharedGroups, lcrs, actions, actionTimings, actionTriggers, accountActions, derivedCharges, cdrStats, users), "", "")
|
||||
if err := csvr.LoadDestinations(); err != nil {
|
||||
log.Print("error in LoadDestinations:", err)
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ func TestLoadFromCSV(t *testing.T) {
|
||||
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.ACCOUNT_ACTIONS_CSV),
|
||||
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.DERIVED_CHARGERS_CSV),
|
||||
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.CDR_STATS_CSV),
|
||||
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.USERS_CSV)), "")
|
||||
path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.USERS_CSV)), "", "")
|
||||
|
||||
if err = loader.LoadDestinations(); err != nil {
|
||||
t.Error("Failed loading destinations: ", err.Error())
|
||||
@@ -201,7 +201,7 @@ func TestLoadFromStorDb(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
loader := NewTpReader(ratingDbStor, accountDbStor, storDb, utils.TEST_SQL)
|
||||
loader := NewTpReader(ratingDbStor, accountDbStor, storDb, utils.TEST_SQL, "")
|
||||
if err := loader.LoadDestinations(); err != nil {
|
||||
t.Error("Failed loading destinations: ", err.Error())
|
||||
}
|
||||
@@ -244,7 +244,7 @@ func TestLoadIndividualProfiles(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
loader := NewTpReader(ratingDbApier, accountDbApier, storDb, utils.TEST_SQL)
|
||||
loader := NewTpReader(ratingDbApier, accountDbApier, storDb, utils.TEST_SQL, "")
|
||||
// Load ratingPlans. This will also set destination keys
|
||||
if ratingPlans, err := storDb.GetTpRatingPlans(utils.TEST_SQL, "", nil); err != nil {
|
||||
t.Fatal("Could not retrieve rating plans")
|
||||
|
||||
@@ -532,7 +532,7 @@ func (tps TpCdrStats) GetCdrStats() (map[string][]*utils.TPCdrStat, error) {
|
||||
return css, nil
|
||||
}
|
||||
|
||||
func UpdateCdrStats(cs *CdrStats, triggers ActionTriggerPriotityList, tpCs *utils.TPCdrStat) {
|
||||
func UpdateCdrStats(cs *CdrStats, triggers ActionTriggerPriotityList, tpCs *utils.TPCdrStat, timezone string) {
|
||||
if tpCs.QueueLength != "" && tpCs.QueueLength != "0" {
|
||||
if qi, err := strconv.Atoi(tpCs.QueueLength); err == nil {
|
||||
cs.QueueLength = qi
|
||||
@@ -560,7 +560,7 @@ func UpdateCdrStats(cs *CdrStats, triggers ActionTriggerPriotityList, tpCs *util
|
||||
if tpCs.SetupInterval != "" {
|
||||
times := strings.Split(tpCs.SetupInterval, utils.INFIELD_SEP)
|
||||
if len(times) > 0 {
|
||||
if sTime, err := utils.ParseTimeDetectLayout(times[0]); err == nil {
|
||||
if sTime, err := utils.ParseTimeDetectLayout(times[0], timezone); err == nil {
|
||||
if len(cs.SetupInterval) < 1 {
|
||||
cs.SetupInterval = append(cs.SetupInterval, sTime)
|
||||
} else {
|
||||
@@ -571,7 +571,7 @@ func UpdateCdrStats(cs *CdrStats, triggers ActionTriggerPriotityList, tpCs *util
|
||||
}
|
||||
}
|
||||
if len(times) > 1 {
|
||||
if eTime, err := utils.ParseTimeDetectLayout(times[1]); err == nil {
|
||||
if eTime, err := utils.ParseTimeDetectLayout(times[1], timezone); err == nil {
|
||||
if len(cs.SetupInterval) < 2 {
|
||||
cs.SetupInterval = append(cs.SetupInterval, eTime)
|
||||
} else {
|
||||
|
||||
@@ -20,5 +20,5 @@ package engine
|
||||
|
||||
// RawCDR is the original CDR received from external sources (eg: FreeSWITCH)
|
||||
type RawCdr interface {
|
||||
AsStoredCdr() *StoredCdr // Convert the inbound Cdr into internally used one, CgrCdr
|
||||
AsStoredCdr(string) *StoredCdr // Convert the inbound Cdr into internally used one, CgrCdr
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ type Responder struct {
|
||||
ExitChan chan bool
|
||||
CdrSrv *CdrServer
|
||||
Stats StatsInterface
|
||||
Timezone string
|
||||
cnt int64
|
||||
}
|
||||
|
||||
@@ -208,7 +209,7 @@ func (rs *Responder) GetDerivedMaxSessionTime(ev *StoredCdr, reply *float64) err
|
||||
if !matchingAllFilters { // Do not process the derived charger further if not all filters were matched
|
||||
continue
|
||||
}
|
||||
startTime, err := ev.GetSetupTime(utils.META_DEFAULT)
|
||||
startTime, err := ev.GetSetupTime(utils.META_DEFAULT, rs.Timezone)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -272,7 +273,7 @@ func (rs *Responder) GetSessionRuns(ev *StoredCdr, sRuns *[]*SessionRun) error {
|
||||
if !utils.IsSliceMember([]string{utils.META_PREPAID, utils.PREPAID}, ev.GetReqType(dc.ReqTypeField)) {
|
||||
continue // We only consider prepaid sessions
|
||||
}
|
||||
startTime, err := ev.GetAnswerTime(dc.AnswerTimeField)
|
||||
startTime, err := ev.GetAnswerTime(dc.AnswerTimeField, rs.Timezone)
|
||||
if err != nil {
|
||||
return errors.New("Error parsing answer event start time")
|
||||
}
|
||||
|
||||
@@ -496,7 +496,7 @@ func TestMySQLSetCdr(t *testing.T) {
|
||||
utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "15s", utils.PDD: "7s", utils.SUPPLIER: "SUPPL1", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": utils.TEST_SQL}
|
||||
|
||||
for _, cdr := range []*CgrCdr{cgrCdr1, cgrCdr2, cgrCdr3, cgrCdr4, cgrCdr5} {
|
||||
if err := mysqlDb.SetCdr(cdr.AsStoredCdr()); err != nil {
|
||||
if err := mysqlDb.SetCdr(cdr.AsStoredCdr("")); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
@@ -890,15 +890,15 @@ func TestMySQLRemStoredCdrs(t *testing.T) {
|
||||
} else if len(storedCdrs) != 7 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
tm, _ := utils.ParseTimeDetectLayout("2013-11-08T08:42:20Z")
|
||||
tm, _ := utils.ParseTimeDetectLayout("2013-11-08T08:42:20Z", "")
|
||||
cgrIdA1 := utils.Sha1("aaa1", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-08T08:42:22Z")
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-08T08:42:22Z", "")
|
||||
cgrIdA2 := utils.Sha1("aaa2", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:24Z")
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:24Z", "")
|
||||
cgrIdA3 := utils.Sha1("aaa3", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:21Z")
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:21Z", "")
|
||||
cgrIdA4 := utils.Sha1("aaa4", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:25Z")
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:25Z", "")
|
||||
cgrIdA5 := utils.Sha1("aaa5", tm.String())
|
||||
cgrIdB2 := utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
|
||||
cgrIdB3 := utils.Sha1("bbb3", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
|
||||
|
||||
@@ -491,7 +491,7 @@ func TestPSQLSetCdr(t *testing.T) {
|
||||
utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "15s", utils.PDD: "7s", utils.SUPPLIER: "SUPPL1", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": utils.TEST_SQL}
|
||||
|
||||
for _, cdr := range []*CgrCdr{cgrCdr1, cgrCdr2, cgrCdr3, cgrCdr4, cgrCdr5} {
|
||||
if err := psqlDb.SetCdr(cdr.AsStoredCdr()); err != nil {
|
||||
if err := psqlDb.SetCdr(cdr.AsStoredCdr("")); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
@@ -885,15 +885,15 @@ func TestPSQLRemStoredCdrs(t *testing.T) {
|
||||
} else if len(storedCdrs) != 7 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
tm, _ := utils.ParseTimeDetectLayout("2013-11-08T08:42:20Z")
|
||||
tm, _ := utils.ParseTimeDetectLayout("2013-11-08T08:42:20Z", "")
|
||||
cgrIdA1 := utils.Sha1("aaa1", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-08T08:42:22Z")
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-08T08:42:22Z", "")
|
||||
cgrIdA2 := utils.Sha1("aaa2", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:24Z")
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:24Z", "")
|
||||
cgrIdA3 := utils.Sha1("aaa3", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:21Z")
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:21Z", "")
|
||||
cgrIdA4 := utils.Sha1("aaa4", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:25Z")
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:25Z", "")
|
||||
cgrIdA5 := utils.Sha1("aaa5", tm.String())
|
||||
cgrIdB2 := utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
|
||||
cgrIdB3 := utils.Sha1("bbb3", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
|
||||
|
||||
@@ -29,19 +29,19 @@ import (
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
func NewStoredCdrFromExternalCdr(extCdr *ExternalCdr) (*StoredCdr, error) {
|
||||
func NewStoredCdrFromExternalCdr(extCdr *ExternalCdr, timezone string) (*StoredCdr, error) {
|
||||
var err error
|
||||
storedCdr := &StoredCdr{CgrId: extCdr.CgrId, OrderId: extCdr.OrderId, TOR: extCdr.TOR, AccId: extCdr.AccId, CdrHost: extCdr.CdrHost, CdrSource: extCdr.CdrSource,
|
||||
ReqType: extCdr.ReqType, Direction: extCdr.Direction, Tenant: extCdr.Tenant, Category: extCdr.Category, Account: extCdr.Account, Subject: extCdr.Subject,
|
||||
Destination: extCdr.Destination, Supplier: extCdr.Supplier, DisconnectCause: extCdr.DisconnectCause,
|
||||
MediationRunId: extCdr.MediationRunId, RatedAccount: extCdr.RatedAccount, RatedSubject: extCdr.RatedSubject, Cost: extCdr.Cost, Rated: extCdr.Rated}
|
||||
if storedCdr.SetupTime, err = utils.ParseTimeDetectLayout(extCdr.SetupTime); err != nil {
|
||||
if storedCdr.SetupTime, err = utils.ParseTimeDetectLayout(extCdr.SetupTime, timezone); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(storedCdr.CgrId) == 0 { // Populate CgrId if not present
|
||||
storedCdr.CgrId = utils.Sha1(storedCdr.AccId, storedCdr.SetupTime.String())
|
||||
}
|
||||
if storedCdr.AnswerTime, err = utils.ParseTimeDetectLayout(extCdr.AnswerTime); err != nil {
|
||||
if storedCdr.AnswerTime, err = utils.ParseTimeDetectLayout(extCdr.AnswerTime, timezone); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if storedCdr.Usage, err = utils.ParseDurationWithSecs(extCdr.Usage); err != nil {
|
||||
@@ -209,7 +209,7 @@ func (storedCdr *StoredCdr) PassesFieldFilter(fieldFilter *utils.RSRField) (bool
|
||||
return false, ""
|
||||
}
|
||||
|
||||
func (storedCdr *StoredCdr) AsStoredCdr() *StoredCdr {
|
||||
func (storedCdr *StoredCdr) AsStoredCdr(timezone string) *StoredCdr {
|
||||
return storedCdr
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ func (storedCdr *StoredCdr) AsHttpForm() url.Values {
|
||||
// Used in mediation, primaryMandatory marks whether missing field out of request represents error or can be ignored
|
||||
func (storedCdr *StoredCdr) ForkCdr(runId string, reqTypeFld, directionFld, tenantFld, categFld, accountFld, subjectFld, destFld, setupTimeFld, pddFld,
|
||||
answerTimeFld, durationFld, supplierFld, disconnectCauseFld *utils.RSRField,
|
||||
extraFlds []*utils.RSRField, primaryMandatory bool) (*StoredCdr, error) {
|
||||
extraFlds []*utils.RSRField, primaryMandatory bool, timezone string) (*StoredCdr, error) {
|
||||
if reqTypeFld == nil {
|
||||
reqTypeFld, _ = utils.NewRSRField(utils.META_DEFAULT)
|
||||
}
|
||||
@@ -378,13 +378,13 @@ func (storedCdr *StoredCdr) ForkCdr(runId string, reqTypeFld, directionFld, tena
|
||||
sTimeStr := storedCdr.FieldAsString(setupTimeFld)
|
||||
if primaryMandatory && len(sTimeStr) == 0 {
|
||||
return nil, utils.NewErrMandatoryIeMissing(utils.SETUP_TIME, setupTimeFld.Id)
|
||||
} else if frkStorCdr.SetupTime, err = utils.ParseTimeDetectLayout(sTimeStr); err != nil {
|
||||
} else if frkStorCdr.SetupTime, err = utils.ParseTimeDetectLayout(sTimeStr, timezone); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aTimeStr := storedCdr.FieldAsString(answerTimeFld)
|
||||
if primaryMandatory && len(aTimeStr) == 0 {
|
||||
return nil, utils.NewErrMandatoryIeMissing(utils.ANSWER_TIME, answerTimeFld.Id)
|
||||
} else if frkStorCdr.AnswerTime, err = utils.ParseTimeDetectLayout(aTimeStr); err != nil {
|
||||
} else if frkStorCdr.AnswerTime, err = utils.ParseTimeDetectLayout(aTimeStr, timezone); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
durStr := storedCdr.FieldAsString(durationFld)
|
||||
@@ -447,7 +447,7 @@ func (storedCdr *StoredCdr) ComputeLcr() bool {
|
||||
func (storedCdr *StoredCdr) GetName() string {
|
||||
return storedCdr.CdrSource
|
||||
}
|
||||
func (storedCdr *StoredCdr) GetCgrId() string {
|
||||
func (storedCdr *StoredCdr) GetCgrId(timezone string) string {
|
||||
return storedCdr.CgrId
|
||||
}
|
||||
func (storedCdr *StoredCdr) GetUUID() string {
|
||||
@@ -528,7 +528,7 @@ func (storedCdr *StoredCdr) GetReqType(fieldName string) string {
|
||||
}
|
||||
return storedCdr.FieldAsString(&utils.RSRField{Id: fieldName})
|
||||
}
|
||||
func (storedCdr *StoredCdr) GetSetupTime(fieldName string) (time.Time, error) {
|
||||
func (storedCdr *StoredCdr) GetSetupTime(fieldName, timezone string) (time.Time, error) {
|
||||
if utils.IsSliceMember([]string{utils.SETUP_TIME, utils.META_DEFAULT}, fieldName) {
|
||||
return storedCdr.SetupTime, nil
|
||||
}
|
||||
@@ -538,9 +538,9 @@ func (storedCdr *StoredCdr) GetSetupTime(fieldName string) (time.Time, error) {
|
||||
} else {
|
||||
sTimeVal = storedCdr.FieldAsString(&utils.RSRField{Id: fieldName})
|
||||
}
|
||||
return utils.ParseTimeDetectLayout(sTimeVal)
|
||||
return utils.ParseTimeDetectLayout(sTimeVal, timezone)
|
||||
}
|
||||
func (storedCdr *StoredCdr) GetAnswerTime(fieldName string) (time.Time, error) {
|
||||
func (storedCdr *StoredCdr) GetAnswerTime(fieldName, timezone string) (time.Time, error) {
|
||||
if utils.IsSliceMember([]string{utils.ANSWER_TIME, utils.META_DEFAULT}, fieldName) {
|
||||
return storedCdr.AnswerTime, nil
|
||||
}
|
||||
@@ -550,7 +550,7 @@ func (storedCdr *StoredCdr) GetAnswerTime(fieldName string) (time.Time, error) {
|
||||
} else {
|
||||
aTimeVal = storedCdr.FieldAsString(&utils.RSRField{Id: fieldName})
|
||||
}
|
||||
return utils.ParseTimeDetectLayout(aTimeVal)
|
||||
return utils.ParseTimeDetectLayout(aTimeVal, timezone)
|
||||
}
|
||||
func (storedCdr *StoredCdr) GetEndTime() (time.Time, error) {
|
||||
return storedCdr.AnswerTime.Add(storedCdr.Usage), nil
|
||||
@@ -607,7 +607,7 @@ func (storedCdr *StoredCdr) MissingParameter() bool {
|
||||
len(storedCdr.Account) == 0 ||
|
||||
len(storedCdr.Destination) == 0
|
||||
}
|
||||
func (storedCdr *StoredCdr) ParseEventValue(rsrFld *utils.RSRField) string {
|
||||
func (storedCdr *StoredCdr) ParseEventValue(rsrFld *utils.RSRField, timezone string) string {
|
||||
return storedCdr.FieldAsString(rsrFld)
|
||||
}
|
||||
func (storedCdr *StoredCdr) String() string {
|
||||
@@ -660,14 +660,14 @@ type UsageRecord struct {
|
||||
ExtraFields map[string]string
|
||||
}
|
||||
|
||||
func (self *UsageRecord) AsStoredCdr() (*StoredCdr, error) {
|
||||
func (self *UsageRecord) AsStoredCdr(timezone string) (*StoredCdr, error) {
|
||||
var err error
|
||||
storedCdr := &StoredCdr{TOR: self.TOR, ReqType: self.ReqType, Direction: self.Direction, Tenant: self.Tenant, Category: self.Category,
|
||||
Account: self.Account, Subject: self.Subject, Destination: self.Destination}
|
||||
if storedCdr.SetupTime, err = utils.ParseTimeDetectLayout(self.SetupTime); err != nil {
|
||||
if storedCdr.SetupTime, err = utils.ParseTimeDetectLayout(self.SetupTime, timezone); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if storedCdr.AnswerTime, err = utils.ParseTimeDetectLayout(self.AnswerTime); err != nil {
|
||||
if storedCdr.AnswerTime, err = utils.ParseTimeDetectLayout(self.AnswerTime, timezone); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if storedCdr.Usage, err = utils.ParseDurationWithSecs(self.Usage); err != nil {
|
||||
@@ -682,7 +682,7 @@ func (self *UsageRecord) AsStoredCdr() (*StoredCdr, error) {
|
||||
return storedCdr, nil
|
||||
}
|
||||
|
||||
func (self *UsageRecord) AsCallDescriptor() (*CallDescriptor, error) {
|
||||
func (self *UsageRecord) AsCallDescriptor(timezone string) (*CallDescriptor, error) {
|
||||
var err error
|
||||
cd := &CallDescriptor{
|
||||
TOR: self.TOR,
|
||||
@@ -697,7 +697,7 @@ func (self *UsageRecord) AsCallDescriptor() (*CallDescriptor, error) {
|
||||
if len(timeStr) == 0 { // In case of auth, answer time will not be defined, so take it out of setup one
|
||||
timeStr = self.SetupTime
|
||||
}
|
||||
if cd.TimeStart, err = utils.ParseTimeDetectLayout(timeStr); err != nil {
|
||||
if cd.TimeStart, err = utils.ParseTimeDetectLayout(timeStr, timezone); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if usage, err := utils.ParseDurationWithSecs(self.Usage); err != nil {
|
||||
|
||||
@@ -45,7 +45,7 @@ func TestNewStoredCdrFromExternalCdr(t *testing.T) {
|
||||
SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID,
|
||||
Usage: time.Duration(10), Pdd: time.Duration(7) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, RatedAccount: "dan", RatedSubject: "dans", Rated: true,
|
||||
}
|
||||
if storedCdr, err := NewStoredCdrFromExternalCdr(extCdr); err != nil {
|
||||
if storedCdr, err := NewStoredCdrFromExternalCdr(extCdr, ""); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eStorCdr, storedCdr) {
|
||||
t.Errorf("Expected: %+v, received: %+v", eStorCdr, storedCdr)
|
||||
@@ -357,7 +357,7 @@ func TestStoredCdrForkCdr(t *testing.T) {
|
||||
&utils.RSRField{Id: utils.CATEGORY}, &utils.RSRField{Id: utils.ACCOUNT}, &utils.RSRField{Id: utils.SUBJECT}, &utils.RSRField{Id: utils.DESTINATION},
|
||||
&utils.RSRField{Id: utils.SETUP_TIME}, &utils.RSRField{Id: utils.PDD}, &utils.RSRField{Id: utils.ANSWER_TIME}, &utils.RSRField{Id: utils.USAGE},
|
||||
&utils.RSRField{Id: utils.SUPPLIER}, &utils.RSRField{Id: utils.DISCONNECT_CAUSE},
|
||||
[]*utils.RSRField{&utils.RSRField{Id: "field_extr1"}, &utils.RSRField{Id: "field_extr2"}}, true)
|
||||
[]*utils.RSRField{&utils.RSRField{Id: "field_extr1"}, &utils.RSRField{Id: "field_extr2"}}, true, "")
|
||||
if err != nil {
|
||||
t.Error("Unexpected error received", err)
|
||||
}
|
||||
@@ -391,7 +391,7 @@ func TestStoredCdrForkCdrStaticVals(t *testing.T) {
|
||||
rsrStDCause, _ := utils.NewRSRField("^HANGUP_COMPLETE")
|
||||
rsrPdd, _ := utils.NewRSRField("^3")
|
||||
rtCdrOut2, err := storCdr.ForkCdr("wholesale_run", rsrStPostpaid, rsrStIn, rsrStCgr, rsrStPC, rsrStFA, rsrStFS, &utils.RSRField{Id: "destination"},
|
||||
rsrStST, rsrPdd, rsrStAT, rsrStDur, rsrStSuppl, rsrStDCause, []*utils.RSRField{}, true)
|
||||
rsrStST, rsrPdd, rsrStAT, rsrStDur, rsrStSuppl, rsrStDCause, []*utils.RSRField{}, true, "")
|
||||
if err != nil {
|
||||
t.Error("Unexpected error received", err)
|
||||
}
|
||||
@@ -407,7 +407,7 @@ func TestStoredCdrForkCdrStaticVals(t *testing.T) {
|
||||
_, err = storCdr.ForkCdr("wholesale_run", &utils.RSRField{Id: "dummy_header"}, &utils.RSRField{Id: "direction"}, &utils.RSRField{Id: "tenant"},
|
||||
&utils.RSRField{Id: "tor"}, &utils.RSRField{Id: "account"}, &utils.RSRField{Id: "subject"}, &utils.RSRField{Id: "destination"},
|
||||
&utils.RSRField{Id: "setup_time"}, &utils.RSRField{Id: utils.PDD}, &utils.RSRField{Id: "answer_time"}, &utils.RSRField{Id: "duration"}, &utils.RSRField{Id: utils.SUPPLIER},
|
||||
&utils.RSRField{Id: utils.DISCONNECT_CAUSE}, []*utils.RSRField{}, true)
|
||||
&utils.RSRField{Id: utils.DISCONNECT_CAUSE}, []*utils.RSRField{}, true, "")
|
||||
if err == nil {
|
||||
t.Error("Failed to detect missing header")
|
||||
}
|
||||
@@ -429,7 +429,7 @@ func TestStoredCdrForkCdrFromMetaDefaults(t *testing.T) {
|
||||
&utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT},
|
||||
&utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT},
|
||||
&utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT},
|
||||
[]*utils.RSRField{&utils.RSRField{Id: "field_extr1"}, &utils.RSRField{Id: "fieldextr2"}}, true)
|
||||
[]*utils.RSRField{&utils.RSRField{Id: "field_extr1"}, &utils.RSRField{Id: "fieldextr2"}}, true, "")
|
||||
if err != nil {
|
||||
t.Fatal("Unexpected error received", err)
|
||||
}
|
||||
@@ -439,7 +439,7 @@ func TestStoredCdrForkCdrFromMetaDefaults(t *testing.T) {
|
||||
}
|
||||
// Should also accept nil as defaults
|
||||
if cdrOut, err := storCdr.ForkCdr("wholesale_run", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
||||
[]*utils.RSRField{&utils.RSRField{Id: "field_extr1"}, &utils.RSRField{Id: "fieldextr2"}}, true); err != nil {
|
||||
[]*utils.RSRField{&utils.RSRField{Id: "field_extr1"}, &utils.RSRField{Id: "fieldextr2"}}, true, ""); err != nil {
|
||||
t.Fatal("Unexpected error received", err)
|
||||
} else if !reflect.DeepEqual(expctCdr, cdrOut) {
|
||||
t.Errorf("Expected: %v, received: %v", expctCdr, cdrOut)
|
||||
@@ -479,7 +479,7 @@ func TestStoredCdrEventFields(t *testing.T) {
|
||||
if res := cdr.GetName(); res != "test" {
|
||||
t.Error("Received: ", res)
|
||||
}
|
||||
if res := cdr.GetCgrId(); res != utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()) {
|
||||
if res := cdr.GetCgrId(""); res != utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()) {
|
||||
t.Error("Received: ", res)
|
||||
}
|
||||
if res := cdr.GetUUID(); res != "dsafdsaf" {
|
||||
@@ -509,10 +509,10 @@ func TestStoredCdrEventFields(t *testing.T) {
|
||||
if res := cdr.GetReqType(utils.META_DEFAULT); res != utils.META_RATED {
|
||||
t.Error("Received: ", res)
|
||||
}
|
||||
if st, _ := cdr.GetSetupTime(utils.META_DEFAULT); st != time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC) {
|
||||
if st, _ := cdr.GetSetupTime(utils.META_DEFAULT, ""); st != time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC) {
|
||||
t.Error("Received: ", st)
|
||||
}
|
||||
if at, _ := cdr.GetAnswerTime(utils.META_DEFAULT); at != time.Date(2013, 11, 7, 8, 42, 27, 0, time.UTC) {
|
||||
if at, _ := cdr.GetAnswerTime(utils.META_DEFAULT, ""); at != time.Date(2013, 11, 7, 8, 42, 27, 0, time.UTC) {
|
||||
t.Error("Received: ", at)
|
||||
}
|
||||
if et, _ := cdr.GetEndTime(); et != time.Date(2013, 11, 7, 8, 42, 37, 0, time.UTC) {
|
||||
@@ -540,7 +540,7 @@ func TesUsageReqAsStoredCdr(t *testing.T) {
|
||||
eStorCdr := &StoredCdr{TOR: utils.VOICE, ReqType: utils.META_RATED, Direction: "*out",
|
||||
Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), Usage: time.Duration(10)}
|
||||
if storedCdr, err := setupReq.AsStoredCdr(); err != nil {
|
||||
if storedCdr, err := setupReq.AsStoredCdr(""); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eStorCdr, storedCdr) {
|
||||
t.Errorf("Expected: %+v, received: %+v", eStorCdr, storedCdr)
|
||||
@@ -555,7 +555,7 @@ func TestUsageReqAsCD(t *testing.T) {
|
||||
eCD := &CallDescriptor{TOR: req.TOR, Direction: req.Direction,
|
||||
Tenant: req.Tenant, Category: req.Category, Account: req.Account, Subject: req.Subject, Destination: req.Destination,
|
||||
TimeStart: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), TimeEnd: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).Add(time.Duration(10))}
|
||||
if cd, err := req.AsCallDescriptor(); err != nil {
|
||||
if cd, err := req.AsCallDescriptor(""); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eCD, cd) {
|
||||
t.Errorf("Expected: %+v, received: %+v", eCD, cd)
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
type TpReader struct {
|
||||
tpid string
|
||||
timezone string
|
||||
ratingStorage RatingStorage
|
||||
accountingStorage AccountingStorage
|
||||
lr LoadReader
|
||||
@@ -36,9 +37,10 @@ type TpReader struct {
|
||||
users map[string]*UserProfile
|
||||
}
|
||||
|
||||
func NewTpReader(rs RatingStorage, as AccountingStorage, lr LoadReader, tpid string) *TpReader {
|
||||
func NewTpReader(rs RatingStorage, as AccountingStorage, lr LoadReader, tpid, timezone string) *TpReader {
|
||||
tpr := &TpReader{
|
||||
tpid: tpid,
|
||||
timezone: timezone,
|
||||
ratingStorage: rs,
|
||||
accountingStorage: as,
|
||||
lr: lr,
|
||||
@@ -456,7 +458,7 @@ func (tpr *TpReader) LoadLCRs() (err error) {
|
||||
}
|
||||
}
|
||||
tag := utils.LCRKey(tpLcr.Direction, tpLcr.Tenant, tpLcr.Category, tpLcr.Account, tpLcr.Subject)
|
||||
activationTime, _ := utils.ParseTimeDetectLayout(tpLcr.ActivationTime)
|
||||
activationTime, _ := utils.ParseTimeDetectLayout(tpLcr.ActivationTime, tpr.timezone)
|
||||
|
||||
lcr, found := tpr.lcrs[tag]
|
||||
if !found {
|
||||
@@ -611,7 +613,7 @@ func (tpr *TpReader) LoadActionTriggers() (err error) {
|
||||
for key, atrsLst := range storAts {
|
||||
atrs := make([]*ActionTrigger, len(atrsLst))
|
||||
for idx, atr := range atrsLst {
|
||||
balanceExpirationDate, _ := utils.ParseTimeDetectLayout(atr.BalanceExpirationDate)
|
||||
balanceExpirationDate, _ := utils.ParseTimeDetectLayout(atr.BalanceExpirationDate, tpr.timezone)
|
||||
id := atr.Id
|
||||
if id == "" {
|
||||
id = utils.GenUUID()
|
||||
@@ -989,7 +991,7 @@ func (tpr *TpReader) LoadCdrStatsFiltered(tag string, save bool) (err error) {
|
||||
// only return error if there was something there for the tag
|
||||
return fmt.Errorf("could not get action triggers for cdr stats id %s: %s", cs.Id, triggerTag)
|
||||
}
|
||||
UpdateCdrStats(cs, triggers, tpStat)
|
||||
UpdateCdrStats(cs, triggers, tpStat, tpr.timezone)
|
||||
tpr.cdrStats[tag] = cs
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user