mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
balance activation times
This commit is contained in:
@@ -10,7 +10,7 @@ CREATE TABLE `tp_timings` (
|
||||
`months` varchar(255) NOT NULL,
|
||||
`month_days` varchar(255) NOT NULL,
|
||||
`week_days` varchar(255) NOT NULL,
|
||||
`time` varchar(16) NOT NULL,
|
||||
`time` varchar(32) NOT NULL,
|
||||
`created_at` TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `tpid` (`tpid`),
|
||||
@@ -150,7 +150,8 @@ CREATE TABLE `tp_actions` (
|
||||
`direction` varchar(8) NOT NULL,
|
||||
`units` DECIMAL(20,4) NOT NULL,
|
||||
`expiry_time` varchar(24) NOT NULL,
|
||||
`destination_tag` varchar(64) NOT NULL,
|
||||
`timing_tags` varchar(128) NOT NULL,
|
||||
`balance_destination_tag` varchar(64) NOT NULL,
|
||||
`rating_subject` varchar(64) NOT NULL,
|
||||
`category` varchar(16) NOT NULL,
|
||||
`shared_group` varchar(64) NOT NULL,
|
||||
@@ -160,7 +161,7 @@ CREATE TABLE `tp_actions` (
|
||||
`created_at` TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `tpid` (`tpid`),
|
||||
UNIQUE KEY `unique_action` (`tpid`,`tag`,`action`,`balance_tag`,`balance_type`,`direction`,`expiry_time`,`destination_tag`,`shared_group`,`balance_weight`,`weight`)
|
||||
UNIQUE KEY `unique_action` (`tpid`,`tag`,`action`,`balance_tag`,`balance_type`,`direction`,`expiry_time`,`timing_tags`,`destination_tag`,`shared_group`,`balance_weight`,`weight`)
|
||||
);
|
||||
|
||||
--
|
||||
@@ -199,7 +200,8 @@ CREATE TABLE `tp_action_triggers` (
|
||||
`min_sleep` BIGINT NOT NULL,
|
||||
`balance_destination_tag` varchar(64) NOT NULL,
|
||||
`balance_weight` DECIMAL(8,2) NOT NULL,
|
||||
`balance_expiry_time` varchar(24) NOT NULL,
|
||||
`balance_expiry_time` varchar(24) NOT NULL,
|
||||
`balance_timing_tags` varchar(128) NOT NULL,
|
||||
`balance_rating_subject` varchar(64) NOT NULL,
|
||||
`balance_category` varchar(16) NOT NULL,
|
||||
`balance_shared_group` varchar(64) NOT NULL,
|
||||
|
||||
@@ -10,7 +10,7 @@ CREATE TABLE tp_timings (
|
||||
months VARCHAR(255) NOT NULL,
|
||||
month_days VARCHAR(255) NOT NULL,
|
||||
week_days VARCHAR(255) NOT NULL,
|
||||
time VARCHAR(16) NOT NULL,
|
||||
time VARCHAR(32) NOT NULL,
|
||||
created_at TIMESTAMP,
|
||||
UNIQUE (tpid, tag)
|
||||
);
|
||||
@@ -131,6 +131,7 @@ CREATE TABLE tp_actions (
|
||||
direction VARCHAR(8) NOT NULL,
|
||||
units NUMERIC(20,4) NOT NULL,
|
||||
expiry_time VARCHAR(24) NOT NULL,
|
||||
timing_tags VARCHAR(128) NOT NULL,
|
||||
destination_tag VARCHAR(64) NOT NULL,
|
||||
rating_subject VARCHAR(64) NOT NULL,
|
||||
category VARCHAR(16) NOT NULL,
|
||||
@@ -139,7 +140,7 @@ CREATE TABLE tp_actions (
|
||||
extra_parameters VARCHAR(256) NOT NULL,
|
||||
weight NUMERIC(8,2) NOT NULL,
|
||||
created_at TIMESTAMP,
|
||||
UNIQUE (tpid, tag, action, balance_tag, balance_type, direction, expiry_time, destination_tag, shared_group, balance_weight, weight)
|
||||
UNIQUE (tpid, tag, action, balance_tag, balance_type, direction, expiry_time, timing_tags, destination_tag, shared_group, balance_weight, weight)
|
||||
);
|
||||
|
||||
--
|
||||
@@ -176,7 +177,8 @@ CREATE TABLE tp_action_triggers (
|
||||
min_sleep BIGINT NOT NULL,
|
||||
balance_destination_tag VARCHAR(64) NOT NULL,
|
||||
balance_weight NUMERIC(8,2) NOT NULL,
|
||||
balance_expiry_time VARCHAR(24) NOT NULL,
|
||||
balance_expiry_time VARCHAR(24) NOT NULL,
|
||||
balance_timing_tags VARCHAR(128) NOT NULL,
|
||||
balance_rating_subject VARCHAR(64) NOT NULL,
|
||||
balance_category VARCHAR(16) NOT NULL,
|
||||
balance_shared_group VARCHAR(64) NOT NULL,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#Tag[0],ThresholdType[1],ThresholdValue[2],Recurrent[3],MinSleep[4],BalanceTag[5],BalanceType[6],BalanceDirection[7],BalanceCategory[8],BalanceDestinationTag[9],BalanceRatingSubject[10],BalanceSharedGroup[11],BalanceExpiryTime[12],BalanceWeight[13],StatsMinQueuedItems[14],ActionsTag[15],Weight[16]
|
||||
CDRST3_WARN_ASR,*min_asr,45,true,1h,,,,,,,,,,3,CDRST_LOG,10
|
||||
CDRST3_WARN_ACD,*min_acd,10,true,1h,,,,,,,,,,5,CDRST_LOG,10
|
||||
CDRST3_WARN_ACC,*max_acc,10,true,10m,,,,,,,,,,5,CDRST_LOG,10
|
||||
CDRST4_WARN_ASR,*min_asr,30,true,0,,,,,,,,,,5,CDRST_LOG,10
|
||||
CDRST4_WARN_ACD,*min_acd,3,true,0,,,,,,,,,,2,CDRST_LOG,10
|
||||
#Tag[0],ThresholdType[1],ThresholdValue[2],Recurrent[3],MinSleep[4],BalanceTag[5],BalanceType[6],BalanceDirection[7],BalanceCategory[8],BalanceDestinationTag[9],BalanceRatingSubject[10],BalanceSharedGroup[11],BalanceExpiryTime[12],BalanceTimingTags[13],BalanceWeight[14],StatsMinQueuedItems[15],ActionsTag[16],Weight[17]
|
||||
CDRST3_WARN_ASR,*min_asr,45,true,1h,,,,,,,,,,,3,CDRST_LOG,10
|
||||
CDRST3_WARN_ACD,*min_acd,10,true,1h,,,,,,,,,,,5,CDRST_LOG,10
|
||||
CDRST3_WARN_ACC,*max_acc,10,true,10m,,,,,,,,,,,5,CDRST_LOG,10
|
||||
CDRST4_WARN_ASR,*min_asr,30,true,0,,,,,,,,,,,5,CDRST_LOG,10
|
||||
CDRST4_WARN_ACD,*min_acd,3,true,0,,,,,,,,,,,2,CDRST_LOG,10
|
||||
|
||||
|
@@ -1,2 +1,2 @@
|
||||
#ActionsTag,Action,BalanceTag,BalanceType,Direction,Units,ExpiryTime,DestinationTag,RatingSubject,Category,BalanceWeight,SharedGroup,ExtraParameters,Weight
|
||||
CDRST_LOG,*log,,,,,,,,,,,,10
|
||||
#ActionsTag,Action,BalanceTag,BalanceType,Direction,Units,ExpiryTime,TimingTags,DestinationTag,RatingSubject,Category,BalanceWeight,SharedGroup,ExtraParameters,Weight
|
||||
CDRST_LOG,*log,,,,,,,,,,,,,10
|
||||
|
||||
|
@@ -1,9 +1,9 @@
|
||||
#Tag[0],ThresholdType[1],ThresholdValue[2],Recurrent[3],MinSleep[4],BalanceTag[5],BalanceType[6],BalanceDirection[7],BalanceCategory[8],BalanceDestinationTag[9],BalanceRatingSubject[10],BalanceSharedGroup[11],BalanceExpiryTime[12],BalanceWeight[13],StatsMinQueuedItems[14],ActionsTag[15],Weight[16]
|
||||
STANDARD_TRIGGERS,*min_balance,2,false,0,,*monetary,*out,,,,,,,,LOG_BALANCE,10
|
||||
STANDARD_TRIGGERS,*max_balance,20,false,0,,*monetary,*out,,,,,,,,LOG_BALANCE,10
|
||||
STANDARD_TRIGGERS,*max_counter,15,false,0,,*monetary,*out,,FS_USERS,,,,,,LOG_BALANCE,10
|
||||
CDRST1_WARN_ASR,*min_asr,45,true,1h,,,,,,,,,,3,CDRST_WARN_HTTP,10
|
||||
CDRST1_WARN_ACD,*min_acd,10,true,1h,,,,,,,,,,5,CDRST_WARN_HTTP,10
|
||||
CDRST1_WARN_ACC,*max_acc,10,true,10m,,,,,,,,,,5,CDRST_WARN_HTTP,10
|
||||
CDRST2_WARN_ASR,*min_asr,30,true,0,,,,,,,,,,5,CDRST_WARN_HTTP,10
|
||||
CDRST2_WARN_ACD,*min_acd,3,true,0,,,,,,,,,,2,CDRST_LOG,10
|
||||
#Tag[0],ThresholdType[1],ThresholdValue[2],Recurrent[3],MinSleep[4],BalanceTag[5],BalanceType[6],BalanceDirection[7],BalanceCategory[8],BalanceDestinationTag[9],BalanceRatingSubject[10],BalanceSharedGroup[11],BalanceExpiryTime[12],BalanceTimingTags[13],BalanceWeight[14],StatsMinQueuedItems[15],ActionsTag[16],Weight[17]
|
||||
STANDARD_TRIGGERS,*min_balance,2,false,0,,*monetary,*out,,,,,,,,,LOG_BALANCE,10
|
||||
STANDARD_TRIGGERS,*max_balance,20,false,0,,*monetary,*out,,,,,,,,,LOG_BALANCE,10
|
||||
STANDARD_TRIGGERS,*max_counter,15,false,0,,*monetary,*out,,FS_USERS,,,,,,,LOG_BALANCE,10
|
||||
CDRST1_WARN_ASR,*min_asr,45,true,1h,,,,,,,,,,,3,CDRST_WARN_HTTP,10
|
||||
CDRST1_WARN_ACD,*min_acd,10,true,1h,,,,,,,,,,,5,CDRST_WARN_HTTP,10
|
||||
CDRST1_WARN_ACC,*max_acc,10,true,10m,,,,,,,,,,,5,CDRST_WARN_HTTP,10
|
||||
CDRST2_WARN_ASR,*min_asr,30,true,0,,,,,,,,,,,5,CDRST_WARN_HTTP,10
|
||||
CDRST2_WARN_ACD,*min_acd,3,true,0,,,,,,,,,,,2,CDRST_LOG,10
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#ActionsTag[0],Action[1],ActionExtraParameters[2],BalanceTag[3],BalanceType[4],Direction[5],Category[6],DestinationTag[7],RatingSubject[8],SharedGroup[9],ExpiryTime[10],Units[11],BalanceWeight[12],Weight[13]
|
||||
PREPAID_10,*topup_reset,,,*monetary,*out,,*any,,,*unlimited,10,10,10
|
||||
BONUS_1,*topup,,,*monetary,*out,,*any,,,*unlimited,1,10,10
|
||||
LOG_BALANCE,*log,,,,,,,,,,,,10
|
||||
CDRST_WARN_HTTP,*call_url,http://localhost:8080,,,,,,,,,,,10
|
||||
CDRST_LOG,*log,,,,,,,,,,,,10
|
||||
#ActionsTag[0],Action[1],ActionExtraParameters[2],BalanceTag[3],BalanceType[4],Direction[5],Category[6],DestinationTag[7],RatingSubject[8],SharedGroup[9],ExpiryTime[10],TimingTags[11],Units[12],BalanceWeight[13],Weight[14]
|
||||
PREPAID_10,*topup_reset,,,*monetary,*out,,*any,,,*unlimited,,10,10,10
|
||||
BONUS_1,*topup,,,*monetary,*out,,*any,,,*unlimited,,1,10,10
|
||||
LOG_BALANCE,*log,,,,,,,,,,,,,10
|
||||
CDRST_WARN_HTTP,*call_url,http://localhost:8080,,,,,,,,,,,,10
|
||||
CDRST_LOG,*log,,,,,,,,,,,,,10
|
||||
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#Tag[0],ThresholdType[1],ThresholdValue[2],Recurrent[3],MinSleep[4],BalanceTag[5],BalanceType[6],BalanceDirection[7],BalanceCategory[8],BalanceDestinationTag[9],BalanceRatingSubject[10],BalanceSharedGroup[11],BalanceExpiryTime[12],BalanceWeight[13],StatsMinQueuedItems[14],ActionsTag[15],Weight[16]
|
||||
STANDARD_TRIGGERS,*min_balance,2,false,0,,*monetary,*out,,,,,,,,LOG_WARNING,10
|
||||
STANDARD_TRIGGERS,*max_counter,5,false,0,,*monetary,*out,,FS_USERS,,,,,,LOG_WARNING,10
|
||||
STANDARD_TRIGGERS,*max_balance,20,false,0,,*monetary,*out,,,,,,,,LOG_WARNING,10
|
||||
STANDARD_TRIGGERS,*max_balance,100,false,0,,*monetary,*out,,,,,,,,DISABLE_AND_LOG,10
|
||||
CDRST1_WARN,*min_asr,45,true,1m,,,,,,,,,,3,LOG_WARNING,10
|
||||
CDRST1_WARN,*min_acd,10,true,1m,,,,,,,,,,5,LOG_WARNING,10
|
||||
CDRST1_WARN,*max_acc,10,true,1m,,,,,,,,,,5,LOG_WARNING,10
|
||||
CDRST1001_WARN,*min_asr,65,true,1m,,,,,,,,,,3,LOG_WARNING,10
|
||||
CDRST1001_WARN,*min_acd,10,true,1m,,,,,,,,,,5,LOG_WARNING,10
|
||||
CDRST1001_WARN,*max_acc,5,true,1m,,,,,,,,,,5,LOG_WARNING,10
|
||||
CDRST3_WARN,*min_acd,60,false,1m,,,,,,,,,,5,LOG_WARNING,10
|
||||
#Tag[0],ThresholdType[1],ThresholdValue[2],Recurrent[3],MinSleep[4],BalanceTag[5],BalanceType[6],BalanceDirection[7],BalanceCategory[8],BalanceDestinationTag[9],BalanceRatingSubject[10],BalanceSharedGroup[11],BalanceExpiryTime[12],BalanceTimingTags[13],BalanceWeight[14],StatsMinQueuedItems[15],ActionsTag[16],Weight[17]
|
||||
STANDARD_TRIGGERS,*min_balance,2,false,0,,*monetary,*out,,,,,,,,,LOG_WARNING,10
|
||||
STANDARD_TRIGGERS,*max_counter,5,false,0,,*monetary,*out,,FS_USERS,,,,,,,LOG_WARNING,10
|
||||
STANDARD_TRIGGERS,*max_balance,20,false,0,,*monetary,*out,,,,,,,,,LOG_WARNING,10
|
||||
STANDARD_TRIGGERS,*max_balance,100,false,0,,*monetary,*out,,,,,,,,,DISABLE_AND_LOG,10
|
||||
CDRST1_WARN,*min_asr,45,true,1m,,,,,,,,,,,3,LOG_WARNING,10
|
||||
CDRST1_WARN,*min_acd,10,true,1m,,,,,,,,,,,5,LOG_WARNING,10
|
||||
CDRST1_WARN,*max_acc,10,true,1m,,,,,,,,,,,5,LOG_WARNING,10
|
||||
CDRST1001_WARN,*min_asr,65,true,1m,,,,,,,,,,,3,LOG_WARNING,10
|
||||
CDRST1001_WARN,*min_acd,10,true,1m,,,,,,,,,,,5,LOG_WARNING,10
|
||||
CDRST1001_WARN,*max_acc,5,true,1m,,,,,,,,,,,5,LOG_WARNING,10
|
||||
CDRST3_WARN,*min_acd,60,false,1m,,,,,,,,,,,5,LOG_WARNING,10
|
||||
|
||||
|
@@ -1,9 +1,9 @@
|
||||
#ActionsTag[0],Action[1],ExtraParameters[2],BalanceTag[3],BalanceType[4],Direction[5],Category[6],DestinationTag[7],RatingSubject[8],SharedGroup[9],ExpiryTime[10],Units[11],BalanceWeight[12],Weight[13]
|
||||
TOPUP_RST_10,*topup_reset,,,*monetary,*out,,*any,,,*unlimited,10,10,10
|
||||
TOPUP_RST_5,*topup_reset,,,*monetary,*out,,*any,,,*unlimited,5,20,10
|
||||
TOPUP_RST_5,*topup_reset,,,*voice,*out,,DST_1002,SPECIAL_1002,,*unlimited,90,20,10
|
||||
TOPUP_RST_SHARED_5,*topup,,,*monetary,*out,,*any,,SHARED_A,*unlimited,5,10,10
|
||||
SHARED_A_0,*topup_reset,,,*monetary,*out,,*any,,SHARED_A,*unlimited,0,10,10
|
||||
LOG_WARNING,*log,,,,,,,,,,,,10
|
||||
DISABLE_AND_LOG,*log,,,,,,,,,,,,10
|
||||
DISABLE_AND_LOG,*disable_account,,,,,,,,,,,,10
|
||||
#ActionsTag[0],Action[1],ExtraParameters[2],BalanceTag[3],BalanceType[4],Direction[5],Category[6],DestinationTag[7],RatingSubject[8],SharedGroup[9],ExpiryTime[10],TimingTags[11],Units[12],BalanceWeight[13],Weight[14]
|
||||
TOPUP_RST_10,*topup_reset,,,*monetary,*out,,*any,,,*unlimited,,10,10,10
|
||||
TOPUP_RST_5,*topup_reset,,,*monetary,*out,,*any,,,*unlimited,,5,20,10
|
||||
TOPUP_RST_5,*topup_reset,,,*voice,*out,,DST_1002,SPECIAL_1002,,*unlimited,,90,20,10
|
||||
TOPUP_RST_SHARED_5,*topup,,,*monetary,*out,,*any,,SHARED_A,*unlimited,,5,10,10
|
||||
SHARED_A_0,*topup_reset,,,*monetary,*out,,*any,,SHARED_A,*unlimited,,0,10,10
|
||||
LOG_WARNING,*log,,,,,,,,,,,,,10
|
||||
DISABLE_AND_LOG,*log,,,,,,,,,,,,,10
|
||||
DISABLE_AND_LOG,*disable_account,,,,,,,,,,,,,10
|
||||
|
||||
|
@@ -40,6 +40,7 @@ type ActionTrigger struct {
|
||||
BalanceDestinationId string // filter for balance
|
||||
BalanceWeight float64 // filter for balance
|
||||
BalanceExpirationDate time.Time // filter for balance
|
||||
BalanceTimingTags string // filter for balance
|
||||
BalanceRatingSubject string // filter for balance
|
||||
BalanceCategory string // filter for balance
|
||||
BalanceSharedGroup string // filter for balance
|
||||
|
||||
@@ -37,6 +37,8 @@ type Balance struct {
|
||||
RatingSubject string
|
||||
Category string
|
||||
SharedGroup string
|
||||
Timings []*RITiming
|
||||
TimingIDs string
|
||||
precision int
|
||||
account *Account // used to store ub reference for shared balances
|
||||
dirty bool
|
||||
@@ -89,6 +91,22 @@ func (b *Balance) IsExpired() bool {
|
||||
return !b.ExpirationDate.IsZero() && b.ExpirationDate.Before(time.Now())
|
||||
}
|
||||
|
||||
func (b *Balance) IsActive() bool {
|
||||
return b.IsActiveAt(time.Now())
|
||||
}
|
||||
|
||||
func (b *Balance) IsActiveAt(t time.Time) bool {
|
||||
if len(b.Timings) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, tim := range b.Timings {
|
||||
if tim.IsActiveAt(t, false) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *Balance) MatchCategory(category string) bool {
|
||||
return b.Category == "" || b.Category == category
|
||||
}
|
||||
@@ -223,10 +241,15 @@ func (b *Balance) DebitUnits(cc *CallCost, count bool, ub *Account, moneyBalance
|
||||
continue
|
||||
}
|
||||
tsWasSplit := false
|
||||
currentTime := ts.TimeStart
|
||||
for incrementIndex, increment := range ts.Increments {
|
||||
if tsWasSplit {
|
||||
break
|
||||
}
|
||||
currentTime = currentTime.Add(increment.Duration)
|
||||
if !b.IsActiveAt(currentTime) {
|
||||
continue
|
||||
}
|
||||
if increment.paid {
|
||||
continue
|
||||
}
|
||||
@@ -369,10 +392,15 @@ func (b *Balance) DebitMoney(cc *CallCost, count bool, ub *Account) error {
|
||||
continue
|
||||
}
|
||||
tsWasSplit := false
|
||||
currentTime := ts.TimeStart
|
||||
for incrementIndex, increment := range ts.Increments {
|
||||
if tsWasSplit {
|
||||
break
|
||||
}
|
||||
currentTime = currentTime.Add(increment.Duration)
|
||||
if !b.IsActiveAt(currentTime) {
|
||||
continue
|
||||
}
|
||||
if increment.paid {
|
||||
continue
|
||||
}
|
||||
@@ -472,7 +500,7 @@ func (bc BalanceChain) Sort() {
|
||||
|
||||
func (bc BalanceChain) GetTotalValue() (total float64) {
|
||||
for _, b := range bc {
|
||||
if !b.IsExpired() {
|
||||
if !b.IsExpired() && b.IsActive() {
|
||||
total += b.Value
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,38 @@ func TestBalanceEqual(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBalanceMatchFilter(t *testing.T) {
|
||||
mb1 := &Balance{Weight: 1, precision: 1, RatingSubject: "1", DestinationId: ""}
|
||||
mb2 := &Balance{Weight: 1, precision: 1, RatingSubject: "", DestinationId: ""}
|
||||
if !mb1.MatchFilter(mb2) {
|
||||
t.Error("Match filter failure: %+v == %+v", mb1, mb2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBalanceMatchFilterEmpty(t *testing.T) {
|
||||
mb1 := &Balance{Weight: 1, precision: 1, RatingSubject: "1", DestinationId: ""}
|
||||
mb2 := &Balance{}
|
||||
if !mb1.MatchFilter(mb2) {
|
||||
t.Error("Match filter failure: %+v == %+v", mb1, mb2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBalanceMatchFilterId(t *testing.T) {
|
||||
mb1 := &Balance{Id: "T1", Weight: 2, precision: 2, RatingSubject: "2", DestinationId: "NAT"}
|
||||
mb2 := &Balance{Id: "T1", Weight: 1, precision: 1, RatingSubject: "1", DestinationId: ""}
|
||||
if !mb1.MatchFilter(mb2) {
|
||||
t.Error("Match filter failure: %+v == %+v", mb1, mb2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBalanceMatchFilterDiffId(t *testing.T) {
|
||||
mb1 := &Balance{Id: "T1", Weight: 1, precision: 1, RatingSubject: "1", DestinationId: ""}
|
||||
mb2 := &Balance{Id: "T2", Weight: 1, precision: 1, RatingSubject: "1", DestinationId: ""}
|
||||
if mb1.MatchFilter(mb2) {
|
||||
t.Error("Match filter failure: %+v != %+v", mb1, mb2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBalanceClone(t *testing.T) {
|
||||
mb1 := &Balance{Value: 1, Weight: 2, RatingSubject: "test", DestinationId: "5"}
|
||||
mb2 := mb1.Clone()
|
||||
|
||||
@@ -522,7 +522,7 @@ func (csvr *CSVReader) LoadRatingProfiles() (err error) {
|
||||
return fmt.Errorf("Cannot parse activation time from %v", record[4])
|
||||
}
|
||||
// extract aliases from subject
|
||||
aliases := strings.Split(subject, ";")
|
||||
aliases := strings.Split(subject, utils.INFIELD_SEP)
|
||||
csvr.dirtyRpAliases = append(csvr.dirtyRpAliases, &TenantRatingSubject{Tenant: tenant, Subject: aliases[0]})
|
||||
if len(aliases) > 1 {
|
||||
subject = aliases[0]
|
||||
@@ -692,11 +692,30 @@ func (csvr *CSVReader) LoadActions() (err error) {
|
||||
Value: units,
|
||||
Weight: balanceWeight,
|
||||
DestinationId: record[ACTSCSVIDX_DESTINATION_TAG],
|
||||
TimingIDs: record[ACTSCSVIDX_TIMING_TAGS],
|
||||
RatingSubject: record[ACTSCSVIDX_RATING_SUBJECT],
|
||||
Category: record[ACTSCSVIDX_CATEGORY],
|
||||
SharedGroup: record[ACTSCSVIDX_SHARED_GROUP],
|
||||
},
|
||||
}
|
||||
// load action timings from tags
|
||||
if a.Balance.TimingIDs != "" {
|
||||
timingIds := strings.Split(a.Balance.TimingIDs, utils.INFIELD_SEP)
|
||||
for _, timingID := range timingIds {
|
||||
if timing, found := csvr.timings[timingID]; found {
|
||||
a.Balance.Timings = append(a.Balance.Timings, &RITiming{
|
||||
Years: timing.Years,
|
||||
Months: timing.Months,
|
||||
MonthDays: timing.MonthDays,
|
||||
WeekDays: timing.WeekDays,
|
||||
StartTime: timing.StartTime,
|
||||
EndTime: timing.EndTime,
|
||||
})
|
||||
} else {
|
||||
return fmt.Errorf("Could not find timing: %v", timingID)
|
||||
}
|
||||
}
|
||||
}
|
||||
if _, err := utils.ParseDate(a.ExpirationString); err != nil {
|
||||
return fmt.Errorf("Could not parse expiration time: %v", err)
|
||||
}
|
||||
@@ -807,6 +826,7 @@ func (csvr *CSVReader) LoadActionTriggers() (err error) {
|
||||
BalanceDestinationId: record[ATRIGCSVIDX_BAL_DESTINATION_TAG],
|
||||
BalanceWeight: balanceWeight,
|
||||
BalanceExpirationDate: balanceExp,
|
||||
BalanceTimingTags: record[ATRIGCSVIDX_BAL_TIMING_TAGS],
|
||||
BalanceRatingSubject: record[ATRIGCSVIDX_BAL_RATING_SUBJECT],
|
||||
BalanceCategory: record[ATRIGCSVIDX_BAL_CATEGORY],
|
||||
BalanceSharedGroup: record[ATRIGCSVIDX_BAL_SHARED_GROUP],
|
||||
@@ -832,7 +852,7 @@ func (csvr *CSVReader) LoadAccountActions() (err error) {
|
||||
for record, err := csvReader.Read(); err == nil; record, err = csvReader.Read() {
|
||||
tenant, account, direction := record[0], record[1], record[2]
|
||||
// extract aliases from subject
|
||||
aliases := strings.Split(account, ";")
|
||||
aliases := strings.Split(account, utils.INFIELD_SEP)
|
||||
csvr.dirtyAccAliases = append(csvr.dirtyAccAliases, &TenantAccount{Tenant: tenant, Account: aliases[0]})
|
||||
if len(aliases) > 1 {
|
||||
account = aliases[0]
|
||||
|
||||
@@ -140,16 +140,16 @@ SG3,*any,*lowest,
|
||||
`
|
||||
|
||||
actions = `
|
||||
MINI,*topup_reset,,,*monetary,*out,,,,,*unlimited,10,10,10
|
||||
MINI,*topup,,,*voice,*out,,NAT,test,,*unlimited,100,10,10
|
||||
SHARED,*topup,,,*monetary,*out,,,,SG1,*unlimited,100,10,10
|
||||
TOPUP10_AC,*topup_reset,,,*monetary,*out,,*any,,,*unlimited,1,10,10
|
||||
TOPUP10_AC1,*topup_reset,,,*voice,*out,,DST_UK_Mobile_BIG5,discounted_minutes,,*unlimited,40,10,10
|
||||
SE0,*topup_reset,,,*monetary,*out,,,,SG2,*unlimited,0,10,10
|
||||
SE10,*topup_reset,,,*monetary,*out,,,,SG2,*unlimited,10,5,10
|
||||
SE10,*topup,,,*monetary,*out,,,,,*unlimited,10,10,10
|
||||
EE0,*topup_reset,,,*monetary,*out,,,,SG3,*unlimited,0,10,10
|
||||
EE0,*allow_negative,,,*monetary,*out,,,,,*unlimited,0,10,10
|
||||
MINI,*topup_reset,,,*monetary,*out,,,,,*unlimited,,10,10,10
|
||||
MINI,*topup,,,*voice,*out,,NAT,test,,*unlimited,,100,10,10
|
||||
SHARED,*topup,,,*monetary,*out,,,,SG1,*unlimited,,100,10,10
|
||||
TOPUP10_AC,*topup_reset,,,*monetary,*out,,*any,,,*unlimited,,1,10,10
|
||||
TOPUP10_AC1,*topup_reset,,,*voice,*out,,DST_UK_Mobile_BIG5,discounted_minutes,,*unlimited,,40,10,10
|
||||
SE0,*topup_reset,,,*monetary,*out,,,,SG2,*unlimited,,0,10,10
|
||||
SE10,*topup_reset,,,*monetary,*out,,,,SG2,*unlimited,,10,5,10
|
||||
SE10,*topup,,,*monetary,*out,,,,,*unlimited,,10,10,10
|
||||
EE0,*topup_reset,,,*monetary,*out,,,,SG3,*unlimited,,0,10,10
|
||||
EE0,*allow_negative,,,*monetary,*out,,,,,*unlimited,,0,10,10
|
||||
`
|
||||
actionTimings = `
|
||||
MORE_MINUTES,MINI,ONE_TIME_RUN,10
|
||||
@@ -162,16 +162,16 @@ TOPUP_EMPTY_AT,EE0,ASAP,10
|
||||
`
|
||||
|
||||
actionTriggers = `
|
||||
STANDARD_TRIGGER,*min_counter,10,false,0,,*voice,*out,,GERMANY_O2,,,,,,SOME_1,10
|
||||
STANDARD_TRIGGER,*max_balance,200,false,0,,*voice,*out,,GERMANY,,,,,,SOME_2,10
|
||||
STANDARD_TRIGGERS,*min_balance,2,false,0,,*monetary,*out,,,,,,,,LOG_WARNING,10
|
||||
STANDARD_TRIGGERS,*max_balance,20,false,0,,*monetary,*out,,,,,,,,LOG_WARNING,10
|
||||
STANDARD_TRIGGERS,*max_counter,5,false,0,,*monetary,*out,,FS_USERS,,,,,,LOG_WARNING,10
|
||||
CDRST1_WARN_ASR,*min_asr,45,true,1h,,,,,,,,,,3,CDRST_WARN_HTTP,10
|
||||
CDRST1_WARN_ACD,*min_acd,10,true,1h,,,,,,,,,,5,CDRST_WARN_HTTP,10
|
||||
CDRST1_WARN_ACC,*max_acc,10,true,10m,,,,,,,,,,5,CDRST_WARN_HTTP,10
|
||||
CDRST2_WARN_ASR,*min_asr,30,true,0,,,,,,,,,,5,CDRST_WARN_HTTP,10
|
||||
CDRST2_WARN_ACD,*min_acd,3,true,0,,,,,,,,,,5,CDRST_WARN_HTTP,10
|
||||
STANDARD_TRIGGER,*min_counter,10,false,0,,*voice,*out,,GERMANY_O2,,,,,,,SOME_1,10
|
||||
STANDARD_TRIGGER,*max_balance,200,false,0,,*voice,*out,,GERMANY,,,,,,,SOME_2,10
|
||||
STANDARD_TRIGGERS,*min_balance,2,false,0,,*monetary,*out,,,,,,,,,LOG_WARNING,10
|
||||
STANDARD_TRIGGERS,*max_balance,20,false,0,,*monetary,*out,,,,,,,,,LOG_WARNING,10
|
||||
STANDARD_TRIGGERS,*max_counter,5,false,0,,*monetary,*out,,FS_USERS,,,,,,,LOG_WARNING,10
|
||||
CDRST1_WARN_ASR,*min_asr,45,true,1h,,,,,,,,,,,3,CDRST_WARN_HTTP,10
|
||||
CDRST1_WARN_ACD,*min_acd,10,true,1h,,,,,,,,,,,5,CDRST_WARN_HTTP,10
|
||||
CDRST1_WARN_ACC,*max_acc,10,true,10m,,,,,,,,,,,5,CDRST_WARN_HTTP,10
|
||||
CDRST2_WARN_ASR,*min_asr,30,true,0,,,,,,,,,,,5,CDRST_WARN_HTTP,10
|
||||
CDRST2_WARN_ACD,*min_acd,3,true,0,,,,,,,,,,,5,CDRST_WARN_HTTP,10
|
||||
`
|
||||
accountActions = `
|
||||
vdf,minitsboy;a1;a2,*out,MORE_MINUTES,STANDARD_TRIGGER
|
||||
|
||||
@@ -573,11 +573,30 @@ func (dbr *DbReader) LoadActions() (err error) {
|
||||
Id: tpact.BalanceTag,
|
||||
Value: tpact.Units,
|
||||
Weight: tpact.BalanceWeight,
|
||||
TimingIDs: tpact.TimingTags,
|
||||
RatingSubject: tpact.RatingSubject,
|
||||
Category: tpact.Category,
|
||||
DestinationId: tpact.DestinationId,
|
||||
},
|
||||
}
|
||||
// load action timings from tags
|
||||
if acts[idx].Balance.TimingIDs != "" {
|
||||
timingIds := strings.Split(acts[idx].Balance.TimingIDs, utils.INFIELD_SEP)
|
||||
for _, timingID := range timingIds {
|
||||
if timing, found := dbr.timings[timingID]; found {
|
||||
acts[idx].Balance.Timings = append(acts[idx].Balance.Timings, &RITiming{
|
||||
Years: timing.Years,
|
||||
Months: timing.Months,
|
||||
MonthDays: timing.MonthDays,
|
||||
WeekDays: timing.WeekDays,
|
||||
StartTime: timing.StartTime,
|
||||
EndTime: timing.EndTime,
|
||||
})
|
||||
} else {
|
||||
return fmt.Errorf("Could not find timing: %v", timingID)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dbr.actions[tag] = acts
|
||||
}
|
||||
@@ -642,6 +661,7 @@ func (dbr *DbReader) LoadActionTriggers() (err error) {
|
||||
BalanceDestinationId: apiAtr.BalanceDestinationId,
|
||||
BalanceWeight: apiAtr.BalanceWeight,
|
||||
BalanceExpirationDate: balance_expiration_date,
|
||||
BalanceTimingTags: apiAtr.BalanceTimingTags,
|
||||
BalanceRatingSubject: apiAtr.BalanceRatingSubject,
|
||||
BalanceCategory: apiAtr.BalanceCategory,
|
||||
BalanceSharedGroup: apiAtr.BalanceSharedGroup,
|
||||
|
||||
@@ -47,6 +47,7 @@ const (
|
||||
ACTSCSVIDX_RATING_SUBJECT
|
||||
ACTSCSVIDX_SHARED_GROUP
|
||||
ACTSCSVIDX_EXPIRY_TIME
|
||||
ACTSCSVIDX_TIMING_TAGS
|
||||
ACTSCSVIDX_UNITS
|
||||
ACTSCSVIDX_BALANCE_WEIGHT
|
||||
ACTSCSVIDX_WEIGHT
|
||||
@@ -67,6 +68,7 @@ const (
|
||||
ATRIGCSVIDX_BAL_RATING_SUBJECT
|
||||
ATRIGCSVIDX_BAL_SHARED_GROUP
|
||||
ATRIGCSVIDX_BAL_EXPIRY_TIME
|
||||
ATRIGCSVIDX_BAL_TIMING_TAGS
|
||||
ATRIGCSVIDX_BAL_WEIGHT
|
||||
ATRIGCSVIDX_STATS_MIN_QUEUED_ITEMS
|
||||
ATRIGCSVIDX_ACTIONS_TAG
|
||||
@@ -127,11 +129,15 @@ func ValidNextGroup(present, next *utils.RateSlot) error {
|
||||
func NewTiming(timingInfo ...string) (rt *utils.TPTiming) {
|
||||
rt = &utils.TPTiming{}
|
||||
rt.Id = timingInfo[0]
|
||||
rt.Years.Parse(timingInfo[1], ";")
|
||||
rt.Months.Parse(timingInfo[2], ";")
|
||||
rt.MonthDays.Parse(timingInfo[3], ";")
|
||||
rt.WeekDays.Parse(timingInfo[4], ";")
|
||||
rt.StartTime = timingInfo[5]
|
||||
rt.Years.Parse(timingInfo[1], utils.INFIELD_SEP)
|
||||
rt.Months.Parse(timingInfo[2], utils.INFIELD_SEP)
|
||||
rt.MonthDays.Parse(timingInfo[3], utils.INFIELD_SEP)
|
||||
rt.WeekDays.Parse(timingInfo[4], utils.INFIELD_SEP)
|
||||
times := strings.Split(timingInfo[5], utils.INFIELD_SEP)
|
||||
rt.StartTime = times[0]
|
||||
if len(times) > 1 {
|
||||
rt.EndTime = times[1]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -134,6 +134,7 @@ type TpAction struct {
|
||||
Direction string
|
||||
Units float64
|
||||
ExpiryTime string
|
||||
TimingTags string
|
||||
DestinationTag string
|
||||
RatingSubject string
|
||||
Category string
|
||||
@@ -168,6 +169,7 @@ type TpActionTrigger struct {
|
||||
BalanceDestinationTag string
|
||||
BalanceWeight float64
|
||||
BalanceExpiryTime string
|
||||
BalanceTimingTags string
|
||||
BalanceRatingSubject string
|
||||
BalanceCategory string
|
||||
BalanceSharedGroup string
|
||||
|
||||
@@ -115,6 +115,63 @@ func (rit *RITiming) CronString() string {
|
||||
return rit.cronString
|
||||
}
|
||||
|
||||
// Returns wheter the Timing is active at the specified time
|
||||
func (rit *RITiming) IsActiveAt(t time.Time, endTime bool) bool {
|
||||
// if the received time represents an endtime consider it 24 instead of 0
|
||||
hour := t.Hour()
|
||||
if endTime && hour == 0 {
|
||||
hour = 24
|
||||
}
|
||||
// check for years
|
||||
if len(rit.Years) > 0 && !rit.Years.Contains(t.Year()) {
|
||||
return false
|
||||
}
|
||||
// check for months
|
||||
if len(rit.Months) > 0 && !rit.Months.Contains(t.Month()) {
|
||||
return false
|
||||
}
|
||||
// check for month days
|
||||
if len(rit.MonthDays) > 0 && !rit.MonthDays.Contains(t.Day()) {
|
||||
return false
|
||||
}
|
||||
// check for weekdays
|
||||
if len(rit.WeekDays) > 0 && !rit.WeekDays.Contains(t.Weekday()) {
|
||||
return false
|
||||
}
|
||||
// check for start hour
|
||||
if rit.StartTime != "" {
|
||||
split := strings.Split(rit.StartTime, ":")
|
||||
sh, _ := strconv.Atoi(split[0])
|
||||
sm, _ := strconv.Atoi(split[1])
|
||||
ss, _ := strconv.Atoi(split[2])
|
||||
// if the hour result before or result the same hour but the minute result before
|
||||
if hour < sh ||
|
||||
(hour == sh && t.Minute() < sm) ||
|
||||
(hour == sh && t.Minute() == sm && t.Second() < ss) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// check for end hour
|
||||
if rit.EndTime != "" {
|
||||
split := strings.Split(rit.EndTime, ":")
|
||||
eh, _ := strconv.Atoi(split[0])
|
||||
em, _ := strconv.Atoi(split[1])
|
||||
es, _ := strconv.Atoi(split[2])
|
||||
// if the hour result after or result the same hour but the minute result after
|
||||
if hour > eh ||
|
||||
(hour == eh && t.Minute() > em) ||
|
||||
(hour == eh && t.Minute() == em && t.Second() > es) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Returns wheter the Timing is active now
|
||||
func (rit *RITiming) IsActive() bool {
|
||||
return rit.IsActiveAt(time.Now(), false)
|
||||
}
|
||||
|
||||
func (rit *RITiming) Stringify() string {
|
||||
return utils.Sha1(fmt.Sprintf("%v", rit))[:8]
|
||||
}
|
||||
@@ -202,54 +259,7 @@ func (pg *RateGroups) AddRate(ps ...*Rate) {
|
||||
Returns true if the received time result inside the interval
|
||||
*/
|
||||
func (i *RateInterval) Contains(t time.Time, endTime bool) bool {
|
||||
// if the received time represents an endtime cosnidere it 24 instead of 0
|
||||
hour := t.Hour()
|
||||
if endTime && hour == 0 {
|
||||
hour = 24
|
||||
}
|
||||
// check for years
|
||||
if len(i.Timing.Years) > 0 && !i.Timing.Years.Contains(t.Year()) {
|
||||
return false
|
||||
}
|
||||
// check for months
|
||||
if len(i.Timing.Months) > 0 && !i.Timing.Months.Contains(t.Month()) {
|
||||
return false
|
||||
}
|
||||
// check for month days
|
||||
if len(i.Timing.MonthDays) > 0 && !i.Timing.MonthDays.Contains(t.Day()) {
|
||||
return false
|
||||
}
|
||||
// check for weekdays
|
||||
if len(i.Timing.WeekDays) > 0 && !i.Timing.WeekDays.Contains(t.Weekday()) {
|
||||
return false
|
||||
}
|
||||
// check for start hour
|
||||
if i.Timing.StartTime != "" {
|
||||
split := strings.Split(i.Timing.StartTime, ":")
|
||||
sh, _ := strconv.Atoi(split[0])
|
||||
sm, _ := strconv.Atoi(split[1])
|
||||
ss, _ := strconv.Atoi(split[2])
|
||||
// if the hour result before or result the same hour but the minute result before
|
||||
if hour < sh ||
|
||||
(hour == sh && t.Minute() < sm) ||
|
||||
(hour == sh && t.Minute() == sm && t.Second() < ss) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// check for end hour
|
||||
if i.Timing.EndTime != "" {
|
||||
split := strings.Split(i.Timing.EndTime, ":")
|
||||
eh, _ := strconv.Atoi(split[0])
|
||||
em, _ := strconv.Atoi(split[1])
|
||||
es, _ := strconv.Atoi(split[2])
|
||||
// if the hour result after or result the same hour but the minute result after
|
||||
if hour > eh ||
|
||||
(hour == eh && t.Minute() > em) ||
|
||||
(hour == eh && t.Minute() == em && t.Second() > es) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
return i.Timing.IsActiveAt(t, endTime)
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -25,6 +25,10 @@ import (
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
ACTIVE_TIME = time.Now()
|
||||
)
|
||||
|
||||
func TestRateIntervalSimpleContains(t *testing.T) {
|
||||
i := &RateInterval{
|
||||
Timing: &RITiming{
|
||||
@@ -337,6 +341,10 @@ func TestRateIntervalCronEmpty(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimingIsActive(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
/*********************************Benchmarks**************************************/
|
||||
|
||||
func BenchmarkRateIntervalContainsDate(b *testing.B) {
|
||||
|
||||
@@ -511,6 +511,7 @@ func (self *SQLStorage) SetTPActions(tpid string, acts map[string][]*utils.TPAct
|
||||
Direction: ac.Direction,
|
||||
Units: ac.Units,
|
||||
ExpiryTime: ac.ExpiryTime,
|
||||
TimingTags: ac.TimingTags,
|
||||
DestinationTag: ac.DestinationId,
|
||||
RatingSubject: ac.RatingSubject,
|
||||
Category: ac.Category,
|
||||
@@ -543,6 +544,7 @@ func (self *SQLStorage) GetTPActions(tpid, actsId string) (*utils.TPActions, err
|
||||
Direction: tpAct.Direction,
|
||||
Units: tpAct.Units,
|
||||
ExpiryTime: tpAct.ExpiryTime,
|
||||
TimingTags: tpAct.TimingTags,
|
||||
DestinationId: tpAct.DestinationTag,
|
||||
RatingSubject: tpAct.RatingSubject,
|
||||
Category: tpAct.Category,
|
||||
@@ -620,6 +622,7 @@ func (self *SQLStorage) SetTPActionTriggers(tpid string, ats map[string][]*utils
|
||||
BalanceDestinationTag: at.BalanceDestinationId,
|
||||
BalanceWeight: at.BalanceWeight,
|
||||
BalanceExpiryTime: at.BalanceExpirationDate,
|
||||
BalanceTimingTags: at.BalanceTimingTags,
|
||||
BalanceRatingSubject: at.BalanceRatingSubject,
|
||||
BalanceCategory: at.BalanceCategory,
|
||||
BalanceSharedGroup: at.BalanceSharedGroup,
|
||||
@@ -1402,6 +1405,7 @@ func (self *SQLStorage) GetTpActions(tpid, tag string) (map[string][]*utils.TPAc
|
||||
Direction: tpAc.Direction,
|
||||
Units: tpAc.Units,
|
||||
ExpiryTime: tpAc.ExpiryTime,
|
||||
TimingTags: tpAc.TimingTags,
|
||||
DestinationId: tpAc.DestinationTag,
|
||||
RatingSubject: tpAc.RatingSubject,
|
||||
Category: tpAc.Category,
|
||||
@@ -1433,6 +1437,7 @@ func (self *SQLStorage) GetTpActionTriggers(tpid, tag string) (map[string][]*uti
|
||||
BalanceDestinationId: tpAt.BalanceDestinationTag,
|
||||
BalanceWeight: tpAt.BalanceWeight,
|
||||
BalanceExpirationDate: tpAt.BalanceExpiryTime,
|
||||
BalanceTimingTags: tpAt.BalanceTimingTags,
|
||||
BalanceRatingSubject: tpAt.BalanceRatingSubject,
|
||||
BalanceCategory: tpAt.BalanceCategory,
|
||||
BalanceSharedGroup: tpAt.BalanceSharedGroup,
|
||||
|
||||
@@ -44,9 +44,9 @@ func TestAcntActsLoadCsv(t *testing.T) {
|
||||
ratingProfiles := ``
|
||||
sharedGroups := ``
|
||||
lcrs := ``
|
||||
actions := `TOPUP10_AC,*topup_reset,,,*voice,*out,,*any,,,*unlimited,10,10,10
|
||||
DISABLE_ACNT,*disable_account,,,,,,,,,,,,10
|
||||
ENABLE_ACNT,*enable_account,,,,,,,,,,,,10`
|
||||
actions := `TOPUP10_AC,*topup_reset,,,*voice,*out,,*any,,,*unlimited,,10,10,10
|
||||
DISABLE_ACNT,*disable_account,,,,,,,,,,,,,10
|
||||
ENABLE_ACNT,*enable_account,,,,,,,,,,,,,10`
|
||||
actionPlans := `TOPUP10_AT,TOPUP10_AC,ASAP,10`
|
||||
actionTriggers := ``
|
||||
accountActions := `cgrates.org,1,*out,TOPUP10_AT,`
|
||||
|
||||
@@ -52,8 +52,8 @@ RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10`
|
||||
*out,cgrates.org,call,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,`
|
||||
sharedGroups := ``
|
||||
lcrs := ``
|
||||
actions := `TOPUP10_AC,*topup_reset,,,*monetary,*out,,*any,,,*unlimited,10,10,10
|
||||
TOPUP10_AC1,*topup_reset,,,*voice,*out,,DST_UK_Mobile_BIG5,discounted_minutes,,*unlimited,40,10,10`
|
||||
actions := `TOPUP10_AC,*topup_reset,,,*monetary,*out,,*any,,,*unlimited,,10,10,10
|
||||
TOPUP10_AC1,*topup_reset,,,*voice,*out,,DST_UK_Mobile_BIG5,discounted_minutes,,*unlimited,,40,10,10`
|
||||
actionPlans := `TOPUP10_AT,TOPUP10_AC,ASAP,10
|
||||
TOPUP10_AT,TOPUP10_AC1,ASAP,10`
|
||||
actionTriggers := ``
|
||||
|
||||
@@ -52,8 +52,8 @@ RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10`
|
||||
*out,cgrates.org,call,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,`
|
||||
sharedGroups := ``
|
||||
lcrs := ``
|
||||
actions := `TOPUP10_AC,*topup_reset,,,*monetary,*out,,*any,,,*unlimited,0,10,10
|
||||
TOPUP10_AC1,*topup_reset,,,*voice,*out,,DST_UK_Mobile_BIG5,discounted_minutes,,*unlimited,40,10,10`
|
||||
actions := `TOPUP10_AC,*topup_reset,,,*monetary,*out,,*any,,,*unlimited,,0,10,10
|
||||
TOPUP10_AC1,*topup_reset,,,*voice,*out,,DST_UK_Mobile_BIG5,discounted_minutes,,*unlimited,,40,10,10`
|
||||
actionPlans := `TOPUP10_AT,TOPUP10_AC,ASAP,10
|
||||
TOPUP10_AT,TOPUP10_AC1,ASAP,10`
|
||||
actionTriggers := ``
|
||||
|
||||
@@ -52,7 +52,7 @@ RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10`
|
||||
*out,cgrates.org,call,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,`
|
||||
sharedGroups := ``
|
||||
lcrs := ``
|
||||
actions := `TOPUP10_AC1,*topup_reset,,,*voice,*out,,DST_UK_Mobile_BIG5,discounted_minutes,,*unlimited,40,10,10`
|
||||
actions := `TOPUP10_AC1,*topup_reset,,,*voice,*out,,DST_UK_Mobile_BIG5,discounted_minutes,,*unlimited,,40,10,10`
|
||||
actionPlans := `TOPUP10_AT,TOPUP10_AC1,ASAP,10`
|
||||
actionTriggers := ``
|
||||
accountActions := `cgrates.org,12346,*out,TOPUP10_AT,`
|
||||
|
||||
@@ -177,6 +177,7 @@ type TPTiming struct {
|
||||
MonthDays MonthDays
|
||||
WeekDays WeekDays
|
||||
StartTime string
|
||||
EndTime string
|
||||
}
|
||||
|
||||
type TPRatingPlan struct {
|
||||
@@ -320,6 +321,7 @@ type TPAction struct {
|
||||
Direction string // Balance direction
|
||||
Units float64 // Number of units to add/deduct
|
||||
ExpiryTime string // Time when the units will expire
|
||||
TimingTags string // Timing when balance is active
|
||||
DestinationId string // Destination profile id
|
||||
RatingSubject string // Reference a rate subject defined in RatingProfiles
|
||||
Category string // category filter for balances
|
||||
@@ -522,7 +524,7 @@ func (self *TPActionTriggers) AsExportSlice() [][]string {
|
||||
retSlice := make([][]string, len(self.ActionTriggers))
|
||||
for idx, at := range self.ActionTriggers {
|
||||
retSlice[idx] = []string{self.ActionTriggersId, at.ThresholdType, strconv.FormatFloat(at.ThresholdValue, 'f', -1, 64), strconv.FormatBool(at.Recurrent), strconv.FormatFloat(at.MinSleep.Seconds(), 'f', -1, 64),
|
||||
at.BalanceTag, at.BalanceType, at.BalanceDirection, at.BalanceCategory, at.BalanceDestinationId, at.BalanceRatingSubject, at.BalanceSharedGroup, at.BalanceExpirationDate,
|
||||
at.BalanceTag, at.BalanceType, at.BalanceDirection, at.BalanceCategory, at.BalanceDestinationId, at.BalanceRatingSubject, at.BalanceSharedGroup, at.BalanceExpirationDate, at.BalanceTimingTags,
|
||||
strconv.FormatFloat(at.BalanceWeight, 'f', -1, 64), strconv.Itoa(at.MinQueuedItems), at.ActionsId, strconv.FormatFloat(at.Weight, 'f', -1, 64)}
|
||||
}
|
||||
return retSlice
|
||||
@@ -539,6 +541,7 @@ type TPActionTrigger struct {
|
||||
BalanceDestinationId string // filter for balance
|
||||
BalanceWeight float64 // filter for balance
|
||||
BalanceExpirationDate string // filter for balance
|
||||
BalanceTimingTags string // filter for balance
|
||||
BalanceRatingSubject string // filter for balance
|
||||
BalanceCategory string // filter for balance
|
||||
BalanceSharedGroup string // filter for balance
|
||||
|
||||
@@ -422,6 +422,7 @@ func TestTPActionPlanAsExportSlice(t *testing.T) {
|
||||
BalanceDestinationId: "",
|
||||
BalanceWeight: 0.0,
|
||||
BalanceExpirationDate: "*never",
|
||||
BalanceTimingTags: "T1",
|
||||
BalanceRatingSubject: "special1",
|
||||
BalanceCategory: "call",
|
||||
BalanceSharedGroup: "SHARED_1",
|
||||
@@ -439,6 +440,7 @@ func TestTPActionPlanAsExportSlice(t *testing.T) {
|
||||
BalanceDestinationId: "FS_USERS",
|
||||
BalanceWeight: 0.0,
|
||||
BalanceExpirationDate: "*never",
|
||||
BalanceTimingTags: "T1",
|
||||
BalanceRatingSubject: "special1",
|
||||
BalanceCategory: "call",
|
||||
BalanceSharedGroup: "SHARED_1",
|
||||
@@ -448,8 +450,8 @@ func TestTPActionPlanAsExportSlice(t *testing.T) {
|
||||
},
|
||||
}
|
||||
expectedSlc := [][]string{
|
||||
[]string{"STANDARD_TRIGGERS", "*min_balance", "2", "false", "0", "b1", "*monetary", "*out", "call", "", "special1", "SHARED_1", "*never", "0", "0", "LOG_WARNING", "10"},
|
||||
[]string{"STANDARD_TRIGGERS", "*max_counter", "5", "false", "0", "b2", "*monetary", "*out", "call", "FS_USERS", "special1", "SHARED_1", "*never", "0", "0", "LOG_WARNING", "10"},
|
||||
[]string{"STANDARD_TRIGGERS", "*min_balance", "2", "false", "0", "b1", "*monetary", "*out", "call", "", "special1", "SHARED_1", "*never", "T1", "0", "0", "LOG_WARNING", "10"},
|
||||
[]string{"STANDARD_TRIGGERS", "*max_counter", "5", "false", "0", "b2", "*monetary", "*out", "call", "FS_USERS", "special1", "SHARED_1", "*never", "T1", "0", "0", "LOG_WARNING", "10"},
|
||||
}
|
||||
if slc := at.AsExportSlice(); !reflect.DeepEqual(expectedSlc, slc) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", expectedSlc, slc)
|
||||
|
||||
@@ -61,9 +61,9 @@ const (
|
||||
RATE_PROFILES_NRCOLS = 7
|
||||
SHARED_GROUPS_NRCOLS = 4
|
||||
LCRS_NRCOLS = 9
|
||||
ACTIONS_NRCOLS = 14
|
||||
ACTIONS_NRCOLS = 15
|
||||
ACTION_PLANS_NRCOLS = 4
|
||||
ACTION_TRIGGERS_NRCOLS = 17
|
||||
ACTION_TRIGGERS_NRCOLS = 18
|
||||
ACCOUNT_ACTIONS_NRCOLS = 5
|
||||
DERIVED_CHARGERS_NRCOLS = 17
|
||||
CDR_STATS_NRCOLS = 21
|
||||
|
||||
Reference in New Issue
Block a user