mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-24 00:28:44 +05:00
add lcr strategy
This commit is contained in:
@@ -23,6 +23,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"log/syslog"
|
||||
"strings"
|
||||
"time"
|
||||
//"encoding/json"
|
||||
"github.com/cgrates/cgrates/cache2go"
|
||||
@@ -711,6 +712,54 @@ func (cd *CallDescriptor) Clone() *CallDescriptor {
|
||||
}
|
||||
}
|
||||
|
||||
func (cd *CallDescriptor) GetLCR() []*LCRCost {
|
||||
return nil
|
||||
func (cd *CallDescriptor) GetLCR() (*LCRCost, error) {
|
||||
lcr, err := dataStorage.GetLCR(cd.GetLCRKey(), false)
|
||||
if err != nil || lcr == nil {
|
||||
return nil, err
|
||||
}
|
||||
lcr.Sort()
|
||||
lcrCost := &LCRCost{
|
||||
TimeSpans: []*LCRTimeSpan{&LCRTimeSpan{StartTime: cd.TimeStart}},
|
||||
}
|
||||
for _, lcrActivation := range lcr.Activations {
|
||||
// TODO: filer entry by destination
|
||||
lcrEntry := lcrActivation.GetLCREntryForPrefix(cd.Destination)
|
||||
if lcrActivation.ActivationTime.Before(cd.TimeStart) ||
|
||||
lcrActivation.ActivationTime.Equal(cd.TimeStart) {
|
||||
lcrCost.TimeSpans[0].Entry = lcrEntry
|
||||
} else {
|
||||
if lcrActivation.ActivationTime.Before(cd.TimeEnd) {
|
||||
// add lcr timespan
|
||||
lcrCost.TimeSpans = append(lcrCost.TimeSpans, &LCRTimeSpan{
|
||||
StartTime: lcrActivation.ActivationTime,
|
||||
Entry: lcrEntry,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, ts := range lcrCost.TimeSpans {
|
||||
if ts.Entry.Strategy == LCR_STRATEGY_STATIC {
|
||||
for _, supplier := range strings.Split(ts.Entry.Suppliers, ";") {
|
||||
supplier = strings.TrimSpace(supplier)
|
||||
lcrCD := cd.Clone()
|
||||
lcrCD.Subject = supplier
|
||||
if cc, err := lcrCD.GetCost(); err != nil || cc == nil {
|
||||
ts.SupplierCosts = append(ts.SupplierCosts, &LCRSupplierCost{
|
||||
Supplier: supplier,
|
||||
Error: err,
|
||||
})
|
||||
} else {
|
||||
ts.SupplierCosts = append(ts.SupplierCosts, &LCRSupplierCost{
|
||||
Supplier: supplier,
|
||||
Cost: cc.Cost,
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// find rating profiles
|
||||
// sort according to strategy
|
||||
ts.Sort()
|
||||
}
|
||||
}
|
||||
return lcrCost, nil
|
||||
}
|
||||
|
||||
100
engine/lcr.go
100
engine/lcr.go
@@ -20,30 +20,106 @@ package engine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
type LCR struct {
|
||||
Tenant string
|
||||
Customer string
|
||||
Direction string
|
||||
LCRs []*LCREntry
|
||||
}
|
||||
const (
|
||||
LCR_STRATEGY_STATIC = "*static"
|
||||
LCR_STRATEGY_LOWEST = "*lowest"
|
||||
LCR_STRATEGY_HIGHEST = "*highest"
|
||||
)
|
||||
|
||||
type LCREntry struct {
|
||||
Destination string
|
||||
TOR string
|
||||
Strategy string
|
||||
Suppliers string
|
||||
type LCR struct {
|
||||
Tenant string
|
||||
Customer string
|
||||
Direction string
|
||||
Activations []*LCRActivation
|
||||
}
|
||||
type LCRActivation struct {
|
||||
ActivationTime time.Time
|
||||
Weight float64
|
||||
Entries []*LCREntry
|
||||
}
|
||||
type LCREntry struct {
|
||||
Destination string
|
||||
TOR string
|
||||
Strategy string
|
||||
Suppliers string
|
||||
}
|
||||
|
||||
type LCRCost struct {
|
||||
TimeSpans []*LCRTimeSpan
|
||||
}
|
||||
|
||||
type LCRTimeSpan struct {
|
||||
StartTime time.Time
|
||||
SupplierCosts []*LCRSupplierCost
|
||||
Entry *LCREntry
|
||||
}
|
||||
|
||||
type LCRSupplierCost struct {
|
||||
Supplier string
|
||||
Cost float64
|
||||
Error error
|
||||
}
|
||||
|
||||
func (lcr *LCR) GetId() string {
|
||||
return fmt.Sprintf("%s:%s:%s", lcr.Direction, lcr.Tenant, lcr.Customer)
|
||||
}
|
||||
|
||||
func (lcr *LCR) Len() int {
|
||||
return len(lcr.Activations)
|
||||
}
|
||||
|
||||
func (lcr *LCR) Swap(i, j int) {
|
||||
lcr.Activations[i], lcr.Activations[j] = lcr.Activations[j], lcr.Activations[i]
|
||||
}
|
||||
|
||||
func (lcr *LCR) Less(i, j int) bool {
|
||||
return lcr.Activations[i].ActivationTime.Before(lcr.Activations[j].ActivationTime)
|
||||
}
|
||||
|
||||
func (lcr *LCR) Sort() {
|
||||
sort.Sort(lcr)
|
||||
}
|
||||
|
||||
func (lcra *LCRActivation) GetLCREntryForPrefix(prefix string) *LCREntry {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (lts *LCRTimeSpan) Sort() {
|
||||
switch lts.Entry.Strategy {
|
||||
case LCR_STRATEGY_LOWEST:
|
||||
sort.Sort(LowestSupplierCostSorter(lts.SupplierCosts))
|
||||
case LCR_STRATEGY_HIGHEST:
|
||||
sort.Sort(HighestSupplierCostSorter(lts.SupplierCosts))
|
||||
}
|
||||
}
|
||||
|
||||
type LowestSupplierCostSorter []*LCRSupplierCost
|
||||
|
||||
func (lscs LowestSupplierCostSorter) Len() int {
|
||||
return len(lscs)
|
||||
}
|
||||
|
||||
func (lscs LowestSupplierCostSorter) Swap(i, j int) {
|
||||
lscs[i], lscs[j] = lscs[j], lscs[i]
|
||||
}
|
||||
|
||||
func (lscs LowestSupplierCostSorter) Less(i, j int) bool {
|
||||
return lscs[i].Cost < lscs[j].Cost
|
||||
}
|
||||
|
||||
type HighestSupplierCostSorter []*LCRSupplierCost
|
||||
|
||||
func (hscs HighestSupplierCostSorter) Len() int {
|
||||
return len(hscs)
|
||||
}
|
||||
|
||||
func (hscs HighestSupplierCostSorter) Swap(i, j int) {
|
||||
hscs[i], hscs[j] = hscs[j], hscs[i]
|
||||
}
|
||||
|
||||
func (hscs HighestSupplierCostSorter) Less(i, j int) bool {
|
||||
return hscs[i].Cost > hscs[j].Cost
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ type CSVReader struct {
|
||||
ratingPlans map[string]*RatingPlan
|
||||
ratingProfiles map[string]*RatingProfile
|
||||
sharedGroups map[string]*SharedGroup
|
||||
lcrs map[string]*LCR
|
||||
// file names
|
||||
destinationsFn, ratesFn, destinationratesFn, timingsFn, destinationratetimingsFn, ratingprofilesFn,
|
||||
sharedgroupsFn, actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn string
|
||||
@@ -70,6 +71,7 @@ func NewFileCSVReader(dataStorage RatingStorage, accountingStorage AccountingSto
|
||||
c.ratingPlans = make(map[string]*RatingPlan)
|
||||
c.ratingProfiles = make(map[string]*RatingProfile)
|
||||
c.sharedGroups = make(map[string]*SharedGroup)
|
||||
c.lcrs = make(map[string]*LCR)
|
||||
c.readerFunc = openFileCSVReader
|
||||
c.rpAliases = make(map[string]string)
|
||||
c.accAliases = make(map[string]string)
|
||||
|
||||
Reference in New Issue
Block a user