From 2d6504b70ccc78be6d4c4d74b259cfe8a126e6c7 Mon Sep 17 00:00:00 2001 From: Vincent Pochet Date: Mon, 26 Aug 2024 14:01:00 +0200 Subject: [PATCH] feat(ProgressiceBilling): Use draft invoices and previous subscriptions --- .../lifetime_usages/calculate_service.rb | 12 ++++- .../lifetime_usages/calculate_service_spec.rb | 46 ++++++++++++++++--- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/app/services/lifetime_usages/calculate_service.rb b/app/services/lifetime_usages/calculate_service.rb index 934d24ab41b..cc731395764 100644 --- a/app/services/lifetime_usages/calculate_service.rb +++ b/app/services/lifetime_usages/calculate_service.rb @@ -33,10 +33,18 @@ def call private - delegate :subscription, to: :lifetime_usage + delegate :subscription, :organization, to: :lifetime_usage def calculate_invoiced_usage_amount_cents - invoices = subscription.invoices.finalized + subscription_ids = organization.subscriptions + .where(external_id: subscription.external_id, subscription_at: subscription.subscription_at) + .where(canceled_at: nil) + .select(:id) + + invoices = organization.invoices.subscription + .where(status: %i[finalized draft]) + .joins(:invoice_subscriptions) + .where(invoice_subscriptions: {subscription_id: subscription_ids}) invoices.sum { |invoice| invoice.fees.charge.sum(:amount_cents) } end diff --git a/spec/services/lifetime_usages/calculate_service_spec.rb b/spec/services/lifetime_usages/calculate_service_spec.rb index 1de700c247d..c4d23ca0c77 100644 --- a/spec/services/lifetime_usages/calculate_service_spec.rb +++ b/spec/services/lifetime_usages/calculate_service_spec.rb @@ -5,17 +5,18 @@ RSpec.describe LifetimeUsages::CalculateService, type: :service do subject(:service) { described_class.new(lifetime_usage: lifetime_usage) } - let(:lifetime_usage) { create(:lifetime_usage, subscription:, recalculate_current_usage:, recalculate_invoiced_usage:) } + let(:lifetime_usage) { create(:lifetime_usage, organization:, subscription:, recalculate_current_usage:, recalculate_invoiced_usage:) } let(:recalculate_current_usage) { false } let(:recalculate_invoiced_usage) { false } - let(:subscription) { create(:subscription, customer_id: customer.id) } - let(:organization) { subscription.organization } + let(:subscription) { create(:subscription, customer_id: customer.id, subscription_at:) } + let(:organization) { customer.organization } let(:customer) { create(:customer) } - let(:invoice_subscription) { create(:invoice_subscription, invoice: invoice, subscription: subscription) } + let(:invoice_subscription) { create(:invoice_subscription, invoice:, subscription:) } let(:billable_metric) { create(:billable_metric, aggregation_type: 'count_agg') } let(:charge) { create(:standard_charge, plan: subscription.plan, billable_metric:, properties: {amount: '10'}) } let(:timestamp) { Time.current } + let(:subscription_at) { timestamp - 6.months } let(:fees) do create_list( :charge_fee, @@ -58,7 +59,7 @@ end context "with draft invoice" do - let(:invoice) { create(:invoice, :draft) } + let(:invoice) { create(:invoice, :draft, organization:) } before do invoice @@ -68,12 +69,43 @@ it "calculates the invoiced_usage as zero" do result = service.call - expect(result.lifetime_usage.invoiced_usage_amount_cents).to be_zero + expect(result.lifetime_usage.invoiced_usage_amount_cents).to eq(200) + expect(lifetime_usage.reload.invoiced_usage_amount_cents).to eq(200) + expect(lifetime_usage.recalculate_invoiced_usage).to be false end end context "with finalized invoice" do - let(:invoice) { create(:invoice, :finalized) } + let(:invoice) { create(:invoice, :finalized, organization:) } + + before do + invoice + invoice_subscription + fees + end + + it "calculates the invoiced_usage_amount_cents correctly" do + result = service.call + expect(result.lifetime_usage.invoiced_usage_amount_cents).to eq(200) + expect(lifetime_usage.reload.invoiced_usage_amount_cents).to eq(200) + expect(lifetime_usage.recalculate_invoiced_usage).to be false + end + end + + context "with invoices from previous subscription" do + let(:subscription) do + create( + :subscription, + customer_id: customer.id, + subscription_at:, + previous_subscription:, + external_id: previous_subscription.external_id + ) + end + + let(:invoice_subscription) { create(:invoice_subscription, invoice:, subscription: previous_subscription) } + let(:previous_subscription) { create(:subscription, :terminated, customer_id: customer.id, subscription_at:) } + let(:invoice) { create(:invoice, :finalized, organization:) } before do invoice