mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-17 06:09:53 +05:00
@@ -211,6 +211,45 @@ func (self *ApierV1) EnableDisableBalance(attr *AttrAddBalance, reply *string) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *ApierV1) RemoveBalances(attr *AttrAddBalance, reply *string) error {
|
||||
expTime, err := utils.ParseDate(attr.ExpiryTime)
|
||||
if err != nil {
|
||||
*reply = err.Error()
|
||||
return err
|
||||
}
|
||||
accId := utils.ConcatenatedKey(attr.Tenant, attr.Account)
|
||||
if _, err := self.AccountDb.GetAccount(accId); err != nil {
|
||||
return utils.ErrNotFound
|
||||
}
|
||||
at := &engine.ActionPlan{
|
||||
AccountIds: []string{accId},
|
||||
}
|
||||
at.SetActions(engine.Actions{
|
||||
&engine.Action{
|
||||
ActionType: engine.REMOVE_BALANCE,
|
||||
BalanceType: attr.BalanceType,
|
||||
Balance: &engine.Balance{
|
||||
Uuid: attr.BalanceUuid,
|
||||
Id: attr.BalanceId,
|
||||
Value: attr.Value,
|
||||
ExpirationDate: expTime,
|
||||
RatingSubject: attr.RatingSubject,
|
||||
Directions: utils.ParseStringMap(attr.Directions),
|
||||
DestinationIds: utils.ParseStringMap(attr.DestinationIds),
|
||||
Weight: attr.Weight,
|
||||
SharedGroups: utils.ParseStringMap(attr.SharedGroups),
|
||||
Disabled: attr.Disabled,
|
||||
},
|
||||
},
|
||||
})
|
||||
if err := at.Execute(); err != nil {
|
||||
*reply = err.Error()
|
||||
return err
|
||||
}
|
||||
*reply = OK
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *ApierV1) ExecuteAction(attr *utils.AttrExecuteAction, reply *string) error {
|
||||
accId := utils.AccountKey(attr.Tenant, attr.Account)
|
||||
at := &engine.ActionPlan{
|
||||
|
||||
@@ -97,7 +97,6 @@ func (ub *Account) debitBalanceAction(a *Action, reset bool) error {
|
||||
if bClone == nil {
|
||||
return errors.New("nil balance")
|
||||
}
|
||||
|
||||
if ub.BalanceMap == nil {
|
||||
ub.BalanceMap = make(map[string]BalanceChain, 1)
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ const (
|
||||
DENY_NEGATIVE = "*deny_negative"
|
||||
RESET_ACCOUNT = "*reset_account"
|
||||
REMOVE_ACCOUNT = "*remove_account"
|
||||
REMOVE_BALANCE = "*remove_balance"
|
||||
TOPUP_RESET = "*topup_reset"
|
||||
TOPUP = "*topup"
|
||||
DEBIT_RESET = "*debit_reset"
|
||||
@@ -128,6 +129,8 @@ func getActionFunc(typ string) (actionTypeFunc, bool) {
|
||||
return mailAsync, true
|
||||
case SET_DDESTINATIONS:
|
||||
return setddestinations, true
|
||||
case REMOVE_BALANCE:
|
||||
return removeBalance, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
@@ -525,6 +528,29 @@ func setddestinations(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actio
|
||||
return nil
|
||||
}
|
||||
|
||||
func removeBalance(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) error {
|
||||
if _, exists := ub.BalanceMap[a.BalanceType]; !exists {
|
||||
return utils.ErrNotFound
|
||||
}
|
||||
bChain := ub.BalanceMap[a.BalanceType]
|
||||
found := false
|
||||
for i := 0; i < len(bChain); i++ {
|
||||
if bChain[i].MatchFilter(a.Balance, false) {
|
||||
// delete without preserving order
|
||||
bChain[i] = bChain[len(bChain)-1]
|
||||
bChain = bChain[:len(bChain)-1]
|
||||
i -= 1
|
||||
found = true
|
||||
}
|
||||
}
|
||||
ub.BalanceMap[a.BalanceType] = bChain
|
||||
if !found {
|
||||
return utils.ErrNotFound
|
||||
}
|
||||
// update account in storage
|
||||
return accountingStorage.SetAccount(ub)
|
||||
}
|
||||
|
||||
// Structure to store actions according to weight
|
||||
type Actions []*Action
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ package engine
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -1351,21 +1350,94 @@ func TestActionTransactionBalanceType(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionExecuteActionNonExistingAccount(t *testing.T) {
|
||||
func TestActionWithExpireWithoutExpire(t *testing.T) {
|
||||
err := accountingStorage.SetAccount(&Account{
|
||||
Id: "cgrates.org:exp",
|
||||
BalanceMap: map[string]BalanceChain{
|
||||
utils.MONETARY: BalanceChain{&Balance{
|
||||
Value: 10,
|
||||
}},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Error("Error setting account: ", err)
|
||||
}
|
||||
at := &ActionPlan{
|
||||
AccountIds: []string{"cgrates.org:exe"},
|
||||
AccountIds: []string{"cgrates.org:exp"},
|
||||
Timing: &RateInterval{},
|
||||
actions: []*Action{
|
||||
&Action{
|
||||
ActionType: TOPUP,
|
||||
BalanceType: utils.MONETARY,
|
||||
Balance: &Balance{Value: 1.1},
|
||||
BalanceType: utils.VOICE,
|
||||
Balance: &Balance{
|
||||
Value: 15,
|
||||
},
|
||||
},
|
||||
&Action{
|
||||
ActionType: TOPUP,
|
||||
BalanceType: utils.VOICE,
|
||||
Balance: &Balance{
|
||||
Value: 30,
|
||||
ExpirationDate: time.Date(2025, time.November, 11, 22, 39, 0, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
err = at.Execute()
|
||||
if err == nil {
|
||||
log.Print("Fail to return error on action execute: ", err)
|
||||
acc, err := accountingStorage.GetAccount("cgrates.org:exp")
|
||||
if err != nil || acc == nil {
|
||||
t.Errorf("Error getting account: %+v: %v", acc, err)
|
||||
}
|
||||
if len(acc.BalanceMap) != 2 ||
|
||||
len(acc.BalanceMap[utils.VOICE]) != 2 {
|
||||
t.Errorf("Error debiting expir and unexpire: %+v", acc.BalanceMap[utils.VOICE][0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionRemoveBalance(t *testing.T) {
|
||||
err := accountingStorage.SetAccount(&Account{
|
||||
Id: "cgrates.org:rembal",
|
||||
BalanceMap: map[string]BalanceChain{
|
||||
utils.MONETARY: BalanceChain{
|
||||
&Balance{
|
||||
Value: 10,
|
||||
},
|
||||
&Balance{
|
||||
Value: 10,
|
||||
DestinationIds: utils.NewStringMap("NAT", "RET"),
|
||||
ExpirationDate: time.Date(2025, time.November, 11, 22, 39, 0, 0, time.UTC),
|
||||
},
|
||||
&Balance{
|
||||
Value: 10,
|
||||
DestinationIds: utils.NewStringMap("NAT", "RET"),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Error("Error setting account: ", err)
|
||||
}
|
||||
at := &ActionPlan{
|
||||
AccountIds: []string{"cgrates.org:rembal"},
|
||||
Timing: &RateInterval{},
|
||||
actions: []*Action{
|
||||
&Action{
|
||||
ActionType: REMOVE_BALANCE,
|
||||
BalanceType: utils.MONETARY,
|
||||
Balance: &Balance{
|
||||
DestinationIds: utils.NewStringMap("NAT", "RET"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
err = at.Execute()
|
||||
acc, err := accountingStorage.GetAccount("cgrates.org:rembal")
|
||||
if err != nil || acc == nil {
|
||||
t.Errorf("Error getting account: %+v: %v", acc, err)
|
||||
}
|
||||
if len(acc.BalanceMap) != 1 ||
|
||||
len(acc.BalanceMap[utils.MONETARY]) != 1 {
|
||||
t.Errorf("Error removing balance: %+v", acc.BalanceMap[utils.MONETARY])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user