mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-13 02:56:24 +05:00
Few more methods on TPCSVImporter, API TPRates modifications to include GroupInterval
This commit is contained in:
@@ -24,6 +24,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
)
|
||||
|
||||
// Creates a new rate within a tariff plan
|
||||
@@ -36,7 +37,12 @@ func (self *Apier) SetTPRate(attrs utils.TPRate, reply *string) error {
|
||||
} else if exists {
|
||||
return errors.New(utils.ERR_DUPLICATE)
|
||||
}
|
||||
if err := self.StorDb.SetTPRate(&attrs); err != nil {
|
||||
rts := make([]*engine.Rate, len(attrs.RateSlots))
|
||||
for idx,rtSlot := range attrs.RateSlots {
|
||||
rts[idx] = &engine.Rate{attrs.RateId, rtSlot.ConnectFee, rtSlot.Rate, float64(rtSlot.RatedUnits),
|
||||
float64(rtSlot.RateIncrements), float64(rtSlot.GroupInterval), rtSlot.RoundingMethod, rtSlot.RoundingDecimals, rtSlot.Weight}
|
||||
}
|
||||
if err := self.StorDb.SetTPRates( attrs.TPid, map[string][]*engine.Rate{ attrs.RateId: rts } ); err != nil {
|
||||
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
|
||||
}
|
||||
*reply = "OK"
|
||||
|
||||
@@ -43,11 +43,12 @@ CREATE TABLE `tp_rates` (
|
||||
`rate` decimal(5,4) NOT NULL,
|
||||
`rated_units` int(11) NOT NULL,
|
||||
`rate_increments` int(11) NOT NULL,
|
||||
`group_interval` int(11) NOT NULL,
|
||||
`rounding_method` varchar(255) NOT NULL,
|
||||
`rounding_decimals` tinyint(4) NOT NULL,
|
||||
`weight` decimal(5,2) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `tpid_tag_rate_weight` (`tpid`,`tag`,`weight`),
|
||||
UNIQUE KEY `unique_tprate` (`tpid`,`tag`,`group_interval`),
|
||||
KEY `tpid` (`tpid`),
|
||||
KEY `tpid_tag` (`tpid`,`tag`)
|
||||
);
|
||||
|
||||
@@ -15,13 +15,14 @@ Creates a new rate within a tariff plan.
|
||||
}
|
||||
|
||||
type RateSlot struct {
|
||||
ConnectFee float64 // ConnectFee applied once the call is answered
|
||||
Rate float64 // Rate applied
|
||||
RatedUnits int // Number of billing units this rate applies to
|
||||
RateIncrements int // This rate will apply in increments of duration
|
||||
RoundingMethod string // Use this method to round the cost
|
||||
RoundingDecimals int // Round the cost number of decimals
|
||||
Weight float64 // Rate's priority when dealing with grouped rates
|
||||
ConnectFee float64 // ConnectFee applied once the call is answered
|
||||
Rate float64 // Rate applied
|
||||
RatedUnits int // Number of billing units this rate applies to
|
||||
RateIncrements int // This rate will apply in increments of duration
|
||||
GroupInterval int // Group position
|
||||
RoundingMethod string // Use this method to round the cost
|
||||
RoundingDecimals int // Round the cost number of decimals
|
||||
Weight float64 // Rate's priority when dealing with grouped rates
|
||||
}
|
||||
|
||||
Mandatory parameters: ``[]string{"TPid", "RateId", "ConnectFee", "RateSlots"}``
|
||||
@@ -39,9 +40,10 @@ Creates a new rate within a tariff plan.
|
||||
{
|
||||
"ConnectFee": 0.2,
|
||||
"Rate": 2,
|
||||
"RateIncrements": 1,
|
||||
"RateIncrements": 60,
|
||||
"RatedUnits": 1,
|
||||
"RoundingDecimals": 2,
|
||||
"RoundingDecimals": 2,
|
||||
"GroupInterval": 0,
|
||||
"RoundingMethod": "*up",
|
||||
"Weight": 10.0
|
||||
},
|
||||
@@ -50,7 +52,8 @@ Creates a new rate within a tariff plan.
|
||||
"Rate": 2.1,
|
||||
"RateIncrements": 1,
|
||||
"RatedUnits": 1,
|
||||
"RoundingDecimals": 2,
|
||||
"RoundingDecimals": 2,
|
||||
"GroupInterval": 60,
|
||||
"RoundingMethod": "*up",
|
||||
"Weight": 20.0
|
||||
}
|
||||
@@ -131,13 +134,14 @@ Queries specific rate on tariff plan.
|
||||
}
|
||||
|
||||
type RateSlot struct {
|
||||
ConnectFee float64 // ConnectFee applied once the call is answered
|
||||
Rate float64 // Rate applied
|
||||
RatedUnits int // Number of billing units this rate applies to
|
||||
RateIncrements int // This rate will apply in increments of duration
|
||||
RoundingMethod string // Use this method to round the cost
|
||||
RoundingDecimals int // Round the cost number of decimals
|
||||
Weight float64 // Rate's priority when dealing with grouped rates
|
||||
ConnectFee float64 // ConnectFee applied once the call is answered
|
||||
Rate float64 // Rate applied
|
||||
RatedUnits int // Number of billing units this rate applies to
|
||||
RateIncrements int // This rate will apply in increments of duration
|
||||
GroupInterval int // Group position
|
||||
RoundingMethod string // Use this method to round the cost
|
||||
RoundingDecimals int // Round the cost number of decimals
|
||||
Weight float64 // Rate's priority when dealing with grouped rates
|
||||
}
|
||||
|
||||
*JSON sample*:
|
||||
@@ -152,9 +156,10 @@ Queries specific rate on tariff plan.
|
||||
{
|
||||
"ConnectFee": 0.2,
|
||||
"Rate": 2,
|
||||
"RateIncrements": 1,
|
||||
"RateIncrements": 60,
|
||||
"RatedUnits": 1,
|
||||
"RoundingDecimals": 2,
|
||||
"RoundingDecimals": 2,
|
||||
"GroupInterval": 0,
|
||||
"RoundingMethod": "*up",
|
||||
"Weight": 10
|
||||
},
|
||||
@@ -163,7 +168,8 @@ Queries specific rate on tariff plan.
|
||||
"Rate": 2.1,
|
||||
"RateIncrements": 1,
|
||||
"RatedUnits": 1,
|
||||
"RoundingDecimals": 2,
|
||||
"RoundingDecimals": 2,
|
||||
"GroupInterval": 60,
|
||||
"RoundingMethod": "*up",
|
||||
"Weight": 20
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ func topupResetAction(ub *UserBalance, a *Action) (err error) {
|
||||
if a.BalanceId == MINUTES {
|
||||
ub.MinuteBuckets = make([]*MinuteBucket, 0)
|
||||
} else {
|
||||
ub.BalanceMap[a.BalanceId+a.Direction] = BalanceChain{&Balance{Value: 0}}
|
||||
ub.BalanceMap[a.BalanceId+a.Direction] = BalanceChain{&Balance{Value: 0}} // ToDo: can ub be empty here?
|
||||
}
|
||||
genericMakeNegative(a)
|
||||
genericDebit(ub, a)
|
||||
|
||||
@@ -68,7 +68,7 @@ type DataStorage interface {
|
||||
GetTPDestination(string, string) (*Destination, error)
|
||||
GetTPDestinationIds(string) ([]string, error)
|
||||
ExistsTPRate(string, string) (bool, error)
|
||||
SetTPRate(*utils.TPRate) error
|
||||
SetTPRates(string, map[string][]*Rate) error
|
||||
GetTPRate(string, string) (*utils.TPRate, error)
|
||||
GetTPRateIds(string) ([]string, error)
|
||||
ExistsTPDestinationRate(string, string) (bool, error)
|
||||
|
||||
@@ -113,7 +113,7 @@ func (ms *MapStorage) ExistsTPRate(tpid, rtId string) (bool, error) {
|
||||
return false, errors.New(utils.ERR_NOT_IMPLEMENTED)
|
||||
}
|
||||
|
||||
func (ms *MapStorage) SetTPRate(rt *utils.TPRate) error {
|
||||
func (ms *MapStorage) SetTPRates(tpid string, rts map[string][]*Rate) error {
|
||||
return errors.New(utils.ERR_NOT_IMPLEMENTED)
|
||||
}
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ func (ms *MongoStorage) ExistsTPRate(tpid, rtId string) (bool, error) {
|
||||
return false, errors.New(utils.ERR_NOT_IMPLEMENTED)
|
||||
}
|
||||
|
||||
func (ms *MongoStorage) SetTPRate(rt *utils.TPRate) error {
|
||||
func (ms *MongoStorage) SetTPRates(tpid string, rts map[string][]*Rate) error {
|
||||
return errors.New(utils.ERR_NOT_IMPLEMENTED)
|
||||
}
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ func (rs *RedisStorage) ExistsTPRate(tpid, rtId string) (bool, error) {
|
||||
return false, errors.New(utils.ERR_NOT_IMPLEMENTED)
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) SetTPRate(rt *utils.TPRate) error {
|
||||
func (rs *RedisStorage) SetTPRates(tpid string, rts map[string][]*Rate) error {
|
||||
return errors.New(utils.ERR_NOT_IMPLEMENTED)
|
||||
}
|
||||
|
||||
|
||||
@@ -210,19 +210,29 @@ func (self *SQLStorage) ExistsTPRate(tpid, rtId string) (bool, error) {
|
||||
return exists, nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) SetTPRate(rt *utils.TPRate) error {
|
||||
for _, rtSlot := range rt.RateSlots {
|
||||
if _, err := self.Db.Exec(fmt.Sprintf("INSERT INTO %s (tpid, tag, connect_fee, rate, rated_units, rate_increments, rounding_method, rounding_decimals, weight) VALUES ('%s', '%s', %f, %f, %d, %d,'%s', %d, %f)",
|
||||
utils.TBL_TP_RATES, rt.TPid, rt.RateId, rtSlot.ConnectFee, rtSlot.Rate, rtSlot.RatedUnits, rtSlot.RateIncrements,
|
||||
rtSlot.RoundingMethod, rtSlot.RoundingDecimals, rtSlot.Weight)); err != nil {
|
||||
return err
|
||||
func (self *SQLStorage) SetTPRates(tpid string, rts map[string][]*Rate) error {
|
||||
if len(rts) == 0 {
|
||||
return nil //Nothing to set
|
||||
}
|
||||
qry := fmt.Sprintf("INSERT INTO %s (tpid, tag, connect_fee, rate, rated_units, rate_increments, group_interval, rounding_method, rounding_decimals, weight) VALUES ", utils.TBL_TP_RATES)
|
||||
for rtId, rtRows := range rts {
|
||||
for idx, rt := range rtRows {
|
||||
if idx != 0 { //Consecutive values after the first will be prefixed with "," as separator
|
||||
qry += ","
|
||||
}
|
||||
qry += fmt.Sprintf("('%s', '%s', %f, %f, %d, %d,%d,'%s', %d, %f)",
|
||||
tpid, rtId, rt.ConnectFee, rt.Price, int(rt.PricedUnits), int(rt.RateIncrements), int(rt.GroupInterval),
|
||||
rt.RoundingMethod, rt.RoundingDecimals, rt.Weight)
|
||||
}
|
||||
}
|
||||
if _, err := self.Db.Exec(qry); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) GetTPRate(tpid, rtId string) (*utils.TPRate, error) {
|
||||
rows, err := self.Db.Query(fmt.Sprintf("SELECT connect_fee, rate, rated_units, rate_increments, rounding_method, rounding_decimals, weight FROM %s WHERE tpid='%s' AND tag='%s'", utils.TBL_TP_RATES, tpid, rtId))
|
||||
rows, err := self.Db.Query(fmt.Sprintf("SELECT connect_fee, rate, rated_units, rate_increments, group_interval, rounding_method, rounding_decimals, weight FROM %s WHERE tpid='%s' AND tag='%s'", utils.TBL_TP_RATES, tpid, rtId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -232,13 +242,14 @@ func (self *SQLStorage) GetTPRate(tpid, rtId string) (*utils.TPRate, error) {
|
||||
for rows.Next() {
|
||||
i++ //Keep here a reference so we know we got at least one prefix
|
||||
var connectFee, rate, weight float64
|
||||
var ratedUnits, rateIncrements, roundingDecimals int
|
||||
var ratedUnits, rateIncrements, roundingDecimals, groupInterval int
|
||||
var roundingMethod string
|
||||
err = rows.Scan(&connectFee, &rate, &ratedUnits, &rateIncrements, &roundingMethod, &roundingDecimals, &weight)
|
||||
err = rows.Scan(&connectFee, &rate, &ratedUnits, &rateIncrements, &groupInterval, &roundingMethod, &roundingDecimals, &weight)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rt.RateSlots = append(rt.RateSlots, utils.RateSlot{connectFee, rate, ratedUnits, rateIncrements, roundingMethod, roundingDecimals, weight})
|
||||
rt.RateSlots = append(rt.RateSlots, utils.RateSlot{connectFee, rate, ratedUnits, rateIncrements, groupInterval,
|
||||
roundingMethod, roundingDecimals, weight})
|
||||
}
|
||||
if i == 0 {
|
||||
return nil, nil
|
||||
|
||||
@@ -35,6 +35,8 @@ type TPCSVImporter struct {
|
||||
Verbose bool // If true will print a detailed information instead of silently discarding it
|
||||
}
|
||||
|
||||
// Maps csv file to handler which should process it. Defined like this since tests on 1.0.3 were failing on Travis.
|
||||
// Change it to func(string) error as soon as Travis updates.
|
||||
var fileHandlers = map[string]func(*TPCSVImporter,string) error{
|
||||
utils.TIMINGS_CSV: (*TPCSVImporter).importTimings,
|
||||
utils.DESTINATIONS_CSV: (*TPCSVImporter).importDestinations,
|
||||
@@ -49,10 +51,6 @@ var fileHandlers = map[string]func(*TPCSVImporter,string) error{
|
||||
}
|
||||
|
||||
func (self *TPCSVImporter) Run() error {
|
||||
|
||||
// Maps csv file to handler which should process it
|
||||
|
||||
|
||||
files, _ := ioutil.ReadDir(self.DirPath)
|
||||
for _, f := range files {
|
||||
fHandler,hasName := fileHandlers[f.Name()]
|
||||
@@ -66,6 +64,9 @@ func (self *TPCSVImporter) Run() error {
|
||||
|
||||
// Handler importing timings from file, saved row by row to storDb
|
||||
func (self *TPCSVImporter) importTimings(fn string) error {
|
||||
if self.Verbose {
|
||||
log.Printf("Processing file: <%s> ", fn)
|
||||
}
|
||||
fParser, err := NewTPCSVFileParser( self.DirPath, fn )
|
||||
if err!=nil {
|
||||
return err
|
||||
@@ -90,11 +91,62 @@ func (self *TPCSVImporter) importTimings(fn string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *TPCSVImporter) importDestinations(fPath string) error {
|
||||
func (self *TPCSVImporter) importDestinations(fn string) error {
|
||||
if self.Verbose {
|
||||
log.Printf("Processing file: <%s> ", fn)
|
||||
}
|
||||
fParser, err := NewTPCSVFileParser( self.DirPath, fn )
|
||||
if err!=nil {
|
||||
return err
|
||||
}
|
||||
lineNr := 0
|
||||
for {
|
||||
lineNr++
|
||||
record, err := fParser.ParseNextLine()
|
||||
if err == io.EOF { // Reached end of file
|
||||
break
|
||||
} else if err != nil {
|
||||
if self.Verbose {
|
||||
log.Printf("Ignoring line %d, warning: <%s> ", lineNr, err.Error())
|
||||
}
|
||||
continue
|
||||
}
|
||||
dst := &Destination{record[0], []string{record[1]}}
|
||||
if err := self.StorDb.SetTPDestination(self.TPid, dst); err != nil {
|
||||
log.Printf("Ignoring line %d, storDb operational error: <%s> ", lineNr, err.Error())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *TPCSVImporter) importRates(fPath string) error {
|
||||
func (self *TPCSVImporter) importRates(fn string) error {
|
||||
if self.Verbose {
|
||||
log.Printf("Processing file: <%s> ", fn)
|
||||
}
|
||||
fParser, err := NewTPCSVFileParser( self.DirPath, fn )
|
||||
if err!=nil {
|
||||
return err
|
||||
}
|
||||
lineNr := 0
|
||||
for {
|
||||
lineNr++
|
||||
record, err := fParser.ParseNextLine()
|
||||
if err == io.EOF { // Reached end of file
|
||||
break
|
||||
} else if err != nil {
|
||||
if self.Verbose {
|
||||
log.Printf("Ignoring line %d, warning: <%s> ", lineNr, err.Error())
|
||||
}
|
||||
continue
|
||||
}
|
||||
rt, err := NewRate(record[0], record[1], record[2], record[3], record[4], record[5], record[6], record[7], record[8])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := self.StorDb.SetTPRates( self.TPid, map[string][]*Rate{ record[0]: []*Rate{rt} } ); err != nil {
|
||||
log.Printf("Ignoring line %d, storDb operational error: <%s> ", lineNr, err.Error())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ type RateSlot struct {
|
||||
Rate float64 // Rate applied
|
||||
RatedUnits int // Number of billing units this rate applies to
|
||||
RateIncrements int // This rate will apply in increments of duration
|
||||
GroupInterval int // Group position
|
||||
RoundingMethod string // Use this method to round the cost
|
||||
RoundingDecimals int // Round the cost number of decimals
|
||||
Weight float64 // Rate's priority when dealing with grouped rates
|
||||
|
||||
Reference in New Issue
Block a user