This commit is contained in:
DanB
2016-01-20 16:58:57 +01:00
7 changed files with 63 additions and 6 deletions

View File

@@ -29,6 +29,7 @@ type CallCost struct {
Direction, Category, Tenant, Subject, Account, Destination, TOR string
Cost float64
Timespans TimeSpans
RatedUsage float64
deductConnectFee bool
negativeConnectFee bool // the connect fee went negative on default balance
maxCostDisconect bool
@@ -61,6 +62,12 @@ func (cc *CallCost) GetDuration() (td time.Duration) {
return
}
func (cc *CallCost) UpdateRatedUsage() time.Duration {
totalDuration := cc.GetDuration()
cc.RatedUsage = totalDuration.Seconds()
return totalDuration
}
func (cc *CallCost) GetConnectFee() float64 {
if len(cc.Timespans) == 0 ||
cc.Timespans[0].RateInterval == nil ||

View File

@@ -50,6 +50,10 @@ func TestSingleResultMerge(t *testing.T) {
if cc1.Cost != 122 {
t.Errorf("Exdpected 120 was %v", cc1.Cost)
}
d := cc1.UpdateRatedUsage()
if d != 2*time.Minute || cc1.RatedUsage != 120.0 {
t.Errorf("error updating rating usage: %v, %v", d, cc1.RatedUsage)
}
}
func TestMultipleResultMerge(t *testing.T) {

View File

@@ -526,6 +526,7 @@ func (cd *CallDescriptor) getCost() (*CallCost, error) {
cc.Cost = utils.Round(cc.Cost, roundingDecimals, roundingMethod)
//utils.Logger.Info(fmt.Sprintf("<Rater> Get Cost: %s => %v", cd.GetKey(), cc))
cc.Timespans.Compress()
cc.UpdateRatedUsage()
return cc, err
}
@@ -668,6 +669,7 @@ func (cd *CallDescriptor) debit(account *Account, dryRun bool, goNegative bool)
return nil, err
}
cc.updateCost()
cc.UpdateRatedUsage()
cc.Timespans.Compress()
//log.Printf("OUT CC: ", cc)
return

View File

@@ -107,6 +107,7 @@ func (self *CdrServer) ProcessExternalCdr(eCDR *ExternalCDR) error {
// RPC method, used to log callcosts to db
func (self *CdrServer) LogCallCost(ccl *CallCostLog) error {
ccl.CallCost.UpdateRatedUsage() // make sure rated usage is updated
if ccl.CheckDuplicate {
_, err := self.guard.Guard(func() (interface{}, error) {
cc, err := self.cdrDb.GetCallCostLog(ccl.CgrId, ccl.RunId)

View File

@@ -157,7 +157,7 @@ func (self *SMGSession) refund(refundDuration time.Duration) error {
Increments: refundIncrements,
}
cd.Increments.Compress()
utils.Logger.Info(fmt.Sprintf("Refunding duration %v with cd: %+v", initialRefundDuration, utils.ToJSON(cd)))
utils.Logger.Info(fmt.Sprintf("Refunding duration %v with cd: %s", initialRefundDuration, utils.ToJSON(cd)))
var response float64
err := self.rater.RefundIncrements(cd, &response)
if err != nil {

View File

@@ -228,18 +228,54 @@ func (self *SMGeneric) ChargeEvent(gev SMGenericEvent, clnt *rpc2.Client) (maxDu
}
if err != nil { // Refund the ones already taken since we have error on one of the debits
for _, sR := range sessionRuns {
for _, cc := range sR.CallCosts {
utils.Logger.Debug(fmt.Sprintf("%+v", cc)) // Refund here
if len(sR.CallCosts) == 0 {
continue
}
cc := sR.CallCosts[0]
if len(sR.CallCosts) > 1 {
for _, ccSR := range sR.CallCosts {
cc.Merge(ccSR)
}
}
// collect increments
var refundIncrements engine.Increments
cc.Timespans.Decompress()
for _, ts := range cc.Timespans {
refundIncrements = append(refundIncrements, ts.Increments...)
}
// refund cc
if len(refundIncrements) > 0 {
cd := &engine.CallDescriptor{
Direction: cc.Direction,
Tenant: cc.Tenant,
Category: cc.Category,
Subject: cc.Subject,
Account: cc.Account,
Destination: cc.Destination,
TOR: cc.TOR,
Increments: refundIncrements,
}
cd.Increments.Compress()
utils.Logger.Info(fmt.Sprintf("Refunding session run callcost: %s", utils.ToJSON(cd)))
var response float64
err := self.rater.RefundIncrements(cd, &response)
if err != nil {
return nilDuration, err
}
}
}
return nilDuration, err
}
var withErrors bool
for _, sR := range sessionRuns {
var cc *engine.CallCost
for _, ccSR := range sR.CallCosts {
cc.Merge(ccSR)
if len(sR.CallCosts) == 0 {
continue
}
cc := sR.CallCosts[0]
if len(sR.CallCosts) > 1 {
for _, ccSR := range sR.CallCosts[1:] {
cc.Merge(ccSR)
}
}
var reply string
if err := self.cdrsrv.LogCallCost(&engine.CallCostLog{

View File

@@ -89,6 +89,13 @@ func TestCondKeyValue(t *testing.T) {
if check, err := cl.Check(o); !check || err != nil {
t.Errorf("Error checking struct: %v %v (%v)", check, err, ToIJSON(cl.rootElement))
}
err = cl.Parse(`{"Other":true, "Field":{"*gt":7}}`)
if err != nil {
t.Errorf("Error loading structure: %+v (%v)", ToIJSON(cl.rootElement), err)
}
if check, err := cl.Check(o); check || err != nil {
t.Errorf("Error checking struct: %v %v (%v)", check, err, ToIJSON(cl.rootElement))
}
err = cl.Parse(``)
if err != nil {
t.Errorf("Error loading structure: %+v (%v)", ToIJSON(cl.rootElement), err)