Leon4gr45's picture
Upload folder using huggingface_hub (part 6)
d6f631f verified
Raw
History Blame Contribute Delete
6.04 kB
package subscription
import (
"encoding/json"
"fmt"
"github.com/openmeterio/openmeter/openmeter/productcatalog"
"github.com/openmeterio/openmeter/pkg/datetime"
"github.com/openmeterio/openmeter/pkg/models"
)
type SubscriptionItem struct {
models.NamespacedID `json:",inline"`
models.ManagedModel `json:",inline"`
models.MetadataModel `json:",inline"`
Annotations models.Annotations `json:"annotations"`
// SubscriptionItem doesn't have a separate Cadence, only one relative to the phase, denoting if it's intentionally different from the phase's cadence.
// The durations are relative to phase start.
ActiveFromOverrideRelativeToPhaseStart *datetime.ISODuration `json:"activeFromOverrideRelativeToPhaseStart,omitempty"`
ActiveToOverrideRelativeToPhaseStart *datetime.ISODuration `json:"activeToOverrideRelativeToPhaseStart,omitempty"`
// The defacto cadence of the item is calculated and persisted after each change.
models.CadencedModel `json:",inline"`
BillingBehaviorOverride BillingBehaviorOverride `json:"billingBehaviorOverride"`
// SubscriptionID is the ID of the subscription this item belongs to.
SubscriptionId string `json:"subscriptionId"`
// PhaseID is the ID of the phase this item belongs to.
PhaseId string `json:"phaseId"`
// Key is the unique key of the item in the phase.
Key string `json:"itemKey"`
RateCard productcatalog.RateCard `json:"rateCard"`
EntitlementID *string `json:"entitlementId,omitempty"`
// Name
Name string `json:"name"`
// Description
Description *string `json:"description,omitempty"`
}
func (i *SubscriptionItem) UnmarshalJSON(b []byte) error {
// First unmarshal the type information to determine which concrete type to use
var serdeTyp struct {
RateCard productcatalog.RateCardSerde `json:"rateCard"`
}
if err := json.Unmarshal(b, &serdeTyp); err != nil {
return fmt.Errorf("failed to JSON deserialize SubscriptionItemSpec: %w", err)
}
// Create a temporary struct with the correct concrete type for RateCard
serde := struct {
models.NamespacedID `json:",inline"`
models.ManagedModel `json:",inline"`
models.MetadataModel `json:",inline"`
ActiveFromOverrideRelativeToPhaseStart *datetime.ISODuration `json:"activeFromOverrideRelativeToPhaseStart,omitempty"`
ActiveToOverrideRelativeToPhaseStart *datetime.ISODuration `json:"activeToOverrideRelativeToPhaseStart,omitempty"`
models.CadencedModel `json:",inline"`
BillingBehaviorOverride BillingBehaviorOverride `json:"billingBehaviorOverride"`
SubscriptionId string `json:"subscriptionId"`
PhaseId string `json:"phaseId"`
Key string `json:"itemKey"`
RateCard productcatalog.RateCard `json:"rateCard"`
EntitlementID *string `json:"entitlementId,omitempty"`
Name string `json:"name"`
Description *string `json:"description,omitempty"`
}{
RateCard: i.RateCard,
}
// Set the concrete type based on the type field
switch serdeTyp.RateCard.Type {
case productcatalog.FlatFeeRateCardType:
serde.RateCard = &productcatalog.FlatFeeRateCard{}
case productcatalog.UsageBasedRateCardType:
serde.RateCard = &productcatalog.UsageBasedRateCard{}
default:
return fmt.Errorf("invalid RateCard type: %s", serdeTyp.RateCard.Type)
}
// Unmarshal the full object
if err := json.Unmarshal(b, &serde); err != nil {
return fmt.Errorf("failed to JSON deserialize SubscriptionItem: %w", err)
}
// Copy all fields from the temporary struct to the actual struct
i.NamespacedID = serde.NamespacedID
i.ManagedModel = serde.ManagedModel
i.MetadataModel = serde.MetadataModel
i.ActiveFromOverrideRelativeToPhaseStart = serde.ActiveFromOverrideRelativeToPhaseStart
i.ActiveToOverrideRelativeToPhaseStart = serde.ActiveToOverrideRelativeToPhaseStart
i.CadencedModel = serde.CadencedModel
i.BillingBehaviorOverride = serde.BillingBehaviorOverride
i.SubscriptionId = serde.SubscriptionId
i.PhaseId = serde.PhaseId
i.Key = serde.Key
i.RateCard = serde.RateCard
i.EntitlementID = serde.EntitlementID
i.Name = serde.Name
i.Description = serde.Description
return nil
}
func (i SubscriptionItem) GetCadence(phaseCadence models.CadencedModel) models.CadencedModel {
start := phaseCadence.ActiveFrom
if i.ActiveFromOverrideRelativeToPhaseStart != nil {
start, _ = i.ActiveFromOverrideRelativeToPhaseStart.AddTo(start)
}
end := phaseCadence.ActiveTo
if i.ActiveToOverrideRelativeToPhaseStart != nil {
iEnd, _ := i.ActiveToOverrideRelativeToPhaseStart.AddTo(start)
if end == nil || iEnd.Before(*end) {
end = &iEnd
}
}
return models.CadencedModel{
ActiveFrom: start,
ActiveTo: end,
}
}
func (i SubscriptionItem) AsEntityInput() CreateSubscriptionItemEntityInput {
return CreateSubscriptionItemEntityInput{
NamespacedModel: models.NamespacedModel{
Namespace: i.Namespace,
},
MetadataModel: i.MetadataModel,
Annotations: i.Annotations,
CadencedModel: i.CadencedModel,
ActiveFromOverrideRelativeToPhaseStart: i.ActiveFromOverrideRelativeToPhaseStart,
ActiveToOverrideRelativeToPhaseStart: i.ActiveToOverrideRelativeToPhaseStart,
PhaseID: i.PhaseId,
Key: i.Key,
RateCard: i.RateCard,
EntitlementID: i.EntitlementID,
Name: i.Name,
Description: i.Description,
BillingBehaviorOverride: i.BillingBehaviorOverride,
}
}
// SubscriptionItemRef is an unstable reference to a SubscriptionItem
type SubscriptionItemRef struct {
SubscriptionId string `json:"subscriptionId"`
PhaseKey string `json:"phaseKey"`
ItemKey string `json:"itemKey"`
}
func (r SubscriptionItemRef) Equals(r2 SubscriptionItemRef) bool {
if r.SubscriptionId != r2.SubscriptionId {
return false
}
if r.PhaseKey != r2.PhaseKey {
return false
}
if r.ItemKey != r2.ItemKey {
return false
}
return true
}