diff --git a/lib/stripe-force/translate/order.rb b/lib/stripe-force/translate/order.rb index a9acd620aa..815ff81bda 100644 --- a/lib/stripe-force/translate/order.rb +++ b/lib/stripe-force/translate/order.rb @@ -244,6 +244,7 @@ def generate_phases_for_initial_order(sf_order:, invoice_items:, subscription_it # add special metadata to line items as well invoice_items_for_prorations.each do |invoice_item| invoice_item[:metadata][StripeForce::Translate::Metadata.metadata_key(@user, MetadataKeys::BACKEND_PRORATION)] = true + invoice_item[:period][:end][:type] = 'phase_end' end backend_proration_term = subscription_term_from_sales_force % billing_frequency diff --git a/test/integration/amendments/test_backend_prorated_amendments.rb b/test/integration/amendments/test_backend_prorated_amendments.rb index 40a913a657..bdb7cb8922 100644 --- a/test/integration/amendments/test_backend_prorated_amendments.rb +++ b/test/integration/amendments/test_backend_prorated_amendments.rb @@ -9,10 +9,13 @@ class Critic::BackendProratedAmendmentTranslation < Critic::OrderAmendmentFuncti end it 'handles an initial order with a backend proration' do + @user.enable_feature FeatureFlags::TEST_CLOCKS, update: true + backend_prorated_term = 6 contract_term = TEST_DEFAULT_CONTRACT_TERM + backend_prorated_term initial_start_date = now_time - end_date = initial_start_date + contract_term.months + initial_end_date = initial_start_date + contract_term.months + backend_proration_start = initial_start_date + TEST_DEFAULT_CONTRACT_TERM.months sf_product_id, sf_pricebook_entry_id = salesforce_recurring_product_with_price( additional_product_fields: { @@ -46,11 +49,11 @@ class Critic::BackendProratedAmendmentTranslation < Critic::OrderAmendmentFuncti # first phase should start now and end at the end of the billing cycle assert_equal(0, first_phase.start_date - initial_start_date.to_i) - assert_equal(0, first_phase.end_date - (initial_start_date + TEST_DEFAULT_CONTRACT_TERM.months).to_i) + assert_equal(0, first_phase.end_date - backend_proration_start.to_i) # second phase should start at the end of the billing cycle and end at the contract term - assert_equal(0, second_phase.start_date - (initial_start_date + TEST_DEFAULT_CONTRACT_TERM.months).to_i) - assert_equal(0, second_phase.end_date - end_date.to_i) + assert_equal(0, second_phase.start_date - backend_proration_start.to_i) + assert_equal(0, second_phase.end_date - initial_end_date.to_i) # first phase should have one item with no quantity, since it is a metered product assert_equal(1, first_phase.items.count) @@ -74,6 +77,35 @@ class Critic::BackendProratedAmendmentTranslation < Critic::OrderAmendmentFuncti assert_equal(TEST_DEFAULT_PRICE / 2, prorated_price.unit_amount_decimal.to_i) assert_equal("one_time", prorated_price.type) assert_equal("true", prorated_price.metadata[StripeForce::Translate::Metadata.metadata_key(@user, MetadataKeys::PRORATION)]) + + # now, let's advance the clock + sf_account = sf_get(sf_order['AccountId']) + stripe_customer_id = sf_account[prefixed_stripe_field(GENERIC_STRIPE_ID)] + stripe_customer = stripe_get(stripe_customer_id) + refute_nil(stripe_customer.test_clock) + + test_clock = advance_test_clock(stripe_customer, (backend_proration_start + 1.day).to_i) + + # simulate sending the webhook + events = Stripe::Event.list({ + type: 'invoiceitem.created', + }, @user.stripe_credentials) + + invoice_events = events.data.select do |event| + event_object = event.data.object + event_object.test_clock == test_clock.id && event.request.id.nil? + end + + assert_equal(1, invoice_events.count) + invoice_event = invoice_events.first + + invoice_period_start = invoice_event.data.object.period.start + invoice_period_end = invoice_event.data.object.period.end + + # sanity check the usage period of this proration invoice + # should be from the first phase end to contract end + assert_equal(backend_proration_start.to_i, invoice_period_start) + assert_equal(initial_end_date.to_i, invoice_period_end) end describe 'amendments' do diff --git a/test/integration/amendments/test_proration_amendments.rb b/test/integration/amendments/test_proration_amendments.rb index 60c0d225e5..b79e884e72 100644 --- a/test/integration/amendments/test_proration_amendments.rb +++ b/test/integration/amendments/test_proration_amendments.rb @@ -20,7 +20,7 @@ class Critic::ProratedAmendmentTranslation < Critic::OrderAmendmentFunctionalTes initial_order_end_date = initial_order_start_date + contract_term amendment_term = 18 - amendment_start_date = now_time + (contract_term - amendment_term).months + amendment_start_date = initial_order_start_date + (contract_term - amendment_term).months amendment_end_date = amendment_start_date + amendment_term.months # normalize the amendment_end_date so test doesn't fail EOM @@ -60,7 +60,6 @@ class Critic::ProratedAmendmentTranslation < Critic::OrderAmendmentFunctionalTes subscription_schedule = Stripe::SubscriptionSchedule.retrieve(stripe_id, @user.stripe_credentials) assert_equal(2, subscription_schedule.phases.count) - first_phase = T.must(subscription_schedule.phases.first) second_phase = T.must(subscription_schedule.phases[1]) @@ -146,6 +145,16 @@ class Critic::ProratedAmendmentTranslation < Critic::OrderAmendmentFunctionalTes assert_equal(1, invoice_events.count) invoice_event = invoice_events.first + invoice_period_start = invoice_event.data.object.period.start + invoice_period_end = invoice_event.data.object.period.end + + # sanity check the usage period of this proration invoice + # should be from the amendment start to the next billing cycle date + assert_equal(amendment_start_date.to_i, invoice_period_start) + # the proration period end should align with the next billing cycle + # since this is billed 'Annually', add a year to the initial order start date to get the start of the next billing cycle + assert_equal((initial_order_start_date + 1.year).to_i, invoice_period_end) + invoice = T.must(StripeForce::ProrationAutoBill.create_invoice_from_invoice_item_event(@user, invoice_event)) assert_equal(1, invoice.lines.count) @@ -153,13 +162,6 @@ class Critic::ProratedAmendmentTranslation < Critic::OrderAmendmentFunctionalTes assert_equal(2, invoice_line.quantity) assert_equal(60_00 * 2, invoice.total) assert_equal("true", invoice.metadata[StripeForce::Translate::Metadata.metadata_key(@user, MetadataKeys::PRORATION_INVOICE)]) - - # sanity check the usage period of this proration invoice - # should be from the amendment start to the next billing cycle date - assert_equal(amendment_start_date.to_i, invoice.period_start) - # the proration period end should align with the next billing cycle - # since this is billed 'Annually', add a year to the initial order start date to get the start of the next billing cycle - assert_equal((initial_order_start_date + 1.year).to_i, invoice.period_end.to_i) end # NOTE this was the first test written and has more extensive edge cases than other amendment tests