diff --git a/engine/mapevent.go b/engine/mapevent.go index 166231426..df6cf4f14 100644 --- a/engine/mapevent.go +++ b/engine/mapevent.go @@ -272,7 +272,7 @@ func (me MapEvent) AsCDR(cfg *config.CGRConfig, tnt, tmz string) (cdr *CDR, err return nil, err } case utils.OrderID: - if cdr.OrderID, err = utils.IfaceAsInt64(v); err != nil { + if cdr.OrderID, err = utils.IfaceAsTInt64(v); err != nil { return nil, err } } diff --git a/utils/reflect.go b/utils/reflect.go index 7a1d5a038..a702eab94 100644 --- a/utils/reflect.go +++ b/utils/reflect.go @@ -152,6 +152,8 @@ func IfaceAsInt64(itm interface{}) (i int64, err error) { return int64(it), nil case time.Duration: return it.Nanoseconds(), nil + case int32: + return int64(it), nil case int64: return it, nil case string: @@ -162,6 +164,29 @@ func IfaceAsInt64(itm interface{}) (i int64, err error) { return } +// same function as IfaceAsInt64 but if the value is float round it to int64 instead of returning error +func IfaceAsTInt64(itm interface{}) (i int64, err error) { + switch it := itm.(type) { + case int: + return int64(it), nil + case time.Duration: + return it.Nanoseconds(), nil + case int32: + return int64(it), nil + case int64: + return it, nil + case float32: + return int64(it), nil + case float64: + return int64(it), nil + case string: + return strconv.ParseInt(it, 10, 64) + default: + err = fmt.Errorf("cannot convert field<%T>: %+v to int", it, it) + } + return +} + func IfaceAsFloat64(itm interface{}) (f float64, err error) { switch it := itm.(type) { case float64: diff --git a/utils/reflect_test.go b/utils/reflect_test.go index d4b4fecdb..5e619f01e 100644 --- a/utils/reflect_test.go +++ b/utils/reflect_test.go @@ -419,6 +419,56 @@ func TestIfaceAsInt64(t *testing.T) { } } +func TestIfaceAsTInt64(t *testing.T) { + eInt := int64(3) + val := interface{}(3) + if itmConvert, err := IfaceAsTInt64(val); err != nil { + t.Error(err) + } else if itmConvert != eInt { + t.Errorf("received: %+v", itmConvert) + } + val = interface{}(time.Duration(3)) + if itmConvert, err := IfaceAsTInt64(val); err != nil { + t.Error(err) + } else if itmConvert != eInt { + t.Errorf("received: %+v", itmConvert) + } + val = interface{}("3") + if itmConvert, err := IfaceAsTInt64(val); err != nil { + t.Error(err) + } else if itmConvert != eInt { + t.Errorf("received: %+v", itmConvert) + } + val = interface{}(int64(3)) + if itmConvert, err := IfaceAsTInt64(val); err != nil { + t.Error(err) + } else if itmConvert != eInt { + t.Errorf("received: %+v", itmConvert) + } + val = interface{}(int32(3)) + if itmConvert, err := IfaceAsTInt64(val); err != nil { + t.Error(err) + } else if itmConvert != eInt { + t.Errorf("received: %+v", itmConvert) + } + val = interface{}(float32(3.14)) + if itmConvert, err := IfaceAsTInt64(val); err != nil { + t.Error(err) + } else if itmConvert != eInt { + t.Errorf("received: %+v", itmConvert) + } + val = interface{}(float64(3.14)) + if itmConvert, err := IfaceAsTInt64(val); err != nil { + t.Error(err) + } else if itmConvert != eInt { + t.Errorf("received: %+v", itmConvert) + } + val = interface{}("This is not an integer") + if _, err := IfaceAsTInt64(val); err == nil { + t.Error("expecting error") + } +} + func TestIfaceAsBool(t *testing.T) { val := interface{}(true) if itmConvert, err := IfaceAsBool(val); err != nil {