diff --git a/models/resources/compute.go b/models/resources/compute.go index 0f8067b..fe0936d 100755 --- a/models/resources/compute.go +++ b/models/resources/compute.go @@ -168,11 +168,28 @@ type PricedComputeResource struct { RAMLocated float64 `json:"ram_in_use" bson:"ram_in_use"` // RAMInUse is the RAM in use } +func (r *PricedComputeResource) ensurePricing() { + if r.SelectedPricing == nil { + r.SelectedPricing = &ComputeResourcePricingProfile{} + } +} + +func (r *PricedComputeResource) IsPurchasable() bool { + r.ensurePricing() + return r.SelectedPricing.IsPurchasable() +} + +func (r *PricedComputeResource) IsBooked() bool { + r.ensurePricing() + return r.SelectedPricing.IsBooked() +} + func (r *PricedComputeResource) GetType() tools.DataType { return tools.COMPUTE_RESOURCE } func (r *PricedComputeResource) GetPriceHT() (float64, error) { + r.ensurePricing() if r.BookingConfiguration == nil { r.BookingConfiguration = &BookingConfiguration{} } @@ -184,9 +201,6 @@ func (r *PricedComputeResource) GetPriceHT() (float64, error) { add := r.BookingConfiguration.UsageStart.Add(time.Duration(1 * time.Hour)) r.BookingConfiguration.UsageEnd = &add } - if r.SelectedPricing == nil { - return 0, errors.New("pricing profile must be set on Priced Compute" + r.ResourceID) - } pricing := r.SelectedPricing price := float64(0) for _, l := range []map[string]float64{r.CPUsLocated, r.GPUsLocated} { diff --git a/models/resources/data.go b/models/resources/data.go index 25bf83c..12e46c9 100755 --- a/models/resources/data.go +++ b/models/resources/data.go @@ -164,11 +164,28 @@ type PricedDataResource struct { UsageStorageGB float64 `json:"storage_gb,omitempty" bson:"storage_gb,omitempty"` } +func (r *PricedDataResource) ensurePricing() { + if r.SelectedPricing == nil { + r.SelectedPricing = &DataResourcePricingProfile{} + } +} + +func (r *PricedDataResource) IsPurchasable() bool { + r.ensurePricing() + return r.SelectedPricing.IsPurchasable() +} + +func (r *PricedDataResource) IsBooked() bool { + r.ensurePricing() + return r.SelectedPricing.IsBooked() +} + func (r *PricedDataResource) GetType() tools.DataType { return tools.DATA_RESOURCE } func (r *PricedDataResource) GetPriceHT() (float64, error) { + r.ensurePricing() if r.BookingConfiguration == nil { r.BookingConfiguration = &BookingConfiguration{} } @@ -180,9 +197,6 @@ func (r *PricedDataResource) GetPriceHT() (float64, error) { add := r.BookingConfiguration.UsageStart.Add(time.Duration(1 * time.Hour)) r.BookingConfiguration.UsageEnd = &add } - if r.SelectedPricing == nil { - return 0, errors.New("pricing profile must be set on Priced Data" + r.ResourceID) - } pricing := r.SelectedPricing var err error amountOfData := float64(1) diff --git a/models/resources/priced_resource.go b/models/resources/priced_resource.go index a471748..c7b7193 100755 --- a/models/resources/priced_resource.go +++ b/models/resources/priced_resource.go @@ -59,6 +59,8 @@ func (abs *PricedResource[T]) GetCreatorID() string { return abs.CreatorID } +// IsPurchasable and IsBooked fall back to false when SelectedPricing is a nil interface. +// Concrete types (PricedComputeResource, etc.) override these and guarantee non-nil pricing. func (abs *PricedResource[T]) IsPurchasable() bool { if any(abs.SelectedPricing) == nil { return false diff --git a/models/resources/processing.go b/models/resources/processing.go index d813797..43c80e7 100755 --- a/models/resources/processing.go +++ b/models/resources/processing.go @@ -70,6 +70,27 @@ type PricedProcessingResource struct { IsService bool } +func (r *PricedProcessingResource) ensurePricing() { + if r.SelectedPricing == nil { + r.SelectedPricing = &ProcessingResourcePricingProfile{} + } +} + +func (r *PricedProcessingResource) IsPurchasable() bool { + r.ensurePricing() + return r.SelectedPricing.IsPurchasable() +} + +func (r *PricedProcessingResource) IsBooked() bool { + r.ensurePricing() + return r.SelectedPricing.IsBooked() +} + +func (r *PricedProcessingResource) GetPriceHT() (float64, error) { + r.ensurePricing() + return r.PricedResource.GetPriceHT() +} + func (r *PricedProcessingResource) GetType() tools.DataType { return tools.PROCESSING_RESOURCE } diff --git a/models/resources/storage.go b/models/resources/storage.go index aa8a694..c27aa62 100755 --- a/models/resources/storage.go +++ b/models/resources/storage.go @@ -185,11 +185,28 @@ type PricedStorageResource struct { UsageStorageGB float64 `json:"storage_gb,omitempty" bson:"storage_gb,omitempty"` } +func (r *PricedStorageResource) ensurePricing() { + if r.SelectedPricing == nil { + r.SelectedPricing = &StorageResourcePricingProfile{} + } +} + +func (r *PricedStorageResource) IsPurchasable() bool { + r.ensurePricing() + return r.SelectedPricing.IsPurchasable() +} + +func (r *PricedStorageResource) IsBooked() bool { + r.ensurePricing() + return r.SelectedPricing.IsBooked() +} + func (r *PricedStorageResource) GetType() tools.DataType { return tools.STORAGE_RESOURCE } func (r *PricedStorageResource) GetPriceHT() (float64, error) { + r.ensurePricing() if r.BookingConfiguration == nil { r.BookingConfiguration = &BookingConfiguration{} } @@ -202,9 +219,6 @@ func (r *PricedStorageResource) GetPriceHT() (float64, error) { add := r.BookingConfiguration.UsageStart.Add(time.Duration(1 * time.Hour)) r.BookingConfiguration.UsageEnd = &add } - if r.SelectedPricing == nil { - return 0, errors.New("pricing profile must be set on Priced Storage" + r.ResourceID) - } pricing := r.SelectedPricing var err error amountOfData := float64(1)