Documentation
¶
Index ¶
- Constants
- type AlignmentError
- type AllowedDuringApplyingPatchesError
- type AnyValuePatch
- type Applies
- type ApplyContext
- type BillingBehaviorOverride
- type CancelledEvent
- type ChangeSubscriptionWorkflowInput
- type ContinuedEvent
- type CreateSubscriptionCustomerInput
- type CreateSubscriptionEntityInput
- type CreateSubscriptionItemCustomerInput
- type CreateSubscriptionItemEntityInput
- type CreateSubscriptionItemInput
- type CreateSubscriptionItemPlanInput
- type CreateSubscriptionPhaseCustomerInput
- type CreateSubscriptionPhaseEntityInput
- type CreateSubscriptionPhaseInput
- type CreateSubscriptionPhasePlanInput
- type CreateSubscriptionPlanInput
- type CreateSubscriptionWorkflowInput
- type CreatedEvent
- type DeletedEvent
- type EntitlementAdapter
- type ForbiddenError
- type ItemNotFoundError
- type ListSubscriptionsInput
- type NoBillingPeriodError
- type NoOpSubscriptionValidator
- func (NoOpSubscriptionValidator) ValidateCancel(context.Context, SubscriptionView) error
- func (NoOpSubscriptionValidator) ValidateContinue(context.Context, SubscriptionView) error
- func (NoOpSubscriptionValidator) ValidateCreate(context.Context, SubscriptionView) error
- func (NoOpSubscriptionValidator) ValidateDelete(context.Context, SubscriptionView) error
- func (NoOpSubscriptionValidator) ValidateUpdate(context.Context, SubscriptionView) error
- type NotFoundError
- type Patch
- type PatchConflictError
- type PatchForbiddenError
- type PatchOperation
- type PatchPath
- func (p PatchPath) IsParentOf(other PatchPath) bool
- func (p PatchPath) ItemKey() string
- func (p PatchPath) MarshalJSON() ([]byte, error)
- func (p PatchPath) PhaseKey() string
- func (p PatchPath) Type() PatchPathType
- func (p *PatchPath) UnmarshalJSON(data []byte) error
- func (p PatchPath) Validate() error
- type PatchPathType
- type PatchValidationError
- type PhaseNotFoundError
- type Plan
- type PlanNotFoundError
- type PlanPhase
- type PlanRateCard
- type PlanRef
- type RateCard
- type RemoveSubscriptionPhaseInput
- type RemoveSubscriptionPhaseShifting
- type ScheduleSubscriptionEntitlementInput
- type Service
- type SpecValidationError
- type Subscription
- type SubscriptionAction
- type SubscriptionEntitlement
- type SubscriptionItem
- type SubscriptionItemRef
- type SubscriptionItemRepository
- type SubscriptionItemSpec
- func (s SubscriptionItemSpec) GetCadence(phaseCadence models.CadencedModel) models.CadencedModel
- func (s SubscriptionItemSpec) GetRef(subId string) SubscriptionItemRef
- func (s SubscriptionItemSpec) ToCreateSubscriptionItemEntityInput(phaseID models.NamespacedID, phaseCadence models.CadencedModel, ...) (CreateSubscriptionItemEntityInput, error)
- func (s SubscriptionItemSpec) ToScheduleSubscriptionEntitlementInput(cust customer.Customer, cadence models.CadencedModel) (ScheduleSubscriptionEntitlementInput, bool, error)
- func (s *SubscriptionItemSpec) Validate() error
- type SubscriptionItemView
- type SubscriptionList
- type SubscriptionPhase
- type SubscriptionPhaseRepository
- type SubscriptionPhaseSpec
- func (s SubscriptionPhaseSpec) GetBillableItemsByKey() map[string][]*SubscriptionItemSpec
- func (s SubscriptionPhaseSpec) GetBillingCadence() (isodate.Period, error)
- func (s SubscriptionPhaseSpec) HasBillables() bool
- func (s SubscriptionPhaseSpec) ToCreateSubscriptionPhaseEntityInput(subscription Subscription, activeFrom time.Time) CreateSubscriptionPhaseEntityInput
- func (s SubscriptionPhaseSpec) Validate(phaseCadence models.CadencedModel, alignment productcatalog.Alignment) error
- type SubscriptionPhaseView
- type SubscriptionRepository
- type SubscriptionSpec
- func (s *SubscriptionSpec) ApplyPatches(patches []Applies, context ApplyContext) error
- func (s *SubscriptionSpec) GetAlignedBillingPeriodAt(phaseKey string, at time.Time) (timeutil.Period, error)
- func (s *SubscriptionSpec) GetCurrentPhaseAt(t time.Time) (*SubscriptionPhaseSpec, bool)
- func (s *SubscriptionSpec) GetPhaseCadence(phaseKey string) (models.CadencedModel, error)
- func (s *SubscriptionSpec) GetSortedPhases() []*SubscriptionPhaseSpec
- func (s *SubscriptionSpec) ToCreateSubscriptionEntityInput(ns string) CreateSubscriptionEntityInput
- func (s *SubscriptionSpec) Validate() error
- type SubscriptionStateMachine
- type SubscriptionStatus
- type SubscriptionValidator
- type SubscriptionView
- type Timing
- type TimingEnum
- type UpdatedEvent
- type ValuePatch
- type WorkflowService
Constants ¶
const (
EventSubsystem metadata.EventSubsystem = "subscription"
)
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AlignmentError ¶
type AlignmentError struct {
Inner error
}
AlignmentError is an error that occurs when the spec is not aligned but we expect it to be.
func (AlignmentError) Error ¶
func (e AlignmentError) Error() string
func (AlignmentError) Unwrap ¶
func (e AlignmentError) Unwrap() error
type AllowedDuringApplyingPatchesError ¶
type AllowedDuringApplyingPatchesError struct {
Inner error
}
Some errors are allowed during applying individual patches, but still mean the Spec as a whole is invalid
func (*AllowedDuringApplyingPatchesError) Error ¶
func (e *AllowedDuringApplyingPatchesError) Error() string
func (*AllowedDuringApplyingPatchesError) Unwrap ¶
func (e *AllowedDuringApplyingPatchesError) Unwrap() error
type AnyValuePatch ¶
type AnyValuePatch interface {
ValueAsAny() any
}
type Applies ¶
type Applies interface {
ApplyTo(spec *SubscriptionSpec, actx ApplyContext) error
}
Each Patch applies its changes to the SubscriptionSpec.
type ApplyContext ¶
type BillingBehaviorOverride ¶
type BillingBehaviorOverride struct {
// If true, the billing cadence will be restarted
// The anchor time will be the time the originating change takes effect,
// which in practive translates to a SubscriptionItem's ActiveFrom property.
RestartBillingPeriod *bool `json:"restartBillingPeriod,omitempty"`
}
type CancelledEvent ¶
type CancelledEvent viewEvent
func (CancelledEvent) EventMetadata ¶
func (s CancelledEvent) EventMetadata() metadata.EventMetadata
func (CancelledEvent) EventName ¶
func (s CancelledEvent) EventName() string
func (CancelledEvent) Validate ¶
func (s CancelledEvent) Validate() error
type ChangeSubscriptionWorkflowInput ¶
type ChangeSubscriptionWorkflowInput struct {
Timing
models.AnnotatedModel
Name string
Description *string
}
type ContinuedEvent ¶
type ContinuedEvent viewEvent
func (ContinuedEvent) EventMetadata ¶
func (s ContinuedEvent) EventMetadata() metadata.EventMetadata
func (ContinuedEvent) EventName ¶
func (s ContinuedEvent) EventName() string
func (ContinuedEvent) Validate ¶
func (s ContinuedEvent) Validate() error
type CreateSubscriptionCustomerInput ¶
type CreateSubscriptionCustomerInput struct {
models.AnnotatedModel `json:",inline"`
Name string `json:"name"`
Description *string `json:"description,omitempty"`
CustomerId string `json:"customerId"`
Currency currencyx.Code `json:"currency"`
ActiveFrom time.Time `json:"activeFrom,omitempty"`
ActiveTo *time.Time `json:"activeTo,omitempty"`
}
type CreateSubscriptionEntityInput ¶
type CreateSubscriptionEntityInput struct {
models.CadencedModel
models.NamespacedModel
models.AnnotatedModel
productcatalog.Alignment
Plan *PlanRef
Name string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
CustomerId string `json:"customerId,omitempty"`
Currency currencyx.Code
}
type CreateSubscriptionItemCustomerInput ¶
type CreateSubscriptionItemCustomerInput struct {
ActiveFromOverrideRelativeToPhaseStart *isodate.Period `json:"activeFromOverrideRelativeToPhaseStart"`
ActiveToOverrideRelativeToPhaseStart *isodate.Period `json:"activeToOverrideRelativeToPhaseStart,omitempty"`
BillingBehaviorOverride
}
type CreateSubscriptionItemEntityInput ¶
type CreateSubscriptionItemEntityInput struct {
models.NamespacedModel
models.AnnotatedModel
ActiveFromOverrideRelativeToPhaseStart *isodate.Period
ActiveToOverrideRelativeToPhaseStart *isodate.Period
models.CadencedModel
BillingBehaviorOverride BillingBehaviorOverride
// PhaseID is the ID of the phase this item belongs to.
PhaseID string
// Key is the unique key of the item in the phase.
Key string
RateCard RateCard
EntitlementID *string
Name string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
}
func (CreateSubscriptionItemEntityInput) Equal ¶
func (i CreateSubscriptionItemEntityInput) Equal(other CreateSubscriptionItemEntityInput) bool
type CreateSubscriptionItemInput ¶
type CreateSubscriptionItemInput struct {
CreateSubscriptionItemPlanInput `json:",inline"`
CreateSubscriptionItemCustomerInput `json:",inline"`
}
type CreateSubscriptionPhaseCustomerInput ¶
type CreateSubscriptionPhaseCustomerInput struct {
models.AnnotatedModel `json:",inline"`
}
type CreateSubscriptionPhaseEntityInput ¶
type CreateSubscriptionPhaseEntityInput struct {
models.NamespacedModel
models.AnnotatedModel
// ActiveFrom is the time the phase becomes active.
ActiveFrom time.Time
// SubscriptionID is the ID of the subscription this phase belongs to.
SubscriptionID string `json:"subscriptionId"`
// Key is the unique key for Phase.
Key string `json:"key"`
// Name
Name string `json:"name"`
// Description
Description *string `json:"description,omitempty"`
// StartAfter
StartAfter isodate.Period `json:"interval"`
}
func (CreateSubscriptionPhaseEntityInput) Equal ¶
func (i CreateSubscriptionPhaseEntityInput) Equal(other CreateSubscriptionPhaseEntityInput) bool
type CreateSubscriptionPhaseInput ¶
type CreateSubscriptionPhaseInput struct {
// Duration is required exactly in cases where the phase wouldn't be the last phase.
Duration *isodate.Period `json:"duration"`
CreateSubscriptionPhasePlanInput
CreateSubscriptionPhaseCustomerInput
}
func (CreateSubscriptionPhaseInput) Validate ¶
func (i CreateSubscriptionPhaseInput) Validate() error
type CreateSubscriptionPhasePlanInput ¶
type CreateSubscriptionPhasePlanInput struct {
PhaseKey string `json:"key"`
StartAfter isodate.Period `json:"startAfter"`
Name string `json:"name"`
Description *string `json:"description,omitempty"`
}
func (CreateSubscriptionPhasePlanInput) Validate ¶
func (i CreateSubscriptionPhasePlanInput) Validate() error
type CreateSubscriptionPlanInput ¶
type CreateSubscriptionPlanInput struct {
Plan *PlanRef `json:"plan"`
productcatalog.Alignment
}
type CreateSubscriptionWorkflowInput ¶
type CreateSubscriptionWorkflowInput struct {
ChangeSubscriptionWorkflowInput
Namespace string
CustomerID string
}
type CreatedEvent ¶
type CreatedEvent viewEvent
func (CreatedEvent) EventMetadata ¶
func (s CreatedEvent) EventMetadata() metadata.EventMetadata
func (CreatedEvent) EventName ¶
func (s CreatedEvent) EventName() string
func (CreatedEvent) Validate ¶
func (s CreatedEvent) Validate() error
type DeletedEvent ¶
type DeletedEvent viewEvent
func (DeletedEvent) EventMetadata ¶
func (s DeletedEvent) EventMetadata() metadata.EventMetadata
func (DeletedEvent) EventName ¶
func (s DeletedEvent) EventName() string
func (DeletedEvent) Validate ¶
func (s DeletedEvent) Validate() error
type EntitlementAdapter ¶
type EntitlementAdapter interface {
ScheduleEntitlement(ctx context.Context, input ScheduleSubscriptionEntitlementInput) (*SubscriptionEntitlement, error)
// At refers to a point in time for which we're querying the system state, meaning:
// if t1 < t2 < t3, and some entitlement was deleted effective at t2, then
// with at = t1 the entitlement will be returned, while with at = t3 it won't.
GetForSubscriptionAt(ctx context.Context, subscriptionID models.NamespacedID, at time.Time) ([]SubscriptionEntitlement, error)
DeleteByItemID(ctx context.Context, itemId models.NamespacedID) error
}
type ForbiddenError ¶
type ForbiddenError struct {
Msg string
}
func (*ForbiddenError) Error ¶
func (e *ForbiddenError) Error() string
type ItemNotFoundError ¶
type ItemNotFoundError struct {
ID string
}
func (*ItemNotFoundError) Error ¶
func (e *ItemNotFoundError) Error() string
type ListSubscriptionsInput ¶
type ListSubscriptionsInput struct {
pagination.Page
Namespaces []string
Customers []string
ActiveAt *time.Time
}
func (ListSubscriptionsInput) Validate ¶
func (i ListSubscriptionsInput) Validate() error
type NoBillingPeriodError ¶
type NoBillingPeriodError struct {
Inner error
}
NoBillingPeriodError is an error that occurs when a phase has no billing period.
func (NoBillingPeriodError) Error ¶
func (e NoBillingPeriodError) Error() string
func (NoBillingPeriodError) Unwrap ¶
func (e NoBillingPeriodError) Unwrap() error
type NoOpSubscriptionValidator ¶
type NoOpSubscriptionValidator struct{}
func (NoOpSubscriptionValidator) ValidateCancel ¶
func (NoOpSubscriptionValidator) ValidateCancel(context.Context, SubscriptionView) error
func (NoOpSubscriptionValidator) ValidateContinue ¶
func (NoOpSubscriptionValidator) ValidateContinue(context.Context, SubscriptionView) error
func (NoOpSubscriptionValidator) ValidateCreate ¶
func (NoOpSubscriptionValidator) ValidateCreate(context.Context, SubscriptionView) error
func (NoOpSubscriptionValidator) ValidateDelete ¶
func (NoOpSubscriptionValidator) ValidateDelete(context.Context, SubscriptionView) error
func (NoOpSubscriptionValidator) ValidateUpdate ¶
func (NoOpSubscriptionValidator) ValidateUpdate(context.Context, SubscriptionView) error
type NotFoundError ¶
func (*NotFoundError) Error ¶
func (e *NotFoundError) Error() string
type PatchConflictError ¶
type PatchConflictError struct {
Msg string
}
func (*PatchConflictError) Error ¶
func (e *PatchConflictError) Error() string
type PatchForbiddenError ¶
type PatchForbiddenError struct {
Msg string
}
func (*PatchForbiddenError) Error ¶
func (e *PatchForbiddenError) Error() string
type PatchOperation ¶
type PatchOperation string
const ( PatchOperationAdd PatchOperation = "add" PatchOperationRemove PatchOperation = "remove" PatchOperationUnschedule PatchOperation = "unschedule" PatchOperationStretch PatchOperation = "stretch" )
func (PatchOperation) Validate ¶
func (o PatchOperation) Validate() error
type PatchPath ¶
type PatchPath string
func NewItemPath ¶
func NewPhasePath ¶
func (PatchPath) IsParentOf ¶
Checks whether p is a parent of other where parent means all segments of p are present and in order in other
func (PatchPath) MarshalJSON ¶
Lets implement JSON Marshaler for Path
func (PatchPath) Type ¶
func (p PatchPath) Type() PatchPathType
func (*PatchPath) UnmarshalJSON ¶
Lets implement JSON Unmarshaler for Path
type PatchPathType ¶
type PatchPathType string
const ( PatchPathTypePhase PatchPathType = "phase" PatchPathTypeItem PatchPathType = "item" )
type PatchValidationError ¶
type PatchValidationError struct {
Msg string
}
func (*PatchValidationError) Error ¶
func (e *PatchValidationError) Error() string
type PhaseNotFoundError ¶
type PhaseNotFoundError struct {
ID string
}
func (*PhaseNotFoundError) Error ¶
func (e *PhaseNotFoundError) Error() string
type Plan ¶
type Plan interface {
ToCreateSubscriptionPlanInput() CreateSubscriptionPlanInput
GetName() string
// Phases are expected to be returned in the order they activate.
GetPhases() []PlanPhase
// Will not make sense on the long term
Currency() currencyx.Code
}
All methods are expected to return stable values.
type PlanNotFoundError ¶
func (PlanNotFoundError) Error ¶
func (e PlanNotFoundError) Error() string
type PlanPhase ¶
type PlanPhase interface {
ToCreateSubscriptionPhasePlanInput() CreateSubscriptionPhasePlanInput
GetRateCards() []PlanRateCard
GetKey() string
}
All methods are expected to return stable values.
type PlanRateCard ¶
type PlanRateCard interface {
ToCreateSubscriptionItemPlanInput() CreateSubscriptionItemPlanInput
GetKey() string
}
All methods are expected to return stable values.
type RateCard ¶
type RateCard struct {
// Name of the RateCard
Name string `json:"name"`
// Description for the RateCard
Description *string `json:"description,omitempty"`
// Feature defines optional Feature assigned to RateCard
FeatureKey *string `json:"featureKey,omitempty"`
// EntitlementTemplate defines the template used for instantiating entitlement.Entitlement.
// If Feature is set then template must be provided as well.
EntitlementTemplate *productcatalog.EntitlementTemplate `json:"entitlementTemplate,omitempty"`
// TaxConfig defines provider specific tax information.
TaxConfig *productcatalog.TaxConfig `json:"taxConfig,omitempty"`
// Price defines the price for the RateCard
Price *productcatalog.Price `json:"price,omitempty"`
// BillingCadence defines the billing cadence of the RateCard in ISO8601 format.
// Example: "P1D12H"
BillingCadence *isodate.Period `json:"billingCadence,omitempty"`
}
RateCard is a local implementation of plan.RateCard until productcatalog models are available TODO: extract ProductCatalog models and use them, doing it like this is a mess....
type RemoveSubscriptionPhaseInput ¶
type RemoveSubscriptionPhaseInput struct {
Shift RemoveSubscriptionPhaseShifting `json:"shift"`
}
type RemoveSubscriptionPhaseShifting ¶
type RemoveSubscriptionPhaseShifting int
const ( RemoveSubscriptionPhaseShiftNext RemoveSubscriptionPhaseShifting = iota RemoveSubscriptionPhaseShiftPrev )
func (RemoveSubscriptionPhaseShifting) Validate ¶
func (s RemoveSubscriptionPhaseShifting) Validate() error
type ScheduleSubscriptionEntitlementInput ¶
type ScheduleSubscriptionEntitlementInput struct {
entitlement.CreateEntitlementInputs
}
func (ScheduleSubscriptionEntitlementInput) Equal ¶
func (s ScheduleSubscriptionEntitlementInput) Equal(other ScheduleSubscriptionEntitlementInput) bool
func (ScheduleSubscriptionEntitlementInput) Validate ¶
func (s ScheduleSubscriptionEntitlementInput) Validate() error
type Service ¶
type Service interface {
// Create a new subscription accotding to the given spec
Create(ctx context.Context, namespace string, spec SubscriptionSpec) (Subscription, error)
// Update the subscription with the given ID to the target spec
Update(ctx context.Context, subscriptionID models.NamespacedID, target SubscriptionSpec) (Subscription, error)
// Delete a scheduled subscription with the given ID
Delete(ctx context.Context, subscriptionID models.NamespacedID) error
// Cancel a running subscription at the provided time
Cancel(ctx context.Context, subscriptionID models.NamespacedID, timing Timing) (Subscription, error)
// Continue a canceled subscription (effectively undoing the cancellation)
Continue(ctx context.Context, subscriptionID models.NamespacedID) (Subscription, error)
// Get the subscription with the given ID
Get(ctx context.Context, subscriptionID models.NamespacedID) (Subscription, error)
// GetView returns a full view of the subscription with the given ID
GetView(ctx context.Context, subscriptionID models.NamespacedID) (SubscriptionView, error)
// List lists the subscriptions matching the set criteria
List(ctx context.Context, params ListSubscriptionsInput) (SubscriptionList, error)
}
type SpecValidationError ¶
func (*SpecValidationError) Error ¶
func (e *SpecValidationError) Error() string
type Subscription ¶
type Subscription struct {
models.NamespacedID
models.ManagedModel
models.CadencedModel
models.AnnotatedModel
productcatalog.Alignment
Name string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
// References the plan (if the Subscription was created form one)
PlanRef *PlanRef `json:"planRef"`
CustomerId string `json:"customerId,omitempty"`
Currency currencyx.Code `json:"currency,omitempty"`
}
func (Subscription) AsEntityInput ¶
func (s Subscription) AsEntityInput() CreateSubscriptionEntityInput
func (Subscription) GetStatusAt ¶
func (s Subscription) GetStatusAt(at time.Time) SubscriptionStatus
type SubscriptionAction ¶
type SubscriptionAction string
const ( SubscriptionActionCreate SubscriptionAction = "create" SubscriptionActionUpdate SubscriptionAction = "update" SubscriptionActionCancel SubscriptionAction = "cancel" SubscriptionActionContinue SubscriptionAction = "continue" SubscriptionActionDelete SubscriptionAction = "delete" )
type SubscriptionEntitlement ¶
type SubscriptionEntitlement struct {
Entitlement entitlement.Entitlement
Cadence models.CadencedModel
}
func (SubscriptionEntitlement) ToScheduleSubscriptionEntitlementInput ¶
func (s SubscriptionEntitlement) ToScheduleSubscriptionEntitlementInput() ScheduleSubscriptionEntitlementInput
func (SubscriptionEntitlement) Validate ¶
func (s SubscriptionEntitlement) Validate() error
type SubscriptionItem ¶
type SubscriptionItem struct {
models.NamespacedID `json:",inline"`
models.ManagedModel `json:",inline"`
models.AnnotatedModel `json:",inline"`
// 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 *isodate.Period `json:"activeFromOverrideRelativeToPhaseStart,omitempty"`
ActiveToOverrideRelativeToPhaseStart *isodate.Period `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 RateCard `json:"rateCard"`
EntitlementID *string `json:"entitlementId,omitempty"`
// Name
Name string `json:"name"`
// Description
Description *string `json:"description,omitempty"`
}
func (SubscriptionItem) AsEntityInput ¶
func (i SubscriptionItem) AsEntityInput() CreateSubscriptionItemEntityInput
func (SubscriptionItem) GetCadence ¶
func (i SubscriptionItem) GetCadence(phaseCadence models.CadencedModel) models.CadencedModel
type SubscriptionItemRef ¶
type SubscriptionItemRef struct {
SubscriptionId string `json:"subscriptionId"`
PhaseKey string `json:"phaseKey"`
ItemKey string `json:"itemKey"`
}
SubscriptionItemRef is an unstable reference to a SubscriptionItem
func (SubscriptionItemRef) Equals ¶
func (r SubscriptionItemRef) Equals(r2 SubscriptionItemRef) bool
type SubscriptionItemRepository ¶
type SubscriptionItemRepository interface {
entutils.TxCreator
GetForSubscriptionAt(ctx context.Context, subscriptionID models.NamespacedID, at time.Time) ([]SubscriptionItem, error)
Create(ctx context.Context, input CreateSubscriptionItemEntityInput) (SubscriptionItem, error)
Delete(ctx context.Context, id models.NamespacedID) error
GetByID(ctx context.Context, id models.NamespacedID) (SubscriptionItem, error)
}
type SubscriptionItemSpec ¶
type SubscriptionItemSpec struct {
CreateSubscriptionItemInput `json:",inline"`
}
func (SubscriptionItemSpec) GetCadence ¶
func (s SubscriptionItemSpec) GetCadence(phaseCadence models.CadencedModel) models.CadencedModel
func (SubscriptionItemSpec) GetRef ¶
func (s SubscriptionItemSpec) GetRef(subId string) SubscriptionItemRef
func (SubscriptionItemSpec) ToCreateSubscriptionItemEntityInput ¶
func (s SubscriptionItemSpec) ToCreateSubscriptionItemEntityInput( phaseID models.NamespacedID, phaseCadence models.CadencedModel, entitlement *entitlement.Entitlement, ) (CreateSubscriptionItemEntityInput, error)
func (SubscriptionItemSpec) ToScheduleSubscriptionEntitlementInput ¶
func (s SubscriptionItemSpec) ToScheduleSubscriptionEntitlementInput( cust customer.Customer, cadence models.CadencedModel, ) (ScheduleSubscriptionEntitlementInput, bool, error)
func (*SubscriptionItemSpec) Validate ¶
func (s *SubscriptionItemSpec) Validate() error
type SubscriptionItemView ¶
type SubscriptionItemView struct {
SubscriptionItem SubscriptionItem `json:"subscriptionItem"`
Spec SubscriptionItemSpec `json:"spec"`
Entitlement *SubscriptionEntitlement `json:"entitlement,omitempty"`
}
func (*SubscriptionItemView) AsSpec ¶
func (s *SubscriptionItemView) AsSpec() SubscriptionItemSpec
func (*SubscriptionItemView) Validate ¶
func (s *SubscriptionItemView) Validate() error
type SubscriptionList ¶
type SubscriptionList = pagination.PagedResponse[Subscription]
type SubscriptionPhase ¶
type SubscriptionPhase struct {
models.NamespacedID `json:",inline"`
models.ManagedModel `json:",inline"`
models.AnnotatedModel `json:",inline"`
ActiveFrom time.Time `json:"activeFrom"`
// SubscriptionID is the ID of the subscription this phase belongs to.
SubscriptionID string `json:"subscriptionId"`
// Key is the unique key for Phase.
Key string `json:"key"`
// Name
Name string `json:"name"`
// Description
Description *string `json:"description,omitempty"`
}
type SubscriptionPhaseRepository ¶
type SubscriptionPhaseRepository interface {
entutils.TxCreator
// Returns the phases for a subscription
GetForSubscriptionAt(ctx context.Context, subscriptionID models.NamespacedID, at time.Time) ([]SubscriptionPhase, error)
// Create a new subscription phase
Create(ctx context.Context, input CreateSubscriptionPhaseEntityInput) (SubscriptionPhase, error)
Delete(ctx context.Context, id models.NamespacedID) error
}
type SubscriptionPhaseSpec ¶
type SubscriptionPhaseSpec struct {
// Duration is not part of the Spec by design
CreateSubscriptionPhasePlanInput `json:",inline"`
CreateSubscriptionPhaseCustomerInput `json:",inline"`
// In each key, for each phase, we have a list of item specs to account for mid-phase changes
ItemsByKey map[string][]*SubscriptionItemSpec `json:"itemsByKey"`
}
func (SubscriptionPhaseSpec) GetBillableItemsByKey ¶
func (s SubscriptionPhaseSpec) GetBillableItemsByKey() map[string][]*SubscriptionItemSpec
GetBillableItemsByKey returns a map of billable items by key
func (SubscriptionPhaseSpec) GetBillingCadence ¶
func (s SubscriptionPhaseSpec) GetBillingCadence() (isodate.Period, error)
func (SubscriptionPhaseSpec) HasBillables ¶
func (s SubscriptionPhaseSpec) HasBillables() bool
func (SubscriptionPhaseSpec) ToCreateSubscriptionPhaseEntityInput ¶
func (s SubscriptionPhaseSpec) ToCreateSubscriptionPhaseEntityInput( subscription Subscription, activeFrom time.Time, ) CreateSubscriptionPhaseEntityInput
func (SubscriptionPhaseSpec) Validate ¶
func (s SubscriptionPhaseSpec) Validate( phaseCadence models.CadencedModel, alignment productcatalog.Alignment, ) error
type SubscriptionPhaseView ¶
type SubscriptionPhaseView struct {
SubscriptionPhase SubscriptionPhase `json:"subscriptionPhase"`
Spec SubscriptionPhaseSpec `json:"spec"`
ItemsByKey map[string][]SubscriptionItemView `json:"itemsByKey"`
}
func (*SubscriptionPhaseView) ActiveFrom ¶
func (s *SubscriptionPhaseView) ActiveFrom(subscriptionCadence models.CadencedModel) time.Time
func (*SubscriptionPhaseView) AsSpec ¶
func (s *SubscriptionPhaseView) AsSpec() SubscriptionPhaseSpec
func (*SubscriptionPhaseView) Validate ¶
func (s *SubscriptionPhaseView) Validate(includeItems bool) error
type SubscriptionRepository ¶
type SubscriptionRepository interface {
entutils.TxCreator
models.CadencedResourceRepo[Subscription]
// Returns all subscriptions active or scheduled after the given timestamp
GetAllForCustomerSince(ctx context.Context, customerID models.NamespacedID, at time.Time) ([]Subscription, error)
// Returns the subscription by ID
GetByID(ctx context.Context, subscriptionID models.NamespacedID) (Subscription, error)
// Create a new subscription
Create(ctx context.Context, input CreateSubscriptionEntityInput) (Subscription, error)
// Delete a subscription
Delete(ctx context.Context, id models.NamespacedID) error
// List subscriptions
List(ctx context.Context, params ListSubscriptionsInput) (SubscriptionList, error)
}
type SubscriptionSpec ¶
type SubscriptionSpec struct {
CreateSubscriptionPlanInput `json:",inline"`
CreateSubscriptionCustomerInput `json:",inline"`
// We use pointers so Patches can manipulate the spec
Phases map[string]*SubscriptionPhaseSpec `json:"phases"`
}
func NewSpecFromPlan ¶
func NewSpecFromPlan(p Plan, c CreateSubscriptionCustomerInput) (SubscriptionSpec, error)
NewSpecFromPlan creates a SubscriptionSpec from a Plan and a CreateSubscriptionCustomerInput.
func (*SubscriptionSpec) ApplyPatches ¶
func (s *SubscriptionSpec) ApplyPatches(patches []Applies, context ApplyContext) error
func (*SubscriptionSpec) GetAlignedBillingPeriodAt ¶
func (s *SubscriptionSpec) GetAlignedBillingPeriodAt(phaseKey string, at time.Time) (timeutil.Period, error)
For a phase in an Aligned subscription, there's a single aligned BillingPeriod for all items in that phase. The period starts with the phase and iterates every BillingCadence duration, but can be reanchored to the time of an edit.
func (*SubscriptionSpec) GetCurrentPhaseAt ¶
func (s *SubscriptionSpec) GetCurrentPhaseAt(t time.Time) (*SubscriptionPhaseSpec, bool)
func (*SubscriptionSpec) GetPhaseCadence ¶
func (s *SubscriptionSpec) GetPhaseCadence(phaseKey string) (models.CadencedModel, error)
func (*SubscriptionSpec) GetSortedPhases ¶
func (s *SubscriptionSpec) GetSortedPhases() []*SubscriptionPhaseSpec
GetSortedPhases returns the subscription phase references time sorted order ASC.
func (*SubscriptionSpec) ToCreateSubscriptionEntityInput ¶
func (s *SubscriptionSpec) ToCreateSubscriptionEntityInput(ns string) CreateSubscriptionEntityInput
func (*SubscriptionSpec) Validate ¶
func (s *SubscriptionSpec) Validate() error
type SubscriptionStateMachine ¶
type SubscriptionStateMachine struct {
// contains filtered or unexported fields
}
SubscriptionStateMachine is a very simple state machine that determines what actions can be taken on a Subscription
func NewStateMachine ¶
func NewStateMachine(status SubscriptionStatus) SubscriptionStateMachine
func (SubscriptionStateMachine) CanTransitionOrErr ¶
func (sm SubscriptionStateMachine) CanTransitionOrErr(ctx context.Context, action SubscriptionAction) error
type SubscriptionStatus ¶
type SubscriptionStatus string
const ( // Active means the subscription is active and the customer is being billed SubscriptionStatusActive SubscriptionStatus = "active" // Canceled means the subscription has already been canceled but is still active SubscriptionStatusCanceled SubscriptionStatus = "canceled" // Inactive means the subscription is inactive (might have been previously active) and the customer is not being billed SubscriptionStatusInactive SubscriptionStatus = "inactive" // Scheduled means the subscription is scheduled to be active in the future SubscriptionStatusScheduled SubscriptionStatus = "scheduled" )
func (SubscriptionStatus) Validate ¶
func (s SubscriptionStatus) Validate() error
type SubscriptionValidator ¶
type SubscriptionValidator interface {
ValidateCreate(context.Context, SubscriptionView) error
ValidateUpdate(context.Context, SubscriptionView) error
ValidateCancel(context.Context, SubscriptionView) error
ValidateContinue(context.Context, SubscriptionView) error
ValidateDelete(context.Context, SubscriptionView) error
}
type SubscriptionView ¶
type SubscriptionView struct {
Subscription Subscription `json:"subscription"`
Customer customer.Customer `json:"customer"`
Spec SubscriptionSpec `json:"spec"`
Phases []SubscriptionPhaseView `json:"phases"`
}
func NewSubscriptionView ¶
func NewSubscriptionView( sub Subscription, cust customer.Customer, phases []SubscriptionPhase, items []SubscriptionItem, ents []SubscriptionEntitlement, ) (*SubscriptionView, error)
func (SubscriptionView) AsSpec ¶
func (s SubscriptionView) AsSpec() SubscriptionSpec
func (SubscriptionView) GetPhaseByKey ¶
func (s SubscriptionView) GetPhaseByKey(key string) (*SubscriptionPhaseView, bool)
func (*SubscriptionView) Validate ¶
func (s *SubscriptionView) Validate(includePhases bool) error
type Timing ¶
type Timing struct {
Custom *time.Time
Enum *TimingEnum
}
Timing represents the timing of a change in a subscription, such as a plan change or a cancellation.
func (Timing) ResolveForSpec ¶
func (c Timing) ResolveForSpec(spec SubscriptionSpec) (time.Time, error)
func (Timing) ValidateForAction ¶
func (c Timing) ValidateForAction(action SubscriptionAction, subView *SubscriptionView) error
type TimingEnum ¶
type TimingEnum string
const ( // Immediate means the change will take effect immediately. TimingImmediate TimingEnum = "immediate" // NextBillingCycle means the change will take effect at the start of the next billing cycle. // This value is only supported for aligned subscriptions. TimingNextBillingCycle TimingEnum = "next_billing_cycle" )
func (TimingEnum) Validate ¶
func (c TimingEnum) Validate() error
type UpdatedEvent ¶
type UpdatedEvent struct {
// We can consider adding the old version or diff here if needed
UpdatedView SubscriptionView `json:"updatedView"`
}
func (UpdatedEvent) EventMetadata ¶
func (s UpdatedEvent) EventMetadata() metadata.EventMetadata
func (UpdatedEvent) EventName ¶
func (s UpdatedEvent) EventName() string
func (UpdatedEvent) Validate ¶
func (s UpdatedEvent) Validate() error
type ValuePatch ¶
type ValuePatch[T any] interface { Patch Value() T AnyValuePatch }
type WorkflowService ¶
type WorkflowService interface {
CreateFromPlan(ctx context.Context, inp CreateSubscriptionWorkflowInput, plan Plan) (SubscriptionView, error)
EditRunning(ctx context.Context, subscriptionID models.NamespacedID, customizations []Patch, timing Timing) (SubscriptionView, error)
ChangeToPlan(ctx context.Context, subscriptionID models.NamespacedID, inp ChangeSubscriptionWorkflowInput, plan Plan) (current Subscription, new SubscriptionView, err error)
}