Skip to content

Commit 3e4f5a7

Browse files
committed
fix: complete custom currency charge migration
1 parent 7854f8e commit 3e4f5a7

10 files changed

Lines changed: 48 additions & 32 deletions

File tree

openmeter/billing/charges/creditpurchase/adapter/funded_credit_activity.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,14 @@ func ListFundedCreditActivities(ctx context.Context, dbClient *db.Client, input
6565

6666
if input.Currency != nil {
6767
query = query.Where(dbchargecreditpurchasecreditgrant.HasCreditPurchaseWith(
68-
dbchargecreditpurchase.HasCustomCurrencyWith(
69-
dbcustomcurrency.CodeEQ(*input.Currency),
70-
dbcustomcurrency.Namespace(input.Customer.Namespace),
71-
dbcustomcurrency.DeletedAtIsNil(),
68+
dbchargecreditpurchase.Or(
69+
dbchargecreditpurchase.HasCustomCurrencyWith(
70+
dbcustomcurrency.CodeEQ(*input.Currency),
71+
dbcustomcurrency.Namespace(input.Customer.Namespace),
72+
dbcustomcurrency.DeletedAtIsNil(),
73+
),
74+
dbchargecreditpurchase.FiatCurrencyCodeEQ(*input.Currency),
7275
),
73-
dbchargecreditpurchase.FiatCurrencyCodeEQ(*input.Currency),
7476
))
7577
}
7678

openmeter/billing/charges/service/base_test.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ import (
2929
usagebasedadapter "github.com/openmeterio/openmeter/openmeter/billing/charges/usagebased/adapter"
3030
usagebasedservice "github.com/openmeterio/openmeter/openmeter/billing/charges/usagebased/service"
3131
billingratingservice "github.com/openmeterio/openmeter/openmeter/billing/rating/service"
32+
currencyadapter "github.com/openmeterio/openmeter/openmeter/currencies/adapter"
33+
"github.com/openmeterio/openmeter/openmeter/currencies/currencyresolver"
34+
currencyservice "github.com/openmeterio/openmeter/openmeter/currencies/service"
3235
currenciestestutils "github.com/openmeterio/openmeter/openmeter/currencies/testutils/currency"
3336
"github.com/openmeterio/openmeter/openmeter/customer"
3437
"github.com/openmeterio/openmeter/openmeter/ledger/recognizer"
@@ -176,6 +179,15 @@ func (s *BaseSuite) SetupSuite() {
176179
})
177180
s.NoError(err)
178181

182+
currencyAdapter, err := currencyadapter.New(currencyadapter.Config{
183+
Client: s.DBClient,
184+
})
185+
s.NoError(err)
186+
currencyService, err := currencyservice.New(currencyAdapter)
187+
s.NoError(err)
188+
currencyResolver, err := currencyresolver.New(currencyService)
189+
s.NoError(err)
190+
179191
chargesService, err := New(Config{
180192
Logger: slog.Default(),
181193
Adapter: chargesAdapter,
@@ -187,8 +199,9 @@ func (s *BaseSuite) SetupSuite() {
187199
UsageBasedService: usageBasedService,
188200
RecognizerService: recognizer.NoopService{},
189201

190-
BillingService: s.BillingService,
191-
TaxCodeService: s.TaxCodeService,
202+
BillingService: s.BillingService,
203+
TaxCodeService: s.TaxCodeService,
204+
CurrencyResolver: currencyResolver,
192205
})
193206
s.NoError(err)
194207
s.Charges = chargesService

openmeter/billing/worker/subscriptionsync/service/base_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ func (s *SuiteBase) assertCharge(ctx context.Context, charge charges.Charge, sub
501501
s.Equal(expectedCharge.Status, string(usageBasedCharge.Status), "%s: status", childID)
502502
s.Equal(subsView.Subscription.SettlementMode, usageBasedCharge.Intent.GetSettlementMode(), "%s: settlement mode", childID)
503503
s.Equal(s.Customer.ID, usageBasedCharge.Intent.GetCustomerID(), "%s: customer id", childID)
504-
s.Equal(subsView.Subscription.Currency, usageBasedCharge.Intent.GetCurrency(), "%s: currency", childID)
504+
s.Equal(subsView.Subscription.Currency, usageBasedCharge.Intent.GetCurrency().GetCode(), "%s: currency", childID)
505505
s.Equal(expectedCharge.Periods[idx], baseIntent.ServicePeriod, "%s: service period", childID)
506506
if len(expectedCharge.FullServicePeriods) > 0 {
507507
s.Equal(expectedCharge.FullServicePeriods[idx], baseIntent.FullServicePeriod, "%s: full service period", childID)
@@ -535,7 +535,7 @@ func (s *SuiteBase) assertCharge(ctx context.Context, charge charges.Charge, sub
535535
s.Equal(expectedCharge.Status, string(flatFeeCharge.Status), "%s: status", childID)
536536
s.Equal(subsView.Subscription.SettlementMode, flatFeeCharge.Intent.GetSettlementMode(), "%s: settlement mode", childID)
537537
s.Equal(s.Customer.ID, flatFeeCharge.Intent.GetCustomerID(), "%s: customer id", childID)
538-
s.Equal(subsView.Subscription.Currency, flatFeeCharge.Intent.GetCurrency(), "%s: currency", childID)
538+
s.Equal(subsView.Subscription.Currency, flatFeeCharge.Intent.GetCurrency().GetCode(), "%s: currency", childID)
539539
s.Equal(expectedCharge.Periods[idx], baseIntent.ServicePeriod, "%s: service period", childID)
540540
if len(expectedCharge.FullServicePeriods) > 0 {
541541
s.Equal(expectedCharge.FullServicePeriods[idx], baseIntent.FullServicePeriod, "%s: full service period", childID)

openmeter/ent/db/migrate/schema.go

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

openmeter/ent/schema/charges.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ func (chargesMetaMixin) Annotations() []schema.Annotation {
294294
return []schema.Annotation{
295295
entsql.Checks(map[string]string{
296296
"currency_reference": `(currency IS NULL) <> (custom_currency_id IS NULL)`,
297+
"currency_not_empty": `currency IS NULL OR currency <> ''`,
297298
}),
298299
}
299300
}

pkg/currencyx/code.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func (c Code) Equal(other Code) bool {
3434
}
3535

3636
func (c Code) Type() CurrencyType {
37-
if len(c) <= 3 {
37+
if len(c) == 3 {
3838
return CurrencyTypeFiat
3939
}
4040

@@ -58,7 +58,7 @@ func (c Code) Validate() error {
5858
return models.NewNillableGenericValidationError(errors.Join(errs...))
5959
}
6060

61-
if c.IsFiat() {
61+
if len(c) == 3 {
6262
if err := validateFiatCurrencyCode(c); err != nil {
6363
errs = append(errs, err)
6464
}

pkg/currencyx/code_test.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ func TestCodeValidate(t *testing.T) {
4343
code: currencyx.Code(strings.Repeat("A", currencyx.CustomCurrencyCodeMaxLength)),
4444
},
4545
{
46-
name: "invalid short fiat code",
46+
name: "custom code too short",
4747
code: "AB",
48-
expectedError: "invalid fiat currency code",
48+
expectedError: "between 4 and 24 characters",
4949
},
5050
{
5151
name: "custom code too long",
@@ -126,16 +126,6 @@ func TestCodeType(t *testing.T) {
126126
code currencyx.Code
127127
expected currencyx.CurrencyType
128128
}{
129-
{
130-
name: "one-character fiat classification",
131-
code: "C",
132-
expected: currencyx.CurrencyTypeFiat,
133-
},
134-
{
135-
name: "two-character fiat classification",
136-
code: "CR",
137-
expected: currencyx.CurrencyTypeFiat,
138-
},
139129
{
140130
name: "fiat",
141131
code: "USD",
Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
-- reverse: recreate charges_search_v1s view without custom_currency_id
2+
DROP VIEW IF EXISTS "charges_search_v1s";
13
-- reverse: modify "charge_usage_based" table
2-
ALTER TABLE "charge_usage_based" DROP CONSTRAINT "charge_usage_based_custom_currencies_charges_usage_based", DROP COLUMN "custom_currency_id", ALTER COLUMN "currency" SET NOT NULL, DROP CONSTRAINT "currency_reference";
4+
ALTER TABLE "charge_usage_based" DROP CONSTRAINT "charge_usage_based_custom_currencies_charges_usage_based", DROP CONSTRAINT "currency_reference", DROP CONSTRAINT "currency_not_empty", DROP COLUMN "custom_currency_id", ALTER COLUMN "currency" SET NOT NULL;
35
-- reverse: modify "charge_flat_fees" table
4-
ALTER TABLE "charge_flat_fees" DROP CONSTRAINT "charge_flat_fees_custom_currencies_charges_flat_fee", DROP COLUMN "custom_currency_id", ALTER COLUMN "currency" SET NOT NULL, DROP CONSTRAINT "currency_reference";
6+
ALTER TABLE "charge_flat_fees" DROP CONSTRAINT "charge_flat_fees_custom_currencies_charges_flat_fee", DROP CONSTRAINT "currency_reference", DROP CONSTRAINT "currency_not_empty", DROP COLUMN "custom_currency_id", ALTER COLUMN "currency" SET NOT NULL;
57
-- reverse: modify "charge_credit_purchases" table
6-
ALTER TABLE "charge_credit_purchases" DROP CONSTRAINT "charge_credit_purchases_custom_currencies_charges_credit_purcha", DROP COLUMN "custom_currency_id", ALTER COLUMN "currency" SET NOT NULL, DROP CONSTRAINT "currency_reference";
8+
ALTER TABLE "charge_credit_purchases" DROP CONSTRAINT "charge_credit_purchases_custom_currencies_charges_credit_purcha", DROP CONSTRAINT "currency_reference", DROP CONSTRAINT "currency_not_empty", DROP COLUMN "custom_currency_id", ALTER COLUMN "currency" SET NOT NULL;
9+
CREATE VIEW "charges_search_v1s" AS
10+
SELECT "id", "namespace", "metadata", "created_at", "updated_at", "deleted_at", "name", "description", "annotations", "customer_id", "service_period_from", "service_period_to", "billing_period_from", "billing_period_to", "full_service_period_from", "full_service_period_to", "status", "unique_reference_id", "currency", "managed_by", "subscription_id", "subscription_phase_id", "subscription_item_id", "advance_after", "tax_code_id", "tax_behavior", NULL::timestamptz AS "base_intent_deleted_at", 'credit_purchase' AS "type" FROM "charge_credit_purchases" UNION ALL SELECT "id", "namespace", "metadata", "created_at", "updated_at", "deleted_at", "name", "description", "annotations", "customer_id", "service_period_from", "service_period_to", "billing_period_from", "billing_period_to", "full_service_period_from", "full_service_period_to", "status", "unique_reference_id", "currency", "managed_by", "subscription_id", "subscription_phase_id", "subscription_item_id", "advance_after", "tax_code_id", "tax_behavior", "intent_deleted_at" AS "base_intent_deleted_at", 'flat_fee' AS "type" FROM "charge_flat_fees" UNION ALL SELECT "id", "namespace", "metadata", "created_at", "updated_at", "deleted_at", "name", "description", "annotations", "customer_id", "service_period_from", "service_period_to", "billing_period_from", "billing_period_to", "full_service_period_from", "full_service_period_to", "status", "unique_reference_id", "currency", "managed_by", "subscription_id", "subscription_phase_id", "subscription_item_id", "advance_after", "tax_code_id", "tax_behavior", "intent_deleted_at" AS "base_intent_deleted_at", 'usage_based' AS "type" FROM "charge_usage_based";
Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
-- modify "charge_credit_purchases" table
2-
ALTER TABLE "charge_credit_purchases" ADD CONSTRAINT "currency_reference" CHECK ((currency IS NULL) <> (custom_currency_id IS NULL)), ALTER COLUMN "currency" DROP NOT NULL, ADD COLUMN "custom_currency_id" character(26) NULL, ADD CONSTRAINT "charge_credit_purchases_custom_currencies_charges_credit_purcha" FOREIGN KEY ("custom_currency_id") REFERENCES "custom_currencies" ("id") ON UPDATE NO ACTION ON DELETE RESTRICT;
2+
ALTER TABLE "charge_credit_purchases" ADD CONSTRAINT "currency_reference" CHECK ((currency IS NULL) <> (custom_currency_id IS NULL)), ADD CONSTRAINT "currency_not_empty" CHECK (currency IS NULL OR currency <> ''), ALTER COLUMN "currency" DROP NOT NULL, ADD COLUMN "custom_currency_id" character(26) NULL, ADD CONSTRAINT "charge_credit_purchases_custom_currencies_charges_credit_purcha" FOREIGN KEY ("custom_currency_id") REFERENCES "custom_currencies" ("id") ON UPDATE NO ACTION ON DELETE RESTRICT;
33
-- modify "charge_flat_fees" table
4-
ALTER TABLE "charge_flat_fees" ADD CONSTRAINT "currency_reference" CHECK ((currency IS NULL) <> (custom_currency_id IS NULL)), ALTER COLUMN "currency" DROP NOT NULL, ADD COLUMN "custom_currency_id" character(26) NULL, ADD CONSTRAINT "charge_flat_fees_custom_currencies_charges_flat_fee" FOREIGN KEY ("custom_currency_id") REFERENCES "custom_currencies" ("id") ON UPDATE NO ACTION ON DELETE RESTRICT;
4+
ALTER TABLE "charge_flat_fees" ADD CONSTRAINT "currency_reference" CHECK ((currency IS NULL) <> (custom_currency_id IS NULL)), ADD CONSTRAINT "currency_not_empty" CHECK (currency IS NULL OR currency <> ''), ALTER COLUMN "currency" DROP NOT NULL, ADD COLUMN "custom_currency_id" character(26) NULL, ADD CONSTRAINT "charge_flat_fees_custom_currencies_charges_flat_fee" FOREIGN KEY ("custom_currency_id") REFERENCES "custom_currencies" ("id") ON UPDATE NO ACTION ON DELETE RESTRICT;
55
-- modify "charge_usage_based" table
6-
ALTER TABLE "charge_usage_based" ADD CONSTRAINT "currency_reference" CHECK ((currency IS NULL) <> (custom_currency_id IS NULL)), ALTER COLUMN "currency" DROP NOT NULL, ADD COLUMN "custom_currency_id" character(26) NULL, ADD CONSTRAINT "charge_usage_based_custom_currencies_charges_usage_based" FOREIGN KEY ("custom_currency_id") REFERENCES "custom_currencies" ("id") ON UPDATE NO ACTION ON DELETE RESTRICT;
6+
ALTER TABLE "charge_usage_based" ADD CONSTRAINT "currency_reference" CHECK ((currency IS NULL) <> (custom_currency_id IS NULL)), ADD CONSTRAINT "currency_not_empty" CHECK (currency IS NULL OR currency <> ''), ALTER COLUMN "currency" DROP NOT NULL, ADD COLUMN "custom_currency_id" character(26) NULL, ADD CONSTRAINT "charge_usage_based_custom_currencies_charges_usage_based" FOREIGN KEY ("custom_currency_id") REFERENCES "custom_currencies" ("id") ON UPDATE NO ACTION ON DELETE RESTRICT;
77

8-
-- TODO: Add empty checks
8+
-- recreate charges_search_v1s view to include custom_currency_id
9+
DROP VIEW IF EXISTS "charges_search_v1s";
10+
CREATE VIEW "charges_search_v1s" AS
11+
SELECT "id", "namespace", "metadata", "created_at", "updated_at", "deleted_at", "name", "description", "annotations", "customer_id", "service_period_from", "service_period_to", "billing_period_from", "billing_period_to", "full_service_period_from", "full_service_period_to", "status", "unique_reference_id", "currency", "custom_currency_id", "managed_by", "subscription_id", "subscription_phase_id", "subscription_item_id", "advance_after", "tax_code_id", "tax_behavior", NULL::timestamptz AS "base_intent_deleted_at", 'credit_purchase' AS "type" FROM "charge_credit_purchases" UNION ALL SELECT "id", "namespace", "metadata", "created_at", "updated_at", "deleted_at", "name", "description", "annotations", "customer_id", "service_period_from", "service_period_to", "billing_period_from", "billing_period_to", "full_service_period_from", "full_service_period_to", "status", "unique_reference_id", "currency", "custom_currency_id", "managed_by", "subscription_id", "subscription_phase_id", "subscription_item_id", "advance_after", "tax_code_id", "tax_behavior", "intent_deleted_at" AS "base_intent_deleted_at", 'flat_fee' AS "type" FROM "charge_flat_fees" UNION ALL SELECT "id", "namespace", "metadata", "created_at", "updated_at", "deleted_at", "name", "description", "annotations", "customer_id", "service_period_from", "service_period_to", "billing_period_from", "billing_period_to", "full_service_period_from", "full_service_period_to", "status", "unique_reference_id", "currency", "custom_currency_id", "managed_by", "subscription_id", "subscription_phase_id", "subscription_item_id", "advance_after", "tax_code_id", "tax_behavior", "intent_deleted_at" AS "base_intent_deleted_at", 'usage_based' AS "type" FROM "charge_usage_based";

tools/migrate/migrations/atlas.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
h1:GsZiySv+ZGohiTpP5HwaXd4KTBcMZsMOgujJRwI2kho=
1+
h1:f00I9PeE3w9+bBTdFVHzvUpjrFB+Wy4/OTrh7nAtjbk=
22
20240826120919_init.up.sql h1:tc1V91/smlmaeJGQ8h+MzTEeFjjnrrFDbDAjOYJK91o=
33
20240903155435_entitlement-expired-index.up.sql h1:Hp8u5uckmLXc1cRvWU0AtVnnK8ShlpzZNp8pbiJLhac=
44
20240917172257_billing-entities.up.sql h1:Q1dAMo0Vjiit76OybClNfYPGC5nmvov2/M2W1ioi4Kw=
@@ -239,4 +239,4 @@ h1:GsZiySv+ZGohiTpP5HwaXd4KTBcMZsMOgujJRwI2kho=
239239
20260716152332_rescope-credit-grant-key-to-customer.up.sql h1:gbeATYlchOi0pwaTUFX+nrbLoS0jZbVDMHn8uMTck0c=
240240
20260717060208_add_bulk_invoice_schema_level_2_migration_function.up.sql h1:kJCvXyNuRC9FMysGg9c6nesUXsfbkNq/RKfTIwnQzEw=
241241
20260717160017_custom_currencies.up.sql h1:HHScXLfjVxumxzNrw/RdxZZZMo3EnCE5Min67fEX9jo=
242-
20260720093016_charges-custom-currencies.up.sql h1:hiascJhglspAGXnm5UY+25dfc0HnDE+GVfMxbvxQ6ok=
242+
20260720093016_charges-custom-currencies.up.sql h1:U9K4UDDHwNCCqcAQ3n9HFTXaibsm66KPebSa/7XB2OE=

0 commit comments

Comments
 (0)