mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Adding Apier TPRates documentation
This commit is contained in:
@@ -26,8 +26,6 @@ import (
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
|
||||
|
||||
// Creates a new rate within a tariff plan
|
||||
func (self *Apier) SetTPRate(attrs utils.TPRate, reply *string) error {
|
||||
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RateId", "ConnectFee", "RateSlots"}); len(missing) != 0 {
|
||||
@@ -38,7 +36,7 @@ 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 {
|
||||
if err := self.StorDb.SetTPRate(&attrs); err != nil {
|
||||
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
|
||||
}
|
||||
*reply = "OK"
|
||||
@@ -46,7 +44,7 @@ func (self *Apier) SetTPRate(attrs utils.TPRate, reply *string) error {
|
||||
}
|
||||
|
||||
type AttrGetTPRate struct {
|
||||
TPid string // Tariff plan id
|
||||
TPid string // Tariff plan id
|
||||
RateId string // Rate id
|
||||
}
|
||||
|
||||
|
||||
230
docs/api_rates.rst
Normal file
230
docs/api_rates.rst
Normal file
@@ -0,0 +1,230 @@
|
||||
Apier.SetTPRate
|
||||
+++++++++++++++++
|
||||
|
||||
Creates a new rate within a tariff plan.
|
||||
|
||||
**Request**:
|
||||
|
||||
Data:
|
||||
::
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
Mandatory parameters: ``[]string{"TPid", "RateId", "ConnectFee", "RateSlots"}``
|
||||
|
||||
*JSON sample*:
|
||||
::
|
||||
|
||||
{
|
||||
"id": 0,
|
||||
"method": "Apier.SetTPRate",
|
||||
"params": [
|
||||
{
|
||||
"RateId": "SAMPLE_RATE_4",
|
||||
"RateSlots": [
|
||||
{
|
||||
"ConnectFee": 0,
|
||||
"Rate": 1.2,
|
||||
"RateIncrements": 1,
|
||||
"RatedUnits": 60,
|
||||
"Weight": 10
|
||||
},
|
||||
{
|
||||
"ConnectFee": 0,
|
||||
"Rate": 2.2,
|
||||
"RateIncrements": 1,
|
||||
"RatedUnits": 60,
|
||||
"Weight": 20
|
||||
}
|
||||
],
|
||||
"TPid": "SAMPLE_TP"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
**Reply**:
|
||||
|
||||
Data:
|
||||
::
|
||||
|
||||
string
|
||||
|
||||
Possible answers:
|
||||
``OK`` - Success.
|
||||
|
||||
*JSON sample*:
|
||||
::
|
||||
|
||||
{
|
||||
"error": null,
|
||||
"id": 0,
|
||||
"result": "OK"
|
||||
}
|
||||
|
||||
**Errors**:
|
||||
|
||||
``MANDATORY_IE_MISSING`` - Mandatory parameter missing from request.
|
||||
|
||||
``SERVER_ERROR`` - Server error occurred.
|
||||
|
||||
``DUPLICATE`` - The specified combination of TPid/RateId already exists in StorDb.
|
||||
|
||||
|
||||
Apier.GetTPRate
|
||||
+++++++++++++++
|
||||
|
||||
Queries specific rate on tariff plan.
|
||||
|
||||
**Request**:
|
||||
|
||||
Data:
|
||||
::
|
||||
|
||||
type AttrGetTPRate struct {
|
||||
TPid string // Tariff plan id
|
||||
RateId string // Rate id
|
||||
}
|
||||
|
||||
Mandatory parameters: ``[]string{"TPid", "RateId"}``
|
||||
|
||||
*JSON sample*:
|
||||
::
|
||||
|
||||
{
|
||||
"id": 1,
|
||||
"method": "Apier.GetTPRate",
|
||||
"params": [
|
||||
{
|
||||
"RateId": "SAMPLE_RATE_4",
|
||||
"TPid": "SAMPLE_TP"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
**Reply**:
|
||||
|
||||
Data:
|
||||
::
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
*JSON sample*:
|
||||
::
|
||||
|
||||
{
|
||||
"error": null,
|
||||
"id": 1,
|
||||
"result": {
|
||||
"RateId": "SAMPLE_RATE_4",
|
||||
"RateSlots": [
|
||||
{
|
||||
"ConnectFee": 0,
|
||||
"Rate": 1.2,
|
||||
"RateIncrements": 1,
|
||||
"RatedUnits": 60,
|
||||
"Weight": 10
|
||||
},
|
||||
{
|
||||
"ConnectFee": 0,
|
||||
"Rate": 2.2,
|
||||
"RateIncrements": 1,
|
||||
"RatedUnits": 60,
|
||||
"Weight": 20
|
||||
}
|
||||
],
|
||||
"TPid": "SAMPLE_TP"
|
||||
}
|
||||
}
|
||||
**Errors**:
|
||||
|
||||
``MANDATORY_IE_MISSING`` - Mandatory parameter missing from request.
|
||||
|
||||
``SERVER_ERROR`` - Server error occurred.
|
||||
|
||||
``NOT_FOUND`` - Requested rate id not found.
|
||||
|
||||
|
||||
Apier.GetTPRateIds
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
Queries rate identities on tariff plan.
|
||||
|
||||
**Request**:
|
||||
|
||||
Data:
|
||||
::
|
||||
|
||||
type AttrGetTPRateIds struct {
|
||||
TPid string // Tariff plan id
|
||||
}
|
||||
|
||||
Mandatory parameters: ``[]string{"TPid"}``
|
||||
|
||||
*JSON sample*:
|
||||
::
|
||||
|
||||
{
|
||||
"id": 1,
|
||||
"method": "Apier.GetTPRateIds",
|
||||
"params": [
|
||||
{
|
||||
"TPid": "SAMPLE_TP"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
**Reply**:
|
||||
|
||||
Data:
|
||||
::
|
||||
|
||||
[]string
|
||||
|
||||
*JSON sample*:
|
||||
::
|
||||
|
||||
{
|
||||
"error": null,
|
||||
"id": 1,
|
||||
"result": [
|
||||
"SAMPLE_RATE_1",
|
||||
"SAMPLE_RATE_2",
|
||||
"SAMPLE_RATE_3",
|
||||
"SAMPLE_RATE_4"
|
||||
]
|
||||
}
|
||||
|
||||
**Errors**:
|
||||
|
||||
``MANDATORY_IE_MISSING`` - Mandatory parameter missing from request.
|
||||
|
||||
``SERVER_ERROR`` - Server error occurred.
|
||||
|
||||
``NOT_FOUND`` - Requested tariff plan not found.
|
||||
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ Creates a new timing within a tariff plan.
|
||||
|
||||
``SERVER_ERROR`` - Server error occurred.
|
||||
|
||||
``DUPLICATE`` - The specified combination of TPid/DestinationId already exists in StorDb.
|
||||
``DUPLICATE`` - The specified combination of TPid/TimingId already exists in StorDb.
|
||||
|
||||
|
||||
Apier.GetTPTiming
|
||||
@@ -136,10 +136,10 @@ Queries specific Timing on tariff plan.
|
||||
|
||||
``SERVER_ERROR`` - Server error occurred.
|
||||
|
||||
``NOT_FOUND`` - Requested destination id not found.
|
||||
``NOT_FOUND`` - Requested timing id not found.
|
||||
|
||||
|
||||
Apier.GetTPDestinationIds
|
||||
Apier.GetTPTimingIds
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
Queries timing identities on tariff plan.
|
||||
@@ -149,11 +149,11 @@ Queries timing identities on tariff plan.
|
||||
Data:
|
||||
::
|
||||
|
||||
type AttrGetTPDestinationIds struct {
|
||||
type AttrGetTPTimingIds struct {
|
||||
TPid string // Tariff plan id
|
||||
}
|
||||
|
||||
Required parameters: ``[]string{"TPid"}``
|
||||
Mandatory parameters: ``[]string{"TPid"}``
|
||||
|
||||
*JSON sample*:
|
||||
::
|
||||
|
||||
@@ -149,13 +149,13 @@ Timings
|
||||
api_tptimings
|
||||
|
||||
|
||||
SetTPRate
|
||||
Rates
|
||||
~~~~~~~
|
||||
|
||||
GetTPRate
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
DeleteTPRate
|
||||
|
||||
GetAllTPRates
|
||||
api_tprates
|
||||
|
||||
|
||||
GetTPRateTiming
|
||||
|
||||
@@ -19,32 +19,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package mediator
|
||||
|
||||
import (
|
||||
"time"
|
||||
"strconv"
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FScsvCDR struct {
|
||||
rowData []string // The original row extracted form csv file
|
||||
rowData []string // The original row extracted form csv file
|
||||
accIdIdx,
|
||||
subjectIdx,
|
||||
reqtypeIdx,
|
||||
directionIdx,
|
||||
tenantIdx,
|
||||
torIdx,
|
||||
accountIdx,
|
||||
destinationIdx,
|
||||
answerTimeIdx,
|
||||
durationIdx int // Field indexes
|
||||
cgrCfg *config.CGRConfig // CGR Config instance
|
||||
subjectIdx,
|
||||
reqtypeIdx,
|
||||
directionIdx,
|
||||
tenantIdx,
|
||||
torIdx,
|
||||
accountIdx,
|
||||
destinationIdx,
|
||||
answerTimeIdx,
|
||||
durationIdx int // Field indexes
|
||||
cgrCfg *config.CGRConfig // CGR Config instance
|
||||
}
|
||||
|
||||
|
||||
func NewFScsvCDR(cdrRow []string, accIdIdx, subjectIdx, reqtypeIdx, directionIdx, tenantIdx, torIdx,
|
||||
accountIdx, destinationIdx, answerTimeIdx, durationIdx int, cfg *config.CGRConfig ) (*FScsvCDR, error) {
|
||||
fscdr := FScsvCDR{ cdrRow, accIdIdx, subjectIdx, reqtypeIdx, directionIdx, tenantIdx,
|
||||
torIdx, accountIdx, destinationIdx, answerTimeIdx, durationIdx, cfg }
|
||||
func NewFScsvCDR(cdrRow []string, accIdIdx, subjectIdx, reqtypeIdx, directionIdx, tenantIdx, torIdx,
|
||||
accountIdx, destinationIdx, answerTimeIdx, durationIdx int, cfg *config.CGRConfig) (*FScsvCDR, error) {
|
||||
fscdr := FScsvCDR{cdrRow, accIdIdx, subjectIdx, reqtypeIdx, directionIdx, tenantIdx,
|
||||
torIdx, accountIdx, destinationIdx, answerTimeIdx, durationIdx, cfg}
|
||||
return &fscdr, nil
|
||||
}
|
||||
|
||||
@@ -111,11 +110,3 @@ func (self *FScsvCDR) GetFallbackSubj() string {
|
||||
func (self *FScsvCDR) GetExtraFields() map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -19,13 +19,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package mediator
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"bufio"
|
||||
"encoding/csv"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/cgrates/cgrates/rater"
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/rater"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/howeyc/fsnotify"
|
||||
"os"
|
||||
@@ -35,14 +35,14 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func NewMediator( connector rater.Connector, storDb rater.DataStorage, cfg *config.CGRConfig) (m *Mediator, err error) {
|
||||
func NewMediator(connector rater.Connector, storDb rater.DataStorage, cfg *config.CGRConfig) (m *Mediator, err error) {
|
||||
m = &Mediator{
|
||||
connector: connector,
|
||||
storDb: storDb,
|
||||
cgrCfg: cfg,
|
||||
storDb: storDb,
|
||||
cgrCfg: cfg,
|
||||
}
|
||||
m.fieldNames = make( map[string][]string )
|
||||
m.fieldIdxs = make( map[string][]int )
|
||||
m.fieldNames = make(map[string][]string)
|
||||
m.fieldIdxs = make(map[string][]int)
|
||||
// Load config fields
|
||||
if errLoad := m.loadConfig(); errLoad != nil {
|
||||
return nil, errLoad
|
||||
@@ -51,14 +51,14 @@ func NewMediator( connector rater.Connector, storDb rater.DataStorage, cfg *conf
|
||||
}
|
||||
|
||||
type Mediator struct {
|
||||
connector rater.Connector
|
||||
storDb rater.DataStorage
|
||||
cgrCfg *config.CGRConfig
|
||||
cdrInDir, cdrOutDir string
|
||||
accIdField string
|
||||
accIdIdx int // Populated only for csv files where we have no names but indexes for the fields
|
||||
fieldNames map[string][]string
|
||||
fieldIdxs map[string][]int // Populated only for csv files where we have no names but indexes for the fields
|
||||
connector rater.Connector
|
||||
storDb rater.DataStorage
|
||||
cgrCfg *config.CGRConfig
|
||||
cdrInDir, cdrOutDir string
|
||||
accIdField string
|
||||
accIdIdx int // Populated only for csv files where we have no names but indexes for the fields
|
||||
fieldNames map[string][]string
|
||||
fieldIdxs map[string][]int // Populated only for csv files where we have no names but indexes for the fields
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -77,8 +77,8 @@ Method logic:
|
||||
*/
|
||||
func (self *Mediator) loadConfig() error {
|
||||
fieldKeys := []string{"subject", "reqtype", "direction", "tenant", "tor", "account", "destination", "time_start", "duration"}
|
||||
cfgVals := [][]string{self.cgrCfg.MediatorSubjectFields, self.cgrCfg.MediatorReqTypeFields, self.cgrCfg.MediatorDirectionFields,
|
||||
self.cgrCfg.MediatorTenantFields, self.cgrCfg.MediatorTORFields, self.cgrCfg.MediatorAccountFields, self.cgrCfg.MediatorDestFields,
|
||||
cfgVals := [][]string{self.cgrCfg.MediatorSubjectFields, self.cgrCfg.MediatorReqTypeFields, self.cgrCfg.MediatorDirectionFields,
|
||||
self.cgrCfg.MediatorTenantFields, self.cgrCfg.MediatorTORFields, self.cgrCfg.MediatorAccountFields, self.cgrCfg.MediatorDestFields,
|
||||
self.cgrCfg.MediatorTimeAnswerFields, self.cgrCfg.MediatorDurationFields}
|
||||
|
||||
refIdx := 0 // Subject becomes reference for our checks
|
||||
@@ -87,7 +87,7 @@ func (self *Mediator) loadConfig() error {
|
||||
}
|
||||
// All other configured fields must match the length of reference fields
|
||||
for iCfgVal := range cfgVals {
|
||||
if ( len(cfgVals[refIdx])!=len(cfgVals[iCfgVal]) ) {
|
||||
if len(cfgVals[refIdx]) != len(cfgVals[iCfgVal]) {
|
||||
// Make sure we have everywhere the length of reference key (subject)
|
||||
return errors.New("Inconsistent lenght of mediator fields.")
|
||||
}
|
||||
@@ -122,7 +122,7 @@ func (self *Mediator) loadConfig() error {
|
||||
for idx, key := range fieldKeys {
|
||||
self.fieldNames[key] = cfgVals[idx]
|
||||
if self.cgrCfg.MediatorCDRType == utils.FSCDR_FILE_CSV { // Special case when field names represent indexes of their location in file
|
||||
self.fieldIdxs[key] = make( []int, len(cfgVals[idx]) )
|
||||
self.fieldIdxs[key] = make([]int, len(cfgVals[idx]))
|
||||
for iStr, cfgStr := range cfgVals[idx] {
|
||||
if self.fieldIdxs[key][iStr], errConv = strconv.Atoi(cfgStr); errConv != nil {
|
||||
return fmt.Errorf("All mediator index members (%s) must be ints", key)
|
||||
@@ -134,8 +134,6 @@ func (self *Mediator) loadConfig() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Watch the specified folder for file moves and parse the files on events
|
||||
func (self *Mediator) TrackCDRFiles() (err error) {
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
@@ -173,7 +171,7 @@ func (self *Mediator) getCostsFromDB(cdr utils.CDR) (cc *rater.CallCost, err err
|
||||
// Retrive the cost from rater
|
||||
func (self *Mediator) getCostsFromRater(cdr utils.CDR) (*rater.CallCost, error) {
|
||||
cc := &rater.CallCost{}
|
||||
d, err := time.ParseDuration(strconv.FormatInt(cdr.GetDuration(),10) + "s")
|
||||
d, err := time.ParseDuration(strconv.FormatInt(cdr.GetDuration(), 10) + "s")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -193,7 +191,7 @@ func (self *Mediator) getCostsFromRater(cdr utils.CDR) (*rater.CallCost, error)
|
||||
Destination: cdr.GetDestination(),
|
||||
TimeStart: t1,
|
||||
TimeEnd: t1.Add(d)}
|
||||
if cdr.GetReqType()== utils.PSEUDOPREPAID {
|
||||
if cdr.GetReqType() == utils.PSEUDOPREPAID {
|
||||
err = self.connector.Debit(cd, cc)
|
||||
} else {
|
||||
err = self.connector.GetCost(cd, cc)
|
||||
@@ -207,7 +205,6 @@ func (self *Mediator) getCostsFromRater(cdr utils.CDR) (*rater.CallCost, error)
|
||||
return cc, nil
|
||||
}
|
||||
|
||||
|
||||
// Parse the files and get cost for every record
|
||||
func (self *Mediator) MediateCSVCDR(cdrfn string) (err error) {
|
||||
flag.Parse()
|
||||
@@ -230,29 +227,29 @@ func (self *Mediator) MediateCSVCDR(cdrfn string) (err error) {
|
||||
for record, ok := csvReader.Read(); ok == nil; record, ok = csvReader.Read() {
|
||||
//t, _ := time.Parse("2006-01-02 15:04:05", record[5])
|
||||
var cc *rater.CallCost
|
||||
|
||||
|
||||
for runIdx := range self.fieldIdxs["subject"] { // Query costs for every run index given by subject
|
||||
csvCDR, errCDR := NewFScsvCDR( record, self.accIdIdx,
|
||||
self.fieldIdxs["subject"][runIdx],
|
||||
self.fieldIdxs["reqtype"][runIdx],
|
||||
self.fieldIdxs["direction"][runIdx],
|
||||
self.fieldIdxs["tenant"][runIdx],
|
||||
self.fieldIdxs["tor"][runIdx],
|
||||
self.fieldIdxs["account"][runIdx],
|
||||
self.fieldIdxs["destination"][runIdx],
|
||||
self.fieldIdxs["answer_time"][runIdx],
|
||||
self.fieldIdxs["duration"][runIdx],
|
||||
self.cgrCfg)
|
||||
csvCDR, errCDR := NewFScsvCDR(record, self.accIdIdx,
|
||||
self.fieldIdxs["subject"][runIdx],
|
||||
self.fieldIdxs["reqtype"][runIdx],
|
||||
self.fieldIdxs["direction"][runIdx],
|
||||
self.fieldIdxs["tenant"][runIdx],
|
||||
self.fieldIdxs["tor"][runIdx],
|
||||
self.fieldIdxs["account"][runIdx],
|
||||
self.fieldIdxs["destination"][runIdx],
|
||||
self.fieldIdxs["answer_time"][runIdx],
|
||||
self.fieldIdxs["duration"][runIdx],
|
||||
self.cgrCfg)
|
||||
if errCDR != nil {
|
||||
rater.Logger.Err(fmt.Sprintf("<Mediator> Could not calculate price for accid: <%s>, err: <%s>",
|
||||
rater.Logger.Err(fmt.Sprintf("<Mediator> Could not calculate price for accid: <%s>, err: <%s>",
|
||||
record[self.accIdIdx], errCDR.Error()))
|
||||
}
|
||||
var errCost error
|
||||
if (csvCDR.GetReqType()==utils.PREPAID || csvCDR.GetReqType()==utils.POSTPAID){
|
||||
var errCost error
|
||||
if csvCDR.GetReqType() == utils.PREPAID || csvCDR.GetReqType() == utils.POSTPAID {
|
||||
// Should be previously calculated and stored in DB
|
||||
cc, errCost = self.getCostsFromDB( csvCDR )
|
||||
cc, errCost = self.getCostsFromDB(csvCDR)
|
||||
} else {
|
||||
cc, errCost = self.getCostsFromRater( csvCDR )
|
||||
cc, errCost = self.getCostsFromRater(csvCDR)
|
||||
}
|
||||
cost := "-1"
|
||||
if errCost != nil || cc == nil {
|
||||
@@ -271,12 +268,12 @@ func (self *Mediator) MediateCSVCDR(cdrfn string) (err error) {
|
||||
|
||||
func (self *Mediator) MediateDBCDR(cdr utils.CDR, db rater.DataStorage) error {
|
||||
var cc *rater.CallCost
|
||||
var errCost error
|
||||
if (cdr.GetReqType()==utils.PREPAID || cdr.GetReqType()==utils.POSTPAID){
|
||||
var errCost error
|
||||
if cdr.GetReqType() == utils.PREPAID || cdr.GetReqType() == utils.POSTPAID {
|
||||
// Should be previously calculated and stored in DB
|
||||
cc, errCost = self.getCostsFromDB( cdr )
|
||||
cc, errCost = self.getCostsFromDB(cdr)
|
||||
} else {
|
||||
cc, errCost = self.getCostsFromRater( cdr )
|
||||
cc, errCost = self.getCostsFromRater(cdr)
|
||||
}
|
||||
cost := "-1"
|
||||
if errCost != nil || cc == nil {
|
||||
@@ -287,4 +284,3 @@ func (self *Mediator) MediateDBCDR(cdr utils.CDR, db rater.DataStorage) error {
|
||||
}
|
||||
return self.storDb.SetRatedCdr(cdr, cc)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package mediator
|
||||
|
||||
import (
|
||||
//"testing"
|
||||
//"testing"
|
||||
)
|
||||
|
||||
/*
|
||||
|
||||
@@ -690,7 +690,6 @@ func TestActionResetCounterCREDIT(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func TestActionTriggerLogging(t *testing.T) {
|
||||
at := &ActionTrigger{
|
||||
Id: "some_uuid",
|
||||
|
||||
@@ -19,12 +19,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package rater
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Defines years days series
|
||||
@@ -73,7 +73,7 @@ func (ys *Years) Parse(input, sep string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (ys Years) Serialize( sep string ) string {
|
||||
func (ys Years) Serialize(sep string) string {
|
||||
if len(ys) == 0 {
|
||||
return "*all"
|
||||
}
|
||||
@@ -89,7 +89,7 @@ func (ys Years) Serialize( sep string ) string {
|
||||
}
|
||||
|
||||
var allMonths []time.Month = []time.Month{time.January, time.February, time.March, time.April, time.May, time.June,
|
||||
time.July, time.August, time.September, time.October, time.November, time.December}
|
||||
time.July, time.August, time.September, time.October, time.November, time.December}
|
||||
|
||||
// Defines months series
|
||||
type Months []time.Month
|
||||
@@ -141,11 +141,11 @@ func (m *Months) Parse(input, sep string) {
|
||||
}
|
||||
|
||||
// Dumps the months in a serialized string, similar to the one parsed
|
||||
func (m Months) Serialize( sep string ) string {
|
||||
func (m Months) Serialize(sep string) string {
|
||||
if len(m) == 0 {
|
||||
return "*none"
|
||||
}
|
||||
if reflect.DeepEqual( m, Months(allMonths) ) {
|
||||
if reflect.DeepEqual(m, Months(allMonths)) {
|
||||
return "*all"
|
||||
}
|
||||
var mStr string
|
||||
@@ -159,7 +159,6 @@ func (m Months) Serialize( sep string ) string {
|
||||
return mStr
|
||||
}
|
||||
|
||||
|
||||
var allMonthDays []int = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}
|
||||
|
||||
// Defines month days series
|
||||
@@ -211,7 +210,7 @@ func (md *MonthDays) Parse(input, sep string) {
|
||||
}
|
||||
|
||||
// Dumps the month days in a serialized string, similar to the one parsed
|
||||
func (md MonthDays) Serialize( sep string ) string {
|
||||
func (md MonthDays) Serialize(sep string) string {
|
||||
if len(md) == 0 {
|
||||
return "*none"
|
||||
}
|
||||
@@ -230,6 +229,7 @@ func (md MonthDays) Serialize( sep string ) string {
|
||||
}
|
||||
|
||||
var allWeekDays []time.Weekday = []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday, time.Saturday, time.Sunday}
|
||||
|
||||
// Defines week days series
|
||||
type WeekDays []time.Weekday
|
||||
|
||||
@@ -278,11 +278,11 @@ func (wd *WeekDays) Parse(input, sep string) {
|
||||
}
|
||||
|
||||
// Dumps the week days in a serialized string, similar to the one parsed
|
||||
func (wd WeekDays) Serialize( sep string ) string {
|
||||
func (wd WeekDays) Serialize(sep string) string {
|
||||
if len(wd) == 0 {
|
||||
return "*none"
|
||||
}
|
||||
if reflect.DeepEqual( wd, WeekDays(allWeekDays) ) {
|
||||
if reflect.DeepEqual(wd, WeekDays(allWeekDays)) {
|
||||
return "*all"
|
||||
}
|
||||
var wdStr string
|
||||
|
||||
@@ -77,7 +77,7 @@ func TestYearsSerialize(t *testing.T) {
|
||||
if expectString2 != yString2 {
|
||||
t.Errorf("Expected: %s, got: %s", expectString2, yString2)
|
||||
}
|
||||
ys3 := &Years{2013,2014,2015}
|
||||
ys3 := &Years{2013, 2014, 2015}
|
||||
yString3 := ys3.Serialize(";")
|
||||
expectString3 := "2013;2014;2015"
|
||||
if expectString3 != yString3 {
|
||||
@@ -104,7 +104,7 @@ func TestMonthsSerialize(t *testing.T) {
|
||||
if expectString2 != mString2 {
|
||||
t.Errorf("Expected: %s, got: %s", expectString2, mString2)
|
||||
}
|
||||
mths3 := &Months{time.January,time.December}
|
||||
mths3 := &Months{time.January, time.December}
|
||||
mString3 := mths3.Serialize(";")
|
||||
expectString3 := "1;12"
|
||||
if expectString3 != mString3 {
|
||||
@@ -131,7 +131,7 @@ func TestMonthDaysSerialize(t *testing.T) {
|
||||
if expectString2 != mdsString2 {
|
||||
t.Errorf("Expected: %s, got: %s", expectString2, mdsString2)
|
||||
}
|
||||
mds3 := &MonthDays{1,2,3,4,5}
|
||||
mds3 := &MonthDays{1, 2, 3, 4, 5}
|
||||
mdsString3 := mds3.Serialize(";")
|
||||
expectString3 := "1;2;3;4;5"
|
||||
if expectString3 != mdsString3 {
|
||||
@@ -158,11 +158,10 @@ func TestWeekDaysSerialize(t *testing.T) {
|
||||
if expectString2 != wdsString2 {
|
||||
t.Errorf("Expected: %s, got: %s", expectString2, wdsString2)
|
||||
}
|
||||
wds3 := &WeekDays{time.Monday, time.Saturday,time.Sunday}
|
||||
wds3 := &WeekDays{time.Monday, time.Saturday, time.Sunday}
|
||||
wdsString3 := wds3.Serialize(";")
|
||||
expectString3 := "1;6;0"
|
||||
if expectString3 != wdsString3 {
|
||||
t.Errorf("Expected: %s, got: %s", expectString3, wdsString3)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ type TPLoader interface {
|
||||
}
|
||||
|
||||
type Rate struct {
|
||||
Tag string
|
||||
Tag string
|
||||
ConnectFee, Price, PricedUnits, RateIncrements, Weight float64
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ func NewRate(tag, connectFee, price, pricedUnits, rateIncrements, weight string)
|
||||
Price: p,
|
||||
PricedUnits: pu,
|
||||
RateIncrements: ri,
|
||||
Weight: wght,
|
||||
Weight: wght,
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -92,7 +92,7 @@ type DestinationRate struct {
|
||||
}
|
||||
|
||||
type Timing struct {
|
||||
Id string
|
||||
Id string
|
||||
Years Years
|
||||
Months Months
|
||||
MonthDays MonthDays
|
||||
|
||||
@@ -148,8 +148,8 @@ func (ms *MongoStorage) SetDestination(dest *Destination) error {
|
||||
}
|
||||
|
||||
func (ms *MongoStorage) GetTPIds() ([]string, error) {
|
||||
return nil, errors.New(utils.ERR_NOT_IMPLEMENTED)
|
||||
}
|
||||
return nil, errors.New(utils.ERR_NOT_IMPLEMENTED)
|
||||
}
|
||||
|
||||
func (ms *MongoStorage) SetTPTiming(tpid string, tm *Timing) error {
|
||||
return errors.New(utils.ERR_NOT_IMPLEMENTED)
|
||||
|
||||
@@ -103,7 +103,7 @@ func (rs *RedisStorage) SetDestination(dest *Destination) (err error) {
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) GetTPIds() ([]string, error) {
|
||||
return nil, errors.New(utils.ERR_NOT_IMPLEMENTED)
|
||||
return nil, errors.New(utils.ERR_NOT_IMPLEMENTED)
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) SetTPTiming(tpid string, tm *Timing) error {
|
||||
|
||||
@@ -83,8 +83,8 @@ func (self *SQLStorage) GetTPIds() ([]string, error) {
|
||||
func (self *SQLStorage) SetTPTiming(tpid string, tm *Timing) error {
|
||||
if _, err := self.Db.Exec(fmt.Sprintf("INSERT INTO %s (tpid, tag, years, months, month_days, week_days, time) VALUES('%s','%s','%s','%s','%s','%s','%s')",
|
||||
utils.TBL_TP_TIMINGS, tpid, tm.Id, tm.Years.Serialize(";"), tm.Months.Serialize(";"), tm.MonthDays.Serialize(";"),
|
||||
tm.WeekDays.Serialize(";"), tm.StartTime )); err != nil {
|
||||
return err
|
||||
tm.WeekDays.Serialize(";"), tm.StartTime)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -100,15 +100,15 @@ func (self *SQLStorage) ExistsTPTiming(tpid, tmId string) (bool, error) {
|
||||
|
||||
func (self *SQLStorage) GetTPTiming(tpid, tmId string) (*Timing, error) {
|
||||
var years, months, monthDays, weekDays, time string
|
||||
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)
|
||||
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, nil
|
||||
case err != nil:
|
||||
return nil, err
|
||||
}
|
||||
return NewTiming( tmId, years, months, monthDays, weekDays, time ), nil
|
||||
return NewTiming(tmId, years, months, monthDays, weekDays, time), nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) GetTPTimingIds(tpid string) ([]string, error) {
|
||||
@@ -211,8 +211,8 @@ func (self *SQLStorage) ExistsTPRate(tpid, rtId string) (bool, error) {
|
||||
|
||||
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,
|
||||
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
|
||||
}
|
||||
@@ -226,7 +226,7 @@ func (self *SQLStorage) GetTPRate(tpid, rtId string) (*utils.TPRate, error) {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
rt := &utils.TPRate{TPid: tpid, RateId:rtId}
|
||||
rt := &utils.TPRate{TPid: tpid, RateId: rtId}
|
||||
i := 0
|
||||
for rows.Next() {
|
||||
i++ //Keep here a reference so we know we got at least one prefix
|
||||
|
||||
@@ -108,7 +108,7 @@ The interval will attach itself to the timespan that overlaps the interval.
|
||||
*/
|
||||
func (ts *TimeSpan) SplitByInterval(i *Interval) (nts *TimeSpan) {
|
||||
//Logger.Debug("here: ", ts, " +++ ", i)
|
||||
// if the span is not in interval return nil
|
||||
// if the span is not in interval return nil
|
||||
if !(i.Contains(ts.TimeStart) || i.Contains(ts.TimeEnd)) {
|
||||
//Logger.Debug("Not in interval")
|
||||
return
|
||||
|
||||
@@ -19,10 +19,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"encoding/hex"
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -20,17 +20,16 @@ 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
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
|
||||
package utils
|
||||
|
||||
// Converts map[string]string into map[string]interface{}
|
||||
|
||||
@@ -16,7 +16,6 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
|
||||
@@ -105,4 +105,3 @@ func UpdateStructWithStrMap(s interface{}, m map[string]string) []string {
|
||||
}
|
||||
return notMatched
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ func TestFirstNonEmpty(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestUUID(t *testing.T) {
|
||||
uuid := GenUUID()
|
||||
if len(uuid) == 0 {
|
||||
t.Fatalf("GenUUID error %s", uuid)
|
||||
}
|
||||
uuid := GenUUID()
|
||||
if len(uuid) == 0 {
|
||||
t.Fatalf("GenUUID error %s", uuid)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user