File size: 3,181 Bytes
1c4c66b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package adapter

import (
	"errors"
	"slices"

	"github.com/samber/lo"
	"github.com/samber/mo"

	"github.com/openmeterio/openmeter/openmeter/customer"
	"github.com/openmeterio/openmeter/openmeter/ent/db"
	"github.com/openmeterio/openmeter/pkg/models"
)

func CustomerFromDBEntity(e db.Customer, expands customer.Expands) (*customer.Customer, error) {
	subjectKeys, err := subjectKeysFromDBEntity(e)
	if err != nil {
		return nil, err
	}

	var metadata *models.Metadata

	if len(e.Metadata) > 0 {
		metadata = lo.ToPtr(models.NewMetadata(e.Metadata))
	}

	var annotations *models.Annotations

	if len(e.Annotations) > 0 {
		annotations = &e.Annotations
	}

	result := &customer.Customer{
		ManagedResource: models.NewManagedResource(models.ManagedResourceInput{
			ID:          e.ID,
			Namespace:   e.Namespace,
			CreatedAt:   e.CreatedAt,
			UpdatedAt:   e.UpdatedAt,
			DeletedAt:   e.DeletedAt,
			Name:        e.Name,
			Description: e.Description,
		}),
		PrimaryEmail: e.PrimaryEmail,
		Currency:     e.Currency,
		Metadata:     metadata,
		Annotation:   annotations,
	}

	// Only set UsageAttribution if there are subject keys
	if len(subjectKeys) > 0 {
		result.UsageAttribution = &customer.CustomerUsageAttribution{
			SubjectKeys: subjectKeys,
		}
	}

	if slices.Contains(expands, customer.ExpandSubscriptions) {
		activeSubscriptionIDs, err := resolveActiveSubscriptionIDs(e)
		if err != nil {
			return nil, err
		}

		result.ActiveSubscriptionIDs = mo.Some(activeSubscriptionIDs)
	}

	if e.Key != "" {
		result.Key = &e.Key
	}

	if e.BillingAddressCity != nil || e.BillingAddressCountry != nil || e.BillingAddressLine1 != nil || e.BillingAddressLine2 != nil || e.BillingAddressPhoneNumber != nil || e.BillingAddressPostalCode != nil || e.BillingAddressState != nil {
		result.BillingAddress = &models.Address{
			City:        e.BillingAddressCity,
			Country:     e.BillingAddressCountry,
			Line1:       e.BillingAddressLine1,
			Line2:       e.BillingAddressLine2,
			PhoneNumber: e.BillingAddressPhoneNumber,
			PostalCode:  e.BillingAddressPostalCode,
			State:       e.BillingAddressState,
		}
	}

	return result, nil
}

func resolveActiveSubscriptionIDs(e db.Customer) ([]string, error) {
	subscriptions, err := e.Edges.SubscriptionOrErr()
	if err != nil {
		if db.IsNotLoaded(err) {
			return nil, errors.New("subscriptions must be loaded for customer")
		}

		return nil, err
	}

	subscriptionIDs := lo.FilterMap(subscriptions, func(item *db.Subscription, _ int) (string, bool) {
		if item == nil {
			return "", false
		}

		return item.ID, true
	})

	return subscriptionIDs, nil
}

func subjectKeysFromDBEntity(customerEntity db.Customer) ([]string, error) {
	subjectEntities, err := customerEntity.Edges.SubjectsOrErr()
	if err != nil {
		if db.IsNotLoaded(err) {
			return nil, errors.New("subjects must be loaded for customer")
		}

		return nil, err
	}

	subjectKeys := lo.FilterMap(subjectEntities, func(item *db.CustomerSubjects, _ int) (string, bool) {
		if item == nil {
			return "", false
		}

		return item.SubjectKey, true
	})

	// Sort the subject keys to make sure the order is consistent
	slices.Sort(subjectKeys)

	return subjectKeys, nil
}