diff --git a/apier/v1/tpdestinationrates.go b/apier/v1/tpdestinationrates.go index 147d30b28..cdecc7151 100644 --- a/apier/v1/tpdestinationrates.go +++ b/apier/v1/tpdestinationrates.go @@ -31,11 +31,6 @@ func (self *ApierV1) SetTPDestinationRate(attrs utils.TPDestinationRate, reply * if missing := utils.MissingStructFields(&attrs, []string{"TPid", "DestinationRateId", "DestinationRates"}); len(missing) != 0 { return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) } - if exists, err := self.StorDb.ExistsTPDestinationRate(attrs.TPid, attrs.DestinationRateId); err != nil { - return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) - } else if exists { - return errors.New(utils.ERR_DUPLICATE) - } if err := self.StorDb.SetTPDestinationRates(attrs.TPid, map[string][]*utils.DestinationRate{attrs.DestinationRateId: attrs.DestinationRates}); err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } @@ -81,3 +76,16 @@ func (self *ApierV1) GetTPDestinationRateIds(attrs AttrGetTPRateIds, reply *[]st } return nil } + +// Removes specific DestinationRate on Tariff plan +func (self *ApierV1) RemTPDestinationRate(attrs AttrGetTPDestinationRate, reply *string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "DestinationRateId"}); len(missing) != 0 { //Params missing + return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) + } + if err := self.StorDb.RemTPData(utils.TBL_TP_DESTINATION_RATES, attrs.TPid, attrs.DestinationRateId); err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } else { + *reply = "OK" + } + return nil +} diff --git a/apier/v1/tpratingplans.go b/apier/v1/tpratingplans.go index 26b36cddd..c56069160 100644 --- a/apier/v1/tpratingplans.go +++ b/apier/v1/tpratingplans.go @@ -28,14 +28,9 @@ import ( // Creates a new DestinationRateTiming profile within a tariff plan func (self *ApierV1) SetTPRatingPlan(attrs utils.TPRatingPlan, reply *string) error { - if missing := utils.MissingStructFields(&attrs, []string{"TPid", "DestRateTimingId", "DestRateTimings"}); len(missing) != 0 { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RatingPlanId", "RatingPlans"}); len(missing) != 0 { return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) } - if exists, err := self.StorDb.ExistsTPRatingPlan(attrs.TPid, attrs.RatingPlanId); err != nil { - return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) - } else if exists { - return errors.New(utils.ERR_DUPLICATE) - } if err := self.StorDb.SetTPRatingPlans(attrs.TPid, map[string][]*utils.RatingPlan{attrs.RatingPlanId: attrs.RatingPlans}); err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } @@ -81,3 +76,16 @@ func (self *ApierV1) GetTPRatingPlanIds(attrs AttrGetTPRatingPlanIds, reply *[]s } return nil } + +// Removes specific RatingPlan on Tariff plan +func (self *ApierV1) RemTPRatingPlan(attrs AttrGetTPRatingPlan, reply *string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RatingPlanId"}); len(missing) != 0 { //Params missing + return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) + } + if err := self.StorDb.RemTPData(utils.TBL_TP_RATING_PLANS, attrs.TPid, attrs.RatingPlanId); err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } else { + *reply = "OK" + } + return nil +} diff --git a/apier/v1/tpratingprofiles.go b/apier/v1/tpratingprofiles.go index 4f76d6a2e..aa1e8dc79 100644 --- a/apier/v1/tpratingprofiles.go +++ b/apier/v1/tpratingprofiles.go @@ -28,15 +28,10 @@ import ( // Creates a new RatingProfile within a tariff plan func (self *ApierV1) SetTPRatingProfile(attrs utils.TPRatingProfile, reply *string) error { - if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RatingProfileId", "Tenant", "TOR", "Direction", "Subject", "RatingActivations"}); len(missing) != 0 { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RatingProfileId", "Tenant", "TOR", "Direction", "Subject", "RatingPlanActivations"}); len(missing) != 0 { return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) } - if exists, err := self.StorDb.ExistsTPRatingProfile(attrs.TPid, attrs.RatingProfileId); err != nil { - return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) - } else if exists { - return errors.New(utils.ERR_DUPLICATE) - } - if err := self.StorDb.SetTPRatingProfiles(attrs.TPid, map[string][]*utils.TPRatingProfile{attrs.RatingProfileId: []*utils.TPRatingProfile{&attrs}}); err != nil { + if err := self.StorDb.SetTPRatingProfiles(attrs.TPid, map[string]*utils.TPRatingProfile{attrs.RatingProfileId: &attrs}); err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } *reply = "OK" @@ -77,3 +72,17 @@ func (self *ApierV1) GetTPRatingProfileIds(attrs utils.AttrTPRatingProfileIds, r } return nil } + + +// Removes specific RatingProfile on Tariff plan +func (self *ApierV1) RemTPRatingProfile(attrs AttrGetTPRatingProfile, reply *string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RatingProfileId"}); len(missing) != 0 { //Params missing + return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) + } + if err := self.StorDb.RemTPData(utils.TBL_TP_RATE_PROFILES, attrs.TPid, attrs.RatingProfileId); err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } else { + *reply = "OK" + } + return nil +} diff --git a/data/storage/mysql/create_tariffplan_tables.sql b/data/storage/mysql/create_tariffplan_tables.sql index 3c1f70452..50db48d52 100644 --- a/data/storage/mysql/create_tariffplan_tables.sql +++ b/data/storage/mysql/create_tariffplan_tables.sql @@ -82,7 +82,7 @@ CREATE TABLE `tp_rating_plans` ( PRIMARY KEY (`id`), KEY `tpid` (`tpid`), KEY `tpid_tag` (`tpid`,`tag`), - UNIQUE KEY `tpid_tag_destrates_timings_weight` (`tpid`,`tag`,`destrates_tag`,`timing_tag`,`weight`) + UNIQUE KEY `tpid_tag_destrates_timings_weight` (`tpid`,`tag`,`destrates_tag`,`timing_tag`) ); -- @@ -99,7 +99,7 @@ CREATE TABLE `tp_rating_profiles` ( `subject` varchar(64) NOT NULL, `activation_time` varchar(24) NOT NULL, `rating_plan_tag` varchar(64) NOT NULL, - `fallback_subject` varchar(64), + `fallback_subjects` varchar(64), PRIMARY KEY (`id`), KEY `tpid_tag` (`tpid`, `tag`), UNIQUE KEY `tpid_tag_tenant_tor_dir_subj_atime` (`tpid`,`tag`, `tenant`,`tor`,`direction`,`subject`,`activation_time`) diff --git a/engine/loader_db.go b/engine/loader_db.go index 2def9b85e..042fe52f1 100644 --- a/engine/loader_db.go +++ b/engine/loader_db.go @@ -23,6 +23,7 @@ import ( "fmt" "github.com/cgrates/cgrates/utils" "log" + "strings" ) type DbReader struct { @@ -207,30 +208,32 @@ func (dbr *DbReader) LoadRatingPlans() error { } func (dbr *DbReader) LoadRatingProfiles() error { - rpfs, err := dbr.storDb.GetTpRatingProfiles(dbr.tpid, "") + mpTpRpfs, err := dbr.storDb.GetTpRatingProfiles(dbr.tpid, "") //map[string]*utils.TPRatingProfile if err != nil { return err } - for _, rp := range rpfs { - rpf := &RatingProfile{Id: rp.RatingProfileId} - at, err := utils.ParseDate(rp.ActivationTime) - if err != nil { - return errors.New(fmt.Sprintf("Cannot parse activation time from %v", rp.ActivationTime)) - } - _, exists := dbr.ratingPlans[rp.RatingPlanId] - if !exists { - if dbExists, err := dbr.dataDb.ExistsData(RATING_PLAN_PREFIX, rp.RatingPlanId); err != nil { - return err - } else if !dbExists { - return errors.New(fmt.Sprintf("Could not load rating plans for tag: %v", rp.RatingPlanId)) + for _, tpRpf := range mpTpRpfs { + rpf := &RatingProfile{Id: tpRpf.RatingProfileId} + for _, tpRa := range tpRpf.RatingPlanActivations { + at, err := utils.ParseDate(tpRa.ActivationTime) + if err != nil { + return errors.New(fmt.Sprintf("Cannot parse activation time from %v", tpRa.ActivationTime)) } + _, exists := dbr.ratingPlans[rpf.Id] + if !exists { + if dbExists, err := dbr.dataDb.ExistsData(RATING_PLAN_PREFIX, rpf.Id); err != nil { + return err + } else if !dbExists { + return errors.New(fmt.Sprintf("Could not load rating plans for tag: %v", rpf.Id)) + } + } + rpf.RatingPlanActivations = append(rpf.RatingPlanActivations, + &RatingPlanActivation{ + ActivationTime: at, + RatingPlanId: tpRa.RatingPlanId, + FallbackKeys: strings.Split(tpRa.FallbackSubjects,FALLBACK_SEP), + }) } - rpf.RatingPlanActivations = append(rpf.RatingPlanActivations, - &RatingPlanActivation{ - ActivationTime: at, - RatingPlanId: rp.RatingPlanId, - FallbackKeys: rp.FallbackKeys, - }) dbr.ratingProfiles[rpf.Id] = rpf } return nil @@ -287,27 +290,30 @@ func (dbr *DbReader) LoadRatingPlanByTag(tag string) error { func (dbr *DbReader) LoadRatingProfileByTag(tag string) error { resultRatingProfile := &RatingProfile{} - rpfs, err := dbr.storDb.GetTpRatingProfiles(dbr.tpid, tag) - if err != nil || len(rpfs) == 0 { + mpTpRpfs, err := dbr.storDb.GetTpRatingProfiles(dbr.tpid, tag) //map[string]*utils.TPRatingProfile + if err != nil || len(mpTpRpfs) == 0 { return fmt.Errorf("No RateProfile with id %s: %v", tag, err) } - for _, rp := range rpfs { - Logger.Debug(fmt.Sprintf("Rating profile: %v", rpfs)) - resultRatingProfile.Id = rp.RatingProfileId - at, err := utils.ParseDate(rp.ActivationTime) - if err != nil { - return fmt.Errorf("Cannot parse activation time from %v", rp.ActivationTime) - } - // Check if referenced RatingPlan exists - _, exists := dbr.ratingPlans[rp.RatingPlanId] - if !exists { - if dbExists, err := dbr.dataDb.ExistsData(RATING_PLAN_PREFIX, rp.RatingPlanId); err != nil { - return err - } else if !dbExists { - return errors.New(fmt.Sprintf("Could not load rating plans for tag: %v", rp.RatingPlanId)) + for _, tpRpf := range mpTpRpfs { + Logger.Debug(fmt.Sprintf("Rating profile: %v", tpRpf)) + resultRatingProfile.Id = tpRpf.RatingProfileId + /// + for _, tpRa := range tpRpf.RatingPlanActivations { + at, err := utils.ParseDate(tpRa.ActivationTime) + if err != nil { + return errors.New(fmt.Sprintf("Cannot parse activation time from %v", tpRa.ActivationTime)) } + _, exists := dbr.ratingPlans[resultRatingProfile.Id] + if !exists { + if dbExists, err := dbr.dataDb.ExistsData(RATING_PLAN_PREFIX, resultRatingProfile.Id); err != nil { + return err + } else if !dbExists { + return errors.New(fmt.Sprintf("Could not load rating plans for tag: %v", resultRatingProfile.Id)) + } + } + resultRatingProfile.RatingPlanActivations = append(resultRatingProfile.RatingPlanActivations, + &RatingPlanActivation{at, tpRa.RatingPlanId, strings.Split(tpRa.FallbackSubjects,FALLBACK_SEP)}) } - resultRatingProfile.RatingPlanActivations = append(resultRatingProfile.RatingPlanActivations, &RatingPlanActivation{at, rp.RatingPlanId, rp.FallbackKeys}) } return dbr.dataDb.SetRatingProfile(resultRatingProfile) } diff --git a/engine/storage_interface.go b/engine/storage_interface.go index 17c61e262..6869f3db2 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -123,7 +123,7 @@ type LoadStorage interface { GetTPRatingPlan(string, string) (*utils.TPRatingPlan, error) GetTPRatingPlanIds(string) ([]string, error) ExistsTPRatingProfile(string, string) (bool, error) - SetTPRatingProfiles(string, map[string][]*utils.TPRatingProfile) error + SetTPRatingProfiles(string, map[string]*utils.TPRatingProfile) error GetTPRatingProfile(string, string) (*utils.TPRatingProfile, error) GetTPRatingProfileIds(*utils.AttrTPRatingProfileIds) ([]string, error) ExistsTPActions(string, string) (bool, error) diff --git a/engine/storage_sql.go b/engine/storage_sql.go index 6b4ae3430..99d0fcad0 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -23,7 +23,6 @@ import ( "encoding/json" "fmt" "github.com/cgrates/cgrates/utils" - "strings" "time" ) @@ -302,18 +301,19 @@ func (self *SQLStorage) SetTPDestinationRates(tpid string, drs map[string][]*uti if len(drs) == 0 { return nil //Nothing to set } - qry := fmt.Sprintf("INSERT INTO %s (tpid, tag, destinations_tag, rates_tag) VALUES ", utils.TBL_TP_DESTINATION_RATES) + vals := "" i := 0 for drId, drRows := range drs { for _, dr := range drRows { if i != 0 { //Consecutive values after the first will be prefixed with "," as separator - qry += "," + vals += "," } - qry += fmt.Sprintf("('%s','%s','%s','%s')", + vals += fmt.Sprintf("('%s','%s','%s','%s')", tpid, drId, dr.DestinationId, dr.RateId) i++ } } + qry := fmt.Sprintf("INSERT INTO %s (tpid,tag,destinations_tag,rates_tag) VALUES %s ON DUPLICATE KEY UPDATE destinations_tag=values(destinations_tag),rates_tag=values(rates_tag)", utils.TBL_TP_DESTINATION_RATES, vals) if _, err := self.Db.Exec(qry); err != nil { return err } @@ -379,18 +379,19 @@ func (self *SQLStorage) SetTPRatingPlans(tpid string, drts map[string][]*utils.R if len(drts) == 0 { return nil //Nothing to set } - qry := fmt.Sprintf("INSERT INTO %s (tpid, tag, destrates_tag, timing_tag, weight) VALUES ", utils.TBL_TP_RATING_PLANS) + vals := "" i := 0 for drtId, drtRows := range drts { for _, drt := range drtRows { if i != 0 { //Consecutive values after the first will be prefixed with "," as separator - qry += "," + vals += "," } - qry += fmt.Sprintf("('%s','%s','%s','%s',%f)", + vals += fmt.Sprintf("('%s','%s','%s','%s',%f)", tpid, drtId, drt.DestinationRatesId, drt.TimingId, drt.Weight) i++ } } + qry := fmt.Sprintf("INSERT INTO %s (tpid, tag, destrates_tag, timing_tag, weight) VALUES %s ON DUPLICATE KEY UPDATE weight=values(weight)", utils.TBL_TP_RATING_PLANS, vals) if _, err := self.Db.Exec(qry); err != nil { return err } @@ -453,24 +454,23 @@ func (self *SQLStorage) ExistsTPRatingProfile(tpid, rpId string) (bool, error) { return exists, nil } -func (self *SQLStorage) SetTPRatingProfiles(tpid string, rps map[string][]*utils.TPRatingProfile) error { +func (self *SQLStorage) SetTPRatingProfiles(tpid string, rps map[string]*utils.TPRatingProfile) error { if len(rps) == 0 { return nil //Nothing to set } - qry := fmt.Sprintf("INSERT INTO %s (tpid,tag,tenant,tor,direction,subject,activation_time,rating_plan_tag,fallback_subject) VALUES ", - utils.TBL_TP_RATE_PROFILES) + vals := "" i := 0 - for rpId, rp := range rps { - for _, rpa := range rp { + for _, rp := range rps { + for _, rpa := range rp.RatingPlanActivations { if i != 0 { //Consecutive values after the first will be prefixed with "," as separator - qry += "," + vals += "," } - qry += fmt.Sprintf("('%s', '%s', '%s', '%s', '%s', '%s', '%s','%s','%s')", tpid, rpId, rpa.Tenant, rpa.TOR, rpa.Direction, - rpa.Subject, rpa.ActivationTime, rpa.RatingPlanId, rpa.FallbackKeys) + vals += fmt.Sprintf("('%s', '%s', '%s', '%s', '%s', '%s', '%s','%s','%s')", tpid, rp.RatingProfileId, rp.Tenant, rp.TOR, rp.Direction, + rp.Subject, rpa.ActivationTime, rpa.RatingPlanId, rpa.FallbackSubjects) i++ } - } + qry := fmt.Sprintf("INSERT INTO %s (tpid,tag,tenant,tor,direction,subject,activation_time,rating_plan_tag,fallback_subjects) VALUES %s ON DUPLICATE KEY UPDATE fallback_subjects=values(fallback_subjects)", utils.TBL_TP_RATE_PROFILES, vals) if _, err := self.Db.Exec(qry); err != nil { return err } @@ -478,7 +478,7 @@ func (self *SQLStorage) SetTPRatingProfiles(tpid string, rps map[string][]*utils } func (self *SQLStorage) GetTPRatingProfile(tpid, rpId string) (*utils.TPRatingProfile, error) { - rows, err := self.Db.Query(fmt.Sprintf("SELECT tenant,tor,direction,subject,activation_time,rating_plan_tag,fallback_subject FROM %s WHERE tpid='%s' AND tag='%s'", utils.TBL_TP_RATE_PROFILES, tpid, rpId)) + rows, err := self.Db.Query(fmt.Sprintf("SELECT tenant,tor,direction,subject,activation_time,rating_plan_tag,fallback_subjects FROM %s WHERE tpid='%s' AND tag='%s'", utils.TBL_TP_RATE_PROFILES, tpid, rpId)) if err != nil { return nil, err } @@ -497,9 +497,8 @@ func (self *SQLStorage) GetTPRatingProfile(tpid, rpId string) (*utils.TPRatingPr rp.TOR = tor rp.Direction = direction rp.Subject = subject - rp.FallbackKeys = strings.Split(fallbackSubj, FALLBACK_SEP) } - rp.RatingPlanActivations = append(rp.RatingPlanActivations, &utils.RatingActivation{aTime, drtId}) + rp.RatingPlanActivations = append(rp.RatingPlanActivations, &utils.TPRatingActivation{aTime, drtId, fallbackSubj}) } if i == 0 { return nil, nil @@ -1113,7 +1112,7 @@ func (self *SQLStorage) GetTpRatingPlans(tpid, tag string) (*utils.TPRatingPlan, func (self *SQLStorage) GetTpRatingProfiles(tpid, tag string) (map[string]*utils.TPRatingProfile, error) { rpfs := make(map[string]*utils.TPRatingProfile) - q := fmt.Sprintf("SELECT tag,tenant,tor,direction,subject,activation_time,rating_plan_tag,fallback_subject FROM %s WHERE tpid='%s'", + q := fmt.Sprintf("SELECT tag,tenant,tor,direction,subject,activation_time,rating_plan_tag,fallback_subjects FROM %s WHERE tpid='%s'", utils.TBL_TP_RATE_PROFILES, tpid) if tag != "" { q += fmt.Sprintf(" AND tag='%s'", tag) @@ -1124,26 +1123,17 @@ func (self *SQLStorage) GetTpRatingProfiles(tpid, tag string) (map[string]*utils } defer rows.Close() for rows.Next() { - var tag, tenant, tor, direction, subject, fallback_subject, rating_plan_tag, activation_time string - if err := rows.Scan(&tag, &tenant, &tor, &direction, &subject, &activation_time, &rating_plan_tag, &fallback_subject); err != nil { + var rcvTag, tenant, tor, direction, subject, fallback_subjects, rating_plan_tag, activation_time string + if err := rows.Scan(&rcvTag, &tenant, &tor, &direction, &subject, &activation_time, &rating_plan_tag, &fallback_subjects); err != nil { return nil, err } - key := fmt.Sprintf("%s:%s:%s:%s", direction, tenant, tor, subject) - rp, ok := rpfs[key] - if !ok || rp.RatingProfileId != tag { - rp = &utils.TPRatingProfile{RatingProfileId: key, Tag: tag} - rpfs[key] = rp - } - rp.RatingPlanId = rating_plan_tag - rp.ActivationTime = activation_time - if fallback_subject != "" { - for _, fbs := range strings.Split(fallback_subject, ";") { - newKey := fmt.Sprintf("%s:%s:%s:%s", direction, tenant, tor, fbs) - var sslice utils.StringSlice = rp.FallbackKeys - if !sslice.Contains(newKey) { - rp.FallbackKeys = append(rp.FallbackKeys, newKey) - } - } + if _,ok := rpfs[rcvTag]; !ok { + rpfs[rcvTag] = &utils.TPRatingProfile{TPid: tpid, RatingProfileId: rcvTag, Tenant: tenant, TOR: tor, Direction:direction, Subject:subject, + RatingPlanActivations: []*utils.TPRatingActivation{ + &utils.TPRatingActivation{ActivationTime:activation_time, RatingPlanId:rating_plan_tag, FallbackSubjects:fallback_subjects}}} + } else { + rpfs[rcvTag].RatingPlanActivations = append( rpfs[rcvTag].RatingPlanActivations, + &utils.TPRatingActivation{ActivationTime:activation_time, RatingPlanId:rating_plan_tag, FallbackSubjects:fallback_subjects} ) } } return rpfs, nil diff --git a/engine/tpimporter_csv.go b/engine/tpimporter_csv.go index a2cf67438..2052c313b 100644 --- a/engine/tpimporter_csv.go +++ b/engine/tpimporter_csv.go @@ -24,7 +24,6 @@ import ( "io/ioutil" "log" "strconv" - "strings" ) // Import tariff plan from csv into storDb @@ -245,7 +244,7 @@ func (self *TPCSVImporter) importRatingProfiles(fn string) error { } continue } - tenant, tor, direction, subject, destRatesTimingTag, fallbacksubject := record[0], record[1], record[2], record[3], record[5], record[6] + tenant, tor, direction, subject, ratingPlanTag, fallbacksubject := record[0], record[1], record[2], record[3], record[5], record[6] _, err = utils.ParseDate(record[4]) if err != nil { if self.Verbose { @@ -258,16 +257,15 @@ func (self *TPCSVImporter) importRatingProfiles(fn string) error { rpTag += "_" + self.ImportId } rp := &utils.TPRatingProfile{ - Tag: rpTag, + RatingProfileId:rpTag, Tenant: tenant, TOR: tor, Direction: direction, Subject: subject, - ActivationTime: record[4], - RatingPlanId: destRatesTimingTag, - FallbackKeys: strings.Split(fallbacksubject, FALLBACK_SEP), + RatingPlanActivations: []*utils.TPRatingActivation{ + &utils.TPRatingActivation{ ActivationTime: record[4], RatingPlanId: ratingPlanTag, FallbackSubjects: fallbacksubject}}, } - if err := self.StorDb.SetTPRatingProfiles(self.TPid, map[string][]*utils.TPRatingProfile{rpTag: []*utils.TPRatingProfile{rp}}); err != nil { + if err := self.StorDb.SetTPRatingProfiles(self.TPid, map[string]*utils.TPRatingProfile{rpTag: rp}); err != nil { if self.Verbose { log.Printf("Ignoring line %d, storDb operational error: <%s> ", lineNr, err.Error()) } diff --git a/utils/apitpdata.go b/utils/apitpdata.go index 811612add..b5622b403 100644 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -123,22 +123,18 @@ func(self *RatingPlan) Timing() *TPTiming { type TPRatingProfile struct { TPid string // Tariff plan id - Tag string RatingProfileId string // RatingProfile id - RatingPlanId string Tenant string // Tenant's Id TOR string // TypeOfRecord Direction string // Traffic direction, OUT is the only one supported for now Subject string // Rating subject, usually the same as account - FallbackKeys []string // Fallback on this subject if rates not found for destination - ActivationTime string - RatingPlanActivations []*RatingActivation // Activate rate profiles at specific time + RatingPlanActivations []*TPRatingActivation // Activate rate profiles at specific time } -type RatingActivation struct { +type TPRatingActivation struct { ActivationTime string // Time when this profile will become active, defined as unix epoch time - DestRateTimingId string // Id of DestRateTiming profile - // FallbackKeys []string + RatingPlanId string // Id of RatingPlan profile + FallbackSubjects string // So we follow the api } type AttrTPRatingProfileIds struct {