mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-21 15:18:44 +05:00
fix for wrong cdr cost
This commit is contained in:
@@ -162,13 +162,19 @@ func (cc *CallCost) AsJSON() string {
|
||||
return utils.ToJSON(cc)
|
||||
}
|
||||
|
||||
// public function to update final (merged) callcost
|
||||
func (cc *CallCost) UpdateCost() {
|
||||
cc.deductConnectFee = true
|
||||
cc.updateCost()
|
||||
}
|
||||
|
||||
func (cc *CallCost) updateCost() {
|
||||
cost := 0.0
|
||||
if cc.deductConnectFee { // add back the connectFee
|
||||
cost += cc.GetConnectFee()
|
||||
}
|
||||
for _, ts := range cc.Timespans {
|
||||
ts.Cost = ts.calculateCost()
|
||||
ts.Cost = ts.CalculateCost()
|
||||
cost += ts.Cost
|
||||
cost = utils.Round(cost, globalRoundingDecimals, utils.ROUNDING_MIDDLE) // just get rid of the extra decimals
|
||||
}
|
||||
|
||||
@@ -458,7 +458,7 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) {
|
||||
// handle max cost
|
||||
maxCost, strategy := ts.RateInterval.GetMaxCost()
|
||||
|
||||
ts.Cost = ts.calculateCost()
|
||||
ts.Cost = ts.CalculateCost()
|
||||
cost += ts.Cost
|
||||
cd.MaxCostSoFar += cost
|
||||
//log.Print("Before: ", cost)
|
||||
@@ -517,7 +517,7 @@ func (cd *CallDescriptor) getCost() (*CallCost, error) {
|
||||
if cd.LoopIndex == 0 && i == 0 && ts.RateInterval != nil {
|
||||
cost += ts.RateInterval.Rating.ConnectFee
|
||||
}
|
||||
cost += ts.calculateCost()
|
||||
cost += ts.CalculateCost()
|
||||
}
|
||||
|
||||
//startIndex := len(fmt.Sprintf("%s:%s:%s:", cd.Direction, cd.Tenant, cd.Category))
|
||||
|
||||
@@ -108,6 +108,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.UpdateCost() // make sure the total cost reflect the increments
|
||||
ccl.CallCost.UpdateRatedUsage() // make sure rated usage is updated
|
||||
if ccl.CheckDuplicate {
|
||||
_, err := self.guard.Guard(func() (interface{}, error) {
|
||||
@@ -177,6 +178,7 @@ func (self *CdrServer) processCdr(cdr *CDR) (err error) {
|
||||
}
|
||||
if self.cgrCfg.CDRSStoreCdrs { // Store RawCDRs, this we do sync so we can reply with the status
|
||||
if cdr.CostDetails != nil {
|
||||
cdr.CostDetails.UpdateCost()
|
||||
cdr.CostDetails.UpdateRatedUsage()
|
||||
}
|
||||
if err := self.cdrDb.SetCDR(cdr, false); err != nil { // Only original CDR stored in primary table, no derived
|
||||
@@ -236,6 +238,7 @@ func (self *CdrServer) rateStoreStatsReplicate(cdr *CDR, sendToStats bool) error
|
||||
if self.cgrCfg.CDRSStoreCdrs { // Store CDRs
|
||||
// Store RatedCDR
|
||||
if cdr.CostDetails != nil {
|
||||
cdr.CostDetails.UpdateCost()
|
||||
cdr.CostDetails.UpdateRatedUsage()
|
||||
}
|
||||
if err := self.cdrDb.SetCDR(cdr, true); err != nil {
|
||||
|
||||
@@ -280,7 +280,7 @@ func (incs Increments) GetTotalCost() float64 {
|
||||
for _, increment := range incs {
|
||||
cost += increment.GetCost()
|
||||
}
|
||||
return cost
|
||||
return utils.Round(cost, globalRoundingDecimals, utils.ROUNDING_MIDDLE)
|
||||
}
|
||||
|
||||
func (incs Increments) Length() (length int) {
|
||||
@@ -321,15 +321,14 @@ func (ts *TimeSpan) SetRateInterval(interval *RateInterval) {
|
||||
// Returns the cost of the timespan according to the relevant cost interval.
|
||||
// It also sets the Cost field of this timespan (used for refund on session
|
||||
// manager debit loop where the cost cannot be recalculated)
|
||||
func (ts *TimeSpan) calculateCost() float64 {
|
||||
func (ts *TimeSpan) CalculateCost() float64 {
|
||||
if ts.Increments.Length() == 0 {
|
||||
if ts.RateInterval == nil {
|
||||
return 0
|
||||
}
|
||||
return ts.RateInterval.GetCost(ts.GetDuration(), ts.GetGroupStart())
|
||||
} else {
|
||||
cost := ts.Increments.GetTotalCost()
|
||||
return utils.Round(cost, globalRoundingDecimals, utils.ROUNDING_MIDDLE)
|
||||
return ts.Increments.GetTotalCost()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,7 +351,7 @@ func (ts *TimeSpan) createIncrementsSlice() {
|
||||
// because ts cost is rounded
|
||||
//incrementCost := rate / rateUnit.Seconds() * rateIncrement.Seconds()
|
||||
nbIncrements := int(ts.GetDuration() / rateIncrement)
|
||||
incrementCost := ts.calculateCost() / float64(nbIncrements)
|
||||
incrementCost := ts.CalculateCost() / float64(nbIncrements)
|
||||
incrementCost = utils.Round(incrementCost, ts.RateInterval.Rating.RoundingDecimals, ts.RateInterval.Rating.RoundingMethod)
|
||||
for s := 0; s < nbIncrements; s++ {
|
||||
inc := &Increment{
|
||||
|
||||
@@ -214,7 +214,7 @@ func TestTSTimespanGetCost(t *testing.T) {
|
||||
t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 5, 17, 55, 0, 0, time.UTC)
|
||||
ts1 := TimeSpan{TimeStart: t1, TimeEnd: t2}
|
||||
if ts1.calculateCost() != 0 {
|
||||
if ts1.CalculateCost() != 0 {
|
||||
t.Error("No interval and still kicking")
|
||||
}
|
||||
ts1.SetRateInterval(
|
||||
@@ -223,12 +223,12 @@ func TestTSTimespanGetCost(t *testing.T) {
|
||||
Rating: &RIRate{Rates: RateGroups{&Rate{0, 1.0, 1 * time.Second, 1 * time.Second}}},
|
||||
},
|
||||
)
|
||||
if ts1.calculateCost() != 600 {
|
||||
if ts1.CalculateCost() != 600 {
|
||||
t.Error("Expected 10 got ", ts1.Cost)
|
||||
}
|
||||
ts1.RateInterval = nil
|
||||
ts1.SetRateInterval(&RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{0, 1.0, 1 * time.Second, 60 * time.Second}}}})
|
||||
if ts1.calculateCost() != 10 {
|
||||
if ts1.CalculateCost() != 10 {
|
||||
t.Error("Expected 6000 got ", ts1.Cost)
|
||||
}
|
||||
}
|
||||
@@ -239,8 +239,8 @@ func TestTSTimespanGetCostIntervals(t *testing.T) {
|
||||
for i := 0; i < 11; i++ {
|
||||
ts.Increments[i] = &Increment{Cost: 0.02}
|
||||
}
|
||||
if ts.calculateCost() != 0.22 {
|
||||
t.Error("Error caclulating timespan cost: ", ts.calculateCost())
|
||||
if ts.CalculateCost() != 0.22 {
|
||||
t.Error("Error caclulating timespan cost: ", ts.CalculateCost())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -180,6 +180,7 @@ func (s *Session) Refund(lastCC *engine.CallCost, hangupTime time.Time) error {
|
||||
lastCC.Timespans = lastCC.Timespans[:i]
|
||||
} else {
|
||||
ts.SplitByIncrement(lastRefundedIncrementIndex)
|
||||
ts.Cost = ts.CalculateCost()
|
||||
}
|
||||
break // do not go to other timespans
|
||||
} else {
|
||||
@@ -214,6 +215,7 @@ func (s *Session) Refund(lastCC *engine.CallCost, hangupTime time.Time) error {
|
||||
}
|
||||
//utils.Logger.Debug(fmt.Sprintf("REFUND INCR: %s", utils.ToJSON(refundIncrements)))
|
||||
lastCC.Cost -= refundIncrements.GetTotalCost()
|
||||
lastCC.UpdateRatedUsage()
|
||||
lastCC.Timespans.Compress()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -132,6 +132,7 @@ func (self *SMGSession) refund(refundDuration time.Duration) error {
|
||||
lastCC.Timespans = lastCC.Timespans[:i]
|
||||
} else {
|
||||
ts.SplitByIncrement(lastRefundedIncrementIndex)
|
||||
ts.Cost = ts.CalculateCost()
|
||||
}
|
||||
break // do not go to other timespans
|
||||
} else {
|
||||
@@ -166,6 +167,7 @@ func (self *SMGSession) refund(refundDuration time.Duration) error {
|
||||
}
|
||||
//utils.Logger.Debug(fmt.Sprintf("REFUND INCR: %s", utils.ToJSON(refundIncrements)))
|
||||
lastCC.Cost -= refundIncrements.GetTotalCost()
|
||||
lastCC.UpdateRatedUsage()
|
||||
lastCC.Timespans.Compress()
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user