FIX: Include one-time purchases in campaign total (#95)
* FIX: Include one-time purchases in campaign total On the subscription banner that shows on the top of the forum it shows the total amount raised toward a goal. But the amount shown was not including one-time purchases. It was only showing subscriptions. This change updates the sync with stripe logic so that it also includes one-time purchases. See: https://meta.discourse.org/t/-/209591 * rubocop: remove extra blank line
This commit is contained in:
parent
4f2af3b01a
commit
c6c5ed2ed3
|
@ -21,6 +21,12 @@ module DiscourseSubscriptions
|
|||
subscriptions = get_subscription_data
|
||||
subscriptions = filter_to_subscriptions_products(subscriptions, product_ids)
|
||||
|
||||
# Fetch product purchases
|
||||
one_time_payments = get_one_time_payments(product_ids)
|
||||
one_time_payments.each do |c|
|
||||
amount += c[:price].to_f / 100.00
|
||||
end
|
||||
|
||||
# get number of subscribers
|
||||
SiteSetting.discourse_subscriptions_campaign_subscribers = subscriptions&.length.to_i
|
||||
|
||||
|
@ -144,6 +150,50 @@ module DiscourseSubscriptions
|
|||
plan = ::Stripe::Price.create(price_object)
|
||||
end
|
||||
|
||||
def get_one_time_payments(product_ids)
|
||||
one_time_payments = []
|
||||
current_set = {
|
||||
has_more: true,
|
||||
last_record: nil
|
||||
}
|
||||
|
||||
if product_ids.present?
|
||||
# lots of matching because the Stripe API doesn't make it easy to match products => payments except from invoices
|
||||
until current_set[:has_more] == false
|
||||
all_invoices = ::Stripe::Invoice.list(
|
||||
limit: 100,
|
||||
starting_after: current_set[:last_record]
|
||||
)
|
||||
|
||||
current_set[:last_record] = all_invoices[:data].last[:id] if all_invoices[:data].present?
|
||||
current_set[:has_more] = all_invoices[:has_more]
|
||||
|
||||
all_invoices[:data].each do |invoice|
|
||||
customer_id = invoice[:customer]
|
||||
line_item = invoice[:lines][:data][0] if invoice[:lines] && invoice[:lines][:data] # Discourse only makes single-line item charges
|
||||
# check if non-subscription and that the plan is active
|
||||
if line_item[:plan] == nil &&
|
||||
line_item[:price] &&
|
||||
line_item[:price][:recurring] == nil &&
|
||||
line_item[:price][:active] == true
|
||||
|
||||
product_id = line_item[:price][:product]
|
||||
if product_ids.include? product_id
|
||||
line_data = {
|
||||
customer_id: customer_id,
|
||||
product_id: product_id,
|
||||
price: line_item[:price][:unit_amount],
|
||||
}
|
||||
one_time_payments << line_data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
one_time_payments
|
||||
end
|
||||
|
||||
def get_subscription_data
|
||||
subscriptions = []
|
||||
current_set = {
|
||||
|
|
|
@ -5,6 +5,7 @@ require 'rails_helper'
|
|||
describe DiscourseSubscriptions::Campaign do
|
||||
describe 'campaign data is refreshed' do
|
||||
let (:user) { Fabricate(:user) }
|
||||
let (:user2) { Fabricate(:user) }
|
||||
let(:subscription) do
|
||||
{
|
||||
id: "sub_1234",
|
||||
|
@ -23,10 +24,30 @@ describe DiscourseSubscriptions::Campaign do
|
|||
}
|
||||
}
|
||||
end
|
||||
let(:invoice) do
|
||||
{
|
||||
id: "in_1234",
|
||||
lines: {
|
||||
data: [
|
||||
{
|
||||
plan: nil,
|
||||
price: {
|
||||
product: "prodct_65432",
|
||||
active: true,
|
||||
unit_amount: 1000,
|
||||
recurring: nil,
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
Fabricate(:product, external_id: "prodct_23456")
|
||||
Fabricate(:customer, product_id: "prodct_23456", user_id: user.id, customer_id: 'x')
|
||||
Fabricate(:product, external_id: "prodct_65432")
|
||||
Fabricate(:customer, product_id: "prodct_65432", user_id: user2.id, customer_id: 'y')
|
||||
SiteSetting.discourse_subscriptions_public_key = "public-key"
|
||||
SiteSetting.discourse_subscriptions_secret_key = "secret-key"
|
||||
end
|
||||
|
@ -35,25 +56,28 @@ describe DiscourseSubscriptions::Campaign do
|
|||
context "for all subscription purchases" do
|
||||
it "refreshes the campaign data properly" do
|
||||
::Stripe::Subscription.expects(:list).returns(data: [subscription], has_more: false)
|
||||
::Stripe::Invoice.expects(:list).returns(data: [invoice], has_more: false)
|
||||
|
||||
DiscourseSubscriptions::Campaign.new.refresh_data
|
||||
|
||||
expect(SiteSetting.discourse_subscriptions_campaign_subscribers).to eq 1
|
||||
expect(SiteSetting.discourse_subscriptions_campaign_amount_raised).to eq 10.00
|
||||
expect(SiteSetting.discourse_subscriptions_campaign_amount_raised).to eq 20.00
|
||||
end
|
||||
|
||||
it "checks if the goal is completed or not" do
|
||||
SiteSetting.discourse_subscriptions_campaign_goal = 5
|
||||
::Stripe::Subscription.expects(:list).returns(data: [subscription], has_more: false)
|
||||
::Stripe::Invoice.expects(:list).returns(data: [invoice], has_more: false)
|
||||
|
||||
DiscourseSubscriptions::Campaign.new.refresh_data
|
||||
expect(Discourse.redis.get('subscriptions_goal_met_date')).to be_present
|
||||
end
|
||||
|
||||
it "checks if goal is < 90% met after being met" do
|
||||
SiteSetting.discourse_subscriptions_campaign_goal = 15
|
||||
SiteSetting.discourse_subscriptions_campaign_goal = 25
|
||||
Discourse.redis.set('subscriptions_goal_met_date', 10.days.ago)
|
||||
::Stripe::Subscription.expects(:list).returns(data: [subscription], has_more: false)
|
||||
::Stripe::Invoice.expects(:list).returns(data: [invoice], has_more: false)
|
||||
|
||||
DiscourseSubscriptions::Campaign.new.refresh_data
|
||||
expect(Discourse.redis.get('subscriptions_goal_met_date')).to be_blank
|
||||
|
@ -89,6 +113,7 @@ describe DiscourseSubscriptions::Campaign do
|
|||
|
||||
it "refreshes campaign data with only the campaign product/subscriptions" do
|
||||
::Stripe::Subscription.expects(:list).returns(data: [subscription, campaign_subscription], has_more: false)
|
||||
::Stripe::Invoice.expects(:list).returns(data: [invoice], has_more: false)
|
||||
|
||||
DiscourseSubscriptions::Campaign.new.refresh_data
|
||||
|
||||
|
|
Loading…
Reference in New Issue