diff --git a/apier/v1/accounts_it_test.go b/apier/v1/accounts_it_test.go index dfacfb3ea..e40beeebe 100644 --- a/apier/v1/accounts_it_test.go +++ b/apier/v1/accounts_it_test.go @@ -64,6 +64,7 @@ var ( testAccITTPFromFolder, testAccITAddBalanceWithDestinations, testAccITAccountWithTriggers, + testAccITAccountMonthlyEstimated, testAccITStopCgrEngine, } ) @@ -928,3 +929,74 @@ func testAccITAccountWithTriggers(t *testing.T) { } } + +func testAccITAccountMonthlyEstimated(t *testing.T) { + var reply string + // add an action that contains topup + topupAction := &utils.AttrSetActions{ActionsId: "TOPUP_ACTION", Actions: []*utils.TPAction{ + {Identifier: utils.TOPUP_RESET, BalanceId: "testAccITAccountMonthlyEstimated", + BalanceType: utils.MONETARY, Units: "5", Weight: 10.0}, + }} + + if err := accRPC.Call(utils.APIerSv2SetActions, topupAction, &reply); err != nil { + t.Error("Got error on APIerSv2.SetActions: ", err.Error()) + } else if reply != utils.OK { + t.Errorf("Calling APIerSv2.SetActions received: %s", reply) + } + + atms1 := &AttrSetActionPlan{ + Id: "ATMS_1", + ReloadScheduler: true, + ActionPlan: []*AttrActionPlan{ + &AttrActionPlan{ActionsId: "TOPUP_ACTION", + MonthDays: "31", + Time: "00:00:00", + Weight: 20.0, + TimingID: utils.MetaMonthlyEstimated}, + }, + } + if err := accRPC.Call(utils.APIerSv1SetActionPlan, &atms1, &reply); err != nil { + t.Error("Got error on APIerSv1.SetActionPlan: ", err.Error()) + } else if reply != utils.OK { + t.Errorf("Calling APIerSv1.SetActionPlan received: %s", reply) + } + + acnt1 := utils.AttrSetAccount{Tenant: "cgrates.org", + Account: "testAccITAccountMonthlyEstimated", + ReloadScheduler: true, + ActionPlanID: "ATMS_1", + } + if err := accRPC.Call(utils.APIerSv1SetAccount, acnt1, &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Errorf("Calling APIerSv1.SetAccount received: %s", reply) + } + + var aps []*engine.ActionPlan + accIDsStrMp := utils.StringMap{ + "cgrates.org:testAccITAccountMonthlyEstimated": true, + } + eTiming := &engine.RITiming{ + ID: utils.MetaMonthlyEstimated, + Years: utils.Years{}, + Months: utils.Months{}, + MonthDays: utils.MonthDays{31}, + WeekDays: utils.WeekDays{}, + StartTime: "00:00:00", + EndTime: "", + } + if err := accRPC.Call(utils.APIerSv1GetActionPlan, + &AttrGetActionPlan{ID: "ATMS_1"}, &aps); err != nil { + t.Error(err) + } else if len(aps) != 1 { + t.Errorf("Expected: %v,\n received: %v", 1, len(aps)) + } else if aps[0].Id != "ATMS_1" { + t.Errorf("Expected: %v,\n received: %v", "AP_PACKAGE_10", aps[0].Id) + } else if !reflect.DeepEqual(aps[0].AccountIDs, accIDsStrMp) { + t.Errorf("Expected: %v,\n received: %v", accIDsStrMp, aps[0].AccountIDs) + } else if len(aps[0].ActionTimings) != 1 { + t.Errorf("Expected: %v,\n received: %v", 1, len(aps)) + } else if !reflect.DeepEqual(aps[0].ActionTimings[0].Timing.Timing, eTiming) { + t.Errorf("Expected: %v,\n received: %v", utils.ToJSON(eTiming), utils.ToJSON(aps[0].ActionTimings[0].Timing.Timing)) + } +} diff --git a/engine/action_plan.go b/engine/action_plan.go index eadd69159..157b23ba9 100644 --- a/engine/action_plan.go +++ b/engine/action_plan.go @@ -128,9 +128,9 @@ func (at *ActionTiming) GetNextStartTime(t1 time.Time) (t time.Time) { i.Timing.MonthDays = append(i.Timing.MonthDays, 1) } at.stCache = cronexpr.MustParse(i.Timing.CronString()).Next(t1) - if i.Timing.ID == utils.MetaMonthlyEstimated && at.stCache.Month() != t1.Month()+1 { + if i.Timing.ID == utils.MetaMonthlyEstimated && at.stCache.Month() > t1.Month()+1 { clnRITiming := i.Timing.Clone() - for at.stCache.Month() != t1.Month()+1 { + for at.stCache.Month() > t1.Month()+1 { clnRITiming.MonthDays[0]-- at.stCache = cronexpr.MustParse(clnRITiming.CronString()).Next(t1) }