Skip to content

Commit 6cd4f01

Browse files
committed
feat(products): link fees to rate_card_rate and add product_item fee type
Fees produced by the new billing path need to reference the catalog rate that generated them and a fee type identifying them as coming from a product item. Add an optional rate_card_rate_id reference to fees (concurrent index, unvalidated foreign key for a safe rollout) and append product_item to Fee::FEE_TYPES. The existing fee types and billing path are untouched.
1 parent ca2a8e3 commit 6cd4f01

7 files changed

Lines changed: 53 additions & 2 deletions

File tree

app/models/fee.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class Fee < ApplicationRecord
2121
belongs_to :organization
2222
belongs_to :billing_entity
2323
belongs_to :fixed_charge, -> { with_discarded }, optional: true
24+
belongs_to :rate_card_rate, optional: true
2425

2526
has_one :adjusted_fee, dependent: :nullify
2627
has_one :billable_metric, -> { with_discarded }, through: :charge
@@ -45,7 +46,7 @@ class Fee < ApplicationRecord
4546
monetize :unit_amount_cents, disable_validation: true, allow_nil: true, with_model_currency: :currency
4647

4748
# TODO: Deprecate add_on type in the near future
48-
FEE_TYPES = %i[charge add_on subscription credit commitment fixed_charge].freeze
49+
FEE_TYPES = %i[charge add_on subscription credit commitment fixed_charge product_item].freeze
4950
PAYMENT_STATUS = %i[pending succeeded failed refunded].freeze
5051

5152
enum :fee_type, FEE_TYPES
@@ -414,6 +415,7 @@ def to_date
414415
# original_fee_id :uuid
415416
# pay_in_advance_event_id :uuid
416417
# pay_in_advance_event_transaction_id :string
418+
# rate_card_rate_id :uuid
417419
# subscription_id :uuid
418420
# true_up_parent_fee_id :uuid
419421
#
@@ -435,6 +437,7 @@ def to_date
435437
# index_fees_on_organization_id (organization_id)
436438
# index_fees_on_original_fee_id (original_fee_id)
437439
# index_fees_on_pay_in_advance_event_transaction_id (pay_in_advance_event_transaction_id) WHERE (deleted_at IS NULL)
440+
# index_fees_on_rate_card_rate_id (rate_card_rate_id)
438441
# index_fees_on_subscription_id (subscription_id)
439442
# index_fees_on_true_up_parent_fee_id (true_up_parent_fee_id)
440443
#
@@ -449,6 +452,7 @@ def to_date
449452
# fk_rails_... (invoice_id => invoices.id)
450453
# fk_rails_... (organization_id => organizations.id)
451454
# fk_rails_... (original_fee_id => fees.id)
455+
# fk_rails_... (rate_card_rate_id => rate_card_rates.id)
452456
# fk_rails_... (subscription_id => subscriptions.id)
453457
# fk_rails_... (true_up_parent_fee_id => fees.id)
454458
#

app/models/rate_card_rate.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ class RateCardRate < ApplicationRecord
3333
belongs_to :organization
3434
belongs_to :rate_card
3535

36+
has_many :fees
37+
3638
enum :rate_model, RATE_MODELS, validate: true
3739
enum :billing_interval_unit, BILLING_INTERVAL_UNITS, validate: true
3840

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# frozen_string_literal: true
2+
3+
class AddRateCardRateToFees < ActiveRecord::Migration[8.0]
4+
disable_ddl_transaction!
5+
6+
def change
7+
add_reference :fees, :rate_card_rate, type: :uuid, null: true, index: {algorithm: :concurrently}
8+
add_foreign_key :fees, :rate_card_rates, column: :rate_card_rate_id, validate: false
9+
end
10+
end

db/structure.sql

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ ALTER TABLE IF EXISTS ONLY public.payment_provider_customers DROP CONSTRAINT IF
231231
ALTER TABLE IF EXISTS ONLY public.wallets DROP CONSTRAINT IF EXISTS fk_rails_4ff087c52e;
232232
ALTER TABLE IF EXISTS ONLY public.rate_cards DROP CONSTRAINT IF EXISTS fk_rails_4f7ffc3e03;
233233
ALTER TABLE IF EXISTS ONLY public.order_forms DROP CONSTRAINT IF EXISTS fk_rails_4ed54bfec0;
234+
ALTER TABLE IF EXISTS ONLY public.fees DROP CONSTRAINT IF EXISTS fk_rails_4cadfc14f3;
234235
ALTER TABLE IF EXISTS ONLY public.product_item_filter_values DROP CONSTRAINT IF EXISTS fk_rails_4b395cde98;
235236
ALTER TABLE IF EXISTS ONLY public.billing_entities DROP CONSTRAINT IF EXISTS fk_rails_4aa58496c3;
236237
ALTER TABLE IF EXISTS ONLY public.recurring_transaction_rules_invoice_custom_sections DROP CONSTRAINT IF EXISTS fk_rails_49fcc221b0;
@@ -689,6 +690,7 @@ DROP INDEX IF EXISTS public.index_fees_taxes_on_fee_id_and_tax_id;
689690
DROP INDEX IF EXISTS public.index_fees_taxes_on_fee_id;
690691
DROP INDEX IF EXISTS public.index_fees_on_true_up_parent_fee_id;
691692
DROP INDEX IF EXISTS public.index_fees_on_subscription_id;
693+
DROP INDEX IF EXISTS public.index_fees_on_rate_card_rate_id;
692694
DROP INDEX IF EXISTS public.index_fees_on_pay_in_advance_event_transaction_id;
693695
DROP INDEX IF EXISTS public.index_fees_on_original_fee_id;
694696
DROP INDEX IF EXISTS public.index_fees_on_organization_id;
@@ -3438,7 +3440,8 @@ CREATE TABLE public.fees (
34383440
precise_credit_notes_amount_cents numeric(30,5) DEFAULT 0.0 NOT NULL,
34393441
fixed_charge_id uuid,
34403442
duplicated_in_advance boolean DEFAULT false,
3441-
original_fee_id uuid
3443+
original_fee_id uuid,
3444+
rate_card_rate_id uuid
34423445
);
34433446

34443447

@@ -8637,6 +8640,13 @@ CREATE INDEX index_fees_on_original_fee_id ON public.fees USING btree (original_
86378640
CREATE INDEX index_fees_on_pay_in_advance_event_transaction_id ON public.fees USING btree (pay_in_advance_event_transaction_id) WHERE (deleted_at IS NULL);
86388641

86398642

8643+
--
8644+
-- Name: index_fees_on_rate_card_rate_id; Type: INDEX; Schema: public; Owner: -
8645+
--
8646+
8647+
CREATE INDEX index_fees_on_rate_card_rate_id ON public.fees USING btree (rate_card_rate_id);
8648+
8649+
86408650
--
86418651
-- Name: index_fees_on_subscription_id; Type: INDEX; Schema: public; Owner: -
86428652
--
@@ -11849,6 +11859,22 @@ ALTER TABLE ONLY public.billing_entities
1184911859
ADD CONSTRAINT fk_rails_4aa58496c3 FOREIGN KEY (applied_dunning_campaign_id) REFERENCES public.dunning_campaigns(id) ON DELETE SET NULL;
1185011860

1185111861

11862+
--
11863+
-- Name: product_item_filter_values fk_rails_4b395cde98; Type: FK CONSTRAINT; Schema: public; Owner: -
11864+
--
11865+
11866+
ALTER TABLE ONLY public.product_item_filter_values
11867+
ADD CONSTRAINT fk_rails_4b395cde98 FOREIGN KEY (billable_metric_filter_id) REFERENCES public.billable_metric_filters(id);
11868+
11869+
11870+
--
11871+
-- Name: fees fk_rails_4cadfc14f3; Type: FK CONSTRAINT; Schema: public; Owner: -
11872+
--
11873+
11874+
ALTER TABLE ONLY public.fees
11875+
ADD CONSTRAINT fk_rails_4cadfc14f3 FOREIGN KEY (rate_card_rate_id) REFERENCES public.rate_card_rates(id) NOT VALID;
11876+
11877+
1185211878
--
1185311879
-- Name: order_forms fk_rails_4ed54bfec0; Type: FK CONSTRAINT; Schema: public; Owner: -
1185411880
--
@@ -13637,6 +13663,7 @@ INSERT INTO "schema_migrations" (version) VALUES
1363713663
('20260609161044'),
1363813664
('20260608111837'),
1363913665
('20260608074112'),
13666+
('20260604182138'),
1364013667
('20260604181958'),
1364113668
('20260604181826'),
1364213669
('20260604181654'),

schema.graphql

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

schema.json

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

spec/models/fee_spec.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
it { is_expected.to belong_to(:add_on).optional }
99
it { is_expected.to belong_to(:charge).optional }
1010
it { is_expected.to belong_to(:fixed_charge).optional }
11+
it { is_expected.to belong_to(:rate_card_rate).optional }
1112
it { is_expected.to have_many(:presentation_breakdowns) }
1213
it { is_expected.to have_one(:fixed_charge_add_on).through(:fixed_charge) }
1314
it { is_expected.to have_one(:adjusted_fee).dependent(:nullify) }

0 commit comments

Comments
 (0)