mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
SetAccount api
This commit is contained in:
@@ -385,6 +385,7 @@ type AttrAddBalance struct {
|
||||
RatingSubject string
|
||||
Categories string
|
||||
DestinationIds string
|
||||
TimingIds string
|
||||
Weight float64
|
||||
SharedGroups string
|
||||
Overwrite bool // When true it will reset if the balance is already there
|
||||
@@ -434,6 +435,7 @@ func (self *ApierV1) AddBalance(attr *AttrAddBalance, reply *string) error {
|
||||
Categories: utils.ParseStringMap(attr.Categories),
|
||||
Weight: attr.Weight,
|
||||
SharedGroups: utils.ParseStringMap(attr.SharedGroups),
|
||||
TimingIDs: utils.ParseStringMap(attr.TimingIds),
|
||||
Blocker: attr.Blocker,
|
||||
Disabled: attr.Disabled,
|
||||
},
|
||||
@@ -478,6 +480,7 @@ func (self *ApierV1) EnableDisableBalance(attr *AttrAddBalance, reply *string) e
|
||||
DestinationIds: utils.ParseStringMap(attr.DestinationIds),
|
||||
Weight: attr.Weight,
|
||||
SharedGroups: utils.ParseStringMap(attr.SharedGroups),
|
||||
TimingIDs: utils.ParseStringMap(attr.TimingIds),
|
||||
Blocker: attr.Blocker,
|
||||
Disabled: attr.Disabled,
|
||||
},
|
||||
@@ -522,6 +525,7 @@ func (self *ApierV1) RemoveBalances(attr *AttrAddBalance, reply *string) error {
|
||||
Categories: utils.ParseStringMap(attr.Categories),
|
||||
Weight: attr.Weight,
|
||||
SharedGroups: utils.ParseStringMap(attr.SharedGroups),
|
||||
TimingIDs: utils.ParseStringMap(attr.TimingIds),
|
||||
Blocker: attr.Blocker,
|
||||
Disabled: attr.Disabled,
|
||||
},
|
||||
@@ -535,6 +539,65 @@ func (self *ApierV1) RemoveBalances(attr *AttrAddBalance, reply *string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type AttrSetBalance struct {
|
||||
Tenant string
|
||||
Account string
|
||||
BalanceType string
|
||||
BalanceUuid *string
|
||||
BalanceId *string
|
||||
Directions *string
|
||||
Value *float64
|
||||
ExpiryTime *string
|
||||
RatingSubject *string
|
||||
Categories *string
|
||||
DestinationIds *string
|
||||
SharedGroups *string
|
||||
TimingIds *string
|
||||
Weight *float64
|
||||
Blocker *bool
|
||||
Disabled *bool
|
||||
expTime time.Time
|
||||
}
|
||||
|
||||
func (attr *AttrSetBalance) SetBalance(b *engine.Balance) {
|
||||
if attr.Directions != nil {
|
||||
b.Directions = utils.ParseStringMap(*attr.Directions)
|
||||
}
|
||||
if attr.Value != nil {
|
||||
b.Value = *attr.Value
|
||||
}
|
||||
if attr.ExpiryTime != nil {
|
||||
b.ExpirationDate = attr.expTime
|
||||
}
|
||||
if attr.RatingSubject != nil {
|
||||
b.RatingSubject = *attr.RatingSubject
|
||||
}
|
||||
if attr.Categories != nil {
|
||||
b.Categories = utils.ParseStringMap(*attr.Categories)
|
||||
}
|
||||
if attr.DestinationIds != nil {
|
||||
b.DestinationIds = utils.ParseStringMap(*attr.DestinationIds)
|
||||
}
|
||||
if attr.SharedGroups != nil {
|
||||
b.SharedGroups = utils.ParseStringMap(*attr.SharedGroups)
|
||||
}
|
||||
if attr.TimingIds != nil {
|
||||
b.TimingIDs = utils.ParseStringMap(*attr.TimingIds)
|
||||
}
|
||||
if attr.Weight != nil {
|
||||
b.Weight = *attr.Weight
|
||||
}
|
||||
if attr.Blocker != nil {
|
||||
b.Blocker = *attr.Blocker
|
||||
}
|
||||
if attr.Disabled != nil {
|
||||
b.Disabled = *attr.Disabled
|
||||
}
|
||||
b.SetDirty() // Mark the balance as dirty since we have modified and it should be checked by action triggers
|
||||
}
|
||||
|
||||
/* // SetAccount api using action and action timing to set balance,
|
||||
//to be uncommented when using pointers in action.balance
|
||||
func (self *ApierV1) SetBalance(attr *AttrAddBalance, reply *string) error {
|
||||
if missing := utils.MissingStructFields(attr, []string{"Tenant", "Account", "BalanceType"}); len(missing) != 0 {
|
||||
return utils.NewErrMandatoryIeMissing(missing...)
|
||||
@@ -551,6 +614,7 @@ func (self *ApierV1) SetBalance(attr *AttrAddBalance, reply *string) error {
|
||||
if _, err := self.AccountDb.GetAccount(accID); err != nil {
|
||||
return utils.ErrNotFound
|
||||
}
|
||||
|
||||
at := &engine.ActionTiming{}
|
||||
at.SetAccountIDs(utils.StringMap{accID: true})
|
||||
|
||||
@@ -569,6 +633,7 @@ func (self *ApierV1) SetBalance(attr *AttrAddBalance, reply *string) error {
|
||||
Categories: utils.ParseStringMap(attr.Categories),
|
||||
Weight: attr.Weight,
|
||||
SharedGroups: utils.ParseStringMap(attr.SharedGroups),
|
||||
TimingIDs: utils.ParseStringMap(attr.TimingIds),
|
||||
Blocker: true,
|
||||
Disabled: attr.Disabled,
|
||||
},
|
||||
@@ -581,3 +646,98 @@ func (self *ApierV1) SetBalance(attr *AttrAddBalance, reply *string) error {
|
||||
*reply = OK
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
|
||||
func (self *ApierV1) SetBalance(attr *AttrSetBalance, reply *string) error {
|
||||
if missing := utils.MissingStructFields(attr, []string{"Tenant", "Account", "BalanceType"}); len(missing) != 0 {
|
||||
return utils.NewErrMandatoryIeMissing(missing...)
|
||||
}
|
||||
if (attr.BalanceId == nil || *attr.BalanceId == "") &&
|
||||
(attr.BalanceUuid == nil || *attr.BalanceUuid == "") {
|
||||
return utils.NewErrMandatoryIeMissing("BalanceId", "or", "BalanceUuid")
|
||||
}
|
||||
var err error
|
||||
if attr.ExpiryTime != nil {
|
||||
attr.expTime, err = utils.ParseTimeDetectLayout(*attr.ExpiryTime, self.Config.DefaultTimezone)
|
||||
if err != nil {
|
||||
*reply = err.Error()
|
||||
return err
|
||||
}
|
||||
}
|
||||
accID := utils.ConcatenatedKey(attr.Tenant, attr.Account)
|
||||
_, err = engine.Guardian.Guard(func() (interface{}, error) {
|
||||
account, err := self.AccountDb.GetAccount(accID)
|
||||
if err != nil {
|
||||
return 0, utils.ErrNotFound
|
||||
}
|
||||
|
||||
if account.BalanceMap == nil {
|
||||
account.BalanceMap = make(map[string]engine.BalanceChain, 1)
|
||||
}
|
||||
var previousSharedGroups utils.StringMap // kept for comparison
|
||||
var balance *engine.Balance
|
||||
var found bool
|
||||
for _, b := range account.BalanceMap[attr.BalanceType] {
|
||||
if b.IsExpired() {
|
||||
continue
|
||||
}
|
||||
if (attr.BalanceUuid != nil && b.Uuid == *attr.BalanceUuid) ||
|
||||
(attr.BalanceId != nil && b.Id == *attr.BalanceId) {
|
||||
previousSharedGroups = b.SharedGroups
|
||||
balance = b
|
||||
found = true
|
||||
break // only set one balance
|
||||
}
|
||||
}
|
||||
|
||||
// if it is not found then we add it to the list
|
||||
if balance == nil {
|
||||
balance := &engine.Balance{}
|
||||
balance.Uuid = utils.GenUUID() // alway overwrite the uuid for consistency
|
||||
account.BalanceMap[attr.BalanceType] = append(account.BalanceMap[attr.BalanceType], balance)
|
||||
}
|
||||
|
||||
if attr.BalanceId != nil && *attr.BalanceId == utils.META_DEFAULT {
|
||||
balance.Id = utils.META_DEFAULT
|
||||
if attr.Value != nil {
|
||||
balance.Value = *attr.Value
|
||||
}
|
||||
} else {
|
||||
attr.SetBalance(balance)
|
||||
}
|
||||
|
||||
if !found || !previousSharedGroups.Equal(balance.SharedGroups) {
|
||||
_, err = engine.Guardian.Guard(func() (interface{}, error) {
|
||||
for sgId := range balance.SharedGroups {
|
||||
// add shared group member
|
||||
sg, err := self.RatingDb.GetSharedGroup(sgId, false)
|
||||
if err != nil || sg == nil {
|
||||
//than is problem
|
||||
utils.Logger.Warning(fmt.Sprintf("Could not get shared group: %v", sgId))
|
||||
} else {
|
||||
if _, found := sg.MemberIds[account.Id]; !found {
|
||||
// add member and save
|
||||
if sg.MemberIds == nil {
|
||||
sg.MemberIds = make(utils.StringMap)
|
||||
}
|
||||
sg.MemberIds[account.Id] = true
|
||||
self.RatingDb.SetSharedGroup(sg)
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0, nil
|
||||
}, 0, balance.SharedGroups.Slice()...)
|
||||
}
|
||||
|
||||
account.InitCounters()
|
||||
account.ExecuteActionTriggers(nil)
|
||||
self.AccountDb.SetAccount(account)
|
||||
return 0, nil
|
||||
}, 0, accID)
|
||||
if err != nil {
|
||||
*reply = err.Error()
|
||||
return err
|
||||
}
|
||||
*reply = utils.OK
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func init() {
|
||||
type CmdSetBalance struct {
|
||||
name string
|
||||
rpcMethod string
|
||||
rpcParams *v1.AttrAddBalance
|
||||
rpcParams *v1.AttrSetBalance
|
||||
*CommandExecuter
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func (self *CmdSetBalance) RpcMethod() string {
|
||||
|
||||
func (self *CmdSetBalance) RpcParams(reset bool) interface{} {
|
||||
if reset || self.rpcParams == nil {
|
||||
self.rpcParams = &v1.AttrAddBalance{BalanceType: utils.MONETARY, Overwrite: false}
|
||||
self.rpcParams = &v1.AttrSetBalance{BalanceType: utils.MONETARY}
|
||||
}
|
||||
return self.rpcParams
|
||||
}
|
||||
|
||||
@@ -122,7 +122,11 @@ func (ub *Account) setBalanceAction(a *Action) error {
|
||||
bClone.Id = b.Id
|
||||
bClone.Uuid = b.Uuid
|
||||
previousSharedGroups = b.SharedGroups
|
||||
*b = *bClone
|
||||
if bClone.Id != utils.META_DEFAULT {
|
||||
*b = *bClone
|
||||
} else {
|
||||
b.Value = bClone.GetValue()
|
||||
}
|
||||
found = true
|
||||
break // only set one balance
|
||||
}
|
||||
@@ -141,27 +145,34 @@ func (ub *Account) setBalanceAction(a *Action) error {
|
||||
bClone.Uuid = utils.GenUUID() // alway overwrite the uuid for consistency
|
||||
ub.BalanceMap[balanceType] = append(ub.BalanceMap[balanceType], bClone)
|
||||
}
|
||||
|
||||
if !found || !previousSharedGroups.Equal(bClone.SharedGroups) {
|
||||
for sgId := range a.Balance.SharedGroups {
|
||||
// add shared group member
|
||||
sg, err := ratingStorage.GetSharedGroup(sgId, false)
|
||||
if err != nil || sg == nil {
|
||||
//than is problem
|
||||
utils.Logger.Warning(fmt.Sprintf("Could not get shared group: %v", sgId))
|
||||
} else {
|
||||
if _, found := sg.MemberIds[ub.Id]; !found {
|
||||
// add member and save
|
||||
if sg.MemberIds == nil {
|
||||
sg.MemberIds = make(utils.StringMap)
|
||||
_, err := Guardian.Guard(func() (interface{}, error) {
|
||||
for sgId := range bClone.SharedGroups {
|
||||
// add shared group member
|
||||
sg, err := ratingStorage.GetSharedGroup(sgId, false)
|
||||
if err != nil || sg == nil {
|
||||
//than is problem
|
||||
utils.Logger.Warning(fmt.Sprintf("Could not get shared group: %v", sgId))
|
||||
} else {
|
||||
if _, found := sg.MemberIds[ub.Id]; !found {
|
||||
// add member and save
|
||||
if sg.MemberIds == nil {
|
||||
sg.MemberIds = make(utils.StringMap)
|
||||
}
|
||||
sg.MemberIds[ub.Id] = true
|
||||
ratingStorage.SetSharedGroup(sg)
|
||||
}
|
||||
sg.MemberIds[ub.Id] = true
|
||||
ratingStorage.SetSharedGroup(sg)
|
||||
}
|
||||
}
|
||||
return 0, nil
|
||||
}, 0, bClone.SharedGroups.Slice()...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
ub.InitCounters()
|
||||
ub.executeActionTriggers(nil)
|
||||
ub.ExecuteActionTriggers(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -222,26 +233,31 @@ func (ub *Account) debitBalanceAction(a *Action, reset bool) error {
|
||||
}
|
||||
}
|
||||
ub.BalanceMap[balanceType] = append(ub.BalanceMap[balanceType], bClone)
|
||||
|
||||
for sgId := range a.Balance.SharedGroups {
|
||||
// add shared group member
|
||||
sg, err := ratingStorage.GetSharedGroup(sgId, false)
|
||||
if err != nil || sg == nil {
|
||||
//than is problem
|
||||
utils.Logger.Warning(fmt.Sprintf("Could not get shared group: %v", sgId))
|
||||
} else {
|
||||
if _, found := sg.MemberIds[ub.Id]; !found {
|
||||
// add member and save
|
||||
if sg.MemberIds == nil {
|
||||
sg.MemberIds = make(utils.StringMap)
|
||||
_, err := Guardian.Guard(func() (interface{}, error) {
|
||||
for sgId := range bClone.SharedGroups {
|
||||
// add shared group member
|
||||
sg, err := ratingStorage.GetSharedGroup(sgId, false)
|
||||
if err != nil || sg == nil {
|
||||
//than is problem
|
||||
utils.Logger.Warning(fmt.Sprintf("Could not get shared group: %v", sgId))
|
||||
} else {
|
||||
if _, found := sg.MemberIds[ub.Id]; !found {
|
||||
// add member and save
|
||||
if sg.MemberIds == nil {
|
||||
sg.MemberIds = make(utils.StringMap)
|
||||
}
|
||||
sg.MemberIds[ub.Id] = true
|
||||
ratingStorage.SetSharedGroup(sg)
|
||||
}
|
||||
sg.MemberIds[ub.Id] = true
|
||||
ratingStorage.SetSharedGroup(sg)
|
||||
}
|
||||
}
|
||||
return 0, nil
|
||||
}, 0, bClone.SharedGroups.Slice()...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
ub.executeActionTriggers(nil)
|
||||
ub.ExecuteActionTriggers(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -552,7 +568,7 @@ func (ub *Account) refundIncrement(increment *Increment, cd *CallDescriptor, cou
|
||||
}
|
||||
|
||||
// Scans the action trigers and execute the actions for which trigger is met
|
||||
func (ub *Account) executeActionTriggers(a *Action) {
|
||||
func (ub *Account) ExecuteActionTriggers(a *Action) {
|
||||
ub.ActionTriggers.Sort()
|
||||
for _, at := range ub.ActionTriggers {
|
||||
// sanity check
|
||||
@@ -618,7 +634,7 @@ func (acc *Account) ResetActionTriggers(a *Action) {
|
||||
}
|
||||
at.Executed = false
|
||||
}
|
||||
acc.executeActionTriggers(a)
|
||||
acc.ExecuteActionTriggers(a)
|
||||
}
|
||||
|
||||
// Sets/Unsets recurrent flag for action triggers
|
||||
@@ -634,7 +650,7 @@ func (acc *Account) SetRecurrent(a *Action, recurrent bool) {
|
||||
// Increments the counter for the type
|
||||
func (acc *Account) countUnits(amount float64, kind string, cc *CallCost, b *Balance) {
|
||||
acc.UnitCounters.addUnits(amount, kind, cc, b)
|
||||
acc.executeActionTriggers(nil)
|
||||
acc.ExecuteActionTriggers(nil)
|
||||
}
|
||||
|
||||
// Create counters for all triggered actions
|
||||
|
||||
@@ -976,7 +976,7 @@ func TestAccountExpActionTrigger(t *testing.T) {
|
||||
&ActionTrigger{ID: "check expired balances", BalanceType: utils.MONETARY, BalanceDirections: utils.StringMap{utils.OUT: true}, ThresholdValue: 10, ThresholdType: utils.TRIGGER_BALANCE_EXPIRED, ActionsId: "TEST_ACTIONS"},
|
||||
},
|
||||
}
|
||||
ub.executeActionTriggers(nil)
|
||||
ub.ExecuteActionTriggers(nil)
|
||||
if ub.BalanceMap[utils.MONETARY][0].IsExpired() ||
|
||||
ub.BalanceMap[utils.MONETARY][0].GetValue() != 10 || // expired was cleaned
|
||||
ub.BalanceMap[utils.VOICE][0].GetValue() != 20 ||
|
||||
|
||||
@@ -57,7 +57,7 @@ const (
|
||||
DENY_NEGATIVE = "*deny_negative"
|
||||
RESET_ACCOUNT = "*reset_account"
|
||||
REMOVE_ACCOUNT = "*remove_account"
|
||||
SET_BALANCE = "*set_balance"
|
||||
SET_BALANCE = "*set_balance" // not ready for production until switching to pointers
|
||||
REMOVE_BALANCE = "*remove_balance"
|
||||
TOPUP_RESET = "*topup_reset"
|
||||
TOPUP = "*topup"
|
||||
|
||||
@@ -359,6 +359,10 @@ func (b *Balance) SetValue(amount float64) {
|
||||
b.dirty = true
|
||||
}
|
||||
|
||||
func (b *Balance) SetDirty() {
|
||||
b.dirty = true
|
||||
}
|
||||
|
||||
func (b *Balance) debitUnits(cd *CallDescriptor, ub *Account, moneyBalances BalanceChain, count bool, dryRun, debitConnectFee bool) (cc *CallCost, err error) {
|
||||
if !b.IsActiveAt(cd.TimeStart) || b.GetValue() <= 0 {
|
||||
return
|
||||
|
||||
@@ -86,6 +86,9 @@ func ParseStringMap(s string) StringMap {
|
||||
}
|
||||
|
||||
func (sm StringMap) Equal(om StringMap) bool {
|
||||
if sm == nil && om != nil {
|
||||
return false
|
||||
}
|
||||
if len(sm) != len(om) {
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user