Documentation
¶
Index ¶
- Constants
- Variables
- func AddonRateCardMatcherForAGivenPlanRateCard(planRateCard RateCard) func(addonRateCard RateCard) bool
- func PercentageDiscountWithValidValue() models.ValidatorFunc[PercentageDiscount]
- func ResolveTaxConfig(ctx context.Context, svc taxcode.Service, namespace string, cfg *TaxConfig) error
- func UsageDiscountWithPrice(price *Price) models.ValidatorFunc[UsageDiscount]
- func UsageDiscountWithValidValue() models.ValidatorFunc[UsageDiscount]
- func ValidateAddonBillingCadenceAreAlignedWithPlan(addonRateCards RateCards) models.ValidatorFunc[Plan]
- func ValidateAddonHasCompatiblePrices() models.ValidatorFunc[Addon]
- func ValidateAddonHasSingleBillingCadence() models.ValidatorFunc[Addon]
- func ValidateAddonMeta() models.ValidatorFunc[Addon]
- func ValidateAddonRateCards() models.ValidatorFunc[Addon]
- func ValidateAddonStatusPublishable() models.ValidatorFunc[Addon]
- func ValidateAddonWithFeatures(ctx context.Context, resolver NamespacedFeatureResolver) models.ValidatorFunc[Addon]
- func ValidateAddonWithStatus(allowed ...AddonStatus) models.ValidatorFunc[Addon]
- func ValidateBillingCadencesAlign(planBillingCadence datetime.ISODuration, ...) error
- func ValidateEffectivePeriod() models.ValidatorFunc[EffectivePeriod]
- func ValidatePhaseMeta() models.ValidatorFunc[Phase]
- func ValidatePhaseRateCards() models.ValidatorFunc[Phase]
- func ValidatePlanBillingCadenceLiteral() models.ValidatorFunc[Plan]
- func ValidatePlanHasAlignedBillingCadences() models.ValidatorFunc[Plan]
- func ValidatePlanMeta() models.ValidatorFunc[Plan]
- func ValidatePlanPhaseAndAddonRateCardsAreCompatible(addonRateCards RateCards) models.ValidatorFunc[Phase]
- func ValidatePlanPhases() models.ValidatorFunc[Plan]
- func ValidatePlanWithFeatures(ctx context.Context, resolver NamespacedFeatureResolver) models.ValidatorFunc[Plan]
- func ValidateRateCards() models.ValidatorFunc[RateCards]
- func ValidateRateCardsWithFeatures(ctx context.Context, resolver NamespacedFeatureResolver) func(cards RateCards) error
- type Addon
- type AddonInstanceType
- type AddonMeta
- type AddonStatus
- type BooleanEntitlementTemplate
- type Commitments
- type Discounts
- type DynamicPrice
- type EffectivePeriod
- type EntitlementTemplate
- func (e *EntitlementTemplate) AsBoolean() (BooleanEntitlementTemplate, error)
- func (e *EntitlementTemplate) AsMetered() (MeteredEntitlementTemplate, error)
- func (e *EntitlementTemplate) AsStatic() (StaticEntitlementTemplate, error)
- func (e *EntitlementTemplate) Equal(v *EntitlementTemplate) bool
- func (e *EntitlementTemplate) FromBoolean(t BooleanEntitlementTemplate)
- func (e *EntitlementTemplate) FromMetered(t MeteredEntitlementTemplate)
- func (e *EntitlementTemplate) FromStatic(t StaticEntitlementTemplate)
- func (e *EntitlementTemplate) MarshalJSON() ([]byte, error)
- func (e *EntitlementTemplate) Type() entitlement.EntitlementType
- func (e *EntitlementTemplate) UnmarshalJSON(bytes []byte) error
- func (e *EntitlementTemplate) Validate() error
- type FeatureResolver
- type FlatFeeRateCard
- func (r *FlatFeeRateCard) AsMeta() RateCardMeta
- func (r *FlatFeeRateCard) ChangeMeta(fn func(m RateCardMeta) (RateCardMeta, error)) error
- func (r *FlatFeeRateCard) Clone() RateCard
- func (r *FlatFeeRateCard) Compatible(v RateCard) error
- func (r *FlatFeeRateCard) Equal(v RateCard) bool
- func (r *FlatFeeRateCard) GetBillingCadence() *datetime.ISODuration
- func (r *FlatFeeRateCard) Key() string
- func (r *FlatFeeRateCard) MarshalJSON() ([]byte, error)
- func (r *FlatFeeRateCard) Merge(v RateCard) error
- func (r *FlatFeeRateCard) Type() RateCardType
- func (r *FlatFeeRateCard) Validate() error
- func (r *FlatFeeRateCard) ValidateWith(v ...models.ValidatorFunc[*FlatFeeRateCard]) error
- type FlatPrice
- type MeteredEntitlementTemplate
- type NamespacedFeatureResolver
- type PackagePrice
- type PaymentTermType
- type PercentageDiscount
- func (d PercentageDiscount) Clone() PercentageDiscount
- func (d PercentageDiscount) Hash() hasher.Hash
- func (d PercentageDiscount) Validate() error
- func (d PercentageDiscount) ValidateForPrice(_ *Price) error
- func (d PercentageDiscount) ValidateWith(v ...models.ValidatorFunc[PercentageDiscount]) error
- type Phase
- type PhaseMeta
- type Plan
- type PlanAddon
- type PlanAddonConfig
- type PlanAddonMeta
- type PlanMeta
- type PlanStatus
- type Price
- func (p *Price) AsDynamic() (DynamicPrice, error)
- func (p *Price) AsFlat() (FlatPrice, error)
- func (p *Price) AsPackage() (PackagePrice, error)
- func (p *Price) AsTiered() (TieredPrice, error)
- func (p *Price) AsUnit() (UnitPrice, error)
- func (p *Price) Clone() *Price
- func (p *Price) Equal(v *Price) bool
- func (p *Price) FromDynamic(price DynamicPrice)
- func (p *Price) FromFlat(price FlatPrice)
- func (p *Price) FromPackage(price PackagePrice)
- func (p *Price) FromTiered(price TieredPrice)
- func (p *Price) FromUnit(price UnitPrice)
- func (p *Price) GetCommitments() Commitments
- func (p *Price) GetPaymentTerm() PaymentTermType
- func (p Price) MarshalJSON() ([]byte, error)
- func (p *Price) SupportsUnitConfig() bool
- func (p *Price) Type() PriceType
- func (p *Price) UnmarshalJSON(bytes []byte) error
- func (p *Price) Validate() error
- type PriceTier
- type PriceTierFlatPrice
- type PriceTierUnitPrice
- type PriceType
- type ProRatingConfig
- type ProRatingMode
- type RateCard
- type RateCardFeature
- type RateCardMeta
- func (r RateCardMeta) Clone() RateCardMeta
- func (r RateCardMeta) Equal(v RateCardMeta) bool
- func (r RateCardMeta) GetFeatureID() *string
- func (r RateCardMeta) GetFeatureKey() *string
- func (r RateCardMeta) HasFeature() bool
- func (r RateCardMeta) IsBillable() bool
- func (r *RateCardMeta) SetFeature(id, key *string)
- func (r RateCardMeta) Validate() error
- func (r RateCardMeta) ValidateWith(v ...models.ValidatorFunc[RateCardMeta]) error
- type RateCardSerde
- type RateCardType
- type RateCardWithOverlay
- type RateCards
- func (c RateCards) At(idx int) RateCard
- func (c RateCards) Billables() RateCards
- func (c RateCards) Clone() RateCards
- func (c RateCards) Equal(v RateCards) bool
- func (c RateCards) HasUnitConfig() bool
- func (c RateCards) SingleBillingCadence() bool
- func (c RateCards) Validate() error
- func (c RateCards) ValidateWith(v ...models.ValidatorFunc[RateCards]) error
- type SettlementMode
- type StaticEntitlementTemplate
- type StripeTaxConfig
- type TaxBehavior
- type TaxCodeConfig
- type TaxConfig
- type TieredPrice
- type TieredPriceMode
- type UnitConfig
- type UnitConfigOperation
- type UnitConfigRoundingMode
- type UnitPrice
- type UsageBasedRateCard
- func (r *UsageBasedRateCard) AsMeta() RateCardMeta
- func (r *UsageBasedRateCard) ChangeMeta(fn func(m RateCardMeta) (RateCardMeta, error)) error
- func (r *UsageBasedRateCard) Clone() RateCard
- func (r *UsageBasedRateCard) Compatible(v RateCard) error
- func (r *UsageBasedRateCard) Equal(v RateCard) bool
- func (r *UsageBasedRateCard) GetBillingCadence() *datetime.ISODuration
- func (r *UsageBasedRateCard) Key() string
- func (r *UsageBasedRateCard) MarshalJSON() ([]byte, error)
- func (r *UsageBasedRateCard) Merge(v RateCard) error
- func (r *UsageBasedRateCard) Type() RateCardType
- func (r *UsageBasedRateCard) Validate() error
- func (r *UsageBasedRateCard) ValidateWith(v ...models.ValidatorFunc[*UsageBasedRateCard]) error
- type UsageDiscount
Constants ¶
const DefaultPaymentTerm = InAdvancePaymentTerm
const ErrCodeAddonHasNoRateCards models.ErrorCode = "addon_has_no_rate_cards"
const ErrCodeAddonInvalidInstanceType models.ErrorCode = "addon_invalid_instance_type"
const ErrCodeAddonInvalidPriceForMultiInstance models.ErrorCode = "addon_invalid_ratecard_price_for_multi_instance"
const ErrCodeAddonInvalidStatus models.ErrorCode = "addon_invalid_status"
const ErrCodeAddonInvalidStatusForPublish models.ErrorCode = "addon_invalid_status_for_publish"
const ErrCodeAddonKeyEmpty models.ErrorCode = "addon_key_empty"
const ErrCodeAddonNameEmpty models.ErrorCode = "addon_name_empty"
const ErrCodeAddonRateCardUnitConfigMismatch models.ErrorCode = "addon_rate_card_unit_config_mismatch"
const ErrCodeBillingCadenceInvalidValue models.ErrorCode = "billing_cadence_invalid_value"
const ErrCodeCurrencyInvalid models.ErrorCode = "currency_invalid"
const ErrCodeDeprecatedUnalignedSubscription models.ErrorCode = "deprecated_unaligned_subscription"
const ErrCodeEffectivePeriodFromAfterTo models.ErrorCode = "effective_period_from_after_to"
const ErrCodeEffectivePeriodFromNotSet models.ErrorCode = "effective_period_from_not_set"
const ErrCodeEntitlementTemplateInvalidIssueAfterResetWithPriority models.ErrorCode = "entitlement_template_invalid_issue_after_reset_with_priority"
const ErrCodeEntitlementTemplateInvalidJSONConfig models.ErrorCode = "entitlement_template_invalid_json_config"
const ErrCodeEntitlementTemplateIssueAfterResetRequired models.ErrorCode = "entitlement_template_issue_after_reset_required"
const ErrCodeEntitlementTemplateNegativeUsagePeriod models.ErrorCode = "entitlement_template_negative_usage_period"
const ErrCodeEntitlementTemplateUsagePeriodLessThenAnHour models.ErrorCode = "entitlement_template_usage_period_less_then_an_hour"
const ErrCodeIDEmpty models.ErrorCode = "resource_id_empty"
const ErrCodeNamespaceEmpty models.ErrorCode = "resource_namespace_empty"
const ErrCodePercentageDiscountInvalidValue models.ErrorCode = "percentage_discount_invalid_value"
const ErrCodePlanAddonCurrencyMismatch models.ErrorCode = "plan_addon_currency_mismatch"
const ErrCodePlanAddonIncompatibleStatus models.ErrorCode = "plan_addon_incompatible_status"
const ErrCodePlanAddonMaxQuantityMustBeSet models.ErrorCode = "plan_addon_max_quantity_must_be_set"
const ErrCodePlanAddonMaxQuantityMustNotBeSet models.ErrorCode = "plan_addon_max_quantity_must_not_be_set"
const ErrCodePlanAddonUnknownPlanPhaseKey models.ErrorCode = "plan_addon_unknown_plan_phase_key"
const ErrCodePlanBillingCadenceInvalid models.ErrorCode = "plan_billing_cadence_invalid"
const ErrCodePlanBillingCadenceNotCompatible models.ErrorCode = "plan_billing_cadence_not_compatible"
const ErrCodePlanHasIncompatibleAddon models.ErrorCode = "plan_has_incompatible_addon"
const ErrCodePlanHasLastPhaseWithDuration models.ErrorCode = "plan_has_last_phase_with_duration"
const ErrCodePlanHasNonLastPhaseWithNoDuration models.ErrorCode = "plan_has_non_last_phase_with_no_duration"
const ErrCodePlanInvalidStatus models.ErrorCode = "plan_invalid_status"
const ErrCodePlanPhaseDuplicatedKey models.ErrorCode = "plan_phase_duplicated_key"
const ErrCodePlanPhaseDurationLessThenAnHour models.ErrorCode = "plan_phase_duration_less_then_an_hour"
const ErrCodePlanPhaseHasNoRateCards models.ErrorCode = "plan_phase_has_no_rate_cards"
const ErrCodePlanPhaseWithNegativeDuration models.ErrorCode = "plan_phase_with_negative_duration"
const ErrCodePlanWithNoPhases models.ErrorCode = "plan_with_no_phases"
const ErrCodeRateCardBillingCadenceMismatch models.ErrorCode = "rate_card_billing_cadence_mismatch"
const ErrCodeRateCardBillingCadenceUnaligned models.ErrorCode = "rate_card_billing_cadence_unaligned"
const ErrCodeRateCardDuplicatedKey models.ErrorCode = "rate_card_duplicated_key"
const ErrCodeRateCardEntitlementTemplateTypeMismatch models.ErrorCode = "rate_card_entitlement_template_type_mismatch"
const ErrCodeRateCardEntitlementTemplateWithNoFeature models.ErrorCode = "entitlement_template_with_no_feature"
const ErrCodeRateCardFeatureArchived models.ErrorCode = "rate_card_feature_archived"
const ErrCodeRateCardFeatureIDMismatch models.ErrorCode = "rate_card_feature_id_mismatch"
const ErrCodeRateCardFeatureKeyMismatch models.ErrorCode = "rate_card_feature_key_mismatch"
const ErrCodeRateCardFeatureMismatch models.ErrorCode = "rate_card_feature_mismatch"
const ErrCodeRateCardFeatureNotFound models.ErrorCode = "rate_card_feature_not_found"
const ErrCodeRateCardKeyFeatureKeyMismatch models.ErrorCode = "rate_card_key_feature_key_mismatch"
const ErrCodeRateCardKeyMismatch models.ErrorCode = "rate_card_key_mismatch"
const ErrCodeRateCardMeteredEntitlementTemplateUsagePeriodMismatch models.ErrorCode = "rate_card_metered_entitlement_template_usage_period_mismatch"
const ErrCodeRateCardMultipleBillingCadence models.ErrorCode = "rate_card_multiple_billing_cadence"
const ErrCodeRateCardOnlyFlatPriceAllowed models.ErrorCode = "rate_card_only_flat_price_allowed"
const ErrCodeRateCardPercentageDiscountNotAllowed models.ErrorCode = "rate_card_percentage_discount_not_allowed"
const ErrCodeRateCardPricePaymentTermMismatch models.ErrorCode = "rate_card_price_payment_term_mismatch"
const ErrCodeRateCardPriceTypeMismatch models.ErrorCode = "rate_card_price_type_mismatch"
const ErrCodeRateCardStaticEntitlementTemplateNotAllowed models.ErrorCode = "rate_card_static_entitlement_template_not_allowed"
const ErrCodeRateCardUnitConfigRequiresUsageBasedPrice models.ErrorCode = "unit_config_requires_usage_based_price"
const ErrCodeRateCardUsageBasedPriceWithFeatureAndNoMeter models.ErrorCode = "usage_based_price_with_feature_and_no_meter"
const ErrCodeRateCardUsageBasedPriceWithNoFeature models.ErrorCode = "usage_based_price_with_no_feature"
const ErrCodeResourceKeyEmpty models.ErrorCode = "resource_key_empty"
const ErrCodeResourceNameEmpty models.ErrorCode = "resource_name_empty"
const ErrCodeUnitConfigNotRepresentable models.ErrorCode = "unit_config_not_representable"
const ErrCodeUsageDiscountNegativeQuantity models.ErrorCode = "usage_discount_negative_quantity"
const ErrCodeUsageDiscountWithFlatPrice models.ErrorCode = "usage_discount_with_flat_price"
Variables ¶
var DynamicPriceDefaultMultiplier = decimal.NewFromFloat(1)
var ErrAddonHasNoRateCards = models.NewValidationIssue( ErrCodeAddonHasNoRateCards, "add-on must have at least one rate card", models.WithFieldString("rateCards"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrAddonInvalidInstanceType = models.NewValidationIssue( ErrCodeAddonInvalidInstanceType, "invalid instance type", models.WithFieldString("instanceType"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrAddonInvalidPriceForMultiInstance = models.NewValidationIssue( ErrCodeAddonInvalidPriceForMultiInstance, "only free or flat price ratecards are allowed for add-on with multiple instance type", models.WithFieldString("price"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrAddonInvalidStatus = models.NewValidationIssue( ErrCodeAddonInvalidStatus, "invalid status", models.WithFieldString("status"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrAddonInvalidStatusForPublish = models.NewValidationIssue( ErrCodeAddonInvalidStatusForPublish, "only draft add-ons can be published", models.WithFieldString("status"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrAddonKeyEmpty = models.NewValidationIssue( ErrCodeAddonKeyEmpty, "key must not be empty", models.WithFieldString("key"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrAddonNameEmpty = models.NewValidationIssue( ErrCodeAddonNameEmpty, "name must not be empty", models.WithFieldString("name"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrAddonRateCardUnitConfigMismatch = models.NewValidationIssue( ErrCodeAddonRateCardUnitConfigMismatch, "unit config must match", models.WithFieldString("unitConfig"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
ErrAddonRateCardUnitConfigMismatch is raised when an addon rate card carries a unit_config that differs from the rate card it extends. Addons layer price/entitlement/discounts additively but do not redefine the unit conversion; a divergent unit_config would be silently dropped by the overlay, so it is rejected here rather than accepted and ignored.
var ErrBillingCadenceInvalidValue = models.NewValidationIssue( ErrCodeBillingCadenceInvalidValue, "billing cadence must be positive and 1 hour long duration at least", models.WithFieldString("billingCadence"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrCurrencyInvalid = models.NewValidationIssue( ErrCodeCurrencyInvalid, "currency is invalid", models.WithFieldString("currency"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrDeprecatedUnalignedSubscription = models.NewValidationIssue( ErrCodeDeprecatedUnalignedSubscription, "unaligned subscriptions are being deprecated", models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrEffectivePeriodFromAfterTo = models.NewValidationIssue( ErrCodeEffectivePeriodFromAfterTo, "effectiveFrom is after effectiveTo", models.WithFieldString("effectiveFrom"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrEffectivePeriodFromNotSet = models.NewValidationIssue( ErrCodeEffectivePeriodFromNotSet, "effectiveFrom is must be provided if effectiveTo is set", models.WithFieldString("effectiveFrom"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrEntitlementTemplateInvalidIssueAfterResetWithPriority = models.NewValidationIssue( ErrCodeEntitlementTemplateInvalidIssueAfterResetWithPriority, "invalid entitlement template as issue after reset is required if issue after reset priority is set", models.WithFieldString("issueAfterReset"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrEntitlementTemplateInvalidJSONConfig = models.NewValidationIssue( ErrCodeEntitlementTemplateInvalidJSONConfig, "invalid JSON in static entitlement config", models.WithFieldString("entitlementTemplate", "config"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrEntitlementTemplateIssueAfterResetRequired = models.NewValidationIssue( ErrCodeEntitlementTemplateIssueAfterResetRequired, "issueAfterReset is required for metered entitlement templates", models.WithFieldString("entitlementTemplate", "issueAfterReset"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrEntitlementTemplateNegativeUsagePeriod = models.NewValidationIssue( ErrCodeEntitlementTemplateNegativeUsagePeriod, "usage period must be positive", models.WithFieldString("usagePeriod"), models.WithWarningSeverity(), )
var ErrEntitlementTemplateUsagePeriodLessThenAnHour = models.NewValidationIssue( ErrCodeEntitlementTemplateUsagePeriodLessThenAnHour, "usage period must be at least 1 hour", models.WithFieldString("usagePeriod"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrIDEmpty = models.NewValidationIssue( ErrCodeIDEmpty, "id must not be empty", models.WithFieldString("id"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrNamespaceEmpty = models.NewValidationIssue( ErrCodeNamespaceEmpty, "namespace must not be empty", models.WithFieldString("namespace"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPercentageDiscountInvalidValue = models.NewValidationIssue( ErrCodePercentageDiscountInvalidValue, "percentage must be between 0 and 100", models.WithFieldString("percentage"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPlanAddonCurrencyMismatch = models.NewValidationIssue( ErrCodePlanAddonCurrencyMismatch, "currency of the plan and addon must match", models.WithFieldString("currency"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPlanAddonIncompatibleStatus = models.NewValidationIssue( ErrCodePlanAddonIncompatibleStatus, "plan status is incompatible with the addon status", models.WithFieldString("status"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPlanAddonMaxQuantityMustBeSet = models.NewValidationIssue( ErrCodePlanAddonMaxQuantityMustBeSet, "maximum quantity, when set, must be a positive integer for add-ons with multiple instance type", models.WithFieldString("maxQuantity"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPlanAddonMaxQuantityMustNotBeSet = models.NewValidationIssue( ErrCodePlanAddonMaxQuantityMustNotBeSet, "maximum quantity must not be set for add-on with single instance type", models.WithFieldString("maxQuantity"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPlanAddonUnknownPlanPhaseKey = models.NewValidationIssue( ErrCodePlanAddonUnknownPlanPhaseKey, "add-on must define valid/existing plan phase key from which the add-on is available for purchase", models.WithFieldString("fromPlanPhase"), models.WithWarningSeverity(), )
var ErrPlanBillingCadenceAllowedValues = []datetime.ISODurationString{
"P1W",
"P2W",
"P4W",
"P1M",
"P3M",
"P6M",
"P12M",
"P1Y",
}
var ErrPlanBillingCadenceInvalid = models.NewValidationIssue( ErrCodePlanBillingCadenceInvalid, fmt.Sprintf("billing cadence must be one of the following: %s", strings.Join(lo.Map(ErrPlanBillingCadenceAllowedValues, func(v datetime.ISODurationString, _ int) string { return v.String() }), ", ")), models.WithFieldString("billingCadence"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPlanBillingCadenceNotCompatible = models.NewValidationIssue( ErrCodePlanBillingCadenceNotCompatible, "plan billing cadence is not compatible with rate card billing cadence", models.WithFieldString("billingCadence"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPlanHasIncompatibleAddon = models.NewValidationIssue( ErrCodePlanHasIncompatibleAddon, "plan has incompatible add-on assignment", models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPlanHasLastPhaseWithDuration = models.NewValidationIssue( ErrCodePlanHasLastPhaseWithDuration, "duration must not be set for the last plan phase", models.WithFieldString("duration"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPlanHasNonLastPhaseWithNoDuration = models.NewValidationIssue( ErrCodePlanHasNonLastPhaseWithNoDuration, "duration must be set for plan phase if it is not the last one", models.WithFieldString("duration"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPlanInvalidStatus = models.NewValidationIssue( ErrCodePlanInvalidStatus, "invalid status", models.WithFieldString("status"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPlanPhaseDuplicatedKey = models.NewValidationIssue( ErrCodePlanPhaseDuplicatedKey, "duplicated key", models.WithFieldString("key"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPlanPhaseDurationLessThenAnHour = models.NewValidationIssue( ErrCodePlanPhaseDurationLessThenAnHour, "duration must be at least 1 hour", models.WithFieldString("duration"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPlanPhaseHasNoRateCards = models.NewValidationIssue( ErrCodePlanPhaseHasNoRateCards, "plan phase must have at least one rate card", models.WithFieldString("rateCards"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPlanPhaseWithNegativeDuration = models.NewValidationIssue( ErrCodePlanPhaseWithNegativeDuration, "duration must be positive", models.WithFieldString("duration"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPlanWithNoPhases = models.NewValidationIssue( ErrCodePlanWithNoPhases, "plan must have at least one phase", models.WithFieldString("phases"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrRateCardBillingCadenceMismatch = models.NewValidationIssue( ErrCodeRateCardBillingCadenceMismatch, "billing cadence must match", models.WithFieldString("billingCadence"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrRateCardBillingCadenceUnaligned = models.NewValidationIssue( ErrCodeRateCardBillingCadenceUnaligned, "ratecards with prices must have compatible billing cadence", models.WithFieldString("billingCadence"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrRateCardDuplicatedKey = models.NewValidationIssue( ErrCodeRateCardDuplicatedKey, "duplicated key", models.WithFieldString("key"), models.WithCriticalSeverity(), )
var ErrRateCardEntitlementTemplateTypeMismatch = models.NewValidationIssue( ErrCodeRateCardEntitlementTemplateTypeMismatch, "entitlement template type must match", models.WithFieldString("type"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrRateCardEntitlementTemplateWithNoFeature = models.NewValidationIssue( ErrCodeRateCardEntitlementTemplateWithNoFeature, "entitlement template requires feature to be associated with", models.WithFieldString("featureKey"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrRateCardFeatureArchived = models.NewValidationIssue( ErrCodeRateCardFeatureArchived, "feature archived", models.WithFieldString("featureKey"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrRateCardFeatureIDMismatch = models.NewValidationIssue( ErrCodeRateCardFeatureIDMismatch, "feature identifiers id must match", models.WithFieldString("featureId"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrRateCardFeatureKeyMismatch = models.NewValidationIssue( ErrCodeRateCardFeatureKeyMismatch, "feature key must match", models.WithFieldString("featureKey"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrRateCardFeatureMismatch = models.NewValidationIssue( ErrCodeRateCardFeatureMismatch, "feature id and key must reference the same feature", models.WithFieldString("featureKey"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrRateCardFeatureNotFound = models.NewValidationIssue( ErrCodeRateCardFeatureNotFound, "feature not found", models.WithFieldString("featureKey"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrRateCardKeyFeatureKeyMismatch = models.NewValidationIssue( ErrCodeRateCardKeyFeatureKeyMismatch, "rate card key must match feature key", models.WithFieldString("key"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrRateCardKeyMismatch = models.NewValidationIssue( ErrCodeRateCardKeyMismatch, "key must match", models.WithFieldString("key"), models.WithWarningSeverity(), )
var ErrRateCardMeteredEntitlementTemplateUsagePeriodMismatch = models.NewValidationIssue( ErrCodeRateCardMeteredEntitlementTemplateUsagePeriodMismatch, "usage period for metered entitlement template must match", models.WithFieldString("usagePeriod"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrRateCardMultipleBillingCadence = models.NewValidationIssue( ErrCodeRateCardMultipleBillingCadence, "ratecards with prices must have the exact same billing cadence", models.WithFieldString("billingCadence"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrRateCardOnlyFlatPriceAllowed = models.NewValidationIssue( ErrCodeRateCardOnlyFlatPriceAllowed, "only flat price is allowed", models.WithFieldString("price"), models.WithWarningSeverity(), )
var ErrRateCardPercentageDiscountNotAllowed = models.NewValidationIssue( ErrCodeRateCardPercentageDiscountNotAllowed, "percentage discount is not allowed", models.WithFieldString("percentage"), models.WithWarningSeverity(), )
var ErrRateCardPricePaymentTermMismatch = models.NewValidationIssue( ErrCodeRateCardPricePaymentTermMismatch, "price payment term must match", models.WithFieldString("price"), models.WithWarningSeverity(), )
var ErrRateCardPriceTypeMismatch = models.NewValidationIssue( ErrCodeRateCardPriceTypeMismatch, "price type must match", models.WithFieldString("price"), models.WithWarningSeverity(), )
var ErrRateCardStaticEntitlementTemplateNotAllowed = models.NewValidationIssue( ErrCodeRateCardStaticEntitlementTemplateNotAllowed, "static entitlement template is not allowed", models.WithFieldString("type"), models.WithWarningSeverity(), )
var ErrRateCardUnitConfigRequiresUsageBasedPrice = models.NewValidationIssue( ErrCodeRateCardUnitConfigRequiresUsageBasedPrice, "unit config requires a usage-based price (unit, graduated, or volume)", models.WithFieldString("unit_config"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrRateCardUsageBasedPriceWithFeatureAndNoMeter = models.NewValidationIssue( ErrCodeRateCardUsageBasedPriceWithFeatureAndNoMeter, "usage-based price requires feature with meter to be associated with", models.WithFieldString("featureKey"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrRateCardUsageBasedPriceWithNoFeature = models.NewValidationIssue( ErrCodeRateCardUsageBasedPriceWithNoFeature, "usage-based price requires feature to be associated with", models.WithFieldString("featureKey"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrResourceKeyEmpty = models.NewValidationIssue( ErrCodeResourceKeyEmpty, "key must not be empty", models.WithFieldString("key"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrResourceNameEmpty = models.NewValidationIssue( ErrCodeResourceNameEmpty, "name must not be empty", models.WithFieldString("name"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrUnitConfigNotRepresentable = models.NewValidationIssue( ErrCodeUnitConfigNotRepresentable, "this resource uses unit_config and is only available via the v3 API", models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrUsageDiscountNegativeQuantity = models.NewValidationIssue( ErrCodeUsageDiscountNegativeQuantity, "usage must be greater than 0", models.WithFieldString("quantity"), models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrUsageDiscountWithFlatPrice = models.NewValidationIssue( ErrCodeUsageDiscountWithFlatPrice, "usage discount is not supported for flat price", models.WithWarningSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ValidateRateCardsHaveCompatibleBillingCadence = models.ValidatorFunc[RateCardWithOverlay](func(r RateCardWithOverlay) error { if r.base == nil || r.overlay == nil { return nil } var errs []error rBillingCadence, vBillingCadence := r.base.GetBillingCadence(), r.overlay.GetBillingCadence() fieldSelector := models.NewFieldSelectorGroup(models.NewFieldSelector("ratecards"). WithExpression(models.NewFieldAttrValue("key", r.base.Key()))) if rBillingCadence != nil && vBillingCadence != nil && !rBillingCadence.Equal(vBillingCadence) { errs = append(errs, models.ErrorWithFieldPrefix(fieldSelector, ErrRateCardBillingCadenceMismatch)) } return errors.Join(errs...) })
var ValidateRateCardsHaveCompatibleDiscounts = models.ValidatorFunc[RateCardWithOverlay](func(r RateCardWithOverlay) error { if r.base == nil || r.overlay == nil { return nil } var errs []error rMeta, vMeta := r.base.AsMeta(), r.overlay.AsMeta() if rMeta.Discounts.Percentage != nil && vMeta.Discounts.Percentage != nil { fieldSelector := models.NewFieldSelectorGroup(models.NewFieldSelector("discounts")) errs = append(errs, models.ErrorWithFieldPrefix(fieldSelector, ErrRateCardPercentageDiscountNotAllowed)) } err := errors.Join(errs...) if err != nil { fieldSelector := models.NewFieldSelectorGroup( models.NewFieldSelector("ratecards"). WithExpression(models.NewFieldAttrValue("key", r.base.Key())), ) return models.ErrorWithFieldPrefix(fieldSelector, err) } return nil })
var ValidateRateCardsHaveCompatibleEntitlementTemplate = models.ValidatorFunc[RateCardWithOverlay](func(r RateCardWithOverlay) error { if r.base == nil || r.overlay == nil { return nil } var errs []error rMeta, vMeta := r.base.AsMeta(), r.overlay.AsMeta() if rMeta.EntitlementTemplate != nil && vMeta.EntitlementTemplate != nil { if rMeta.EntitlementTemplate.Type() != vMeta.EntitlementTemplate.Type() { errs = append(errs, ErrRateCardEntitlementTemplateTypeMismatch) } else { switch rMeta.EntitlementTemplate.Type() { case entitlement.EntitlementTypeStatic: errs = append(errs, ErrRateCardStaticEntitlementTemplateNotAllowed) case entitlement.EntitlementTypeMetered: rMetered, err := rMeta.EntitlementTemplate.AsMetered() if err != nil { return err } vMetered, err := vMeta.EntitlementTemplate.AsMetered() if err != nil { return err } if !rMetered.UsagePeriod.Equal(&vMetered.UsagePeriod) { errs = append(errs, ErrRateCardMeteredEntitlementTemplateUsagePeriodMismatch) } case entitlement.EntitlementTypeBoolean: } } } err := errors.Join(errs...) if err != nil { fieldSelector := models.NewFieldSelectorGroup( models.NewFieldSelector("ratecards"). WithExpression(models.NewFieldAttrValue("key", r.base.Key())), models.NewFieldSelector("entitlementTemplate"), ) return models.ErrorWithFieldPrefix(fieldSelector, err) } return nil })
var ValidateRateCardsHaveCompatibleFeatureID = models.ValidatorFunc[RateCardWithOverlay](func(r RateCardWithOverlay) error { if r.base == nil || r.overlay == nil { return nil } rMeta, vMeta := r.base.AsMeta(), r.overlay.AsMeta() fieldSelector := models.NewFieldSelectorGroup(models.NewFieldSelector("ratecards"). WithExpression(models.NewFieldAttrValue("key", r.base.Key()))) if rMeta.FeatureID != nil && vMeta.FeatureID != nil && *rMeta.FeatureID != *vMeta.FeatureID { return models.ErrorWithFieldPrefix(fieldSelector, ErrRateCardFeatureIDMismatch) } return nil })
var ValidateRateCardsHaveCompatibleFeatureKey = models.ValidatorFunc[RateCardWithOverlay](func(r RateCardWithOverlay) error { if r.base == nil || r.overlay == nil { return nil } rMeta, vMeta := r.base.AsMeta(), r.overlay.AsMeta() fieldSelector := models.NewFieldSelectorGroup(models.NewFieldSelector("ratecards"). WithExpression(models.NewFieldAttrValue("key", r.base.Key()))) if rMeta.FeatureKey != nil && vMeta.FeatureKey != nil && *rMeta.FeatureKey != *vMeta.FeatureKey { return models.ErrorWithFieldPrefix(fieldSelector, ErrRateCardFeatureKeyMismatch) } return nil })
var ValidateRateCardsHaveCompatiblePrice = models.ValidatorFunc[RateCardWithOverlay](func(r RateCardWithOverlay) error { if r.base == nil || r.overlay == nil { return nil } var errs []error rMeta, vMeta := r.base.AsMeta(), r.overlay.AsMeta() fieldSelector := models.NewFieldSelectorGroup(models.NewFieldSelector("ratecards"). WithExpression(models.NewFieldAttrValue("key", r.base.Key()))) if rMeta.Price != nil && vMeta.Price != nil { if rMeta.Price.Type() != vMeta.Price.Type() { errs = append(errs, models.ErrorWithFieldPrefix(fieldSelector, ErrRateCardPriceTypeMismatch)) } switch rMeta.Price.Type() { case FlatPriceType: rFlat, _ := rMeta.Price.AsFlat() vFlat, _ := vMeta.Price.AsFlat() if rFlat.PaymentTerm != vFlat.PaymentTerm { errs = append(errs, models.ErrorWithFieldPrefix(fieldSelector, ErrRateCardPricePaymentTermMismatch)) } default: errs = append(errs, models.ErrorWithFieldPrefix(fieldSelector, ErrRateCardOnlyFlatPriceAllowed)) } } return errors.Join(errs...) })
var ValidateRateCardsHaveCompatibleUnitConfig = models.ValidatorFunc[RateCardWithOverlay](func(r RateCardWithOverlay) error { if r.base == nil || r.overlay == nil { return nil } rMeta, vMeta := r.base.AsMeta(), r.overlay.AsMeta() if rMeta.UnitConfig != nil && vMeta.UnitConfig != nil && !rMeta.UnitConfig.Equal(vMeta.UnitConfig) { fieldSelector := models.NewFieldSelectorGroup(models.NewFieldSelector("ratecards"). WithExpression(models.NewFieldAttrValue("key", r.base.Key()))) return models.ErrorWithFieldPrefix(fieldSelector, ErrAddonRateCardUnitConfigMismatch) } return nil })
if r.base == nil || r.overlay == nil { return nil } fieldSelector := models.NewFieldSelectorGroup(models.NewFieldSelector("ratecards"). WithExpression(models.NewFieldAttrValue("key", r.base.Key()))) if r.base.Key() != r.overlay.Key() { return models.ErrorWithFieldPrefix(fieldSelector, ErrRateCardKeyMismatch) } return nil })
Functions ¶
func AddonRateCardMatcherForAGivenPlanRateCard ¶
func AddonRateCardMatcherForAGivenPlanRateCard(planRateCard RateCard) func(addonRateCard RateCard) bool
Determines if an Addon RateCard will effect a given Plan RateCard Right now we only support a single RateCard per addon effecting a single plan RateCard and we match them by key. FIXME(galexi): matching like this is unwieldy as sometimes we'd want to match productcatalog.RateCard, sometimes addon.RateCard, or subscriptionaddon.RateCard...
func PercentageDiscountWithValidValue ¶
func PercentageDiscountWithValidValue() models.ValidatorFunc[PercentageDiscount]
func ResolveTaxConfig ¶
func ResolveTaxConfig(ctx context.Context, svc taxcode.Service, namespace string, cfg *TaxConfig) error
ResolveTaxConfig cross-populates TaxCodeID and provider-specific codes on the pointed-to config so the persisted record is internally consistent. Four input cases:
- Only TaxCodeID: looks up the entity, validates it exists (400 if not), and sets Stripe from the entity's Stripe app mapping (or clears Stripe if the entity has no mapping).
- Only Stripe.Code: upserts the TaxCode entity via GetOrCreateByAppMapping and stamps TaxCodeID (idempotent; updating the code txcd_A → txcd_B updates the FK).
- Both TaxCodeID and Stripe.Code: TaxCodeID wins. Stripe is overridden from the entity's Stripe app mapping (or cleared if the entity has no mapping); the caller-supplied Stripe.Code is discarded.
- Neither: no-op.
No-op when cfg is nil.
func UsageDiscountWithPrice ¶
func UsageDiscountWithPrice(price *Price) models.ValidatorFunc[UsageDiscount]
func UsageDiscountWithValidValue ¶
func UsageDiscountWithValidValue() models.ValidatorFunc[UsageDiscount]
func ValidateAddonBillingCadenceAreAlignedWithPlan ¶
func ValidateAddonBillingCadenceAreAlignedWithPlan(addonRateCards RateCards) models.ValidatorFunc[Plan]
func ValidateAddonHasCompatiblePrices ¶
func ValidateAddonHasCompatiblePrices() models.ValidatorFunc[Addon]
func ValidateAddonHasSingleBillingCadence ¶
func ValidateAddonHasSingleBillingCadence() models.ValidatorFunc[Addon]
func ValidateAddonMeta ¶
func ValidateAddonMeta() models.ValidatorFunc[Addon]
ValidateAddonMeta returns a validation function can be passed to the object which implements models.CustomValidator interface. It validates attributes in AddonMeta of Addon.
func ValidateAddonRateCards ¶
func ValidateAddonRateCards() models.ValidatorFunc[Addon]
ValidateAddonRateCards returns a validation function can be passed to the object which implements models.CustomValidator interface. It checks for invalid and duplicated ratecards.
func ValidateAddonStatusPublishable ¶
func ValidateAddonStatusPublishable() models.ValidatorFunc[Addon]
func ValidateAddonWithFeatures ¶
func ValidateAddonWithFeatures(ctx context.Context, resolver NamespacedFeatureResolver) models.ValidatorFunc[Addon]
func ValidateAddonWithStatus ¶
func ValidateAddonWithStatus(allowed ...AddonStatus) models.ValidatorFunc[Addon]
func ValidateBillingCadencesAlign ¶
func ValidateBillingCadencesAlign(planBillingCadence datetime.ISODuration, rateCardBillingCadence datetime.ISODuration) error
Alignment means that either - the two cadences are identical - if a RateCard's cadence is "longer" than the Plan's cadence, the plan cadence must "divide" without remainder the ratecard's cadence - if a RateCard's cadence is "shorter" than the Plan's cadence, the ratecard's cadence must "divide" without remainder the plan's cadence "longer" and "shorter" are not generally meaningful terms for periods, as for instance sometimes P1M equals P4W, sometimes its longer.
func ValidateEffectivePeriod ¶
func ValidateEffectivePeriod() models.ValidatorFunc[EffectivePeriod]
func ValidatePhaseMeta ¶
func ValidatePhaseMeta() models.ValidatorFunc[Phase]
ValidatePhaseMeta returns a validation function can be passed to the object which implements models.CustomValidator interface. It validates attributes in PhaseMeta of Phase.
func ValidatePhaseRateCards ¶
func ValidatePhaseRateCards() models.ValidatorFunc[Phase]
ValidatePhaseRateCards returns a validation function can be passed to the object which implements models.CustomValidator interface. It checks for invalid and duplicated ratecards in Phase.
func ValidatePlanBillingCadenceLiteral ¶
func ValidatePlanBillingCadenceLiteral() models.ValidatorFunc[Plan]
ValidatePlanBillingCadenceLiteral validates that the billing cadence of the plan is at least a month.
func ValidatePlanHasAlignedBillingCadences ¶
func ValidatePlanHasAlignedBillingCadences() models.ValidatorFunc[Plan]
ValidatePlanHasAlignedBillingCadences validates that the billing cadence of the plan is aligned with the billing cadence of the rate cards.
func ValidatePlanMeta ¶
func ValidatePlanMeta() models.ValidatorFunc[Plan]
func ValidatePlanPhaseAndAddonRateCardsAreCompatible ¶
func ValidatePlanPhaseAndAddonRateCardsAreCompatible(addonRateCards RateCards) models.ValidatorFunc[Phase]
func ValidatePlanPhases ¶
func ValidatePlanPhases() models.ValidatorFunc[Plan]
func ValidatePlanWithFeatures ¶
func ValidatePlanWithFeatures(ctx context.Context, resolver NamespacedFeatureResolver) models.ValidatorFunc[Plan]
func ValidateRateCards ¶
func ValidateRateCards() models.ValidatorFunc[RateCards]
ValidateRateCards returns a validation function can be passed to the object which implements models.CustomValidator interface. It checks for invalid and duplicated ratecards in the RateCards collection.
func ValidateRateCardsWithFeatures ¶
func ValidateRateCardsWithFeatures(ctx context.Context, resolver NamespacedFeatureResolver) func(cards RateCards) error
Types ¶
type Addon ¶
func (Addon) HasUnitConfig ¶
func (Addon) Publishable ¶
Publishable validates the Addon to ensure that it meets all requirements needed for being published. It is a stricter version of Validate. It is the caller's responsibility to handle managed resource-specific parameters to ensure the Addon is eligible for publishing. E.g. checking the DeletedAt attribute of the addon.Addon.
func (Addon) ValidateWith ¶
func (a Addon) ValidateWith(validators ...models.ValidatorFunc[Addon]) error
func (Addon) ValidationErrors ¶
func (a Addon) ValidationErrors() (models.ValidationIssues, error)
ValidationErrors returns a list of possible validation errors for the add-on. It returns nil if the add-on has no validation issues.
type AddonInstanceType ¶
type AddonInstanceType string
const ( AddonInstanceTypeSingle AddonInstanceType = "single" AddonInstanceTypeMultiple AddonInstanceType = "multiple" )
func (AddonInstanceType) Validate ¶
func (a AddonInstanceType) Validate() error
func (AddonInstanceType) Values ¶
func (a AddonInstanceType) Values() []string
type AddonMeta ¶
type AddonMeta struct {
EffectivePeriod
// Key is the unique key for Add-on.
Key string `json:"key"`
// Version
Version int `json:"version"`
// Name
Name string `json:"name"`
// Description
Description *string `json:"description,omitempty"`
// Currency
Currency currency.Code `json:"currency"`
// InstanceType
InstanceType AddonInstanceType `json:"instanceType"`
// Metadata
Metadata models.Metadata `json:"metadata,omitempty"`
// Annotations
Annotations models.Annotations `json:"annotations,omitempty"`
}
func (AddonMeta) Status ¶
func (m AddonMeta) Status() AddonStatus
Status returns the current status of the Addons
type AddonStatus ¶
type AddonStatus string
const ( AddonStatusDraft AddonStatus = "draft" AddonStatusActive AddonStatus = "active" AddonStatusArchived AddonStatus = "archived" AddonStatusInvalid AddonStatus = "invalid" )
func (AddonStatus) Validate ¶
func (s AddonStatus) Validate() error
func (AddonStatus) Values ¶
func (s AddonStatus) Values() []AddonStatus
type BooleanEntitlementTemplate ¶
type BooleanEntitlementTemplate struct {
// Metadata a set of key/value pairs describing metadata for the RateCard.
Metadata models.Metadata `json:"metadata,omitempty"`
}
func (*BooleanEntitlementTemplate) Equal ¶
func (t *BooleanEntitlementTemplate) Equal(v *BooleanEntitlementTemplate) bool
func (*BooleanEntitlementTemplate) Validate ¶
func (t *BooleanEntitlementTemplate) Validate() error
type Commitments ¶
type Commitments struct {
// MinimumAmount defines the least amount the customer committed to spend.
MinimumAmount *decimal.Decimal `json:"minimumAmount,omitempty"`
// MaximumAmount defines the upper limit of amount the customer entitled to spend.
MaximumAmount *decimal.Decimal `json:"maximumAmount,omitempty"`
}
func (Commitments) Equal ¶
func (c Commitments) Equal(v Commitments) bool
func (Commitments) Validate ¶
func (c Commitments) Validate() error
type Discounts ¶
type Discounts struct {
Percentage *PercentageDiscount `json:"percentage,omitempty"`
Usage *UsageDiscount `json:"usage,omitempty"`
}
func (Discounts) ValidateForPrice ¶
type DynamicPrice ¶
type DynamicPrice struct {
Commitments `json:",inline"`
// Multiplier defines the multiplier applied to the price.
Multiplier decimal.Decimal `json:"multiplier"`
}
func (DynamicPrice) Clone ¶
func (p DynamicPrice) Clone() DynamicPrice
func (*DynamicPrice) Equal ¶
func (p *DynamicPrice) Equal(v *DynamicPrice) bool
func (DynamicPrice) Validate ¶
func (p DynamicPrice) Validate() error
type EffectivePeriod ¶
type EffectivePeriod struct {
// EffectiveFrom defines the time from the Plan or Addon becomes active.
EffectiveFrom *time.Time `json:"effectiveFrom,omitempty"`
// EffectiveTo defines the time from the Plan or Addon becomes archived.
EffectiveTo *time.Time `json:"effectiveTo,omitempty"`
}
EffectivePeriod describes lifecycle of resource based on the time period defined by it.
func (EffectivePeriod) AsPeriod ¶
func (p EffectivePeriod) AsPeriod() timeutil.OpenPeriod
func (EffectivePeriod) Equal ¶
func (p EffectivePeriod) Equal(o EffectivePeriod) bool
Equal returns true if the two EffectivePeriod objects are equal.
func (EffectivePeriod) Validate ¶
func (p EffectivePeriod) Validate() error
func (EffectivePeriod) ValidateWith ¶
func (p EffectivePeriod) ValidateWith(v ...models.ValidatorFunc[EffectivePeriod]) error
type EntitlementTemplate ¶
type EntitlementTemplate struct {
// contains filtered or unexported fields
}
EntitlementTemplate is the template used for instantiating entitlement.Entitlement for RateCard.
func NewEntitlementTemplateFrom ¶
func NewEntitlementTemplateFrom[T MeteredEntitlementTemplate | StaticEntitlementTemplate | BooleanEntitlementTemplate](c T) *EntitlementTemplate
func (*EntitlementTemplate) AsBoolean ¶
func (e *EntitlementTemplate) AsBoolean() (BooleanEntitlementTemplate, error)
func (*EntitlementTemplate) AsMetered ¶
func (e *EntitlementTemplate) AsMetered() (MeteredEntitlementTemplate, error)
func (*EntitlementTemplate) AsStatic ¶
func (e *EntitlementTemplate) AsStatic() (StaticEntitlementTemplate, error)
func (*EntitlementTemplate) Equal ¶
func (e *EntitlementTemplate) Equal(v *EntitlementTemplate) bool
func (*EntitlementTemplate) FromBoolean ¶
func (e *EntitlementTemplate) FromBoolean(t BooleanEntitlementTemplate)
func (*EntitlementTemplate) FromMetered ¶
func (e *EntitlementTemplate) FromMetered(t MeteredEntitlementTemplate)
func (*EntitlementTemplate) FromStatic ¶
func (e *EntitlementTemplate) FromStatic(t StaticEntitlementTemplate)
func (*EntitlementTemplate) MarshalJSON ¶
func (e *EntitlementTemplate) MarshalJSON() ([]byte, error)
func (*EntitlementTemplate) Type ¶
func (e *EntitlementTemplate) Type() entitlement.EntitlementType
func (*EntitlementTemplate) UnmarshalJSON ¶
func (e *EntitlementTemplate) UnmarshalJSON(bytes []byte) error
func (*EntitlementTemplate) Validate ¶
func (e *EntitlementTemplate) Validate() error
type FeatureResolver ¶
type FlatFeeRateCard ¶
type FlatFeeRateCard struct {
RateCardMeta
// BillingCadence defines the billing cadence of the RateCard in ISO8601 format.
// When nil (null) it means it is a one time fee.
// Example: "P1D12H"
BillingCadence *datetime.ISODuration `json:"billingCadence"`
}
func (*FlatFeeRateCard) AsMeta ¶
func (r *FlatFeeRateCard) AsMeta() RateCardMeta
func (*FlatFeeRateCard) ChangeMeta ¶
func (r *FlatFeeRateCard) ChangeMeta(fn func(m RateCardMeta) (RateCardMeta, error)) error
func (*FlatFeeRateCard) Clone ¶
func (r *FlatFeeRateCard) Clone() RateCard
func (*FlatFeeRateCard) Compatible ¶
func (r *FlatFeeRateCard) Compatible(v RateCard) error
func (*FlatFeeRateCard) Equal ¶
func (r *FlatFeeRateCard) Equal(v RateCard) bool
func (*FlatFeeRateCard) GetBillingCadence ¶
func (r *FlatFeeRateCard) GetBillingCadence() *datetime.ISODuration
func (*FlatFeeRateCard) Key ¶
func (r *FlatFeeRateCard) Key() string
func (*FlatFeeRateCard) MarshalJSON ¶
func (r *FlatFeeRateCard) MarshalJSON() ([]byte, error)
func (*FlatFeeRateCard) Merge ¶
func (r *FlatFeeRateCard) Merge(v RateCard) error
func (*FlatFeeRateCard) Type ¶
func (r *FlatFeeRateCard) Type() RateCardType
func (*FlatFeeRateCard) Validate ¶
func (r *FlatFeeRateCard) Validate() error
func (*FlatFeeRateCard) ValidateWith ¶
func (r *FlatFeeRateCard) ValidateWith(v ...models.ValidatorFunc[*FlatFeeRateCard]) error
type FlatPrice ¶
type FlatPrice struct {
// Amount of the flat price.
Amount decimal.Decimal `json:"amount"`
// PaymentTerm defines the payment term of the flat price.
// Defaults to InAdvancePaymentTerm.
PaymentTerm PaymentTermType `json:"paymentTerm,omitempty"`
}
type MeteredEntitlementTemplate ¶
type MeteredEntitlementTemplate struct {
// Metadata a set of key/value pairs describing metadata for the RateCard.
Metadata models.Metadata `json:"metadata,omitempty"`
// IsSoftLimit set to `true` for allowing the subject to use the feature even if the entitlement is exhausted.
IsSoftLimit bool `json:"isSoftLimit,omitempty"`
// IssueAfterReset defines the amount to be automatically granted at entitlement.Entitlement creation or reset.
IssueAfterReset *float64 `json:"issueAfterReset,omitempty"`
// IssueAfterResetPriority defines the grant priority for the default grant.
IssueAfterResetPriority *uint8 `json:"issueAfterResetPriority,omitempty"`
// PreserveOverageAtReset defines whether the overage is preserved after reset.
PreserveOverageAtReset *bool `json:"preserveOverageAtReset,omitempty"`
// UsagePeriod defines the interval of the entitlement in ISO8601 format.
// Defaults to the billing cadence of the rate card.
// Example: "P1D12H"
UsagePeriod datetime.ISODuration `json:"usagePeriod,omitempty"`
}
func (*MeteredEntitlementTemplate) Equal ¶
func (t *MeteredEntitlementTemplate) Equal(v *MeteredEntitlementTemplate) bool
func (*MeteredEntitlementTemplate) Validate ¶
func (t *MeteredEntitlementTemplate) Validate() error
type PackagePrice ¶
type PackagePrice struct {
Commitments `json:",inline"`
Amount decimal.Decimal `json:"amount"`
QuantityPerPackage decimal.Decimal `json:"quantityPerPackage"`
}
func (PackagePrice) Clone ¶
func (p PackagePrice) Clone() PackagePrice
func (*PackagePrice) Equal ¶
func (p *PackagePrice) Equal(v *PackagePrice) bool
func (PackagePrice) Validate ¶
func (p PackagePrice) Validate() error
type PaymentTermType ¶
type PaymentTermType string
const ( InAdvancePaymentTerm PaymentTermType = "in_advance" InArrearsPaymentTerm PaymentTermType = "in_arrears" )
func (PaymentTermType) StringValues ¶
func (p PaymentTermType) StringValues() []string
func (PaymentTermType) Validate ¶
func (p PaymentTermType) Validate() error
func (PaymentTermType) Values ¶
func (p PaymentTermType) Values() []string
type PercentageDiscount ¶
type PercentageDiscount struct {
// Percentage defines percentage of the discount.
Percentage models.Percentage `json:"percentage"`
}
func (PercentageDiscount) Clone ¶
func (d PercentageDiscount) Clone() PercentageDiscount
func (PercentageDiscount) Hash ¶
func (d PercentageDiscount) Hash() hasher.Hash
func (PercentageDiscount) Validate ¶
func (d PercentageDiscount) Validate() error
func (PercentageDiscount) ValidateForPrice ¶
func (d PercentageDiscount) ValidateForPrice(_ *Price) error
func (PercentageDiscount) ValidateWith ¶
func (d PercentageDiscount) ValidateWith(v ...models.ValidatorFunc[PercentageDiscount]) error
type Phase ¶
func (Phase) ValidateWith ¶
func (p Phase) ValidateWith(v ...models.ValidatorFunc[Phase]) error
type PhaseMeta ¶
type PhaseMeta struct {
// Key is the unique key for Phase.
Key string `json:"key"`
// Name is the name of the Phase.
Name string `json:"name"`
// Description is the detailed description of the Phase.
Description *string `json:"description,omitempty"`
// Metadata stores user defined metadata for Phase.
Metadata models.Metadata `json:"metadata,omitempty"`
// Duration is the duration of the Phase.
Duration *datetime.ISODuration `json:"duration"`
}
type Plan ¶
func (Plan) HasUnitConfig ¶
HasUnitConfig reports whether any rate card in any phase carries a unit_config conversion. The v1 API cannot represent unit_config, so v1 read and mutation surfaces use this to reject such plans instead of silently stripping the field.
func (Plan) ValidateWith ¶
func (p Plan) ValidateWith(validators ...models.ValidatorFunc[Plan]) error
func (Plan) ValidationErrors ¶
func (p Plan) ValidationErrors() (models.ValidationIssues, error)
ValidationErrors returns a list of possible validation errors for the plan. It returns nil if the plan has no validation issues.
type PlanAddon ¶
type PlanAddon struct {
PlanAddonMeta
// Plan
Plan Plan `json:"plan"`
// Addon
Addon Addon `json:"addon"`
}
func (PlanAddon) ValidateWith ¶
func (c PlanAddon) ValidateWith(validators ...models.ValidatorFunc[PlanAddon]) error
func (PlanAddon) ValidationErrors ¶
func (c PlanAddon) ValidationErrors() (models.ValidationIssues, error)
ValidationErrors returns a list of possible validation error(s) regarding to compatibility of the plan and add-on in the assignment. It returns nil if the plan and add-on are compatible.
type PlanAddonConfig ¶
type PlanAddonConfig struct {
// FromPlanPhase
FromPlanPhase string `json:"fromPlanPhase"`
// MaxQuantity caps how many units a customer may assign for multiple-instance addons.
// nil means unlimited; a positive integer enforces a hard cap; zero or negative is invalid.
MaxQuantity *int `json:"maxQuantity"`
}
type PlanAddonMeta ¶
type PlanAddonMeta struct {
models.Metadata
models.Annotations
PlanAddonConfig
}
type PlanMeta ¶
type PlanMeta struct {
EffectivePeriod
// Key is the unique key for Plan.
Key string `json:"key"`
// Version
Version int `json:"version"`
// Name
Name string `json:"name"`
// Description
Description *string `json:"description,omitempty"`
// Currency
Currency currency.Code `json:"currency"`
// BillingCadence is the default billing cadence for subscriptions using this plan.
BillingCadence datetime.ISODuration `json:"billing_cadence"`
// ProRatingConfig is the default pro-rating configuration for subscriptions using this plan.
ProRatingConfig ProRatingConfig `json:"pro_rating_config"`
// SettlementMode is the settlement mode for subscriptions using this plan.
SettlementMode SettlementMode `json:"settlement_mode"`
// Metadata
Metadata models.Metadata `json:"metadata,omitempty"`
}
func (PlanMeta) Status ¶
func (p PlanMeta) Status() PlanStatus
Status returns the current status of the Plan
type PlanStatus ¶
type PlanStatus string
const ( PlanStatusDraft PlanStatus = "draft" PlanStatusActive PlanStatus = "active" PlanStatusArchived PlanStatus = "archived" PlanStatusScheduled PlanStatus = "scheduled" PlanStatusInvalid PlanStatus = "invalid" )
func (PlanStatus) Validate ¶
func (s PlanStatus) Validate() error
func (PlanStatus) Values ¶
func (s PlanStatus) Values() []PlanStatus
type Price ¶
type Price struct {
// contains filtered or unexported fields
}
func NewPriceFrom ¶
func NewPriceFrom[T FlatPrice | UnitPrice | TieredPrice | DynamicPrice | PackagePrice](v T) *Price
func (*Price) AsDynamic ¶
func (p *Price) AsDynamic() (DynamicPrice, error)
func (*Price) AsPackage ¶
func (p *Price) AsPackage() (PackagePrice, error)
func (*Price) AsTiered ¶
func (p *Price) AsTiered() (TieredPrice, error)
func (*Price) FromDynamic ¶
func (p *Price) FromDynamic(price DynamicPrice)
func (*Price) FromPackage ¶
func (p *Price) FromPackage(price PackagePrice)
func (*Price) FromTiered ¶
func (p *Price) FromTiered(price TieredPrice)
func (*Price) GetCommitments ¶
func (p *Price) GetCommitments() Commitments
func (*Price) GetPaymentTerm ¶
func (p *Price) GetPaymentTerm() PaymentTermType
func (Price) MarshalJSON ¶
func (*Price) SupportsUnitConfig ¶
SupportsUnitConfig reports whether a unit_config conversion can be applied to this price. unit_config is a per-quantity conversion applied to the raw metered quantity before rating, so it is only meaningful on per-unit prices (unit and the graduated/volume tiered modes). Flat prices are not per-quantity, and package/dynamic prices already carry their own conversion that unit_config would double up on.
func (*Price) UnmarshalJSON ¶
type PriceTier ¶
type PriceTier struct {
// UpToAmount defines the quantity will be contained in the tier. Inclusive.
// If null, the tier is open-ended.
UpToAmount *decimal.Decimal `json:"upToAmount,omitempty"`
// FlatPrice defines the flat price component of the tier.
FlatPrice *PriceTierFlatPrice `json:"flatPrice,omitempty"`
// UnitPrice defines the unit price component of the tier.
UnitPrice *PriceTierUnitPrice `json:"unitPrice,omitempty"`
}
PriceTier describes a tier of price(s).
type PriceTierFlatPrice ¶
type PriceTierFlatPrice struct {
// Amount of the flat price.
Amount decimal.Decimal `json:"amount"`
}
func (PriceTierFlatPrice) Clone ¶
func (f PriceTierFlatPrice) Clone() PriceTierFlatPrice
func (PriceTierFlatPrice) Equal ¶
func (f PriceTierFlatPrice) Equal(v PriceTierFlatPrice) bool
func (PriceTierFlatPrice) Validate ¶
func (f PriceTierFlatPrice) Validate() error
type PriceTierUnitPrice ¶
type PriceTierUnitPrice struct {
// Amount of the flat price.
Amount decimal.Decimal `json:"amount"`
}
func (PriceTierUnitPrice) Clone ¶
func (u PriceTierUnitPrice) Clone() PriceTierUnitPrice
func (PriceTierUnitPrice) Equal ¶
func (u PriceTierUnitPrice) Equal(v PriceTierUnitPrice) bool
func (PriceTierUnitPrice) Validate ¶
func (u PriceTierUnitPrice) Validate() error
type ProRatingConfig ¶
type ProRatingConfig struct {
// Enabled indicates whether pro-rating is enabled.
Enabled bool `json:"enabled"`
// Mode specifies how pro-rating should be calculated.
Mode ProRatingMode `json:"mode"`
}
ProRatingConfig defines the pro-rating behavior configuration.
func (ProRatingConfig) Equal ¶
func (p ProRatingConfig) Equal(o ProRatingConfig) bool
Equal returns true if the two ProRatingConfigs are equal.
func (ProRatingConfig) Validate ¶
func (p ProRatingConfig) Validate() error
Validate validates the ProRatingConfig.
type ProRatingMode ¶
type ProRatingMode string
const (
ProRatingModeProratePrices ProRatingMode = "prorate_prices"
)
func (ProRatingMode) Values ¶
func (m ProRatingMode) Values() []string
type RateCard ¶
type RateCard interface {
models.Validator
models.Equaler[RateCard]
RateCardFeature
Type() RateCardType
AsMeta() RateCardMeta
Key() string
Merge(RateCard) error
ChangeMeta(func(m RateCardMeta) (RateCardMeta, error)) error
Clone() RateCard
Compatible(RateCard) error
GetBillingCadence() *datetime.ISODuration
IsBillable() bool
}
type RateCardFeature ¶
type RateCardMeta ¶
type RateCardMeta struct {
// Key is the unique key for Plan.
Key string `json:"key"`
// Name of the RateCard
Name string `json:"name"`
// Description for the RateCard
Description *string `json:"description,omitempty"`
// Metadata a set of key/value pairs describing metadata for the RateCard
Metadata models.Metadata `json:"metadata,omitempty"`
// FeatureKey is the key of the feature assigned to the RateCard
FeatureKey *string `json:"featureKey,omitempty"`
// FeatureID is the ID of the feature assigned to the RateCard
FeatureID *string `json:"featureID,omitempty"`
// EntitlementTemplate defines the template used for instantiating entitlement.Entitlement.
// If Feature is set then template must be provided as well.
EntitlementTemplate *EntitlementTemplate `json:"entitlementTemplate,omitempty"`
// TaxConfig defines provider specific tax information.
TaxConfig *TaxConfig `json:"taxConfig,omitempty"`
// TaxCode is the tax code assigned to the RateCard. It is only populated if the tax code was eagerly loaded.
TaxCode *taxcode.TaxCode `json:"taxCode,omitempty"`
// Price defines the price for the RateCard
Price *Price `json:"price"`
// Discounts defines a list of discounts for the RateCard
Discounts Discounts `json:"discounts,omitempty"`
// UnitConfig defines an optional per-rate-card conversion applied to the raw
// metered quantity before pricing and entitlement evaluation. Shared by plan
// and addon rate cards.
UnitConfig *UnitConfig `json:"unitConfig,omitempty"`
}
func (RateCardMeta) Clone ¶
func (r RateCardMeta) Clone() RateCardMeta
func (RateCardMeta) Equal ¶
func (r RateCardMeta) Equal(v RateCardMeta) bool
func (RateCardMeta) GetFeatureID ¶
func (r RateCardMeta) GetFeatureID() *string
func (RateCardMeta) GetFeatureKey ¶
func (r RateCardMeta) GetFeatureKey() *string
func (RateCardMeta) HasFeature ¶
func (r RateCardMeta) HasFeature() bool
func (RateCardMeta) IsBillable ¶
func (r RateCardMeta) IsBillable() bool
func (*RateCardMeta) SetFeature ¶
func (r *RateCardMeta) SetFeature(id, key *string)
func (RateCardMeta) Validate ¶
func (r RateCardMeta) Validate() error
func (RateCardMeta) ValidateWith ¶
func (r RateCardMeta) ValidateWith(v ...models.ValidatorFunc[RateCardMeta]) error
type RateCardSerde ¶
type RateCardSerde struct {
Type RateCardType `json:"type"`
}
type RateCardType ¶
type RateCardType string
const ( FlatFeeRateCardType RateCardType = "flat_fee" UsageBasedRateCardType RateCardType = "usage_based" )
func (RateCardType) Values ¶
func (s RateCardType) Values() []string
type RateCardWithOverlay ¶
type RateCardWithOverlay struct {
// contains filtered or unexported fields
}
func NewRateCardWithOverlay ¶
func NewRateCardWithOverlay(base, overlay RateCard) RateCardWithOverlay
func (RateCardWithOverlay) Validate ¶
func (r RateCardWithOverlay) Validate() error
func (RateCardWithOverlay) ValidateWith ¶
func (r RateCardWithOverlay) ValidateWith(validators ...models.ValidatorFunc[RateCardWithOverlay]) error
type RateCards ¶
type RateCards []RateCard
func (RateCards) HasUnitConfig ¶
func (RateCards) SingleBillingCadence ¶
SingleBillingCadence returns true if all ratecards in the collection has the same billing cadence.
func (RateCards) ValidateWith ¶
func (c RateCards) ValidateWith(v ...models.ValidatorFunc[RateCards]) error
type SettlementMode ¶
type SettlementMode string
const ( CreditThenInvoiceSettlementMode SettlementMode = "credit_then_invoice" CreditOnlySettlementMode SettlementMode = "credit_only" )
func (SettlementMode) Validate ¶
func (s SettlementMode) Validate() error
func (SettlementMode) Values ¶
func (s SettlementMode) Values() []string
type StaticEntitlementTemplate ¶
type StaticEntitlementTemplate struct {
// Metadata a set of key/value pairs describing metadata for the RateCard.
Metadata models.Metadata `json:"metadata,omitempty"`
// Config stores a JSON parsable configuration for the entitlement.Entitlement.
// This value is also returned when checking entitlement access, and
// it is useful for configuring fine-grained access settings to the feature implemented in customers own system.
Config json.RawMessage `json:"config,omitempty"`
}
func (*StaticEntitlementTemplate) Equal ¶
func (t *StaticEntitlementTemplate) Equal(v *StaticEntitlementTemplate) bool
func (*StaticEntitlementTemplate) Validate ¶
func (t *StaticEntitlementTemplate) Validate() error
type StripeTaxConfig ¶
type StripeTaxConfig struct {
// Code stores the product tax code.
// See: https://docs.stripe.com/tax/tax-codes
// Example:"txcd_10000000"
Code string `json:"code"`
}
func (StripeTaxConfig) Clone ¶
func (s StripeTaxConfig) Clone() StripeTaxConfig
func (*StripeTaxConfig) Equal ¶
func (s *StripeTaxConfig) Equal(v *StripeTaxConfig) bool
func (*StripeTaxConfig) Validate ¶
func (s *StripeTaxConfig) Validate() error
type TaxBehavior ¶
type TaxBehavior string
const ( InclusiveTaxBehavior TaxBehavior = "inclusive" ExclusiveTaxBehavior TaxBehavior = "exclusive" )
func (TaxBehavior) Validate ¶
func (t TaxBehavior) Validate() error
func (TaxBehavior) Values ¶
func (t TaxBehavior) Values() []string
type TaxCodeConfig ¶
type TaxCodeConfig struct {
Behavior *TaxBehavior `json:"behavior,omitempty"`
TaxCodeID string `json:"tax_code_id"`
}
TaxCodeConfig holds a lean reference to a tax code entry — only the FK and the behavior flag. Used in charge intents where provider-specific fields (e.g. Stripe.Code) are not stored and are resolved at invoice snapshot time via BackfillTaxConfig.
func TaxCodeConfigFrom ¶
func TaxCodeConfigFrom(cfg *TaxConfig) TaxCodeConfig
TaxCodeConfigFrom extracts the lean reference fields from a full TaxConfig. Returns the zero value when cfg is nil or when neither Behavior nor TaxCodeID is set (e.g. Stripe-only config).
func (TaxCodeConfig) ToTaxConfig ¶
func (c TaxCodeConfig) ToTaxConfig() TaxConfig
ToTaxConfig converts TaxCodeConfig to TaxConfig (without provider-specific fields).
func (TaxCodeConfig) Validate ¶
func (c TaxCodeConfig) Validate() error
type TaxConfig ¶
type TaxConfig struct {
Behavior *TaxBehavior `json:"behavior,omitempty"`
Stripe *StripeTaxConfig `json:"stripe,omitempty"`
TaxCodeID *string `json:"tax_code_id,omitempty"`
}
TaxConfig stores the provider-specific tax configs.
func BackfillTaxConfig ¶
func BackfillTaxConfig(cfg *TaxConfig, taxBehavior *TaxBehavior, tc *taxcode.TaxCode) *TaxConfig
BackfillTaxConfig fills in missing legacy TaxConfig fields from the new tax_behavior column and the TaxCode entity's app mappings.
func MergeTaxConfigs ¶
MergeTaxConfigs merges two TaxConfigs with overrides taking precedence.
Stripe and TaxCodeID are two encodings of the same intent-level tax-code identity, so they merge as a unit: a config that overrides only the Stripe code must not inherit the base's (different) TaxCodeID, which would leave the result pointing at two different tax entities.
type TieredPrice ¶
type TieredPrice struct {
Commitments `json:",inline"`
// Mode defines whether the tier is volume-based or graduated.
// * VolumeTieredPrice: the maximum quantity within a period determines the per-unit price
// * GraduatedTieredPrice: pricing can change as the quantity grows
Mode TieredPriceMode `json:"mode"`
// Tiers defines the list of PriceTier.
Tiers []PriceTier `json:"tiers"`
}
func (*TieredPrice) Clone ¶
func (t *TieredPrice) Clone() TieredPrice
func (*TieredPrice) Equal ¶
func (t *TieredPrice) Equal(v *TieredPrice) bool
func (*TieredPrice) Validate ¶
func (t *TieredPrice) Validate() error
func (*TieredPrice) WithSortedTiers ¶
func (t *TieredPrice) WithSortedTiers() TieredPrice
type TieredPriceMode ¶
type TieredPriceMode string
const ( // In `volume`-based tiering, the maximum quantity within a period determines the per unit price. VolumeTieredPrice TieredPriceMode = "volume" // In `graduated` tiering, pricing can change as the quantity grows. GraduatedTieredPrice TieredPriceMode = "graduated" )
func NewTieredPriceMode ¶
func NewTieredPriceMode(s string) (TieredPriceMode, error)
func (TieredPriceMode) StringValues ¶
func (p TieredPriceMode) StringValues() []string
func (TieredPriceMode) Values ¶
func (p TieredPriceMode) Values() []TieredPriceMode
type UnitConfig ¶
type UnitConfig struct {
// Operation is the arithmetic conversion to apply: multiply or divide.
Operation UnitConfigOperation `json:"operation"`
// ConversionFactor is the positive non-zero factor used by Operation. Full
// precision is retained; the factor is never capped.
ConversionFactor decimal.Decimal `json:"conversionFactor"`
// Rounding controls how the converted quantity is rounded for invoicing.
// Defaults to "none". Entitlement balance checks always use the unrounded
// (converted) value, never the rounded one.
Rounding UnitConfigRoundingMode `json:"rounding,omitempty"`
// Precision is the number of decimal places retained when rounding. It is
// only meaningful when Rounding is set to a value other than "none"; it is
// ignored otherwise. Defaults to 0 (whole units).
Precision int `json:"precision,omitempty"`
// DisplayUnit is a human-readable label for the converted unit shown on
// invoices and the customer portal (e.g. "GB", "hours").
DisplayUnit *string `json:"displayUnit,omitempty"`
}
UnitConfig transforms a raw metered quantity into a billing quantity before pricing and entitlement evaluation. It is a self-contained domain DTO with no dependency on the persistence layer — persistence maps to/from it.
Rounding and Precision are value types with sensible defaults (no rounding, zero decimal places); only DisplayUnit is optional and pointer-typed.
func (*UnitConfig) Apply ¶
func (c *UnitConfig) Apply(raw decimal.Decimal) (converted, invoiced decimal.Decimal)
Apply transforms a raw metered quantity into the converted (precise) and invoiced (rounded) billing quantities.
- converted: raw with the operation × conversion_factor applied. Used for entitlement balance checks, which always see the precise value.
- invoiced: converted with the configured rounding/precision applied. Used as the line quantity at billing time. Equal to converted when no rounding is set.
When c is nil, both return values equal raw. Callers must have already run Validate so the operation and rounding enums are known values; an unrecognized operation or rounding mode falls back to identity rather than panicking mid-billing.
func (UnitConfig) Clone ¶
func (c UnitConfig) Clone() UnitConfig
func (*UnitConfig) Equal ¶
func (c *UnitConfig) Equal(v *UnitConfig) bool
func (*UnitConfig) Validate ¶
func (c *UnitConfig) Validate() error
type UnitConfigOperation ¶
type UnitConfigOperation string
const ( UnitConfigOperationMultiply UnitConfigOperation = "multiply" UnitConfigOperationDivide UnitConfigOperation = "divide" )
func (UnitConfigOperation) Validate ¶
func (o UnitConfigOperation) Validate() error
func (UnitConfigOperation) Values ¶
func (o UnitConfigOperation) Values() []string
type UnitConfigRoundingMode ¶
type UnitConfigRoundingMode string
const ( UnitConfigRoundingModeNone UnitConfigRoundingMode = "none" UnitConfigRoundingModeCeiling UnitConfigRoundingMode = "ceiling" UnitConfigRoundingModeFloor UnitConfigRoundingMode = "floor" UnitConfigRoundingModeHalfUp UnitConfigRoundingMode = "half_up" )
func (UnitConfigRoundingMode) IsNone ¶
func (r UnitConfigRoundingMode) IsNone() bool
IsNone reports whether the mode applies no rounding. The empty string is the zero value of the field and is treated as the default, "none".
func (UnitConfigRoundingMode) Validate ¶
func (r UnitConfigRoundingMode) Validate() error
func (UnitConfigRoundingMode) Values ¶
func (r UnitConfigRoundingMode) Values() []string
type UnitPrice ¶
type UnitPrice struct {
Commitments `json:",inline"`
// Amount of the unit price.
Amount decimal.Decimal `json:"amount"`
}
type UsageBasedRateCard ¶
type UsageBasedRateCard struct {
RateCardMeta
// BillingCadence defines the billing cadence of the RateCard in ISO8601 format.
// Example: "P1D12H"
BillingCadence datetime.ISODuration `json:"billingCadence"`
}
func (*UsageBasedRateCard) AsMeta ¶
func (r *UsageBasedRateCard) AsMeta() RateCardMeta
func (*UsageBasedRateCard) ChangeMeta ¶
func (r *UsageBasedRateCard) ChangeMeta(fn func(m RateCardMeta) (RateCardMeta, error)) error
func (*UsageBasedRateCard) Clone ¶
func (r *UsageBasedRateCard) Clone() RateCard
func (*UsageBasedRateCard) Compatible ¶
func (r *UsageBasedRateCard) Compatible(v RateCard) error
func (*UsageBasedRateCard) Equal ¶
func (r *UsageBasedRateCard) Equal(v RateCard) bool
func (*UsageBasedRateCard) GetBillingCadence ¶
func (r *UsageBasedRateCard) GetBillingCadence() *datetime.ISODuration
func (*UsageBasedRateCard) Key ¶
func (r *UsageBasedRateCard) Key() string
func (*UsageBasedRateCard) MarshalJSON ¶
func (r *UsageBasedRateCard) MarshalJSON() ([]byte, error)
func (*UsageBasedRateCard) Merge ¶
func (r *UsageBasedRateCard) Merge(v RateCard) error
func (*UsageBasedRateCard) Type ¶
func (r *UsageBasedRateCard) Type() RateCardType
func (*UsageBasedRateCard) Validate ¶
func (r *UsageBasedRateCard) Validate() error
func (*UsageBasedRateCard) ValidateWith ¶
func (r *UsageBasedRateCard) ValidateWith(v ...models.ValidatorFunc[*UsageBasedRateCard]) error
type UsageDiscount ¶
func (UsageDiscount) Clone ¶
func (d UsageDiscount) Clone() UsageDiscount
func (UsageDiscount) Hash ¶
func (d UsageDiscount) Hash() hasher.Hash
func (UsageDiscount) Validate ¶
func (d UsageDiscount) Validate() error
func (UsageDiscount) ValidateForPrice ¶
func (d UsageDiscount) ValidateForPrice(price *Price) error
func (UsageDiscount) ValidateWith ¶
func (d UsageDiscount) ValidateWith(v ...models.ValidatorFunc[UsageDiscount]) error