Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

misc: prevent applying taxes for current usage where it is not necessary #2532

Merged
merged 2 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion app/graphql/resolvers/customers/usage_resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ class UsageResolver < Resolvers::BaseResolver
type Types::Customers::Usage::Current, null: false

def resolve(customer_id:, subscription_id:)
result = Invoices::CustomerUsageService.with_ids(context[:current_user], customer_id:, subscription_id:).call
result = Invoices::CustomerUsageService.with_ids(
context[:current_user],
customer_id:,
subscription_id:,
apply_taxes: false
).call

result.success? ? result.usage : result_error(result)
end
Expand Down
26 changes: 18 additions & 8 deletions app/services/invoices/customer_usage_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,26 @@

module Invoices
class CustomerUsageService < BaseService
def initialize(current_user, customer:, subscription:)
def initialize(current_user, customer:, subscription:, apply_taxes: true)
super(current_user)

@apply_taxes = apply_taxes
@customer = customer
@subscription = subscription
end

def self.with_external_ids(customer_external_id:, external_subscription_id:, organization_id:)
def self.with_external_ids(customer_external_id:, external_subscription_id:, organization_id:, apply_taxes: true)
customer = Customer.find_by!(external_id: customer_external_id, organization_id:)
subscription = customer&.active_subscriptions&.find_by(external_id: external_subscription_id)
new(nil, customer:, subscription:)
new(nil, customer:, subscription:, apply_taxes:)
rescue ActiveRecord::RecordNotFound
result.not_found_failure!(resource: 'customer')
end

def self.with_ids(current_user, customer_id:, subscription_id:)
def self.with_ids(current_user, customer_id:, subscription_id:, apply_taxes: true)
customer = Customer.find_by(id: customer_id, organization_id: current_user.organization_ids)
subscription = customer&.active_subscriptions&.find_by(id: subscription_id)
new(current_user, customer:, subscription:)
new(current_user, customer:, subscription:, apply_taxes:)
rescue ActiveRecord::RecordNotFound
result.not_found_failure!(resource: 'customer')
end
Expand All @@ -36,7 +37,7 @@ def call

private

attr_reader :invoice, :subscription
attr_reader :invoice, :subscription, :apply_taxes

delegate :plan, to: :subscription
delegate :organization, to: :subscription
Expand All @@ -56,10 +57,12 @@ def compute_usage

add_charge_fees

if customer_provider_taxation?
if apply_taxes && customer_provider_taxation?
compute_amounts_with_provider_taxes
else
elsif apply_taxes
compute_amounts
else
compute_amounts_without_tax
end

format_usage
Expand Down Expand Up @@ -141,6 +144,13 @@ def compute_amounts
invoice.total_amount_cents = invoice.fees_amount_cents + invoice.taxes_amount_cents
end

def compute_amounts_without_tax
invoice.fees_amount_cents = invoice.fees.sum(&:amount_cents)
invoice.taxes_amount_cents = 0
invoice.taxes_rate = 0
invoice.total_amount_cents = invoice.fees_amount_cents
end

def compute_amounts_with_provider_taxes
invoice.fees_amount_cents = invoice.fees.sum(&:amount_cents)

Expand Down
3 changes: 2 additions & 1 deletion app/services/lifetime_usages/calculate_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ def calculate_current_usage_amount_cents
result = Invoices::CustomerUsageService.call(
nil, # current_user
customer: subscription.customer,
subscription: subscription
subscription: subscription,
apply_taxes: false
)
result.usage.amount_cents
end
Expand Down
4 changes: 2 additions & 2 deletions spec/graphql/resolvers/customers/usage_resolver_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@
expect(usage_response['currency']).to eq('EUR')
expect(usage_response['issuingDate']).to eq(Time.zone.today.end_of_month.iso8601)
expect(usage_response['amountCents']).to eq('405')
expect(usage_response['totalAmountCents']).to eq('486')
expect(usage_response['taxesAmountCents']).to eq('81')
expect(usage_response['totalAmountCents']).to eq('405')
expect(usage_response['taxesAmountCents']).to eq('0')

charge_usage = usage_response['chargesUsage'].first
expect(charge_usage['billableMetric']['name']).to eq(metric.name)
Expand Down
28 changes: 27 additions & 1 deletion spec/services/invoices/customer_usage_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

RSpec.describe Invoices::CustomerUsageService, type: :service, cache: :memory do
subject(:usage_service) do
described_class.with_ids(membership.user, customer_id:, subscription_id:)
described_class.with_ids(membership.user, customer_id:, subscription_id:, apply_taxes:)
end

let(:membership) { create(:membership) }
Expand All @@ -15,6 +15,7 @@
let(:subscription_id) { subscription&.id }
let(:plan) { create(:plan, interval: 'monthly') }
let(:timestamp) { Time.current }
let(:apply_taxes) { true }

let(:subscription) do
create(
Expand Down Expand Up @@ -93,6 +94,31 @@
end
end

context 'when apply_taxes property is set to false' do
let(:apply_taxes) { false }

it 'initializes an invoice' do
result = usage_service.call

aggregate_failures do
expect(result).to be_success
expect(result.invoice).to be_a(Invoice)

expect(result.usage).to have_attributes(
from_datetime: Time.current.beginning_of_month.iso8601,
to_datetime: Time.current.end_of_month.iso8601,
issuing_date: Time.zone.today.end_of_month.iso8601,
currency: 'EUR',
amount_cents: 2532, # 1266 * 2,
taxes_amount_cents: 0,
total_amount_cents: 2532
)
expect(result.usage.fees.size).to eq(1)
expect(result.usage.fees.first.charge.invoice_display_name).to eq(charge.invoice_display_name)
end
end
end

context 'when there is tax provider integration' do
let(:integration) { create(:anrok_integration, organization:) }
let(:integration_customer) { create(:anrok_customer, integration:, customer:) }
Expand Down