mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Merge branch 'master' into lcr
This commit is contained in:
@@ -126,7 +126,7 @@ func (self *ApierV1) AddBalance(attr *AttrAddBalance, reply *string) error {
|
||||
Balance: &engine.Balance{
|
||||
Value: attr.Value,
|
||||
ExpirationDate: attr.ExpirationDate,
|
||||
RateSubject: attr.RatingSubject,
|
||||
RatingSubject: attr.RatingSubject,
|
||||
DestinationId: attr.DestinationId,
|
||||
Weight: attr.Weight,
|
||||
},
|
||||
@@ -300,7 +300,7 @@ func (self *ApierV1) SetActions(attrs AttrSetActions, reply *string) error {
|
||||
Value: apiAct.Units,
|
||||
Weight: apiAct.BalanceWeight,
|
||||
DestinationId: apiAct.DestinationId,
|
||||
RateSubject: apiAct.RatingSubject,
|
||||
RatingSubject: apiAct.RatingSubject,
|
||||
},
|
||||
}
|
||||
storeActions[idx] = a
|
||||
|
||||
156
charging_tests/ddazmbl1_test.go
Normal file
156
charging_tests/ddazmbl1_test.go
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
Rating system designed to be used in VoIP Carriers World
|
||||
Copyright (C) 2012-2014 ITsysCOM GmbH
|
||||
|
||||
This program is free software: you can Storagetribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITH*out ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package engine
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/cache2go"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/scheduler"
|
||||
)
|
||||
|
||||
var ratingDb engine.RatingStorage
|
||||
var acntDb engine.AccountingStorage
|
||||
|
||||
func init() {
|
||||
ratingDb, _ = engine.NewMapStorageJson()
|
||||
engine.SetRatingStorage(ratingDb)
|
||||
acntDb, _ = engine.NewMapStorageJson()
|
||||
engine.SetAccountingStorage(acntDb)
|
||||
}
|
||||
|
||||
func TestLoadCsvTp(t *testing.T) {
|
||||
timings := `ALWAYS,*any,*any,*any,*any,00:00:00
|
||||
ASAP,*any,*any,*any,*any,*asap`
|
||||
destinations := `DST_UK_Mobile_BIG5,447596
|
||||
DST_UK_Mobile_BIG5,447956`
|
||||
rates := `RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s,*up,8
|
||||
RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s,*up,8`
|
||||
destinationRates := `DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG
|
||||
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5`
|
||||
ratingPlans := `RP_UK_Mobile_BIG5_PKG,DR_UK_Mobile_BIG5_PKG,ALWAYS,10
|
||||
RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10`
|
||||
ratingProfiles := `cgrates.org,call,*out,*any,2013-01-06T00:00:00Z,RP_UK,
|
||||
cgrates.org,call,*out,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,`
|
||||
sharedGroups := ``
|
||||
actions := `TOPUP10_AC,*topup_reset,*monetary,*out,10,*unlimited,*any,,10,,,10
|
||||
TOPUP10_AC1,*topup_reset,*minutes,*out,40,*unlimited,DST_UK_Mobile_BIG5,discounted_minutes,10,,,10`
|
||||
actionPlans := `TOPUP10_AT,TOPUP10_AC,ASAP,10
|
||||
TOPUP10_AT,TOPUP10_AC1,ASAP,10`
|
||||
actionTriggers := ``
|
||||
accountActions := `cgrates.org,12345,*out,TOPUP10_AT,`
|
||||
csvr := engine.NewStringCSVReader(ratingDb, acntDb, ',', destinations, timings, rates, destinationRates, ratingPlans, ratingProfiles, sharedGroups, actions, actionPlans, actionTriggers, accountActions)
|
||||
if err := csvr.LoadDestinations(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := csvr.LoadTimings(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := csvr.LoadRates(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := csvr.LoadDestinationRates(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := csvr.LoadRatingPlans(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := csvr.LoadRatingProfiles(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := csvr.LoadSharedGroups(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := csvr.LoadActions(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := csvr.LoadActionTimings(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := csvr.LoadActionTriggers(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := csvr.LoadAccountActions(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
csvr.WriteToDatabase(false, false)
|
||||
if acnt, err := acntDb.GetAccount("*out:cgrates.org:12345"); err != nil {
|
||||
t.Error(err)
|
||||
} else if acnt == nil {
|
||||
t.Error("No account saved")
|
||||
}
|
||||
ratingDb.CacheRating(nil, nil, nil, nil)
|
||||
acntDb.CacheAccounting(nil, nil, nil)
|
||||
if cachedDests := cache2go.CountEntries(engine.DESTINATION_PREFIX); cachedDests != 2 {
|
||||
t.Error("Wrong number of cached destinations found", cachedDests)
|
||||
}
|
||||
if cachedRPlans := cache2go.CountEntries(engine.RATING_PLAN_PREFIX); cachedRPlans != 2 {
|
||||
t.Error("Wrong number of cached rating plans found", cachedRPlans)
|
||||
}
|
||||
if cachedRProfiles := cache2go.CountEntries(engine.RATING_PROFILE_PREFIX); cachedRProfiles != 2 {
|
||||
t.Error("Wrong number of cached rating profiles found", cachedRProfiles)
|
||||
}
|
||||
if cachedActions := cache2go.CountEntries(engine.ACTION_PREFIX); cachedActions != 2 {
|
||||
t.Error("Wrong number of cached actions found", cachedActions)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExecuteActions(t *testing.T) {
|
||||
scheduler.NewScheduler().LoadActionTimings(acntDb)
|
||||
time.Sleep(time.Duration(1) * time.Microsecond) // Give time to scheduler to topup the account
|
||||
if acnt, err := acntDb.GetAccount("*out:cgrates.org:12345"); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(acnt.BalanceMap) != 2 {
|
||||
t.Error("Account does not have enough balances: ", acnt.BalanceMap)
|
||||
} else if acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value != 40 {
|
||||
t.Errorf("Account does not have enough minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
|
||||
} else if acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value != 10 {
|
||||
t.Error("Account does not have enough monetary balance", acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDebit(t *testing.T) {
|
||||
cd := &engine.CallDescriptor{
|
||||
Direction: "*out",
|
||||
TOR: "call",
|
||||
Tenant: "cgrates.org",
|
||||
Subject: "12345",
|
||||
Account: "12345",
|
||||
Destination: "447956933443",
|
||||
TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2014, 3, 4, 6, 0, 10, 0, time.UTC),
|
||||
}
|
||||
if cc, err := cd.Debit(); err != nil {
|
||||
t.Error(err)
|
||||
} else if cc.Cost != 0.01 {
|
||||
t.Error("Wrong cost returned: ", cc.Cost)
|
||||
}
|
||||
acnt, err := acntDb.GetAccount("*out:cgrates.org:12345")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value != 20 {
|
||||
t.Error("Account does not have expected minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
|
||||
}
|
||||
if acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value != 9.99 {
|
||||
t.Error("Account does not have expected monetary balance", acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value)
|
||||
}
|
||||
}
|
||||
@@ -53,9 +53,9 @@ var (
|
||||
dbdata_encoding = flag.String("dbdata_encoding", cgrConfig.DBDataEncoding, "The encoding used to store object data in strings.")
|
||||
raterAddress = flag.String("rater_address", "", "Rater address for remote tests. Empty for internal rater.")
|
||||
tor = flag.String("tor", "call", "The type of record to use in queries.")
|
||||
tenant = flag.String("tenant", "call", "The type of record to use in queries.")
|
||||
tenant = flag.String("tenant", "cgrates.org", "The type of record to use in queries.")
|
||||
subject = flag.String("subject", "1001", "The rating subject to use in queries.")
|
||||
destination = flag.String("destination", "+4986517174963", "The destination to use in queries.")
|
||||
destination = flag.String("destination", "1002", "The destination to use in queries.")
|
||||
|
||||
nilDuration = time.Duration(0)
|
||||
)
|
||||
@@ -150,8 +150,8 @@ func main() {
|
||||
defer pprof.StopCPUProfile()
|
||||
}
|
||||
cd := &engine.CallDescriptor{
|
||||
TimeStart: time.Date(2013, time.December, 13, 22, 30, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2013, time.December, 13, 22, 31, 0, 0, time.UTC),
|
||||
TimeStart: time.Date(2014, time.December, 11, 55, 30, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2014, time.December, 11, 55, 31, 0, 0, time.UTC),
|
||||
CallDuration: 60 * time.Second,
|
||||
Direction: "*out",
|
||||
TOR: *tor,
|
||||
|
||||
@@ -38,7 +38,7 @@ type CmdDebitBalance struct {
|
||||
|
||||
// name should be exec's name
|
||||
func (self *CmdDebitBalance) Usage(name string) string {
|
||||
return fmt.Sprintf("\n\tUsage: cgr-console [cfg_opts...{-h}] debit_balance <tor> <tenant> <subject> <destination> <start_time|*now> <duration>")
|
||||
return fmt.Sprintf("\n\tUsage: cgr-console [cfg_opts...{-h}] debit_balance <tor> <tenant> <account> <subject> <destination> <start_time|*now> <duration>")
|
||||
}
|
||||
|
||||
// set param defaults
|
||||
@@ -50,17 +50,17 @@ func (self *CmdDebitBalance) defaults() error {
|
||||
|
||||
// Parses command line args and builds CmdBalance value
|
||||
func (self *CmdDebitBalance) FromArgs(args []string) error {
|
||||
if len(args) != 8 {
|
||||
if len(args) != 9 {
|
||||
return fmt.Errorf(self.Usage(""))
|
||||
}
|
||||
// Args look OK, set defaults before going further
|
||||
self.defaults()
|
||||
var tStart time.Time
|
||||
var err error
|
||||
if args[6] == "*now" {
|
||||
if args[7] == "*now" {
|
||||
tStart = time.Now()
|
||||
} else {
|
||||
tStart, err = utils.ParseDate(args[6])
|
||||
tStart, err = utils.ParseDate(args[7])
|
||||
if err != nil {
|
||||
fmt.Println("\n*start_time* should have one of the formats:")
|
||||
fmt.Println("\ttime.RFC3339\teg:2013-08-07T17:30:00Z in UTC")
|
||||
@@ -70,14 +70,15 @@ func (self *CmdDebitBalance) FromArgs(args []string) error {
|
||||
return fmt.Errorf(self.Usage(""))
|
||||
}
|
||||
}
|
||||
callDur, err := utils.ParseDurationWithSecs(args[7])
|
||||
callDur, err := utils.ParseDurationWithSecs(args[8])
|
||||
if err != nil {
|
||||
fmt.Println("\n\tExample durations: 60s for 60 seconds, 25m for 25minutes, 1m25s for one minute and 25 seconds\n")
|
||||
}
|
||||
self.rpcParams.TOR = args[2]
|
||||
self.rpcParams.Tenant = args[3]
|
||||
self.rpcParams.Subject = args[4]
|
||||
self.rpcParams.Destination = args[5]
|
||||
self.rpcParams.Account = args[4]
|
||||
self.rpcParams.Subject = args[5]
|
||||
self.rpcParams.Destination = args[6]
|
||||
self.rpcParams.TimeStart = tStart
|
||||
self.rpcParams.CallDuration = callDur
|
||||
self.rpcParams.TimeEnd = tStart.Add(callDur)
|
||||
|
||||
@@ -47,9 +47,9 @@ cd = {"Direction":"*out",
|
||||
"TOR":"call",
|
||||
"Tenant": "cgrates.org",
|
||||
"Subject": "1001",
|
||||
"Destination": "+49",
|
||||
"TimeStart": "2013-08-07T17:30:00Z",
|
||||
"TimeEnd": "2013-08-07T18:30:00Z",
|
||||
"Destination": "1002",
|
||||
"TimeStart": "2014-04-03T11:12:23.190554134+02:00",
|
||||
"TimeEnd": "2014-04-03T11:13:23.190554134+02:00",
|
||||
"CallDuration": 60000000000,
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ cd = {"Direction":"*out",
|
||||
|
||||
start_time = time.time()
|
||||
i = 0
|
||||
runs = 1e5
|
||||
runs = 5e5
|
||||
result = ""
|
||||
for i in range(int(runs) + 1):
|
||||
result = rpc.call("Responder.GetCost", cd)
|
||||
|
||||
@@ -182,9 +182,33 @@ func (ub *Account) getBalancesForPrefix(prefix string, balances BalanceChain, sh
|
||||
}
|
||||
// resort by precision
|
||||
usefulBalances.Sort()
|
||||
// clear precision
|
||||
for _, b := range usefulBalances {
|
||||
b.precision = 0
|
||||
}
|
||||
return usefulBalances
|
||||
}
|
||||
|
||||
// like getBalancesForPrefix but expanding shared balances
|
||||
func (account *Account) getAlldBalancesForPrefix(destination, balanceType string) (bc BalanceChain) {
|
||||
balances := account.getBalancesForPrefix(destination, account.BalanceMap[balanceType], "")
|
||||
for _, b := range balances {
|
||||
if b.SharedGroup != "" {
|
||||
sharedGroup, err := accountingStorage.GetSharedGroup(b.SharedGroup, false)
|
||||
if err != nil {
|
||||
Logger.Warning(fmt.Sprintf("Could not get shared group: %v", b.SharedGroup))
|
||||
continue
|
||||
}
|
||||
sharedBalances := sharedGroup.GetBalances(destination, balanceType, account)
|
||||
sharedBalances = sharedGroup.SortBalancesByStrategy(b, sharedBalances)
|
||||
bc = append(bc, sharedBalances...)
|
||||
} else {
|
||||
bc = append(bc, b)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ub *Account) debitCreditBalance(cc *CallCost, count bool) (err error) {
|
||||
usefulMinuteBalances := ub.getAlldBalancesForPrefix(cc.Destination, MINUTES+cc.Direction)
|
||||
usefulMoneyBalances := ub.getAlldBalancesForPrefix(cc.Destination, CREDIT+cc.Direction)
|
||||
@@ -482,23 +506,3 @@ func (account *Account) GetUniqueSharedGroupMembers(destination, direction strin
|
||||
}
|
||||
return memberIds, nil
|
||||
}
|
||||
|
||||
// like getBalancesForPrefix but expanding shared balances
|
||||
func (account *Account) getAlldBalancesForPrefix(destination, balanceType string) (bc BalanceChain) {
|
||||
balances := account.getBalancesForPrefix(destination, account.BalanceMap[balanceType], "")
|
||||
for _, b := range balances {
|
||||
if b.SharedGroup != "" {
|
||||
sharedGroup, err := accountingStorage.GetSharedGroup(b.SharedGroup, false)
|
||||
if err != nil {
|
||||
Logger.Warning(fmt.Sprintf("Could not get shared group: %v", b.SharedGroup))
|
||||
continue
|
||||
}
|
||||
sharedBalances := sharedGroup.GetBalances(destination, balanceType, account)
|
||||
sharedBalances = sharedGroup.SortBalancesByStrategy(b, sharedBalances)
|
||||
bc = append(bc, sharedBalances...)
|
||||
} else {
|
||||
bc = append(bc, b)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -115,8 +115,8 @@ func TestGetSecondsForPrefix(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetSpecialPricedSeconds(t *testing.T) {
|
||||
b1 := &Balance{Value: 10, Weight: 10, DestinationId: "NAT", RateSubject: "minu"}
|
||||
b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET", RateSubject: "minu"}
|
||||
b1 := &Balance{Value: 10, Weight: 10, DestinationId: "NAT", RatingSubject: "minu"}
|
||||
b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET", RatingSubject: "minu"}
|
||||
|
||||
ub1 := &Account{
|
||||
Id: "OUT:CUSTOMER_1:rif",
|
||||
@@ -158,7 +158,7 @@ func TestAccountStorageStore(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditZeroSecond(t *testing.T) {
|
||||
b1 := &Balance{Uuid: "testb", Value: 10, Weight: 10, DestinationId: "NAT", RateSubject: "*zero1s"}
|
||||
b1 := &Balance{Uuid: "testb", Value: 10, Weight: 10, DestinationId: "NAT", RatingSubject: "*zero1s"}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -187,7 +187,7 @@ func TestDebitCreditZeroSecond(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditZeroMinute(t *testing.T) {
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RateSubject: "*zero1m"}
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RatingSubject: "*zero1m"}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -220,8 +220,8 @@ func TestDebitCreditZeroMinute(t *testing.T) {
|
||||
}
|
||||
}
|
||||
func TestDebitCreditZeroMixedMinute(t *testing.T) {
|
||||
b1 := &Balance{Uuid: "testm", Value: 70, Weight: 5, DestinationId: "NAT", RateSubject: "*zero1m"}
|
||||
b2 := &Balance{Uuid: "tests", Value: 10, Weight: 10, DestinationId: "NAT", RateSubject: "*zero1s"}
|
||||
b1 := &Balance{Uuid: "testm", Value: 70, Weight: 5, DestinationId: "NAT", RatingSubject: "*zero1m"}
|
||||
b2 := &Balance{Uuid: "tests", Value: 10, Weight: 10, DestinationId: "NAT", RatingSubject: "*zero1s"}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -255,7 +255,7 @@ func TestDebitCreditZeroMixedMinute(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditNoCredit(t *testing.T) {
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RateSubject: "*zero1m"}
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RatingSubject: "*zero1m"}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -295,7 +295,7 @@ func TestDebitCreditNoCredit(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditHasCredit(t *testing.T) {
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RateSubject: "*zero1m"}
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RatingSubject: "*zero1m"}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -337,7 +337,7 @@ func TestDebitCreditHasCredit(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditSplitMinutesMoney(t *testing.T) {
|
||||
b1 := &Balance{Uuid: "testb", Value: 10, Weight: 10, DestinationId: "NAT", RateSubject: "*zero1s"}
|
||||
b1 := &Balance{Uuid: "testb", Value: 10, Weight: 10, DestinationId: "NAT", RatingSubject: "*zero1s"}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -374,7 +374,7 @@ func TestDebitCreditSplitMinutesMoney(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditMoreTimespans(t *testing.T) {
|
||||
b1 := &Balance{Uuid: "testb", Value: 150, Weight: 10, DestinationId: "NAT", RateSubject: "*zero1m"}
|
||||
b1 := &Balance{Uuid: "testb", Value: 150, Weight: 10, DestinationId: "NAT", RatingSubject: "*zero1m"}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -411,8 +411,8 @@ func TestDebitCreditMoreTimespans(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditMoreTimespansMixed(t *testing.T) {
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RateSubject: "*zero1m"}
|
||||
b2 := &Balance{Uuid: "testa", Value: 150, Weight: 5, DestinationId: "NAT", RateSubject: "*zero1s"}
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RatingSubject: "*zero1m"}
|
||||
b2 := &Balance{Uuid: "testa", Value: 150, Weight: 5, DestinationId: "NAT", RatingSubject: "*zero1s"}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -450,7 +450,7 @@ func TestDebitCreditMoreTimespansMixed(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditNoConectFeeCredit(t *testing.T) {
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RateSubject: "*zero1m"}
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RatingSubject: "*zero1m"}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -527,7 +527,7 @@ func TestDebitCreditMoneyOnly(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditSubjectMinutes(t *testing.T) {
|
||||
b1 := &Balance{Uuid: "testb", Value: 250, Weight: 10, DestinationId: "NAT", RateSubject: "minu"}
|
||||
b1 := &Balance{Uuid: "testb", Value: 250, Weight: 10, DestinationId: "NAT", RatingSubject: "minu"}
|
||||
cc := &CallCost{
|
||||
Tenant: "vdf",
|
||||
TOR: "0",
|
||||
@@ -586,7 +586,7 @@ func TestDebitCreditSubjectMoney(t *testing.T) {
|
||||
deductConnectFee: true,
|
||||
}
|
||||
rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{
|
||||
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 75, DestinationId: "NAT", RateSubject: "minu"}},
|
||||
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 75, DestinationId: "NAT", RatingSubject: "minu"}},
|
||||
}}
|
||||
err := rifsBalance.debitCreditBalance(cc, false)
|
||||
if err != nil {
|
||||
@@ -606,7 +606,7 @@ func TestDebitCreditSubjectMoney(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditSubjectMixed(t *testing.T) {
|
||||
b1 := &Balance{Uuid: "testb", Value: 40, Weight: 10, DestinationId: "NAT", RateSubject: "minu"}
|
||||
b1 := &Balance{Uuid: "testb", Value: 40, Weight: 10, DestinationId: "NAT", RatingSubject: "minu"}
|
||||
cc := &CallCost{
|
||||
Tenant: "vdf",
|
||||
TOR: "0",
|
||||
@@ -624,7 +624,7 @@ func TestDebitCreditSubjectMixed(t *testing.T) {
|
||||
}
|
||||
rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{
|
||||
MINUTES + OUTBOUND: BalanceChain{b1},
|
||||
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 150, RateSubject: "minu"}},
|
||||
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 150, RatingSubject: "minu"}},
|
||||
}}
|
||||
err := rifsBalance.debitCreditBalance(cc, false)
|
||||
if err != nil {
|
||||
@@ -649,7 +649,7 @@ func TestDebitCreditSubjectMixed(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditSubjectMixedMoreTS(t *testing.T) {
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RateSubject: "minu"}
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RatingSubject: "minu"}
|
||||
cc := &CallCost{
|
||||
Tenant: "vdf",
|
||||
TOR: "0",
|
||||
@@ -673,7 +673,7 @@ func TestDebitCreditSubjectMixedMoreTS(t *testing.T) {
|
||||
}
|
||||
rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{
|
||||
MINUTES + OUTBOUND: BalanceChain{b1},
|
||||
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 50, RateSubject: "minu"}},
|
||||
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 50, RatingSubject: "minu"}},
|
||||
}}
|
||||
err := rifsBalance.debitCreditBalance(cc, false)
|
||||
if err == nil {
|
||||
@@ -700,7 +700,7 @@ func TestDebitCreditSubjectMixedMoreTS(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditSubjectMixedPartPay(t *testing.T) {
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RateSubject: "minu"}
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RatingSubject: "minu"}
|
||||
cc := &CallCost{
|
||||
Tenant: "vdf",
|
||||
TOR: "0",
|
||||
@@ -724,7 +724,7 @@ func TestDebitCreditSubjectMixedPartPay(t *testing.T) {
|
||||
}
|
||||
rifsBalance := &Account{Id: "other", BalanceMap: map[string]BalanceChain{
|
||||
MINUTES + OUTBOUND: BalanceChain{b1},
|
||||
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 75, RateSubject: "minu"}},
|
||||
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 75, RatingSubject: "minu"}},
|
||||
}}
|
||||
err := rifsBalance.debitCreditBalance(cc, false)
|
||||
if err == nil {
|
||||
|
||||
@@ -48,22 +48,22 @@ type Action struct {
|
||||
}
|
||||
|
||||
const (
|
||||
LOG = "*log"
|
||||
RESET_TRIGGERS = "*reset_triggers"
|
||||
ALLOW_NEGATIVE = "*allow_negative"
|
||||
DENY_NEGATIVE = "*deny_negative"
|
||||
RESET_ACCOUNT = "*reset_account"
|
||||
TOPUP_RESET = "*topup_reset"
|
||||
TOPUP = "*topup"
|
||||
DEBIT = "*debit"
|
||||
RESET_COUNTER = "*reset_counter"
|
||||
RESET_COUNTERS = "*reset_counters"
|
||||
ENABLE_USER = "*enable_user"
|
||||
DISABLE_USER = "*disable_user"
|
||||
CALL_URL = "*call_url"
|
||||
CALL_URL_ASYNC = "*call_url_async"
|
||||
MAIL_ASYNC = "*mail_async"
|
||||
UNLIMITED = "*unlimited"
|
||||
LOG = "*log"
|
||||
RESET_TRIGGERS = "*reset_triggers"
|
||||
ALLOW_NEGATIVE = "*allow_negative"
|
||||
DENY_NEGATIVE = "*deny_negative"
|
||||
RESET_ACCOUNT = "*reset_account"
|
||||
TOPUP_RESET = "*topup_reset"
|
||||
TOPUP = "*topup"
|
||||
DEBIT = "*debit"
|
||||
RESET_COUNTER = "*reset_counter"
|
||||
RESET_COUNTERS = "*reset_counters"
|
||||
ENABLE_ACCOUNT = "*enable_account"
|
||||
DISABLE_ACCOUNT = "*disable_account"
|
||||
CALL_URL = "*call_url"
|
||||
CALL_URL_ASYNC = "*call_url_async"
|
||||
MAIL_ASYNC = "*mail_async"
|
||||
UNLIMITED = "*unlimited"
|
||||
)
|
||||
|
||||
type actionTypeFunc func(*Account, *Action) error
|
||||
@@ -90,9 +90,9 @@ func getActionFunc(typ string) (actionTypeFunc, bool) {
|
||||
return resetCounterAction, true
|
||||
case RESET_COUNTERS:
|
||||
return resetCountersAction, true
|
||||
case ENABLE_USER:
|
||||
case ENABLE_ACCOUNT:
|
||||
return enableUserAction, true
|
||||
case DISABLE_USER:
|
||||
case DISABLE_ACCOUNT:
|
||||
return disableUserAction, true
|
||||
case CALL_URL:
|
||||
return callUrl, true
|
||||
|
||||
@@ -235,7 +235,10 @@ func (at *ActionTiming) Execute() (err error) {
|
||||
for _, ubId := range at.AccountIds {
|
||||
_, err := AccLock.Guard(ubId, func() (float64, error) {
|
||||
ub, err := accountingStorage.GetAccount(ubId)
|
||||
if ub.Disabled {
|
||||
if err != nil {
|
||||
Logger.Warning(fmt.Sprintf("Could not get user balances for this id: %s. Skipping!", ubId))
|
||||
return 0, err
|
||||
} else if ub.Disabled {
|
||||
return 0, fmt.Errorf("User %s is disabled", ubId)
|
||||
}
|
||||
if err != nil {
|
||||
|
||||
@@ -21,8 +21,8 @@ package engine
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type ActionTrigger struct {
|
||||
|
||||
@@ -33,7 +33,7 @@ type Balance struct {
|
||||
ExpirationDate time.Time
|
||||
Weight float64
|
||||
DestinationId string
|
||||
RateSubject string
|
||||
RatingSubject string
|
||||
SharedGroup string
|
||||
precision int
|
||||
account *Account // used to store ub reference for shared balances
|
||||
@@ -50,14 +50,14 @@ func (b *Balance) Equal(o *Balance) bool {
|
||||
return b.ExpirationDate.Equal(o.ExpirationDate) &&
|
||||
b.Weight == o.Weight &&
|
||||
b.DestinationId == o.DestinationId &&
|
||||
b.RateSubject == o.RateSubject &&
|
||||
b.RatingSubject == o.RatingSubject &&
|
||||
b.SharedGroup == o.SharedGroup
|
||||
}
|
||||
|
||||
// the default balance has no destinationid, Expirationdate or ratesubject
|
||||
func (b *Balance) IsDefault() bool {
|
||||
return (b.DestinationId == "" || b.DestinationId == utils.ANY) &&
|
||||
b.RateSubject == "" &&
|
||||
b.RatingSubject == "" &&
|
||||
b.ExpirationDate.IsZero() &&
|
||||
b.SharedGroup == ""
|
||||
}
|
||||
@@ -81,7 +81,7 @@ func (b *Balance) Clone() *Balance {
|
||||
DestinationId: b.DestinationId,
|
||||
ExpirationDate: b.ExpirationDate,
|
||||
Weight: b.Weight,
|
||||
RateSubject: b.RateSubject,
|
||||
RatingSubject: b.RatingSubject,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,8 +125,8 @@ func (b *Balance) GetMinutesForCredit(origCD *CallDescriptor, initialCredit floa
|
||||
}
|
||||
|
||||
func (b *Balance) GetCost(cd *CallDescriptor) (*CallCost, error) {
|
||||
if b.RateSubject != "" {
|
||||
cd.Subject = b.RateSubject
|
||||
if b.RatingSubject != "" {
|
||||
cd.Subject = b.RatingSubject
|
||||
cd.Account = cd.Subject
|
||||
cd.RatingInfos = nil
|
||||
return cd.GetCost()
|
||||
@@ -162,13 +162,13 @@ func (b *Balance) DebitMinutes(cc *CallCost, count bool, ub *Account, moneyBalan
|
||||
if increment.paid {
|
||||
continue
|
||||
}
|
||||
if duration, err := utils.ParseZeroRatingSubject(b.RateSubject); err == nil {
|
||||
if duration, err := utils.ParseZeroRatingSubject(b.RatingSubject); err == nil {
|
||||
seconds := duration.Seconds()
|
||||
amount := seconds
|
||||
if seconds == 1 {
|
||||
amount = increment.Duration.Seconds()
|
||||
}
|
||||
if b.Value >= amount { // balance has at least 60 seconds
|
||||
if b.Value >= amount {
|
||||
newTs := ts
|
||||
inc := increment
|
||||
if seconds > 1 { // we need to recreate increments
|
||||
@@ -215,7 +215,7 @@ func (b *Balance) DebitMinutes(cc *CallCost, count bool, ub *Account, moneyBalan
|
||||
}
|
||||
// get the new rate
|
||||
cd := cc.CreateCallDescriptor()
|
||||
cd.Subject = b.RateSubject
|
||||
cd.Subject = b.RatingSubject
|
||||
cd.TimeStart = ts.GetTimeStartForIncrement(incrementIndex)
|
||||
cd.TimeEnd = cc.Timespans[len(cc.Timespans)-1].TimeEnd
|
||||
cd.CallDuration = cc.Timespans[len(cc.Timespans)-1].CallDuration
|
||||
@@ -240,7 +240,7 @@ func (b *Balance) DebitMinutes(cc *CallCost, count bool, ub *Account, moneyBalan
|
||||
break
|
||||
}
|
||||
}
|
||||
if moneyBal != nil && b.Value >= seconds {
|
||||
if (cost == 0 || moneyBal != nil) && b.Value >= seconds {
|
||||
b.SubstractAmount(seconds)
|
||||
nInc.BalanceInfo.MinuteBalanceUuid = b.Uuid
|
||||
nInc.BalanceInfo.AccountId = ub.Id
|
||||
@@ -310,7 +310,7 @@ func (b *Balance) DebitMoney(cc *CallCost, count bool, ub *Account) error {
|
||||
continue
|
||||
}
|
||||
// check standard subject tags
|
||||
if b.RateSubject == "" {
|
||||
if b.RatingSubject == "" {
|
||||
amount := increment.Cost
|
||||
if b.Value >= amount {
|
||||
b.SubstractAmount(amount)
|
||||
@@ -324,7 +324,7 @@ func (b *Balance) DebitMoney(cc *CallCost, count bool, ub *Account) error {
|
||||
} else {
|
||||
// get the new rate
|
||||
cd := cc.CreateCallDescriptor()
|
||||
cd.Subject = b.RateSubject
|
||||
cd.Subject = b.RatingSubject
|
||||
cd.TimeStart = ts.GetTimeStartForIncrement(incrementIndex)
|
||||
cd.TimeEnd = cc.Timespans[len(cc.Timespans)-1].TimeEnd
|
||||
cd.CallDuration = cc.Timespans[len(cc.Timespans)-1].CallDuration
|
||||
|
||||
@@ -79,16 +79,16 @@ func TestBalanceSortWeightLess(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBalanceEqual(t *testing.T) {
|
||||
mb1 := &Balance{Weight: 1, precision: 1, RateSubject: "1", DestinationId: ""}
|
||||
mb2 := &Balance{Weight: 1, precision: 1, RateSubject: "1", DestinationId: ""}
|
||||
mb3 := &Balance{Weight: 1, precision: 1, RateSubject: "2", DestinationId: ""}
|
||||
mb1 := &Balance{Weight: 1, precision: 1, RatingSubject: "1", DestinationId: ""}
|
||||
mb2 := &Balance{Weight: 1, precision: 1, RatingSubject: "1", DestinationId: ""}
|
||||
mb3 := &Balance{Weight: 1, precision: 1, RatingSubject: "2", DestinationId: ""}
|
||||
if !mb1.Equal(mb2) || mb2.Equal(mb3) {
|
||||
t.Error("Equal failure!", mb1 == mb2, mb3)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBalanceClone(t *testing.T) {
|
||||
mb1 := &Balance{Value: 1, Weight: 2, RateSubject: "test", DestinationId: "5"}
|
||||
mb1 := &Balance{Value: 1, Weight: 2, RatingSubject: "test", DestinationId: "5"}
|
||||
mb2 := mb1.Clone()
|
||||
if mb1 == mb2 || !reflect.DeepEqual(mb1, mb2) {
|
||||
t.Errorf("Cloning failure: \n%v\n%v", mb1, mb2)
|
||||
|
||||
@@ -58,7 +58,7 @@ func populateDB() {
|
||||
Id: "*out:vdf:broker",
|
||||
BalanceMap: map[string]BalanceChain{
|
||||
MINUTES + OUTBOUND: BalanceChain{
|
||||
&Balance{Value: 20, DestinationId: "NAT", Weight: 10, RateSubject: "rif"},
|
||||
&Balance{Value: 20, DestinationId: "NAT", Weight: 10, RatingSubject: "rif"},
|
||||
&Balance{Value: 100, DestinationId: "RET", Weight: 20},
|
||||
}},
|
||||
}
|
||||
@@ -67,7 +67,7 @@ func populateDB() {
|
||||
Id: "*out:vdf:minitsboy",
|
||||
BalanceMap: map[string]BalanceChain{
|
||||
MINUTES + OUTBOUND: BalanceChain{
|
||||
&Balance{Value: 20, DestinationId: "NAT", Weight: 10, RateSubject: "rif"},
|
||||
&Balance{Value: 20, DestinationId: "NAT", Weight: 10, RatingSubject: "rif"},
|
||||
&Balance{Value: 100, DestinationId: "RET", Weight: 20},
|
||||
},
|
||||
CREDIT + OUTBOUND: BalanceChain{
|
||||
@@ -575,7 +575,7 @@ func TestMaxDebitZeroDefinedRate(t *testing.T) {
|
||||
cd1 := &CallDescriptor{
|
||||
Direction: "*out",
|
||||
TOR: "call",
|
||||
Tenant: "cgrates.directvoip.co.uk",
|
||||
Tenant: "cgrates.org",
|
||||
Subject: "12345",
|
||||
Account: "12345",
|
||||
Destination: "447956",
|
||||
@@ -603,7 +603,7 @@ func TestMaxDebitZeroDefinedRateOnlyMinutes(t *testing.T) {
|
||||
cd1 := &CallDescriptor{
|
||||
Direction: "*out",
|
||||
TOR: "call",
|
||||
Tenant: "cgrates.directvoip.co.uk",
|
||||
Tenant: "cgrates.org",
|
||||
Subject: "12345",
|
||||
Account: "12345",
|
||||
Destination: "447956",
|
||||
@@ -613,7 +613,7 @@ func TestMaxDebitZeroDefinedRateOnlyMinutes(t *testing.T) {
|
||||
CallDuration: 0}
|
||||
cc, err := cd1.MaxDebit()
|
||||
if err != nil {
|
||||
t.Error("Error maxdebiting: ", err)
|
||||
t.Fatal("Error maxdebiting: ", err)
|
||||
}
|
||||
if cc.GetDuration() != 40*time.Second {
|
||||
t.Error("Error obtaining max debit duration: ", cc.GetDuration())
|
||||
@@ -623,7 +623,29 @@ func TestMaxDebitZeroDefinedRateOnlyMinutes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************** BENCHMARKS ***************************************/
|
||||
func TestMaxDebitConsumesMinutes(t *testing.T) {
|
||||
ap, _ := accountingStorage.GetActionTimings("TOPUP10_AT")
|
||||
for _, at := range ap {
|
||||
at.Execute()
|
||||
}
|
||||
cd1 := &CallDescriptor{
|
||||
Direction: "*out",
|
||||
TOR: "call",
|
||||
Tenant: "cgrates.org",
|
||||
Subject: "12345",
|
||||
Account: "12345",
|
||||
Destination: "447956",
|
||||
TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2014, 3, 4, 6, 0, 5, 0, time.UTC),
|
||||
LoopIndex: 0,
|
||||
CallDuration: 0}
|
||||
cd1.MaxDebit()
|
||||
if cd1.account.BalanceMap[MINUTES+OUTBOUND][0].Value != 20 {
|
||||
t.Error("Error using minutes: ", cd1.account.BalanceMap[MINUTES+OUTBOUND][0].Value)
|
||||
}
|
||||
}
|
||||
|
||||
/*************** BENCHMARKS ********************/
|
||||
func BenchmarkStorageGetting(b *testing.B) {
|
||||
b.StopTimer()
|
||||
t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC)
|
||||
|
||||
@@ -518,16 +518,16 @@ func (csvr *CSVReader) LoadSharedGroups() (err error) {
|
||||
sg, found := csvr.sharedGroups[tag]
|
||||
if found {
|
||||
sg.AccountParameters[record[1]] = &SharingParameters{
|
||||
Strategy: record[2],
|
||||
RateSubject: record[3],
|
||||
Strategy: record[2],
|
||||
RatingSubject: record[3],
|
||||
}
|
||||
} else {
|
||||
sg = &SharedGroup{
|
||||
Id: tag,
|
||||
AccountParameters: map[string]*SharingParameters{
|
||||
record[1]: &SharingParameters{
|
||||
Strategy: record[2],
|
||||
RateSubject: record[3],
|
||||
Strategy: record[2],
|
||||
RatingSubject: record[3],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -584,7 +584,7 @@ func (csvr *CSVReader) LoadActions() (err error) {
|
||||
Value: units,
|
||||
Weight: balanceWeight,
|
||||
DestinationId: record[6],
|
||||
RateSubject: record[7],
|
||||
RatingSubject: record[7],
|
||||
SharedGroup: record[9],
|
||||
},
|
||||
}
|
||||
|
||||
@@ -118,8 +118,8 @@ vdf,0,*out,fallback1,2013-11-18T13:45:00Z,G,fallback2
|
||||
vdf,0,*out,fallback1,2013-11-18T13:46:00Z,G,fallback2
|
||||
vdf,0,*out,fallback1,2013-11-18T13:47:00Z,G,fallback2
|
||||
vdf,0,*out,fallback2,2013-11-18T13:45:00Z,R,rif
|
||||
cgrates.directvoip.co.uk,call,*out,*any,2013-01-06T00:00:00Z,RP_UK,
|
||||
cgrates.directvoip.co.uk,call,*out,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,
|
||||
cgrates.org,call,*out,*any,2013-01-06T00:00:00Z,RP_UK,
|
||||
cgrates.org,call,*out,discounted_minutes,2013-01-06T00:00:00Z,RP_UK_Mobile_BIG5_PKG,
|
||||
`
|
||||
sharedGroups = `
|
||||
SG1,*any,*lowest,
|
||||
@@ -157,7 +157,7 @@ STANDARD_TRIGGERS,*monetary,*out,*max_counter,5,FS_USERS,LOG_WARNING,10
|
||||
`
|
||||
accountActions = `
|
||||
vdf,minitsboy;a1;a2,*out,MORE_MINUTES,STANDARD_TRIGGER
|
||||
cgrates.directvoip.co.uk,12345,*out,TOPUP10_AT,STANDARD_TRIGGERS
|
||||
cgrates.org,12345,*out,TOPUP10_AT,STANDARD_TRIGGERS
|
||||
vdf,empty0,*out,TOPUP_SHARED0_AT,
|
||||
vdf,empty10,*out,TOPUP_SHARED10_AT,
|
||||
vdf,emptyX,*out,TOPUP_EMPTY_AT,
|
||||
@@ -633,7 +633,7 @@ func TestLoadActions(t *testing.T) {
|
||||
Uuid: as1[1].Balance.Uuid,
|
||||
Value: 100,
|
||||
Weight: 10,
|
||||
RateSubject: "test",
|
||||
RatingSubject: "test",
|
||||
DestinationId: "NAT",
|
||||
},
|
||||
},
|
||||
@@ -673,8 +673,8 @@ func TestLoadSharedGroups(t *testing.T) {
|
||||
Id: "SG1",
|
||||
AccountParameters: map[string]*SharingParameters{
|
||||
"*any": &SharingParameters{
|
||||
Strategy: "*lowest",
|
||||
RateSubject: "",
|
||||
Strategy: "*lowest",
|
||||
RatingSubject: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -686,8 +686,8 @@ func TestLoadSharedGroups(t *testing.T) {
|
||||
Id: "SG2",
|
||||
AccountParameters: map[string]*SharingParameters{
|
||||
"*any": &SharingParameters{
|
||||
Strategy: "*lowest",
|
||||
RateSubject: "one",
|
||||
Strategy: "*lowest",
|
||||
RatingSubject: "one",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -473,7 +473,7 @@ func (dbr *DbReader) LoadActions() (err error) {
|
||||
Uuid: utils.GenUUID(),
|
||||
Value: tpact.Units,
|
||||
Weight: tpact.BalanceWeight,
|
||||
RateSubject: tpact.RatingSubject,
|
||||
RatingSubject: tpact.RatingSubject,
|
||||
DestinationId: tpact.DestinationId,
|
||||
},
|
||||
}
|
||||
@@ -712,7 +712,7 @@ func (dbr *DbReader) LoadAccountActionsFiltered(qriedAA *utils.TPAccountActions)
|
||||
Uuid: utils.GenUUID(),
|
||||
Value: tpact.Units,
|
||||
Weight: tpact.BalanceWeight,
|
||||
RateSubject: tpact.RatingSubject,
|
||||
RatingSubject: tpact.RatingSubject,
|
||||
DestinationId: tpact.DestinationId,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ type SharedGroup struct {
|
||||
}
|
||||
|
||||
type SharingParameters struct {
|
||||
Strategy string
|
||||
RateSubject string
|
||||
Strategy string
|
||||
RatingSubject string
|
||||
}
|
||||
|
||||
func (sg *SharedGroup) GetMembersExceptUser(ubId string) []string {
|
||||
|
||||
@@ -41,6 +41,10 @@ func NewMapStorage() (*MapStorage, error) {
|
||||
return &MapStorage{dict: make(map[string][]byte), ms: NewCodecMsgpackMarshaler()}, nil
|
||||
}
|
||||
|
||||
func NewMapStorageJson() (*MapStorage, error) {
|
||||
return &MapStorage{dict: make(map[string][]byte), ms: new(JSONBufMarshaler)}, nil
|
||||
}
|
||||
|
||||
func (ms *MapStorage) Close() {}
|
||||
|
||||
func (ms *MapStorage) Flush() error {
|
||||
@@ -182,8 +186,9 @@ func (ms *MapStorage) SetRatingPlan(rp *RatingPlan) (err error) {
|
||||
w.Close()
|
||||
ms.dict[RATING_PLAN_PREFIX+rp.Id] = b.Bytes()
|
||||
response := 0
|
||||
|
||||
go historyScribe.Record(rp.GetHistoryRecord(), &response)
|
||||
if historyScribe != nil {
|
||||
go historyScribe.Record(rp.GetHistoryRecord(), &response)
|
||||
}
|
||||
//cache2go.Cache(RATING_PLAN_PREFIX+rp.Id, rp)
|
||||
return
|
||||
}
|
||||
@@ -211,7 +216,9 @@ func (ms *MapStorage) SetRatingProfile(rpf *RatingProfile) (err error) {
|
||||
result, err := ms.ms.Marshal(rpf)
|
||||
ms.dict[RATING_PROFILE_PREFIX+rpf.Id] = result
|
||||
response := 0
|
||||
go historyScribe.Record(rpf.GetHistoryRecord(), &response)
|
||||
if historyScribe != nil {
|
||||
go historyScribe.Record(rpf.GetHistoryRecord(), &response)
|
||||
}
|
||||
//cache2go.Cache(RATING_PROFILE_PREFIX+rpf.Id, rpf)
|
||||
return
|
||||
}
|
||||
@@ -342,7 +349,9 @@ func (ms *MapStorage) SetDestination(dest *Destination) (err error) {
|
||||
w.Close()
|
||||
ms.dict[DESTINATION_PREFIX+dest.Id] = b.Bytes()
|
||||
response := 0
|
||||
go historyScribe.Record(dest.GetHistoryRecord(), &response)
|
||||
if historyScribe != nil {
|
||||
go historyScribe.Record(dest.GetHistoryRecord(), &response)
|
||||
}
|
||||
//cache2go.Cache(DESTINATION_PREFIX+dest.Id, dest)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ func (self *SQLStorage) SetTPSharedGroups(tpid string, sgs map[string]*SharedGro
|
||||
buffer.WriteRune(',')
|
||||
}
|
||||
buffer.WriteString(fmt.Sprintf("('%s','%s','%s','%s','%s')",
|
||||
tpid, sgId, account, params.Strategy, params.RateSubject))
|
||||
tpid, sgId, account, params.Strategy, params.RatingSubject))
|
||||
i++
|
||||
}
|
||||
}
|
||||
@@ -962,7 +962,7 @@ func (self *SQLStorage) GetTpTimings(tpid, tag string) (map[string]*utils.TPTimi
|
||||
|
||||
func (self *SQLStorage) GetTpRatingPlans(tpid, tag string) (map[string][]*utils.TPRatingPlanBinding, error) {
|
||||
rpbns := make(map[string][]*utils.TPRatingPlanBinding)
|
||||
q := fmt.Sprintf("SELECT * FROM %s WHERE tpid='%s'", utils.TBL_TP_RATING_PLANS, tpid)
|
||||
q := fmt.Sprintf("SELECT tpid, id, destrates_id, timing_id, weight FROM %s WHERE tpid='%s'", utils.TBL_TP_RATING_PLANS, tpid)
|
||||
if tag != "" {
|
||||
q += fmt.Sprintf(" AND id='%s'", tag)
|
||||
}
|
||||
@@ -972,10 +972,9 @@ func (self *SQLStorage) GetTpRatingPlans(tpid, tag string) (map[string][]*utils.
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var id int
|
||||
var weight float64
|
||||
var tpid, tag, destination_rates_tag, timings_tag string
|
||||
if err := rows.Scan(&id, &tpid, &tag, &destination_rates_tag, &timings_tag, &weight); err != nil {
|
||||
var tpid, id, destination_rates_tag, timings_tag string
|
||||
if err := rows.Scan(&tpid, &id, &destination_rates_tag, &timings_tag, &weight); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rpb := &utils.TPRatingPlanBinding{
|
||||
@@ -983,10 +982,11 @@ func (self *SQLStorage) GetTpRatingPlans(tpid, tag string) (map[string][]*utils.
|
||||
TimingId: timings_tag,
|
||||
Weight: weight,
|
||||
}
|
||||
if rpBnLst, exists := rpbns[tag]; exists {
|
||||
rpBnLst = append(rpBnLst, rpb)
|
||||
// Logger.Debug(fmt.Sprintf("For RatingPlan id: %s, loading RatingPlanBinding: %v", tag, rpb))
|
||||
if _, exists := rpbns[id]; exists {
|
||||
rpbns[id] = append(rpbns[id], rpb)
|
||||
} else { // New
|
||||
rpbns[tag] = []*utils.TPRatingPlanBinding{rpb}
|
||||
rpbns[id] = []*utils.TPRatingPlanBinding{rpb}
|
||||
}
|
||||
}
|
||||
return rpbns, nil
|
||||
@@ -1055,16 +1055,16 @@ func (self *SQLStorage) GetTpSharedGroups(tpid, tag string) (map[string]*SharedG
|
||||
sg, found := sgs[tag]
|
||||
if found {
|
||||
sg.AccountParameters[account] = &SharingParameters{
|
||||
Strategy: strategy,
|
||||
RateSubject: rateSubject,
|
||||
Strategy: strategy,
|
||||
RatingSubject: rateSubject,
|
||||
}
|
||||
} else {
|
||||
sg = &SharedGroup{
|
||||
Id: tag,
|
||||
AccountParameters: map[string]*SharingParameters{
|
||||
account: &SharingParameters{
|
||||
Strategy: strategy,
|
||||
RateSubject: rateSubject,
|
||||
Strategy: strategy,
|
||||
RatingSubject: rateSubject,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
4
test.sh
4
test.sh
@@ -15,6 +15,8 @@ go test -i github.com/cgrates/cgrates/cdre
|
||||
|
||||
go test github.com/cgrates/cgrates/engine
|
||||
en=$?
|
||||
go test github.com/cgrates/cgrates/charging_tests
|
||||
ct=$?
|
||||
go test github.com/cgrates/cgrates/sessionmanager
|
||||
sm=$?
|
||||
go test github.com/cgrates/cgrates/config
|
||||
@@ -39,4 +41,4 @@ go test github.com/cgrates/cgrates/cdre
|
||||
cdre=$?
|
||||
|
||||
|
||||
exit $en && $sm && $cfg && $bl && $cr && $md && $cdrs && $cdrc && $fs && $ut && $hs && $c2g && $cdre
|
||||
exit $en && $ct && $sm && $cfg && $bl && $cr && $md && $cdrs && $cdrc && $fs && $ut && $hs && $c2g && $cdre
|
||||
|
||||
Reference in New Issue
Block a user