73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
# File 'lib/stripe_mock/request_handlers/invoices.rb', line 73
def upcoming_invoice(route, method_url, params, = {})
stripe_account = && [:stripe_account] || Stripe.api_key
route =~ method_url
raise Stripe::InvalidRequestError.new('Missing required param: customer if subscription is not provided', nil, http_status: 400) if params[:customer].nil? && params[:subscription].nil?
raise Stripe::InvalidRequestError.new('When previewing changes to a subscription, you must specify either `subscription` or `subscription_items`', nil, http_status: 400) if !params[:subscription_proration_date].nil? && params[:subscription].nil? && params[:subscription_plan].nil?
raise Stripe::InvalidRequestError.new('Cannot specify proration date without specifying a subscription', nil, http_status: 400) if !params[:subscription_proration_date].nil? && params[:subscription].nil?
customer = customers[stripe_account][params[:customer]]
assert_existence :customer, params[:customer], customer
raise Stripe::InvalidRequestError.new("No upcoming invoices for customer: #{customer[:id]}", nil, http_status: 404) if customer[:subscriptions][:data].length == 0
subscription =
if params[:subscription]
customer[:subscriptions][:data].select{|s|s[:id] == params[:subscription]}.first
else
customer[:subscriptions][:data].min_by { |sub| sub[:current_period_end] }
end
if params[:subscription_proration_date] && !((subscription[:current_period_start]..subscription[:current_period_end]) === params[:subscription_proration_date])
raise Stripe::InvalidRequestError.new('Cannot specify proration date outside of current subscription period', nil, http_status: 400)
end
prorating = false
subscription_proration_date = nil
subscription_plan_id = params[:subscription_plan] || subscription[:plan][:id]
subscription_quantity = params[:subscription_quantity] || subscription[:quantity]
if subscription_plan_id != subscription[:plan][:id] || subscription_quantity != subscription[:quantity]
prorating = true
invoice_date = Time.now.to_i
subscription_plan = assert_existence :plan, subscription_plan_id, plans[subscription_plan_id.to_s]
preview_subscription = Data.mock_subscription
preview_subscription = resolve_subscription_changes(preview_subscription, [subscription_plan], customer, { trial_end: params[:subscription_trial_end] })
preview_subscription[:id] = subscription[:id]
preview_subscription[:quantity] = subscription_quantity
subscription_proration_date = params[:subscription_proration_date] || Time.now
else
preview_subscription = subscription
invoice_date = subscription[:current_period_end]
end
invoice_lines = []
if prorating
unused_amount = (
subscription[:plan][:amount].to_f *
subscription[:quantity] *
(subscription[:current_period_end] - subscription_proration_date.to_i) / (subscription[:current_period_end] - subscription[:current_period_start])
).ceil
invoice_lines << Data.mock_line_item(
id: new_id('ii'),
amount: -unused_amount,
description: 'Unused time',
plan: subscription[:plan],
period: {
start: subscription_proration_date.to_i,
end: subscription[:current_period_end]
},
quantity: subscription[:quantity],
proration: true
)
preview_plan = assert_existence :plan, params[:subscription_plan], plans[params[:subscription_plan]]
if preview_plan[:interval] == subscription[:plan][:interval] && preview_plan[:interval_count] == subscription[:plan][:interval_count] && params[:subscription_trial_end].nil?
remaining_amount = preview_plan[:amount] * subscription_quantity * (subscription[:current_period_end] - subscription_proration_date.to_i) / (subscription[:current_period_end] - subscription[:current_period_start])
invoice_lines << Data.mock_line_item(
id: new_id('ii'),
amount: remaining_amount,
description: 'Remaining time',
plan: preview_plan,
period: {
start: subscription_proration_date.to_i,
end: subscription[:current_period_end]
},
quantity: subscription_quantity,
proration: true
)
end
end
subscription_line = get_mock_subscription_line_item(preview_subscription)
invoice_lines << subscription_line
Data.mock_invoice(invoice_lines,
id: new_id('in'),
customer: customer[:id],
discount: customer[:discount],
created: invoice_date,
starting_balance: customer[:account_balance],
subscription: preview_subscription[:id],
period_start: prorating ? invoice_date : preview_subscription[:current_period_start],
period_end: prorating ? invoice_date : preview_subscription[:current_period_end],
next_payment_attempt: preview_subscription[:current_period_end] + 3600 )
end
|