Files
danbooru/app/models/user_upgrade.rb
evazion 449fd6c49c upgrades: factor out Stripe integration.
Factor out the Stripe code from the UserUpgrade class. Introduce a new
PaymentTransaction abstract class that represents a payment with some
payment processor, and a PaymentTransaction::Stripe class that
implements transactions with Stripe.

Note that we can't completely eliminate Stripe even though we no longer
accept payments with it because we still need to be able to look up old
payments in Stripe.
2022-05-06 22:52:33 -05:00

168 lines
3.6 KiB
Ruby

# frozen_string_literal: true
class UserUpgrade < ApplicationRecord
belongs_to :recipient, class_name: "User"
belongs_to :purchaser, class_name: "User"
delegate :payment_url, :receipt_url, to: :transaction
enum upgrade_type: {
gold: 0,
platinum: 10,
gold_to_platinum: 20,
}, _suffix: "upgrade"
enum status: {
pending: 0,
processing: 10,
complete: 20,
refunded: 30,
}
scope :gifted, -> { where("recipient_id != purchaser_id") }
scope :self_upgrade, -> { where("recipient_id = purchaser_id") }
def self.enabled?
Danbooru.config.user_upgrades_enabled?
end
def self.gold_price
if Danbooru.config.is_promotion?
1500
else
2000
end
end
def self.platinum_price
2 * gold_price
end
def self.gold_to_platinum_price
platinum_price - gold_price
end
def level
case upgrade_type
when "gold"
User::Levels::GOLD
when "platinum"
User::Levels::PLATINUM
when "gold_to_platinum"
User::Levels::PLATINUM
else
raise NotImplementedError
end
end
def previous_level
case upgrade_type
when "gold"
User::Levels::MEMBER
when "platinum"
User::Levels::MEMBER
when "gold_to_platinum"
User::Levels::GOLD
else
raise NotImplementedError
end
end
def level_string
User.level_string(level)
end
def is_gift?
recipient != purchaser
end
def self.visible(user)
if user.is_owner?
all
else
where(recipient: user).or(where(purchaser: user))
end
end
def self.search(params)
q = search_attributes(params, :id, :created_at, :updated_at, :upgrade_type, :status, :stripe_id, :recipient, :purchaser)
if params[:is_gifted].to_s.truthy?
q = q.gifted
elsif params[:is_gifted].to_s.falsy?
q = q.self_upgrade
end
q.apply_default_order(params)
end
concerning :UpgradeMethods do
def process_upgrade!(payment_status)
recipient.with_lock do
return unless pending? || processing?
if payment_status == "paid"
upgrade_recipient!
dmail_recipient!
dmail_purchaser!
update!(status: :complete)
else
update!(status: :processing)
end
end
end
def upgrade_recipient!
recipient.update!(level: level)
end
def dmail_recipient!
if is_gift?
body = "Congratulations, your account has been upgraded to #{level_string} by <@#{purchaser.name}>. Enjoy!"
else
body = "You are now a #{level_string} user. Thanks for supporting #{Danbooru.config.canonical_app_name}!"
end
title = "You have been upgraded to #{level_string}!"
Dmail.create_automated(to: recipient, title: title, body: body)
end
def dmail_purchaser!
return unless is_gift?
title = "#{recipient.name} has been upgraded to #{level_string}!"
body = "<@#{recipient.name}> is now a #{level_string} user. Thanks for supporting #{Danbooru.config.canonical_app_name}!"
Dmail.create_automated(to: purchaser, title: title, body: body)
end
end
concerning :TransactionMethods do
def create_checkout!(country: "US", allow_promotion_codes: false)
transaction.create!(country: country, allow_promotion_codes: allow_promotion_codes)
end
def refund!(reason: nil)
with_lock do
return if refunded?
transaction.refund!(reason)
recipient.update!(level: previous_level)
update!(status: "refunded")
end
end
def transaction
PaymentTransaction::Stripe.new(self)
end
def has_receipt?
!pending?
end
def has_payment?
!pending?
end
end
end