本文整理汇总了Golang中github.com/cgrates/cgrates/engine.CallCost类的典型用法代码示例。如果您正苦于以下问题:Golang CallCost类的具体用法?Golang CallCost怎么用?Golang CallCost使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了CallCost类的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: Refund
func (s *Session) Refund(lastCC *engine.CallCost, hangupTime time.Time) error {
end := lastCC.Timespans[len(lastCC.Timespans)-1].TimeEnd
refundDuration := end.Sub(hangupTime)
//engine.Logger.Debug(fmt.Sprintf("HANGUPTIME: %s REFUNDDURATION: %s", hangupTime.String(), refundDuration.String()))
var refundIncrements engine.Increments
for i := len(lastCC.Timespans) - 1; i >= 0; i-- {
ts := lastCC.Timespans[i]
tsDuration := ts.GetDuration()
if refundDuration <= tsDuration {
lastRefundedIncrementIndex := -1
for j := len(ts.Increments) - 1; j >= 0; j-- {
increment := ts.Increments[j]
if increment.Duration <= refundDuration {
refundIncrements = append(refundIncrements, increment)
refundDuration -= increment.Duration
lastRefundedIncrementIndex = j
} else {
break //increment duration is larger, cannot refund increment
}
}
if lastRefundedIncrementIndex == 0 {
lastCC.Timespans[i] = nil
lastCC.Timespans = lastCC.Timespans[:i]
} else {
ts.SplitByIncrement(lastRefundedIncrementIndex)
}
break // do not go to other timespans
} else {
refundIncrements = append(refundIncrements, ts.Increments...)
// remove the timespan entirely
lastCC.Timespans[i] = nil
lastCC.Timespans = lastCC.Timespans[:i]
// continue to the next timespan with what is left to refund
refundDuration -= tsDuration
}
}
// show only what was actualy refunded (stopped in timespan)
// engine.Logger.Info(fmt.Sprintf("Refund duration: %v", initialRefundDuration-refundDuration))
if len(refundIncrements) > 0 {
cd := &engine.CallDescriptor{
Direction: lastCC.Direction,
Tenant: lastCC.Tenant,
Category: lastCC.Category,
Subject: lastCC.Subject,
Account: lastCC.Account,
Destination: lastCC.Destination,
Increments: refundIncrements,
}
var response float64
err := s.sessionManager.Rater().RefundIncrements(cd, &response)
if err != nil {
return err
}
}
//engine.Logger.Debug(fmt.Sprintf("REFUND INCR: %s", utils.ToJSON(refundIncrements)))
lastCC.Cost -= refundIncrements.GetTotalCost()
lastCC.Timespans.Compress()
return nil
}
开发者ID:nikbyte,项目名称:cgrates,代码行数:60,代码来源:session.go
示例2: TestTpBalanceCounter
func TestTpBalanceCounter(t *testing.T) {
if !*testIntegration {
return
}
tStart := time.Date(2016, 3, 31, 0, 0, 0, 0, time.UTC)
cd := engine.CallDescriptor{
Direction: "*out",
Category: "call",
Tenant: "cgrates.org",
Subject: "1001",
Destination: "+49",
DurationIndex: 0,
TimeStart: tStart,
TimeEnd: tStart.Add(time.Duration(20) * time.Second),
}
var cc engine.CallCost
if err := tpRPC.Call("Responder.Debit", cd, &cc); err != nil {
t.Error("Got error on Responder.GetCost: ", err.Error())
} else if cc.GetDuration() != 20*time.Second {
t.Errorf("Calling Responder.MaxDebit got callcost: %v", cc.GetDuration())
}
var acnt *engine.Account
attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"}
if err := tpRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
t.Error("Got error on ApierV2.GetAccount: ", err.Error())
} else if acnt.UnitCounters[utils.MONETARY][1].Counters[0].Value != 20.0 {
t.Errorf("Calling ApierV2.GetBalance received: %s", utils.ToIJSON(acnt))
}
}
开发者ID:iwada,项目名称:cgrates,代码行数:29,代码来源:tp_it_test.go
示例3: TestTpZeroNegativeCost
func TestTpZeroNegativeCost(t *testing.T) {
tStart := time.Date(2016, 3, 31, 0, 0, 0, 0, time.UTC)
cd := engine.CallDescriptor{
Direction: "*out",
Category: "call",
Tenant: "cgrates.org",
Subject: "free",
Account: "1013",
Destination: "+4915",
DurationIndex: 0,
TimeStart: tStart,
TimeEnd: tStart.Add(time.Duration(20) * time.Second),
}
var cc engine.CallCost
if err := tpRPC.Call("Responder.Debit", cd, &cc); err != nil {
t.Error("Got error on Responder.GetCost: ", err.Error())
} else if cc.GetDuration() != 20*time.Second {
t.Errorf("Calling Responder.MaxDebit got callcost: %v", utils.ToIJSON(cc))
}
var acnt engine.Account
attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1013"}
if err := tpRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
t.Error("Got error on ApierV2.GetAccount: ", err.Error())
} else if acnt.BalanceMap[utils.VOICE][0].Value != 100.0 {
t.Errorf("Calling ApierV2.GetAccount received: %s", utils.ToIJSON(acnt))
}
}
开发者ID:cgrates,项目名称:cgrates,代码行数:27,代码来源:tp_it_test.go
示例4: GetDataCost
func (apier *ApierV1) GetDataCost(attrs AttrGetDataCost, reply *engine.DataCost) error {
usageAsDuration := time.Duration(attrs.Usage) * time.Second // Convert to seconds to match the loaded rates
cd := &engine.CallDescriptor{
Direction: attrs.Direction,
Category: attrs.Category,
Tenant: attrs.Tenant,
Account: attrs.Account,
Subject: attrs.Subject,
TimeStart: attrs.StartTime,
TimeEnd: attrs.StartTime.Add(usageAsDuration),
DurationIndex: usageAsDuration,
TOR: utils.DATA,
}
var cc engine.CallCost
if err := apier.Responder.GetCost(cd, &cc); err != nil {
return utils.NewErrServerError(err)
}
if dc, err := cc.ToDataCost(); err != nil {
return utils.NewErrServerError(err)
} else if dc != nil {
*reply = *dc
}
return nil
}
开发者ID:eloycoto,项目名称:cgrates,代码行数:24,代码来源:costs.go
示例5: debitLoop
// the debit loop method (to be stoped by sending somenthing on stopDebit channel)
func (s *Session) debitLoop(runIdx int) {
nextCd := *s.sessionRuns[runIdx].callDescriptor
index := 0.0
debitPeriod := s.sessionManager.GetDebitPeriod()
for {
select {
case <-s.stopDebit:
return
default:
}
if index > 0 { // first time use the session start time
nextCd.TimeStart = nextCd.TimeEnd
}
nextCd.TimeEnd = nextCd.TimeStart.Add(debitPeriod)
nextCd.LoopIndex = index
nextCd.DurationIndex += debitPeriod // first presumed duration
cc := new(engine.CallCost)
if err := s.sessionManager.MaxDebit(&nextCd, cc); err != nil {
engine.Logger.Err(fmt.Sprintf("Could not complete debit opperation: %v", err))
s.sessionManager.DisconnectSession(s.uuid, SYSTEM_ERROR, "")
return
}
if cc.GetDuration() == 0 {
s.sessionManager.DisconnectSession(s.uuid, INSUFFICIENT_FUNDS, nextCd.Destination)
return
}
if cc.GetDuration() <= cfg.FSMinDurLowBalance && len(cfg.FSLowBalanceAnnFile) != 0 {
if _, err := fsock.FS.SendApiCmd(fmt.Sprintf("uuid_broadcast %s %s aleg\n\n", s.uuid, cfg.FSLowBalanceAnnFile)); err != nil {
engine.Logger.Err(fmt.Sprintf("<SessionManager> Could not send uuid_broadcast to freeswitch: %s", err.Error()))
}
}
s.sessionRuns[runIdx].callCosts = append(s.sessionRuns[runIdx].callCosts, cc)
nextCd.TimeEnd = cc.GetEndTime() // set debited timeEnd
// update call duration with real debited duration
nextCd.DurationIndex -= debitPeriod
nextCd.DurationIndex += nextCd.GetDuration()
time.Sleep(cc.GetDuration())
index++
}
}
开发者ID:intralanman,项目名称:cgrates,代码行数:41,代码来源:session.go
示例6: ChargeEvent
// Processes one time events (eg: SMS)
func (smg *SMGeneric) ChargeEvent(gev SMGenericEvent) (maxUsage time.Duration, err error) {
cacheKey := "ChargeEvent" + gev.GetCgrId(smg.timezone)
if item, err := smg.responseCache.Get(cacheKey); err == nil && item != nil {
return item.Value.(time.Duration), item.Err
}
defer smg.responseCache.Cache(cacheKey, &cache.CacheItem{Value: maxUsage, Err: err})
var sessionRuns []*engine.SessionRun
if err = smg.rater.Call("Responder.GetSessionRuns", gev.AsStoredCdr(smg.cgrCfg, smg.timezone), &sessionRuns); err != nil {
return
} else if len(sessionRuns) == 0 {
return
}
var maxDurInit bool // Avoid differences between default 0 and received 0
for _, sR := range sessionRuns {
cc := new(engine.CallCost)
if err = smg.rater.Call("Responder.MaxDebit", sR.CallDescriptor, cc); err != nil {
utils.Logger.Err(fmt.Sprintf("<SMGeneric> Could not Debit CD: %+v, RunID: %s, error: %s", sR.CallDescriptor, sR.DerivedCharger.RunID, err.Error()))
break
}
sR.CallCosts = append(sR.CallCosts, cc) // Save it so we can revert on issues
if ccDur := cc.GetDuration(); ccDur == 0 {
err = utils.ErrInsufficientCredit
break
} else if !maxDurInit || ccDur < maxUsage {
maxUsage = ccDur
}
}
if err != nil { // Refund the ones already taken since we have error on one of the debits
for _, sR := range sessionRuns {
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 := cc.CreateCallDescriptor()
cd.Increments = refundIncrements
cd.CgrID = sR.CallDescriptor.CgrID
cd.RunID = sR.CallDescriptor.RunID
cd.Increments.Compress()
//utils.Logger.Info(fmt.Sprintf("Refunding session run callcost: %s", utils.ToJSON(cd)))
var response float64
err = smg.rater.Call("Responder.RefundIncrements", cd, &response)
if err != nil {
return
}
}
}
return
}
var withErrors bool
for _, sR := range sessionRuns {
if len(sR.CallCosts) == 0 {
continue
}
cc := sR.CallCosts[0]
if len(sR.CallCosts) > 1 {
for _, ccSR := range sR.CallCosts[1:] {
cc.Merge(ccSR)
}
}
cc.Round()
roundIncrements := cc.GetRoundIncrements()
if len(roundIncrements) != 0 {
cd := cc.CreateCallDescriptor()
cd.Increments = roundIncrements
var response float64
if errRefund := smg.rater.Call("Responder.RefundRounding", cd, &response); errRefund != nil {
utils.Logger.Err(fmt.Sprintf("<SM> ERROR failed to refund rounding: %v", errRefund))
}
}
var reply string
smCost := &engine.SMCost{
CGRID: gev.GetCgrId(smg.timezone),
CostSource: utils.SESSION_MANAGER_SOURCE,
RunID: sR.DerivedCharger.RunID,
OriginHost: gev.GetOriginatorIP(utils.META_DEFAULT),
OriginID: gev.GetUUID(),
CostDetails: cc,
}
if errStore := smg.cdrsrv.Call("CdrsV1.StoreSMCost", engine.AttrCDRSStoreSMCost{Cost: smCost,
CheckDuplicate: true}, &reply); errStore != nil && !strings.HasSuffix(errStore.Error(), utils.ErrExists.Error()) {
withErrors = true
utils.Logger.Err(fmt.Sprintf("<SMGeneric> Could not save CC: %+v, RunID: %s error: %s", cc, sR.DerivedCharger.RunID, errStore.Error()))
}
}
if withErrors {
err = ErrPartiallyExecuted
//.........这里部分代码省略.........
开发者ID:rinor,项目名称:cgrates,代码行数:101,代码来源:smgeneric.go
示例7: TestTutLocalMaxDebit
// Check call costs
func TestTutLocalMaxDebit(t *testing.T) {
if !*testLocal {
return
}
tStart := time.Date(2014, 8, 4, 13, 0, 0, 0, time.UTC)
cd := engine.CallDescriptor{
Direction: "*out",
Category: "call",
Tenant: "cgrates.org",
Subject: "1001",
Account: "1001",
Destination: "1002",
DurationIndex: 0,
TimeStart: tStart,
TimeEnd: tStart.Add(time.Duration(20) * time.Second),
}
var cc engine.CallCost
if err := tutLocalRpc.Call("Responder.MaxDebit", cd, &cc); err != nil {
t.Error("Got error on Responder.GetCost: ", err.Error())
} else if cc.GetDuration() == 20 {
t.Errorf("Calling Responder.MaxDebit got callcost: %v", cc.GetDuration())
}
cd = engine.CallDescriptor{
Direction: "*out",
Category: "call",
Tenant: "cgrates.org",
Subject: "1001",
Account: "1001",
Destination: "1003",
DurationIndex: 0,
TimeStart: tStart,
TimeEnd: tStart.Add(time.Duration(200) * time.Second),
}
if err := tutLocalRpc.Call("Responder.MaxDebit", cd, &cc); err != nil {
t.Error("Got error on Responder.MaxDebit: ", err.Error())
} else if cc.GetDuration() == 200 {
t.Errorf("Calling Responder.MaxDebit got duration: %v", cc.GetDuration())
}
cd = engine.CallDescriptor{
Direction: "*out",
Category: "call",
Tenant: "cgrates.org",
Subject: "1001",
Account: "1001",
Destination: "1007",
DurationIndex: 0,
TimeStart: tStart,
TimeEnd: tStart.Add(time.Duration(120) * time.Second),
}
if err := tutLocalRpc.Call("Responder.MaxDebit", cd, &cc); err != nil {
t.Error("Got error on Responder.GetCost: ", err.Error())
} else if cc.GetDuration() == 120 {
t.Errorf("Calling Responder.MaxDebit got callcost: %v", cc.GetDuration())
}
cd = engine.CallDescriptor{
Direction: "*out",
Category: "call",
Tenant: "cgrates.org",
Subject: "1004",
Account: "1004",
Destination: "1007",
DurationIndex: 0,
TimeStart: tStart,
TimeEnd: tStart.Add(time.Duration(120) * time.Second),
}
if err := tutLocalRpc.Call("Responder.MaxDebit", cd, &cc); err != nil {
t.Error("Got error on Responder.GetCost: ", err.Error())
} else if cc.GetDuration() != time.Duration(62)*time.Second { // We have as strategy *dsconnect
t.Errorf("Calling Responder.MaxDebit got callcost: %v", cc.GetDuration())
}
var maxTime float64
if err := tutLocalRpc.Call("Responder.GetMaxSessionTime", cd, &maxTime); err != nil {
t.Error("Got error on Responder.GetCost: ", err.Error())
} else if maxTime != 62000000000 { // We have as strategy *dsconnect
t.Errorf("Calling Responder.GetMaxSessionTime got maxTime: %f", maxTime)
}
}
开发者ID:nikbyte,项目名称:cgrates,代码行数:78,代码来源:tutorial_local_test.go
示例8: TestTutLocalGetCosts
// Check call costs
func TestTutLocalGetCosts(t *testing.T) {
if !*testLocal {
return
}
tStart, _ := utils.ParseDate("2014-08-04T13:00:00Z")
tEnd, _ := utils.ParseDate("2014-08-04T13:00:20Z")
cd := engine.CallDescriptor{
Direction: "*out",
Category: "call",
Tenant: "cgrates.org",
Subject: "1001",
Account: "1001",
Destination: "1002",
DurationIndex: 0,
TimeStart: tStart,
TimeEnd: tEnd,
}
var cc engine.CallCost
if err := tutLocalRpc.Call("Responder.GetCost", cd, &cc); err != nil {
t.Error("Got error on Responder.GetCost: ", err.Error())
} else if cc.Cost != 0.6 {
t.Errorf("Calling Responder.GetCost got callcost: %v", cc.Cost)
}
// Make sure that the same cost is returned via users aliasing
cd = engine.CallDescriptor{
Direction: "*out",
Category: "call",
Tenant: utils.USERS,
Subject: utils.USERS,
Account: utils.USERS,
Destination: "1002",
DurationIndex: 0,
TimeStart: tStart,
TimeEnd: tEnd,
ExtraFields: map[string]string{"Uuid": "388539dfd4f5cefee8f488b78c6c244b9e19138e"},
}
if err := tutLocalRpc.Call("Responder.GetCost", cd, &cc); err != nil {
t.Error("Got error on Responder.GetCost: ", err.Error())
} else if cc.Cost != 0.6 {
t.Errorf("Calling Responder.GetCost got callcost: %v", cc.Cost)
}
tStart, _ = utils.ParseDate("2014-08-04T13:00:00Z")
tEnd, _ = utils.ParseDate("2014-08-04T13:01:25Z")
cd = engine.CallDescriptor{
Direction: "*out",
Category: "call",
Tenant: "cgrates.org",
Subject: "1001",
Account: "1001",
Destination: "1002",
DurationIndex: 0,
TimeStart: tStart,
TimeEnd: tEnd,
}
if err := tutLocalRpc.Call("Responder.GetCost", cd, &cc); err != nil {
t.Error("Got error on Responder.GetCost: ", err.Error())
} else if cc.Cost != 0.6417 { // 0.01 first minute, 0.04 25 seconds with RT_20CNT
t.Errorf("Calling Responder.GetCost got callcost: %v", cc.Cost)
}
tStart, _ = utils.ParseDate("2014-08-04T13:00:00Z")
tEnd, _ = utils.ParseDate("2014-08-04T13:00:20Z")
cd = engine.CallDescriptor{
Direction: "*out",
Category: "call",
Tenant: "cgrates.org",
Subject: "1001",
Account: "1001",
Destination: "1003",
DurationIndex: 0,
TimeStart: tStart,
TimeEnd: tEnd,
}
if err := tutLocalRpc.Call("Responder.GetCost", cd, &cc); err != nil {
t.Error("Got error on Responder.GetCost: ", err.Error())
} else if cc.Cost != 1 {
t.Errorf("Calling Responder.GetCost got callcost: %v", cc.Cost)
}
tStart, _ = utils.ParseDate("2014-08-04T13:00:00Z")
tEnd, _ = utils.ParseDate("2014-08-04T13:01:25Z")
cd = engine.CallDescriptor{
Direction: "*out",
Category: "call",
Tenant: "cgrates.org",
Subject: "1001",
Account: "1001",
Destination: "1003",
DurationIndex: 0,
TimeStart: tStart,
TimeEnd: tEnd,
}
if err := tutLocalRpc.Call("Responder.GetCost", cd, &cc); err != nil {
t.Error("Got error on Responder.GetCost: ", err.Error())
} else if cc.Cost != 1.3 {
t.Errorf("Calling Responder.GetCost got callcost: %v", cc.Cost)
}
tStart, _ = utils.ParseDate("2014-08-04T13:00:00Z")
tEnd, _ = utils.ParseDate("2014-08-04T13:00:20Z")
cd = engine.CallDescriptor{
Direction: "*out",
//.........这里部分代码省略.........
开发者ID:nikbyte,项目名称:cgrates,代码行数:101,代码来源:tutorial_local_test.go
示例9: debitLoop
// the debit loop method (to be stoped by sending somenthing on stopDebit channel)
func (s *Session) debitLoop(runIdx int) {
nextCd := s.sessionRuns[runIdx].CallDescriptor
nextCd.CgrID = s.eventStart.GetCgrId(s.sessionManager.Timezone())
index := 0.0
debitPeriod := s.sessionManager.DebitInterval()
for {
select {
case <-s.stopDebit:
return
default:
}
if index > 0 { // first time use the session start time
nextCd.TimeStart = nextCd.TimeEnd
}
nextCd.TimeEnd = nextCd.TimeStart.Add(debitPeriod)
nextCd.LoopIndex = index
nextCd.DurationIndex += debitPeriod // first presumed duration
cc := new(engine.CallCost)
if err := s.sessionManager.Rater().Call("Responder.MaxDebit", nextCd, cc); err != nil {
utils.Logger.Err(fmt.Sprintf("Could not complete debit opperation: %v", err))
if err.Error() == utils.ErrUnauthorizedDestination.Error() {
s.sessionManager.DisconnectSession(s.eventStart, s.connId, UNAUTHORIZED_DESTINATION)
return
}
s.sessionManager.DisconnectSession(s.eventStart, s.connId, SYSTEM_ERROR)
return
}
if cc.GetDuration() == 0 {
s.sessionManager.DisconnectSession(s.eventStart, s.connId, INSUFFICIENT_FUNDS)
return
}
if s.warnMinDur != time.Duration(0) && cc.GetDuration() <= s.warnMinDur {
s.sessionManager.WarnSessionMinDuration(s.eventStart.GetUUID(), s.connId)
}
s.sessionRuns[runIdx].CallCosts = append(s.sessionRuns[runIdx].CallCosts, cc)
nextCd.TimeEnd = cc.GetEndTime() // set debited timeEnd
// update call duration with real debited duration
nextCd.DurationIndex -= debitPeriod
nextCd.DurationIndex += cc.GetDuration()
nextCd.MaxCostSoFar += cc.Cost
time.Sleep(cc.GetDuration())
index++
}
}
开发者ID:iwada,项目名称:cgrates,代码行数:45,代码来源:session.go
示例10: debitLoop
// the debit loop method (to be stoped by sending somenthing on stopDebit channel)
func (s *Session) debitLoop(runIdx int) {
nextCd := s.sessionRuns[runIdx].CallDescriptor
nextCd.CgrId = s.eventStart.GetCgrId("")
index := 0.0
debitPeriod := s.sessionManager.DebitInterval()
for {
select {
case <-s.stopDebit:
return
default:
}
if index > 0 { // first time use the session start time
nextCd.TimeStart = nextCd.TimeEnd
}
nextCd.TimeEnd = nextCd.TimeStart.Add(debitPeriod)
nextCd.LoopIndex = index
//engine.Logger.Debug(fmt.Sprintf("NEXTCD: %s", utils.ToJSON(nextCd)))
nextCd.DurationIndex += debitPeriod // first presumed duration
cc := new(engine.CallCost)
if err := s.sessionManager.Rater().MaxDebit(nextCd, cc); err != nil {
engine.Logger.Err(fmt.Sprintf("Could not complete debit opperation: %v", err))
s.sessionManager.DisconnectSession(s.eventStart, s.connId, SYSTEM_ERROR)
return
}
if cc.GetDuration() == 0 {
s.sessionManager.DisconnectSession(s.eventStart, s.connId, INSUFFICIENT_FUNDS)
return
}
if s.warnMinDur != time.Duration(0) && cc.GetDuration() <= s.warnMinDur {
s.sessionManager.WarnSessionMinDuration(s.eventStart.GetUUID(), s.connId)
}
s.sessionRuns[runIdx].CallCosts = append(s.sessionRuns[runIdx].CallCosts, cc)
//engine.Logger.Debug(fmt.Sprintf("CALLCOST: %s", utils.ToJSON(cc)))
nextCd.TimeEnd = cc.GetEndTime() // set debited timeEnd
//engine.Logger.Debug(fmt.Sprintf("NEXTCD: %s DURATION: %s", utils.ToJSON(nextCd), nextCd.GetDuration().String()))
// update call duration with real debited duration
nextCd.DurationIndex -= debitPeriod
nextCd.DurationIndex += cc.GetDuration()
nextCd.MaxCostSoFar += cc.Cost
time.Sleep(cc.GetDuration())
index++
}
}
开发者ID:nikbyte,项目名称:cgrates,代码行数:44,代码来源:session.go
示例11: Refund
func (s *Session) Refund(lastCC *engine.CallCost, hangupTime time.Time) error {
end := lastCC.Timespans[len(lastCC.Timespans)-1].TimeEnd
refundDuration := end.Sub(hangupTime)
var refundIncrements engine.Increments
for i := len(lastCC.Timespans) - 1; i >= 0; i-- {
ts := lastCC.Timespans[i]
tsDuration := ts.GetDuration()
if refundDuration <= tsDuration {
lastRefundedIncrementIndex := -1
for j := len(ts.Increments) - 1; j >= 0; j-- {
increment := ts.Increments[j]
if increment.Duration <= refundDuration {
refundIncrements = append(refundIncrements, increment)
refundDuration -= increment.Duration
lastRefundedIncrementIndex = j
} else {
break //increment duration is larger, cannot refund increment
}
}
if lastRefundedIncrementIndex == 0 {
lastCC.Timespans[i] = nil
lastCC.Timespans = lastCC.Timespans[:i]
} else {
ts.SplitByIncrement(lastRefundedIncrementIndex)
ts.Cost = ts.CalculateCost()
}
break // do not go to other timespans
} else {
refundIncrements = append(refundIncrements, ts.Increments...)
// remove the timespan entirely
lastCC.Timespans[i] = nil
lastCC.Timespans = lastCC.Timespans[:i]
// continue to the next timespan with what is left to refund
refundDuration -= tsDuration
}
}
// show only what was actualy refunded (stopped in timespan)
// utils.Logger.Info(fmt.Sprintf("Refund duration: %v", initialRefundDuration-refundDuration))
if len(refundIncrements) > 0 {
cd := &engine.CallDescriptor{
CgrID: s.eventStart.GetCgrId(s.sessionManager.Timezone()),
Direction: lastCC.Direction,
Tenant: lastCC.Tenant,
Category: lastCC.Category,
Subject: lastCC.Subject,
Account: lastCC.Account,
Destination: lastCC.Destination,
TOR: lastCC.TOR,
Increments: refundIncrements,
}
cd.Increments.Compress()
//utils.Logger.Info(fmt.Sprintf("Refunding duration %v with cd: %+v", refundDuration, cd))
var response float64
err := s.sessionManager.Rater().Call("Responder.RefundIncrements", cd, &response)
if err != nil {
return err
}
}
lastCC.Cost -= refundIncrements.GetTotalCost()
lastCC.UpdateRatedUsage()
lastCC.Timespans.Compress()
return nil
}
开发者ID:cgrates,项目名称:cgrates,代码行数:64,代码来源:session.go
注:本文中的github.com/cgrates/cgrates/engine.CallCost类示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论