From 5516c8ff1fa4006bed5f3d7dc960222f3f1467dc Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Wed, 4 Sep 2013 18:18:49 +0300 Subject: [PATCH] started bucket balance merge --- engine/actions_test.go | 2 +- engine/balances.go | 31 ++++++++++++++++++++++++++++--- engine/userbalance_test.go | 2 +- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/engine/actions_test.go b/engine/actions_test.go index 01c783131..e735bc4e2 100644 --- a/engine/actions_test.go +++ b/engine/actions_test.go @@ -87,7 +87,7 @@ func TestActionTimingOnlyMonthdays(t *testing.T) { tomorrow := time.Date(y, m, d, 0, 0, 0, 0, time.Local).AddDate(0, 0, 1) at := &ActionTiming{Timing: &Interval{MonthDays: MonthDays{1, 25, 2, tomorrow.Day()}}} st := at.GetNextStartTime() - expected := time.Date(y, m, tomorrow.Day(), 0, 0, 0, 0, time.Local) + expected := tomorrow if !st.Equal(expected) { t.Errorf("Expected %v was %v", expected, st) } diff --git a/engine/balances.go b/engine/balances.go index cffdf95a1..132cce5ff 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -19,21 +19,33 @@ along with this program. If not, see package engine import ( + "math" "sort" "time" ) +// Can hold different units as seconds or monetary type Balance struct { Id string Value float64 ExpirationDate time.Time Weight float64 GroupIds []string - SpecialPercent float64 + SpecialPrice float64 // absolute for minutes and percent for monetary (can be positive or negative) + DestinationId string + precision int } +/*func (b *Balance) Equal(o *Balance) bool { + return b.ExpirationDate.Equal(o.ExpirationDate) && + b.Weight == o.Weight && + b.Value == o.Value && + b.SpecialPrice == b.SpecialPrice && + b.DestinationId == o.DestinationId +}*/ +// TODO: why func (b *Balance) Equal(o *Balance) bool { - return b.ExpirationDate.Equal(o.ExpirationDate) || + return b.ExpirationDate.Equal(o.ExpirationDate) && b.Weight == o.Weight } @@ -45,11 +57,22 @@ func (b *Balance) Clone() *Balance { return &Balance{ Id: b.Id, Value: b.Value, + SpecialPrice: b.SpecialPrice, + DestinationId: b.DestinationId, ExpirationDate: b.ExpirationDate, Weight: b.Weight, } } +// Returns the available number of seconds for a specified credit +func (b *Balance) GetSecondsForCredit(credit float64) (seconds float64) { + seconds = b.Value + if b.SpecialPrice > 0 { + seconds = math.Min(credit/b.SpecialPrice, b.Value) + } + return +} + /* Structure to store minute buckets according to weight, precision or price. */ @@ -64,7 +87,9 @@ func (bc BalanceChain) Swap(i, j int) { } func (bc BalanceChain) Less(j, i int) bool { - return bc[i].Weight < bc[j].Weight + return bc[i].Weight < bc[j].Weight || + bc[i].precision < bc[j].precision || + bc[i].SpecialPrice > bc[j].SpecialPrice } func (bc BalanceChain) Sort() { diff --git a/engine/userbalance_test.go b/engine/userbalance_test.go index b3daec4db..bc1d3b92d 100644 --- a/engine/userbalance_test.go +++ b/engine/userbalance_test.go @@ -405,7 +405,7 @@ func TestUserBalanceExecuteTriggeredActions(t *testing.T) { BalanceMap: map[string]BalanceChain{CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 100}}}, UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceId: CREDIT, Direction: OUTBOUND, Units: 1}}, MinuteBuckets: []*MinuteBucket{&MinuteBucket{Seconds: 10, Weight: 20, Price: 1, DestinationId: "NAT"}, &MinuteBucket{Weight: 10, Price: 10, PriceType: PRICE_ABSOLUTE, DestinationId: "RET"}}, - ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ThresholdType: "*max_counter", ActionsId: "TEST_ACTIONS"}}, + ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceId: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ThresholdType: TRIGGER_MAX_COUNTER, ActionsId: "TEST_ACTIONS"}}, } ub.countUnits(&Action{BalanceId: CREDIT, Units: 1}) if ub.BalanceMap[CREDIT+OUTBOUND][0].Value != 110 || ub.MinuteBuckets[0].Seconds != 20 {