mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-12 10:36:24 +05:00
Merge branch 'actmods' of https://github.com/cgrates/cgrates into actmods
This commit is contained in:
@@ -642,6 +642,7 @@ func (bc BalanceChain) SaveDirtyBalances(acc *Account) {
|
||||
allowNegative := ""
|
||||
disabled := ""
|
||||
if b.account != nil { // only publish modifications for balances with account set
|
||||
//utils.LogStack()
|
||||
accountId = b.account.Id
|
||||
allowNegative = strconv.FormatBool(b.account.AllowNegative)
|
||||
disabled = strconv.FormatBool(b.account.Disabled)
|
||||
|
||||
@@ -152,3 +152,15 @@ func (cc *CallCost) AsJSON() string {
|
||||
ccJson, _ := json.Marshal(cc)
|
||||
return string(ccJson)
|
||||
}
|
||||
|
||||
func (cc *CallCost) UpdateCost() {
|
||||
cost := 0.0
|
||||
if cc.deductConnectFee { // add back the connectFee
|
||||
cost += cc.GetConnectFee()
|
||||
}
|
||||
for _, ts := range cc.Timespans {
|
||||
cost += ts.getCost()
|
||||
cost = utils.Round(cost, globalRoundingDecimals, utils.ROUNDING_MIDDLE) // just get rid of the extra decimals
|
||||
}
|
||||
cc.Cost = cost
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ var (
|
||||
|
||||
// Exported method to set the storage getter.
|
||||
func SetRatingStorage(sg RatingStorage) {
|
||||
ratingStorage = sg
|
||||
ratingStorage = sg
|
||||
}
|
||||
|
||||
func SetAccountingStorage(ag AccountingStorage) {
|
||||
@@ -636,16 +636,7 @@ func (cd *CallDescriptor) debit(account *Account, dryRun bool, goNegative bool)
|
||||
utils.Logger.Err(fmt.Sprintf("<Rater> Error getting cost for account key <%s>: %s", cd.GetAccountKey(), err.Error()))
|
||||
return nil, err
|
||||
}
|
||||
cost := 0.0
|
||||
// calculate call cost after balances
|
||||
if cc.deductConnectFee { // add back the connectFee
|
||||
cost += cc.GetConnectFee()
|
||||
}
|
||||
for _, ts := range cc.Timespans {
|
||||
cost += ts.getCost()
|
||||
cost = utils.Round(cost, globalRoundingDecimals, utils.ROUNDING_MIDDLE) // just get rid of the extra decimals
|
||||
}
|
||||
cc.Cost = cost
|
||||
cc.UpdateCost()
|
||||
cc.Timespans.Compress()
|
||||
//log.Printf("OUT CC: ", cc)
|
||||
return
|
||||
|
||||
@@ -557,6 +557,28 @@ func TestGetCostWithMaxCost(t *testing.T) {
|
||||
t.Errorf("Expected %v was %v", expected, cc.Cost)
|
||||
}
|
||||
}
|
||||
func TestGetCostRoundingIssue(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT")
|
||||
for _, at := range ap {
|
||||
at.Execute()
|
||||
}
|
||||
cd := &CallDescriptor{
|
||||
Direction: "*out",
|
||||
Category: "call",
|
||||
Tenant: "cgrates.org",
|
||||
Subject: "dy",
|
||||
Account: "dy",
|
||||
Destination: "0723123113",
|
||||
TimeStart: time.Date(2015, 10, 26, 13, 29, 27, 0, time.UTC),
|
||||
TimeEnd: time.Date(2015, 10, 26, 13, 29, 51, 0, time.UTC),
|
||||
MaxCostSoFar: 0,
|
||||
}
|
||||
cc, err := cd.GetCost()
|
||||
expected := 0.17
|
||||
if cc.Cost != expected || err != nil {
|
||||
t.Errorf("Expected %v was %+v", expected, cc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMaxSessionTimeWithMaxCostFree(t *testing.T) {
|
||||
ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT")
|
||||
|
||||
@@ -70,6 +70,7 @@ RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s
|
||||
RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s
|
||||
R_URG,0,0,1,1,0
|
||||
MX,0,1,1s,1s,0
|
||||
DY,0.15,0.05,60s,1s,0s
|
||||
`
|
||||
destinationRates = `
|
||||
RT_STANDARD,GERMANY,R1,*middle,4,0,
|
||||
@@ -91,6 +92,7 @@ DATA_RATE,*any,LANDLINE_OFFPEAK,*middle,4,0,
|
||||
RT_URG,URG,R_URG,*middle,4,0,
|
||||
MX_FREE,RET,MX,*middle,4,10,*free
|
||||
MX_DISC,RET,MX,*middle,4,10,*disconnect
|
||||
RT_DY,RET,DY,*up,2,0,
|
||||
`
|
||||
ratingPlans = `
|
||||
STANDARD,RT_STANDARD,WORKDAYS_00,10
|
||||
@@ -115,6 +117,7 @@ RP_MX,MX_DISC,WORKDAYS_00,10
|
||||
RP_MX,MX_FREE,WORKDAYS_18,10
|
||||
GER_ONLY,GER,*any,10
|
||||
ANY_PLAN,DATA_RATE,*any,10
|
||||
DY_PLAN,RT_DY,*any,10
|
||||
`
|
||||
ratingProfiles = `
|
||||
*out,CUSTOMER_1,0,rif:from:tm,2012-01-01T00:00:00Z,PREMIUM,danb,
|
||||
@@ -141,6 +144,7 @@ ANY_PLAN,DATA_RATE,*any,10
|
||||
*out,cgrates.org,call,nt,2012-02-28T00:00:00Z,GER_ONLY,,
|
||||
*in,cgrates.org,LCR_STANDARD,max,2013-03-23T00:00:00Z,RP_MX,,
|
||||
*out,cgrates.org,call,money,2015-02-28T00:00:00Z,EVENING,,
|
||||
*out,cgrates.org,call,dy,2015-02-28T00:00:00Z,DY_PLAN,,
|
||||
`
|
||||
sharedGroups = `
|
||||
SG1,*any,*lowest,
|
||||
@@ -391,7 +395,7 @@ func TestLoadTimimgs(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLoadRates(t *testing.T) {
|
||||
if len(csvr.rates) != 13 {
|
||||
if len(csvr.rates) != 14 {
|
||||
t.Error("Failed to load rates: ", len(csvr.rates))
|
||||
}
|
||||
rate := csvr.rates["R1"].RateSlots[0]
|
||||
@@ -461,7 +465,7 @@ func TestLoadRates(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLoadDestinationRates(t *testing.T) {
|
||||
if len(csvr.destinationRates) != 14 {
|
||||
if len(csvr.destinationRates) != 15 {
|
||||
t.Error("Failed to load destinationrates: ", len(csvr.destinationRates))
|
||||
}
|
||||
drs := csvr.destinationRates["RT_STANDARD"]
|
||||
@@ -609,7 +613,7 @@ func TestLoadDestinationRates(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLoadRatingPlans(t *testing.T) {
|
||||
if len(csvr.ratingPlans) != 13 {
|
||||
if len(csvr.ratingPlans) != 14 {
|
||||
t.Error("Failed to load rating plans: ", len(csvr.ratingPlans))
|
||||
}
|
||||
rplan := csvr.ratingPlans["STANDARD"]
|
||||
@@ -781,7 +785,7 @@ func TestLoadRatingPlans(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLoadRatingProfiles(t *testing.T) {
|
||||
if len(csvr.ratingProfiles) != 21 {
|
||||
if len(csvr.ratingProfiles) != 22 {
|
||||
t.Error("Failed to load rating profiles: ", len(csvr.ratingProfiles), csvr.ratingProfiles)
|
||||
}
|
||||
rp := csvr.ratingProfiles["*out:test:0:trp"]
|
||||
|
||||
@@ -263,11 +263,7 @@ func (ts *TimeSpan) getCost() float64 {
|
||||
ts.Cost = utils.Round(cost, ts.RateInterval.Rating.RoundingDecimals, ts.RateInterval.Rating.RoundingMethod)
|
||||
return ts.Cost
|
||||
} else {
|
||||
cost := 0.0
|
||||
// some increments may have 0 cost because of the max cost strategy
|
||||
for _, inc := range ts.Increments {
|
||||
cost += inc.Cost
|
||||
}
|
||||
cost := ts.Increments.GetTotalCost()
|
||||
if ts.RateInterval != nil && ts.RateInterval.Rating != nil {
|
||||
return utils.Round(cost, ts.RateInterval.Rating.RoundingDecimals, ts.RateInterval.Rating.RoundingMethod)
|
||||
} else {
|
||||
|
||||
@@ -233,6 +233,8 @@ func (s *Session) SaveOperations() {
|
||||
firstCC.Merge(cc)
|
||||
//utils.Logger.Debug(fmt.Sprintf("AFTER MERGE: %s", utils.ToJSON(firstCC)))
|
||||
}
|
||||
// make sure we have rounded timespans final cost
|
||||
firstCC.UpdateCost()
|
||||
|
||||
var reply string
|
||||
err := s.sessionManager.CdrSrv().LogCallCost(&engine.CallCostLog{
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"log/syslog"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
var Logger LoggerInterface
|
||||
@@ -85,3 +86,9 @@ func (sl *StdLogger) Warning(m string) (err error) {
|
||||
log.Print("[WARNING]" + m)
|
||||
return
|
||||
}
|
||||
|
||||
func LogStack() {
|
||||
buf := make([]byte, 300)
|
||||
runtime.Stack(buf, false)
|
||||
Logger.Debug(string(buf))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user