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 = get_subscription_data
|
||||||
subscriptions = filter_to_subscriptions_products(subscriptions, product_ids)
|
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
|
# get number of subscribers
|
||||||
SiteSetting.discourse_subscriptions_campaign_subscribers = subscriptions&.length.to_i
|
SiteSetting.discourse_subscriptions_campaign_subscribers = subscriptions&.length.to_i
|
||||||
|
|
||||||
|
@ -144,6 +150,50 @@ module DiscourseSubscriptions
|
||||||
plan = ::Stripe::Price.create(price_object)
|
plan = ::Stripe::Price.create(price_object)
|
||||||
end
|
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
|
def get_subscription_data
|
||||||
subscriptions = []
|
subscriptions = []
|
||||||
current_set = {
|
current_set = {
|
||||||
|
|
|
@ -5,6 +5,7 @@ require 'rails_helper'
|
||||||
describe DiscourseSubscriptions::Campaign do
|
describe DiscourseSubscriptions::Campaign do
|
||||||
describe 'campaign data is refreshed' do
|
describe 'campaign data is refreshed' do
|
||||||
let (:user) { Fabricate(:user) }
|
let (:user) { Fabricate(:user) }
|
||||||
|
let (:user2) { Fabricate(:user) }
|
||||||
let(:subscription) do
|
let(:subscription) do
|
||||||
{
|
{
|
||||||
id: "sub_1234",
|
id: "sub_1234",
|
||||||
|
@ -23,10 +24,30 @@ describe DiscourseSubscriptions::Campaign do
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
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
|
before do
|
||||||
Fabricate(:product, external_id: "prodct_23456")
|
Fabricate(:product, external_id: "prodct_23456")
|
||||||
Fabricate(:customer, product_id: "prodct_23456", user_id: user.id, customer_id: 'x')
|
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_public_key = "public-key"
|
||||||
SiteSetting.discourse_subscriptions_secret_key = "secret-key"
|
SiteSetting.discourse_subscriptions_secret_key = "secret-key"
|
||||||
end
|
end
|
||||||
|
@ -35,25 +56,28 @@ describe DiscourseSubscriptions::Campaign do
|
||||||
context "for all subscription purchases" do
|
context "for all subscription purchases" do
|
||||||
it "refreshes the campaign data properly" do
|
it "refreshes the campaign data properly" do
|
||||||
::Stripe::Subscription.expects(:list).returns(data: [subscription], has_more: false)
|
::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
|
DiscourseSubscriptions::Campaign.new.refresh_data
|
||||||
|
|
||||||
expect(SiteSetting.discourse_subscriptions_campaign_subscribers).to eq 1
|
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
|
end
|
||||||
|
|
||||||
it "checks if the goal is completed or not" do
|
it "checks if the goal is completed or not" do
|
||||||
SiteSetting.discourse_subscriptions_campaign_goal = 5
|
SiteSetting.discourse_subscriptions_campaign_goal = 5
|
||||||
::Stripe::Subscription.expects(:list).returns(data: [subscription], has_more: false)
|
::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
|
DiscourseSubscriptions::Campaign.new.refresh_data
|
||||||
expect(Discourse.redis.get('subscriptions_goal_met_date')).to be_present
|
expect(Discourse.redis.get('subscriptions_goal_met_date')).to be_present
|
||||||
end
|
end
|
||||||
|
|
||||||
it "checks if goal is < 90% met after being met" do
|
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)
|
Discourse.redis.set('subscriptions_goal_met_date', 10.days.ago)
|
||||||
::Stripe::Subscription.expects(:list).returns(data: [subscription], has_more: false)
|
::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
|
DiscourseSubscriptions::Campaign.new.refresh_data
|
||||||
expect(Discourse.redis.get('subscriptions_goal_met_date')).to be_blank
|
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
|
it "refreshes campaign data with only the campaign product/subscriptions" do
|
||||||
::Stripe::Subscription.expects(:list).returns(data: [subscription, campaign_subscription], has_more: false)
|
::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
|
DiscourseSubscriptions::Campaign.new.refresh_data
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue