2025-01-13 11:24:07 +01:00
|
|
|
package resources
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
|
|
|
|
"time"
|
|
|
|
|
|
2026-01-13 16:04:31 +01:00
|
|
|
"cloud.o-forge.io/core/oc-lib/models/booking"
|
2025-01-13 11:24:07 +01:00
|
|
|
"cloud.o-forge.io/core/oc-lib/models/common/pricing"
|
|
|
|
|
"cloud.o-forge.io/core/oc-lib/tools"
|
|
|
|
|
)
|
|
|
|
|
|
2026-01-13 16:04:31 +01:00
|
|
|
type BookingConfiguration struct {
|
|
|
|
|
ExplicitBookingDurationS float64 `json:"explicit_location_duration_s,omitempty" bson:"explicit_location_duration_s,omitempty"`
|
|
|
|
|
UsageStart *time.Time `json:"start,omitempty" bson:"start,omitempty"`
|
|
|
|
|
UsageEnd *time.Time `json:"end,omitempty" bson:"end,omitempty"`
|
|
|
|
|
Mode booking.BookingMode `json:"mode,omitempty" bson:"mode,omitempty"`
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-20 13:07:06 +01:00
|
|
|
type PricedResource[T pricing.PricingProfileITF] struct {
|
2026-01-13 16:04:31 +01:00
|
|
|
Name string `json:"name,omitempty" bson:"name,omitempty"`
|
|
|
|
|
Logo string `json:"logo,omitempty" bson:"logo,omitempty"`
|
|
|
|
|
InstancesRefs map[string]string `json:"instances_refs,omitempty" bson:"instances_refs,omitempty"`
|
2026-03-20 13:07:06 +01:00
|
|
|
SelectedPricing T `json:"selected_pricing,omitempty" bson:"selected_pricing,omitempty"`
|
2026-01-13 16:04:31 +01:00
|
|
|
Quantity int `json:"quantity,omitempty" bson:"quantity,omitempty"`
|
|
|
|
|
BookingConfiguration *BookingConfiguration `json:"booking_configuration,omitempty" bson:"booking_configuration,omitempty"`
|
|
|
|
|
Variations []*pricing.PricingVariation `json:"pricing_variations" bson:"pricing_variations"`
|
|
|
|
|
CreatorID string `json:"peer_id,omitempty" bson:"peer_id,omitempty"`
|
|
|
|
|
ResourceID string `json:"resource_id,omitempty" bson:"resource_id,omitempty"`
|
2026-02-23 15:18:27 +01:00
|
|
|
InstanceID string `json:"instance_id,omitempty" bson:"resource_id,omitempty"`
|
|
|
|
|
|
|
|
|
|
ResourceType tools.DataType `json:"resource_type,omitempty" bson:"resource_type,omitempty"`
|
2026-01-13 16:04:31 +01:00
|
|
|
}
|
|
|
|
|
|
2026-03-20 13:07:06 +01:00
|
|
|
func (abs *PricedResource[T]) GetQuantity() int {
|
2026-01-13 16:04:31 +01:00
|
|
|
return abs.Quantity
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-20 13:07:06 +01:00
|
|
|
func (abs *PricedResource[T]) AddQuantity(amount int) {
|
2026-01-13 16:04:31 +01:00
|
|
|
abs.Quantity += amount
|
2025-06-20 12:10:36 +02:00
|
|
|
}
|
|
|
|
|
|
2026-03-20 13:07:06 +01:00
|
|
|
func (abs *PricedResource[T]) SelectPricing() pricing.PricingProfileITF {
|
2025-06-20 12:10:36 +02:00
|
|
|
return abs.SelectedPricing
|
2025-01-13 11:24:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-03-20 13:07:06 +01:00
|
|
|
func (abs *PricedResource[T]) GetID() string {
|
2025-01-13 11:24:07 +01:00
|
|
|
return abs.ResourceID
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-20 13:07:06 +01:00
|
|
|
func (abs *PricedResource[T]) GetInstanceID() string {
|
2026-02-23 15:22:48 +01:00
|
|
|
return abs.InstanceID
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-20 13:07:06 +01:00
|
|
|
func (abs *PricedResource[T]) GetType() tools.DataType {
|
2025-01-13 11:24:07 +01:00
|
|
|
return abs.ResourceType
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-20 13:07:06 +01:00
|
|
|
func (abs *PricedResource[T]) GetCreatorID() string {
|
2025-01-13 11:24:07 +01:00
|
|
|
return abs.CreatorID
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-20 13:28:35 +01:00
|
|
|
// IsPurchasable and IsBooked fall back to false when SelectedPricing is a nil interface.
|
|
|
|
|
// Concrete types (PricedComputeResource, etc.) override these and guarantee non-nil pricing.
|
2026-03-20 13:07:06 +01:00
|
|
|
func (abs *PricedResource[T]) IsPurchasable() bool {
|
|
|
|
|
if any(abs.SelectedPricing) == nil {
|
2025-01-13 11:24:07 +01:00
|
|
|
return false
|
|
|
|
|
}
|
2026-03-20 13:07:06 +01:00
|
|
|
return abs.SelectedPricing.IsPurchasable()
|
2025-06-20 07:51:32 +02:00
|
|
|
}
|
|
|
|
|
|
2026-03-20 13:07:06 +01:00
|
|
|
func (abs *PricedResource[T]) IsBooked() bool {
|
|
|
|
|
if any(abs.SelectedPricing) == nil {
|
2025-06-20 07:51:32 +02:00
|
|
|
return false
|
|
|
|
|
}
|
2026-03-20 13:07:06 +01:00
|
|
|
return abs.SelectedPricing.IsBooked()
|
2025-01-13 11:24:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-03-20 13:07:06 +01:00
|
|
|
func (abs *PricedResource[T]) GetLocationEnd() *time.Time {
|
2026-01-13 16:04:31 +01:00
|
|
|
if abs.BookingConfiguration == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return abs.BookingConfiguration.UsageEnd
|
2025-01-13 11:24:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-03-20 13:07:06 +01:00
|
|
|
func (abs *PricedResource[T]) GetLocationStart() *time.Time {
|
2026-01-13 16:04:31 +01:00
|
|
|
if abs.BookingConfiguration == nil {
|
2026-03-20 14:20:26 +01:00
|
|
|
return nil
|
2026-01-13 16:04:31 +01:00
|
|
|
}
|
|
|
|
|
return abs.BookingConfiguration.UsageStart
|
2025-01-13 11:24:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-03-20 13:07:06 +01:00
|
|
|
func (abs *PricedResource[T]) SetLocationStart(start time.Time) {
|
2026-01-13 16:04:31 +01:00
|
|
|
if abs.BookingConfiguration == nil {
|
|
|
|
|
abs.BookingConfiguration = &BookingConfiguration{}
|
|
|
|
|
}
|
|
|
|
|
abs.BookingConfiguration.UsageStart = &start
|
2025-01-13 11:24:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-03-20 13:07:06 +01:00
|
|
|
func (abs *PricedResource[T]) SetLocationEnd(end time.Time) {
|
2026-01-13 16:04:31 +01:00
|
|
|
if abs.BookingConfiguration == nil {
|
|
|
|
|
abs.BookingConfiguration = &BookingConfiguration{}
|
|
|
|
|
}
|
|
|
|
|
abs.BookingConfiguration.UsageEnd = &end
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-20 13:07:06 +01:00
|
|
|
func (abs *PricedResource[T]) GetBookingMode() booking.BookingMode {
|
2026-01-13 16:04:31 +01:00
|
|
|
if abs.BookingConfiguration == nil {
|
|
|
|
|
return booking.WHEN_POSSIBLE
|
|
|
|
|
}
|
|
|
|
|
return abs.BookingConfiguration.Mode
|
2025-01-13 11:24:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-03-20 13:07:06 +01:00
|
|
|
func (abs *PricedResource[T]) GetExplicitDurationInS() float64 {
|
2026-01-13 16:04:31 +01:00
|
|
|
if abs.BookingConfiguration == nil {
|
|
|
|
|
abs.BookingConfiguration = &BookingConfiguration{}
|
|
|
|
|
}
|
|
|
|
|
if abs.BookingConfiguration.ExplicitBookingDurationS == 0 {
|
|
|
|
|
if abs.BookingConfiguration.UsageEnd == nil && abs.BookingConfiguration.UsageStart == nil {
|
2026-03-20 14:01:14 +01:00
|
|
|
return (5 * time.Minute).Seconds()
|
2025-01-13 11:24:07 +01:00
|
|
|
}
|
2026-01-13 16:04:31 +01:00
|
|
|
if abs.BookingConfiguration.UsageEnd == nil {
|
2026-03-20 10:30:30 +01:00
|
|
|
add := abs.BookingConfiguration.UsageStart.Add(5 * time.Minute)
|
2026-01-13 16:04:31 +01:00
|
|
|
abs.BookingConfiguration.UsageEnd = &add
|
2025-02-10 10:42:37 +01:00
|
|
|
}
|
2026-03-20 14:32:46 +01:00
|
|
|
d := abs.BookingConfiguration.UsageEnd.Sub(*abs.BookingConfiguration.UsageStart).Seconds()
|
|
|
|
|
if d <= 0 {
|
|
|
|
|
return (5 * time.Minute).Seconds()
|
|
|
|
|
}
|
|
|
|
|
return d
|
2025-01-13 11:24:07 +01:00
|
|
|
}
|
2026-01-13 16:04:31 +01:00
|
|
|
return abs.BookingConfiguration.ExplicitBookingDurationS
|
2025-01-13 11:24:07 +01:00
|
|
|
}
|
|
|
|
|
|
2026-03-20 13:07:06 +01:00
|
|
|
func (r *PricedResource[T]) GetPriceHT() (float64, error) {
|
2025-02-10 13:04:13 +01:00
|
|
|
now := time.Now()
|
2026-01-13 16:04:31 +01:00
|
|
|
if r.BookingConfiguration == nil {
|
|
|
|
|
r.BookingConfiguration = &BookingConfiguration{}
|
|
|
|
|
}
|
|
|
|
|
if r.BookingConfiguration.UsageStart == nil {
|
|
|
|
|
r.BookingConfiguration.UsageStart = &now
|
2025-01-13 11:24:07 +01:00
|
|
|
}
|
2026-01-13 16:04:31 +01:00
|
|
|
if r.BookingConfiguration.UsageEnd == nil {
|
2026-03-20 14:42:48 +01:00
|
|
|
add := r.BookingConfiguration.UsageStart.Add(time.Duration(5 * time.Minute))
|
2026-01-13 16:04:31 +01:00
|
|
|
r.BookingConfiguration.UsageEnd = &add
|
2025-02-10 13:04:13 +01:00
|
|
|
}
|
2026-03-20 13:07:06 +01:00
|
|
|
if any(r.SelectedPricing) == nil {
|
|
|
|
|
return 0, errors.New("pricing profile must be set for resource " + r.ResourceID)
|
2025-01-13 11:24:07 +01:00
|
|
|
}
|
2025-06-16 13:48:32 +02:00
|
|
|
pricing := r.SelectedPricing
|
2026-01-13 16:04:31 +01:00
|
|
|
return pricing.GetPriceHT(1, 0, *r.BookingConfiguration.UsageStart, *r.BookingConfiguration.UsageEnd, r.Variations)
|
2025-01-13 11:24:07 +01:00
|
|
|
}
|