mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-21 15:18:44 +05:00
moved rounding params from rates to destination rates
This commit is contained in:
@@ -161,3 +161,13 @@ func (cc *CallCost) ToDataCost() (*DataCost, error) {
|
||||
}
|
||||
return dc, nil
|
||||
}
|
||||
|
||||
func (cc *CallCost) GetLongestRounding() (roundingDecimals int, roundingMethod string) {
|
||||
for _, ts := range cc.Timespans {
|
||||
if ts.RateInterval.Rating.RoundingDecimals > roundingDecimals {
|
||||
roundingDecimals = ts.RateInterval.Rating.RoundingDecimals
|
||||
roundingMethod = ts.RateInterval.Rating.RoundingMethod
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ func TestCallCostToDataCost(t *testing.T) {
|
||||
t.Error("Error convertiong to data cost: ", err)
|
||||
}
|
||||
js, _ := json.Marshal(dc)
|
||||
expected := `{"Direction":"*out","Category":"data","Tenant":"cgrates.org","Subject":"rif","Account":"","Destination":"*any","TOR":"*data","Cost":65,"DataSpans":[{"DataStart":0,"DataEnd":60,"Cost":60,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":0,"Rates":[{"GroupIntervalStart":0,"Value":1,"RateIncrement":60000000000,"RateUnit":1000000000},{"GroupIntervalStart":60000000000,"Value":1,"RateIncrement":1000000000,"RateUnit":1000000000}],"RoundingMethod":"*up","RoundingDecimals":4},"Weight":10},"DataIndex":60,"Increments":[],"MatchedSubject":"","MatchedPrefix":"","MatchedDestId":""},{"DataStart":60,"DataEnd":65,"Cost":5,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":0,"Rates":[{"GroupIntervalStart":0,"Value":1,"RateIncrement":60000000000,"RateUnit":1000000000},{"GroupIntervalStart":60000000000,"Value":1,"RateIncrement":1000000000,"RateUnit":1000000000}],"RoundingMethod":"*up","RoundingDecimals":4},"Weight":10},"DataIndex":65,"Increments":[],"MatchedSubject":"*out:cgrates.org:data:rif","MatchedPrefix":"*any","MatchedDestId":"*any"}]}`
|
||||
expected := `{"Direction":"*out","Category":"data","Tenant":"cgrates.org","Subject":"rif","Account":"","Destination":"*any","TOR":"*data","Cost":65,"DataSpans":[{"DataStart":0,"DataEnd":60,"Cost":60,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":0,"RoundingMethod":"*middle","RoundingDecimals":4,"Rates":[{"GroupIntervalStart":0,"Value":1,"RateIncrement":60000000000,"RateUnit":1000000000},{"GroupIntervalStart":60000000000,"Value":1,"RateIncrement":1000000000,"RateUnit":1000000000}]},"Weight":10},"DataIndex":60,"Increments":[],"MatchedSubject":"","MatchedPrefix":"","MatchedDestId":""},{"DataStart":60,"DataEnd":65,"Cost":5,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":0,"RoundingMethod":"*middle","RoundingDecimals":4,"Rates":[{"GroupIntervalStart":0,"Value":1,"RateIncrement":60000000000,"RateUnit":1000000000},{"GroupIntervalStart":60000000000,"Value":1,"RateIncrement":1000000000,"RateUnit":1000000000}]},"Weight":10},"DataIndex":65,"Increments":[],"MatchedSubject":"*out:cgrates.org:data:rif","MatchedPrefix":"*any","MatchedDestId":"*any"}]}`
|
||||
if string(js) != expected {
|
||||
t.Error("Error coverting to data cost: ", string(js))
|
||||
}
|
||||
|
||||
@@ -431,9 +431,6 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) {
|
||||
}
|
||||
cost += ts.getCost()
|
||||
}
|
||||
// global rounding
|
||||
//TODO: use the longest rounding/method from ts
|
||||
cost = utils.Round(cost, globalRoundingDecimals, globalRoundingMethod)
|
||||
//startIndex := len(fmt.Sprintf("%s:%s:%s:", cd.Direction, cd.Tenant, cd.Category))
|
||||
cc := &CallCost{
|
||||
Direction: cd.Direction,
|
||||
@@ -447,6 +444,9 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) {
|
||||
deductConnectFee: cd.LoopIndex == 0,
|
||||
TOR: cd.TOR,
|
||||
}
|
||||
// global rounding
|
||||
roundingDecimals, roundingMethod := cc.GetLongestRounding()
|
||||
cc.Cost = utils.Round(cc.Cost, roundingDecimals, roundingMethod)
|
||||
//Logger.Info(fmt.Sprintf("<Rater> Get Cost: %s => %v", cd.GetKey(), cc))
|
||||
cc.Timespans.Compress()
|
||||
return cc, err
|
||||
|
||||
@@ -385,7 +385,7 @@ func (csvr *CSVReader) LoadRates() (err error) {
|
||||
for record, err := csvReader.Read(); err == nil; record, err = csvReader.Read() {
|
||||
tag := record[0]
|
||||
var r *utils.TPRate
|
||||
r, err = NewLoadRate(record[0], record[1], record[2], record[3], record[4], record[5], record[6], record[7])
|
||||
r, err = NewLoadRate(record[0], record[1], record[2], record[3], record[4], record[5])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -420,6 +420,11 @@ func (csvr *CSVReader) LoadDestinationRates() (err error) {
|
||||
if !exists {
|
||||
return fmt.Errorf("Could not get rates for tag %v", record[2])
|
||||
}
|
||||
roundingDecimals, err := strconv.Atoi(record[4])
|
||||
if err != nil {
|
||||
log.Printf("Error parsing rounding decimals: %s", record[4])
|
||||
return err
|
||||
}
|
||||
destinationExists := false
|
||||
for _, d := range csvr.destinations {
|
||||
if d.Id == record[1] {
|
||||
@@ -427,7 +432,7 @@ func (csvr *CSVReader) LoadDestinationRates() (err error) {
|
||||
break
|
||||
}
|
||||
}
|
||||
var err error
|
||||
|
||||
if !destinationExists && csvr.dataStorage != nil {
|
||||
if destinationExists, err = csvr.dataStorage.HasData(DESTINATION_PREFIX, record[1]); err != nil {
|
||||
return err
|
||||
@@ -440,8 +445,10 @@ func (csvr *CSVReader) LoadDestinationRates() (err error) {
|
||||
DestinationRateId: tag,
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: record[1],
|
||||
Rate: r,
|
||||
DestinationId: record[1],
|
||||
Rate: r,
|
||||
RoundingMethod: record[3],
|
||||
RoundingDecimals: roundingDecimals,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -56,37 +56,37 @@ ALWAYS,*any,*any,*any,*any,00:00:00
|
||||
ASAP,*any,*any,*any,*any,*asap
|
||||
`
|
||||
rates = `
|
||||
R1,0,0.2,60,1,0,*middle,2
|
||||
R2,0,0.1,60s,1s,0,*middle,2
|
||||
R3,0,0.05,60s,1s,0,*middle,2
|
||||
R4,1,1,1s,1s,0,*up,2
|
||||
R5,0,0.5,1s,1s,0,*down,2
|
||||
LANDLINE_OFFPEAK,0,1,1,60,0,*up,4
|
||||
LANDLINE_OFFPEAK,0,1,1,1,60,*up,4
|
||||
GBP_71,0.000000,5.55555,1s,1s,0s,*up,4
|
||||
GBP_72,0.000000,7.77777,1s,1s,0s,*up,4
|
||||
GBP_70,0.000000,1,1,1,0,*up,4
|
||||
RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s,*up,8
|
||||
RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s,*up,8
|
||||
R_URG,0,0,1,1,0,*down,2
|
||||
R1,0,0.2,60,1,0
|
||||
R2,0,0.1,60s,1s,0
|
||||
R3,0,0.05,60s,1s,0
|
||||
R4,1,1,1s,1s,0
|
||||
R5,0,0.5,1s,1s,0
|
||||
LANDLINE_OFFPEAK,0,1,1,60,0
|
||||
LANDLINE_OFFPEAK,0,1,1,1,60
|
||||
GBP_71,0.000000,5.55555,1s,1s,0s
|
||||
GBP_72,0.000000,7.77777,1s,1s,0s
|
||||
GBP_70,0.000000,1,1,1,0
|
||||
RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s
|
||||
RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s
|
||||
R_URG,0,0,1,1,0
|
||||
`
|
||||
destinationRates = `
|
||||
RT_STANDARD,GERMANY,R1
|
||||
RT_STANDARD,GERMANY_O2,R2
|
||||
RT_STANDARD,GERMANY_PREMIUM,R2
|
||||
RT_DEFAULT,ALL,R2
|
||||
RT_STD_WEEKEND,GERMANY,R2
|
||||
RT_STD_WEEKEND,GERMANY_O2,R3
|
||||
P1,NAT,R4
|
||||
P2,NAT,R5
|
||||
T1,NAT,LANDLINE_OFFPEAK
|
||||
T2,GERMANY,GBP_72
|
||||
T2,GERMANY_O2,GBP_70
|
||||
T2,GERMANY_PREMIUM,GBP_71
|
||||
DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG
|
||||
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5
|
||||
DATA_RATE,*any,LANDLINE_OFFPEAK
|
||||
RT_URG,URG,R_URG
|
||||
RT_STANDARD,GERMANY,R1,*middle,4
|
||||
RT_STANDARD,GERMANY_O2,R2,*middle,4
|
||||
RT_STANDARD,GERMANY_PREMIUM,R2,*middle,4
|
||||
RT_DEFAULT,ALL,R2,*middle,4
|
||||
RT_STD_WEEKEND,GERMANY,R2,*middle,4
|
||||
RT_STD_WEEKEND,GERMANY_O2,R3,*middle,4
|
||||
P1,NAT,R4,*middle,4
|
||||
P2,NAT,R5,*middle,4
|
||||
T1,NAT,LANDLINE_OFFPEAK,*middle,4
|
||||
T2,GERMANY,GBP_72,*middle,4
|
||||
T2,GERMANY_O2,GBP_70,*middle,4
|
||||
T2,GERMANY_PREMIUM,GBP_71,*middle,4
|
||||
DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG,*middle,4
|
||||
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5,*middle,4
|
||||
DATA_RATE,*any,LANDLINE_OFFPEAK,*middle,4
|
||||
RT_URG,URG,R_URG,*middle,4
|
||||
`
|
||||
ratingPlans = `
|
||||
STANDARD,RT_STANDARD,WORKDAYS_00,10
|
||||
@@ -309,7 +309,7 @@ func TestLoadRates(t *testing.T) {
|
||||
t.Error("Failed to load rates: ", csvr.rates)
|
||||
}
|
||||
rate := csvr.rates["R1"].RateSlots[0]
|
||||
expctRs, err := utils.NewRateSlot(0, 0.2, "60", "1", "0", utils.ROUNDING_MIDDLE, 2)
|
||||
expctRs, err := utils.NewRateSlot(0, 0.2, "60", "1", "0")
|
||||
if err != nil {
|
||||
t.Error("Error loading rate: ", rate, err.Error())
|
||||
} else if !reflect.DeepEqual(rate, expctRs) ||
|
||||
@@ -319,7 +319,7 @@ func TestLoadRates(t *testing.T) {
|
||||
t.Error("Error loading rate: ", rate, expctRs)
|
||||
}
|
||||
rate = csvr.rates["R2"].RateSlots[0]
|
||||
if expctRs, err = utils.NewRateSlot(0, 0.1, "60s", "1s", "0", utils.ROUNDING_MIDDLE, 2); err != nil {
|
||||
if expctRs, err = utils.NewRateSlot(0, 0.1, "60s", "1s", "0"); err != nil {
|
||||
t.Error("Error loading rate: ", rate, err.Error())
|
||||
} else if !reflect.DeepEqual(rate, expctRs) ||
|
||||
rate.RateUnitDuration() != expctRs.RateUnitDuration() ||
|
||||
@@ -328,7 +328,7 @@ func TestLoadRates(t *testing.T) {
|
||||
t.Error("Error loading rate: ", rate)
|
||||
}
|
||||
rate = csvr.rates["R3"].RateSlots[0]
|
||||
if expctRs, err = utils.NewRateSlot(0, 0.05, "60s", "1s", "0", utils.ROUNDING_MIDDLE, 2); err != nil {
|
||||
if expctRs, err = utils.NewRateSlot(0, 0.05, "60s", "1s", "0"); err != nil {
|
||||
t.Error("Error loading rate: ", rate, err.Error())
|
||||
} else if !reflect.DeepEqual(rate, expctRs) ||
|
||||
rate.RateUnitDuration() != expctRs.RateUnitDuration() ||
|
||||
@@ -337,7 +337,7 @@ func TestLoadRates(t *testing.T) {
|
||||
t.Error("Error loading rate: ", rate)
|
||||
}
|
||||
rate = csvr.rates["R4"].RateSlots[0]
|
||||
if expctRs, err = utils.NewRateSlot(1, 1.0, "1s", "1s", "0", utils.ROUNDING_UP, 2); err != nil {
|
||||
if expctRs, err = utils.NewRateSlot(1, 1.0, "1s", "1s", "0"); err != nil {
|
||||
t.Error("Error loading rate: ", rate, err.Error())
|
||||
} else if !reflect.DeepEqual(rate, expctRs) ||
|
||||
rate.RateUnitDuration() != expctRs.RateUnitDuration() ||
|
||||
@@ -346,7 +346,7 @@ func TestLoadRates(t *testing.T) {
|
||||
t.Error("Error loading rate: ", rate)
|
||||
}
|
||||
rate = csvr.rates["R5"].RateSlots[0]
|
||||
if expctRs, err = utils.NewRateSlot(0, 0.5, "1s", "1s", "0", utils.ROUNDING_DOWN, 2); err != nil {
|
||||
if expctRs, err = utils.NewRateSlot(0, 0.5, "1s", "1s", "0"); err != nil {
|
||||
t.Error("Error loading rate: ", rate, err.Error())
|
||||
} else if !reflect.DeepEqual(rate, expctRs) ||
|
||||
rate.RateUnitDuration() != expctRs.RateUnitDuration() ||
|
||||
@@ -355,7 +355,7 @@ func TestLoadRates(t *testing.T) {
|
||||
t.Error("Error loading rate: ", rate)
|
||||
}
|
||||
rate = csvr.rates["LANDLINE_OFFPEAK"].RateSlots[0]
|
||||
if expctRs, err = utils.NewRateSlot(0, 1, "1", "60", "0", utils.ROUNDING_UP, 4); err != nil {
|
||||
if expctRs, err = utils.NewRateSlot(0, 1, "1", "60", "0"); err != nil {
|
||||
t.Error("Error loading rate: ", rate, err.Error())
|
||||
} else if !reflect.DeepEqual(rate, expctRs) ||
|
||||
rate.RateUnitDuration() != expctRs.RateUnitDuration() ||
|
||||
@@ -364,7 +364,7 @@ func TestLoadRates(t *testing.T) {
|
||||
t.Error("Error loading rate: ", rate)
|
||||
}
|
||||
rate = csvr.rates["LANDLINE_OFFPEAK"].RateSlots[1]
|
||||
if expctRs, err = utils.NewRateSlot(0, 1, "1", "1", "60", utils.ROUNDING_UP, 4); err != nil {
|
||||
if expctRs, err = utils.NewRateSlot(0, 1, "1", "1", "60"); err != nil {
|
||||
t.Error("Error loading rate: ", rate, err.Error())
|
||||
} else if !reflect.DeepEqual(rate, expctRs) ||
|
||||
rate.RateUnitDuration() != expctRs.RateUnitDuration() ||
|
||||
@@ -384,16 +384,22 @@ func TestLoadDestinationRates(t *testing.T) {
|
||||
DestinationRateId: "RT_STANDARD",
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "GERMANY",
|
||||
Rate: csvr.rates["R1"],
|
||||
DestinationId: "GERMANY",
|
||||
Rate: csvr.rates["R1"],
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "GERMANY_O2",
|
||||
Rate: csvr.rates["R2"],
|
||||
DestinationId: "GERMANY_O2",
|
||||
Rate: csvr.rates["R2"],
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "GERMANY_PREMIUM",
|
||||
Rate: csvr.rates["R2"],
|
||||
DestinationId: "GERMANY_PREMIUM",
|
||||
Rate: csvr.rates["R2"],
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -405,24 +411,30 @@ func TestLoadDestinationRates(t *testing.T) {
|
||||
DestinationRateId: "RT_DEFAULT",
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "ALL",
|
||||
Rate: csvr.rates["R2"],
|
||||
DestinationId: "ALL",
|
||||
Rate: csvr.rates["R2"],
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
},
|
||||
}) {
|
||||
t.Errorf("Error loading destination rate: %+v", drs)
|
||||
t.Errorf("Error loading destination rate: %+v", drs.DestinationRates[0])
|
||||
}
|
||||
drs = csvr.destinationRates["RT_STD_WEEKEND"]
|
||||
if !reflect.DeepEqual(drs, &utils.TPDestinationRate{
|
||||
DestinationRateId: "RT_STD_WEEKEND",
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "GERMANY",
|
||||
Rate: csvr.rates["R2"],
|
||||
DestinationId: "GERMANY",
|
||||
Rate: csvr.rates["R2"],
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "GERMANY_O2",
|
||||
Rate: csvr.rates["R3"],
|
||||
DestinationId: "GERMANY_O2",
|
||||
Rate: csvr.rates["R3"],
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
},
|
||||
}) {
|
||||
@@ -433,8 +445,10 @@ func TestLoadDestinationRates(t *testing.T) {
|
||||
DestinationRateId: "P1",
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "NAT",
|
||||
Rate: csvr.rates["R4"],
|
||||
DestinationId: "NAT",
|
||||
Rate: csvr.rates["R4"],
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
},
|
||||
}) {
|
||||
@@ -445,8 +459,10 @@ func TestLoadDestinationRates(t *testing.T) {
|
||||
DestinationRateId: "P2",
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "NAT",
|
||||
Rate: csvr.rates["R5"],
|
||||
DestinationId: "NAT",
|
||||
Rate: csvr.rates["R5"],
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
},
|
||||
}) {
|
||||
@@ -457,8 +473,10 @@ func TestLoadDestinationRates(t *testing.T) {
|
||||
DestinationRateId: "T1",
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "NAT",
|
||||
Rate: csvr.rates["LANDLINE_OFFPEAK"],
|
||||
DestinationId: "NAT",
|
||||
Rate: csvr.rates["LANDLINE_OFFPEAK"],
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
},
|
||||
}) {
|
||||
@@ -469,16 +487,22 @@ func TestLoadDestinationRates(t *testing.T) {
|
||||
DestinationRateId: "T2",
|
||||
DestinationRates: []*utils.DestinationRate{
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "GERMANY",
|
||||
Rate: csvr.rates["GBP_72"],
|
||||
DestinationId: "GERMANY",
|
||||
Rate: csvr.rates["GBP_72"],
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "GERMANY_O2",
|
||||
Rate: csvr.rates["GBP_70"],
|
||||
DestinationId: "GERMANY_O2",
|
||||
Rate: csvr.rates["GBP_70"],
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
&utils.DestinationRate{
|
||||
DestinationId: "GERMANY_PREMIUM",
|
||||
Rate: csvr.rates["GBP_71"],
|
||||
DestinationId: "GERMANY_PREMIUM",
|
||||
Rate: csvr.rates["GBP_71"],
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
},
|
||||
}) {
|
||||
@@ -524,7 +548,7 @@ func TestLoadRatingPlans(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Ratings: map[string]*RIRate{
|
||||
"d54545c1": &RIRate{
|
||||
"822a5aef": &RIRate{
|
||||
ConnectFee: 0,
|
||||
Rates: []*Rate{
|
||||
&Rate{
|
||||
@@ -535,9 +559,9 @@ func TestLoadRatingPlans(t *testing.T) {
|
||||
},
|
||||
},
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 2,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
"4bb00b9c": &RIRate{
|
||||
"4a25c533": &RIRate{
|
||||
ConnectFee: 0,
|
||||
Rates: []*Rate{
|
||||
&Rate{
|
||||
@@ -548,9 +572,9 @@ func TestLoadRatingPlans(t *testing.T) {
|
||||
},
|
||||
},
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 2,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
"e06c337f": &RIRate{
|
||||
"b05c5f6b": &RIRate{
|
||||
ConnectFee: 0,
|
||||
Rates: []*Rate{
|
||||
&Rate{
|
||||
@@ -561,9 +585,9 @@ func TestLoadRatingPlans(t *testing.T) {
|
||||
},
|
||||
},
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 2,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
"2efe78aa": &RIRate{
|
||||
"9f49ef8e": &RIRate{
|
||||
ConnectFee: 0,
|
||||
Rates: []*Rate{
|
||||
&Rate{
|
||||
@@ -573,56 +597,56 @@ func TestLoadRatingPlans(t *testing.T) {
|
||||
RateUnit: time.Second,
|
||||
},
|
||||
},
|
||||
RoundingMethod: utils.ROUNDING_DOWN,
|
||||
RoundingDecimals: 2,
|
||||
RoundingMethod: utils.ROUNDING_MIDDLE,
|
||||
RoundingDecimals: 4,
|
||||
},
|
||||
},
|
||||
DestinationRates: map[string]RPRateList{
|
||||
"GERMANY": []*RPRate{
|
||||
&RPRate{
|
||||
Timing: "14ae6e41",
|
||||
Rating: "d54545c1",
|
||||
Rating: "822a5aef",
|
||||
Weight: 10,
|
||||
},
|
||||
&RPRate{
|
||||
Timing: "9a6f8e32",
|
||||
Rating: "4bb00b9c",
|
||||
Rating: "4a25c533",
|
||||
Weight: 10,
|
||||
},
|
||||
&RPRate{
|
||||
Timing: "7181e535",
|
||||
Rating: "4bb00b9c",
|
||||
Rating: "4a25c533",
|
||||
Weight: 10,
|
||||
},
|
||||
},
|
||||
"GERMANY_O2": []*RPRate{
|
||||
&RPRate{
|
||||
Timing: "14ae6e41",
|
||||
Rating: "4bb00b9c",
|
||||
Rating: "4a25c533",
|
||||
Weight: 10,
|
||||
},
|
||||
&RPRate{
|
||||
Timing: "9a6f8e32",
|
||||
Rating: "e06c337f",
|
||||
Rating: "b05c5f6b",
|
||||
Weight: 10,
|
||||
},
|
||||
&RPRate{
|
||||
Timing: "7181e535",
|
||||
Rating: "e06c337f",
|
||||
Rating: "b05c5f6b",
|
||||
Weight: 10,
|
||||
},
|
||||
},
|
||||
"GERMANY_PREMIUM": []*RPRate{
|
||||
&RPRate{
|
||||
Timing: "14ae6e41",
|
||||
Rating: "4bb00b9c",
|
||||
Rating: "4a25c533",
|
||||
Weight: 10,
|
||||
},
|
||||
},
|
||||
"URG": []*RPRate{
|
||||
&RPRate{
|
||||
Timing: "96c78ff5",
|
||||
Rating: "2efe78aa",
|
||||
Rating: "9f49ef8e",
|
||||
Weight: 20,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -52,7 +52,7 @@ type TPLoader interface {
|
||||
WriteToDatabase(bool, bool) error
|
||||
}
|
||||
|
||||
func NewLoadRate(tag, connectFee, price, ratedUnits, rateIncrements, groupInterval, roundingMethod, roundingDecimals string) (r *utils.TPRate, err error) {
|
||||
func NewLoadRate(tag, connectFee, price, ratedUnits, rateIncrements, groupInterval string) (r *utils.TPRate, err error) {
|
||||
cf, err := strconv.ParseFloat(connectFee, 64)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing connect fee from: %v", connectFee)
|
||||
@@ -63,12 +63,7 @@ func NewLoadRate(tag, connectFee, price, ratedUnits, rateIncrements, groupInterv
|
||||
log.Printf("Error parsing price from: %v", price)
|
||||
return
|
||||
}
|
||||
rd, err := strconv.Atoi(roundingDecimals)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing rounding decimals: %s", roundingDecimals)
|
||||
return
|
||||
}
|
||||
rs, err := utils.NewRateSlot(cf, p, ratedUnits, rateIncrements, groupInterval, roundingMethod, rd)
|
||||
rs, err := utils.NewRateSlot(cf, p, ratedUnits, rateIncrements, groupInterval)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -86,9 +81,6 @@ func ValidNextGroup(present, next *utils.RateSlot) error {
|
||||
if math.Mod(next.GroupIntervalStartDuration().Seconds(), present.RateIncrementDuration().Seconds()) != 0 {
|
||||
return errors.New(fmt.Sprintf("GroupIntervalStart of %#v must be a multiple of RateIncrement of %#v", next, present))
|
||||
}
|
||||
if present.RoundingMethod != next.RoundingMethod || present.RoundingDecimals != next.RoundingDecimals {
|
||||
return errors.New(fmt.Sprintf("Rounding stuff must be equal for sam rate tag: %#v, %#v", present, next))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -128,8 +120,8 @@ func GetRateInterval(rpl *utils.TPRatingPlanBinding, dr *utils.DestinationRate)
|
||||
Weight: rpl.Weight,
|
||||
Rating: &RIRate{
|
||||
ConnectFee: dr.Rate.RateSlots[0].ConnectFee,
|
||||
RoundingMethod: dr.Rate.RateSlots[0].RoundingMethod,
|
||||
RoundingDecimals: dr.Rate.RateSlots[0].RoundingDecimals,
|
||||
RoundingMethod: dr.RoundingMethod,
|
||||
RoundingDecimals: dr.RoundingDecimals,
|
||||
},
|
||||
}
|
||||
for _, rl := range dr.Rate.RateSlots {
|
||||
@@ -189,7 +181,7 @@ var FileValidators = map[string]*FileLineRegexValidator{
|
||||
regexp.MustCompile(`(?:\w+\s*,\s*){1}(?:\*any\s*,\s*|(?:\d{1,4};?)+\s*,\s*|\s*,\s*){4}(?:\d{2}:\d{2}:\d{2}|\*asap){1}$`),
|
||||
"Tag([0-9A-Za-z_]),Years([0-9;]|*any|<empty>),Months([0-9;]|*any|<empty>),MonthDays([0-9;]|*any|<empty>),WeekDays([0-9;]|*any|<empty>),Time([0-9:]|*asap)"},
|
||||
utils.RATES_CSV: &FileLineRegexValidator{utils.RATES_NRCOLS,
|
||||
regexp.MustCompile(`(?:\w+\s*,\s*){1}(?:\d+\.?\d*,){2}(?:\d+s*,){3}(?:\*\w+,){1}(?:\d+\.?\d*,?){1}$`),
|
||||
regexp.MustCompile(`(?:\w+\s*,\s*){1}(?:\d+\.?\d*,){2}(?:\d+s*,?){3}$`),
|
||||
"Tag([0-9A-Za-z_]),ConnectFee([0-9.]),Rate([0-9.]),RateUnit([0-9.]),RateIncrementStart([0-9.])"},
|
||||
utils.DESTINATION_RATES_CSV: &FileLineRegexValidator{utils.DESTINATION_RATES_NRCOLS,
|
||||
regexp.MustCompile(`^(?:\w+\s*),(?:\w+\s*),(?:\w+\s*)$`),
|
||||
|
||||
@@ -20,11 +20,12 @@ package engine
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
var timingsSample = `#Tag,Years,Months,MonthDays,WeekDays,Time
|
||||
@@ -39,7 +40,7 @@ DUMMY,INVALID;DATA
|
||||
GERMANY_MOBILE,+4915
|
||||
`
|
||||
var ratesSample = `#Tag,DestinationRatesTag,TimingTag,Weight
|
||||
RT_1CENT,0,1,1s,1s,0s,*up,2
|
||||
RT_1CENT,0,1,1s,1s,0s
|
||||
DUMMY,INVALID;DATA
|
||||
`
|
||||
|
||||
@@ -410,7 +411,7 @@ func TestTPCSVFileParser(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !reflect.DeepEqual(record, []string{"RT_1CENT", "0", "1", "1s", "1s", "0s", "*up", "2"}) {
|
||||
if !reflect.DeepEqual(record, []string{"RT_1CENT", "0", "1", "1s", "1s", "0s"}) {
|
||||
t.Error("Unexpected record extracted", record)
|
||||
}
|
||||
case 3:
|
||||
|
||||
@@ -54,9 +54,9 @@ func (rit *RITiming) Stringify() string {
|
||||
// Separate structure used for rating plan size optimization
|
||||
type RIRate struct {
|
||||
ConnectFee float64
|
||||
Rates RateGroups // GroupRateInterval (start time): Rate
|
||||
RoundingMethod string //ROUNDING_UP, ROUNDING_DOWN, ROUNDING_MIDDLE
|
||||
RoundingMethod string
|
||||
RoundingDecimals int
|
||||
Rates RateGroups // GroupRateInterval (start time): Rate
|
||||
}
|
||||
|
||||
func (rir *RIRate) Stringify() string {
|
||||
|
||||
@@ -198,8 +198,7 @@ func (self *SQLStorage) SetTPRates(tpid string, rts map[string][]*utils.RateSlot
|
||||
buffer.WriteRune(',')
|
||||
}
|
||||
buffer.WriteString(fmt.Sprintf("('%s', '%s', %f, %f, '%s', '%s','%s','%s', %d)",
|
||||
tpid, rtId, rt.ConnectFee, rt.Rate, rt.RateUnit, rt.RateIncrement, rt.GroupIntervalStart,
|
||||
rt.RoundingMethod, rt.RoundingDecimals))
|
||||
tpid, rtId, rt.ConnectFee, rt.Rate, rt.RateUnit, rt.RateIncrement, rt.GroupIntervalStart))
|
||||
i++
|
||||
}
|
||||
}
|
||||
@@ -900,13 +899,12 @@ func (self *SQLStorage) GetTpRates(tpid, tag string) (map[string]*utils.TPRate,
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var tag, rate_unit, rate_increment, group_interval_start, roundingMethod string
|
||||
var tag, rate_unit, rate_increment, group_interval_start string
|
||||
var connect_fee, rate float64
|
||||
var roundingDecimals int
|
||||
if err := rows.Scan(&tag, &connect_fee, &rate, &rate_unit, &rate_increment, &group_interval_start, &roundingMethod, &roundingDecimals); err != nil {
|
||||
if err := rows.Scan(&tag, &connect_fee, &rate, &rate_unit, &rate_increment, &group_interval_start); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rs, err := utils.NewRateSlot(connect_fee, rate, rate_unit, rate_increment, group_interval_start, roundingMethod, roundingDecimals)
|
||||
rs, err := utils.NewRateSlot(connect_fee, rate, rate_unit, rate_increment, group_interval_start)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -729,7 +729,7 @@ func TestTimespanCreateIncrements(t *testing.T) {
|
||||
if len(ts.Increments) != 3 {
|
||||
t.Error("Error creating increment slice: ", len(ts.Increments))
|
||||
}
|
||||
if len(ts.Increments) < 3 || ts.Increments[2].Cost != 20.0667 {
|
||||
if len(ts.Increments) < 3 || ts.Increments[2].Cost != 20.0666666667 {
|
||||
t.Error("Wrong second slice: ", ts.Increments[2].Cost)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ func (self *TPCSVImporter) importRates(fn string) error {
|
||||
}
|
||||
continue
|
||||
}
|
||||
rt, err := NewLoadRate(record[0], record[1], record[2], record[3], record[4], record[5], record[6], record[7])
|
||||
rt, err := NewLoadRate(record[0], record[1], record[2], record[3], record[4], record[5])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -42,10 +42,10 @@ func TestLoadCsvTp(t *testing.T) {
|
||||
ASAP,*any,*any,*any,*any,*asap`
|
||||
destinations := `DST_UK_Mobile_BIG5,447596
|
||||
DST_UK_Mobile_BIG5,447956`
|
||||
rates := `RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s,*up,8
|
||||
RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s,*up,8`
|
||||
destinationRates := `DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG
|
||||
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5`
|
||||
rates := `RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s
|
||||
RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s`
|
||||
destinationRates := `DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG,*up,8
|
||||
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5,*up,8`
|
||||
ratingPlans := `RP_UK_Mobile_BIG5_PKG,DR_UK_Mobile_BIG5_PKG,ALWAYS,10
|
||||
RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10`
|
||||
ratingProfiles := `*out,cgrates.org,call,*any,2013-01-06T00:00:00Z,RP_UK,
|
||||
|
||||
@@ -42,10 +42,10 @@ func TestLoadCsvTp2(t *testing.T) {
|
||||
ASAP,*any,*any,*any,*any,*asap`
|
||||
destinations := `DST_UK_Mobile_BIG5,447596
|
||||
DST_UK_Mobile_BIG5,447956`
|
||||
rates := `RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s,*up,8
|
||||
RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s,*up,8`
|
||||
destinationRates := `DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG
|
||||
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5`
|
||||
rates := `RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s
|
||||
RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s`
|
||||
destinationRates := `DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG,*up,8
|
||||
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5,*up,8`
|
||||
ratingPlans := `RP_UK_Mobile_BIG5_PKG,DR_UK_Mobile_BIG5_PKG,ALWAYS,10
|
||||
RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10`
|
||||
ratingProfiles := `*out,cgrates.org,call,*any,2013-01-06T00:00:00Z,RP_UK,
|
||||
|
||||
@@ -42,10 +42,10 @@ func TestLoadCsvTp3(t *testing.T) {
|
||||
ASAP,*any,*any,*any,*any,*asap`
|
||||
destinations := `DST_UK_Mobile_BIG5,447596
|
||||
DST_UK_Mobile_BIG5,447956`
|
||||
rates := `RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s,*up,8
|
||||
RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s,*up,8`
|
||||
destinationRates := `DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG
|
||||
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5`
|
||||
rates := `RT_UK_Mobile_BIG5_PKG,0.01,0,20s,20s,0s
|
||||
RT_UK_Mobile_BIG5,0.01,0.10,1s,1s,0s`
|
||||
destinationRates := `DR_UK_Mobile_BIG5_PKG,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5_PKG,*up,8
|
||||
DR_UK_Mobile_BIG5,DST_UK_Mobile_BIG5,RT_UK_Mobile_BIG5,*up,8`
|
||||
ratingPlans := `RP_UK_Mobile_BIG5_PKG,DR_UK_Mobile_BIG5_PKG,ALWAYS,10
|
||||
RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10`
|
||||
ratingProfiles := `*out,cgrates.org,call,*any,2013-01-06T00:00:00Z,RP_UK,
|
||||
|
||||
@@ -40,9 +40,9 @@ type TPRate struct {
|
||||
}
|
||||
|
||||
// Needed so we make sure we always use SetDurations() on a newly created value
|
||||
func NewRateSlot(connectFee, rate float64, rateUnit, rateIncrement, grpInterval, rndMethod string, rndDecimals int) (*RateSlot, error) {
|
||||
func NewRateSlot(connectFee, rate float64, rateUnit, rateIncrement, grpInterval string) (*RateSlot, error) {
|
||||
rs := &RateSlot{ConnectFee: connectFee, Rate: rate, RateUnit: rateUnit, RateIncrement: rateIncrement,
|
||||
GroupIntervalStart: grpInterval, RoundingMethod: rndMethod, RoundingDecimals: rndDecimals}
|
||||
GroupIntervalStart: grpInterval}
|
||||
if err := rs.SetDurations(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -55,8 +55,6 @@ type RateSlot struct {
|
||||
RateUnit string // Number of billing units this rate applies to
|
||||
RateIncrement string // This rate will apply in increments of duration
|
||||
GroupIntervalStart string // Group position
|
||||
RoundingMethod string // Use this method to round the cost
|
||||
RoundingDecimals int // Round the cost number of decimals
|
||||
rateUnitDur time.Duration
|
||||
rateIncrementDur time.Duration
|
||||
groupIntervalStartDur time.Duration
|
||||
@@ -93,9 +91,11 @@ type TPDestinationRate struct {
|
||||
}
|
||||
|
||||
type DestinationRate struct {
|
||||
DestinationId string // The destination identity
|
||||
RateId string // The rate identity
|
||||
Rate *TPRate
|
||||
DestinationId string // The destination identity
|
||||
RateId string // The rate identity
|
||||
Rate *TPRate
|
||||
RoundingMethod string
|
||||
RoundingDecimals int
|
||||
}
|
||||
|
||||
type ApierTPTiming struct {
|
||||
|
||||
@@ -51,8 +51,8 @@ const (
|
||||
DERIVED_CHARGERS_CSV = "DerivedChargers.csv"
|
||||
TIMINGS_NRCOLS = 6
|
||||
DESTINATIONS_NRCOLS = 2
|
||||
RATES_NRCOLS = 8
|
||||
DESTINATION_RATES_NRCOLS = 3
|
||||
RATES_NRCOLS = 6
|
||||
DESTINATION_RATES_NRCOLS = 5
|
||||
DESTRATE_TIMINGS_NRCOLS = 4
|
||||
RATE_PROFILES_NRCOLS = 7
|
||||
SHARED_GROUPS_NRCOLS = 4
|
||||
|
||||
Reference in New Issue
Block a user