mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
implemented received call bonus
This commit is contained in:
@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package timespans
|
||||
|
||||
import (
|
||||
// "log"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -47,11 +48,11 @@ func (mb *MinuteBucket) store() (result string) {
|
||||
De-serializes the minute bucket for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (mb *MinuteBucket) restore(input string) {
|
||||
mbse := strings.Split(input, "|")
|
||||
mb.Seconds, _ = strconv.ParseFloat(mbse[0], 64)
|
||||
mb.Priority, _ = strconv.Atoi(mbse[1])
|
||||
mb.Price, _ = strconv.ParseFloat(mbse[2], 64)
|
||||
mb.DestinationId = mbse[3]
|
||||
elements := strings.Split(input, "|")
|
||||
mb.Seconds, _ = strconv.ParseFloat(elements[0], 64)
|
||||
mb.Priority, _ = strconv.Atoi(elements[1])
|
||||
mb.Price, _ = strconv.ParseFloat(elements[2], 64)
|
||||
mb.DestinationId = elements[3]
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -45,13 +45,6 @@ type VolumeDiscount struct {
|
||||
Discount float64 // procentage
|
||||
}
|
||||
|
||||
type RecivedCallBonus struct {
|
||||
Credit float64
|
||||
SmsCredit float64
|
||||
Traffic float64
|
||||
MinuteBuckets *MinuteBucket
|
||||
}
|
||||
|
||||
/*
|
||||
Serializes the tariff plan for the storage. Used for key-value storages.
|
||||
*/
|
||||
@@ -59,13 +52,19 @@ func (tp *TariffPlan) store() (result string) {
|
||||
result += strconv.FormatFloat(tp.SmsCredit, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(tp.Traffic, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(tp.ReceivedCallSecondsLimit, 'f', -1, 64) + ";"
|
||||
if tp.RecivedCallBonus == nil {
|
||||
tp.RecivedCallBonus = &RecivedCallBonus{}
|
||||
}
|
||||
result += tp.RecivedCallBonus.store() + ";"
|
||||
for i, mb := range tp.MinuteBuckets {
|
||||
if i > 0 {
|
||||
result += ","
|
||||
}
|
||||
result += mb.store()
|
||||
}
|
||||
result += ";"
|
||||
if tp.VolumeDiscountThresholds != nil {
|
||||
result += ";"
|
||||
}
|
||||
for i, vd := range tp.VolumeDiscountThresholds {
|
||||
if i > 0 {
|
||||
result += ","
|
||||
@@ -84,13 +83,15 @@ func (tp *TariffPlan) restore(input string) {
|
||||
tp.SmsCredit, _ = strconv.ParseFloat(elements[0], 64)
|
||||
tp.Traffic, _ = strconv.ParseFloat(elements[1], 64)
|
||||
tp.ReceivedCallSecondsLimit, _ = strconv.ParseFloat(elements[2], 64)
|
||||
for _, mbs := range strings.Split(elements[3], ",") {
|
||||
tp.RecivedCallBonus = &RecivedCallBonus{}
|
||||
tp.RecivedCallBonus.restore(elements[3])
|
||||
for _, mbs := range strings.Split(elements[4], ",") {
|
||||
mb := &MinuteBucket{}
|
||||
mb.restore(mbs)
|
||||
tp.MinuteBuckets = append(tp.MinuteBuckets, mb)
|
||||
}
|
||||
if len(elements) > 4 {
|
||||
for _, vdss := range strings.Split(elements[4], ",") {
|
||||
if len(elements) > 5 {
|
||||
for _, vdss := range strings.Split(elements[5], ",") {
|
||||
vd := &VolumeDiscount{}
|
||||
vds := strings.Split(vdss, "|")
|
||||
vd.Volume, _ = strconv.ParseFloat(vds[0], 64)
|
||||
@@ -99,3 +100,41 @@ func (tp *TariffPlan) restore(input string) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Structure to be filled for each tariff plan with the bonus value for received calls minutes.
|
||||
*/
|
||||
type RecivedCallBonus struct {
|
||||
Credit float64
|
||||
SmsCredit float64
|
||||
Traffic float64
|
||||
MinuteBucket *MinuteBucket
|
||||
}
|
||||
|
||||
/*
|
||||
Serializes the tariff plan for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (rcb *RecivedCallBonus) store() (result string) {
|
||||
result += strconv.FormatFloat(rcb.Credit, 'f', -1, 64) + ","
|
||||
result += strconv.FormatFloat(rcb.SmsCredit, 'f', -1, 64) + ","
|
||||
result += strconv.FormatFloat(rcb.Traffic, 'f', -1, 64)
|
||||
if rcb.MinuteBucket != nil {
|
||||
result += ","
|
||||
result += rcb.MinuteBucket.store()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
De-serializes the tariff plan for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (rcb *RecivedCallBonus) restore(input string) {
|
||||
elements := strings.Split(input, ",")
|
||||
rcb.Credit, _ = strconv.ParseFloat(elements[0], 64)
|
||||
rcb.SmsCredit, _ = strconv.ParseFloat(elements[1], 64)
|
||||
rcb.Traffic, _ = strconv.ParseFloat(elements[2], 64)
|
||||
if len(elements) > 3 {
|
||||
rcb.MinuteBucket = &MinuteBucket{}
|
||||
rcb.MinuteBucket.restore(elements[3])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,14 @@ import (
|
||||
func TestTariffPlanStoreRestore(t *testing.T) {
|
||||
b1 := &MinuteBucket{Seconds: 10, Priority: 10, Price: 0.01, DestinationId: "nationale"}
|
||||
b2 := &MinuteBucket{Seconds: 100, Priority: 20, Price: 0.0, DestinationId: "retea"}
|
||||
rcb := &RecivedCallBonus{Credit: 100}
|
||||
vd := &VolumeDiscount{100, 10}
|
||||
seara := &TariffPlan{Id: "seara_voo", SmsCredit: 100, ReceivedCallSecondsLimit: 0, MinuteBuckets: []*MinuteBucket{b1, b2}, VolumeDiscountThresholds: []*VolumeDiscount{vd}}
|
||||
seara := &TariffPlan{Id: "seara_voo",
|
||||
SmsCredit: 100,
|
||||
ReceivedCallSecondsLimit: 0,
|
||||
RecivedCallBonus: rcb,
|
||||
MinuteBuckets: []*MinuteBucket{b1, b2},
|
||||
VolumeDiscountThresholds: []*VolumeDiscount{vd}}
|
||||
s := seara.store()
|
||||
tp1 := &TariffPlan{Id: "seara_voo"}
|
||||
tp1.restore(s)
|
||||
@@ -82,7 +88,7 @@ func BenchmarkTariffPlanKyotoStoreRestore(b *testing.B) {
|
||||
defer getter.Close()
|
||||
b1 := &MinuteBucket{Seconds: 10, Priority: 10, Price: 0.01, DestinationId: "nationale"}
|
||||
b2 := &MinuteBucket{Seconds: 100, Priority: 20, Price: 0.0, DestinationId: "retea"}
|
||||
seara := &TariffPlan{Id: "seara", SmsCredit: 100, MinuteBuckets: []*MinuteBucket{b1, b2}}
|
||||
seara := &TariffPlan{Id: "seara_other", SmsCredit: 100, MinuteBuckets: []*MinuteBucket{b1, b2}}
|
||||
for i := 0; i < b.N; i++ {
|
||||
getter.SetTariffPlan(seara)
|
||||
getter.GetTariffPlan(seara.Id)
|
||||
@@ -94,7 +100,7 @@ func BenchmarkTariffPlanRedisStoreRestore(b *testing.B) {
|
||||
defer getter.Close()
|
||||
b1 := &MinuteBucket{Seconds: 10, Priority: 10, Price: 0.01, DestinationId: "nationale"}
|
||||
b2 := &MinuteBucket{Seconds: 100, Priority: 20, Price: 0.0, DestinationId: "retea"}
|
||||
seara := &TariffPlan{Id: "seara", SmsCredit: 100, MinuteBuckets: []*MinuteBucket{b1, b2}}
|
||||
seara := &TariffPlan{Id: "seara_other", SmsCredit: 100, MinuteBuckets: []*MinuteBucket{b1, b2}}
|
||||
for i := 0; i < b.N; i++ {
|
||||
getter.SetTariffPlan(seara)
|
||||
getter.GetTariffPlan(seara.Id)
|
||||
@@ -106,7 +112,7 @@ func BenchmarkTariffPlanMongoStoreRestore(b *testing.B) {
|
||||
defer getter.Close()
|
||||
b1 := &MinuteBucket{Seconds: 10, Priority: 10, Price: 0.01, DestinationId: "nationale"}
|
||||
b2 := &MinuteBucket{Seconds: 100, Priority: 20, Price: 0.0, DestinationId: "retea"}
|
||||
seara := &TariffPlan{Id: "seara", SmsCredit: 100, MinuteBuckets: []*MinuteBucket{b1, b2}}
|
||||
seara := &TariffPlan{Id: "seara_other", SmsCredit: 100, MinuteBuckets: []*MinuteBucket{b1, b2}}
|
||||
for i := 0; i < b.N; i++ {
|
||||
getter.SetTariffPlan(seara)
|
||||
getter.GetTariffPlan(seara.Id)
|
||||
|
||||
Binary file not shown.
@@ -1,14 +1,17 @@
|
||||
[
|
||||
{"Id":"seara","SmsCredit":100,"ReceivedCallsSecondsLimit": 100,
|
||||
"RecivedCallBonus" : {"Credit": 100},
|
||||
"MinuteBuckets":
|
||||
[{"Seconds":10,"Priority":10,"Price":0.01,"DestinationId":"nationale"}, {"Seconds":100,"Priority":20,"Price":0,"DestinationId":"retea"}],
|
||||
"VolumeDiscountThresholds":
|
||||
[{"Volume": 100, "Discount": 10},{"Volume": 500, "Discount": 15},{"Volume": 1000, "Discount": 20}]
|
||||
},
|
||||
{"Id":"dimineata","SmsCredit":100,"ReceivedCallsSecondsLimit": 100,
|
||||
"RecivedCallBonus" : {"Credit": 100},
|
||||
"MinuteBuckets":
|
||||
[{"Seconds":100,"Priority":10,"Price":0.01,"DestinationId":"nationale"}, {"Seconds":1000,"Priority":20,"Price":0,"DestinationId":"retea"}],
|
||||
"VolumeDiscountThresholds":
|
||||
[{"Volume": 100, "Discount": 10},{"Volume": 500, "Discount": 15},{"Volume": 1000, "Discount": 20}]
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -80,7 +80,10 @@ func (ub *UserBudget) store() (result string) {
|
||||
result += strconv.FormatFloat(ub.VolumeDiscountSeconds, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(ub.ReceivedCallSeconds, 'f', -1, 64) + ";"
|
||||
result += strconv.Itoa(ub.ResetDayOfTheMonth) + ";"
|
||||
result += ub.TariffPlanId + ";"
|
||||
result += ub.TariffPlanId
|
||||
if ub.MinuteBuckets != nil {
|
||||
result += ";"
|
||||
}
|
||||
for i, mb := range ub.MinuteBuckets {
|
||||
if i > 0 {
|
||||
result += ","
|
||||
@@ -102,10 +105,12 @@ func (ub *UserBudget) restore(input string) {
|
||||
ub.ReceivedCallSeconds, _ = strconv.ParseFloat(elements[4], 64)
|
||||
ub.ResetDayOfTheMonth, _ = strconv.Atoi(elements[5])
|
||||
ub.TariffPlanId = elements[6]
|
||||
for _, mbs := range strings.Split(elements[7], ",") {
|
||||
mb := &MinuteBucket{}
|
||||
mb.restore(mbs)
|
||||
ub.MinuteBuckets = append(ub.MinuteBuckets, mb)
|
||||
if len(elements) > 7 {
|
||||
for _, mbs := range strings.Split(elements[7], ",") {
|
||||
mb := &MinuteBucket{}
|
||||
mb.restore(mbs)
|
||||
ub.MinuteBuckets = append(ub.MinuteBuckets, mb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,7 +254,18 @@ func (ub *UserBudget) addReceivedCallSeconds(sg StorageGetter, amount float64) e
|
||||
if tariffPlan, err := ub.getTariffPlan(sg); tariffPlan != nil && err == nil {
|
||||
if ub.ReceivedCallSeconds >= tariffPlan.ReceivedCallSecondsLimit {
|
||||
ub.ReceivedCallSeconds -= tariffPlan.ReceivedCallSecondsLimit
|
||||
// do the dew
|
||||
if tariffPlan.RecivedCallBonus != nil { // apply the bonus
|
||||
ub.Credit += tariffPlan.RecivedCallBonus.Credit
|
||||
ub.SmsCredit += tariffPlan.RecivedCallBonus.SmsCredit
|
||||
ub.Traffic += tariffPlan.RecivedCallBonus.Traffic
|
||||
if tariffPlan.RecivedCallBonus.MinuteBucket != nil {
|
||||
for _, mb := range ub.MinuteBuckets {
|
||||
if mb.DestinationId == tariffPlan.RecivedCallBonus.MinuteBucket.DestinationId {
|
||||
mb.Seconds += tariffPlan.RecivedCallBonus.MinuteBucket.Seconds
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return sg.SetUserBudget(ub)
|
||||
|
||||
@@ -376,6 +376,18 @@ func TestGetVolumeDiscountSteps(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecivedCallsBonus(t *testing.T) {
|
||||
getter, _ := NewKyotoStorage("test.kch")
|
||||
defer getter.Close()
|
||||
rcb := &RecivedCallBonus{Credit: 100}
|
||||
seara := &TariffPlan{Id: "seara_voo", SmsCredit: 100, ReceivedCallSecondsLimit: 10, RecivedCallBonus: rcb}
|
||||
rifsBudget := &UserBudget{Id: "other", Credit: 21, tariffPlan: seara, ResetDayOfTheMonth: 10, ReceivedCallSeconds: 1}
|
||||
err := rifsBudget.addReceivedCallSeconds(getter, 12)
|
||||
if err != nil || rifsBudget.Credit != 121 || rifsBudget.ReceivedCallSeconds != 3 {
|
||||
t.Error("Wrong Received call bonus procedure: ", rifsBudget)
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************** Benchmarks *******************************/
|
||||
|
||||
func BenchmarkGetSecondForPrefix(b *testing.B) {
|
||||
|
||||
Reference in New Issue
Block a user