| package reconciler |
|
|
| import ( |
| "fmt" |
|
|
| "github.com/openmeterio/openmeter/openmeter/billing" |
| "github.com/openmeterio/openmeter/openmeter/billing/charges" |
| chargesflatfee "github.com/openmeterio/openmeter/openmeter/billing/charges/flatfee" |
| chargesmeta "github.com/openmeterio/openmeter/openmeter/billing/charges/meta" |
| "github.com/openmeterio/openmeter/openmeter/billing/worker/subscriptionsync/service/persistedstate" |
| "github.com/openmeterio/openmeter/openmeter/billing/worker/subscriptionsync/service/targetstate" |
| "github.com/openmeterio/openmeter/openmeter/productcatalog" |
| "github.com/openmeterio/openmeter/pkg/timeutil" |
| ) |
|
|
| type flatFeeChargeCollection struct { |
| chargePatchCollection |
| } |
|
|
| func newFlatFeeChargeCollection(preallocatedCapacity int) *flatFeeChargeCollection { |
| return &flatFeeChargeCollection{ |
| chargePatchCollection: newChargePatchCollection(billing.LineEngineTypeChargeFlatFee, persistedstate.ItemTypeChargeFlatFee, preallocatedCapacity), |
| } |
| } |
|
|
| func (c *flatFeeChargeCollection) AddCreate(target targetstate.StateItem) error { |
| intent, err := newFlatFeeChargeIntent(target) |
| if err != nil { |
| return err |
| } |
|
|
| return c.addCreate(intent) |
| } |
|
|
| func (c *flatFeeChargeCollection) AddShrink(_ string, existing persistedstate.Item, target targetstate.StateItem) error { |
| _, ok := existing.(persistedstate.FlatFeeChargeGetter) |
| if !ok { |
| return fmt.Errorf("existing item is not a flat fee charge [item_type=%s,id=%s]", existing.Type(), existing.ID()) |
| } |
|
|
| patch, err := chargesmeta.NewPatchShrink(chargesmeta.NewPatchShrinkInput{ |
| ChangeSource: billing.ChangeSourceSystem, |
| NewServicePeriodTo: target.GetServicePeriod().To, |
| NewFullServicePeriodTo: target.FullServicePeriod.To, |
| NewBillingPeriodTo: target.BillingPeriod.To, |
| NewInvoiceAt: target.GetInvoiceAt(), |
| }) |
| if err != nil { |
| return err |
| } |
|
|
| return c.addPatch(existing.ID().ID, patch) |
| } |
|
|
| func (c *flatFeeChargeCollection) AddExtend(existing persistedstate.Item, target targetstate.StateItem) error { |
| _, ok := existing.(persistedstate.FlatFeeChargeGetter) |
| if !ok { |
| return fmt.Errorf("existing item is not a flat fee charge [item_type=%s,id=%s]", existing.Type(), existing.ID()) |
| } |
|
|
| patch, err := chargesmeta.NewPatchExtend(chargesmeta.NewPatchExtendInput{ |
| ChangeSource: billing.ChangeSourceSystem, |
| NewServicePeriodTo: target.GetServicePeriod().To, |
| NewFullServicePeriodTo: target.FullServicePeriod.To, |
| NewBillingPeriodTo: target.BillingPeriod.To, |
| NewInvoiceAt: target.GetInvoiceAt(), |
| }) |
| if err != nil { |
| return err |
| } |
|
|
| return c.addPatch(existing.ID().ID, patch) |
| } |
|
|
| func newFlatFeeChargeIntent(target targetstate.StateItem) (charges.ChargeIntent, error) { |
| rateCardMeta := target.Spec.RateCard.AsMeta() |
| price := rateCardMeta.Price |
| if price == nil { |
| return charges.ChargeIntent{}, fmt.Errorf("price is required for flat fee charge") |
| } |
|
|
| flatPrice, err := price.AsFlat() |
| if err != nil { |
| return charges.ChargeIntent{}, fmt.Errorf("converting price to flat: %w", err) |
| } |
|
|
| annotations, err := target.SubscriptionItem.Annotations.Clone() |
| if err != nil { |
| return charges.ChargeIntent{}, err |
| } |
|
|
| return charges.NewChargeIntent(chargesflatfee.Intent{ |
| Intent: chargesmeta.Intent{ |
| ManagedBy: billing.SubscriptionManagedLine, |
| CustomerID: target.Subscription.CustomerId, |
| Annotations: annotations, |
| Currency: target.CurrencyCalculator.Details().Code, |
| UniqueReferenceID: &target.UniqueID, |
| TaxConfig: productcatalog.TaxCodeConfigFrom(rateCardMeta.TaxConfig), |
| Subscription: &chargesmeta.SubscriptionReference{ |
| SubscriptionID: target.Subscription.ID, |
| PhaseID: target.PhaseID, |
| ItemID: target.SubscriptionItem.ID, |
| }, |
| }, |
| IntentMutableFields: chargesflatfee.IntentMutableFields{ |
| IntentMutableFields: chargesmeta.IntentMutableFields{ |
| Name: rateCardMeta.Name, |
| Description: rateCardMeta.Description, |
| Metadata: target.SubscriptionItem.Metadata.Clone(), |
| ServicePeriod: target.GetServicePeriod(), |
| FullServicePeriod: timeutil.ClosedPeriod{ |
| From: target.FullServicePeriod.From, |
| To: target.FullServicePeriod.To, |
| }, |
| BillingPeriod: timeutil.ClosedPeriod{ |
| From: target.BillingPeriod.From, |
| To: target.BillingPeriod.To, |
| }, |
| }, |
| InvoiceAt: target.GetInvoiceAt(), |
| PaymentTerm: flatPrice.PaymentTerm, |
| PercentageDiscounts: billing.DiscountsFromProductCatalog(rateCardMeta.Discounts).UpsertCorrelationIDs().Percentage, |
| ProRating: target.Subscription.ProRatingConfig, |
| AmountBeforeProration: flatPrice.Amount, |
| }, |
| FeatureKey: rateCardMeta.FeatureKey, |
| SettlementMode: target.Subscription.SettlementMode, |
| }), nil |
| } |
|
|