Skip to content

Commit 69c9411

Browse files
committed
fix(taxes): handle product fee tax changes
1 parent 3ba9d8f commit 69c9411

6 files changed

Lines changed: 53 additions & 4 deletions

File tree

app/models/fee.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class Fee < ApplicationRecord
6060
validates :events_count, numericality: {greater_than_or_equal_to: 0}, allow_nil: true
6161
validates :true_up_fee_id, presence: false, unless: :charge?
6262
validates :total_aggregated_units, presence: true, if: :charge?
63+
validates :rate_card_rate, presence: true, if: :product?
6364

6465
scope :positive_units, -> { where("fees.units > ?", 0) }
6566

app/services/taxes/destroy_service.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,12 @@ def call
5151
attr_reader :tax
5252

5353
def draft_invoice_ids
54-
@draft_invoice_ids ||= tax.organization.invoices
54+
@draft_invoice_ids ||= (
55+
tax.organization.invoices
5556
.where(customer_id: tax.applicable_customers.select(:id))
5657
.draft
57-
.pluck(:id)
58+
.pluck(:id) + tax.draft_fee_taxes.distinct.pluck("fees.invoice_id")
59+
).uniq
5860
end
5961
end
6062
end

app/services/taxes/update_service.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def call
1515
return result.not_found_failure!(resource: "tax") unless tax
1616

1717
customer_ids = tax.applicable_customers.select(:id).to_a
18+
draft_invoice_ids = tax.draft_fee_taxes.distinct.pluck("fees.invoice_id")
1819

1920
tax.name = params[:name] if params.key?(:name)
2021
tax.code = params[:code] if params.key?(:code)
@@ -26,8 +27,9 @@ def call
2627
manage_taxes_on_billing_entity if params.key?(:applied_to_organization)
2728

2829
customer_ids = (customer_ids + tax.reload.applicable_customers.select(:id)).uniq
29-
draft_invoices = tax.organization.invoices.where(customer_id: customer_ids).draft
30-
draft_invoices.update_all(ready_to_be_refreshed: true) # rubocop:disable Rails/SkipsModelValidations
30+
draft_invoice_ids |= tax.organization.invoices.where(customer_id: customer_ids).draft.pluck(:id)
31+
tax.organization.invoices.where(id: draft_invoice_ids)
32+
.update_all(ready_to_be_refreshed: true) # rubocop:disable Rails/SkipsModelValidations
3133

3234
result.tax = tax
3335
result

spec/models/fee_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@
1919
it { is_expected.to have_one(:true_up_fee).with_foreign_key(:true_up_parent_fee_id).class_name("Fee").dependent(:destroy) }
2020
it { is_expected.to belong_to(:original_fee).class_name("Fee").optional }
2121

22+
describe "validations" do
23+
it "requires a Rate Card Rate for Product fees" do
24+
fee = build(:fee, fee_type: :product, rate_card_rate: nil)
25+
26+
fee.validate
27+
28+
expect(fee.errors.of_kind?(:rate_card_rate, :blank)).to be(true)
29+
end
30+
end
31+
2232
describe "#ordered_by_period" do
2333
let(:fee1) do
2434
create(:fee, properties: {

spec/services/taxes/destroy_service_spec.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,23 @@
2323
expect { destroy_service.call }.to change { draft_invoice.reload.ready_to_be_refreshed }.to(true)
2424
end
2525

26+
context "when the tax is applied only to a Rate Card" do
27+
let(:tax) { create(:tax, organization:) }
28+
let(:rate_card) { create(:rate_card, organization:) }
29+
let(:rate_card_rate) { create(:rate_card_rate, organization:, rate_card:) }
30+
let(:draft_invoice) { create(:invoice, :draft, organization:, customer:) }
31+
32+
before do
33+
create(:rate_card_applied_tax, rate_card:, tax:, organization:)
34+
fee = create(:product_fee, invoice: draft_invoice, rate_card_rate:)
35+
create(:fee_applied_tax, fee:, tax:)
36+
end
37+
38+
it "marks the draft invoice as ready to be refreshed" do
39+
expect { destroy_service.call }.to change { draft_invoice.reload.ready_to_be_refreshed }.to(true)
40+
end
41+
end
42+
2643
it "does not remove the other tax from the default billing entity" do
2744
expect { destroy_service.call }.to change { billing_entity.applied_taxes.count }.by(-1)
2845
end

spec/services/taxes/update_service_spec.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,23 @@
113113
expect { update_service.call }.to change { draft_invoice.reload.ready_to_be_refreshed }.to(true)
114114
end
115115

116+
context "when the tax is applied only to a Rate Card" do
117+
let(:tax) { create(:tax, organization:) }
118+
let(:rate_card) { create(:rate_card, organization:) }
119+
let(:rate_card_rate) { create(:rate_card_rate, organization:, rate_card:) }
120+
let(:draft_invoice) { create(:invoice, :draft, organization:, customer:) }
121+
122+
before do
123+
create(:rate_card_applied_tax, rate_card:, tax:, organization:)
124+
fee = create(:product_fee, invoice: draft_invoice, rate_card_rate:)
125+
create(:fee_applied_tax, fee:, tax:)
126+
end
127+
128+
it "marks the draft invoice as ready to be refreshed" do
129+
expect { update_service.call }.to change { draft_invoice.reload.ready_to_be_refreshed }.to(true)
130+
end
131+
end
132+
116133
context "when tax is not found" do
117134
let(:tax) { nil }
118135

0 commit comments

Comments
 (0)