diff --git a/apier/tpaccountactions.go b/apier/tpaccountactions.go index 8d06a9fad..aefb74753 100644 --- a/apier/tpaccountactions.go +++ b/apier/tpaccountactions.go @@ -22,6 +22,7 @@ import ( "errors" "fmt" + "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" ) @@ -38,13 +39,13 @@ func (self *ApierV1) SetTPAccountActions(attrs utils.TPAccountActions, reply *st return nil } -type AttrGetTPAccountActions struct { +type AttrGetTPAccountActionsByLoadId struct { TPid string // Tariff plan id LoadId string // AccountActions id } // Queries specific AccountActions profile on tariff plan -func (self *ApierV1) GetTPAccountActions(attrs utils.TPAccountActions, reply *[]*utils.TPAccountActions) error { +func (self *ApierV1) GetTPAccountActionsByLoadId(attrs utils.TPAccountActions, reply *[]*utils.TPAccountActions) error { mndtryFlds := []string{"TPid", "LoadId"} if len(attrs.Account) != 0 { // If account provided as filter, make all related fields mandatory mndtryFlds = append(mndtryFlds, "Tenant", "Account", "Direction") @@ -70,6 +71,39 @@ func (self *ApierV1) GetTPAccountActions(attrs utils.TPAccountActions, reply *[] return nil } +type AttrGetTPAccountActions struct { + TPid string // Tariff plan id + AccountActionsId string // DerivedCharge id +} + +// Queries specific DerivedCharge on tariff plan +func (self *ApierV1) GetTPAccountActions(attrs AttrGetTPAccountActions, reply *utils.TPAccountActions) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "AccountActionsId"}); len(missing) != 0 { //Params missing + return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) + } + tmpAa := &utils.TPAccountActions{TPid: attrs.TPid} + if err := tmpAa.SetAccountActionsId(attrs.AccountActionsId); err != nil { + return err + } + if aas, err := self.StorDb.GetTpAccountActions(tmpAa); err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } else if len(aas) == 0 { + return errors.New(utils.ERR_NOT_FOUND) + } else { + aa := aas[tmpAa.KeyId()] + tpdc := utils.TPAccountActions{ + TPid: attrs.TPid, + ActionPlanId: aa.ActionPlanId, + ActionTriggersId: aa.ActionTriggersId, + } + if err := tpdc.SetAccountActionsId(attrs.AccountActionsId); err != nil { + return err + } + *reply = tpdc + } + return nil +} + type AttrGetTPAccountActionIds struct { TPid string // Tariff plan id } @@ -89,12 +123,31 @@ func (self *ApierV1) GetTPAccountActionLoadIds(attrs AttrGetTPAccountActionIds, return nil } +// Queries DerivedCharges identities on specific tariff plan. +func (self *ApierV1) GetTPAccountActionIds(attrs AttrGetTPAccountActionIds, reply *[]string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid"}); len(missing) != 0 { //Params missing + return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) + } + if ids, err := self.StorDb.GetTPTableIds(attrs.TPid, utils.TBL_TP_ACCOUNT_ACTIONS, utils.TPDistinctIds{"loadid", "direction", "tenant", "account"}, nil); err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } else if ids == nil { + return errors.New(utils.ERR_NOT_FOUND) + } else { + *reply = ids + } + return nil +} + // Removes specific AccountActions on Tariff plan -func (self *ApierV1) RemTPAccountActions(attrs utils.TPAccountActions, reply *string) error { +func (self *ApierV1) RemTPAccountActions(attrs AttrGetTPAccountActions, reply *string) error { if missing := utils.MissingStructFields(&attrs, []string{"TPid", "LoadId", "Tenant", "Account", "Direction"}); len(missing) != 0 { //Params missing return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) } - if err := self.StorDb.RemTPData(utils.TBL_TP_ACCOUNT_ACTIONS, attrs.TPid, attrs.LoadId, attrs.Tenant, attrs.Account, attrs.Direction); err != nil { + aa := engine.TpAccountAction{Tpid: attrs.TPid} + if err := aa.SetAccountActionId(attrs.AccountActionsId); err != nil { + return err + } + if err := self.StorDb.RemTPData(utils.TBL_TP_ACCOUNT_ACTIONS, aa.Tpid, aa.Loadid, aa.Tenant, aa.Account, aa.Direction); err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } else { *reply = "OK" diff --git a/apier/tpderivedcharges.go b/apier/tpderivedcharges.go index 525abda09..b2132375d 100644 --- a/apier/tpderivedcharges.go +++ b/apier/tpderivedcharges.go @@ -22,6 +22,7 @@ import ( "errors" "fmt" + "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" ) @@ -58,7 +59,11 @@ func (self *ApierV1) GetTPDerivedChargers(attrs AttrGetTPDerivedChargers, reply if missing := utils.MissingStructFields(&attrs, []string{"TPid", "DerivedChargersId"}); len(missing) != 0 { //Params missing return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) } - if sgs, err := self.StorDb.GetTpDerivedChargers(attrs.TPid, attrs.DerivedChargersId); err != nil { + tmpDc := &utils.TPDerivedChargers{TPid: attrs.TPid} + if err := tmpDc.SetDerivedChargersId(attrs.DerivedChargersId); err != nil { + return err + } + if sgs, err := self.StorDb.GetTpDerivedChargers(tmpDc); err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } else if len(sgs) == 0 { return errors.New(utils.ERR_NOT_FOUND) @@ -84,7 +89,7 @@ func (self *ApierV1) GetTPDerivedChargerIds(attrs AttrGetTPDerivedChargeIds, rep if missing := utils.MissingStructFields(&attrs, []string{"TPid"}); len(missing) != 0 { //Params missing return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) } - if ids, err := self.StorDb.GetTPTableIds(attrs.TPid, utils.TBL_TP_DERIVED_CHARGERS, utils.TPDistinctIds{"direction", "tenant", "category", "account", "subject", "loadid"}, nil); err != nil { + if ids, err := self.StorDb.GetTPTableIds(attrs.TPid, utils.TBL_TP_DERIVED_CHARGERS, utils.TPDistinctIds{"loadid", "direction", "tenant", "category", "account", "subject"}, nil); err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } else if ids == nil { return errors.New(utils.ERR_NOT_FOUND) @@ -99,7 +104,11 @@ func (self *ApierV1) RemTPDerivedChargers(attrs AttrGetTPDerivedChargers, reply if missing := utils.MissingStructFields(&attrs, []string{"TPid", "DerivedChargesId"}); len(missing) != 0 { //Params missing return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) } - if err := self.StorDb.RemTPData(utils.TBL_TP_DERIVED_CHARGERS, attrs.TPid, attrs.DerivedChargersId); err != nil { + tmpDc := engine.TpDerivedCharger{} + if err := tmpDc.SetDerivedChargersId(attrs.DerivedChargersId); err != nil { + return err + } + if err := self.StorDb.RemTPData(utils.TBL_TP_DERIVED_CHARGERS, attrs.TPid, tmpDc.Loadid, tmpDc.Direction, tmpDc.Tenant, tmpDc.Category, tmpDc.Account, tmpDc.Subject); err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } else { *reply = "OK" diff --git a/data/storage/mysql/create_tariffplan_tables.sql b/data/storage/mysql/create_tariffplan_tables.sql index 394ad254f..8cd7eaabc 100644 --- a/data/storage/mysql/create_tariffplan_tables.sql +++ b/data/storage/mysql/create_tariffplan_tables.sql @@ -42,8 +42,8 @@ CREATE TABLE `tp_rates` ( `tbid` int(11) NOT NULL AUTO_INCREMENT, `tpid` varchar(64) NOT NULL, `id` varchar(64) NOT NULL, - `connect_fee` decimal(5,4) NOT NULL, - `rate` DECIMAL(5,4) NOT NULL, + `connect_fee` decimal(7,4) NOT NULL, + `rate` decimal(7,4) NOT NULL, `rate_unit` varchar(16) NOT NULL, `rate_increment` varchar(16) NOT NULL, `group_interval_start` varchar(16) NOT NULL, diff --git a/engine/models.go b/engine/models.go index 9b90f527b..5c95b2321 100644 --- a/engine/models.go +++ b/engine/models.go @@ -138,6 +138,29 @@ type TpActionTrigger struct { Weight float64 } +type TpAccountAction struct { + Tbid int64 `gorm:"primary_key:yes"` + Tpid string + Loadid string + Direction string + Tenant string + Account string + ActionPlanId string + ActionTriggersId string +} + +func (aa *TpAccountAction) SetAccountActionId(id string) error { + ids := strings.Split(id, utils.TP_ID_SEP) + if len(ids) != 4 { + return fmt.Errorf("Wrong TP Account Action Id!") + } + aa.Loadid = ids[0] + aa.Direction = ids[1] + aa.Tenant = ids[2] + aa.Account = ids[3] + return nil +} + type TpSharedGroup struct { Tbid int64 `gorm:"primary_key:yes"` Tpid string @@ -173,14 +196,14 @@ type TpDerivedCharger struct { func (tpdc *TpDerivedCharger) SetDerivedChargersId(id string) error { ids := strings.Split(id, utils.TP_ID_SEP) if len(ids) != 6 { - return fmt.Errorf("Wrong TP Derived Charge Id!") + return fmt.Errorf("Wrong TP Derived Charger Id: %s", id) } - tpdc.Direction = ids[0] - tpdc.Tenant = ids[1] - tpdc.Category = ids[2] - tpdc.Account = ids[3] - tpdc.Subject = ids[4] - tpdc.Loadid = ids[5] + tpdc.Loadid = ids[0] + tpdc.Direction = ids[1] + tpdc.Tenant = ids[2] + tpdc.Category = ids[3] + tpdc.Account = ids[4] + tpdc.Subject = ids[5] return nil } diff --git a/engine/storage_interface.go b/engine/storage_interface.go index 3af698efb..9247d1d19 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -163,7 +163,7 @@ type LoadStorage interface { GetTpCdrStats(string, string) (map[string][]*utils.TPCdrStat, error) SetTPDerivedChargers(string, map[string][]*utils.TPDerivedCharger) error - GetTpDerivedChargers(string, string) (map[string][]*utils.TPDerivedCharger, error) + GetTpDerivedChargers(*utils.TPDerivedChargers) (map[string][]*utils.TPDerivedCharger, error) SetTPLCRs(string, map[string]*LCR) error GetTpLCRs(string, string) (map[string]*LCR, error) diff --git a/engine/storage_sql.go b/engine/storage_sql.go index a47a2a172..8cab8a8fb 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -168,6 +168,9 @@ func (self *SQLStorage) RemTPData(table, tpid string, args ...string) error { case utils.TBL_TP_ACCOUNT_ACTIONS: q = fmt.Sprintf("DELETE FROM %s WHERE tpid='%s' AND loadid='%s' AND tenant='%s' AND account='%s' AND direction='%s'", table, tpid, args[0], args[1], args[2], args[3]) + case utils.TBL_TP_DERIVED_CHARGERS: + q = fmt.Sprintf("DELETE FROM %s WHERE tpid='%s' AND loadid='%s' AND direction='%s' AND tenant='%s' AND category='%s' AND account='%s' AND subject='%s'", + table, tpid, args[0], args[1], args[2], args[3], args[4], args[5]) } if _, err := self.Db.Exec(q); err != nil { return err @@ -561,26 +564,33 @@ func (self *SQLStorage) SetTPActionTriggers(tpid string, ats map[string][]*utils } // Sets a group of account actions. Map key has the role of grouping within a tpid -func (self *SQLStorage) SetTPAccountActions(tpid string, aa map[string]*utils.TPAccountActions) error { - if len(aa) == 0 { +func (self *SQLStorage) SetTPAccountActions(tpid string, aas map[string]*utils.TPAccountActions) error { + if len(aas) == 0 { return nil //Nothing to set } - var buffer bytes.Buffer - buffer.WriteString(fmt.Sprintf("INSERT INTO %s (tpid, loadid, tenant, account, direction, action_plan_id, action_triggers_id) VALUES ", utils.TBL_TP_ACCOUNT_ACTIONS)) - i := 0 - for _, aActs := range aa { - if i != 0 { //Consecutive values after the first will be prefixed with "," as separator - buffer.WriteRune(',') - } - buffer.WriteString(fmt.Sprintf("('%s','%s','%s','%s','%s','%s','%s')", - tpid, aActs.LoadId, aActs.Tenant, aActs.Account, aActs.Direction, aActs.ActionPlanId, aActs.ActionTriggersId)) - i++ - } - buffer.WriteString(" ON DUPLICATE KEY UPDATE action_plan_id=values(action_plan_id), action_triggers_id=values(action_triggers_id)") - if _, err := self.Db.Exec(buffer.String()); err != nil { - return err + tx := self.db.Begin() + for _, aa := range aas { + // parse identifiers + tx.Where("tpid = ?", tpid). + Where("direction = ?", aa.Direction). + Where("tenant = ?", aa.Tenant). + Where("account = ?", aa.Account). + Where("loadid = ?", aa.LoadId). + Delete(TpAccountAction{}) + + tx.Save(TpAccountAction{ + Tpid: aa.TPid, + Loadid: aa.LoadId, + Tenant: aa.Tenant, + Account: aa.Account, + Direction: aa.Direction, + ActionPlanId: aa.ActionPlanId, + ActionTriggersId: aa.ActionTriggersId, + }) } + tx.Commit() return nil + } func (self *SQLStorage) LogCallCost(cgrid, source, runid string, cc *CallCost) (err error) { @@ -1331,29 +1341,33 @@ func (self *SQLStorage) GetTpCdrStats(tpid, tag string) (map[string][]*utils.TPC return css, nil } -func (self *SQLStorage) GetTpDerivedChargers(tpid, tag string) (map[string][]*utils.TPDerivedCharger, error) { +func (self *SQLStorage) GetTpDerivedChargers(dc *utils.TPDerivedChargers) (map[string][]*utils.TPDerivedCharger, error) { dcs := make(map[string][]*utils.TPDerivedCharger) var tpDerivedChargers []TpDerivedCharger - q := self.db.Where("tpid = ?", tpid) - if len(tag) != 0 { - // parse identifiers - tmpDc := TpDerivedCharger{} - if err := tmpDc.SetDerivedChargersId(tag); err != nil { - return nil, err - } - q = q.Where("tpid = ?", tpid). - Where("direction = ?", tmpDc.Direction). - Where("tenant = ?", tmpDc.Tenant). - Where("account = ?", tmpDc.Account). - Where("category = ?", tmpDc.Category). - Where("subject = ?", tmpDc.Subject). - Where("loadid = ?", tmpDc.Loadid) + q := self.db.Where("tpid = ?", dc.TPid) + if len(dc.Direction) != 0 { + q = q.Where("direction = ?", dc.Direction) + } + if len(dc.Tenant) != 0 { + q = q.Where("tenant = ?", dc.Tenant) + } + if len(dc.Account) != 0 { + q = q.Where("account = ?", dc.Account) + } + if len(dc.Category) != 0 { + q = q.Where("category = ?", dc.Category) + } + if len(dc.Subject) != 0 { + q = q.Where("subject = ?", dc.Subject) + } + if len(dc.Loadid) != 0 { + q = q.Where("loadid = ?", dc.Loadid) } if err := q.Find(&tpDerivedChargers).Error; err != nil { return nil, err } - + tag := dc.GetDerivedChargesId() for _, tpDc := range tpDerivedChargers { dcs[tag] = append(dcs[tag], &utils.TPDerivedCharger{ RunId: tpDc.RunId, @@ -1494,40 +1508,35 @@ func (self *SQLStorage) GetTpActionTriggers(tpid, tag string) (map[string][]*uti } func (self *SQLStorage) GetTpAccountActions(aaFltr *utils.TPAccountActions) (map[string]*utils.TPAccountActions, error) { - q := fmt.Sprintf("SELECT loadid, tenant, account, direction, action_plan_id, action_triggers_id FROM %s WHERE tpid='%s'", utils.TBL_TP_ACCOUNT_ACTIONS, aaFltr.TPid) - if len(aaFltr.LoadId) != 0 { - q += fmt.Sprintf(" AND loadid='%s'", aaFltr.LoadId) + aas := make(map[string]*utils.TPAccountActions) + var tpAccActs []TpAccountAction + q := self.db.Where("tpid = ?", aaFltr.TPid) + if len(aaFltr.Direction) != 0 { + q = q.Where("direction = ?", aaFltr.Direction) } if len(aaFltr.Tenant) != 0 { - q += fmt.Sprintf(" AND tenant='%s'", aaFltr.Tenant) + q = q.Where("tenant = ?", aaFltr.Tenant) } if len(aaFltr.Account) != 0 { - q += fmt.Sprintf(" AND account='%s'", aaFltr.Account) + q = q.Where("account = ?", aaFltr.Account) } - if len(aaFltr.Direction) != 0 { - q += fmt.Sprintf(" AND direction='%s'", aaFltr.Direction) + if len(aaFltr.LoadId) != 0 { + q = q.Where("loadid = ?", aaFltr.LoadId) } - rows, err := self.Db.Query(q) - if err != nil { + if err := q.Find(&tpAccActs).Error; err != nil { return nil, err } - defer rows.Close() - aa := make(map[string]*utils.TPAccountActions) - for rows.Next() { - var aaLoadId, tenant, account, direction, action_plan_tag, action_triggers_tag string - if err := rows.Scan(&aaLoadId, &tenant, &account, &direction, &action_plan_tag, &action_triggers_tag); err != nil { - return nil, err - } + for _, tpAa := range tpAccActs { aacts := &utils.TPAccountActions{ - TPid: aaFltr.TPid, - LoadId: aaLoadId, - Tenant: tenant, - Account: account, - Direction: direction, - ActionPlanId: action_plan_tag, - ActionTriggersId: action_triggers_tag, + TPid: tpAa.Tpid, + LoadId: tpAa.Loadid, + Tenant: tpAa.Tenant, + Account: tpAa.Account, + Direction: tpAa.Direction, + ActionPlanId: tpAa.ActionPlanId, + ActionTriggersId: tpAa.ActionTriggersId, } - aa[aacts.KeyId()] = aacts + aas[aacts.KeyId()] = aacts } - return aa, nil + return aas, nil } diff --git a/utils/apitpdata.go b/utils/apitpdata.go index 5f5e3a75d..dca7cf53c 100644 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -300,7 +300,9 @@ type TPDerivedChargers struct { } func (tpdc TPDerivedChargers) GetDerivedChargesId() string { - return tpdc.Direction + + return tpdc.Loadid + + TP_ID_SEP + + tpdc.Direction + TP_ID_SEP + tpdc.Tenant + TP_ID_SEP + @@ -308,9 +310,7 @@ func (tpdc TPDerivedChargers) GetDerivedChargesId() string { TP_ID_SEP + tpdc.Account + TP_ID_SEP + - tpdc.Subject + - TP_ID_SEP + - tpdc.Loadid + tpdc.Subject } func (tpdc *TPDerivedChargers) SetDerivedChargersId(id string) error { @@ -318,12 +318,12 @@ func (tpdc *TPDerivedChargers) SetDerivedChargersId(id string) error { if len(ids) != 6 { return fmt.Errorf("Wrong TP Derived Charge Id: %s", id) } - tpdc.Direction = ids[0] - tpdc.Tenant = ids[1] - tpdc.Category = ids[2] - tpdc.Account = ids[3] - tpdc.Subject = ids[4] - tpdc.Loadid = ids[5] + tpdc.Loadid = ids[0] + tpdc.Direction = ids[1] + tpdc.Tenant = ids[2] + tpdc.Category = ids[3] + tpdc.Account = ids[4] + tpdc.Subject = ids[5] return nil } @@ -406,6 +406,28 @@ func (self *TPAccountActions) KeyId() string { return fmt.Sprintf("%s:%s:%s", self.Direction, self.Tenant, self.Account) } +func (aa *TPAccountActions) GetAccountActionsId() string { + return aa.LoadId + + TP_ID_SEP + + aa.Direction + + TP_ID_SEP + + aa.Tenant + + TP_ID_SEP + + aa.Account +} + +func (aa *TPAccountActions) SetAccountActionsId(id string) error { + ids := strings.Split(id, TP_ID_SEP) + if len(ids) != 4 { + return fmt.Errorf("Wrong TP Account Action Id: %s", id) + } + aa.LoadId = ids[0] + aa.Direction = ids[1] + aa.Tenant = ids[2] + aa.Account = ids[3] + return nil +} + type AttrGetAccount struct { Tenant string Account string diff --git a/utils/consts.go b/utils/consts.go index ef5e9cc0b..1f13a1eb7 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -158,7 +158,7 @@ const ( CREATE_CDRS_TABLES_SQL = "create_cdrs_tables.sql" CREATE_TARIFFPLAN_TABLES_SQL = "create_tariffplan_tables.sql" TEST_SQL = "TEST_SQL" - TP_ID_SEP = "|" + TP_ID_SEP = "_" ) var (