| package httpdriver |
|
|
| import ( |
| "errors" |
| "fmt" |
|
|
| "github.com/samber/lo" |
|
|
| "github.com/openmeterio/openmeter/api" |
| productcataloghttp "github.com/openmeterio/openmeter/openmeter/productcatalog/http" |
| subscriptionhttp "github.com/openmeterio/openmeter/openmeter/productcatalog/subscription/http" |
| "github.com/openmeterio/openmeter/openmeter/subscription" |
| subscriptionaddon "github.com/openmeterio/openmeter/openmeter/subscription/addon" |
| addondiff "github.com/openmeterio/openmeter/openmeter/subscription/addon/diff" |
| subscriptionworkflow "github.com/openmeterio/openmeter/openmeter/subscription/workflow" |
| "github.com/openmeterio/openmeter/pkg/clock" |
| "github.com/openmeterio/openmeter/pkg/slicesx" |
| "github.com/openmeterio/openmeter/pkg/timeutil" |
| ) |
|
|
| func MapCreateSubscriptionAddonRequestToInput(req api.SubscriptionAddonCreate) (subscriptionworkflow.AddAddonWorkflowInput, error) { |
| timing, err := subscriptionhttp.MapAPITimingToTiming(req.Timing) |
| if err != nil { |
| return subscriptionworkflow.AddAddonWorkflowInput{}, fmt.Errorf("failed to cast Timing: %w", err) |
| } |
|
|
| r := subscriptionworkflow.AddAddonWorkflowInput{ |
| AddonID: req.Addon.Id, |
| InitialQuantity: req.Quantity, |
| Timing: timing, |
| } |
|
|
| if req.Metadata != nil { |
| r.MetadataModel.Metadata = lo.FromPtr(req.Metadata) |
| } |
|
|
| return r, nil |
| } |
|
|
| func MapSubscriptionAddonToResponse(view subscription.SubscriptionView, addon subscriptionaddon.SubscriptionAddon) (api.SubscriptionAddon, error) { |
| now := clock.Now() |
|
|
| |
| inst, _ := addon.GetInstanceAt(now) |
|
|
| pers := lo.Map(addon.GetInstances(), func(i subscriptionaddon.SubscriptionAddonInstance, _ int) timeutil.OpenPeriod { |
| return i.AsPeriod() |
| }) |
|
|
| if len(pers) == 0 { |
| return api.SubscriptionAddon{}, errors.New("no instances found") |
| } |
|
|
| union := lo.Reduce(pers, func(agg timeutil.OpenPeriod, item timeutil.OpenPeriod, _ int) timeutil.OpenPeriod { |
| return agg.Union(item) |
| }, pers[0]) |
|
|
| affectedMap := addondiff.GetAffectedItemIDs(view, addon) |
|
|
| rateCards, err := slicesx.MapWithErr(addon.RateCards, func(r subscriptionaddon.SubscriptionAddonRateCard) (api.SubscriptionAddonRateCard, error) { |
| rc, err := productcataloghttp.FromRateCard(r.AddonRateCard.RateCard) |
| if err != nil { |
| return api.SubscriptionAddonRateCard{}, fmt.Errorf("failed to cast RateCard: %w", err) |
| } |
|
|
| ids := affectedMap[r.AddonRateCard.RateCard.Key()] |
|
|
| return api.SubscriptionAddonRateCard{ |
| RateCard: rc, |
| AffectedSubscriptionItemIds: ids, |
| }, nil |
| }) |
| if err != nil { |
| return api.SubscriptionAddon{}, fmt.Errorf("failed to cast RateCards: %w", err) |
| } |
|
|
| return api.SubscriptionAddon{ |
| Id: addon.ID, |
| CreatedAt: addon.CreatedAt, |
| UpdatedAt: addon.UpdatedAt, |
| DeletedAt: addon.DeletedAt, |
| Metadata: lo.EmptyableToPtr(api.Metadata(addon.Metadata)), |
| Description: addon.Description, |
| Name: addon.Name, |
| SubscriptionId: addon.SubscriptionID, |
| Addon: struct { |
| Id string "json:\"id\"" |
| InstanceType api.AddonInstanceType "json:\"instanceType\"" |
| Key string "json:\"key\"" |
| Version int "json:\"version\"" |
| }{ |
| Id: addon.Addon.ID, |
| InstanceType: api.AddonInstanceType(addon.Addon.InstanceType), |
| Key: addon.Addon.Key, |
| Version: addon.Addon.Version, |
| }, |
| ActiveFrom: *union.From, |
| ActiveTo: union.To, |
| Quantity: inst.Quantity, |
| QuantityAt: now, |
| Timeline: lo.Map(addon.GetInstances(), func(i subscriptionaddon.SubscriptionAddonInstance, _ int) api.SubscriptionAddonTimelineSegment { |
| return api.SubscriptionAddonTimelineSegment{ |
| Quantity: i.Quantity, |
| ActiveFrom: i.CadencedModel.ActiveFrom, |
| ActiveTo: i.CadencedModel.ActiveTo, |
| } |
| }), |
| RateCards: rateCards, |
| }, nil |
| } |
|
|