mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
refound money
This commit is contained in:
@@ -26,7 +26,7 @@ import (
|
||||
|
||||
// Can hold different units as seconds or monetary
|
||||
type Balance struct {
|
||||
Id string
|
||||
Uuid string
|
||||
Value float64
|
||||
ExpirationDate time.Time
|
||||
Weight float64
|
||||
@@ -51,7 +51,7 @@ func (b *Balance) IsExpired() bool {
|
||||
|
||||
func (b *Balance) Clone() *Balance {
|
||||
return &Balance{
|
||||
Id: b.Id,
|
||||
Uuid: b.Uuid,
|
||||
Value: b.Value,
|
||||
DestinationId: b.DestinationId,
|
||||
ExpirationDate: b.ExpirationDate,
|
||||
@@ -138,3 +138,12 @@ func (bc BalanceChain) Clone() BalanceChain {
|
||||
}
|
||||
return newChain
|
||||
}
|
||||
|
||||
func (bc BalanceChain) GetBalance(uuid string) *Balance {
|
||||
for _, balance := range bc {
|
||||
if balance.Uuid == uuid {
|
||||
return balance
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ type CallDescriptor struct {
|
||||
Amount float64
|
||||
FallbackSubject string // the subject to check for destination if not found on primary subject
|
||||
RatingPlans []*RatingPlan
|
||||
Increments Increments
|
||||
userBalance *UserBalance
|
||||
}
|
||||
|
||||
@@ -408,6 +409,14 @@ func (cd *CallDescriptor) MaxDebit(startTime time.Time) (cc *CallCost, err error
|
||||
return cd.Debit()
|
||||
}
|
||||
|
||||
func (cd *CallDescriptor) RefoundIncrements() (left float64, err error) {
|
||||
if userBalance, err := cd.getUserBalance(); err == nil && userBalance != nil {
|
||||
defer storageGetter.SetUserBalance(userBalance)
|
||||
userBalance.refoundIncrements(cd.Increments, true)
|
||||
}
|
||||
return 0.0, err
|
||||
}
|
||||
|
||||
/*
|
||||
Interface method used to add/substract an amount of cents from user's money balance.
|
||||
The amount filed has to be filled in call descriptor.
|
||||
|
||||
@@ -381,7 +381,7 @@ func (csvr *CSVReader) LoadActions() (err error) {
|
||||
Weight: weight,
|
||||
ExpirationString: record[5],
|
||||
Balance: &Balance{
|
||||
Id: utils.GenUUID(),
|
||||
Uuid: utils.GenUUID(),
|
||||
Value: units,
|
||||
Weight: minutesWeight,
|
||||
SpecialPrice: value,
|
||||
|
||||
@@ -552,7 +552,7 @@ func TestLoadActions(t *testing.T) {
|
||||
ExpirationString: UNLIMITED,
|
||||
Weight: 10,
|
||||
Balance: &Balance{
|
||||
Id: as[0].Balance.Id,
|
||||
Uuid: as[0].Balance.Uuid,
|
||||
Value: 10,
|
||||
Weight: 10,
|
||||
},
|
||||
@@ -565,7 +565,7 @@ func TestLoadActions(t *testing.T) {
|
||||
ExpirationString: UNLIMITED,
|
||||
Weight: 10,
|
||||
Balance: &Balance{
|
||||
Id: as[1].Balance.Id,
|
||||
Uuid: as[1].Balance.Uuid,
|
||||
Value: 100,
|
||||
Weight: 10,
|
||||
SpecialPriceType: PRICE_ABSOLUTE,
|
||||
|
||||
@@ -76,6 +76,18 @@ func (rs *Responder) MaxDebit(arg CallDescriptor, reply *CallCost) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (rs *Responder) RefoundIncrements(arg CallDescriptor, reply *float64) (err error) {
|
||||
if rs.Bal != nil {
|
||||
*reply, err = rs.callMethod(&arg, "Responder.RefoundIncrements")
|
||||
} else {
|
||||
r, e := AccLock.Guard(arg.GetUserBalanceKey(), func() (float64, error) {
|
||||
return arg.RefoundIncrements()
|
||||
})
|
||||
*reply, err = r, e
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (rs *Responder) DebitCents(arg CallDescriptor, reply *float64) (err error) {
|
||||
if rs.Bal != nil {
|
||||
*reply, err = rs.callMethod(&arg, "Responder.DebitCents")
|
||||
@@ -340,6 +352,7 @@ type Connector interface {
|
||||
GetCost(CallDescriptor, *CallCost) error
|
||||
Debit(CallDescriptor, *CallCost) error
|
||||
MaxDebit(CallDescriptor, *CallCost) error
|
||||
RefoundIncrements(Increments, *float64) error
|
||||
DebitCents(CallDescriptor, *float64) error
|
||||
DebitSeconds(CallDescriptor, *float64) error
|
||||
GetMaxSessionTime(CallDescriptor, *float64) error
|
||||
@@ -360,6 +373,9 @@ func (rcc *RPCClientConnector) Debit(cd CallDescriptor, cc *CallCost) error {
|
||||
func (rcc *RPCClientConnector) MaxDebit(cd CallDescriptor, cc *CallCost) error {
|
||||
return rcc.Client.Call("Responder.MaxDebit", cd, cc)
|
||||
}
|
||||
func (rcc *RPCClientConnector) RefoundIncrements(cd CallDescriptor, resp *float64) error {
|
||||
return rcc.Client.Call("Responder.RefoundIncrements", cd, resp)
|
||||
}
|
||||
func (rcc *RPCClientConnector) DebitCents(cd CallDescriptor, resp *float64) error {
|
||||
return rcc.Client.Call("Responder.DebitCents", cd, resp)
|
||||
}
|
||||
|
||||
@@ -33,13 +33,13 @@ type TimeSpan struct {
|
||||
RateInterval *RateInterval
|
||||
CallDuration time.Duration // the call duration so far till TimeEnd
|
||||
overlapped bool // mark a timespan as overlapped by an expanded one
|
||||
Increments []*Increment
|
||||
Increments Increments
|
||||
}
|
||||
|
||||
type Increment struct {
|
||||
Duration time.Duration
|
||||
Cost float64
|
||||
BalanceId string
|
||||
BalanceUuid string
|
||||
BalanceType string
|
||||
BalanceRateInterval *RateInterval
|
||||
MinuteInfo *MinuteInfo
|
||||
@@ -52,6 +52,16 @@ type MinuteInfo struct {
|
||||
Price float64
|
||||
}
|
||||
|
||||
type Increments []*Increment
|
||||
|
||||
func (incs Increments) GetTotalCost() float64 {
|
||||
cost := 0.0
|
||||
for _, increment := range incs {
|
||||
cost += increment.Cost
|
||||
}
|
||||
return cost
|
||||
}
|
||||
|
||||
// Returns the duration of the timespan
|
||||
func (ts *TimeSpan) GetDuration() time.Duration {
|
||||
return ts.TimeEnd.Sub(ts.TimeStart)
|
||||
|
||||
@@ -108,8 +108,8 @@ func (ub *UserBalance) debitBalanceAction(a *Action) error {
|
||||
if a == nil {
|
||||
return errors.New("nil minute action!")
|
||||
}
|
||||
if a.Balance.Id == "" {
|
||||
a.Balance.Id = utils.GenUUID()
|
||||
if a.Balance.Uuid == "" {
|
||||
a.Balance.Uuid = utils.GenUUID()
|
||||
}
|
||||
if ub.BalanceMap == nil {
|
||||
ub.BalanceMap = make(map[string]BalanceChain, 0)
|
||||
@@ -204,7 +204,7 @@ func (ub *UserBalance) debitCreditBalance(cc *CallCost, count bool) error {
|
||||
amount := increment.Duration.Seconds()
|
||||
if b.Value >= amount {
|
||||
b.Value -= amount
|
||||
increment.BalanceId = b.Id
|
||||
increment.BalanceUuid = b.Uuid
|
||||
increment.MinuteInfo = &MinuteInfo{b.DestinationId, amount, 0}
|
||||
paid = true
|
||||
if count {
|
||||
@@ -259,7 +259,7 @@ func (ub *UserBalance) debitCreditBalance(cc *CallCost, count bool) error {
|
||||
}
|
||||
cc.Timespans = newTimespans
|
||||
b.Value -= amount
|
||||
newTs.Increments[0].BalanceId = b.Id
|
||||
newTs.Increments[0].BalanceUuid = b.Uuid
|
||||
newTs.Increments[0].MinuteInfo = &MinuteInfo{b.DestinationId, amount, 0}
|
||||
paid = true
|
||||
if count {
|
||||
@@ -309,7 +309,7 @@ func (ub *UserBalance) debitCreditBalance(cc *CallCost, count bool) error {
|
||||
amount := increment.Cost
|
||||
if b.Value >= amount {
|
||||
b.Value -= amount
|
||||
increment.BalanceId = b.Id
|
||||
increment.BalanceUuid = b.Uuid
|
||||
paid = true
|
||||
if count {
|
||||
ub.countUnits(&Action{BalanceId: CREDIT, Direction: cc.Direction, Balance: &Balance{Value: amount, DestinationId: cc.Destination}})
|
||||
@@ -337,6 +337,25 @@ func (ub *UserBalance) debitCreditBalance(cc *CallCost, count bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ub *UserBalance) refoundIncrements(increments Increments, count bool) {
|
||||
for _, increment := range increments {
|
||||
var balance *Balance
|
||||
for _, balanceChain := range ub.BalanceMap {
|
||||
if balance = balanceChain.GetBalance(increment.BalanceUuid); balance != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
if balance != nil {
|
||||
balance.Value += increment.Cost
|
||||
if count {
|
||||
ub.countUnits(&Action{BalanceId: increment.BalanceType, Direction: OUTBOUND, Balance: &Balance{Value: increment.Cost}})
|
||||
}
|
||||
} else {
|
||||
// TODO: where should put the money?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Debits some amount of user's specified balance. Returns the remaining credit in user's balance.
|
||||
*/
|
||||
|
||||
@@ -46,7 +46,7 @@ func populateTestActionsForTriggers() {
|
||||
}
|
||||
|
||||
func TestBalanceStoreRestore(t *testing.T) {
|
||||
b := &Balance{Value: 14, Weight: 1, Id: "test", ExpirationDate: time.Date(2013, time.July, 15, 17, 48, 0, 0, time.UTC)}
|
||||
b := &Balance{Value: 14, Weight: 1, Uuid: "test", ExpirationDate: time.Date(2013, time.July, 15, 17, 48, 0, 0, time.UTC)}
|
||||
marsh := NewCodecMsgpackMarshaler()
|
||||
output, err := marsh.Marshal(b)
|
||||
if err != nil {
|
||||
@@ -188,7 +188,7 @@ func TestDebitNegativeMoneyBalance(t *testing.T) {
|
||||
*/
|
||||
|
||||
func TestDebitCreditZeroSecond(t *testing.T) {
|
||||
b1 := &Balance{Id: "testb", Value: 10, Weight: 10, DestinationId: "NAT", RateSubject: ZEROSECOND}
|
||||
b1 := &Balance{Uuid: "testb", Value: 10, Weight: 10, DestinationId: "NAT", RateSubject: ZEROSECOND}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -206,7 +206,7 @@ func TestDebitCreditZeroSecond(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error("Error debiting balance: ", err)
|
||||
}
|
||||
if cc.Timespans[0].Increments[0].BalanceId != "testb" {
|
||||
if cc.Timespans[0].Increments[0].BalanceUuid != "testb" {
|
||||
t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0])
|
||||
}
|
||||
if rifsBalance.BalanceMap[MINUTES+OUTBOUND][0].Value != 0 ||
|
||||
@@ -216,7 +216,7 @@ func TestDebitCreditZeroSecond(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditZeroMinute(t *testing.T) {
|
||||
b1 := &Balance{Id: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RateSubject: ZEROMINUTE}
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RateSubject: ZEROMINUTE}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -237,7 +237,7 @@ func TestDebitCreditZeroMinute(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error("Error debiting balance: ", err)
|
||||
}
|
||||
if cc.Timespans[0].Increments[0].BalanceId != "testb" ||
|
||||
if cc.Timespans[0].Increments[0].BalanceUuid != "testb" ||
|
||||
cc.Timespans[0].Increments[0].Duration != time.Minute {
|
||||
t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0])
|
||||
}
|
||||
@@ -248,8 +248,8 @@ func TestDebitCreditZeroMinute(t *testing.T) {
|
||||
}
|
||||
}
|
||||
func TestDebitCreditZeroMixedMinute(t *testing.T) {
|
||||
b1 := &Balance{Id: "testm", Value: 70, Weight: 5, DestinationId: "NAT", RateSubject: ZEROMINUTE}
|
||||
b2 := &Balance{Id: "tests", Value: 10, Weight: 10, DestinationId: "NAT", RateSubject: ZEROSECOND}
|
||||
b1 := &Balance{Uuid: "testm", Value: 70, Weight: 5, DestinationId: "NAT", RateSubject: ZEROMINUTE}
|
||||
b2 := &Balance{Uuid: "tests", Value: 10, Weight: 10, DestinationId: "NAT", RateSubject: ZEROSECOND}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -270,8 +270,8 @@ func TestDebitCreditZeroMixedMinute(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error("Error debiting balance: ", err)
|
||||
}
|
||||
if cc.Timespans[0].Increments[0].BalanceId != "tests" ||
|
||||
cc.Timespans[1].Increments[0].BalanceId != "testm" {
|
||||
if cc.Timespans[0].Increments[0].BalanceUuid != "tests" ||
|
||||
cc.Timespans[1].Increments[0].BalanceUuid != "testm" {
|
||||
t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0], cc.Timespans[1].Increments[0])
|
||||
}
|
||||
if rifsBalance.BalanceMap[MINUTES+OUTBOUND][1].Value != 0 ||
|
||||
@@ -282,7 +282,7 @@ func TestDebitCreditZeroMixedMinute(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditNoCredit(t *testing.T) {
|
||||
b1 := &Balance{Id: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RateSubject: ZEROMINUTE}
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RateSubject: ZEROMINUTE}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -308,7 +308,7 @@ func TestDebitCreditNoCredit(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error("Error debiting balance: ", err)
|
||||
}
|
||||
if cc.Timespans[0].Increments[0].BalanceId != "testb" ||
|
||||
if cc.Timespans[0].Increments[0].BalanceUuid != "testb" ||
|
||||
cc.Timespans[0].Increments[0].Duration != time.Minute {
|
||||
t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0])
|
||||
}
|
||||
@@ -322,7 +322,7 @@ func TestDebitCreditNoCredit(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditHasCredit(t *testing.T) {
|
||||
b1 := &Balance{Id: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RateSubject: ZEROMINUTE}
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RateSubject: ZEROMINUTE}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -343,13 +343,13 @@ func TestDebitCreditHasCredit(t *testing.T) {
|
||||
}
|
||||
rifsBalance := &UserBalance{Id: "other", BalanceMap: map[string]BalanceChain{
|
||||
MINUTES + OUTBOUND: BalanceChain{b1},
|
||||
CREDIT + OUTBOUND: BalanceChain{&Balance{Id: "moneya", Value: 50}},
|
||||
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 50}},
|
||||
}}
|
||||
err := rifsBalance.debitCreditBalance(cc, false)
|
||||
if err != nil {
|
||||
t.Error("Error debiting balance: ", err)
|
||||
}
|
||||
if cc.Timespans[0].Increments[0].BalanceId != "testb" ||
|
||||
if cc.Timespans[0].Increments[0].BalanceUuid != "testb" ||
|
||||
cc.Timespans[0].Increments[0].Duration != time.Minute {
|
||||
t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0])
|
||||
}
|
||||
@@ -364,7 +364,7 @@ func TestDebitCreditHasCredit(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditSplitMinutesMoney(t *testing.T) {
|
||||
b1 := &Balance{Id: "testb", Value: 10, Weight: 10, DestinationId: "NAT", RateSubject: ZEROSECOND}
|
||||
b1 := &Balance{Uuid: "testb", Value: 10, Weight: 10, DestinationId: "NAT", RateSubject: ZEROSECOND}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -379,13 +379,13 @@ func TestDebitCreditSplitMinutesMoney(t *testing.T) {
|
||||
}
|
||||
rifsBalance := &UserBalance{Id: "other", BalanceMap: map[string]BalanceChain{
|
||||
MINUTES + OUTBOUND: BalanceChain{b1},
|
||||
CREDIT + OUTBOUND: BalanceChain{&Balance{Id: "moneya", Value: 50}},
|
||||
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 50}},
|
||||
}}
|
||||
err := rifsBalance.debitCreditBalance(cc, false)
|
||||
if err != nil {
|
||||
t.Error("Error debiting balance: ", err)
|
||||
}
|
||||
if cc.Timespans[0].Increments[0].BalanceId != "testb" ||
|
||||
if cc.Timespans[0].Increments[0].BalanceUuid != "testb" ||
|
||||
cc.Timespans[0].Increments[0].Duration != 10*time.Second {
|
||||
t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0])
|
||||
}
|
||||
@@ -400,7 +400,7 @@ func TestDebitCreditSplitMinutesMoney(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditMoreTimespans(t *testing.T) {
|
||||
b1 := &Balance{Id: "testb", Value: 150, Weight: 10, DestinationId: "NAT", RateSubject: ZEROMINUTE}
|
||||
b1 := &Balance{Uuid: "testb", Value: 150, Weight: 10, DestinationId: "NAT", RateSubject: ZEROMINUTE}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -426,7 +426,7 @@ func TestDebitCreditMoreTimespans(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error("Error debiting balance: ", err)
|
||||
}
|
||||
if cc.Timespans[0].Increments[0].BalanceId != "testb" ||
|
||||
if cc.Timespans[0].Increments[0].BalanceUuid != "testb" ||
|
||||
cc.Timespans[0].Increments[0].Duration != time.Minute {
|
||||
t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0])
|
||||
}
|
||||
@@ -437,8 +437,8 @@ func TestDebitCreditMoreTimespans(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditMoreTimespansMixed(t *testing.T) {
|
||||
b1 := &Balance{Id: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RateSubject: ZEROMINUTE}
|
||||
b2 := &Balance{Id: "testa", Value: 150, Weight: 5, DestinationId: "NAT", RateSubject: ZEROSECOND}
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RateSubject: ZEROMINUTE}
|
||||
b2 := &Balance{Uuid: "testa", Value: 150, Weight: 5, DestinationId: "NAT", RateSubject: ZEROSECOND}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -464,7 +464,7 @@ func TestDebitCreditMoreTimespansMixed(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error("Error debiting balance: ", err)
|
||||
}
|
||||
if cc.Timespans[0].Increments[0].BalanceId != "testb" ||
|
||||
if cc.Timespans[0].Increments[0].BalanceUuid != "testb" ||
|
||||
cc.Timespans[0].Increments[0].Duration != time.Minute {
|
||||
t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0])
|
||||
}
|
||||
@@ -476,7 +476,7 @@ func TestDebitCreditMoreTimespansMixed(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebitCreditNoConectFeeCredit(t *testing.T) {
|
||||
b1 := &Balance{Id: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RateSubject: ZEROMINUTE}
|
||||
b1 := &Balance{Uuid: "testb", Value: 70, Weight: 10, DestinationId: "NAT", RateSubject: ZEROMINUTE}
|
||||
cc := &CallCost{
|
||||
Direction: OUTBOUND,
|
||||
Destination: "0723045326",
|
||||
@@ -529,14 +529,14 @@ func TestDebitCreditMoneyOnly(t *testing.T) {
|
||||
},
|
||||
}
|
||||
rifsBalance := &UserBalance{Id: "other", BalanceMap: map[string]BalanceChain{
|
||||
CREDIT + OUTBOUND: BalanceChain{&Balance{Id: "money", Value: 50}},
|
||||
CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "money", Value: 50}},
|
||||
}}
|
||||
err := rifsBalance.debitCreditBalance(cc, false)
|
||||
if err != nil {
|
||||
t.Error("Error debiting balance: ", err)
|
||||
}
|
||||
|
||||
if cc.Timespans[0].Increments[0].BalanceId != "money" ||
|
||||
if cc.Timespans[0].Increments[0].BalanceUuid != "money" ||
|
||||
cc.Timespans[0].Increments[0].Duration != 10*time.Second {
|
||||
t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0])
|
||||
}
|
||||
|
||||
@@ -245,30 +245,34 @@ func (sm *FSSessionManager) OnChannelHangupComplete(ev Event) {
|
||||
hangupTime = time.Now()
|
||||
}
|
||||
end := lastCC.Timespans[len(lastCC.Timespans)-1].TimeEnd
|
||||
refoundDuration := end.Sub(hangupTime).Seconds()
|
||||
cost := 0.0
|
||||
refoundDuration := end.Sub(hangupTime)
|
||||
var refoundIncrements []*engine.Increment
|
||||
engine.Logger.Info(fmt.Sprintf("Refund duration: %v", refoundDuration))
|
||||
for i := len(lastCC.Timespans) - 1; i >= 0; i-- {
|
||||
ts := lastCC.Timespans[i]
|
||||
tsDuration := ts.GetDuration().Seconds()
|
||||
tsDuration := ts.GetDuration()
|
||||
if refoundDuration <= tsDuration {
|
||||
// find procentage
|
||||
procentage := (refoundDuration * 100) / tsDuration
|
||||
tmpCost := (procentage * ts.Cost) / 100
|
||||
ts.Cost -= tmpCost
|
||||
cost += tmpCost
|
||||
// set the end time to now
|
||||
ts.TimeEnd = hangupTime
|
||||
lastRefoundedIncrementIndex := 0
|
||||
var lastRefoundedIncrement *engine.Increment
|
||||
for incrementIndex, increment := range ts.Increments {
|
||||
if increment.Duration <= refoundDuration {
|
||||
refoundIncrements = append(refoundIncrements, increment)
|
||||
refoundDuration -= increment.Duration
|
||||
lastRefoundedIncrementIndex = incrementIndex
|
||||
lastRefoundedIncrement = increment
|
||||
}
|
||||
}
|
||||
ts.SplitByIncrement(lastRefoundedIncrementIndex, lastRefoundedIncrement)
|
||||
break // do not go to other timespans
|
||||
} else {
|
||||
cost += ts.Cost
|
||||
// remove the timestamp entirely
|
||||
refoundIncrements = append(refoundIncrements, ts.Increments...)
|
||||
// remove the timespan entirely
|
||||
lastCC.Timespans = lastCC.Timespans[:i]
|
||||
// continue to the next timespan with what is left to refound
|
||||
refoundDuration -= tsDuration
|
||||
}
|
||||
}
|
||||
if cost > 0 {
|
||||
if len(refoundIncrements) > 0 {
|
||||
cd := &engine.CallDescriptor{
|
||||
Direction: lastCC.Direction,
|
||||
Tenant: lastCC.Tenant,
|
||||
@@ -276,7 +280,7 @@ func (sm *FSSessionManager) OnChannelHangupComplete(ev Event) {
|
||||
Subject: lastCC.Subject,
|
||||
Account: lastCC.Account,
|
||||
Destination: lastCC.Destination,
|
||||
Amount: -cost,
|
||||
Increments: refoundIncrements,
|
||||
// FallbackSubject: lastCC.FallbackSubject, // TODO: check how to best add it
|
||||
}
|
||||
var response float64
|
||||
|
||||
Reference in New Issue
Block a user