2024-12-12 16:25:47 +01:00
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" )
}
type PricingStrategy [ T Strategy ] struct {
2025-01-14 11:28:16 +01:00
Price float64 ` json:"price" bson:"price" default:"0" ` // Price is the Price of the pricing
Currency string ` json:"currency" bson:"currency" default:"USD" ` // Currency is the currency of the pricing
2024-12-12 16:25:47 +01:00
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 ] ) 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
}