massive draft for payment process (UNCOMPLETE)
This commit is contained in:
136
models/common/pricing/pricing_strategy.go
Normal file
136
models/common/pricing/pricing_strategy.go
Normal file
@@ -0,0 +1,136 @@
|
||||
package pricing
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type BuyingStrategy int
|
||||
|
||||
const (
|
||||
UNLIMITED BuyingStrategy = iota
|
||||
SUBSCRIPTION
|
||||
PAY_PER_USE
|
||||
)
|
||||
|
||||
type Strategy interface {
|
||||
GetStrategy() string
|
||||
GetStrategyValue() int
|
||||
}
|
||||
|
||||
type TimePricingStrategy int
|
||||
|
||||
const (
|
||||
ONCE TimePricingStrategy = iota
|
||||
PER_SECOND
|
||||
PER_MINUTE
|
||||
PER_HOUR
|
||||
PER_DAY
|
||||
PER_WEEK
|
||||
PER_MONTH
|
||||
)
|
||||
|
||||
func (t TimePricingStrategy) GetStrategy() string {
|
||||
return [...]string{"ONCE", "PER_SECOND", "PER_MINUTE", "PER_HOUR", "PER_DAY", "PER_WEEK", "PER_MONTH"}[t]
|
||||
}
|
||||
|
||||
func (t TimePricingStrategy) GetStrategyValue() int {
|
||||
return int(t)
|
||||
}
|
||||
|
||||
func getAverageTimeInSecond(averageTimeInSecond float64, start time.Time, end *time.Time) float64 {
|
||||
now := time.Now()
|
||||
after := now.Add(time.Duration(averageTimeInSecond) * time.Second)
|
||||
|
||||
fromAverageDuration := after.Sub(now).Seconds()
|
||||
var tEnd time.Time
|
||||
if end == nil {
|
||||
tEnd = start.Add(1 * time.Hour)
|
||||
} else {
|
||||
tEnd = *end
|
||||
}
|
||||
fromDateDuration := tEnd.Sub(start).Seconds()
|
||||
|
||||
if fromAverageDuration > fromDateDuration {
|
||||
return fromAverageDuration
|
||||
}
|
||||
return fromDateDuration
|
||||
}
|
||||
|
||||
func BookingEstimation(t TimePricingStrategy, price float64, locationDurationInSecond float64, start time.Time, end *time.Time) (float64, error) {
|
||||
locationDurationInSecond = getAverageTimeInSecond(locationDurationInSecond, start, end)
|
||||
priceStr := fmt.Sprintf("%v", price)
|
||||
p, err := strconv.ParseFloat(priceStr, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
switch t {
|
||||
case ONCE:
|
||||
return p, nil
|
||||
case PER_HOUR:
|
||||
return p * float64(locationDurationInSecond/3600), nil
|
||||
case PER_MINUTE:
|
||||
return p * float64(locationDurationInSecond/60), nil
|
||||
case PER_SECOND:
|
||||
return p * locationDurationInSecond, nil
|
||||
case PER_DAY:
|
||||
return p * float64(locationDurationInSecond/86400), nil
|
||||
case PER_WEEK:
|
||||
return p * float64(locationDurationInSecond/604800), nil
|
||||
case PER_MONTH:
|
||||
return p * float64(locationDurationInSecond/2592000), nil
|
||||
}
|
||||
return 0, errors.New("Pricing strategy not found")
|
||||
}
|
||||
|
||||
// hmmmm
|
||||
type PricingStrategy[T Strategy] struct {
|
||||
Price float64 `json:"Price" bson:"Price" default:"0"` // Price is the Price of the pricing
|
||||
BuyingStrategy BuyingStrategy `json:"buying_strategy" bson:"buying_strategy" default:"0"` // BuyingStrategy is the buying strategy of the pricing
|
||||
TimePricingStrategy TimePricingStrategy `json:"time_pricing_strategy" bson:"time_pricing_strategy" default:"0"` // TimePricingStrategy is the time pricing strategy of the pricing
|
||||
OverrideStrategy T `json:"override_strategy" bson:"override_strategy" default:"-1"` // Modulation is the modulation of the pricing
|
||||
}
|
||||
|
||||
func (p PricingStrategy[T]) SetStrategy(Price float64, BuyingStrategy BuyingStrategy, TimePricingStrategy TimePricingStrategy) error {
|
||||
if TimePricingStrategy == ONCE && (BuyingStrategy != UNLIMITED || BuyingStrategy != PAY_PER_USE) {
|
||||
return errors.New("time pricing strategy can only be set to ONCE if buying strategy is UNLIMITED or PAY_PER_USE")
|
||||
} else if BuyingStrategy == SUBSCRIPTION && (TimePricingStrategy == ONCE) {
|
||||
return errors.New("subscription duration in second must be set if buying strategy is SUBSCRIPTION")
|
||||
}
|
||||
p.Price = Price
|
||||
p.BuyingStrategy = BuyingStrategy
|
||||
p.TimePricingStrategy = TimePricingStrategy
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p PricingStrategy[T]) SetSpecificPerUseStrategy(strategy T) error {
|
||||
if p.BuyingStrategy == UNLIMITED {
|
||||
return errors.New("UNLIMITED buying strategy can't have a specific strategy, Price is set on buying")
|
||||
}
|
||||
p.OverrideStrategy = strategy
|
||||
return nil
|
||||
}
|
||||
|
||||
// QUANTITY can be how many of gb core per example
|
||||
func (p PricingStrategy[T]) GetPrice(amountOfData float64, bookingTimeDuration float64, start time.Time, end *time.Time) (float64, error) {
|
||||
if p.BuyingStrategy == SUBSCRIPTION {
|
||||
return BookingEstimation(p.GetTimePricingStrategy(), p.Price*float64(amountOfData), bookingTimeDuration, start, end)
|
||||
} else if p.BuyingStrategy == UNLIMITED {
|
||||
return p.Price, nil
|
||||
}
|
||||
return p.Price * float64(amountOfData), nil
|
||||
}
|
||||
|
||||
func (p PricingStrategy[T]) GetBuyingStrategy() BuyingStrategy {
|
||||
return p.BuyingStrategy
|
||||
}
|
||||
|
||||
func (p PricingStrategy[T]) GetTimePricingStrategy() TimePricingStrategy {
|
||||
return p.TimePricingStrategy
|
||||
}
|
||||
|
||||
func (p PricingStrategy[T]) GetOverrideStrategy() T {
|
||||
return p.OverrideStrategy
|
||||
}
|
||||
Reference in New Issue
Block a user