From d3e16d37121535a9bd89de67293b4fcfc9f65b83 Mon Sep 17 00:00:00 2001 From: DanB Date: Wed, 10 Jul 2013 10:36:51 +0200 Subject: [PATCH] Apier.SetTPRates with RateSlots --- apier/tprates.go | 52 +++++++++++-------- apier/tptimings.go | 2 +- .../mysql/create_tariffplan_tables.sql | 2 +- rater/storage_interface.go | 3 +- rater/storage_map.go | 6 ++- rater/storage_mongo.go | 6 ++- rater/storage_redis.go | 6 ++- rater/storage_sql.go | 36 +++++++++++-- utils/data_tprates.go | 36 +++++++++++++ 9 files changed, 119 insertions(+), 30 deletions(-) create mode 100644 utils/data_tprates.go diff --git a/apier/tprates.go b/apier/tprates.go index b9b046b0d..b9a581d45 100644 --- a/apier/tprates.go +++ b/apier/tprates.go @@ -23,37 +23,47 @@ package apier import ( "errors" "fmt" - "github.com/cgrates/cgrates/rater" "github.com/cgrates/cgrates/utils" - "strings" ) -type ApierTPRate struct { - TPid string // Tariff plan id - RateId string // Rates id - ConnectFee string // ConnectFee applied once the call is answered - Rate string // Rate applied - RatedUnits string // Number of billing units this rate applies to - RateIncrements string // This rate will apply in increments of - Weight string // Rate's priority when dealing with grouped rates -} + // Creates a new rate within a tariff plan -func (self *Apier) SetTPRate(attrs ApierTPRate, reply *string) error { - if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RateId", "ConnectFee", "Rate", "RatedUnits", "RateIncrements", "Weight"}); len(missing) != 0 { +func (self *Apier) SetTPRate(attrs utils.TPRate, reply *string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RateId", "ConnectFee", "RateSlots"}); len(missing) != 0 { return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) } - rt, errRt := rater.NewRate(attrs.RateId, attrs.ConnectFee, attrs.Rate, attrs.RatedUnits, attrs.RateIncrements, attrs.Weight) - if errRt != nil { - return fmt.Errorf("%s:%v", utils.ERR_SERVER_ERROR, errRt.Error()) - } - err := self.StorDb.SetTPRate(attrs.TPid, rt) - switch { - case strings.HasPrefix(err.Error(), "Error 1062"): //MySQL way of saying duplicate + if exists, err := self.StorDb.ExistsTPRate(attrs.TPid, attrs.RateId); err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } else if exists { return errors.New(utils.ERR_DUPLICATE) - case err != nil: + } + if err := self.StorDb.SetTPRate(&attrs); err!=nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } *reply = "OK" return nil } + +/* +type AttrGetTPRate struct { + TPid string // Tariff plan id + RateId string // Rate id +} + +// Queries specific Rate on tariff plan +func (self *Apier) GetTPRate(attrs AttrGetTPRate, reply *ApierTPRate) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RateId"}); len(missing) != 0 { //Params missing + return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) + } + if tm, err := self.StorDb.GetTPTiming(attrs.TPid, attrs.TimingId); err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } else if tm == nil { + return errors.New(utils.ERR_NOT_FOUND) + } else { + *reply = ApierTPTiming{attrs.TPid, tm.Id, tm.Years.Serialize(";"), + tm.Months.Serialize(";"), tm.MonthDays.Serialize(";"), tm.WeekDays.Serialize(";"), tm.StartTime} + } + return nil +} +*/ diff --git a/apier/tptimings.go b/apier/tptimings.go index a456f7c44..aa6d93737 100644 --- a/apier/tptimings.go +++ b/apier/tptimings.go @@ -41,7 +41,7 @@ func (self *Apier) SetTPTiming(attrs ApierTPTiming, reply *string) error { return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) } if exists, err := self.StorDb.ExistsTPTiming(attrs.TPid, attrs.TimingId); err != nil { - return fmt.Errorf("%s:%v", utils.ERR_SERVER_ERROR, err.Error()) + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } else if exists { return errors.New(utils.ERR_DUPLICATE) } diff --git a/data/storage/mysql/create_tariffplan_tables.sql b/data/storage/mysql/create_tariffplan_tables.sql index 8e1973d95..4301c1fdc 100644 --- a/data/storage/mysql/create_tariffplan_tables.sql +++ b/data/storage/mysql/create_tariffplan_tables.sql @@ -44,7 +44,7 @@ CREATE TABLE `tp_rates` ( `weight` DECIMAL(5,2) NOT NULL, PRIMARY KEY (`id`), KEY `tpid` (`tpid`), - UNIQUE KEY `tpid_rate_weight` (`tpid`,`rate`,`weight`) + UNIQUE KEY `tpid_tag_rate_weight` (`tpid`,`tag`,`weight`) ); -- diff --git a/rater/storage_interface.go b/rater/storage_interface.go index f1d26a906..30f0ee59e 100644 --- a/rater/storage_interface.go +++ b/rater/storage_interface.go @@ -67,7 +67,8 @@ type DataStorage interface { ExistsTPDestination(string, string) (bool, error) GetTPDestination(string, string) (*Destination, error) GetTPDestinationIds(string) ([]string, error) - SetTPRate(string, *Rate) error + ExistsTPRate(string, string) (bool, error) + SetTPRate(*utils.TPRate) error // End Apier functions GetActions(string) (Actions, error) SetActions(string, Actions) error diff --git a/rater/storage_map.go b/rater/storage_map.go index a724561d1..0a3da08ad 100644 --- a/rater/storage_map.go +++ b/rater/storage_map.go @@ -109,7 +109,11 @@ func (ms *MapStorage) GetTPDestinationIds(tpid string) ([]string, error) { return nil, errors.New(utils.ERR_NOT_IMPLEMENTED) } -func (ms *MapStorage) SetTPRate(tpid string, rt *Rate) error { +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 { return errors.New(utils.ERR_NOT_IMPLEMENTED) } diff --git a/rater/storage_mongo.go b/rater/storage_mongo.go index b7c71b17a..7056a49ff 100644 --- a/rater/storage_mongo.go +++ b/rater/storage_mongo.go @@ -184,7 +184,11 @@ func (ms *MongoStorage) SetTPDestination(tpid string, dest *Destination) error { return errors.New(utils.ERR_NOT_IMPLEMENTED) } -func (ms *MongoStorage) SetTPRate(tpid string, rt *Rate) error { +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 { return errors.New(utils.ERR_NOT_IMPLEMENTED) } diff --git a/rater/storage_redis.go b/rater/storage_redis.go index 7d3790396..59b324c5b 100644 --- a/rater/storage_redis.go +++ b/rater/storage_redis.go @@ -139,7 +139,11 @@ func (rs *RedisStorage) SetTPDestination(tpid string, dest *Destination) error { return errors.New(utils.ERR_NOT_IMPLEMENTED) } -func (rs *RedisStorage) SetTPRate(tpid string, rt *Rate) error { +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 { return errors.New(utils.ERR_NOT_IMPLEMENTED) } diff --git a/rater/storage_sql.go b/rater/storage_sql.go index 661efd93e..c514745ba 100644 --- a/rater/storage_sql.go +++ b/rater/storage_sql.go @@ -200,13 +200,43 @@ func (self *SQLStorage) SetTPDestination(tpid string, dest *Destination) error { return nil } -func (self *SQLStorage) SetTPRate(tpid string, rt *Rate) error { - if _, err := self.Db.Exec(fmt.Sprintf("INSERT INTO %s (tpid, tag, connect_fee, rate, rated_units, rate_increments, weight) VALUES ('%s', '%s', %f, %f, %d, %d, %f)", utils.TBL_TP_RATES, tpid, rt.Tag, rt.ConnectFee, rt.Price, int(rt.PricedUnits), int(rt.RateIncrements), rt.Weight)); err != nil { - return err +func (self *SQLStorage) ExistsTPRate(tpid, rtId string) (bool, error) { + var exists bool + err := self.Db.QueryRow(fmt.Sprintf("SELECT EXISTS (SELECT 1 FROM %s WHERE tpid='%s' AND tag='%s')", utils.TBL_TP_RATES, tpid, rtId)).Scan(&exists) + if err != nil { + return false, err + } + 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, weight) VALUES ('%s', '%s', %f, %f, %d, %d, %f)", + utils.TBL_TP_RATES, rt.TPid, rt.RateId, rtSlot.ConnectFee, rtSlot.Rate, rtSlot.RatedUnits, rtSlot.RateIncrements, + rtSlot.Weight)); err != nil { + return err + } } return nil } +func (self *SQLStorage) GetTPRate(tpid, rtId, weight string) (*utils.TPRate, error) { +/* + var tpid, tag string + var connect_fee, rate, rated_units, rate_increments, weight float64 + err := self.Db.QueryRow(fmt.Sprintf("SELECT years, months, month_days, week_days, time FROM %s WHERE tpid='%s' AND tag='%s' LIMIT 1", + utils.TBL_TP_TIMINGS, tpid, tmId)).Scan(&years,&months,&monthDays,&weekDays,&time) + switch { + case err == sql.ErrNoRows: + return nil,nil + case err!=nil: + return nil, err + } + return NewTiming( tmId, years, months, monthDays, weekDays, time ), nil +*/ + return nil, nil +} + func (self *SQLStorage) GetActions(string) (as Actions, err error) { return } diff --git a/utils/data_tprates.go b/utils/data_tprates.go new file mode 100644 index 000000000..0547ef334 --- /dev/null +++ b/utils/data_tprates.go @@ -0,0 +1,36 @@ +/* +Rating system designed to be used in VoIP Carriers World +Copyright (C) 2013 ITsysCOM + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package utils + +// This file deals with tp_rates data definition + + +type TPRate struct { + TPid string // Tariff plan id + RateId string // Rate id + RateSlots []RateSlot // One or more RateSlots +} + +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 + Weight float64 // Rate's priority when dealing with grouped rates +}