mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
SetAccountAction API and filter for RESET_TRIGGERS
This commit is contained in:
@@ -238,8 +238,8 @@ func (self *Apier) AddAccount(attr *AttrAccount, reply *float64) error {
|
||||
}
|
||||
|
||||
type AttrSetAccountAction struct {
|
||||
TPid string
|
||||
RateProfileId string
|
||||
TPid string
|
||||
AccountActionId string
|
||||
}
|
||||
|
||||
// Process dependencies and load a specific rating profile from storDb into dataDb.
|
||||
@@ -249,8 +249,15 @@ func (self *Apier) SetAccountAction(attrs AttrSetAccountAction, reply *string) e
|
||||
}
|
||||
dbReader := rater.NewDbReader(self.StorDb, self.DataDb, attrs.TPid)
|
||||
|
||||
if err := dbReader.LoadAccountActionByTag(attrs.RateProfileId); err != nil {
|
||||
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
|
||||
rater.AccLock.Guard(attrs.AccountActionId, func() (float64, error) {
|
||||
if err := dbReader.LoadAccountActionsByTag(attrs.AccountActionId); err != nil {
|
||||
return 0, fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
|
||||
}
|
||||
return 0, nil
|
||||
})
|
||||
if self.Sched != nil {
|
||||
self.Sched.LoadActionTimings(self.DataDb)
|
||||
self.Sched.Restart()
|
||||
}
|
||||
*reply = "OK"
|
||||
return nil
|
||||
|
||||
@@ -331,10 +331,65 @@ AddAcount
|
||||
Example
|
||||
AddAccount(attr \*AttrAccount, reply \*float64)
|
||||
|
||||
Apier.SetAccountAction
|
||||
++++++++++++++++++++++
|
||||
|
||||
Process dependencies and load a specific rating profile from storDb into dataDb.
|
||||
|
||||
**Request**:
|
||||
|
||||
Data:
|
||||
::
|
||||
|
||||
type AttrSetAccountAction struct {
|
||||
TPid string
|
||||
AccountActionId string
|
||||
}
|
||||
|
||||
Mandatory parameters: ``[]string{"TPid", "AccountActionId"}``
|
||||
|
||||
*JSON sample*:
|
||||
::
|
||||
|
||||
{
|
||||
"id": 0,
|
||||
"method": "Apier.SetAccountAction",
|
||||
"params": [
|
||||
{
|
||||
"AccountActionId": "ACC_SAMPLE_1",
|
||||
"TPid": "TPID_SAMPLE_1"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
**Reply**:
|
||||
|
||||
Data:
|
||||
::
|
||||
|
||||
string
|
||||
|
||||
Possible answers:
|
||||
``OK`` - Success.
|
||||
|
||||
*JSON sample*:
|
||||
::
|
||||
|
||||
{
|
||||
"error": null,
|
||||
"id": 0,
|
||||
"result": "OK"
|
||||
}
|
||||
|
||||
**Errors**:
|
||||
|
||||
``MANDATORY_IE_MISSING`` - Mandatory parameter missing from request.
|
||||
|
||||
``SERVER_ERROR`` - Server error occurred.
|
||||
|
||||
RatingProfiles
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ func logAction(ub *UserBalance, a *Action) (err error) {
|
||||
}
|
||||
|
||||
func resetTriggersAction(ub *UserBalance, a *Action) (err error) {
|
||||
ub.resetActionTriggers()
|
||||
ub.resetActionTriggers(a)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ func genericReset(ub *UserBalance) {
|
||||
}
|
||||
ub.MinuteBuckets = make([]*MinuteBucket, 0)
|
||||
ub.UnitCounters = make([]*UnitsCounter, 0)
|
||||
ub.resetActionTriggers()
|
||||
ub.resetActionTriggers(nil)
|
||||
}
|
||||
|
||||
// Structure to store actions according to weight
|
||||
|
||||
@@ -415,7 +415,7 @@ func TestActionResetTriggres(t *testing.T) {
|
||||
Id: "TEST_UB",
|
||||
BalanceMap: map[string]BalanceChain{CREDIT: BalanceChain{&Balance{Value: 10}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Units: 1}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
}
|
||||
resetTriggersAction(ub, nil)
|
||||
@@ -424,13 +424,40 @@ func TestActionResetTriggres(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionResetTriggresExecutesThem(t *testing.T) {
|
||||
ub := &UserBalance{
|
||||
Id: "TEST_UB",
|
||||
BalanceMap: map[string]BalanceChain{CREDIT: BalanceChain{&Balance{Value: 10}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Units: 1}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
}
|
||||
resetTriggersAction(ub, nil)
|
||||
if ub.ActionTriggers[0].Executed == true || ub.BalanceMap[CREDIT][0].Value == 12 {
|
||||
t.Error("Reset triggers action failed!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionResetTriggresActionFilter(t *testing.T) {
|
||||
ub := &UserBalance{
|
||||
Id: "TEST_UB",
|
||||
BalanceMap: map[string]BalanceChain{CREDIT: BalanceChain{&Balance{Value: 10}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Units: 1}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
}
|
||||
resetTriggersAction(ub, &Action{BalanceId: SMS})
|
||||
if ub.ActionTriggers[0].Executed == false || ub.ActionTriggers[1].Executed == false {
|
||||
t.Error("Reset triggers action failed!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionSetPostpaid(t *testing.T) {
|
||||
ub := &UserBalance{
|
||||
Id: "TEST_UB",
|
||||
Type: UB_TYPE_PREPAID,
|
||||
BalanceMap: map[string]BalanceChain{CREDIT: BalanceChain{&Balance{Value: 100}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Units: 1}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
}
|
||||
setPostpaidAction(ub, nil)
|
||||
@@ -445,7 +472,7 @@ func TestActionSetPrepaid(t *testing.T) {
|
||||
Type: UB_TYPE_POSTPAID,
|
||||
BalanceMap: map[string]BalanceChain{CREDIT: BalanceChain{&Balance{Value: 100}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Units: 1}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
}
|
||||
setPrepaidAction(ub, nil)
|
||||
@@ -460,8 +487,8 @@ func TestActionResetPrepaid(t *testing.T) {
|
||||
Type: UB_TYPE_POSTPAID,
|
||||
BalanceMap: map[string]BalanceChain{CREDIT: BalanceChain{&Balance{Value: 100}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Units: 1}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: SMS, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceId: SMS, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
}
|
||||
resetPrepaidAction(ub, nil)
|
||||
if ub.Type != UB_TYPE_PREPAID ||
|
||||
@@ -479,8 +506,8 @@ func TestActionResetPostpaid(t *testing.T) {
|
||||
Type: UB_TYPE_PREPAID,
|
||||
BalanceMap: map[string]BalanceChain{CREDIT: BalanceChain{&Balance{Value: 100}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Units: 1}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: SMS, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceId: SMS, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
}
|
||||
resetPostpaidAction(ub, nil)
|
||||
if ub.Type != UB_TYPE_POSTPAID ||
|
||||
@@ -498,7 +525,7 @@ func TestActionTopupResetCredit(t *testing.T) {
|
||||
Type: UB_TYPE_PREPAID,
|
||||
BalanceMap: map[string]BalanceChain{CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 100}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Direction: OUTBOUND, Units: 1}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceId: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
}
|
||||
a := &Action{BalanceId: CREDIT, Direction: OUTBOUND, Units: 10}
|
||||
@@ -518,7 +545,7 @@ func TestActionTopupResetMinutes(t *testing.T) {
|
||||
Type: UB_TYPE_PREPAID,
|
||||
BalanceMap: map[string]BalanceChain{CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 100}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Direction: OUTBOUND, Units: 1}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceId: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
}
|
||||
a := &Action{BalanceId: MINUTES, Direction: OUTBOUND, MinuteBucket: &MinuteBucket{Seconds: 5, Weight: 20, Price: 1, DestinationId: "NAT"}}
|
||||
@@ -539,7 +566,7 @@ func TestActionTopupCredit(t *testing.T) {
|
||||
Type: UB_TYPE_PREPAID,
|
||||
BalanceMap: map[string]BalanceChain{CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 100}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Direction: OUTBOUND, Units: 1}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceId: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
}
|
||||
a := &Action{BalanceId: CREDIT, Direction: OUTBOUND, Units: 10}
|
||||
@@ -559,7 +586,7 @@ func TestActionTopupMinutes(t *testing.T) {
|
||||
Type: UB_TYPE_PREPAID,
|
||||
BalanceMap: map[string]BalanceChain{CREDIT: BalanceChain{&Balance{Value: 100}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Units: 1}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
}
|
||||
a := &Action{BalanceId: MINUTES, MinuteBucket: &MinuteBucket{Seconds: 5, Weight: 20, Price: 1, DestinationId: "NAT"}}
|
||||
@@ -580,7 +607,7 @@ func TestActionDebitCredit(t *testing.T) {
|
||||
Type: UB_TYPE_PREPAID,
|
||||
BalanceMap: map[string]BalanceChain{CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 100}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Direction: OUTBOUND, Units: 1}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceId: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
}
|
||||
a := &Action{BalanceId: CREDIT, Direction: OUTBOUND, Units: 10}
|
||||
@@ -600,7 +627,7 @@ func TestActionDebitMinutes(t *testing.T) {
|
||||
Type: UB_TYPE_PREPAID,
|
||||
BalanceMap: map[string]BalanceChain{CREDIT: BalanceChain{&Balance{Value: 100}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Units: 1}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
}
|
||||
a := &Action{BalanceId: MINUTES, MinuteBucket: &MinuteBucket{Seconds: 5, Weight: 20, Price: 1, DestinationId: "NAT"}}
|
||||
@@ -621,7 +648,7 @@ func TestActionResetAllCounters(t *testing.T) {
|
||||
Type: UB_TYPE_POSTPAID,
|
||||
BalanceMap: map[string]BalanceChain{CREDIT: BalanceChain{&Balance{Value: 100}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Units: 1}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
}
|
||||
resetCountersAction(ub, nil)
|
||||
@@ -648,7 +675,7 @@ func TestActionResetCounterMinutes(t *testing.T) {
|
||||
Type: UB_TYPE_POSTPAID,
|
||||
BalanceMap: map[string]BalanceChain{CREDIT: BalanceChain{&Balance{Value: 100}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Units: 1}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
}
|
||||
a := &Action{BalanceId: MINUTES}
|
||||
@@ -676,7 +703,7 @@ func TestActionResetCounterCREDIT(t *testing.T) {
|
||||
Type: UB_TYPE_POSTPAID,
|
||||
BalanceMap: map[string]BalanceChain{CREDIT: BalanceChain{&Balance{Value: 100}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Direction: OUTBOUND, Units: 1}, &UnitsCounter{BalanceId: SMS, Direction: OUTBOUND, Units: 1}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
|
||||
}
|
||||
a := &Action{BalanceId: CREDIT, Direction: OUTBOUND}
|
||||
|
||||
@@ -394,17 +394,10 @@ func (csvr *CSVReader) LoadActions() (err error) {
|
||||
ExpirationDate: expDate,
|
||||
}
|
||||
} else {
|
||||
price, percent := 0.0, 0.0
|
||||
value, err := strconv.ParseFloat(record[8], 64)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Could not parse action price: %v", err))
|
||||
}
|
||||
if record[7] == PERCENT {
|
||||
percent = value
|
||||
}
|
||||
if record[7] == ABSOLUTE {
|
||||
price = value
|
||||
}
|
||||
minutesWeight, err := strconv.ParseFloat(record[9], 64)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Could not parse action minutes weight: %v", err))
|
||||
@@ -423,8 +416,8 @@ func (csvr *CSVReader) LoadActions() (err error) {
|
||||
MinuteBucket: &MinuteBucket{
|
||||
Seconds: units,
|
||||
Weight: minutesWeight,
|
||||
Price: price,
|
||||
Percent: percent,
|
||||
Price: value,
|
||||
PriceType: record[7],
|
||||
DestinationId: record[6],
|
||||
ExpirationDate: expDate,
|
||||
},
|
||||
|
||||
@@ -313,7 +313,7 @@ func (dbr *DbReader) LoadAccountActions() (err error) {
|
||||
tag := fmt.Sprintf("%s:%s:%s", aa.Direction, aa.Tenant, aa.Account)
|
||||
aTriggers, exists := dbr.actionsTriggers[aa.ActionTriggersTag]
|
||||
if aa.ActionTriggersTag != "" && !exists {
|
||||
// only return error if there was something ther for the tag
|
||||
// only return error if there was something there for the tag
|
||||
return errors.New(fmt.Sprintf("Could not get action triggers for tag %v", aa.ActionTriggersTag))
|
||||
}
|
||||
ub := &UserBalance{
|
||||
@@ -341,27 +341,84 @@ func (dbr *DbReader) LoadAccountActionsByTag(tag string) error {
|
||||
return err
|
||||
}
|
||||
accountAction := accountActions[0]
|
||||
actionTimingsMap, err := dbr.storDb.GetTpActionTimings(dbr.tpid, accountAction.ActionTimingsTag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
actionTriggersMap, err := dbr.storDb.GetTpActionTriggers(dbr.tpid, accountAction.ActionTriggersTag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
id := fmt.Sprintf("%s:%s:%s", accountAction.Direction, accountAction.Tenant, accountAction.Account)
|
||||
|
||||
// collecting action ids
|
||||
var actionsIds []string
|
||||
for _, atms := range actionTimingsMap {
|
||||
for _, atm := range atms {
|
||||
actionsIds = append(actionsIds, atm.ActionsId)
|
||||
var actionsIds []string // collects action ids
|
||||
|
||||
// action timings
|
||||
if accountAction.ActionTimingsTag != "" {
|
||||
// get old userBalanceIds
|
||||
var exitingUserBalanceIds []string
|
||||
exitingActionTimings, err := dbr.dataDb.GetActionTimings(accountAction.ActionTimingsTag)
|
||||
if err == nil && len(exitingActionTimings) > 0 {
|
||||
// all action timings from a specific tag shuld have the same list of user balances from the first one
|
||||
exitingUserBalanceIds = exitingActionTimings[0].UserBalanceIds
|
||||
}
|
||||
|
||||
actionTimingsMap, err := dbr.storDb.GetTpActionTimings(dbr.tpid, accountAction.ActionTimingsTag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var actionTimings []*ActionTiming
|
||||
for _, at := range actionTimingsMap[accountAction.ActionTimingsTag] {
|
||||
_, exists := dbr.actions[at.ActionsId]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("ActionTiming: Could not load the action for tag: %v", at.ActionsId))
|
||||
}
|
||||
t, exists := dbr.timings[at.Tag]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("ActionTiming: Could not load the timing for tag: %v", at.Tag))
|
||||
}
|
||||
actTmg := &ActionTiming{
|
||||
Id: utils.GenUUID(),
|
||||
Tag: at.Tag,
|
||||
Weight: at.Weight,
|
||||
Timing: &Interval{
|
||||
Months: t.Months,
|
||||
MonthDays: t.MonthDays,
|
||||
WeekDays: t.WeekDays,
|
||||
StartTime: t.StartTime,
|
||||
},
|
||||
ActionsId: at.ActionsId,
|
||||
}
|
||||
// collect action ids from timings
|
||||
actionsIds = append(actionsIds, actTmg.ActionsId)
|
||||
//add user balance id if no already in
|
||||
found := false
|
||||
for _, ubId := range exitingUserBalanceIds {
|
||||
if ubId == id {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
at.UserBalanceIds = append(exitingUserBalanceIds, id)
|
||||
}
|
||||
actionTimings = append(actionTimings, actTmg)
|
||||
}
|
||||
|
||||
// write action timings
|
||||
err = dbr.dataDb.SetActionTimings(accountAction.ActionTimingsTag, actionTimings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, atrs := range actionTriggersMap {
|
||||
for _, atr := range atrs {
|
||||
|
||||
// action triggers
|
||||
var actionTriggers ActionTriggerPriotityList
|
||||
if accountAction.ActionTriggersTag != "" {
|
||||
actionTriggersMap, err := dbr.storDb.GetTpActionTriggers(dbr.tpid, accountAction.ActionTriggersTag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
actionTriggers = actionTriggersMap[accountAction.ActionTriggersTag]
|
||||
// collect action ids from triggers
|
||||
for _, atr := range actionTriggers {
|
||||
actionsIds = append(actionsIds, atr.ActionsId)
|
||||
}
|
||||
}
|
||||
|
||||
// actions
|
||||
var acts map[string][]*Action
|
||||
for _, actId := range actionsIds {
|
||||
actions, err := dbr.storDb.GetTpActions(dbr.tpid, actId)
|
||||
@@ -372,79 +429,19 @@ func (dbr *DbReader) LoadAccountActionsByTag(tag string) error {
|
||||
acts[id] = act
|
||||
}
|
||||
}
|
||||
|
||||
// write action timings
|
||||
for k, atms := range actionTimingsMap {
|
||||
err = dbr.storDb.SetActionTimings(k, atms)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// write actions
|
||||
for k, as := range acts {
|
||||
err = dbr.storDb.SetActions(k, as)
|
||||
err = dbr.dataDb.SetActions(k, as)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
activationPeriods := make(map[string]*ActivationPeriod)
|
||||
resultRatingProfile := &RatingProfile{Id: tag}
|
||||
rpm, err := dbr.storDb.GetTpRatingProfiles(dbr.tpid, tag)
|
||||
ub, err := dbr.dataDb.GetUserBalance(id)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(rpm) == 0 {
|
||||
return fmt.Errorf("No RateProfile with id: %s", tag)
|
||||
}
|
||||
for _, ratingProfile := range rpm {
|
||||
resultRatingProfile.FallbackKey = ratingProfile.FallbackKey // it will be the last fallback key
|
||||
at := time.Unix(ratingProfile.activationTime, 0)
|
||||
drtm, err := dbr.storDb.GetTpDestinationRateTimings(dbr.tpid, ratingProfile.destRatesTimingTag)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(drtm) == 0 {
|
||||
return fmt.Errorf("No DestRateTimings profile with id: %s", ratingProfile.destRatesTimingTag)
|
||||
}
|
||||
for _, destrateTiming := range drtm {
|
||||
tm, err := dbr.storDb.GetTpTimings(dbr.tpid, destrateTiming.TimingsTag)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(tm) == 0 {
|
||||
return fmt.Errorf("No Timings profile with id: %s", destrateTiming.TimingsTag)
|
||||
}
|
||||
destrateTiming.timing = tm[destrateTiming.TimingsTag]
|
||||
drm, err := dbr.storDb.GetTpDestinationRates(dbr.tpid, destrateTiming.DestinationRatesTag)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(drm) == 0 {
|
||||
return fmt.Errorf("No Timings profile with id: %s", destrateTiming.DestinationRatesTag)
|
||||
}
|
||||
for _, drate := range drm[destrateTiming.DestinationRatesTag] {
|
||||
rt, err := dbr.storDb.GetTpRates(dbr.tpid, drate.RateTag)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(rt) == 0 {
|
||||
return fmt.Errorf("No Rates profile with id: %s", drate.RateTag)
|
||||
}
|
||||
drate.Rate = rt[drate.RateTag]
|
||||
if _, exists := activationPeriods[destrateTiming.Tag]; !exists {
|
||||
activationPeriods[destrateTiming.Tag] = &ActivationPeriod{}
|
||||
}
|
||||
activationPeriods[destrateTiming.Tag].AddIntervalIfNotPresent(destrateTiming.GetInterval(drate))
|
||||
dm, err := dbr.storDb.GetTpDestinations(dbr.tpid, drate.DestinationsTag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, destination := range dm {
|
||||
ap := activationPeriods[ratingProfile.destRatesTimingTag]
|
||||
newAP := &ActivationPeriod{ActivationTime: at}
|
||||
newAP.Intervals = append(newAP.Intervals, ap.Intervals...)
|
||||
resultRatingProfile.AddActivationPeriodIfNotPresent(destination.Id, newAP)
|
||||
dbr.dataDb.SetDestination(destination)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ub.ActionTriggers = actionTriggers
|
||||
|
||||
return dbr.dataDb.SetRatingProfile(resultRatingProfile)
|
||||
return dbr.dataDb.SetUserBalance(ub)
|
||||
}
|
||||
|
||||
@@ -27,13 +27,18 @@ import (
|
||||
type MinuteBucket struct {
|
||||
Seconds float64
|
||||
Weight float64
|
||||
Price float64
|
||||
Percent float64 // percentage from standard price
|
||||
Price float64 // percentage from standard price or absolute value depending on Type
|
||||
PriceType string
|
||||
DestinationId string
|
||||
ExpirationDate time.Time
|
||||
precision int
|
||||
}
|
||||
|
||||
const (
|
||||
PERCENT = "PERCENT"
|
||||
ABSOLUTE = "ABSOLUTE"
|
||||
)
|
||||
|
||||
// Returns the available number of seconds for a specified credit
|
||||
func (mb *MinuteBucket) GetSecondsForCredit(credit float64) (seconds float64) {
|
||||
seconds = mb.Seconds
|
||||
@@ -49,7 +54,7 @@ func (mb *MinuteBucket) Clone() *MinuteBucket {
|
||||
Seconds: mb.Seconds,
|
||||
Weight: mb.Weight,
|
||||
Price: mb.Price,
|
||||
Percent: mb.Percent,
|
||||
PriceType: mb.PriceType,
|
||||
DestinationId: mb.DestinationId,
|
||||
}
|
||||
}
|
||||
@@ -59,7 +64,7 @@ func (mb *MinuteBucket) Equal(o *MinuteBucket) bool {
|
||||
return mb.DestinationId == o.DestinationId &&
|
||||
mb.Weight == o.Weight &&
|
||||
mb.Price == o.Price &&
|
||||
mb.Percent == o.Percent
|
||||
mb.PriceType == o.PriceType
|
||||
}
|
||||
|
||||
func (mb *MinuteBucket) IsExpired() bool {
|
||||
|
||||
@@ -57,16 +57,16 @@ func TestMinutBucketSortPrice(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMinutBucketEqual(t *testing.T) {
|
||||
mb1 := &MinuteBucket{Weight: 1, precision: 1, Price: 1, Percent: 1, DestinationId: ""}
|
||||
mb2 := &MinuteBucket{Weight: 1, precision: 1, Price: 1, Percent: 1, DestinationId: ""}
|
||||
mb3 := &MinuteBucket{Weight: 1, precision: 1, Price: 2, Percent: 1, DestinationId: ""}
|
||||
mb1 := &MinuteBucket{Weight: 1, precision: 1, Price: 1, PriceType: ABSOLUTE, DestinationId: ""}
|
||||
mb2 := &MinuteBucket{Weight: 1, precision: 1, Price: 1, PriceType: ABSOLUTE, DestinationId: ""}
|
||||
mb3 := &MinuteBucket{Weight: 1, precision: 1, Price: 2, PriceType: ABSOLUTE, DestinationId: ""}
|
||||
if !mb1.Equal(mb2) || mb2.Equal(mb3) {
|
||||
t.Error("Equal failure!", mb1, mb2, mb3)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMinutBucketClone(t *testing.T) {
|
||||
mb1 := &MinuteBucket{Seconds: 1, Weight: 2, Price: 3, Percent: 4, DestinationId: "5"}
|
||||
mb1 := &MinuteBucket{Seconds: 1, Weight: 2, Price: 3, PriceType: ABSOLUTE, DestinationId: "5"}
|
||||
mb2 := mb1.Clone()
|
||||
if mb1 == mb2 || !reflect.DeepEqual(mb1, mb2) {
|
||||
t.Error("Cloning failure: ", mb1, mb2)
|
||||
|
||||
@@ -522,7 +522,7 @@ func (mb *MinuteBucket) Store() (result string, err error) {
|
||||
result += strconv.FormatFloat(mb.Seconds, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(mb.Weight, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(mb.Price, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(mb.Percent, 'f', -1, 64) + ";"
|
||||
result += mb.PriceType + ";"
|
||||
result += mb.DestinationId
|
||||
return
|
||||
}
|
||||
@@ -533,7 +533,7 @@ func (mb *MinuteBucket) Restore(input string) error {
|
||||
mb.Seconds, _ = strconv.ParseFloat(elements[0], 64)
|
||||
mb.Weight, _ = strconv.ParseFloat(elements[1], 64)
|
||||
mb.Price, _ = strconv.ParseFloat(elements[2], 64)
|
||||
mb.Percent, _ = strconv.ParseFloat(elements[3], 64)
|
||||
mb.PriceType = elements[3]
|
||||
mb.DestinationId = elements[4]
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -990,13 +990,7 @@ func (self *SQLStorage) GetTpActions(tpid, tag string) (map[string][]*Action, er
|
||||
ExpirationDate: expDate,
|
||||
}
|
||||
} else {
|
||||
var percent, price float64
|
||||
if rate_type == PERCENT {
|
||||
percent = rate
|
||||
}
|
||||
if rate_type == ABSOLUTE {
|
||||
price = rate
|
||||
}
|
||||
var price float64
|
||||
a = &Action{
|
||||
Id: utils.GenUUID(),
|
||||
ActionType: action,
|
||||
@@ -1008,7 +1002,7 @@ func (self *SQLStorage) GetTpActions(tpid, tag string) (map[string][]*Action, er
|
||||
Seconds: units,
|
||||
Weight: minutes_weight,
|
||||
Price: price,
|
||||
Percent: percent,
|
||||
PriceType: rate_type,
|
||||
DestinationId: destinations_tag,
|
||||
ExpirationDate: expDate,
|
||||
},
|
||||
|
||||
@@ -28,10 +28,10 @@ func TestUnitsCounterStoreRestore(t *testing.T) {
|
||||
Direction: OUTBOUND,
|
||||
BalanceId: SMS,
|
||||
Units: 100,
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
}
|
||||
r, err := uc.Store()
|
||||
if err != nil || r != "OUT/SMS/100/0;20;1;0;NAT,0;10;10;0;RET" {
|
||||
if err != nil || r != "OUT/SMS/100/0;20;1;;NAT,0;10;10;ABSOLUTE;RET" {
|
||||
t.Errorf("Error serializing units counter: %v", string(r))
|
||||
}
|
||||
o := &UnitsCounter{}
|
||||
@@ -46,7 +46,7 @@ func TestUnitsCounterAddMinuteBucket(t *testing.T) {
|
||||
Direction: OUTBOUND,
|
||||
BalanceId: SMS,
|
||||
Units: 100,
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
}
|
||||
uc.addMinutes(20, "test")
|
||||
if len(uc.MinuteBuckets) != 2 {
|
||||
@@ -59,7 +59,7 @@ func TestUnitsCounterAddMinuteBucketExists(t *testing.T) {
|
||||
Direction: OUTBOUND,
|
||||
BalanceId: SMS,
|
||||
Units: 100,
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
}
|
||||
uc.addMinutes(5, "0723")
|
||||
if len(uc.MinuteBuckets) != 2 || uc.MinuteBuckets[0].Seconds != 15 {
|
||||
|
||||
@@ -38,9 +38,6 @@ const (
|
||||
TRAFFIC = "INTERNET"
|
||||
TRAFFIC_TIME = "INTERNET_TIME"
|
||||
MINUTES = "MINUTES"
|
||||
// Price types
|
||||
PERCENT = "PERCENT"
|
||||
ABSOLUTE = "ABSOLUTE"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -283,7 +280,7 @@ func (ub *UserBalance) debitBalance(balanceId string, amount float64, count bool
|
||||
}
|
||||
|
||||
// Scans the action trigers and execute the actions for which trigger is met
|
||||
func (ub *UserBalance) executeActionTriggers() {
|
||||
func (ub *UserBalance) executeActionTriggers(a *Action) {
|
||||
ub.ActionTriggers.Sort()
|
||||
for _, at := range ub.ActionTriggers {
|
||||
if at.Executed {
|
||||
@@ -291,6 +288,13 @@ func (ub *UserBalance) executeActionTriggers() {
|
||||
// the next reset (see RESET_TRIGGERS action type)
|
||||
continue
|
||||
}
|
||||
if a != nil && (at.BalanceId != a.BalanceId ||
|
||||
at.Direction != a.Direction ||
|
||||
(a.MinuteBucket != nil &&
|
||||
(at.ThresholdType != a.MinuteBucket.PriceType ||
|
||||
at.ThresholdValue != a.MinuteBucket.Price))) {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(at.ThresholdType, "COUNTER") {
|
||||
for _, uc := range ub.UnitCounters {
|
||||
if uc.BalanceId == at.BalanceId {
|
||||
@@ -358,10 +362,19 @@ func (ub *UserBalance) executeActionTriggers() {
|
||||
}
|
||||
|
||||
// Mark all action trigers as ready for execution
|
||||
func (ub *UserBalance) resetActionTriggers() {
|
||||
// If the action is not nil it acts like a filter
|
||||
func (ub *UserBalance) resetActionTriggers(a *Action) {
|
||||
for _, at := range ub.ActionTriggers {
|
||||
if a != nil && (at.BalanceId != a.BalanceId ||
|
||||
at.Direction != a.Direction ||
|
||||
(a.MinuteBucket != nil &&
|
||||
(at.ThresholdType != a.MinuteBucket.PriceType ||
|
||||
at.ThresholdValue != a.MinuteBucket.Price))) {
|
||||
continue
|
||||
}
|
||||
at.Executed = false
|
||||
}
|
||||
ub.executeActionTriggers(a)
|
||||
}
|
||||
|
||||
// Returns the unit counter that matches the specified action type
|
||||
@@ -396,7 +409,7 @@ func (ub *UserBalance) countUnits(a *Action) {
|
||||
} else {
|
||||
unitsCounter.Units += a.Units
|
||||
}
|
||||
ub.executeActionTriggers()
|
||||
ub.executeActionTriggers(nil)
|
||||
}
|
||||
|
||||
// Create minute counters for all triggered actions that have actions operating on minute buckets
|
||||
|
||||
@@ -100,7 +100,7 @@ func TestUserBalanceStoreRestore(t *testing.T) {
|
||||
Direction: OUTBOUND,
|
||||
BalanceId: SMS,
|
||||
Units: 100,
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
}
|
||||
at := &ActionTrigger{
|
||||
Id: "some_uuid",
|
||||
@@ -117,7 +117,7 @@ func TestUserBalanceStoreRestore(t *testing.T) {
|
||||
Id: "rif",
|
||||
Type: UB_TYPE_POSTPAID,
|
||||
BalanceMap: map[string]BalanceChain{SMS + OUTBOUND: BalanceChain{&Balance{Value: 14, ExpirationDate: zeroTime}}, TRAFFIC + OUTBOUND: BalanceChain{&Balance{Value: 1024, ExpirationDate: zeroTime}}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
UnitCounters: []*UnitsCounter{uc, uc},
|
||||
ActionTriggers: ActionTriggerPriotityList{at, at, at},
|
||||
}
|
||||
@@ -361,7 +361,7 @@ func TestUserBalancedebitMinuteBucket(t *testing.T) {
|
||||
Id: "rif",
|
||||
Type: UB_TYPE_POSTPAID,
|
||||
BalanceMap: map[string]BalanceChain{SMS: BalanceChain{&Balance{Value: 14}}, TRAFFIC: BalanceChain{&Balance{Value: 1204}}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
}
|
||||
newMb := &MinuteBucket{Weight: 20, Price: 1, DestinationId: "NEW"}
|
||||
ub.debitMinuteBucket(newMb)
|
||||
@@ -376,7 +376,7 @@ func TestUserBalancedebitMinuteBucketExists(t *testing.T) {
|
||||
Id: "rif",
|
||||
Type: UB_TYPE_POSTPAID,
|
||||
BalanceMap: map[string]BalanceChain{SMS + OUTBOUND: BalanceChain{&Balance{Value: 14}}, TRAFFIC + OUTBOUND: BalanceChain{&Balance{Value: 1024}}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 15, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 15, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
}
|
||||
newMb := &MinuteBucket{Seconds: -10, Weight: 20, Price: 1, DestinationId: "NAT"}
|
||||
ub.debitMinuteBucket(newMb)
|
||||
@@ -390,7 +390,7 @@ func TestUserBalanceAddMinuteNil(t *testing.T) {
|
||||
Id: "rif",
|
||||
Type: UB_TYPE_POSTPAID,
|
||||
BalanceMap: map[string]BalanceChain{SMS + OUTBOUND: BalanceChain{&Balance{Value: 14}}, TRAFFIC + OUTBOUND: BalanceChain{&Balance{Value: 1024}}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
}
|
||||
ub.debitMinuteBucket(nil)
|
||||
if len(ub.MinuteBuckets) != 2 {
|
||||
@@ -422,7 +422,7 @@ func TestUserBalanceExecuteTriggeredActions(t *testing.T) {
|
||||
Id: "TEST_UB",
|
||||
BalanceMap: map[string]BalanceChain{CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 100}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Direction: OUTBOUND, Units: 1}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ThresholdType: "MAX_COUNTER", ActionsId: "TEST_ACTIONS"}},
|
||||
}
|
||||
ub.countUnits(&Action{BalanceId: CREDIT, Units: 1})
|
||||
@@ -435,7 +435,7 @@ func TestUserBalanceExecuteTriggeredActions(t *testing.T) {
|
||||
t.Error("Error executing triggered actions", ub.BalanceMap[CREDIT+OUTBOUND][0].Value, ub.MinuteBuckets[0].Seconds)
|
||||
}
|
||||
// we can reset them
|
||||
ub.resetActionTriggers()
|
||||
ub.resetActionTriggers(nil)
|
||||
ub.countUnits(&Action{BalanceId: CREDIT, Direction: OUTBOUND, Units: 1})
|
||||
if ub.BalanceMap[CREDIT+OUTBOUND][0].Value != 120 || ub.MinuteBuckets[0].Seconds != 30 {
|
||||
t.Error("Error executing triggered actions", ub.BalanceMap[CREDIT+OUTBOUND][0].Value, ub.MinuteBuckets[0].Seconds)
|
||||
@@ -447,7 +447,7 @@ func TestUserBalanceExecuteTriggeredActionsBalance(t *testing.T) {
|
||||
Id: "TEST_UB",
|
||||
BalanceMap: map[string]BalanceChain{CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 100}}},
|
||||
UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Direction: OUTBOUND, Units: 1}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, Percent: 0, DestinationId: "RET"}},
|
||||
MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: ABSOLUTE, DestinationId: "RET"}},
|
||||
ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, Direction: OUTBOUND, ThresholdValue: 100, ThresholdType: "MIN_COUNTER", ActionsId: "TEST_ACTIONS"}},
|
||||
}
|
||||
ub.countUnits(&Action{BalanceId: CREDIT, Units: 1})
|
||||
|
||||
Reference in New Issue
Block a user