mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Merge branch 'master' of https://github.com/cgrates/cgrates
This commit is contained in:
@@ -339,12 +339,12 @@ func (ub *Account) executeActionTriggers(a *Action) {
|
||||
if uc.BalanceType == at.BalanceType {
|
||||
for _, mb := range uc.Balances {
|
||||
if strings.Contains(at.ThresholdType, "*max") {
|
||||
if mb.MatchDestination(at.DestinationId) && mb.Value >= at.ThresholdValue {
|
||||
if mb.MatchActionTrigger(at) && mb.Value >= at.ThresholdValue {
|
||||
// run the actions
|
||||
at.Execute(ub)
|
||||
}
|
||||
} else { //MIN
|
||||
if mb.MatchDestination(at.DestinationId) && mb.Value <= at.ThresholdValue {
|
||||
if mb.MatchActionTrigger(at) && mb.Value <= at.ThresholdValue {
|
||||
// run the actions
|
||||
at.Execute(ub)
|
||||
}
|
||||
@@ -354,13 +354,16 @@ func (ub *Account) executeActionTriggers(a *Action) {
|
||||
}
|
||||
} else { // BALANCE
|
||||
for _, b := range ub.BalanceMap[at.BalanceType+at.Direction] {
|
||||
if !b.dirty { // do not check clean balances
|
||||
continue
|
||||
}
|
||||
if strings.Contains(at.ThresholdType, "*max") {
|
||||
if b.MatchDestination(at.DestinationId) && b.Value >= at.ThresholdValue {
|
||||
if b.MatchActionTrigger(at) && b.Value >= at.ThresholdValue {
|
||||
// run the actions
|
||||
at.Execute(ub)
|
||||
}
|
||||
} else { //MIN
|
||||
if b.MatchDestination(at.DestinationId) && b.Value <= at.ThresholdValue {
|
||||
if b.MatchActionTrigger(at) && b.Value <= at.ThresholdValue {
|
||||
// run the actions
|
||||
at.Execute(ub)
|
||||
}
|
||||
|
||||
@@ -22,26 +22,29 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
type ActionTrigger struct {
|
||||
Id string // uniquely identify the trigger
|
||||
BalanceType string
|
||||
Direction string
|
||||
ThresholdType string //*min_counter, *max_counter, *min_balance, *max_balance
|
||||
ThresholdValue float64
|
||||
Recurrent bool // reset eexcuted flag each run
|
||||
DestinationId string
|
||||
Weight float64
|
||||
ActionsId string
|
||||
Executed bool
|
||||
Id string // uniquely identify the trigger
|
||||
BalanceType string
|
||||
Direction string
|
||||
ThresholdType string //*min_counter, *max_counter, *min_balance, *max_balance
|
||||
ThresholdValue float64
|
||||
Recurrent bool // reset eexcuted flag each run
|
||||
DestinationId string
|
||||
BalanceWeight float64
|
||||
BalanceExpirationDate time.Time
|
||||
Weight float64
|
||||
ActionsId string
|
||||
Executed bool
|
||||
}
|
||||
|
||||
func (at *ActionTrigger) Execute(ub *Account) (err error) {
|
||||
if ub.Disabled {
|
||||
return fmt.Errorf("User %s is disabled", ub.Id)
|
||||
return fmt.Errorf("User %s is disabled and there are triggers in action!", ub.Id)
|
||||
}
|
||||
// does NOT need to Lock() because it is triggered from a method that took the Lock
|
||||
var aac Actions
|
||||
|
||||
@@ -827,7 +827,7 @@ func TestActionResetCounterMinutes(t *testing.T) {
|
||||
CREDIT: BalanceChain{&Balance{Value: 100}},
|
||||
MINUTES: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationId: "NAT"}, &Balance{Weight: 10, DestinationId: "RET"}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceType: CREDIT, Balances: BalanceChain{&Balance{Value: 1}}}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, ThresholdType: "*max_counter", ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
}
|
||||
a := &Action{BalanceType: MINUTES}
|
||||
resetCounterAction(ub, a)
|
||||
@@ -840,14 +840,14 @@ func TestActionResetCounterMinutes(t *testing.T) {
|
||||
for _, b := range ub.UnitCounters[1].Balances {
|
||||
t.Logf("B: %+v", b)
|
||||
}
|
||||
t.Error("Reset counters action failed!", ub.UnitCounters[1])
|
||||
t.Errorf("Reset counters action failed: %+v", ub)
|
||||
}
|
||||
if len(ub.UnitCounters) < 2 || len(ub.UnitCounters[1].Balances) < 1 {
|
||||
t.FailNow()
|
||||
}
|
||||
mb := ub.UnitCounters[1].Balances[0]
|
||||
if mb.Weight != 20 || mb.Value != 0 || mb.DestinationId != "NAT" {
|
||||
t.Errorf("Balance cloned incorrectly: %v!", mb)
|
||||
t.Errorf("Balance cloned incorrectly: %+v!", mb)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,20 @@ func (b *Balance) MatchDestination(destinationId string) bool {
|
||||
return !b.HasDestination() || b.DestinationId == destinationId
|
||||
}
|
||||
|
||||
func (b *Balance) MatchActionTrigger(at *ActionTrigger) bool {
|
||||
matchesExpirationDate := true
|
||||
if !at.BalanceExpirationDate.IsZero() {
|
||||
matchesExpirationDate = (at.BalanceExpirationDate.Equal(b.ExpirationDate))
|
||||
}
|
||||
matchesWeight := true
|
||||
if at.BalanceWeight > 0 {
|
||||
matchesWeight = (at.BalanceWeight == b.Weight)
|
||||
}
|
||||
return b.MatchDestination(at.DestinationId) &&
|
||||
matchesExpirationDate &&
|
||||
matchesWeight
|
||||
}
|
||||
|
||||
func (b *Balance) Clone() *Balance {
|
||||
return &Balance{
|
||||
Uuid: b.Uuid,
|
||||
|
||||
@@ -19,6 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package engine
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/cgrates/cgrates/cache2go"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
@@ -36,6 +38,10 @@ type UnitsCounter struct {
|
||||
func (uc *UnitsCounter) initBalances(ats []*ActionTrigger) {
|
||||
uc.Balances = BalanceChain{&Balance{}} // general balance
|
||||
for _, at := range ats {
|
||||
if !strings.Contains(at.ThresholdType, "counter") {
|
||||
// only get actions fo counter type action triggers
|
||||
continue
|
||||
}
|
||||
acs, err := accountingStorage.GetActions(at.ActionsId, false)
|
||||
if err != nil {
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user