Skip to content

Commit 2939678

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 3f49147 commit 2939678

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
enum :status, STATUSES, validate: true
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;
@@ -690,6 +691,7 @@ DROP INDEX IF EXISTS public.index_fees_taxes_on_fee_id_and_tax_id;
690691
DROP INDEX IF EXISTS public.index_fees_taxes_on_fee_id;
691692
DROP INDEX IF EXISTS public.index_fees_on_true_up_parent_fee_id;
692693
DROP INDEX IF EXISTS public.index_fees_on_subscription_id;
694+
DROP INDEX IF EXISTS public.index_fees_on_rate_card_rate_id;
693695
DROP INDEX IF EXISTS public.index_fees_on_pay_in_advance_event_transaction_id;
694696
DROP INDEX IF EXISTS public.index_fees_on_original_fee_id;
695697
DROP INDEX IF EXISTS public.index_fees_on_organization_id;
@@ -3451,7 +3453,8 @@ CREATE TABLE public.fees (
34513453
precise_credit_notes_amount_cents numeric(30,5) DEFAULT 0.0 NOT NULL,
34523454
fixed_charge_id uuid,
34533455
duplicated_in_advance boolean DEFAULT false,
3454-
original_fee_id uuid
3456+
original_fee_id uuid,
3457+
rate_card_rate_id uuid
34553458
);
34563459

34573460

@@ -8651,6 +8654,13 @@ CREATE INDEX index_fees_on_original_fee_id ON public.fees USING btree (original_
86518654
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);
86528655

86538656

8657+
--
8658+
-- Name: index_fees_on_rate_card_rate_id; Type: INDEX; Schema: public; Owner: -
8659+
--
8660+
8661+
CREATE INDEX index_fees_on_rate_card_rate_id ON public.fees USING btree (rate_card_rate_id);
8662+
8663+
86548664
--
86558665
-- Name: index_fees_on_subscription_id; Type: INDEX; Schema: public; Owner: -
86568666
--
@@ -11870,6 +11880,22 @@ ALTER TABLE ONLY public.billing_entities
1187011880
ADD CONSTRAINT fk_rails_4aa58496c3 FOREIGN KEY (applied_dunning_campaign_id) REFERENCES public.dunning_campaigns(id) ON DELETE SET NULL;
1187111881

1187211882

11883+
--
11884+
-- Name: product_item_filter_values fk_rails_4b395cde98; Type: FK CONSTRAINT; Schema: public; Owner: -
11885+
--
11886+
11887+
ALTER TABLE ONLY public.product_item_filter_values
11888+
ADD CONSTRAINT fk_rails_4b395cde98 FOREIGN KEY (billable_metric_filter_id) REFERENCES public.billable_metric_filters(id);
11889+
11890+
11891+
--
11892+
-- Name: fees fk_rails_4cadfc14f3; Type: FK CONSTRAINT; Schema: public; Owner: -
11893+
--
11894+
11895+
ALTER TABLE ONLY public.fees
11896+
ADD CONSTRAINT fk_rails_4cadfc14f3 FOREIGN KEY (rate_card_rate_id) REFERENCES public.rate_card_rates(id) NOT VALID;
11897+
11898+
1187311899
--
1187411900
-- Name: order_forms fk_rails_4ed54bfec0; Type: FK CONSTRAINT; Schema: public; Owner: -
1187511901
--
@@ -13658,6 +13684,7 @@ INSERT INTO "schema_migrations" (version) VALUES
1365813684
('20260609161044'),
1365913685
('20260608111837'),
1366013686
('20260608074112'),
13687+
('20260604182138'),
1366113688
('20260604181958'),
1366213689
('20260604181826'),
1366313690
('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)