mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
using utils types to load data
This commit is contained in:
@@ -34,15 +34,14 @@ const (
|
||||
)
|
||||
|
||||
type ActionTiming struct {
|
||||
Id string // uniquely identify the timing
|
||||
Tag string // informative purpose only
|
||||
UserBalanceIds []string
|
||||
Timing *RateInterval
|
||||
Weight float64
|
||||
ActionsId string
|
||||
actions Actions
|
||||
stCache time.Time // cached time of the next start
|
||||
ActionsTag, TimingsTag string // used only for loading
|
||||
Id string // uniquely identify the timing
|
||||
Tag string // informative purpose only
|
||||
UserBalanceIds []string
|
||||
Timing *RateInterval
|
||||
Weight float64
|
||||
ActionsId string
|
||||
actions Actions
|
||||
stCache time.Time // cached time of the next start
|
||||
}
|
||||
|
||||
type ActionTimings []*ActionTiming
|
||||
|
||||
@@ -86,7 +86,7 @@ func TestActionTimingOnlyMonthdays(t *testing.T) {
|
||||
now := time.Now()
|
||||
y, m, d := now.Date()
|
||||
tomorrow := time.Date(y, m, d, 0, 0, 0, 0, time.Local).AddDate(0, 0, 1)
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{MonthDays: MonthDays{1, 25, 2, tomorrow.Day()}}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{MonthDays: utils.MonthDays{1, 25, 2, tomorrow.Day()}}}}
|
||||
st := at.GetNextStartTime()
|
||||
expected := tomorrow
|
||||
if !st.Equal(expected) {
|
||||
@@ -103,7 +103,7 @@ func TestActionTimingHourMonthdays(t *testing.T) {
|
||||
if now.After(testTime) {
|
||||
day = tomorrow.Day()
|
||||
}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{MonthDays: MonthDays{now.Day(), tomorrow.Day()}, StartTime: "10:01:00"}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{MonthDays: utils.MonthDays{now.Day(), tomorrow.Day()}, StartTime: "10:01:00"}}}
|
||||
st := at.GetNextStartTime()
|
||||
expected := time.Date(y, m, day, 10, 1, 0, 0, time.Local)
|
||||
if !st.Equal(expected) {
|
||||
@@ -115,7 +115,7 @@ func TestActionTimingOnlyMonths(t *testing.T) {
|
||||
now := time.Now()
|
||||
y, m, d := now.Date()
|
||||
nextMonth := time.Date(y, m, d, 0, 0, 0, 0, time.Local).AddDate(0, 1, 0)
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Months: Months{time.February, time.May, nextMonth.Month()}}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Months: utils.Months{time.February, time.May, nextMonth.Month()}}}}
|
||||
st := at.GetNextStartTime()
|
||||
expected := time.Date(y, nextMonth.Month(), 1, 0, 0, 0, 0, time.Local)
|
||||
if !st.Equal(expected) {
|
||||
@@ -132,7 +132,7 @@ func TestActionTimingHourMonths(t *testing.T) {
|
||||
if now.After(testTime) {
|
||||
month = nextMonth.Month()
|
||||
}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Months: Months{now.Month(), nextMonth.Month()}, StartTime: "10:01:00"}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Months: utils.Months{now.Month(), nextMonth.Month()}, StartTime: "10:01:00"}}}
|
||||
st := at.GetNextStartTime()
|
||||
expected := time.Date(y, month, d, 10, 1, 0, 0, time.Local)
|
||||
if !st.Equal(expected) {
|
||||
@@ -159,8 +159,8 @@ func TestActionTimingHourMonthdaysMonths(t *testing.T) {
|
||||
}
|
||||
at := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Months: Months{now.Month(), nextMonth.Month()},
|
||||
MonthDays: MonthDays{now.Day(), tomorrow.Day()},
|
||||
Months: utils.Months{now.Month(), nextMonth.Month()},
|
||||
MonthDays: utils.MonthDays{now.Day(), tomorrow.Day()},
|
||||
StartTime: "10:01:00",
|
||||
},
|
||||
}}
|
||||
@@ -177,8 +177,8 @@ func TestActionTimingFirstOfTheMonth(t *testing.T) {
|
||||
nextMonth := time.Date(y, m, 1, 0, 0, 0, 0, time.Local).AddDate(0, 1, 0)
|
||||
at := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Months: Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
|
||||
MonthDays: MonthDays{1},
|
||||
Months: utils.Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
|
||||
MonthDays: utils.MonthDays{1},
|
||||
},
|
||||
}}
|
||||
st := at.GetNextStartTime()
|
||||
@@ -192,7 +192,7 @@ func TestActionTimingOnlyYears(t *testing.T) {
|
||||
now := time.Now()
|
||||
y, m, d := now.Date()
|
||||
nextYear := time.Date(y, m, d, 0, 0, 0, 0, time.Local).AddDate(1, 0, 0)
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: Years{now.Year(), nextYear.Year()}}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{now.Year(), nextYear.Year()}}}}
|
||||
st := at.GetNextStartTime()
|
||||
expected := time.Date(nextYear.Year(), 1, 1, 0, 0, 0, 0, time.Local)
|
||||
if !st.Equal(expected) {
|
||||
@@ -209,7 +209,7 @@ func TestActionTimingHourYears(t *testing.T) {
|
||||
if now.After(testTime) {
|
||||
year = nextYear.Year()
|
||||
}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: Years{now.Year(), nextYear.Year()}, StartTime: "10:01:00"}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{now.Year(), nextYear.Year()}, StartTime: "10:01:00"}}}
|
||||
st := at.GetNextStartTime()
|
||||
expected := time.Date(year, m, d, 10, 1, 0, 0, time.Local)
|
||||
if !st.Equal(expected) {
|
||||
@@ -236,8 +236,8 @@ func TestActionTimingHourMonthdaysYear(t *testing.T) {
|
||||
}
|
||||
at := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: Years{now.Year(), nextYear.Year()},
|
||||
MonthDays: MonthDays{now.Day(), tomorrow.Day()},
|
||||
Years: utils.Years{now.Year(), nextYear.Year()},
|
||||
MonthDays: utils.MonthDays{now.Day(), tomorrow.Day()},
|
||||
StartTime: "10:01:00",
|
||||
},
|
||||
}}
|
||||
@@ -275,9 +275,9 @@ func TestActionTimingHourMonthdaysMonthYear(t *testing.T) {
|
||||
}
|
||||
at := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: Years{now.Year(), nextYear.Year()},
|
||||
Months: Months{now.Month(), nextMonth.Month()},
|
||||
MonthDays: MonthDays{now.Day(), tomorrow.Day()},
|
||||
Years: utils.Years{now.Year(), nextYear.Year()},
|
||||
Months: utils.Months{now.Month(), nextMonth.Month()},
|
||||
MonthDays: utils.MonthDays{now.Day(), tomorrow.Day()},
|
||||
StartTime: "10:01:00",
|
||||
},
|
||||
}}
|
||||
@@ -294,9 +294,9 @@ func TestActionTimingFirstOfTheYear(t *testing.T) {
|
||||
nextYear := time.Date(y, 1, 1, 0, 0, 0, 0, time.Local).AddDate(1, 0, 0)
|
||||
at := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: Years{nextYear.Year()},
|
||||
Months: Months{time.January},
|
||||
MonthDays: MonthDays{1},
|
||||
Years: utils.Years{nextYear.Year()},
|
||||
Months: utils.Months{time.January},
|
||||
MonthDays: utils.MonthDays{1},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
}}
|
||||
@@ -313,7 +313,7 @@ func TestActionTimingFirstMonthOfTheYear(t *testing.T) {
|
||||
nextYear := time.Date(y, 1, 1, 0, 0, 0, 0, time.Local).AddDate(1, 0, 0)
|
||||
at := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Months: Months{time.January},
|
||||
Months: utils.Months{time.January},
|
||||
},
|
||||
}}
|
||||
st := at.GetNextStartTime()
|
||||
@@ -367,18 +367,18 @@ func TestActionTimingLogFunction(t *testing.T) {
|
||||
func TestActionTimingPriotityListSortByWeight(t *testing.T) {
|
||||
at1 := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: Years{2100},
|
||||
Months: Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
|
||||
MonthDays: MonthDays{1},
|
||||
Years: utils.Years{2100},
|
||||
Months: utils.Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
|
||||
MonthDays: utils.MonthDays{1},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
Weight: 20,
|
||||
}}
|
||||
at2 := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: Years{2100},
|
||||
Months: Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
|
||||
MonthDays: MonthDays{2},
|
||||
Years: utils.Years{2100},
|
||||
Months: utils.Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
|
||||
MonthDays: utils.MonthDays{2},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
Weight: 10,
|
||||
@@ -395,8 +395,8 @@ func TestActionTimingPriotityListWeight(t *testing.T) {
|
||||
at1 := &ActionTiming{
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Months: Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
|
||||
MonthDays: MonthDays{1},
|
||||
Months: utils.Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
|
||||
MonthDays: utils.MonthDays{1},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
},
|
||||
@@ -405,8 +405,8 @@ func TestActionTimingPriotityListWeight(t *testing.T) {
|
||||
at2 := &ActionTiming{
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Months: Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
|
||||
MonthDays: MonthDays{1},
|
||||
Months: utils.Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
|
||||
MonthDays: utils.MonthDays{1},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
},
|
||||
@@ -871,9 +871,9 @@ func TestActionTriggerLogging(t *testing.T) {
|
||||
func TestActionTimingLogging(t *testing.T) {
|
||||
i := &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Months: Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
|
||||
MonthDays: MonthDays{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
|
||||
WeekDays: WeekDays{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
|
||||
Months: utils.Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
|
||||
MonthDays: utils.MonthDays{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
|
||||
WeekDays: utils.WeekDays{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
|
||||
StartTime: "18:00:00",
|
||||
EndTime: "00:00:00",
|
||||
},
|
||||
|
||||
@@ -161,13 +161,15 @@ func (cd *CallDescriptor) getRatingPlansForPrefix(key string, recursionDepth int
|
||||
if err != nil || rp == nil {
|
||||
return err
|
||||
}
|
||||
if err = rp.GetRatingPlansForPrefix(cd); err != nil {
|
||||
if err = rp.GetRatingPlansForPrefix(cd); err != nil || !cd.continousRatingInfos() {
|
||||
// try rating profile fallback
|
||||
if len(rp.FallbackKeys) > 0 {
|
||||
recursionDepth++
|
||||
for _, fbk := range rp.FallbackKeys {
|
||||
if err := cd.getRatingPlansForPrefix(fbk, recursionDepth); err == nil {
|
||||
return err
|
||||
for _, ri := range cd.RatingInfos {
|
||||
if len(ri.FallbackKeys) > 0 {
|
||||
recursionDepth++
|
||||
for _, fbk := range ri.FallbackKeys {
|
||||
if err := cd.getRatingPlansForPrefix(fbk, recursionDepth); err == nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,272 +0,0 @@
|
||||
/*
|
||||
Rating system designed to be used in VoIP Carriers World
|
||||
Copyright (C) 2013 ITsysCOM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package engine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Defines years days series
|
||||
type Years []int
|
||||
|
||||
func (ys Years) Sort() {
|
||||
sort.Sort(ys)
|
||||
}
|
||||
|
||||
func (ys Years) Len() int {
|
||||
return len(ys)
|
||||
}
|
||||
|
||||
func (ys Years) Swap(i, j int) {
|
||||
ys[i], ys[j] = ys[j], ys[i]
|
||||
}
|
||||
|
||||
func (ys Years) Less(j, i int) bool {
|
||||
return ys[j] < ys[i]
|
||||
}
|
||||
|
||||
// Return true if the specified date is inside the series
|
||||
func (ys Years) Contains(year int) (result bool) {
|
||||
result = false
|
||||
for _, yss := range ys {
|
||||
if yss == year {
|
||||
result = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Parse Years elements from string separated by sep.
|
||||
func (ys *Years) Parse(input, sep string) {
|
||||
switch input {
|
||||
case "*any", "":
|
||||
*ys = []int{}
|
||||
default:
|
||||
elements := strings.Split(input, sep)
|
||||
for _, yss := range elements {
|
||||
if year, err := strconv.Atoi(yss); err == nil {
|
||||
*ys = append(*ys, year)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ys Years) Serialize(sep string) string {
|
||||
if len(ys) == 0 {
|
||||
return "*any"
|
||||
}
|
||||
var yStr string
|
||||
for idx, yr := range ys {
|
||||
if idx != 0 {
|
||||
yStr = fmt.Sprintf("%s%s%d", yStr, sep, yr)
|
||||
} else {
|
||||
yStr = strconv.Itoa(yr)
|
||||
}
|
||||
}
|
||||
return yStr
|
||||
}
|
||||
|
||||
// Defines months series
|
||||
type Months []time.Month
|
||||
|
||||
func (m Months) Sort() {
|
||||
sort.Sort(m)
|
||||
}
|
||||
|
||||
func (m Months) Len() int {
|
||||
return len(m)
|
||||
}
|
||||
|
||||
func (m Months) Swap(i, j int) {
|
||||
m[i], m[j] = m[j], m[i]
|
||||
}
|
||||
|
||||
func (m Months) Less(j, i int) bool {
|
||||
return m[j] < m[i]
|
||||
}
|
||||
|
||||
// Return true if the specified date is inside the series
|
||||
func (m Months) Contains(month time.Month) (result bool) {
|
||||
for _, ms := range m {
|
||||
if ms == month {
|
||||
result = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Loades Month elemnents from a string separated by sep.
|
||||
func (m *Months) Parse(input, sep string) {
|
||||
switch input {
|
||||
case "*any", "": // Apier cannot receive empty string, hence using meta-tag
|
||||
*m = []time.Month{}
|
||||
default:
|
||||
elements := strings.Split(input, sep)
|
||||
for _, ms := range elements {
|
||||
if month, err := strconv.Atoi(ms); err == nil {
|
||||
*m = append(*m, time.Month(month))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dumps the months in a serialized string, similar to the one parsed
|
||||
func (m Months) Serialize(sep string) string {
|
||||
if len(m) == 0 {
|
||||
return "*any"
|
||||
}
|
||||
var mStr string
|
||||
for idx, mt := range m {
|
||||
if idx != 0 {
|
||||
mStr = fmt.Sprintf("%s%s%d", mStr, sep, mt)
|
||||
} else {
|
||||
mStr = strconv.Itoa(int(mt))
|
||||
}
|
||||
}
|
||||
return mStr
|
||||
}
|
||||
|
||||
// Defines month days series
|
||||
type MonthDays []int
|
||||
|
||||
func (md MonthDays) Sort() {
|
||||
sort.Sort(md)
|
||||
}
|
||||
|
||||
func (md MonthDays) Len() int {
|
||||
return len(md)
|
||||
}
|
||||
|
||||
func (md MonthDays) Swap(i, j int) {
|
||||
md[i], md[j] = md[j], md[i]
|
||||
}
|
||||
|
||||
func (md MonthDays) Less(j, i int) bool {
|
||||
return md[j] < md[i]
|
||||
}
|
||||
|
||||
// Return true if the specified date is inside the series
|
||||
func (md MonthDays) Contains(monthDay int) (result bool) {
|
||||
result = false
|
||||
for _, mds := range md {
|
||||
if mds == monthDay {
|
||||
result = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Parse MonthDay elements from string separated by sep.
|
||||
func (md *MonthDays) Parse(input, sep string) {
|
||||
switch input {
|
||||
case "*any", "":
|
||||
*md = []int{}
|
||||
default:
|
||||
elements := strings.Split(input, sep)
|
||||
for _, mds := range elements {
|
||||
if day, err := strconv.Atoi(mds); err == nil {
|
||||
*md = append(*md, day)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dumps the month days in a serialized string, similar to the one parsed
|
||||
func (md MonthDays) Serialize(sep string) string {
|
||||
if len(md) == 0 {
|
||||
return "*any"
|
||||
}
|
||||
var mdsStr string
|
||||
for idx, mDay := range md {
|
||||
if idx != 0 {
|
||||
mdsStr = fmt.Sprintf("%s%s%d", mdsStr, sep, mDay)
|
||||
} else {
|
||||
mdsStr = strconv.Itoa(mDay)
|
||||
}
|
||||
}
|
||||
return mdsStr
|
||||
}
|
||||
|
||||
// Defines week days series
|
||||
type WeekDays []time.Weekday
|
||||
|
||||
func (wd WeekDays) Sort() {
|
||||
sort.Sort(wd)
|
||||
}
|
||||
|
||||
func (wd WeekDays) Len() int {
|
||||
return len(wd)
|
||||
}
|
||||
|
||||
func (wd WeekDays) Swap(i, j int) {
|
||||
wd[i], wd[j] = wd[j], wd[i]
|
||||
}
|
||||
|
||||
func (wd WeekDays) Less(j, i int) bool {
|
||||
return wd[j] < wd[i]
|
||||
}
|
||||
|
||||
// Return true if the specified date is inside the series
|
||||
func (wd WeekDays) Contains(weekDay time.Weekday) (result bool) {
|
||||
result = false
|
||||
for _, wds := range wd {
|
||||
if wds == weekDay {
|
||||
result = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (wd *WeekDays) Parse(input, sep string) {
|
||||
switch input {
|
||||
case "*any", "":
|
||||
*wd = []time.Weekday{}
|
||||
default:
|
||||
elements := strings.Split(input, sep)
|
||||
for _, wds := range elements {
|
||||
if day, err := strconv.Atoi(wds); err == nil {
|
||||
*wd = append(*wd, time.Weekday(day%7)) // %7 for sunday = 7 normalization
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dumps the week days in a serialized string, similar to the one parsed
|
||||
func (wd WeekDays) Serialize(sep string) string {
|
||||
if len(wd) == 0 {
|
||||
return "*any"
|
||||
}
|
||||
var wdStr string
|
||||
for idx, d := range wd {
|
||||
if idx != 0 {
|
||||
wdStr = fmt.Sprintf("%s%s%d", wdStr, sep, d)
|
||||
} else {
|
||||
wdStr = strconv.Itoa(int(d))
|
||||
}
|
||||
}
|
||||
return wdStr
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
Rating system designed to be used in VoIP Carriers World
|
||||
Copyright (C) 2013 ITsysCOM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package engine
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestMonthStoreRestoreJson(t *testing.T) {
|
||||
m := Months{5, 6, 7, 8}
|
||||
r, _ := json.Marshal(m)
|
||||
if string(r) != "[5,6,7,8]" {
|
||||
t.Errorf("Error serializing months: %v", string(r))
|
||||
}
|
||||
o := Months{}
|
||||
json.Unmarshal(r, &o)
|
||||
if !reflect.DeepEqual(o, m) {
|
||||
t.Errorf("Expected %v was %v", m, o)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMonthDayStoreRestoreJson(t *testing.T) {
|
||||
md := MonthDays{24, 25, 26}
|
||||
r, _ := json.Marshal(md)
|
||||
if string(r) != "[24,25,26]" {
|
||||
t.Errorf("Error serializing month days: %v", string(r))
|
||||
}
|
||||
o := MonthDays{}
|
||||
json.Unmarshal(r, &o)
|
||||
if !reflect.DeepEqual(o, md) {
|
||||
t.Errorf("Expected %v was %v", md, o)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWeekDayStoreRestoreJson(t *testing.T) {
|
||||
wd := WeekDays{time.Saturday, time.Sunday}
|
||||
r, _ := json.Marshal(wd)
|
||||
if string(r) != "[6,0]" {
|
||||
t.Errorf("Error serializing week days: %v", string(r))
|
||||
}
|
||||
o := WeekDays{}
|
||||
json.Unmarshal(r, &o)
|
||||
if !reflect.DeepEqual(o, wd) {
|
||||
t.Errorf("Expected %v was %v", wd, o)
|
||||
}
|
||||
}
|
||||
|
||||
func TestYearsSerialize(t *testing.T) {
|
||||
ys := &Years{}
|
||||
yString := ys.Serialize(";")
|
||||
expectString := "*any"
|
||||
if expectString != yString {
|
||||
t.Errorf("Expected: %s, got: %s", expectString, yString)
|
||||
}
|
||||
ys2 := &Years{2012}
|
||||
yString2 := ys2.Serialize(";")
|
||||
expectString2 := "2012"
|
||||
if expectString2 != yString2 {
|
||||
t.Errorf("Expected: %s, got: %s", expectString2, yString2)
|
||||
}
|
||||
ys3 := &Years{2013, 2014, 2015}
|
||||
yString3 := ys3.Serialize(";")
|
||||
expectString3 := "2013;2014;2015"
|
||||
if expectString3 != yString3 {
|
||||
t.Errorf("Expected: %s, got: %s", expectString3, yString3)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMonthsSerialize(t *testing.T) {
|
||||
mths := &Months{}
|
||||
mString := mths.Serialize(";")
|
||||
expectString := "*any"
|
||||
if expectString != mString {
|
||||
t.Errorf("Expected: %s, got: %s", expectString, mString)
|
||||
}
|
||||
mths2 := &Months{time.January}
|
||||
mString2 := mths2.Serialize(";")
|
||||
expectString2 := "1"
|
||||
if expectString2 != mString2 {
|
||||
t.Errorf("Expected: %s, got: %s", expectString2, mString2)
|
||||
}
|
||||
mths3 := &Months{time.January, time.December}
|
||||
mString3 := mths3.Serialize(";")
|
||||
expectString3 := "1;12"
|
||||
if expectString3 != mString3 {
|
||||
t.Errorf("Expected: %s, got: %s", expectString3, mString3)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMonthDaysSerialize(t *testing.T) {
|
||||
mds := &MonthDays{}
|
||||
mdsString := mds.Serialize(";")
|
||||
expectString := "*any"
|
||||
if expectString != mdsString {
|
||||
t.Errorf("Expected: %s, got: %s", expectString, mdsString)
|
||||
}
|
||||
mds2 := &MonthDays{1}
|
||||
mdsString2 := mds2.Serialize(";")
|
||||
expectString2 := "1"
|
||||
if expectString2 != mdsString2 {
|
||||
t.Errorf("Expected: %s, got: %s", expectString2, mdsString2)
|
||||
}
|
||||
mds3 := &MonthDays{1, 2, 3, 4, 5}
|
||||
mdsString3 := mds3.Serialize(";")
|
||||
expectString3 := "1;2;3;4;5"
|
||||
if expectString3 != mdsString3 {
|
||||
t.Errorf("Expected: %s, got: %s", expectString3, mdsString3)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWeekDaysSerialize(t *testing.T) {
|
||||
wds := &WeekDays{}
|
||||
wdsString := wds.Serialize(";")
|
||||
expectString := "*any"
|
||||
if expectString != wdsString {
|
||||
t.Errorf("Expected: %s, got: %s", expectString, wdsString)
|
||||
}
|
||||
wds2 := &WeekDays{time.Monday}
|
||||
wdsString2 := wds2.Serialize(";")
|
||||
expectString2 := "1"
|
||||
if expectString2 != wdsString2 {
|
||||
t.Errorf("Expected: %s, got: %s", expectString2, wdsString2)
|
||||
}
|
||||
wds3 := &WeekDays{time.Monday, time.Saturday, time.Sunday}
|
||||
wdsString3 := wds3.Serialize(";")
|
||||
expectString3 := "1;6;0"
|
||||
if expectString3 != wdsString3 {
|
||||
t.Errorf("Expected: %s, got: %s", expectString3, wdsString3)
|
||||
}
|
||||
}
|
||||
@@ -38,9 +38,9 @@ type CSVReader struct {
|
||||
actionsTriggers map[string][]*ActionTrigger
|
||||
accountActions []*UserBalance
|
||||
destinations []*Destination
|
||||
timings map[string]*Timing
|
||||
rates map[string][]*LoadRate
|
||||
destinationRates map[string][]*DestinationRate
|
||||
timings map[string]*utils.TPTiming
|
||||
rates map[string]*utils.TPRate
|
||||
destinationRates map[string]*utils.TPDestinationRate
|
||||
ratingPlans map[string]*RatingPlan
|
||||
ratingProfiles map[string]*RatingProfile
|
||||
// file names
|
||||
@@ -55,9 +55,9 @@ func NewFileCSVReader(storage DataStorage, sep rune, destinationsFn, timingsFn,
|
||||
c.actions = make(map[string][]*Action)
|
||||
c.actionsTimings = make(map[string][]*ActionTiming)
|
||||
c.actionsTriggers = make(map[string][]*ActionTrigger)
|
||||
c.rates = make(map[string][]*LoadRate)
|
||||
c.destinationRates = make(map[string][]*DestinationRate)
|
||||
c.timings = make(map[string]*Timing)
|
||||
c.rates = make(map[string]*utils.TPRate)
|
||||
c.destinationRates = make(map[string]*utils.TPDestinationRate)
|
||||
c.timings = make(map[string]*utils.TPTiming)
|
||||
c.ratingPlans = make(map[string]*RatingPlan)
|
||||
c.ratingProfiles = make(map[string]*RatingProfile)
|
||||
c.readerFunc = openFileCSVReader
|
||||
@@ -236,7 +236,7 @@ func (csvr *CSVReader) LoadRates() (err error) {
|
||||
|
||||
for record, err := csvReader.Read(); err == nil; record, err = csvReader.Read() {
|
||||
tag := record[0]
|
||||
var r *LoadRate
|
||||
var r *utils.TPRate
|
||||
r, err = NewLoadRate(record[0], record[1], record[2], record[3], record[4], record[5], record[6], record[7])
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -244,11 +244,14 @@ func (csvr *CSVReader) LoadRates() (err error) {
|
||||
// same tag only to create rate groups
|
||||
existingRates, exists := csvr.rates[tag]
|
||||
if exists {
|
||||
if err := existingRates[len(existingRates)-1].ValidNextGroup(r); err != nil {
|
||||
rss := existingRates.RateSlots
|
||||
if err := ValidNextGroup(rss[len(rss)-1], r.RateSlots[0]); err != nil {
|
||||
return err
|
||||
}
|
||||
csvr.rates[tag].RateSlots = append(csvr.rates[tag].RateSlots, r.RateSlots[0])
|
||||
} else {
|
||||
csvr.rates[tag] = r
|
||||
}
|
||||
csvr.rates[tag] = append(csvr.rates[tag], r)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -283,13 +286,22 @@ func (csvr *CSVReader) LoadDestinationRates() (err error) {
|
||||
return fmt.Errorf("Could not get destination for tag %v", record[1])
|
||||
}
|
||||
}
|
||||
dr := &DestinationRate{
|
||||
Tag: tag,
|
||||
DestinationsTag: record[1],
|
||||
rates: r,
|
||||
dr := &utils.TPDestinationRate{
|
||||
DestinationRateId: tag,
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: record[1],
|
||||
Rate: r,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
csvr.destinationRates[tag] = append(csvr.destinationRates[tag], dr)
|
||||
existingDR, exists := csvr.destinationRates[tag]
|
||||
if exists {
|
||||
existingDR.DestinationRates = append(existingDR.DestinationRates, dr.DestinationRates[0])
|
||||
} else {
|
||||
existingDR = dr
|
||||
}
|
||||
csvr.destinationRates[tag] = existingDR
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -314,14 +326,14 @@ func (csvr *CSVReader) LoadRatingPlans() (err error) {
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("Could not find destination rate for tag %v", record[1]))
|
||||
}
|
||||
drt := NewDestinationRateTiming(t, record[3])
|
||||
rpl := NewRatingPlan(t, record[3])
|
||||
plan, exists := csvr.ratingPlans[tag]
|
||||
if !exists {
|
||||
plan = &RatingPlan{Id: tag}
|
||||
csvr.ratingPlans[tag] = plan
|
||||
}
|
||||
for _, dr := range drs {
|
||||
plan.AddRateInterval(dr.DestinationsTag, drt.GetRateInterval(dr))
|
||||
for _, dr := range drs.DestinationRates {
|
||||
plan.AddRateInterval(dr.DestinationId, GetRateInterval(rpl, dr))
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
@@ -190,45 +190,45 @@ func TestLoadTimimgs(t *testing.T) {
|
||||
t.Error("Failed to load timings: ", csvr.timings)
|
||||
}
|
||||
timing := csvr.timings["WORKDAYS_00"]
|
||||
if !reflect.DeepEqual(timing, &Timing{
|
||||
if !reflect.DeepEqual(timing, &utils.TPTiming{
|
||||
Id: "WORKDAYS_00",
|
||||
Years: Years{},
|
||||
Months: Months{},
|
||||
MonthDays: MonthDays{},
|
||||
WeekDays: WeekDays{1, 2, 3, 4, 5},
|
||||
Years: utils.Years{},
|
||||
Months: utils.Months{},
|
||||
MonthDays: utils.MonthDays{},
|
||||
WeekDays: utils.WeekDays{1, 2, 3, 4, 5},
|
||||
StartTime: "00:00:00",
|
||||
}) {
|
||||
t.Error("Error loading timing: ", timing)
|
||||
}
|
||||
timing = csvr.timings["WORKDAYS_18"]
|
||||
if !reflect.DeepEqual(timing, &Timing{
|
||||
if !reflect.DeepEqual(timing, &utils.TPTiming{
|
||||
Id: "WORKDAYS_18",
|
||||
Years: Years{},
|
||||
Months: Months{},
|
||||
MonthDays: MonthDays{},
|
||||
WeekDays: WeekDays{1, 2, 3, 4, 5},
|
||||
Years: utils.Years{},
|
||||
Months: utils.Months{},
|
||||
MonthDays: utils.MonthDays{},
|
||||
WeekDays: utils.WeekDays{1, 2, 3, 4, 5},
|
||||
StartTime: "18:00:00",
|
||||
}) {
|
||||
t.Error("Error loading timing: ", timing)
|
||||
}
|
||||
timing = csvr.timings["WEEKENDS"]
|
||||
if !reflect.DeepEqual(timing, &Timing{
|
||||
if !reflect.DeepEqual(timing, &utils.TPTiming{
|
||||
Id: "WEEKENDS",
|
||||
Years: Years{},
|
||||
Months: Months{},
|
||||
MonthDays: MonthDays{},
|
||||
WeekDays: WeekDays{time.Saturday, time.Sunday},
|
||||
Years: utils.Years{},
|
||||
Months: utils.Months{},
|
||||
MonthDays: utils.MonthDays{},
|
||||
WeekDays: utils.WeekDays{time.Saturday, time.Sunday},
|
||||
StartTime: "00:00:00",
|
||||
}) {
|
||||
t.Error("Error loading timing: ", timing)
|
||||
}
|
||||
timing = csvr.timings["ONE_TIME_RUN"]
|
||||
if !reflect.DeepEqual(timing, &Timing{
|
||||
if !reflect.DeepEqual(timing, &utils.TPTiming{
|
||||
Id: "ONE_TIME_RUN",
|
||||
Years: Years{2012},
|
||||
Months: Months{},
|
||||
MonthDays: MonthDays{},
|
||||
WeekDays: WeekDays{},
|
||||
Years: utils.Years{2012},
|
||||
Months: utils.Months{},
|
||||
MonthDays: utils.MonthDays{},
|
||||
WeekDays: utils.WeekDays{},
|
||||
StartTime: "*asap",
|
||||
}) {
|
||||
t.Error("Error loading timing: ", timing)
|
||||
@@ -239,24 +239,22 @@ func TestLoadRates(t *testing.T) {
|
||||
if len(csvr.rates) != 9 {
|
||||
t.Error("Failed to load rates: ", csvr.rates)
|
||||
}
|
||||
rate := csvr.rates["R1"][0]
|
||||
if !reflect.DeepEqual(rate, &LoadRate{
|
||||
Tag: "R1",
|
||||
rate := csvr.rates["R1"].RateSlots[0]
|
||||
if !reflect.DeepEqual(rate, &utils.RateSlot{
|
||||
ConnectFee: 0,
|
||||
Price: 0.2,
|
||||
Rate: 0.2,
|
||||
RateUnit: time.Minute,
|
||||
RateIncrement: time.Second,
|
||||
GroupIntervalStart: 0,
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 2,
|
||||
}) {
|
||||
t.Error("Error loading rate: ", csvr.rates["R1"][0])
|
||||
t.Error("Error loading rate: ", csvr.rates["R1"].RateSlots[0])
|
||||
}
|
||||
rate = csvr.rates["R2"][0]
|
||||
if !reflect.DeepEqual(rate, &LoadRate{
|
||||
Tag: "R2",
|
||||
rate = csvr.rates["R2"].RateSlots[0]
|
||||
if !reflect.DeepEqual(rate, &utils.RateSlot{
|
||||
ConnectFee: 0,
|
||||
Price: 0.1,
|
||||
Rate: 0.1,
|
||||
RateUnit: time.Minute,
|
||||
RateIncrement: time.Second,
|
||||
GroupIntervalStart: 0,
|
||||
@@ -265,11 +263,10 @@ func TestLoadRates(t *testing.T) {
|
||||
}) {
|
||||
t.Error("Error loading rate: ", csvr.rates)
|
||||
}
|
||||
rate = csvr.rates["R3"][0]
|
||||
if !reflect.DeepEqual(rate, &LoadRate{
|
||||
Tag: "R3",
|
||||
rate = csvr.rates["R3"].RateSlots[0]
|
||||
if !reflect.DeepEqual(rate, &utils.RateSlot{
|
||||
ConnectFee: 0,
|
||||
Price: 0.05,
|
||||
Rate: 0.05,
|
||||
RateUnit: time.Minute,
|
||||
RateIncrement: time.Second,
|
||||
GroupIntervalStart: 0,
|
||||
@@ -278,11 +275,10 @@ func TestLoadRates(t *testing.T) {
|
||||
}) {
|
||||
t.Error("Error loading rate: ", csvr.rates)
|
||||
}
|
||||
rate = csvr.rates["R4"][0]
|
||||
if !reflect.DeepEqual(rate, &LoadRate{
|
||||
Tag: "R4",
|
||||
rate = csvr.rates["R4"].RateSlots[0]
|
||||
if !reflect.DeepEqual(rate, &utils.RateSlot{
|
||||
ConnectFee: 1,
|
||||
Price: 1.0,
|
||||
Rate: 1.0,
|
||||
RateUnit: time.Second,
|
||||
RateIncrement: time.Second,
|
||||
GroupIntervalStart: 0,
|
||||
@@ -291,11 +287,10 @@ func TestLoadRates(t *testing.T) {
|
||||
}) {
|
||||
t.Error("Error loading rate: ", csvr.rates)
|
||||
}
|
||||
rate = csvr.rates["R5"][0]
|
||||
if !reflect.DeepEqual(rate, &LoadRate{
|
||||
Tag: "R5",
|
||||
rate = csvr.rates["R5"].RateSlots[0]
|
||||
if !reflect.DeepEqual(rate, &utils.RateSlot{
|
||||
ConnectFee: 0,
|
||||
Price: 0.5,
|
||||
Rate: 0.5,
|
||||
RateUnit: time.Second,
|
||||
RateIncrement: time.Second,
|
||||
GroupIntervalStart: 0,
|
||||
@@ -305,11 +300,10 @@ func TestLoadRates(t *testing.T) {
|
||||
t.Error("Error loading rate: ", csvr.rates)
|
||||
}
|
||||
|
||||
rate = csvr.rates["LANDLINE_OFFPEAK"][0]
|
||||
if !reflect.DeepEqual(rate, &LoadRate{
|
||||
Tag: "LANDLINE_OFFPEAK",
|
||||
rate = csvr.rates["LANDLINE_OFFPEAK"].RateSlots[0]
|
||||
if !reflect.DeepEqual(rate, &utils.RateSlot{
|
||||
ConnectFee: 0,
|
||||
Price: 1,
|
||||
Rate: 1,
|
||||
RateUnit: time.Second,
|
||||
RateIncrement: time.Minute,
|
||||
GroupIntervalStart: 0,
|
||||
@@ -318,11 +312,10 @@ func TestLoadRates(t *testing.T) {
|
||||
}) {
|
||||
t.Errorf("Error loading rate: %+v", rate)
|
||||
}
|
||||
rate = csvr.rates["LANDLINE_OFFPEAK"][1]
|
||||
if !reflect.DeepEqual(rate, &LoadRate{
|
||||
Tag: "LANDLINE_OFFPEAK",
|
||||
rate = csvr.rates["LANDLINE_OFFPEAK"].RateSlots[1]
|
||||
if !reflect.DeepEqual(rate, &utils.RateSlot{
|
||||
ConnectFee: 0,
|
||||
Price: 1,
|
||||
Rate: 1,
|
||||
RateUnit: time.Second,
|
||||
RateIncrement: time.Second,
|
||||
GroupIntervalStart: 60 * time.Second,
|
||||
@@ -338,96 +331,107 @@ func TestLoadDestinationRates(t *testing.T) {
|
||||
t.Error("Failed to load destinationrates: ", csvr.destinationRates)
|
||||
}
|
||||
drs := csvr.destinationRates["RT_STANDARD"]
|
||||
if !reflect.DeepEqual(drs, []*DestinationRate{
|
||||
&DestinationRate{
|
||||
Tag: "RT_STANDARD",
|
||||
DestinationsTag: "GERMANY",
|
||||
rates: csvr.rates["R1"],
|
||||
dr := &utils.TPDestinationRate{
|
||||
TPid: "",
|
||||
DestinationRateId: "RT_STANDARD",
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "GERMANY",
|
||||
Rate: csvr.rates["R1"],
|
||||
},
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "GERMANY_O2",
|
||||
Rate: csvr.rates["R2"],
|
||||
},
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "GERMANY_PREMIUM",
|
||||
Rate: csvr.rates["R2"],
|
||||
},
|
||||
},
|
||||
&DestinationRate{
|
||||
Tag: "RT_STANDARD",
|
||||
DestinationsTag: "GERMANY_O2",
|
||||
rates: csvr.rates["R2"],
|
||||
},
|
||||
&DestinationRate{
|
||||
Tag: "RT_STANDARD",
|
||||
DestinationsTag: "GERMANY_PREMIUM",
|
||||
rates: csvr.rates["R2"],
|
||||
},
|
||||
}) {
|
||||
t.Error("Error loading destination rate: ", drs)
|
||||
}
|
||||
if !reflect.DeepEqual(drs, dr) {
|
||||
t.Errorf("Error loading destination rate: \n%+v \n%+v", drs, dr)
|
||||
}
|
||||
drs = csvr.destinationRates["RT_DEFAULT"]
|
||||
if !reflect.DeepEqual(drs, []*DestinationRate{
|
||||
&DestinationRate{
|
||||
Tag: "RT_DEFAULT",
|
||||
DestinationsTag: "ALL",
|
||||
rates: csvr.rates["R2"],
|
||||
if !reflect.DeepEqual(drs, &utils.TPDestinationRate{
|
||||
DestinationRateId: "RT_DEFAULT",
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "ALL",
|
||||
Rate: csvr.rates["R2"],
|
||||
},
|
||||
},
|
||||
}) {
|
||||
t.Error("Error loading destination rate: ", drs)
|
||||
t.Errorf("Error loading destination rate: %+v", drs)
|
||||
}
|
||||
drs = csvr.destinationRates["RT_STD_WEEKEND"]
|
||||
if !reflect.DeepEqual(drs, []*DestinationRate{
|
||||
&DestinationRate{
|
||||
Tag: "RT_STD_WEEKEND",
|
||||
DestinationsTag: "GERMANY",
|
||||
rates: csvr.rates["R2"],
|
||||
},
|
||||
&DestinationRate{
|
||||
Tag: "RT_STD_WEEKEND",
|
||||
DestinationsTag: "GERMANY_O2",
|
||||
rates: csvr.rates["R3"],
|
||||
if !reflect.DeepEqual(drs, &utils.TPDestinationRate{
|
||||
DestinationRateId: "RT_STD_WEEKEND",
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "GERMANY",
|
||||
Rate: csvr.rates["R2"],
|
||||
},
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "GERMANY_O2",
|
||||
Rate: csvr.rates["R3"],
|
||||
},
|
||||
},
|
||||
}) {
|
||||
t.Error("Error loading destination rate: ", drs)
|
||||
}
|
||||
drs = csvr.destinationRates["P1"]
|
||||
if !reflect.DeepEqual(drs, []*DestinationRate{
|
||||
&DestinationRate{
|
||||
Tag: "P1",
|
||||
DestinationsTag: "NAT",
|
||||
rates: csvr.rates["R4"],
|
||||
if !reflect.DeepEqual(drs, &utils.TPDestinationRate{
|
||||
DestinationRateId: "P1",
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "NAT",
|
||||
Rate: csvr.rates["R4"],
|
||||
},
|
||||
},
|
||||
}) {
|
||||
t.Error("Error loading destination rate: ", drs)
|
||||
}
|
||||
drs = csvr.destinationRates["P2"]
|
||||
if !reflect.DeepEqual(drs, []*DestinationRate{
|
||||
&DestinationRate{
|
||||
Tag: "P2",
|
||||
DestinationsTag: "NAT",
|
||||
rates: csvr.rates["R5"],
|
||||
if !reflect.DeepEqual(drs, &utils.TPDestinationRate{
|
||||
DestinationRateId: "P2",
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "NAT",
|
||||
Rate: csvr.rates["R5"],
|
||||
},
|
||||
},
|
||||
}) {
|
||||
t.Error("Error loading destination rate: ", drs)
|
||||
}
|
||||
drs = csvr.destinationRates["T1"]
|
||||
if !reflect.DeepEqual(drs, []*DestinationRate{
|
||||
&DestinationRate{
|
||||
Tag: "T1",
|
||||
DestinationsTag: "NAT",
|
||||
rates: csvr.rates["LANDLINE_OFFPEAK"],
|
||||
if !reflect.DeepEqual(drs, &utils.TPDestinationRate{
|
||||
DestinationRateId: "T1",
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "NAT",
|
||||
Rate: csvr.rates["LANDLINE_OFFPEAK"],
|
||||
},
|
||||
},
|
||||
}) {
|
||||
t.Error("Error loading destination rate: ", drs)
|
||||
}
|
||||
drs = csvr.destinationRates["T2"]
|
||||
if !reflect.DeepEqual(drs, []*DestinationRate{
|
||||
&DestinationRate{
|
||||
Tag: "T2",
|
||||
DestinationsTag: "GERMANY",
|
||||
rates: csvr.rates["GBP_72"],
|
||||
},
|
||||
&DestinationRate{
|
||||
Tag: "T2",
|
||||
DestinationsTag: "GERMANY_O2",
|
||||
rates: csvr.rates["GBP_70"],
|
||||
},
|
||||
&DestinationRate{
|
||||
Tag: "T2",
|
||||
DestinationsTag: "GERMANY_PREMIUM",
|
||||
rates: csvr.rates["GBP_71"],
|
||||
if !reflect.DeepEqual(drs, &utils.TPDestinationRate{
|
||||
DestinationRateId: "T2",
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "GERMANY",
|
||||
Rate: csvr.rates["GBP_72"],
|
||||
},
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "GERMANY_O2",
|
||||
Rate: csvr.rates["GBP_70"],
|
||||
},
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "GERMANY_PREMIUM",
|
||||
Rate: csvr.rates["GBP_71"],
|
||||
},
|
||||
},
|
||||
}) {
|
||||
t.Error("Error loading destination rate: ", drs)
|
||||
@@ -443,24 +447,24 @@ func TestLoadDestinationRateTimings(t *testing.T) {
|
||||
Id: "STANDARD",
|
||||
Timings: map[string]*RITiming{
|
||||
"14ae6e41": &RITiming{
|
||||
Years: Years{},
|
||||
Months: Months{},
|
||||
MonthDays: MonthDays{},
|
||||
WeekDays: WeekDays{1, 2, 3, 4, 5},
|
||||
Years: utils.Years{},
|
||||
Months: utils.Months{},
|
||||
MonthDays: utils.MonthDays{},
|
||||
WeekDays: utils.WeekDays{1, 2, 3, 4, 5},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
"9a6f8e32": &RITiming{
|
||||
Years: Years{},
|
||||
Months: Months{},
|
||||
MonthDays: MonthDays{},
|
||||
WeekDays: WeekDays{1, 2, 3, 4, 5},
|
||||
Years: utils.Years{},
|
||||
Months: utils.Months{},
|
||||
MonthDays: utils.MonthDays{},
|
||||
WeekDays: utils.WeekDays{1, 2, 3, 4, 5},
|
||||
StartTime: "18:00:00",
|
||||
},
|
||||
"7181e535": &RITiming{
|
||||
Years: Years{},
|
||||
Months: Months{},
|
||||
MonthDays: MonthDays{},
|
||||
WeekDays: WeekDays{time.Saturday, time.Sunday},
|
||||
Years: utils.Years{},
|
||||
Months: utils.Months{},
|
||||
MonthDays: utils.MonthDays{},
|
||||
WeekDays: utils.WeekDays{time.Saturday, time.Sunday},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
},
|
||||
@@ -625,10 +629,10 @@ func TestLoadActionTimings(t *testing.T) {
|
||||
UserBalanceIds: []string{"*out:vdf:minitsboy"},
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: Years{2012},
|
||||
Months: Months{},
|
||||
MonthDays: MonthDays{},
|
||||
WeekDays: WeekDays{},
|
||||
Years: utils.Years{2012},
|
||||
Months: utils.Months{},
|
||||
MonthDays: utils.MonthDays{},
|
||||
WeekDays: utils.WeekDays{},
|
||||
StartTime: ASAP,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -34,9 +34,9 @@ type DbReader struct {
|
||||
actionsTriggers map[string][]*ActionTrigger
|
||||
accountActions []*UserBalance
|
||||
destinations []*Destination
|
||||
timings map[string]*Timing
|
||||
rates map[string][]*LoadRate
|
||||
destinationRates map[string][]*DestinationRate
|
||||
timings map[string]*utils.TPTiming
|
||||
rates map[string]*utils.TPRate
|
||||
destinationRates map[string]*utils.TPDestinationRate
|
||||
ratingPlans map[string]*RatingPlan
|
||||
ratingProfiles map[string]*RatingProfile
|
||||
}
|
||||
@@ -153,15 +153,15 @@ func (dbr *DbReader) LoadDestinationRates() (err error) {
|
||||
return err
|
||||
}
|
||||
for _, drs := range dbr.destinationRates {
|
||||
for _, dr := range drs {
|
||||
rates, exists := dbr.rates[dr.RateTag]
|
||||
for _, dr := range drs.DestinationRates {
|
||||
rate, exists := dbr.rates[dr.RateId]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("Could not find rate for tag %v", dr.RateTag))
|
||||
return errors.New(fmt.Sprintf("Could not find rate for tag %v", dr.RateId))
|
||||
}
|
||||
dr.rates = rates
|
||||
dr.Rate = rate
|
||||
destinationExists := false
|
||||
for _, d := range dbr.destinations {
|
||||
if d.Id == dr.DestinationsTag {
|
||||
if d.Id == dr.DestinationId {
|
||||
destinationExists = true
|
||||
break
|
||||
}
|
||||
@@ -183,24 +183,24 @@ func (dbr *DbReader) LoadRatingPlans() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, drt := range drts {
|
||||
t, exists := dbr.timings[drt.TimingTag]
|
||||
for _, drt := range drts.RatingPlans {
|
||||
t, exists := dbr.timings[drt.TimingId]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("Could not get timing for tag %v", drt.TimingTag))
|
||||
return errors.New(fmt.Sprintf("Could not get timing for tag %v", drt.TimingId))
|
||||
}
|
||||
drt.timing = t
|
||||
drs, exists := dbr.destinationRates[drt.DestinationRatesTag]
|
||||
drt.Timing = t
|
||||
drs, exists := dbr.destinationRates[drt.DestRatesId]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("Could not find destination rate for tag %v", drt.DestinationRatesTag))
|
||||
return errors.New(fmt.Sprintf("Could not find destination rate for tag %v", drt.DestRatesId))
|
||||
}
|
||||
|
||||
plan, exists := dbr.ratingPlans[drt.Tag]
|
||||
plan, exists := dbr.ratingPlans[drts.RatingPlanId]
|
||||
if !exists {
|
||||
plan = &RatingPlan{Id: drt.Tag}
|
||||
dbr.ratingPlans[drt.Tag] = plan
|
||||
plan = &RatingPlan{Id: drts.RatingPlanId}
|
||||
dbr.ratingPlans[drts.RatingPlanId] = plan
|
||||
}
|
||||
for _, dr := range drs {
|
||||
plan.AddRateInterval(dr.DestinationsTag, drt.GetRateInterval(dr))
|
||||
for _, dr := range drs.DestinationRates {
|
||||
plan.AddRateInterval(dr.DestinationId, GetRateInterval(drt, dr))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -212,11 +212,12 @@ func (dbr *DbReader) LoadRatingProfiles() error {
|
||||
return err
|
||||
}
|
||||
for _, rp := range rpfs {
|
||||
rpf := &RatingProfile{Id: rp.RatingProfileId}
|
||||
at, err := utils.ParseDate(rp.ActivationTime)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Cannot parse activation time from %v", rp.ActivationTime))
|
||||
}
|
||||
_, exists := dbr.ratingPlans[rp.DestRatesTimingTag]
|
||||
_, exists := dbr.ratingPlans[rp.RatingPlanId]
|
||||
if !exists {
|
||||
if dbExists, err := dbr.dataDb.ExistsData(RATING_PLAN, rp.DestRatesTimingTag); err != nil {
|
||||
return err
|
||||
@@ -224,13 +225,13 @@ func (dbr *DbReader) LoadRatingProfiles() error {
|
||||
return errors.New(fmt.Sprintf("Could not load rating plans for tag: %v", rp.DestRatesTimingTag))
|
||||
}
|
||||
}
|
||||
rp.RatingPlanActivations = append(rp.RatingPlanActivations,
|
||||
rpf.RatingPlanActivations = append(rpf.RatingPlanActivations,
|
||||
&RatingPlanActivation{
|
||||
ActivationTime: at,
|
||||
RatingPlanId: rp.DestRatesTimingTag,
|
||||
RatingPlanId: rp.RatingPlanId,
|
||||
FallbackKeys: rp.FallbackKeys,
|
||||
})
|
||||
dbr.ratingProfiles[rp.Id] = rp
|
||||
dbr.ratingProfiles[rpf.Id] = rpf
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -238,31 +239,30 @@ func (dbr *DbReader) LoadRatingProfiles() error {
|
||||
func (dbr *DbReader) LoadRatingPlanByTag(tag string) error {
|
||||
ratingPlan := &RatingPlan{}
|
||||
rps, err := dbr.storDb.GetTpRatingPlans(dbr.tpid, tag)
|
||||
if err != nil || len(rps) == 0 {
|
||||
if err != nil || len(rps.RatingPlans) == 0 {
|
||||
return fmt.Errorf("No DestRateTimings profile with id %s: %v", tag, err)
|
||||
}
|
||||
for _, rp := range rps {
|
||||
|
||||
for _, rp := range rps.RatingPlans {
|
||||
Logger.Debug(fmt.Sprintf("Rating Plan: %v", rp))
|
||||
tm, err := dbr.storDb.GetTpTimings(dbr.tpid, rp.TimingTag)
|
||||
tm, err := dbr.storDb.GetTpTimings(dbr.tpid, rp.TimingId)
|
||||
Logger.Debug(fmt.Sprintf("Timing: %v", tm))
|
||||
if err != nil || len(tm) == 0 {
|
||||
return fmt.Errorf("No Timings profile with id %s: %v", rp.TimingTag, err)
|
||||
return fmt.Errorf("No Timings profile with id %s: %v", rp.TimingId, err)
|
||||
}
|
||||
rp.timing = tm[rp.TimingTag]
|
||||
drm, err := dbr.storDb.GetTpDestinationRates(dbr.tpid, rp.DestinationRatesTag)
|
||||
rp.Timing = tm[rp.TimingId]
|
||||
drm, err := dbr.storDb.GetTpDestinationRates(dbr.tpid, rp.DestRatesId)
|
||||
if err != nil || len(drm) == 0 {
|
||||
return fmt.Errorf("No DestinationRates profile with id %s: %v", rp.DestinationRatesTag, err)
|
||||
return fmt.Errorf("No DestinationRates profile with id %s: %v", rp.DestRatesId, err)
|
||||
}
|
||||
for _, drate := range drm[rp.DestinationRatesTag] {
|
||||
for _, drate := range drm[rp.DestRatesId].DestinationRates {
|
||||
Logger.Debug(fmt.Sprintf("Destination rate: %v", drate))
|
||||
rt, err := dbr.storDb.GetTpRates(dbr.tpid, drate.RateTag)
|
||||
rt, err := dbr.storDb.GetTpRates(dbr.tpid, drate.RateId)
|
||||
if err != nil || len(rt) == 0 {
|
||||
return fmt.Errorf("No Rates profile with id %s: %v", drate.RateTag, err)
|
||||
return fmt.Errorf("No Rates profile with id %s: %v", drate.RateId, err)
|
||||
}
|
||||
Logger.Debug(fmt.Sprintf("Rate: %v", rt))
|
||||
drate.rates = rt[drate.RateTag]
|
||||
ratingPlan.AddRateInterval(drate.DestinationsTag, rp.GetRateInterval(drate))
|
||||
drate.Rate = rt[drate.RateId]
|
||||
ratingPlan.AddRateInterval(drate.DestinationId, GetRateInterval(rp, drate))
|
||||
|
||||
dms, err := dbr.storDb.GetTpDestinations(dbr.tpid, drate.DestinationsTag)
|
||||
if err != nil {
|
||||
@@ -275,7 +275,7 @@ func (dbr *DbReader) LoadRatingPlanByTag(tag string) error {
|
||||
}
|
||||
continue
|
||||
}
|
||||
Logger.Debug(fmt.Sprintf("Tag: %s Destinations: %v", drate.DestinationsTag, dms))
|
||||
Logger.Debug(fmt.Sprintf("Tag: %s Destinations: %v", drate.DestinationId, dms))
|
||||
for _, destination := range dms {
|
||||
Logger.Debug(fmt.Sprintf("Destination: %v", destination))
|
||||
dbr.dataDb.SetDestination(destination)
|
||||
@@ -287,16 +287,16 @@ func (dbr *DbReader) LoadRatingPlanByTag(tag string) error {
|
||||
|
||||
func (dbr *DbReader) LoadRatingProfileByTag(tag string) error {
|
||||
resultRatingProfile := &RatingProfile{}
|
||||
rpm, err := dbr.storDb.GetTpRatingProfiles(dbr.tpid, tag)
|
||||
if err != nil || len(rpm) == 0 {
|
||||
rpfs, err := dbr.storDb.GetTpRatingProfiles(dbr.tpid, tag)
|
||||
if err != nil || len(rpfs) == 0 {
|
||||
return fmt.Errorf("No RateProfile with id %s: %v", tag, err)
|
||||
}
|
||||
for _, ratingProfile := range rpm {
|
||||
Logger.Debug(fmt.Sprintf("Rating profile: %v", rpm))
|
||||
resultRatingProfile.Id = ratingProfile.Id // idem
|
||||
at, err := utils.ParseDate(ratingProfile.ActivationTime)
|
||||
for _, rp := range rpfs {
|
||||
Logger.Debug(fmt.Sprintf("Rating profile: %v", rpfs))
|
||||
resultRatingProfile.Id = rp.RatingProfileId
|
||||
at, err := utils.ParseDate(rp.ActivationTime)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Cannot parse activation time from %v", ratingProfile.ActivationTime)
|
||||
return fmt.Errorf("Cannot parse activation time from %v", rp.ActivationTime)
|
||||
}
|
||||
// Check if referenced RatingPlan exists
|
||||
_, exists := dbr.ratingPlans[ratingProfile.DestRatesTimingTag]
|
||||
@@ -307,7 +307,7 @@ func (dbr *DbReader) LoadRatingProfileByTag(tag string) error {
|
||||
return errors.New(fmt.Sprintf("Could not load rating plans for tag: %v", ratingProfile.DestRatesTimingTag))
|
||||
}
|
||||
}
|
||||
resultRatingProfile.RatingPlanActivations = append(resultRatingProfile.RatingPlanActivations, &RatingPlanActivation{at, ratingProfile.DestRatesTimingTag, ratingProfile.FallbackKeys})
|
||||
resultRatingProfile.RatingPlanActivations = append(resultRatingProfile.RatingPlanActivations, &RatingPlanActivation{at, rp.RatingPlanId, rp.FallbackKeys})
|
||||
}
|
||||
return dbr.dataDb.SetRatingProfile(resultRatingProfile)
|
||||
}
|
||||
@@ -323,18 +323,18 @@ func (dbr *DbReader) LoadActionTimings() (err error) {
|
||||
return err
|
||||
}
|
||||
for tag, ats := range atsMap {
|
||||
for _, at := range ats {
|
||||
for _, at := range ats.ActionTimings {
|
||||
_, exists := dbr.actions[at.ActionsId]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("ActionTiming: Could not load the action for tag: %v", at.ActionsId))
|
||||
}
|
||||
t, exists := dbr.timings[at.Tag]
|
||||
t, exists := dbr.timings[ats.ActionTimingsId]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("ActionTiming: Could not load the timing for tag: %v", at.Tag))
|
||||
return errors.New(fmt.Sprintf("ActionTiming: Could not load the timing for tag: %v", ats.ActionTimingsId))
|
||||
}
|
||||
actTmg := &ActionTiming{
|
||||
Id: utils.GenUUID(),
|
||||
Tag: at.Tag,
|
||||
Tag: ats.ActionTimingsId,
|
||||
Weight: at.Weight,
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
@@ -419,23 +419,24 @@ func (dbr *DbReader) LoadAccountActionsByTag(tag string) error {
|
||||
return fmt.Errorf("No ActionTimings with id <%s>", accountAction.ActionTimingsTag)
|
||||
}
|
||||
var actionTimings []*ActionTiming
|
||||
for _, at := range actionTimingsMap[accountAction.ActionTimingsTag] {
|
||||
ats := actionTimingsMap[accountAction.ActionTimingsTag]
|
||||
for _, at := range ats.ActionTimings {
|
||||
existsAction, err := dbr.storDb.ExistsTPActions(dbr.tpid, at.ActionsId)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !existsAction {
|
||||
return fmt.Errorf("No Action with id <%s>", at.ActionsId)
|
||||
}
|
||||
timingsMap, err := dbr.storDb.GetTpTimings(dbr.tpid, at.Tag)
|
||||
timingsMap, err := dbr.storDb.GetTpTimings(dbr.tpid, ats.ActionTimingsId)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(timingsMap) == 0 {
|
||||
return fmt.Errorf("No Timing with id <%s>", at.Tag)
|
||||
return fmt.Errorf("No Timing with id <%s>", ats.ActionTimingsId)
|
||||
}
|
||||
t := timingsMap[at.Tag]
|
||||
t := timingsMap[ats.ActionTimingsId]
|
||||
actTmg := &ActionTiming{
|
||||
Id: utils.GenUUID(),
|
||||
Tag: at.Tag,
|
||||
Tag: ats.ActionTimingsId,
|
||||
Weight: at.Weight,
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
@@ -458,7 +459,7 @@ func (dbr *DbReader) LoadAccountActionsByTag(tag string) error {
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
at.UserBalanceIds = append(exitingUserBalanceIds, id)
|
||||
actTmg.UserBalanceIds = append(exitingUserBalanceIds, id)
|
||||
}
|
||||
actionTimings = append(actionTimings, actTmg)
|
||||
}
|
||||
|
||||
@@ -47,15 +47,15 @@ type TPLoader interface {
|
||||
WriteToDatabase(bool, bool) error
|
||||
}
|
||||
|
||||
type LoadRate struct {
|
||||
/*type LoadRate struct {
|
||||
Tag string
|
||||
ConnectFee, Price float64
|
||||
RateUnit, RateIncrement, GroupIntervalStart time.Duration
|
||||
RoundingMethod string
|
||||
RoundingDecimals int
|
||||
}
|
||||
}*/
|
||||
|
||||
func NewLoadRate(tag, connectFee, price, ratedUnits, rateIncrements, groupInterval, roundingMethod, roundingDecimals string) (r *LoadRate, err error) {
|
||||
func NewLoadRate(tag, connectFee, price, ratedUnits, rateIncrements, groupInterval, roundingMethod, roundingDecimals string) (r *utils.TPRate, err error) {
|
||||
cf, err := strconv.ParseFloat(connectFee, 64)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing connect fee from: %v", connectFee)
|
||||
@@ -87,20 +87,24 @@ func NewLoadRate(tag, connectFee, price, ratedUnits, rateIncrements, groupInterv
|
||||
return
|
||||
}
|
||||
|
||||
r = &LoadRate{
|
||||
Tag: tag,
|
||||
ConnectFee: cf,
|
||||
Price: p,
|
||||
GroupIntervalStart: gi,
|
||||
RateUnit: ru,
|
||||
RateIncrement: ri,
|
||||
RoundingMethod: roundingMethod,
|
||||
RoundingDecimals: rd,
|
||||
r = &utils.TPRate{
|
||||
RateId: tag,
|
||||
RateSlots: []*utils.RateSlot{
|
||||
&utils.RateSlot{
|
||||
ConnectFee: cf,
|
||||
Rate: p,
|
||||
GroupIntervalStart: gi,
|
||||
RateUnit: ru,
|
||||
RateIncrement: ri,
|
||||
RoundingMethod: roundingMethod,
|
||||
RoundingDecimals: rd,
|
||||
},
|
||||
},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (present *LoadRate) ValidNextGroup(next *LoadRate) error {
|
||||
func ValidNextGroup(present, next *utils.RateSlot) error {
|
||||
if next.GroupIntervalStart <= present.GroupIntervalStart {
|
||||
return errors.New(fmt.Sprintf("Next rate group interval start must be heigher than the last one: %#v", next))
|
||||
}
|
||||
@@ -113,24 +117,8 @@ func (present *LoadRate) ValidNextGroup(next *LoadRate) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type DestinationRate struct {
|
||||
Tag string
|
||||
DestinationsTag string
|
||||
RateTag string // intermediary used when loading from db
|
||||
rates []*LoadRate
|
||||
}
|
||||
|
||||
type Timing struct {
|
||||
Id string
|
||||
Years Years
|
||||
Months Months
|
||||
MonthDays MonthDays
|
||||
WeekDays WeekDays
|
||||
StartTime string
|
||||
}
|
||||
|
||||
func NewTiming(timingInfo ...string) (rt *Timing) {
|
||||
rt = &Timing{}
|
||||
func NewTiming(timingInfo ...string) (rt *utils.TPTiming) {
|
||||
rt = &utils.TPTiming{}
|
||||
rt.Id = timingInfo[0]
|
||||
rt.Years.Parse(timingInfo[1], ";")
|
||||
rt.Months.Parse(timingInfo[2], ";")
|
||||
@@ -140,47 +128,39 @@ func NewTiming(timingInfo ...string) (rt *Timing) {
|
||||
return
|
||||
}
|
||||
|
||||
type DestinationRateTiming struct {
|
||||
Tag string
|
||||
DestinationRatesTag string // intermediary used when loading from db
|
||||
Weight float64
|
||||
TimingTag string // intermediary used when loading from db
|
||||
timing *Timing
|
||||
}
|
||||
|
||||
func NewDestinationRateTiming(timing *Timing, weight string) (drt *DestinationRateTiming) {
|
||||
func NewRatingPlan(timing *utils.TPTiming, weight string) (drt *utils.RatingPlan) {
|
||||
w, err := strconv.ParseFloat(weight, 64)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing weight unit from: %v", weight)
|
||||
return
|
||||
}
|
||||
drt = &DestinationRateTiming{
|
||||
timing: timing,
|
||||
drt = &utils.RatingPlan{
|
||||
Timing: timing,
|
||||
Weight: w,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (drt *DestinationRateTiming) GetRateInterval(dr *DestinationRate) (i *RateInterval) {
|
||||
func GetRateInterval(rpl *utils.RatingPlan, dr *utils.DestinationRate) (i *RateInterval) {
|
||||
i = &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: drt.timing.Years,
|
||||
Months: drt.timing.Months,
|
||||
MonthDays: drt.timing.MonthDays,
|
||||
WeekDays: drt.timing.WeekDays,
|
||||
StartTime: drt.timing.StartTime,
|
||||
Years: rpl.Timing.Years,
|
||||
Months: rpl.Timing.Months,
|
||||
MonthDays: rpl.Timing.MonthDays,
|
||||
WeekDays: rpl.Timing.WeekDays,
|
||||
StartTime: rpl.Timing.StartTime,
|
||||
},
|
||||
Weight: drt.Weight,
|
||||
Weight: rpl.Weight,
|
||||
Rating: &RIRate{
|
||||
ConnectFee: dr.rates[0].ConnectFee,
|
||||
RoundingMethod: dr.rates[0].RoundingMethod,
|
||||
RoundingDecimals: dr.rates[0].RoundingDecimals,
|
||||
ConnectFee: dr.Rate.RateSlots[0].ConnectFee,
|
||||
RoundingMethod: dr.Rate.RateSlots[0].RoundingMethod,
|
||||
RoundingDecimals: dr.Rate.RateSlots[0].RoundingDecimals,
|
||||
},
|
||||
}
|
||||
for _, rl := range dr.rates {
|
||||
for _, rl := range dr.Rate.RateSlots {
|
||||
i.Rating.Rates = append(i.Rating.Rates, &Rate{
|
||||
GroupIntervalStart: rl.GroupIntervalStart,
|
||||
Value: rl.Price,
|
||||
Value: rl.Rate,
|
||||
RateIncrement: rl.RateIncrement,
|
||||
RateUnit: rl.RateUnit,
|
||||
})
|
||||
|
||||
@@ -39,10 +39,10 @@ type RateInterval struct {
|
||||
|
||||
// Separate structure used for rating plan size optimization
|
||||
type RITiming struct {
|
||||
Years Years
|
||||
Months Months
|
||||
MonthDays MonthDays
|
||||
WeekDays WeekDays
|
||||
Years utils.Years
|
||||
Months utils.Months
|
||||
MonthDays utils.MonthDays
|
||||
WeekDays utils.WeekDays
|
||||
StartTime, EndTime string // ##:##:## format
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
func TestRateIntervalSimpleContains(t *testing.T) {
|
||||
i := &RateInterval{
|
||||
Timing: &RITiming{
|
||||
WeekDays: WeekDays{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
|
||||
WeekDays: utils.WeekDays{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
|
||||
StartTime: "18:00:00",
|
||||
EndTime: "",
|
||||
},
|
||||
@@ -39,7 +39,7 @@ func TestRateIntervalSimpleContains(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRateIntervalMonth(t *testing.T) {
|
||||
i := &RateInterval{Timing: &RITiming{Months: Months{time.February}}}
|
||||
i := &RateInterval{Timing: &RITiming{Months: utils.Months{time.February}}}
|
||||
d := time.Date(2012, time.February, 10, 23, 0, 0, 0, time.UTC)
|
||||
d1 := time.Date(2012, time.January, 10, 23, 0, 0, 0, time.UTC)
|
||||
if !i.Contains(d, false) {
|
||||
@@ -51,7 +51,7 @@ func TestRateIntervalMonth(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRateIntervalMonthDay(t *testing.T) {
|
||||
i := &RateInterval{Timing: &RITiming{MonthDays: MonthDays{10}}}
|
||||
i := &RateInterval{Timing: &RITiming{MonthDays: utils.MonthDays{10}}}
|
||||
d := time.Date(2012, time.February, 10, 23, 0, 0, 0, time.UTC)
|
||||
d1 := time.Date(2012, time.February, 11, 23, 0, 0, 0, time.UTC)
|
||||
if !i.Contains(d, false) {
|
||||
@@ -63,7 +63,7 @@ func TestRateIntervalMonthDay(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRateIntervalMonthAndMonthDay(t *testing.T) {
|
||||
i := &RateInterval{Timing: &RITiming{Months: Months{time.February}, MonthDays: MonthDays{10}}}
|
||||
i := &RateInterval{Timing: &RITiming{Months: utils.Months{time.February}, MonthDays: utils.MonthDays{10}}}
|
||||
d := time.Date(2012, time.February, 10, 23, 0, 0, 0, time.UTC)
|
||||
d1 := time.Date(2012, time.February, 11, 23, 0, 0, 0, time.UTC)
|
||||
d2 := time.Date(2012, time.January, 10, 23, 0, 0, 0, time.UTC)
|
||||
@@ -98,8 +98,8 @@ func TestRateIntervalWeekDays(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRateIntervalMonthAndMonthDayAndWeekDays(t *testing.T) {
|
||||
i := &RateInterval{Timing: &RITiming{Months: Months{time.February}, MonthDays: MonthDays{1}, WeekDays: []time.Weekday{time.Wednesday}}}
|
||||
i2 := &RateInterval{Timing: &RITiming{Months: Months{time.February}, MonthDays: MonthDays{2}, WeekDays: []time.Weekday{time.Wednesday, time.Thursday}}}
|
||||
i := &RateInterval{Timing: &RITiming{Months: utils.Months{time.February}, MonthDays: utils.MonthDays{1}, WeekDays: []time.Weekday{time.Wednesday}}}
|
||||
i2 := &RateInterval{Timing: &RITiming{Months: utils.Months{time.February}, MonthDays: utils.MonthDays{2}, WeekDays: []time.Weekday{time.Wednesday, time.Thursday}}}
|
||||
d := time.Date(2012, time.February, 1, 23, 0, 0, 0, time.UTC)
|
||||
d1 := time.Date(2012, time.February, 2, 23, 0, 0, 0, time.UTC)
|
||||
if !i.Contains(d, false) {
|
||||
@@ -139,9 +139,9 @@ func TestRateIntervalHours(t *testing.T) {
|
||||
func TestRateIntervalEverything(t *testing.T) {
|
||||
i := &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Months: Months{time.February},
|
||||
Years: Years{2012},
|
||||
MonthDays: MonthDays{1},
|
||||
Months: utils.Months{time.February},
|
||||
Years: utils.Years{2012},
|
||||
MonthDays: utils.MonthDays{1},
|
||||
WeekDays: []time.Weekday{time.Wednesday, time.Thursday},
|
||||
StartTime: "14:30:00",
|
||||
EndTime: "15:00:00"}}
|
||||
@@ -170,14 +170,14 @@ func TestRateIntervalEverything(t *testing.T) {
|
||||
func TestRateIntervalEqual(t *testing.T) {
|
||||
i1 := &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Months: Months{time.February},
|
||||
MonthDays: MonthDays{1},
|
||||
Months: utils.Months{time.February},
|
||||
MonthDays: utils.MonthDays{1},
|
||||
WeekDays: []time.Weekday{time.Wednesday, time.Thursday},
|
||||
StartTime: "14:30:00",
|
||||
EndTime: "15:00:00"}}
|
||||
i2 := &RateInterval{Timing: &RITiming{
|
||||
Months: Months{time.February},
|
||||
MonthDays: MonthDays{1},
|
||||
Months: utils.Months{time.February},
|
||||
MonthDays: utils.MonthDays{1},
|
||||
WeekDays: []time.Weekday{time.Wednesday, time.Thursday},
|
||||
StartTime: "14:30:00",
|
||||
EndTime: "15:00:00"}}
|
||||
@@ -189,14 +189,14 @@ func TestRateIntervalEqual(t *testing.T) {
|
||||
func TestRateIntervalNotEqual(t *testing.T) {
|
||||
i1 := &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Months: Months{time.February},
|
||||
MonthDays: MonthDays{1},
|
||||
Months: utils.Months{time.February},
|
||||
MonthDays: utils.MonthDays{1},
|
||||
WeekDays: []time.Weekday{time.Wednesday},
|
||||
StartTime: "14:30:00",
|
||||
EndTime: "15:00:00"}}
|
||||
i2 := &RateInterval{Timing: &RITiming{
|
||||
Months: Months{time.February},
|
||||
MonthDays: MonthDays{1},
|
||||
Months: utils.Months{time.February},
|
||||
MonthDays: utils.MonthDays{1},
|
||||
WeekDays: []time.Weekday{time.Wednesday, time.Thursday},
|
||||
StartTime: "14:30:00",
|
||||
EndTime: "15:00:00"}}
|
||||
@@ -207,15 +207,15 @@ func TestRateIntervalNotEqual(t *testing.T) {
|
||||
|
||||
func TestRitStrigyfy(t *testing.T) {
|
||||
rit1 := &RITiming{
|
||||
Years: Years{},
|
||||
Months: Months{time.January, time.February},
|
||||
MonthDays: MonthDays{},
|
||||
Years: utils.Years{},
|
||||
Months: utils.Months{time.January, time.February},
|
||||
MonthDays: utils.MonthDays{},
|
||||
StartTime: "00:00:00",
|
||||
}
|
||||
rit2 := &RITiming{
|
||||
Years: Years{},
|
||||
Months: Months{time.January, time.February},
|
||||
MonthDays: MonthDays{},
|
||||
Years: utils.Years{},
|
||||
Months: utils.Months{time.January, time.February},
|
||||
MonthDays: utils.MonthDays{},
|
||||
StartTime: "00:00:00",
|
||||
}
|
||||
if rit1.Stringify() != rit2.Stringify() {
|
||||
@@ -286,7 +286,7 @@ func TestRateStrigyfy(t *testing.T) {
|
||||
/*********************************Benchmarks**************************************/
|
||||
|
||||
func BenchmarkRateIntervalContainsDate(b *testing.B) {
|
||||
i := &RateInterval{Timing: &RITiming{Months: Months{time.February}, MonthDays: MonthDays{1}, WeekDays: []time.Weekday{time.Wednesday, time.Thursday}, StartTime: "14:30:00", EndTime: "15:00:00"}}
|
||||
i := &RateInterval{Timing: &RITiming{Months: utils.Months{time.February}, MonthDays: utils.MonthDays{1}, WeekDays: []time.Weekday{time.Wednesday, time.Thursday}, StartTime: "14:30:00", EndTime: "15:00:00"}}
|
||||
d := time.Date(2012, time.February, 1, 14, 30, 0, 0, time.UTC)
|
||||
for x := 0; x < b.N; x++ {
|
||||
i.Contains(d, false)
|
||||
|
||||
@@ -20,6 +20,7 @@ package engine
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -148,20 +149,20 @@ func TestFallbackNoInfiniteLoopSelf(t *testing.T) {
|
||||
func TestApAddIntervalIfNotPresent(t *testing.T) {
|
||||
i1 := &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Months: Months{time.February},
|
||||
MonthDays: MonthDays{1},
|
||||
Months: utils.Months{time.February},
|
||||
MonthDays: utils.MonthDays{1},
|
||||
WeekDays: []time.Weekday{time.Wednesday, time.Thursday},
|
||||
StartTime: "14:30:00",
|
||||
EndTime: "15:00:00"}}
|
||||
i2 := &RateInterval{Timing: &RITiming{
|
||||
Months: Months{time.February},
|
||||
MonthDays: MonthDays{1},
|
||||
Months: utils.Months{time.February},
|
||||
MonthDays: utils.MonthDays{1},
|
||||
WeekDays: []time.Weekday{time.Wednesday, time.Thursday},
|
||||
StartTime: "14:30:00",
|
||||
EndTime: "15:00:00"}}
|
||||
i3 := &RateInterval{Timing: &RITiming{
|
||||
Months: Months{time.February},
|
||||
MonthDays: MonthDays{1},
|
||||
Months: utils.Months{time.February},
|
||||
MonthDays: utils.MonthDays{1},
|
||||
WeekDays: []time.Weekday{time.Wednesday},
|
||||
StartTime: "14:30:00",
|
||||
EndTime: "15:00:00"}}
|
||||
|
||||
@@ -26,11 +26,8 @@ import (
|
||||
)
|
||||
|
||||
type RatingProfile struct {
|
||||
Id string
|
||||
RatingPlanActivations RatingPlanActivations
|
||||
Tag, Tenant, TOR, Direction, Subject string // used only for loading
|
||||
DestRatesTimingTag, RatesFallbackSubject, ActivationTime string // used only for loading
|
||||
FallbackKeys []string // used only for loading
|
||||
Id string
|
||||
RatingPlanActivations RatingPlanActivations
|
||||
}
|
||||
|
||||
type RatingPlanActivation struct {
|
||||
@@ -82,6 +79,7 @@ type RatingInfo struct {
|
||||
MatchedPrefix string
|
||||
ActivationTime time.Time
|
||||
RateIntervals RateIntervalList
|
||||
FallbackKeys []string
|
||||
}
|
||||
|
||||
type RatingInfos []*RatingInfo
|
||||
@@ -127,11 +125,11 @@ func (rp *RatingProfile) GetRatingPlansForPrefix(cd *CallDescriptor) (err error)
|
||||
}
|
||||
}
|
||||
if bestPrecision > 0 {
|
||||
ris = append(ris, &RatingInfo{rp.Id, cd.Destination[:bestPrecision], rpa.ActivationTime, rps})
|
||||
ris = append(ris, &RatingInfo{rp.Id, cd.Destination[:bestPrecision], rpa.ActivationTime, rps, rpa.FallbackKeys})
|
||||
} else {
|
||||
// mark the end of previous!
|
||||
if len(cd.RatingInfos) > 0 {
|
||||
ris = append(ris, &RatingInfo{"", "", rpa.ActivationTime, nil})
|
||||
ris = append(ris, &RatingInfo{"", "", rpa.ActivationTime, nil, rpa.FallbackKeys})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,28 +104,28 @@ type LoadStorage interface {
|
||||
Storage
|
||||
// Apier functions
|
||||
GetTPIds() ([]string, error)
|
||||
SetTPTiming(string, *Timing) error
|
||||
SetTPTiming(string, *utils.TPTiming) error
|
||||
ExistsTPTiming(string, string) (bool, error)
|
||||
GetTPTiming(string, string) (*Timing, error)
|
||||
GetTPTiming(string, string) (*utils.TPTiming, error)
|
||||
GetTPTimingIds(string) ([]string, error)
|
||||
SetTPDestination(string, *Destination) error
|
||||
ExistsTPDestination(string, string) (bool, error)
|
||||
GetTPDestination(string, string) (*Destination, error)
|
||||
GetTPDestinationIds(string) ([]string, error)
|
||||
ExistsTPRate(string, string) (bool, error)
|
||||
SetTPRates(string, map[string][]*LoadRate) error
|
||||
SetTPRates(string, map[string]*utils.TPRate) error
|
||||
GetTPRate(string, string) (*utils.TPRate, error)
|
||||
GetTPRateIds(string) ([]string, error)
|
||||
ExistsTPDestinationRate(string, string) (bool, error)
|
||||
SetTPDestinationRates(string, map[string][]*DestinationRate) error
|
||||
SetTPDestinationRates(string, map[string]*utils.TPDestinationRate) error
|
||||
GetTPDestinationRate(string, string) (*utils.TPDestinationRate, error)
|
||||
GetTPDestinationRateIds(string) ([]string, error)
|
||||
ExistsTPRatingPlan(string, string) (bool, error)
|
||||
SetTPRatingPlans(string, map[string][]*DestinationRateTiming) error
|
||||
SetTPRatingPlans(string, map[string]*utils.TPRatingPlan) error
|
||||
GetTPRatingPlan(string, string) (*utils.TPRatingPlan, error)
|
||||
GetTPRatingPlanIds(string) ([]string, error)
|
||||
ExistsTPRatingProfile(string, string) (bool, error)
|
||||
SetTPRatingProfiles(string, map[string][]*RatingProfile) error
|
||||
SetTPRatingProfiles(string, map[string][]*utils.TPRatingProfile) error
|
||||
GetTPRatingProfile(string, string) (*utils.TPRatingProfile, error)
|
||||
GetTPRatingProfileIds(*utils.AttrTPRatingProfileIds) ([]string, error)
|
||||
ExistsTPActions(string, string) (bool, error)
|
||||
@@ -133,8 +133,8 @@ type LoadStorage interface {
|
||||
GetTPActions(string, string) (*utils.TPActions, error)
|
||||
GetTPActionIds(string) ([]string, error)
|
||||
ExistsTPActionTimings(string, string) (bool, error)
|
||||
SetTPActionTimings(string, map[string][]*ActionTiming) error
|
||||
GetTPActionTimings(string, string) (map[string][]*utils.TPActionTimingsRow, error)
|
||||
SetTPActionTimings(string, map[string]*utils.ApiTPActionTimings) error
|
||||
GetTPActionTimings(string, string) (map[string]*utils.ApiTPActionTimings, error)
|
||||
GetTPActionTimingIds(string) ([]string, error)
|
||||
ExistsTPActionTriggers(string, string) (bool, error)
|
||||
SetTPActionTriggers(string, map[string][]*ActionTrigger) error
|
||||
@@ -144,13 +144,13 @@ type LoadStorage interface {
|
||||
GetTPAccountActionIds(string) ([]string, error)
|
||||
// loader functions
|
||||
GetTpDestinations(string, string) ([]*Destination, error)
|
||||
GetTpTimings(string, string) (map[string]*Timing, error)
|
||||
GetTpRates(string, string) (map[string][]*LoadRate, error)
|
||||
GetTpDestinationRates(string, string) (map[string][]*DestinationRate, error)
|
||||
GetTpRatingPlans(string, string) ([]*DestinationRateTiming, error)
|
||||
GetTpRatingProfiles(string, string) (map[string]*RatingProfile, error)
|
||||
GetTpTimings(string, string) (map[string]*utils.TPTiming, error)
|
||||
GetTpRates(string, string) (map[string]*utils.TPRate, error)
|
||||
GetTpDestinationRates(string, string) (map[string]*utils.TPDestinationRate, error)
|
||||
GetTpRatingPlans(string, string) (*utils.TPRatingPlan, error)
|
||||
GetTpRatingProfiles(string, string) (map[string]*utils.TPRatingProfile, error)
|
||||
GetTpActions(string, string) (map[string][]*Action, error)
|
||||
GetTpActionTimings(string, string) (map[string][]*ActionTiming, error)
|
||||
GetTpActionTimings(string, string) (map[string]utils.ApiTPActionTimings, error)
|
||||
GetTpActionTriggers(string, string) (map[string][]*ActionTrigger, error)
|
||||
GetTpAccountActions(string, string) (map[string]*AccountAction, error)
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ func (self *SQLStorage) GetTPIds() ([]string, error) {
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) SetTPTiming(tpid string, tm *Timing) error {
|
||||
func (self *SQLStorage) SetTPTiming(tpid string, tm *utils.TPTiming) error {
|
||||
if _, err := self.Db.Exec(fmt.Sprintf("INSERT INTO %s (tpid, tag, years, months, month_days, week_days, time) VALUES('%s','%s','%s','%s','%s','%s','%s')",
|
||||
utils.TBL_TP_TIMINGS, tpid, tm.Id, tm.Years.Serialize(";"), tm.Months.Serialize(";"), tm.MonthDays.Serialize(";"),
|
||||
tm.WeekDays.Serialize(";"), tm.StartTime)); err != nil {
|
||||
@@ -82,7 +82,7 @@ func (self *SQLStorage) ExistsTPTiming(tpid, tmId string) (bool, error) {
|
||||
return exists, nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) GetTPTiming(tpid, tmId string) (*Timing, error) {
|
||||
func (self *SQLStorage) GetTPTiming(tpid, tmId string) (*utils.TPTiming, error) {
|
||||
var years, months, monthDays, weekDays, time string
|
||||
err := self.Db.QueryRow(fmt.Sprintf("SELECT years, months, month_days, week_days, time FROM %s WHERE tpid='%s' AND tag='%s' LIMIT 1",
|
||||
utils.TBL_TP_TIMINGS, tpid, tmId)).Scan(&years, &months, &monthDays, &weekDays, &time)
|
||||
@@ -193,19 +193,19 @@ func (self *SQLStorage) ExistsTPRate(tpid, rtId string) (bool, error) {
|
||||
return exists, nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) SetTPRates(tpid string, rts map[string][]*LoadRate) error {
|
||||
func (self *SQLStorage) SetTPRates(tpid string, rts map[string]*utils.TPRate) error {
|
||||
if len(rts) == 0 {
|
||||
return nil //Nothing to set
|
||||
}
|
||||
qry := fmt.Sprintf("INSERT INTO %s (tpid, tag, connect_fee, rate, rate_unit, rate_increment, group_interval_start, rounding_method, rounding_decimals) VALUES ", utils.TBL_TP_RATES)
|
||||
i := 0
|
||||
for rtId, rtRows := range rts {
|
||||
for _, rt := range rtRows {
|
||||
for _, rt := range rtRows.RateSlots {
|
||||
if i != 0 { //Consecutive values after the first will be prefixed with "," as separator
|
||||
qry += ","
|
||||
}
|
||||
qry += fmt.Sprintf("('%s', '%s', %f, %f, %d, %d,%d,'%s', %d)",
|
||||
tpid, rtId, rt.ConnectFee, rt.Price, rt.RateUnit, rt.RateIncrement, rt.GroupIntervalStart,
|
||||
tpid, rtId, rt.ConnectFee, rt.Rate, rt.RateUnit, rt.RateIncrement, rt.GroupIntervalStart,
|
||||
rt.RoundingMethod, rt.RoundingDecimals)
|
||||
i++
|
||||
}
|
||||
@@ -234,8 +234,7 @@ func (self *SQLStorage) GetTPRate(tpid, rtId string) (*utils.TPRate, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rt.RateSlots = append(rt.RateSlots, utils.RateSlot{connectFee, rate, rateUnit.String(), rateIncrement.String(),
|
||||
groupIntervalStart.String(), roundingMethod, roundingDecimals})
|
||||
rt.RateSlots = append(rt.RateSlots, &utils.RateSlot{connectFee, rate, rateUnit, rateIncrement, groupIntervalStart, roundingMethod, roundingDecimals})
|
||||
}
|
||||
if i == 0 {
|
||||
return nil, nil
|
||||
@@ -275,19 +274,19 @@ func (self *SQLStorage) ExistsTPDestinationRate(tpid, drId string) (bool, error)
|
||||
return exists, nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) SetTPDestinationRates(tpid string, drs map[string][]*DestinationRate) error {
|
||||
func (self *SQLStorage) SetTPDestinationRates(tpid string, drs map[string]*utils.TPDestinationRate) error {
|
||||
if len(drs) == 0 {
|
||||
return nil //Nothing to set
|
||||
}
|
||||
qry := fmt.Sprintf("INSERT INTO %s (tpid, tag, destinations_tag, rates_tag) VALUES ", utils.TBL_TP_DESTINATION_RATES)
|
||||
i := 0
|
||||
for drId, drRows := range drs {
|
||||
for _, dr := range drRows {
|
||||
for _, dr := range drRows.DestinationRates {
|
||||
if i != 0 { //Consecutive values after the first will be prefixed with "," as separator
|
||||
qry += ","
|
||||
}
|
||||
qry += fmt.Sprintf("('%s','%s','%s','%s')",
|
||||
tpid, drId, dr.DestinationsTag, dr.RateTag)
|
||||
tpid, drId, dr.DestinationId, dr.RateId)
|
||||
i++
|
||||
}
|
||||
}
|
||||
@@ -312,7 +311,7 @@ func (self *SQLStorage) GetTPDestinationRate(tpid, drId string) (*utils.TPDestin
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dr.DestinationRates = append(dr.DestinationRates, utils.DestinationRate{dstTag, ratesTag})
|
||||
dr.DestinationRates = append(dr.DestinationRates, &utils.DestinationRate{dstTag, ratesTag, nil})
|
||||
}
|
||||
if i == 0 {
|
||||
return nil, nil
|
||||
@@ -352,19 +351,19 @@ func (self *SQLStorage) ExistsTPRatingPlan(tpid, drtId string) (bool, error) {
|
||||
return exists, nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) SetTPRatingPlans(tpid string, drts map[string][]*DestinationRateTiming) error {
|
||||
func (self *SQLStorage) SetTPRatingPlans(tpid string, drts map[string]*utils.TPRatingPlan) error {
|
||||
if len(drts) == 0 {
|
||||
return nil //Nothing to set
|
||||
}
|
||||
qry := fmt.Sprintf("INSERT INTO %s (tpid, tag, destrates_tag, timing_tag, weight) VALUES ", utils.TBL_TP_RATING_PLANS)
|
||||
i := 0
|
||||
for drtId, drtRows := range drts {
|
||||
for _, drt := range drtRows {
|
||||
for _, drt := range drtRows.RatingPlans {
|
||||
if i != 0 { //Consecutive values after the first will be prefixed with "," as separator
|
||||
qry += ","
|
||||
}
|
||||
qry += fmt.Sprintf("('%s','%s','%s','%s',%f)",
|
||||
tpid, drtId, drt.DestinationRatesTag, drt.TimingTag, drt.Weight)
|
||||
tpid, drtId, drt.DestRatesId, drt.TimingId, drt.Weight)
|
||||
i++
|
||||
}
|
||||
}
|
||||
@@ -390,7 +389,7 @@ func (self *SQLStorage) GetTPRatingPlan(tpid, drtId string) (*utils.TPRatingPlan
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
drt.RatingPlans = append(drt.RatingPlans, utils.RatingPlan{drTag, timingTag, weight})
|
||||
drt.RatingPlans = append(drt.RatingPlans, &utils.RatingPlan{drTag, timingTag, weight, nil})
|
||||
}
|
||||
if i == 0 {
|
||||
return nil, nil
|
||||
@@ -430,7 +429,7 @@ func (self *SQLStorage) ExistsTPRatingProfile(tpid, rpId string) (bool, error) {
|
||||
return exists, nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) SetTPRatingProfiles(tpid string, rps map[string][]*RatingProfile) error {
|
||||
func (self *SQLStorage) SetTPRatingProfiles(tpid string, rps map[string][]*utils.TPRatingProfile) error {
|
||||
if len(rps) == 0 {
|
||||
return nil //Nothing to set
|
||||
}
|
||||
@@ -443,7 +442,7 @@ func (self *SQLStorage) SetTPRatingProfiles(tpid string, rps map[string][]*Ratin
|
||||
qry += ","
|
||||
}
|
||||
qry += fmt.Sprintf("('%s', '%s', '%s', '%s', '%s', '%s', '%s','%s','%s')", tpid, rpId, rpa.Tenant, rpa.TOR, rpa.Direction,
|
||||
rpa.Subject, rpa.ActivationTime, rpa.DestRatesTimingTag, rpa.RatesFallbackSubject)
|
||||
rpa.Subject, rpa.ActivationTime, rpa.RatingPlanId, rpa.FallbackKeys)
|
||||
i++
|
||||
}
|
||||
|
||||
@@ -474,9 +473,9 @@ func (self *SQLStorage) GetTPRatingProfile(tpid, rpId string) (*utils.TPRatingPr
|
||||
rp.TOR = tor
|
||||
rp.Direction = direction
|
||||
rp.Subject = subject
|
||||
rp.RatesFallbackSubject = fallbackSubj
|
||||
rp.FallbackKeys = strings.Split(fallbackSubj, FALLBACK_SEP)
|
||||
}
|
||||
rp.RatingActivations = append(rp.RatingActivations, utils.RatingActivation{aTime, drtId})
|
||||
rp.RatingPlanActivations = append(rp.RatingPlanActivations, &utils.RatingActivation{aTime, drtId})
|
||||
}
|
||||
if i == 0 {
|
||||
return nil, nil
|
||||
@@ -567,7 +566,7 @@ func (self *SQLStorage) GetTPActions(tpid, actsId string) (*utils.TPActions, err
|
||||
if err = rows.Scan(&action, &balanceId, &dir, &units, &expTime, &destId, &rateSubject, &balanceWeight, &extraParameters, &weight); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
acts.Actions = append(acts.Actions, utils.Action{action, balanceId, dir, units, expTime, destId, rateSubject, balanceWeight, extraParameters, weight})
|
||||
acts.Actions = append(acts.Actions, &utils.Action{action, balanceId, dir, units, expTime, destId, rateSubject, balanceWeight, extraParameters, weight})
|
||||
}
|
||||
if i == 0 {
|
||||
return nil, nil
|
||||
@@ -607,19 +606,19 @@ func (self *SQLStorage) ExistsTPActionTimings(tpid, atId string) (bool, error) {
|
||||
}
|
||||
|
||||
// Sets actionTimings in sqlDB. Imput is expected in form map[actionTimingId][]rows, eg a full .csv file content
|
||||
func (self *SQLStorage) SetTPActionTimings(tpid string, ats map[string][]*ActionTiming) error {
|
||||
func (self *SQLStorage) SetTPActionTimings(tpid string, ats map[string]utils.ApiTPActionTimings) error {
|
||||
if len(ats) == 0 {
|
||||
return nil //Nothing to set
|
||||
}
|
||||
qry := fmt.Sprintf("INSERT INTO %s (tpid,tag,actions_tag,timing_tag,weight) VALUES ", utils.TBL_TP_ACTION_TIMINGS)
|
||||
i := 0
|
||||
for atId, atRows := range ats {
|
||||
for _, at := range atRows {
|
||||
for _, at := range atRows.ActionTimings {
|
||||
if i != 0 { //Consecutive values after the first will be prefixed with "," as separator
|
||||
qry += ","
|
||||
}
|
||||
qry += fmt.Sprintf("('%s','%s','%s','%s',%f)",
|
||||
tpid, atId, at.ActionsTag, at.TimingsTag, at.Weight)
|
||||
tpid, atId, at.ActionsId, at.TimingId, at.Weight)
|
||||
i++
|
||||
}
|
||||
}
|
||||
@@ -629,8 +628,8 @@ func (self *SQLStorage) SetTPActionTimings(tpid string, ats map[string][]*Action
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) GetTPActionTimings(tpid, atId string) (map[string][]*utils.TPActionTimingsRow, error) {
|
||||
ats := make(map[string][]*utils.TPActionTimingsRow)
|
||||
func (self *SQLStorage) GetTPActionTimings(tpid, atId string) (map[string][]*utils.ApiActionTiming, error) {
|
||||
ats := make(map[string][]*utils.ApiActionTiming)
|
||||
q := fmt.Sprintf("SELECT tag,actions_tag,timing_tag,weight FROM %s WHERE tpid='%s'", utils.TBL_TP_ACTION_TIMINGS, tpid)
|
||||
if atId != "" {
|
||||
q += fmt.Sprintf(" AND tag='%s'", atId)
|
||||
@@ -648,7 +647,7 @@ func (self *SQLStorage) GetTPActionTimings(tpid, atId string) (map[string][]*uti
|
||||
if err = rows.Scan(&tag, &actionsId, &timingId, &weight); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ats[tag] = append(ats[tag], &utils.TPActionTimingsRow{actionsId, timingId, weight})
|
||||
ats[tag] = append(ats[tag], &utils.ApiActionTiming{actionsId, timingId, weight})
|
||||
}
|
||||
return ats, nil
|
||||
}
|
||||
@@ -957,8 +956,8 @@ func (self *SQLStorage) GetTpDestinations(tpid, tag string) ([]*Destination, err
|
||||
return dests, nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) GetTpRates(tpid, tag string) (map[string][]*LoadRate, error) {
|
||||
rts := make(map[string][]*LoadRate)
|
||||
func (self *SQLStorage) GetTpRates(tpid, tag string) (map[string]*utils.TPRate, error) {
|
||||
rts := make(map[string]*utils.TPRate)
|
||||
q := fmt.Sprintf("SELECT tag, connect_fee, rate, rate_unit, rate_increment, group_interval_start, rounding_method, rounding_decimals FROM %s WHERE tpid='%s' ", utils.TBL_TP_RATES, tpid)
|
||||
if tag != "" {
|
||||
q += fmt.Sprintf(" AND tag='%s'", tag)
|
||||
@@ -976,30 +975,38 @@ func (self *SQLStorage) GetTpRates(tpid, tag string) (map[string][]*LoadRate, er
|
||||
if err := rows.Scan(&tag, &connect_fee, &rate, &rate_unit, &rate_increment, &group_interval_start, &roundingMethod, &roundingDecimals); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r := &LoadRate{
|
||||
Tag: tag,
|
||||
ConnectFee: connect_fee,
|
||||
Price: rate,
|
||||
RateUnit: rate_unit,
|
||||
RateIncrement: rate_increment,
|
||||
GroupIntervalStart: group_interval_start,
|
||||
RoundingMethod: roundingMethod,
|
||||
RoundingDecimals: roundingDecimals,
|
||||
r := &utils.TPRate{
|
||||
RateId: tag,
|
||||
RateSlots: []*utils.RateSlot{
|
||||
&utils.RateSlot{
|
||||
ConnectFee: connect_fee,
|
||||
Rate: rate,
|
||||
RateUnit: rate_unit,
|
||||
RateIncrement: rate_increment,
|
||||
GroupIntervalStart: group_interval_start,
|
||||
RoundingMethod: roundingMethod,
|
||||
RoundingDecimals: roundingDecimals,
|
||||
},
|
||||
},
|
||||
}
|
||||
// same tag only to create rate groups
|
||||
existingRates, exists := rts[tag]
|
||||
if exists {
|
||||
if err := existingRates[len(existingRates)-1].ValidNextGroup(r); err != nil {
|
||||
rss := existingRates.RateSlots
|
||||
if err := ValidNextGroup(rss[len(rss)-1], r.RateSlots[0]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rts[tag].RateSlots = append(rts[tag].RateSlots, r.RateSlots[0])
|
||||
} else {
|
||||
rts[tag] = r
|
||||
|
||||
}
|
||||
rts[tag] = append(rts[tag], r)
|
||||
}
|
||||
return rts, nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) GetTpDestinationRates(tpid, tag string) (map[string][]*DestinationRate, error) {
|
||||
rts := make(map[string][]*DestinationRate)
|
||||
func (self *SQLStorage) GetTpDestinationRates(tpid, tag string) (map[string]*utils.TPDestinationRate, error) {
|
||||
rts := make(map[string]*utils.TPDestinationRate)
|
||||
q := fmt.Sprintf("SELECT * FROM %s WHERE tpid='%s'", utils.TBL_TP_DESTINATION_RATES, tpid)
|
||||
if tag != "" {
|
||||
q += fmt.Sprintf(" AND tag='%s'", tag)
|
||||
@@ -1015,18 +1022,29 @@ func (self *SQLStorage) GetTpDestinationRates(tpid, tag string) (map[string][]*D
|
||||
if err := rows.Scan(&id, &tpid, &tag, &destinations_tag, &rate_tag); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dr := &DestinationRate{
|
||||
Tag: tag,
|
||||
DestinationsTag: destinations_tag,
|
||||
RateTag: rate_tag,
|
||||
|
||||
dr := &utils.TPDestinationRate{
|
||||
DestinationRateId: tag,
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: destinations_tag,
|
||||
RateId: rate_tag,
|
||||
},
|
||||
},
|
||||
}
|
||||
rts[tag] = append(rts[tag], dr)
|
||||
existingDR, exists := rts[tag]
|
||||
if exists {
|
||||
existingDR.DestinationRates = append(existingDR.DestinationRates, dr.DestinationRates[0])
|
||||
} else {
|
||||
existingDR = dr
|
||||
}
|
||||
rts[tag] = existingDR
|
||||
}
|
||||
return rts, nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) GetTpTimings(tpid, tag string) (map[string]*Timing, error) {
|
||||
tms := make(map[string]*Timing)
|
||||
func (self *SQLStorage) GetTpTimings(tpid, tag string) (map[string]*utils.TPTiming, error) {
|
||||
tms := make(map[string]*utils.TPTiming)
|
||||
q := fmt.Sprintf("SELECT * FROM %s WHERE tpid='%s'", utils.TBL_TP_TIMINGS, tpid)
|
||||
if tag != "" {
|
||||
q += fmt.Sprintf(" AND tag='%s'", tag)
|
||||
@@ -1047,8 +1065,8 @@ func (self *SQLStorage) GetTpTimings(tpid, tag string) (map[string]*Timing, erro
|
||||
return tms, nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) GetTpRatingPlans(tpid, tag string) ([]*DestinationRateTiming, error) {
|
||||
var rts []*DestinationRateTiming
|
||||
func (self *SQLStorage) GetTpRatingPlans(tpid, tag string) (*utils.TPRatingPlan, error) {
|
||||
rts := &utils.TPRatingPlan{RatingPlanId: tag}
|
||||
q := fmt.Sprintf("SELECT * FROM %s WHERE tpid='%s'", utils.TBL_TP_RATING_PLANS, tpid)
|
||||
if tag != "" {
|
||||
q += fmt.Sprintf(" AND tag='%s'", tag)
|
||||
@@ -1065,19 +1083,18 @@ func (self *SQLStorage) GetTpRatingPlans(tpid, tag string) ([]*DestinationRateTi
|
||||
if err := rows.Scan(&id, &tpid, &tag, &destination_rates_tag, &timings_tag, &weight); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rt := &DestinationRateTiming{
|
||||
Tag: tag,
|
||||
DestinationRatesTag: destination_rates_tag,
|
||||
Weight: weight,
|
||||
TimingTag: timings_tag,
|
||||
rt := &utils.RatingPlan{
|
||||
DestRatesId: destination_rates_tag,
|
||||
Weight: weight,
|
||||
TimingId: timings_tag,
|
||||
}
|
||||
rts = append(rts, rt)
|
||||
rts.RatingPlans = append(rts.RatingPlans, rt)
|
||||
}
|
||||
return rts, nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) GetTpRatingProfiles(tpid, tag string) (map[string]*RatingProfile, error) {
|
||||
rpfs := make(map[string]*RatingProfile)
|
||||
func (self *SQLStorage) GetTpRatingProfiles(tpid, tag string) (map[string]*utils.TPRatingProfile, error) {
|
||||
rpfs := make(map[string]*utils.TPRatingProfile)
|
||||
q := fmt.Sprintf("SELECT tag,tenant,tor,direction,subject,activation_time,rating_plan_tag,fallback_subject FROM %s WHERE tpid='%s'",
|
||||
utils.TBL_TP_RATE_PROFILES, tpid)
|
||||
if tag != "" {
|
||||
@@ -1095,11 +1112,11 @@ func (self *SQLStorage) GetTpRatingProfiles(tpid, tag string) (map[string]*Ratin
|
||||
}
|
||||
key := fmt.Sprintf("%s:%s:%s:%s", direction, tenant, tor, subject)
|
||||
rp, ok := rpfs[key]
|
||||
if !ok || rp.Tag != tag {
|
||||
rp = &RatingProfile{Id: key, Tag: tag}
|
||||
if !ok || rp.RatingProfileId != tag {
|
||||
rp = &utils.TPRatingProfile{RatingProfileId: key, Tag: tag}
|
||||
rpfs[key] = rp
|
||||
}
|
||||
rp.DestRatesTimingTag = rating_plan_tag
|
||||
rp.RatingPlanId = rating_plan_tag
|
||||
rp.ActivationTime = activation_time
|
||||
if fallback_subject != "" {
|
||||
for _, fbs := range strings.Split(fallback_subject, ";") {
|
||||
|
||||
@@ -54,7 +54,7 @@ func TestRightMargin(t *testing.T) {
|
||||
func TestSplitMiddle(t *testing.T) {
|
||||
i := &RateInterval{
|
||||
Timing: &RITiming{
|
||||
WeekDays: WeekDays{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
|
||||
WeekDays: utils.WeekDays{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
|
||||
StartTime: "18:00:00",
|
||||
EndTime: "",
|
||||
}}
|
||||
@@ -123,7 +123,7 @@ func TestLeftMargin(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLeftHourMargin(t *testing.T) {
|
||||
i := &RateInterval{Timing: &RITiming{Months: Months{time.December}, MonthDays: MonthDays{1}, StartTime: "09:00:00"}}
|
||||
i := &RateInterval{Timing: &RITiming{Months: utils.Months{time.December}, MonthDays: utils.MonthDays{1}, StartTime: "09:00:00"}}
|
||||
t1 := time.Date(2012, time.December, 1, 8, 45, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.December, 1, 9, 20, 0, 0, time.UTC)
|
||||
ts := &TimeSpan{TimeStart: t1, TimeEnd: t2}
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Import tariff plan from csv into storDb
|
||||
@@ -142,7 +143,7 @@ func (self *TPCSVImporter) importRates(fn string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := self.StorDb.SetTPRates(self.TPid, map[string][]*LoadRate{record[0]: []*LoadRate{rt}}); err != nil {
|
||||
if err := self.StorDb.SetTPRates(self.TPid, map[string]*utils.TPRate{record[0]: rt}); err != nil {
|
||||
if self.Verbose {
|
||||
log.Printf("Ignoring line %d, storDb operational error: <%s> ", lineNr, err.Error())
|
||||
}
|
||||
@@ -169,9 +170,17 @@ func (self *TPCSVImporter) importDestinationRates(fn string) error {
|
||||
}
|
||||
continue
|
||||
}
|
||||
dr := &DestinationRate{record[0], record[1], record[2], nil}
|
||||
dr := &utils.TPDestinationRate{
|
||||
DestinationRateId: record[0],
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: record[1],
|
||||
RateId: record[2],
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := self.StorDb.SetTPDestinationRates(self.TPid,
|
||||
map[string][]*DestinationRate{dr.Tag: []*DestinationRate{dr}}); err != nil {
|
||||
map[string]*utils.TPDestinationRate{dr.DestinationRateId: dr}); err != nil {
|
||||
if self.Verbose {
|
||||
log.Printf("Ignoring line %d, storDb operational error: <%s> ", lineNr, err.Error())
|
||||
}
|
||||
@@ -205,12 +214,17 @@ func (self *TPCSVImporter) importRatingPlans(fn string) error {
|
||||
}
|
||||
continue
|
||||
}
|
||||
drt := &DestinationRateTiming{Tag: record[0],
|
||||
DestinationRatesTag: record[1],
|
||||
Weight: weight,
|
||||
TimingTag: record[2],
|
||||
drt := &utils.TPRatingPlan{
|
||||
RatingPlanId: record[0],
|
||||
RatingPlans: []*utils.RatingPlan{
|
||||
&utils.RatingPlan{
|
||||
DestRatesId: record[1],
|
||||
Weight: weight,
|
||||
TimingId: record[2],
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := self.StorDb.SetTPRatingPlans(self.TPid, map[string][]*DestinationRateTiming{drt.Tag: []*DestinationRateTiming{drt}}); err != nil {
|
||||
if err := self.StorDb.SetTPRatingPlans(self.TPid, map[string]*utils.TPRatingPlan{drt.RatingPlanId: drt}); err != nil {
|
||||
if self.Verbose {
|
||||
log.Printf("Ignoring line %d, storDb operational error: <%s> ", lineNr, err.Error())
|
||||
}
|
||||
@@ -249,17 +263,17 @@ func (self *TPCSVImporter) importRatingProfiles(fn string) error {
|
||||
if self.ImportId != "" {
|
||||
rpTag += "_" + self.ImportId
|
||||
}
|
||||
rp := &RatingProfile{
|
||||
Tag: rpTag,
|
||||
Tenant: tenant,
|
||||
TOR: tor,
|
||||
Direction: direction,
|
||||
Subject: subject,
|
||||
ActivationTime: record[4],
|
||||
DestRatesTimingTag: destRatesTimingTag,
|
||||
RatesFallbackSubject: fallbacksubject,
|
||||
rp := &utils.TPRatingProfile{
|
||||
Tag: rpTag,
|
||||
Tenant: tenant,
|
||||
TOR: tor,
|
||||
Direction: direction,
|
||||
Subject: subject,
|
||||
ActivationTime: record[4],
|
||||
RatingPlanId: destRatesTimingTag,
|
||||
FallbackKeys: strings.Split(fallbacksubject, FALLBACK_SEP),
|
||||
}
|
||||
if err := self.StorDb.SetTPRatingProfiles(self.TPid, map[string][]*RatingProfile{rpTag: []*RatingProfile{rp}}); err != nil {
|
||||
if err := self.StorDb.SetTPRatingProfiles(self.TPid, map[string][]*utils.TPRatingProfile{rpTag: []*utils.TPRatingProfile{rp}}); err != nil {
|
||||
if self.Verbose {
|
||||
log.Printf("Ignoring line %d, storDb operational error: <%s> ", lineNr, err.Error())
|
||||
}
|
||||
@@ -351,13 +365,17 @@ func (self *TPCSVImporter) importActionTimings(fn string) error {
|
||||
}
|
||||
continue
|
||||
}
|
||||
at := &ActionTiming{
|
||||
Tag: tag,
|
||||
ActionsTag: actionsTag,
|
||||
TimingsTag: timingTag,
|
||||
Weight: weight,
|
||||
ats := &utils.ApiTPActionTimings{
|
||||
ActionTimingsId: tag,
|
||||
ActionTimings: []*utils.ApiActionTiming{
|
||||
&utils.ApiActionTiming{
|
||||
ActionsId: actionsTag,
|
||||
TimingId: timingTag,
|
||||
Weight: weight,
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := self.StorDb.SetTPActionTimings(self.TPid, map[string][]*ActionTiming{tag: []*ActionTiming{at}}); err != nil {
|
||||
if err := self.StorDb.SetTPActionTimings(self.TPid, map[string]*utils.ApiTPActionTimings{tag: ats}); err != nil {
|
||||
if self.Verbose {
|
||||
log.Printf("Ignoring line %d, storDb operational error: <%s> ", lineNr, err.Error())
|
||||
}
|
||||
|
||||
@@ -18,61 +18,80 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// This file deals with tp_* data definition
|
||||
|
||||
type TPRate struct {
|
||||
TPid string // Tariff plan id
|
||||
RateId string // Rate id
|
||||
RateSlots []RateSlot // One or more RateSlots
|
||||
TPid string // Tariff plan id
|
||||
RateId string // Rate id
|
||||
RateSlots []*RateSlot // One or more RateSlots
|
||||
}
|
||||
|
||||
type RateSlot struct {
|
||||
ConnectFee float64 // ConnectFee applied once the call is answered
|
||||
Rate float64 // Rate applied
|
||||
RateUnit string // Number of billing units this rate applies to
|
||||
RateIncrement string // This rate will apply in increments of duration
|
||||
GroupIntervalStart string // Group position
|
||||
RoundingMethod string // Use this method to round the cost
|
||||
RoundingDecimals int // Round the cost number of decimals
|
||||
ConnectFee float64 // ConnectFee applied once the call is answered
|
||||
Rate float64 // Rate applied
|
||||
RateUnit time.Duration // Number of billing units this rate applies to
|
||||
RateIncrement time.Duration // This rate will apply in increments of duration
|
||||
GroupIntervalStart time.Duration // Group position
|
||||
RoundingMethod string // Use this method to round the cost
|
||||
RoundingDecimals int // Round the cost number of decimals
|
||||
}
|
||||
|
||||
type TPDestinationRate struct {
|
||||
TPid string // Tariff plan id
|
||||
DestinationRateId string // DestinationRate profile id
|
||||
DestinationRates []DestinationRate // Set of destinationid-rateid bindings
|
||||
TPid string // Tariff plan id
|
||||
DestinationRateId string // DestinationRate profile id
|
||||
DestinationRates []*DestinationRate // Set of destinationid-rateid bindings
|
||||
}
|
||||
|
||||
type DestinationRate struct {
|
||||
DestinationId string // The destination identity
|
||||
RateId string // The rate identity
|
||||
Rate *TPRate
|
||||
}
|
||||
|
||||
type TPTiming struct {
|
||||
Id string
|
||||
Years Years
|
||||
Months Months
|
||||
MonthDays MonthDays
|
||||
WeekDays WeekDays
|
||||
StartTime string
|
||||
}
|
||||
|
||||
type TPRatingPlan struct {
|
||||
TPid string // Tariff plan id
|
||||
RatingPlanId string // RatingPlan profile id
|
||||
RatingPlans []RatingPlan // Set of destinationid-rateid bindings
|
||||
TPid string // Tariff plan id
|
||||
RatingPlanId string // RatingPlan profile id
|
||||
RatingPlans []*RatingPlan // Set of destinationid-rateid bindings
|
||||
}
|
||||
|
||||
type RatingPlan struct {
|
||||
DestRatesId string // The DestinationRate identity
|
||||
TimingId string // The timing identity
|
||||
Weight float64 // Binding priority taken into consideration when more DestinationRates are active on a time slot
|
||||
Timing *TPTiming
|
||||
}
|
||||
|
||||
type TPRatingProfile struct {
|
||||
TPid string // Tariff plan id
|
||||
RatingProfileId string // RatingProfile id
|
||||
Tenant string // Tenant's Id
|
||||
TOR string // TypeOfRecord
|
||||
Direction string // Traffic direction, OUT is the only one supported for now
|
||||
Subject string // Rating subject, usually the same as account
|
||||
RatesFallbackSubject string // Fallback on this subject if rates not found for destination
|
||||
RatingActivations []RatingActivation // Activate rate profiles at specific time
|
||||
TPid string // Tariff plan id
|
||||
Tag string
|
||||
RatingProfileId string // RatingProfile id
|
||||
RatingPlanId string
|
||||
Tenant string // Tenant's Id
|
||||
TOR string // TypeOfRecord
|
||||
Direction string // Traffic direction, OUT is the only one supported for now
|
||||
Subject string // Rating subject, usually the same as account
|
||||
FallbackKeys []string // Fallback on this subject if rates not found for destination
|
||||
ActivationTime string
|
||||
RatingPlanActivations []*RatingActivation // Activate rate profiles at specific time
|
||||
}
|
||||
|
||||
type RatingActivation struct {
|
||||
ActivationTime string // Time when this profile will become active, defined as unix epoch time
|
||||
DestRateTimingId string // Id of DestRateTiming profile
|
||||
// FallbackKeys []string
|
||||
}
|
||||
|
||||
type AttrTPRatingProfileIds struct {
|
||||
@@ -84,9 +103,9 @@ type AttrTPRatingProfileIds struct {
|
||||
}
|
||||
|
||||
type TPActions struct {
|
||||
TPid string // Tariff plan id
|
||||
ActionsId string // Actions id
|
||||
Actions []Action // Set of actions this Actions profile will perform
|
||||
TPid string // Tariff plan id
|
||||
ActionsId string // Actions id
|
||||
Actions []*Action // Set of actions this Actions profile will perform
|
||||
}
|
||||
|
||||
type Action struct {
|
||||
@@ -94,7 +113,7 @@ type Action struct {
|
||||
BalanceType string // Type of balance the action will operate on
|
||||
Direction string // Balance direction
|
||||
Units float64 // Number of units to add/deduct
|
||||
ExpiryTime string // Time when the units will expire
|
||||
ExpiryTime string // Time when the units will expire\
|
||||
DestinationId string // Destination profile id
|
||||
RatingSubject string // Reference a rate subject defined in RatingProfiles
|
||||
BalanceWeight float64 // Balance weight
|
||||
@@ -103,9 +122,9 @@ type Action struct {
|
||||
}
|
||||
|
||||
type ApiTPActionTimings struct {
|
||||
TPid string // Tariff plan id
|
||||
ActionTimingsId string // ActionTimings id
|
||||
ActionTimings []ApiActionTiming // Set of ActionTiming bindings this profile will group
|
||||
TPid string // Tariff plan id
|
||||
ActionTimingsId string // ActionTimings id
|
||||
ActionTimings []*ApiActionTiming // Set of ActionTiming bindings this profile will group
|
||||
}
|
||||
|
||||
type ApiActionTiming struct {
|
||||
@@ -115,9 +134,9 @@ type ApiActionTiming struct {
|
||||
}
|
||||
|
||||
type ApiTPActionTriggers struct {
|
||||
TPid string // Tariff plan id
|
||||
ActionTriggersId string // Profile id
|
||||
ActionTriggers []ApiActionTrigger // Set of triggers grouped in this profile
|
||||
TPid string // Tariff plan id
|
||||
ActionTriggersId string // Profile id
|
||||
ActionTriggers []*ApiActionTrigger // Set of triggers grouped in this profile
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
Rating system designed to be used in VoIP Carriers World
|
||||
Copyright (C) 2013 ITsysCOM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package utils
|
||||
|
||||
// Represents a single row in .csv or storDb, id will be used as key in the map holding all rows
|
||||
type TPActionTimingsRow struct {
|
||||
ActionsId string // Actions id
|
||||
TimingId string // Timing profile id
|
||||
Weight float64 // Binding's weight
|
||||
}
|
||||
Reference in New Issue
Block a user