mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-16 05:39:54 +05:00
restructured action plan
This commit is contained in:
@@ -21,7 +21,6 @@ package engine
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
@@ -32,20 +31,31 @@ const (
|
||||
FORMAT = "2006-1-2 15:04:05 MST"
|
||||
)
|
||||
|
||||
type ActionPlan struct {
|
||||
Uuid string // uniquely identify the timing
|
||||
Id string // informative purpose only
|
||||
AccountIds []string
|
||||
type ActionTiming struct {
|
||||
Uuid string
|
||||
Timing *RateInterval
|
||||
Weight float64
|
||||
ActionsId string
|
||||
Weight float64
|
||||
actions Actions
|
||||
accountIDs map[string]struct{}
|
||||
stCache time.Time // cached time of the next start
|
||||
}
|
||||
|
||||
type ActionPlans []*ActionPlan
|
||||
type ActionPlan struct {
|
||||
Uuid string // uniquely identify the timing
|
||||
Id string // informative purpose only
|
||||
AccountIDs map[string]struct{}
|
||||
ActionTimings []*ActionTiming
|
||||
}
|
||||
|
||||
func (at *ActionPlan) GetNextStartTime(now time.Time) (t time.Time) {
|
||||
func (apl *ActionPlan) RemoveAccountID(accID string) (found bool) {
|
||||
if _, found = apl.AccountIDs[accID]; found {
|
||||
delete(apl.AccountIDs, accID)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (at *ActionTiming) GetNextStartTime(now time.Time) (t time.Time) {
|
||||
if !at.stCache.IsZero() {
|
||||
return at.stCache
|
||||
}
|
||||
@@ -68,7 +78,7 @@ func (at *ActionPlan) GetNextStartTime(now time.Time) (t time.Time) {
|
||||
}
|
||||
|
||||
// To be deleted after the above solution proves reliable
|
||||
func (at *ActionPlan) GetNextStartTimeOld(now time.Time) (t time.Time) {
|
||||
func (at *ActionTiming) GetNextStartTimeOld(now time.Time) (t time.Time) {
|
||||
if !at.stCache.IsZero() {
|
||||
return at.stCache
|
||||
}
|
||||
@@ -218,15 +228,15 @@ YEARS:
|
||||
return
|
||||
}
|
||||
|
||||
func (at *ActionPlan) ResetStartTimeCache() {
|
||||
func (at *ActionTiming) ResetStartTimeCache() {
|
||||
at.stCache = time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
}
|
||||
|
||||
func (at *ActionPlan) SetActions(as Actions) {
|
||||
func (at *ActionTiming) SetActions(as Actions) {
|
||||
at.actions = as
|
||||
}
|
||||
|
||||
func (at *ActionPlan) getActions() (as []*Action, err error) {
|
||||
func (at *ActionTiming) getActions() (as []*Action, err error) {
|
||||
if at.actions == nil {
|
||||
at.actions, err = ratingStorage.GetActions(at.ActionsId, false)
|
||||
}
|
||||
@@ -234,8 +244,8 @@ func (at *ActionPlan) getActions() (as []*Action, err error) {
|
||||
return at.actions, err
|
||||
}
|
||||
|
||||
func (at *ActionPlan) Execute() (err error) {
|
||||
if len(at.AccountIds) == 0 { // nothing to do if no accounts set
|
||||
func (at *ActionTiming) Execute() (err error) {
|
||||
if len(at.accountIDs) == 0 { // nothing to do if no accounts set
|
||||
return
|
||||
}
|
||||
at.ResetStartTimeCache()
|
||||
@@ -244,8 +254,8 @@ func (at *ActionPlan) Execute() (err error) {
|
||||
utils.Logger.Err(fmt.Sprintf("Failed to get actions for %s: %s", at.ActionsId, err))
|
||||
return
|
||||
}
|
||||
_, err = Guardian.Guard(func() (interface{}, error) {
|
||||
for _, accId := range at.AccountIds {
|
||||
for accId, _ := range at.accountIDs {
|
||||
_, err = Guardian.Guard(func() (interface{}, error) {
|
||||
ub, err := accountingStorage.GetAccount(accId)
|
||||
if err != nil {
|
||||
utils.Logger.Warning(fmt.Sprintf("Could not get user balances for this id: %s. Skipping!", accId))
|
||||
@@ -261,45 +271,7 @@ func (at *ActionPlan) Execute() (err error) {
|
||||
if expDate, parseErr := utils.ParseDate(a.ExpirationString); (a.Balance == nil || a.Balance.ExpirationDate.IsZero()) && parseErr == nil && !expDate.IsZero() {
|
||||
a.Balance.ExpirationDate = expDate
|
||||
}
|
||||
// handle remove action
|
||||
if a.ActionType == REMOVE_ACCOUNT {
|
||||
if err := accountingStorage.RemoveAccount(accId); err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("Could not remove account Id: %s: %v", accId, err))
|
||||
transactionFailed = true
|
||||
break
|
||||
}
|
||||
// clean the account id from all action plans
|
||||
allATs, err := ratingStorage.GetAllActionPlans()
|
||||
if err != nil && err != utils.ErrNotFound {
|
||||
utils.Logger.Err(fmt.Sprintf("Could not get action plans: %s: %v", accId, err))
|
||||
transactionFailed = true
|
||||
break
|
||||
}
|
||||
for key, ats := range allATs {
|
||||
changed := false
|
||||
for _, at := range ats {
|
||||
for i := 0; i < len(at.AccountIds); i++ {
|
||||
if at.AccountIds[i] == accId {
|
||||
// delete without preserving order
|
||||
at.AccountIds[i] = at.AccountIds[len(at.AccountIds)-1]
|
||||
at.AccountIds = at.AccountIds[:len(at.AccountIds)-1]
|
||||
i--
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if changed {
|
||||
// save action plan
|
||||
ratingStorage.SetActionPlans(key, ats)
|
||||
// cache
|
||||
ratingStorage.CacheRatingPrefixValues(map[string][]string{utils.ACTION_PLAN_PREFIX: []string{utils.ACTION_PLAN_PREFIX + key}})
|
||||
}
|
||||
}
|
||||
toBeSaved = false
|
||||
continue // do not go to getActionFunc
|
||||
// TODO: maybe we should break here as the account is gone
|
||||
// will leave continue for now as the next action can create another acount
|
||||
}
|
||||
|
||||
actionFunction, exists := getActionFunc(a.ActionType)
|
||||
if !exists {
|
||||
// do not allow the action plan to be rescheduled
|
||||
@@ -318,18 +290,18 @@ func (at *ActionPlan) Execute() (err error) {
|
||||
if !transactionFailed && toBeSaved {
|
||||
accountingStorage.SetAccount(ub)
|
||||
}
|
||||
}
|
||||
return 0, nil
|
||||
}, 0, at.AccountIds...)
|
||||
return 0, nil
|
||||
}, 0, accId)
|
||||
}
|
||||
if err != nil {
|
||||
utils.Logger.Warning(fmt.Sprintf("Error executing action plan: %v", err))
|
||||
return err
|
||||
}
|
||||
storageLogger.LogActionPlan(utils.SCHED_SOURCE, at, aac)
|
||||
storageLogger.LogActionTiming(utils.SCHED_SOURCE, at, aac)
|
||||
return
|
||||
}
|
||||
|
||||
func (at *ActionPlan) IsASAP() bool {
|
||||
func (at *ActionTiming) IsASAP() bool {
|
||||
if at.Timing == nil {
|
||||
return false
|
||||
}
|
||||
@@ -337,17 +309,17 @@ func (at *ActionPlan) IsASAP() bool {
|
||||
}
|
||||
|
||||
// Structure to store actions according to weight
|
||||
type ActionPlanPriotityList []*ActionPlan
|
||||
type ActionTimingPriorityList []*ActionTiming
|
||||
|
||||
func (atpl ActionPlanPriotityList) Len() int {
|
||||
func (atpl ActionTimingPriorityList) Len() int {
|
||||
return len(atpl)
|
||||
}
|
||||
|
||||
func (atpl ActionPlanPriotityList) Swap(i, j int) {
|
||||
func (atpl ActionTimingPriorityList) Swap(i, j int) {
|
||||
atpl[i], atpl[j] = atpl[j], atpl[i]
|
||||
}
|
||||
|
||||
func (atpl ActionPlanPriotityList) Less(i, j int) bool {
|
||||
func (atpl ActionTimingPriorityList) Less(i, j int) bool {
|
||||
if atpl[i].GetNextStartTime(time.Now()).Equal(atpl[j].GetNextStartTime(time.Now())) {
|
||||
// higher weights earlyer in the list
|
||||
return atpl[i].Weight > atpl[j].Weight
|
||||
@@ -355,20 +327,16 @@ func (atpl ActionPlanPriotityList) Less(i, j int) bool {
|
||||
return atpl[i].GetNextStartTime(time.Now()).Before(atpl[j].GetNextStartTime(time.Now()))
|
||||
}
|
||||
|
||||
func (atpl ActionPlanPriotityList) Sort() {
|
||||
func (atpl ActionTimingPriorityList) Sort() {
|
||||
sort.Sort(atpl)
|
||||
}
|
||||
|
||||
func (at *ActionPlan) String_DISABLED() string {
|
||||
return at.Id + " " + at.GetNextStartTime(time.Now()).String() + ",w: " + strconv.FormatFloat(at.Weight, 'f', -1, 64)
|
||||
}
|
||||
|
||||
// Helper to remove ActionPlan members based on specific filters, empty data means no always match
|
||||
func RemActionPlan(ats ActionPlans, actionTimingId, accountId string) ActionPlans {
|
||||
for idx, at := range ats {
|
||||
if len(actionTimingId) != 0 && at.Uuid != actionTimingId { // No Match for ActionPlanId, no need to move further
|
||||
continue
|
||||
}
|
||||
/*func RemActionPlan(apl ActionPlan, actionTimingId, accountId string) ActionPlan {
|
||||
if len(actionTimingId) != 0 && apl.Uuid != actionTimingId { // No Match for ActionPlanId, no need to move further
|
||||
continue
|
||||
}
|
||||
for idx, ats := range apl.ActionTimings {
|
||||
if len(accountId) == 0 { // No account defined, considered match for complete removal
|
||||
if len(ats) == 1 { // Removing last item, by init empty
|
||||
return make([]*ActionPlan, 0)
|
||||
@@ -392,4 +360,4 @@ func RemActionPlan(ats ActionPlans, actionTimingId, accountId string) ActionPlan
|
||||
}
|
||||
}
|
||||
return ats
|
||||
}
|
||||
}*/
|
||||
|
||||
@@ -79,47 +79,6 @@ func (at *ActionTrigger) Execute(ub *Account, sq *StatsQueueTriggered) (err erro
|
||||
a.Balance = &Balance{}
|
||||
}
|
||||
a.Balance.ExpirationDate, _ = utils.ParseDate(a.ExpirationString)
|
||||
// handle remove action
|
||||
if a.ActionType == REMOVE_ACCOUNT {
|
||||
accId := ub.Id
|
||||
if err := accountingStorage.RemoveAccount(accId); err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("Could not remove account Id: %s: %v", accId, err))
|
||||
transactionFailed = true
|
||||
break
|
||||
}
|
||||
// clean the account id from all action plans
|
||||
allATs, err := ratingStorage.GetAllActionPlans()
|
||||
if err != nil && err != utils.ErrNotFound {
|
||||
utils.Logger.Err(fmt.Sprintf("Could not get action plans: %s: %v", accId, err))
|
||||
transactionFailed = true
|
||||
break
|
||||
}
|
||||
for key, ats := range allATs {
|
||||
changed := false
|
||||
for _, at := range ats {
|
||||
for i := 0; i < len(at.AccountIds); i++ {
|
||||
if at.AccountIds[i] == accId {
|
||||
// delete without preserving order
|
||||
at.AccountIds[i] = at.AccountIds[len(at.AccountIds)-1]
|
||||
at.AccountIds = at.AccountIds[:len(at.AccountIds)-1]
|
||||
i -= 1
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if changed {
|
||||
// save action plan
|
||||
ratingStorage.SetActionPlans(key, ats)
|
||||
// cache
|
||||
ratingStorage.CacheRatingPrefixValues(map[string][]string{utils.ACTION_PLAN_PREFIX: []string{utils.ACTION_PLAN_PREFIX + key}})
|
||||
}
|
||||
}
|
||||
toBeSaved = false
|
||||
continue // do not go to getActionFunc
|
||||
// TODO: maybe we should break here as the account is gone
|
||||
// will leave continue for now as the next action can create another acount
|
||||
}
|
||||
|
||||
actionFunction, exists := getActionFunc(a.ActionType)
|
||||
if !exists {
|
||||
utils.Logger.Err(fmt.Sprintf("Function type %v not available, aborting execution!", a.ActionType))
|
||||
|
||||
@@ -38,7 +38,7 @@ var (
|
||||
)
|
||||
|
||||
func TestActionTimingAlways(t *testing.T) {
|
||||
at := &ActionPlan{Timing: &RateInterval{Timing: &RITiming{StartTime: "00:00:00"}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{StartTime: "00:00:00"}}}
|
||||
st := at.GetNextStartTime(referenceDate)
|
||||
y, m, d := referenceDate.Date()
|
||||
expected := time.Date(y, m, d, 0, 0, 0, 0, time.Local).AddDate(0, 0, 1)
|
||||
@@ -48,7 +48,7 @@ func TestActionTimingAlways(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestActionPlanNothing(t *testing.T) {
|
||||
at := &ActionPlan{}
|
||||
at := &ActionTiming{}
|
||||
st := at.GetNextStartTime(referenceDate)
|
||||
expected := time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
if !st.Equal(expected) {
|
||||
@@ -57,7 +57,7 @@ func TestActionPlanNothing(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestActionTimingMidnight(t *testing.T) {
|
||||
at := &ActionPlan{Timing: &RateInterval{Timing: &RITiming{StartTime: "00:00:00"}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{StartTime: "00:00:00"}}}
|
||||
y, m, d := referenceDate.Date()
|
||||
now := time.Date(y, m, d, 0, 0, 1, 0, time.Local)
|
||||
st := at.GetNextStartTime(now)
|
||||
@@ -68,7 +68,7 @@ func TestActionTimingMidnight(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestActionPlanOnlyHour(t *testing.T) {
|
||||
at := &ActionPlan{Timing: &RateInterval{Timing: &RITiming{StartTime: "10:01:00"}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{StartTime: "10:01:00"}}}
|
||||
st := at.GetNextStartTime(referenceDate)
|
||||
|
||||
y, m, d := now.Date()
|
||||
@@ -82,7 +82,7 @@ func TestActionPlanOnlyHour(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestActionPlanHourYear(t *testing.T) {
|
||||
at := &ActionPlan{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2022}, StartTime: "10:01:00"}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2022}, StartTime: "10:01:00"}}}
|
||||
st := at.GetNextStartTime(referenceDate)
|
||||
expected := time.Date(2022, 1, 1, 10, 1, 0, 0, time.Local)
|
||||
if !st.Equal(expected) {
|
||||
@@ -91,7 +91,7 @@ func TestActionPlanHourYear(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestActionPlanOnlyWeekdays(t *testing.T) {
|
||||
at := &ActionPlan{Timing: &RateInterval{Timing: &RITiming{WeekDays: []time.Weekday{time.Monday}}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{WeekDays: []time.Weekday{time.Monday}}}}
|
||||
st := at.GetNextStartTime(referenceDate)
|
||||
|
||||
y, m, d := now.Date()
|
||||
@@ -112,7 +112,7 @@ func TestActionPlanOnlyWeekdays(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestActionPlanHourWeekdays(t *testing.T) {
|
||||
at := &ActionPlan{Timing: &RateInterval{Timing: &RITiming{WeekDays: []time.Weekday{time.Monday}, StartTime: "10:01:00"}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{WeekDays: []time.Weekday{time.Monday}, StartTime: "10:01:00"}}}
|
||||
st := at.GetNextStartTime(referenceDate)
|
||||
|
||||
y, m, d := now.Date()
|
||||
@@ -135,7 +135,7 @@ func TestActionPlanOnlyMonthdays(t *testing.T) {
|
||||
|
||||
y, m, d := now.Date()
|
||||
tomorrow := time.Date(y, m, d, 0, 0, 0, 0, time.Local).AddDate(0, 0, 1)
|
||||
at := &ActionPlan{Timing: &RateInterval{Timing: &RITiming{MonthDays: utils.MonthDays{1, 25, 2, tomorrow.Day()}}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{MonthDays: utils.MonthDays{1, 25, 2, tomorrow.Day()}}}}
|
||||
st := at.GetNextStartTime(referenceDate)
|
||||
expected := tomorrow
|
||||
if !st.Equal(expected) {
|
||||
@@ -151,7 +151,7 @@ func TestActionPlanHourMonthdays(t *testing.T) {
|
||||
if now.After(testTime) {
|
||||
y, m, d = tomorrow.Date()
|
||||
}
|
||||
at := &ActionPlan{Timing: &RateInterval{Timing: &RITiming{MonthDays: utils.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(referenceDate)
|
||||
expected := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
|
||||
if !st.Equal(expected) {
|
||||
@@ -163,7 +163,7 @@ func TestActionPlanOnlyMonths(t *testing.T) {
|
||||
|
||||
y, m, _ := now.Date()
|
||||
nextMonth := time.Date(y, m, 1, 0, 0, 0, 0, time.Local).AddDate(0, 1, 0)
|
||||
at := &ActionPlan{Timing: &RateInterval{Timing: &RITiming{Months: utils.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(referenceDate)
|
||||
expected := time.Date(nextMonth.Year(), nextMonth.Month(), 1, 0, 0, 0, 0, time.Local)
|
||||
if !st.Equal(expected) {
|
||||
@@ -186,7 +186,7 @@ func TestActionPlanHourMonths(t *testing.T) {
|
||||
y = nextMonth.Year()
|
||||
|
||||
}
|
||||
at := &ActionPlan{Timing: &RateInterval{Timing: &RITiming{
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{
|
||||
Months: utils.Months{now.Month(), nextMonth.Month()},
|
||||
StartTime: "10:01:00"}}}
|
||||
st := at.GetNextStartTime(referenceDate)
|
||||
@@ -216,7 +216,7 @@ func TestActionPlanHourMonthdaysMonths(t *testing.T) {
|
||||
month = nextMonth.Month()
|
||||
}
|
||||
}
|
||||
at := &ActionPlan{Timing: &RateInterval{
|
||||
at := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Months: utils.Months{now.Month(), nextMonth.Month()},
|
||||
MonthDays: utils.MonthDays{now.Day(), tomorrow.Day()},
|
||||
@@ -234,7 +234,7 @@ func TestActionPlanFirstOfTheMonth(t *testing.T) {
|
||||
|
||||
y, m, _ := now.Date()
|
||||
nextMonth := time.Date(y, m, 1, 0, 0, 0, 0, time.Local).AddDate(0, 1, 0)
|
||||
at := &ActionPlan{Timing: &RateInterval{
|
||||
at := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
MonthDays: utils.MonthDays{1},
|
||||
},
|
||||
@@ -249,7 +249,7 @@ func TestActionPlanFirstOfTheMonth(t *testing.T) {
|
||||
func TestActionPlanOnlyYears(t *testing.T) {
|
||||
y, _, _ := referenceDate.Date()
|
||||
nextYear := time.Date(y, 1, 1, 0, 0, 0, 0, time.Local).AddDate(1, 0, 0)
|
||||
at := &ActionPlan{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{now.Year(), nextYear.Year()}}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{now.Year(), nextYear.Year()}}}}
|
||||
st := at.GetNextStartTime(referenceDate)
|
||||
expected := nextYear
|
||||
if !st.Equal(expected) {
|
||||
@@ -258,7 +258,7 @@ func TestActionPlanOnlyYears(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestActionPlanPast(t *testing.T) {
|
||||
at := &ActionPlan{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2023}}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2023}}}}
|
||||
st := at.GetNextStartTime(referenceDate)
|
||||
expected := time.Date(2023, 1, 1, 0, 0, 0, 0, time.Local)
|
||||
if !st.Equal(expected) {
|
||||
@@ -267,7 +267,7 @@ func TestActionPlanPast(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestActionPlanHourYears(t *testing.T) {
|
||||
at := &ActionPlan{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{referenceDate.Year(), referenceDate.Year() + 1}, StartTime: "10:01:00"}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{referenceDate.Year(), referenceDate.Year() + 1}, StartTime: "10:01:00"}}}
|
||||
st := at.GetNextStartTime(referenceDate)
|
||||
expected := time.Date(referenceDate.Year(), 1, 1, 10, 1, 0, 0, time.Local)
|
||||
if referenceDate.After(expected) {
|
||||
@@ -292,7 +292,7 @@ func TestActionPlanHourMonthdaysYear(t *testing.T) {
|
||||
expected = tomorrow
|
||||
}
|
||||
}
|
||||
at := &ActionPlan{Timing: &RateInterval{
|
||||
at := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: utils.Years{now.Year(), nextYear.Year()},
|
||||
MonthDays: utils.MonthDays{now.Day(), tomorrow.Day()},
|
||||
@@ -332,7 +332,7 @@ func TestActionPlanHourMonthdaysMonthYear(t *testing.T) {
|
||||
year = nextYear.Year()
|
||||
}
|
||||
}
|
||||
at := &ActionPlan{Timing: &RateInterval{
|
||||
at := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: utils.Years{now.Year(), nextYear.Year()},
|
||||
Months: utils.Months{now.Month(), nextMonth.Month()},
|
||||
@@ -350,7 +350,7 @@ func TestActionPlanHourMonthdaysMonthYear(t *testing.T) {
|
||||
func TestActionPlanFirstOfTheYear(t *testing.T) {
|
||||
y, _, _ := now.Date()
|
||||
nextYear := time.Date(y, 1, 1, 0, 0, 0, 0, time.Local).AddDate(1, 0, 0)
|
||||
at := &ActionPlan{Timing: &RateInterval{
|
||||
at := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: utils.Years{nextYear.Year()},
|
||||
Months: utils.Months{time.January},
|
||||
@@ -371,7 +371,7 @@ func TestActionPlanFirstMonthOfTheYear(t *testing.T) {
|
||||
if referenceDate.After(expected) {
|
||||
expected = expected.AddDate(1, 0, 0)
|
||||
}
|
||||
at := &ActionPlan{Timing: &RateInterval{
|
||||
at := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Months: utils.Months{time.January},
|
||||
},
|
||||
@@ -388,7 +388,7 @@ func TestActionPlanFirstMonthOfTheYearSecondDay(t *testing.T) {
|
||||
if referenceDate.After(expected) {
|
||||
expected = expected.AddDate(1, 0, 0)
|
||||
}
|
||||
at := &ActionPlan{Timing: &RateInterval{
|
||||
at := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Months: utils.Months{time.January},
|
||||
MonthDays: utils.MonthDays{2},
|
||||
@@ -401,7 +401,7 @@ func TestActionPlanFirstMonthOfTheYearSecondDay(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestActionPlanCheckForASAP(t *testing.T) {
|
||||
at := &ActionPlan{Timing: &RateInterval{Timing: &RITiming{StartTime: utils.ASAP}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{StartTime: utils.ASAP}}}
|
||||
if !at.IsASAP() {
|
||||
t.Errorf("%v should be asap!", at)
|
||||
}
|
||||
@@ -413,7 +413,7 @@ func TestActionPlanLogFunction(t *testing.T) {
|
||||
BalanceType: "test",
|
||||
Balance: &Balance{Value: 1.1},
|
||||
}
|
||||
at := &ActionPlan{
|
||||
at := &ActionTiming{
|
||||
actions: []*Action{a},
|
||||
}
|
||||
err := at.Execute()
|
||||
@@ -428,8 +428,8 @@ func TestActionPlanFunctionNotAvailable(t *testing.T) {
|
||||
BalanceType: "test",
|
||||
Balance: &Balance{Value: 1.1},
|
||||
}
|
||||
at := &ActionPlan{
|
||||
AccountIds: []string{"cgrates.org:dy"},
|
||||
at := &ActionTiming{
|
||||
accountIDs: map[string]struct{}{"cgrates.org:dy": struct{}{}},
|
||||
Timing: &RateInterval{},
|
||||
actions: []*Action{a},
|
||||
}
|
||||
@@ -439,8 +439,8 @@ func TestActionPlanFunctionNotAvailable(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionPlanPriotityListSortByWeight(t *testing.T) {
|
||||
at1 := &ActionPlan{Timing: &RateInterval{
|
||||
func TestActionTimingPriorityListSortByWeight(t *testing.T) {
|
||||
at1 := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: utils.Years{2020},
|
||||
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},
|
||||
@@ -449,7 +449,7 @@ func TestActionPlanPriotityListSortByWeight(t *testing.T) {
|
||||
},
|
||||
Weight: 20,
|
||||
}}
|
||||
at2 := &ActionPlan{Timing: &RateInterval{
|
||||
at2 := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: utils.Years{2020},
|
||||
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},
|
||||
@@ -458,7 +458,7 @@ func TestActionPlanPriotityListSortByWeight(t *testing.T) {
|
||||
},
|
||||
Weight: 10,
|
||||
}}
|
||||
var atpl ActionPlanPriotityList
|
||||
var atpl ActionTimingPriorityList
|
||||
atpl = append(atpl, at2, at1)
|
||||
atpl.Sort()
|
||||
if atpl[0] != at1 || atpl[1] != at2 {
|
||||
@@ -466,8 +466,8 @@ func TestActionPlanPriotityListSortByWeight(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionPlanPriotityListWeight(t *testing.T) {
|
||||
at1 := &ActionPlan{
|
||||
func TestActionTimingPriorityListWeight(t *testing.T) {
|
||||
at1 := &ActionTiming{
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
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},
|
||||
@@ -477,7 +477,7 @@ func TestActionPlanPriotityListWeight(t *testing.T) {
|
||||
},
|
||||
Weight: 20,
|
||||
}
|
||||
at2 := &ActionPlan{
|
||||
at2 := &ActionTiming{
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
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},
|
||||
@@ -487,7 +487,7 @@ func TestActionPlanPriotityListWeight(t *testing.T) {
|
||||
},
|
||||
Weight: 10,
|
||||
}
|
||||
var atpl ActionPlanPriotityList
|
||||
var atpl ActionTimingPriorityList
|
||||
atpl = append(atpl, at2, at1)
|
||||
atpl.Sort()
|
||||
if atpl[0] != at1 || atpl[1] != at2 {
|
||||
@@ -495,17 +495,18 @@ func TestActionPlanPriotityListWeight(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
func TestActionPlansRemoveMember(t *testing.T) {
|
||||
at1 := &ActionPlan{
|
||||
Uuid: "some uuid",
|
||||
Id: "test",
|
||||
AccountIds: []string{"one", "two", "three"},
|
||||
AccountIDs: []string{"one", "two", "three"},
|
||||
ActionsId: "TEST_ACTIONS",
|
||||
}
|
||||
at2 := &ActionPlan{
|
||||
Uuid: "some uuid22",
|
||||
Id: "test2",
|
||||
AccountIds: []string{"three", "four"},
|
||||
AccountIDs: []string{"three", "four"},
|
||||
ActionsId: "TEST_ACTIONS2",
|
||||
}
|
||||
ats := ActionPlans{at1, at2}
|
||||
@@ -522,7 +523,7 @@ func TestActionPlansRemoveMember(t *testing.T) {
|
||||
if ats2 = RemActionPlan(ats2, "", ""); len(ats2) != 0 {
|
||||
t.Error("Should have no members anymore", ats2)
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
func TestActionTriggerMatchNil(t *testing.T) {
|
||||
at := &ActionTrigger{
|
||||
@@ -1056,10 +1057,8 @@ func TestActionPlanLogging(t *testing.T) {
|
||||
Rates: RateGroups{&Rate{0, 1.0, 1 * time.Second, 60 * time.Second}},
|
||||
},
|
||||
}
|
||||
at := &ActionPlan{
|
||||
Uuid: "some uuid",
|
||||
Id: "test",
|
||||
AccountIds: []string{"one", "two", "three"},
|
||||
at := &ActionTiming{
|
||||
accountIDs: map[string]struct{}{"one": struct{}{}, "two": struct{}{}, "three": struct{}{}},
|
||||
Timing: i,
|
||||
Weight: 10.0,
|
||||
ActionsId: "TEST_ACTIONS",
|
||||
@@ -1068,7 +1067,7 @@ func TestActionPlanLogging(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error("Error getting actions for the action trigger: ", err)
|
||||
}
|
||||
storageLogger.LogActionPlan(utils.SCHED_SOURCE, at, as)
|
||||
storageLogger.LogActionTiming(utils.SCHED_SOURCE, at, as)
|
||||
//expected := "some uuid|test|one,two,three|;1,2,3,4,5,6,7,8,9,10,11,12;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;1,2,3,4,5;18:00:00;00:00:00;10;0;1;60;1|10|TEST_ACTIONS*|TOPUP|MONETARY|OUT|10|0"
|
||||
var key string
|
||||
atMap, _ := ratingStorage.GetAllActionPlans()
|
||||
@@ -1104,8 +1103,8 @@ func TestRemoveAction(t *testing.T) {
|
||||
ActionType: REMOVE_ACCOUNT,
|
||||
}
|
||||
|
||||
at := &ActionPlan{
|
||||
AccountIds: []string{"cgrates.org:remo"},
|
||||
at := &ActionTiming{
|
||||
accountIDs: map[string]struct{}{"cgrates.org:remo": struct{}{}},
|
||||
actions: Actions{a},
|
||||
}
|
||||
at.Execute()
|
||||
@@ -1123,8 +1122,8 @@ func TestTopupAction(t *testing.T) {
|
||||
Balance: &Balance{Value: 25, DestinationIds: utils.NewStringMap("RET"), Directions: utils.NewStringMap(utils.OUT), Weight: 20},
|
||||
}
|
||||
|
||||
at := &ActionPlan{
|
||||
AccountIds: []string{"vdf:minu"},
|
||||
at := &ActionTiming{
|
||||
accountIDs: map[string]struct{}{"vdf:minu": struct{}{}},
|
||||
actions: Actions{a},
|
||||
}
|
||||
|
||||
@@ -1145,8 +1144,8 @@ func TestTopupActionLoaded(t *testing.T) {
|
||||
Balance: &Balance{Value: 25, DestinationIds: utils.NewStringMap("RET"), Directions: utils.NewStringMap(utils.OUT), Weight: 20},
|
||||
}
|
||||
|
||||
at := &ActionPlan{
|
||||
AccountIds: []string{"vdf:minitsboy"},
|
||||
at := &ActionTiming{
|
||||
accountIDs: map[string]struct{}{"vdf:minitsboy": struct{}{}},
|
||||
actions: Actions{a},
|
||||
}
|
||||
|
||||
@@ -1297,8 +1296,8 @@ func TestActionTransactionFuncType(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error("Error setting account: ", err)
|
||||
}
|
||||
at := &ActionPlan{
|
||||
AccountIds: []string{"cgrates.org:trans"},
|
||||
at := &ActionTiming{
|
||||
accountIDs: map[string]struct{}{"cgrates.org:trans": struct{}{}},
|
||||
Timing: &RateInterval{},
|
||||
actions: []*Action{
|
||||
&Action{
|
||||
@@ -1335,8 +1334,8 @@ func TestActionTransactionBalanceType(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error("Error setting account: ", err)
|
||||
}
|
||||
at := &ActionPlan{
|
||||
AccountIds: []string{"cgrates.org:trans"},
|
||||
at := &ActionTiming{
|
||||
accountIDs: map[string]struct{}{"cgrates.org:trans": struct{}{}},
|
||||
Timing: &RateInterval{},
|
||||
actions: []*Action{
|
||||
&Action{
|
||||
@@ -1373,8 +1372,8 @@ func TestActionWithExpireWithoutExpire(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error("Error setting account: ", err)
|
||||
}
|
||||
at := &ActionPlan{
|
||||
AccountIds: []string{"cgrates.org:exp"},
|
||||
at := &ActionTiming{
|
||||
accountIDs: map[string]struct{}{"cgrates.org:exp": struct{}{}},
|
||||
Timing: &RateInterval{},
|
||||
actions: []*Action{
|
||||
&Action{
|
||||
@@ -1428,8 +1427,8 @@ func TestActionRemoveBalance(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error("Error setting account: ", err)
|
||||
}
|
||||
at := &ActionPlan{
|
||||
AccountIds: []string{"cgrates.org:rembal"},
|
||||
at := &ActionTiming{
|
||||
accountIDs: map[string]struct{}{"cgrates.org:rembal": struct{}{}},
|
||||
Timing: &RateInterval{},
|
||||
actions: []*Action{
|
||||
&Action{
|
||||
|
||||
@@ -487,8 +487,9 @@ func TestMaxSessionTimeWithAccount(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMaxSessionTimeWithMaxRate(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
//acc, _ := accountingStorage.GetAccount("cgrates.org:12345")
|
||||
@@ -513,8 +514,9 @@ func TestMaxSessionTimeWithMaxRate(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMaxSessionTimeWithMaxCost(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
cd := &CallDescriptor{
|
||||
@@ -536,8 +538,9 @@ func TestMaxSessionTimeWithMaxCost(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetCostWithMaxCost(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
cd := &CallDescriptor{
|
||||
@@ -558,8 +561,9 @@ func TestGetCostWithMaxCost(t *testing.T) {
|
||||
}
|
||||
}
|
||||
func TestGetCostRoundingIssue(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
cd := &CallDescriptor{
|
||||
@@ -582,8 +586,9 @@ func TestGetCostRoundingIssue(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetCostRatingInfoOnZeroTime(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
cd := &CallDescriptor{
|
||||
@@ -609,8 +614,9 @@ func TestGetCostRatingInfoOnZeroTime(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitRatingInfoOnZeroTime(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
cd := &CallDescriptor{
|
||||
@@ -637,8 +643,9 @@ func TestDebitRatingInfoOnZeroTime(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMaxDebitRatingInfoOnZeroTime(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
cd := &CallDescriptor{
|
||||
@@ -664,8 +671,9 @@ func TestMaxDebitRatingInfoOnZeroTime(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMaxDebitUnknowDest(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
cd := &CallDescriptor{
|
||||
@@ -686,8 +694,9 @@ func TestMaxDebitUnknowDest(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetCostMaxDebitRoundingIssue(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
cd := &CallDescriptor{
|
||||
@@ -718,8 +727,9 @@ func TestGetCostMaxDebitRoundingIssue(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMaxSessionTimeWithMaxCostFree(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
cd := &CallDescriptor{
|
||||
@@ -741,8 +751,9 @@ func TestMaxSessionTimeWithMaxCostFree(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMaxDebitWithMaxCostFree(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
cd := &CallDescriptor{
|
||||
@@ -764,8 +775,9 @@ func TestMaxDebitWithMaxCostFree(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetCostWithMaxCostFree(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
cd := &CallDescriptor{
|
||||
@@ -818,12 +830,14 @@ func TestMaxSessionTimeWithAccountAlias(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMaxSessionTimeWithAccountShared(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP_SHARED0_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP_SHARED0_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
ap, _ = ratingStorage.GetActionPlans("TOPUP_SHARED10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ = ratingStorage.GetActionPlan("TOPUP_SHARED10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
|
||||
@@ -857,12 +871,14 @@ func TestMaxSessionTimeWithAccountShared(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMaxDebitWithAccountShared(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP_SHARED0_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP_SHARED0_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
ap, _ = ratingStorage.GetActionPlans("TOPUP_SHARED10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ = ratingStorage.GetActionPlan("TOPUP_SHARED10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
|
||||
@@ -1077,8 +1093,9 @@ func TestMaxSesionTimeLongerThanMoney(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitFromShareAndNormal(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP_SHARED10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP_SHARED10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
|
||||
@@ -1105,8 +1122,9 @@ func TestDebitFromShareAndNormal(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitFromEmptyShare(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP_EMPTY_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP_EMPTY_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
|
||||
@@ -1133,8 +1151,9 @@ func TestDebitFromEmptyShare(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitNegatve(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("POST_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("POST_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
|
||||
@@ -1172,8 +1191,9 @@ func TestDebitNegatve(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMaxDebitZeroDefinedRate(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
cd1 := &CallDescriptor{
|
||||
@@ -1200,8 +1220,9 @@ func TestMaxDebitZeroDefinedRate(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMaxDebitZeroDefinedRateOnlyMinutes(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
cd1 := &CallDescriptor{
|
||||
@@ -1228,8 +1249,9 @@ func TestMaxDebitZeroDefinedRateOnlyMinutes(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMaxDebitConsumesMinutes(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false)
|
||||
for _, at := range ap {
|
||||
ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false)
|
||||
for _, at := range ap.ActionTimings {
|
||||
at.accountIDs = ap.AccountIDs
|
||||
at.Execute()
|
||||
}
|
||||
cd1 := &CallDescriptor{
|
||||
|
||||
@@ -985,25 +985,42 @@ func TestLoadActionTimings(t *testing.T) {
|
||||
if len(csvr.actionPlans) != 6 {
|
||||
t.Error("Failed to load action timings: ", len(csvr.actionPlans))
|
||||
}
|
||||
atm := csvr.actionPlans["MORE_MINUTES"][0]
|
||||
atm := csvr.actionPlans["MORE_MINUTES"]
|
||||
expected := &ActionPlan{
|
||||
Uuid: atm.Uuid,
|
||||
Id: "MORE_MINUTES",
|
||||
AccountIds: []string{"vdf:minitsboy"},
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: utils.Years{2012},
|
||||
Months: utils.Months{},
|
||||
MonthDays: utils.MonthDays{},
|
||||
WeekDays: utils.WeekDays{},
|
||||
StartTime: utils.ASAP,
|
||||
AccountIDs: map[string]struct{}{"vdf:minitsboy": struct{}{}},
|
||||
ActionTimings: []*ActionTiming{
|
||||
&ActionTiming{
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: utils.Years{2012},
|
||||
Months: utils.Months{},
|
||||
MonthDays: utils.MonthDays{},
|
||||
WeekDays: utils.WeekDays{},
|
||||
StartTime: utils.ASAP,
|
||||
},
|
||||
},
|
||||
Weight: 10,
|
||||
ActionsId: "MINI",
|
||||
},
|
||||
&ActionTiming{
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: utils.Years{2012},
|
||||
Months: utils.Months{},
|
||||
MonthDays: utils.MonthDays{},
|
||||
WeekDays: utils.WeekDays{},
|
||||
StartTime: utils.ASAP,
|
||||
},
|
||||
},
|
||||
Weight: 10,
|
||||
ActionsId: "SHARED",
|
||||
},
|
||||
},
|
||||
Weight: 10,
|
||||
ActionsId: "MINI",
|
||||
}
|
||||
if !reflect.DeepEqual(atm, expected) {
|
||||
t.Errorf("Error loading action timing:\n%+v", atm)
|
||||
t.Errorf("Error loading action timing:\n%+v", atm.ActionTimings[1].Timing)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,9 +63,9 @@ type RatingStorage interface {
|
||||
SetSharedGroup(*SharedGroup) error
|
||||
GetActionTriggers(string) (ActionTriggers, error)
|
||||
SetActionTriggers(string, ActionTriggers) error
|
||||
GetActionPlans(string, bool) (ActionPlans, error)
|
||||
SetActionPlans(string, ActionPlans) error
|
||||
GetAllActionPlans() (map[string]ActionPlans, error)
|
||||
GetActionPlan(string, bool) (*ActionPlan, error)
|
||||
SetActionPlan(string, *ActionPlan) error
|
||||
GetAllActionPlans() (map[string]*ActionPlan, error)
|
||||
}
|
||||
|
||||
type AccountingStorage interface {
|
||||
@@ -106,7 +106,7 @@ type LogStorage interface {
|
||||
Storage
|
||||
//GetAllActionTimingsLogs() (map[string]ActionsTimings, error)
|
||||
LogActionTrigger(ubId, source string, at *ActionTrigger, as Actions) error
|
||||
LogActionPlan(source string, at *ActionPlan, as Actions) error
|
||||
LogActionTiming(source string, at *ActionTiming, as Actions) error
|
||||
}
|
||||
|
||||
type LoadStorage interface {
|
||||
|
||||
@@ -178,7 +178,7 @@ func (ms *MapStorage) cacheRating(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actK
|
||||
}
|
||||
if strings.HasPrefix(k, utils.ACTION_PLAN_PREFIX) {
|
||||
cache2go.RemKey(k)
|
||||
if _, err := ms.GetActionPlans(k[len(utils.ACTION_PLAN_PREFIX):], true); err != nil {
|
||||
if _, err := ms.GetActionPlan(k[len(utils.ACTION_PLAN_PREFIX):], true); err != nil {
|
||||
cache2go.RollbackTransaction()
|
||||
return err
|
||||
}
|
||||
@@ -645,11 +645,11 @@ func (ms *MapStorage) SetActionTriggers(key string, atrs ActionTriggers) (err er
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MapStorage) GetActionPlans(key string, skipCache bool) (ats ActionPlans, err error) {
|
||||
func (ms *MapStorage) GetActionPlan(key string, skipCache bool) (ats *ActionPlan, err error) {
|
||||
key = utils.ACTION_PLAN_PREFIX + key
|
||||
if !skipCache {
|
||||
if x, err := cache2go.Get(key); err == nil {
|
||||
return x.(ActionPlans), nil
|
||||
return x.(*ActionPlan), nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
@@ -663,8 +663,8 @@ func (ms *MapStorage) GetActionPlans(key string, skipCache bool) (ats ActionPlan
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MapStorage) SetActionPlans(key string, ats ActionPlans) (err error) {
|
||||
if len(ats) == 0 {
|
||||
func (ms *MapStorage) SetActionPlan(key string, ats *ActionPlan) (err error) {
|
||||
if len(ats.ActionTimings) == 0 {
|
||||
// delete the key
|
||||
delete(ms.dict, utils.ACTION_PLAN_PREFIX+key)
|
||||
cache2go.RemKey(utils.ACTION_PLAN_PREFIX + key)
|
||||
@@ -675,15 +675,15 @@ func (ms *MapStorage) SetActionPlans(key string, ats ActionPlans) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MapStorage) GetAllActionPlans() (ats map[string]ActionPlans, err error) {
|
||||
func (ms *MapStorage) GetAllActionPlans() (ats map[string]*ActionPlan, err error) {
|
||||
apls, err := cache2go.GetAllEntries(utils.ACTION_PLAN_PREFIX)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ats = make(map[string]ActionPlans, len(apls))
|
||||
ats = make(map[string]*ActionPlan, len(apls))
|
||||
for key, value := range apls {
|
||||
apl := value.(ActionPlans)
|
||||
apl := value.(*ActionPlan)
|
||||
ats[key] = apl
|
||||
}
|
||||
|
||||
@@ -774,7 +774,7 @@ func (ms *MapStorage) LogActionTrigger(ubId, source string, at *ActionTrigger, a
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MapStorage) LogActionPlan(source string, at *ActionPlan, as Actions) (err error) {
|
||||
func (ms *MapStorage) LogActionTiming(source string, at *ActionTiming, as Actions) (err error) {
|
||||
mat, err := ms.ms.Marshal(at)
|
||||
if err != nil {
|
||||
return
|
||||
|
||||
@@ -451,7 +451,7 @@ func (ms *MongoStorage) cacheRating(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, ac
|
||||
}
|
||||
for _, key := range aplKeys {
|
||||
cache2go.RemKey(key)
|
||||
if _, err = ms.GetActionPlans(key[len(utils.ACTION_PLAN_PREFIX):], true); err != nil {
|
||||
if _, err = ms.GetActionPlan(key[len(utils.ACTION_PLAN_PREFIX):], true); err != nil {
|
||||
cache2go.RollbackTransaction()
|
||||
return err
|
||||
}
|
||||
@@ -1026,17 +1026,17 @@ func (ms *MongoStorage) SetActionTriggers(key string, atrs ActionTriggers) (err
|
||||
return err
|
||||
}
|
||||
|
||||
func (ms *MongoStorage) GetActionPlans(key string, skipCache bool) (ats ActionPlans, err error) {
|
||||
func (ms *MongoStorage) GetActionPlan(key string, skipCache bool) (ats *ActionPlan, err error) {
|
||||
if !skipCache {
|
||||
if x, err := cache2go.Get(utils.ACTION_PLAN_PREFIX + key); err == nil {
|
||||
return x.(ActionPlans), nil
|
||||
return x.(*ActionPlan), nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
var kv struct {
|
||||
Key string
|
||||
Value ActionPlans
|
||||
Value *ActionPlan
|
||||
}
|
||||
err = ms.db.C(colApl).Find(bson.M{"key": key}).One(&kv)
|
||||
if err == nil {
|
||||
@@ -1046,8 +1046,8 @@ func (ms *MongoStorage) GetActionPlans(key string, skipCache bool) (ats ActionPl
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MongoStorage) SetActionPlans(key string, ats ActionPlans) error {
|
||||
if len(ats) == 0 {
|
||||
func (ms *MongoStorage) SetActionPlan(key string, ats *ActionPlan) error {
|
||||
if len(ats.ActionTimings) == 0 {
|
||||
cache2go.RemKey(utils.ACTION_PLAN_PREFIX + key)
|
||||
err := ms.db.C(colApl).Remove(bson.M{"key": key})
|
||||
if err != mgo.ErrNotFound {
|
||||
@@ -1057,20 +1057,20 @@ func (ms *MongoStorage) SetActionPlans(key string, ats ActionPlans) error {
|
||||
}
|
||||
_, err := ms.db.C(colApl).Upsert(bson.M{"key": key}, &struct {
|
||||
Key string
|
||||
Value ActionPlans
|
||||
Value *ActionPlan
|
||||
}{Key: key, Value: ats})
|
||||
return err
|
||||
}
|
||||
|
||||
func (ms *MongoStorage) GetAllActionPlans() (ats map[string]ActionPlans, err error) {
|
||||
func (ms *MongoStorage) GetAllActionPlans() (ats map[string]*ActionPlan, err error) {
|
||||
apls, err := cache2go.GetAllEntries(utils.ACTION_PLAN_PREFIX)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ats = make(map[string]ActionPlans, len(apls))
|
||||
ats = make(map[string]*ActionPlan, len(apls))
|
||||
for key, value := range apls {
|
||||
apl := value.(ActionPlans)
|
||||
apl := value.(*ActionPlan)
|
||||
ats[key] = apl
|
||||
}
|
||||
|
||||
|
||||
@@ -689,9 +689,9 @@ func (ms *MongoStorage) LogActionTrigger(ubId, source string, at *ActionTrigger,
|
||||
}{ubId, at, as, time.Now(), source})
|
||||
}
|
||||
|
||||
func (ms *MongoStorage) LogActionPlan(source string, at *ActionPlan, as Actions) (err error) {
|
||||
func (ms *MongoStorage) LogActionTiming(source string, at *ActionTiming, as Actions) (err error) {
|
||||
return ms.db.C(colLogApl).Insert(&struct {
|
||||
ActionPlan *ActionPlan
|
||||
ActionPlan *ActionTiming
|
||||
Actions Actions
|
||||
LogTime time.Time
|
||||
Source string
|
||||
|
||||
@@ -282,7 +282,7 @@ func (rs *RedisStorage) cacheRating(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, ac
|
||||
}
|
||||
for _, key := range aplKeys {
|
||||
cache2go.RemKey(key)
|
||||
if _, err = rs.GetActionPlans(key[len(utils.ACTION_PLAN_PREFIX):], true); err != nil {
|
||||
if _, err = rs.GetActionPlan(key[len(utils.ACTION_PLAN_PREFIX):], true); err != nil {
|
||||
cache2go.RollbackTransaction()
|
||||
return err
|
||||
}
|
||||
@@ -893,11 +893,11 @@ func (rs *RedisStorage) SetActionTriggers(key string, atrs ActionTriggers) (err
|
||||
return conn.Cmd("SET", utils.ACTION_TRIGGER_PREFIX+key, result).Err
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) GetActionPlans(key string, skipCache bool) (ats ActionPlans, err error) {
|
||||
func (rs *RedisStorage) GetActionPlan(key string, skipCache bool) (ats *ActionPlan, err error) {
|
||||
key = utils.ACTION_PLAN_PREFIX + key
|
||||
if !skipCache {
|
||||
if x, err := cache2go.Get(key); err == nil {
|
||||
return x.(ActionPlans), nil
|
||||
return x.(*ActionPlan), nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
@@ -911,8 +911,8 @@ func (rs *RedisStorage) GetActionPlans(key string, skipCache bool) (ats ActionPl
|
||||
return
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) SetActionPlans(key string, ats ActionPlans) (err error) {
|
||||
if len(ats) == 0 {
|
||||
func (rs *RedisStorage) SetActionPlan(key string, ats *ActionPlan) (err error) {
|
||||
if len(ats.ActionTimings) == 0 {
|
||||
// delete the key
|
||||
err = rs.db.Cmd("DEL", utils.ACTION_PLAN_PREFIX+key).Err
|
||||
cache2go.RemKey(utils.ACTION_PLAN_PREFIX + key)
|
||||
@@ -925,15 +925,15 @@ func (rs *RedisStorage) SetActionPlans(key string, ats ActionPlans) (err error)
|
||||
return rs.db.Cmd("SET", utils.ACTION_PLAN_PREFIX+key, result).Err
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) GetAllActionPlans() (ats map[string]ActionPlans, err error) {
|
||||
func (rs *RedisStorage) GetAllActionPlans() (ats map[string]*ActionPlan, err error) {
|
||||
apls, err := cache2go.GetAllEntries(utils.ACTION_PLAN_PREFIX)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ats = make(map[string]ActionPlans, len(apls))
|
||||
ats = make(map[string]*ActionPlan, len(apls))
|
||||
for key, value := range apls {
|
||||
apl := value.(ActionPlans)
|
||||
apl := value.(*ActionPlan)
|
||||
ats[key] = apl
|
||||
}
|
||||
|
||||
|
||||
@@ -592,7 +592,7 @@ func (self *SQLStorage) GetCallCostLog(cgrid, source, runid string) (*CallCost,
|
||||
func (self *SQLStorage) LogActionTrigger(ubId, source string, at *ActionTrigger, as Actions) (err error) {
|
||||
return
|
||||
}
|
||||
func (self *SQLStorage) LogActionPlan(source string, at *ActionPlan, as Actions) (err error) {
|
||||
func (self *SQLStorage) LogActionTiming(source string, at *ActionTiming, as Actions) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ type TpReader struct {
|
||||
accountingStorage AccountingStorage
|
||||
lr LoadReader
|
||||
actions map[string][]*Action
|
||||
actionPlans map[string][]*ActionPlan
|
||||
actionPlans map[string]*ActionPlan
|
||||
actionsTriggers map[string]ActionTriggers
|
||||
accountActions map[string]*Account
|
||||
dirtyRpAliases []*TenantRatingSubject // used to clean aliases that might have changed
|
||||
@@ -73,7 +73,7 @@ func NewTpReader(rs RatingStorage, as AccountingStorage, lr LoadReader, tpid, ti
|
||||
|
||||
func (tpr *TpReader) Init() {
|
||||
tpr.actions = make(map[string][]*Action)
|
||||
tpr.actionPlans = make(map[string][]*ActionPlan)
|
||||
tpr.actionPlans = make(map[string]*ActionPlan)
|
||||
tpr.actionsTriggers = make(map[string]ActionTriggers)
|
||||
tpr.rates = make(map[string]*utils.TPRate)
|
||||
tpr.destinations = make(map[string]*Destination)
|
||||
@@ -575,9 +575,14 @@ func (tpr *TpReader) LoadActionPlans() (err error) {
|
||||
if !exists {
|
||||
return fmt.Errorf("[ActionPlans] Could not load the timing for tag: %v", at.TimingId)
|
||||
}
|
||||
actPln := &ActionPlan{
|
||||
Uuid: utils.GenUUID(),
|
||||
Id: atId,
|
||||
var actPln *ActionPlan
|
||||
if actPln, exists = tpr.actionPlans[atId]; !exists {
|
||||
actPln = &ActionPlan{
|
||||
Uuid: utils.GenUUID(),
|
||||
Id: atId,
|
||||
}
|
||||
}
|
||||
actPln.ActionTimings = append(actPln.ActionTimings, &ActionTiming{
|
||||
Weight: at.Weight,
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
@@ -589,8 +594,9 @@ func (tpr *TpReader) LoadActionPlans() (err error) {
|
||||
},
|
||||
},
|
||||
ActionsId: at.ActionsId,
|
||||
}
|
||||
tpr.actionPlans[atId] = append(tpr.actionPlans[atId], actPln)
|
||||
})
|
||||
|
||||
tpr.actionPlans[atId] = actPln
|
||||
}
|
||||
}
|
||||
|
||||
@@ -660,11 +666,10 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error
|
||||
// action timings
|
||||
if accountAction.ActionPlanId != "" {
|
||||
// get old userBalanceIds
|
||||
var exitingAccountIds []string
|
||||
existingActionPlans, err := tpr.ratingStorage.GetActionPlans(accountAction.ActionPlanId, true)
|
||||
if err == nil && len(existingActionPlans) > 0 {
|
||||
// all action timings from a specific tag shuld have the same list of user balances from the first one
|
||||
exitingAccountIds = existingActionPlans[0].AccountIds
|
||||
var exitingAccountIds map[string]struct{}
|
||||
existingActionPlan, err := tpr.ratingStorage.GetActionPlan(accountAction.ActionPlanId, true)
|
||||
if err == nil && existingActionPlan != nil {
|
||||
exitingAccountIds = existingActionPlan.AccountIDs
|
||||
}
|
||||
|
||||
tpap, err := tpr.lr.GetTpActionPlans(tpr.tpid, accountAction.ActionPlanId)
|
||||
@@ -677,7 +682,7 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var actionTimings []*ActionPlan
|
||||
var actionPlan *ActionPlan
|
||||
ats := aps[accountAction.ActionPlanId]
|
||||
for _, at := range ats {
|
||||
// Check action exists before saving it inside actionTiming key
|
||||
@@ -703,9 +708,13 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error
|
||||
} else {
|
||||
t = tpr.timings[at.TimingId] // *asap
|
||||
}
|
||||
actPln := &ActionPlan{
|
||||
Uuid: utils.GenUUID(),
|
||||
Id: accountAction.ActionPlanId,
|
||||
if actionPlan == nil {
|
||||
actionPlan = &ActionPlan{
|
||||
Uuid: utils.GenUUID(),
|
||||
Id: accountAction.ActionPlanId,
|
||||
}
|
||||
}
|
||||
actionPlan.ActionTimings = append(actionPlan.ActionTimings, &ActionTiming{
|
||||
Weight: at.Weight,
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
@@ -716,25 +725,15 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error
|
||||
},
|
||||
},
|
||||
ActionsId: at.ActionsId,
|
||||
}
|
||||
})
|
||||
// collect action ids from timings
|
||||
actionsIds = append(actionsIds, actPln.ActionsId)
|
||||
//add user balance id if no already in
|
||||
found := false
|
||||
for _, ubId := range exitingAccountIds {
|
||||
if ubId == id {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
actPln.AccountIds = append(exitingAccountIds, id)
|
||||
}
|
||||
actionTimings = append(actionTimings, actPln)
|
||||
actionsIds = append(actionsIds, at.ActionsId)
|
||||
exitingAccountIds[id] = struct{}{}
|
||||
actionPlan.AccountIDs = exitingAccountIds
|
||||
}
|
||||
|
||||
// write action triggers
|
||||
err = tpr.ratingStorage.SetActionPlans(accountAction.ActionPlanId, actionTimings)
|
||||
// write action plan
|
||||
err = tpr.ratingStorage.SetActionPlan(accountAction.ActionPlanId, actionPlan)
|
||||
if err != nil {
|
||||
return errors.New(err.Error() + " (SetActionPlan): " + accountAction.ActionPlanId)
|
||||
}
|
||||
@@ -883,14 +882,15 @@ func (tpr *TpReader) LoadAccountActions() (err error) {
|
||||
}
|
||||
ub.InitCounters()
|
||||
tpr.accountActions[aa.KeyId()] = ub
|
||||
aTimings, exists := tpr.actionPlans[aa.ActionPlanId]
|
||||
actionPlan, exists := tpr.actionPlans[aa.ActionPlanId]
|
||||
if !exists {
|
||||
log.Printf("could not get action plan for tag %v", aa.ActionPlanId)
|
||||
// must not continue here
|
||||
}
|
||||
for _, at := range aTimings {
|
||||
at.AccountIds = append(at.AccountIds, aa.KeyId())
|
||||
if actionPlan.AccountIDs == nil {
|
||||
actionPlan.AccountIDs = make(map[string]struct{})
|
||||
}
|
||||
actionPlan.AccountIDs[aa.KeyId()] = struct{}{}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1319,7 +1319,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose bool) (err error) {
|
||||
log.Print("Action Plans:")
|
||||
}
|
||||
for k, ats := range tpr.actionPlans {
|
||||
err = tpr.ratingStorage.SetActionPlans(k, ats)
|
||||
err = tpr.ratingStorage.SetActionPlan(k, ats)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user