File size: 2,610 Bytes
16cdcb7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package subscription

import (
	"time"

	"github.com/openmeterio/openmeter/openmeter/customer"
	"github.com/openmeterio/openmeter/openmeter/productcatalog"
	"github.com/openmeterio/openmeter/pkg/currencyx"
	"github.com/openmeterio/openmeter/pkg/datetime"
	"github.com/openmeterio/openmeter/pkg/models"
)

type Subscription struct {
	models.NamespacedID
	models.ManagedModel
	models.CadencedModel
	models.MetadataModel

	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"`

	BillingCadence  datetime.ISODuration           `json:"billing_cadence"`
	BillingAnchor   time.Time                      `json:"billingAnchor"`
	ProRatingConfig productcatalog.ProRatingConfig `json:"pro_rating_config"`
	SettlementMode  productcatalog.SettlementMode  `json:"settlement_mode"`

	Annotations models.Annotations `json:"annotations"`
}

func (s Subscription) AsEntityInput() CreateSubscriptionEntityInput {
	return CreateSubscriptionEntityInput{
		CadencedModel: s.CadencedModel,
		NamespacedModel: models.NamespacedModel{
			Namespace: s.Namespace,
		},
		MetadataModel:   s.MetadataModel,
		Annotations:     s.Annotations,
		Plan:            s.PlanRef,
		Name:            s.Name,
		Description:     s.Description,
		CustomerId:      s.CustomerId,
		Currency:        s.Currency,
		BillingCadence:  s.BillingCadence,
		BillingAnchor:   s.BillingAnchor,
		ProRatingConfig: s.ProRatingConfig,
		SettlementMode:  s.SettlementMode,
	}
}

func (s Subscription) GetStatusAt(at time.Time) SubscriptionStatus {
	// Cadence might not be initialized
	if s.CadencedModel.IsZero() {
		return SubscriptionStatusInactive
	}

	if s.DeletedAt != nil && !s.DeletedAt.After(at) {
		return SubscriptionStatusInactive
	}

	// If the subscription has already started...
	if !s.ActiveFrom.After(at) {
		// ...and it has not been canceled yet, it is active
		if s.ActiveTo == nil {
			return SubscriptionStatusActive
		}
		// ...and it has been canceled, it is canceled
		if s.ActiveTo.After(at) {
			return SubscriptionStatusCanceled
		}
	} else {
		// If the subscription is scheduled to start in the future, it is scheduled
		return SubscriptionStatusScheduled
	}

	// The default status is inactive
	return SubscriptionStatusInactive
}

func (s Subscription) GetCustomerID() customer.CustomerID {
	return customer.CustomerID{
		Namespace: s.Namespace,
		ID:        s.CustomerId,
	}
}