예제 #1
0
파일: accounts.go 프로젝트: bhepp/cgrates
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
}
예제 #2
0
파일: accounts.go 프로젝트: bhepp/cgrates
func (attr *AttrSetBalance) SetBalance(b *engine.Balance) {
	if b == nil {
		return
	}
	if attr.Directions != nil {
		b.Directions = utils.StringMapFromSlice(*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.StringMapFromSlice(*attr.Categories)
	}
	if attr.DestinationIDs != nil {
		b.DestinationIds = utils.StringMapFromSlice(*attr.DestinationIDs)
	}
	if attr.SharedGroups != nil {
		b.SharedGroups = utils.StringMapFromSlice(*attr.SharedGroups)
	}
	if attr.TimingIDs != nil {
		b.TimingIDs = utils.StringMapFromSlice(*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
}