1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-11-29 10:24:20 +01:00
fab-manager/app/models/subscription.rb

226 lines
6.6 KiB
Ruby
Raw Normal View History

2019-09-10 11:46:14 +02:00
# frozen_string_literal: true
# Subscription is an active or archived subscription of an User to a Plan
2020-03-25 10:16:47 +01:00
class Subscription < ApplicationRecord
2016-03-23 18:39:41 +01:00
include NotifyWith::NotificationAttachedObject
belongs_to :plan
belongs_to :statistic_profile
2016-03-23 18:39:41 +01:00
has_one :payment_schedule, as: :scheduled, dependent: :destroy
2016-03-23 18:39:41 +01:00
has_many :invoices, as: :invoiced, dependent: :destroy
has_many :offer_days, dependent: :destroy
validates_presence_of :plan_id
2016-04-07 12:28:25 +02:00
validates_with SubscriptionGroupValidator
2016-03-23 18:39:41 +01:00
# creation
2018-12-10 17:20:23 +01:00
after_save :notify_member_subscribed_plan
after_save :notify_admin_subscribed_plan
2016-03-23 18:39:41 +01:00
after_save :notify_partner_subscribed_plan, if: :of_partner_plan?
2019-05-29 12:01:24 +02:00
# @param invoice if true then only the subscription is payed, without reservation
# if false then the subscription is payed with reservation
2020-12-02 14:28:41 +01:00
# @param payment_method is only used for schedules
def save_with_payment(operator_profile_id, invoice: true, coupon_code: nil, payment_intent_id: nil, schedule: nil, payment_method: nil)
return false unless valid?
2018-12-11 15:07:21 +01:00
set_expiration_date
return false unless save
2018-12-10 17:20:23 +01:00
UsersCredits::Manager.new(user: user).reset_credits
if invoice
@wallet_amount_debit = get_wallet_amount_debit
# debit wallet
wallet_transaction = debit_user_wallet
2020-11-10 17:02:21 +01:00
payment = if schedule
generate_schedule(operator_profile_id, payment_method, coupon_code)
2020-11-10 17:02:21 +01:00
else
generate_invoice(operator_profile_id, coupon_code, payment_intent_id)
end
if wallet_transaction
2020-11-10 17:02:21 +01:00
payment.wallet_amount = @wallet_amount_debit
payment.wallet_transaction_id = wallet_transaction.id
end
2020-11-10 17:02:21 +01:00
payment.save
end
true
end
def generate_schedule(operator_profile_id, payment_method, coupon_code = nil)
2020-11-10 17:02:21 +01:00
operator = InvoicingProfile.find(operator_profile_id)&.user
coupon = Coupon.find_by(code: coupon_code) unless coupon_code.nil?
PaymentScheduleService.new.create(
self,
plan.amount,
coupon: coupon,
operator: operator,
payment_method: payment_method,
user: user
)
2020-11-10 17:02:21 +01:00
end
def generate_invoice(operator_profile_id, coupon_code = nil, payment_intent_id = nil)
2016-08-11 18:17:28 +02:00
coupon_id = nil
total = plan.amount
operator = InvoicingProfile.find(operator_profile_id)&.user
method = operator&.admin? || (operator&.manager? && operator != user) ? nil : 'stripe'
2016-08-11 18:17:28 +02:00
unless coupon_code.nil?
@coupon = Coupon.find_by(code: coupon_code)
unless @coupon.nil?
total = CouponService.new.apply(plan.amount, @coupon, user.id)
coupon_id = @coupon.id
end
2016-08-11 18:17:28 +02:00
end
2019-06-11 16:56:11 +02:00
invoice = Invoice.new(
invoiced_id: id,
invoiced_type: 'Subscription',
invoicing_profile: user.invoicing_profile,
statistic_profile: user.statistic_profile,
total: total,
coupon_id: coupon_id,
operator_profile_id: operator_profile_id,
stp_payment_intent_id: payment_intent_id,
payment_method: method
2019-06-11 16:56:11 +02:00
)
invoice.invoice_items.push InvoiceItem.new(
amount: plan.amount,
description: plan.name,
subscription_id: id
)
2016-03-23 18:39:41 +01:00
invoice
end
2019-09-09 17:37:54 +02:00
def generate_and_save_invoice(operator_profile_id)
generate_invoice(operator_profile_id).save
2016-03-23 18:39:41 +01:00
end
def cancel
update_columns(canceled_at: DateTime.current)
2016-03-23 18:39:41 +01:00
end
def expire(time)
if !expired?
2018-12-10 17:20:23 +01:00
update_columns(expiration_date: time, canceled_at: time)
2016-03-23 18:39:41 +01:00
notify_admin_subscription_canceled
notify_member_subscription_canceled
true
else
false
end
end
def expired?
expired_at <= DateTime.current
2016-03-23 18:39:41 +01:00
end
def expired_at
last_offered = offer_days.order(:end_at).last
return last_offered.end_at if last_offered
expiration_date
end
def free_extend(expiration, operator_profile_id)
return false if expiration <= expired_at
od = offer_days.create(start_at: expired_at, end_at: expiration)
2019-06-11 16:56:11 +02:00
invoice = Invoice.new(
invoiced_id: od.id,
invoiced_type: 'OfferDay',
invoicing_profile: user.invoicing_profile,
statistic_profile: user.statistic_profile,
operator_profile_id: operator_profile_id,
2019-06-11 16:56:11 +02:00
total: 0
)
invoice.invoice_items.push InvoiceItem.new(amount: 0, description: plan.name, subscription_id: id)
invoice.save
2016-03-23 18:39:41 +01:00
if save
notify_subscription_extended(true)
2016-03-23 18:39:41 +01:00
return true
end
false
2016-03-23 18:39:41 +01:00
end
def user
statistic_profile.user
end
2016-03-23 18:39:41 +01:00
private
2016-03-23 18:39:41 +01:00
def notify_member_subscribed_plan
NotificationCenter.call type: 'notify_member_subscribed_plan',
receiver: user,
attached_object: self
end
def notify_admin_subscribed_plan
NotificationCenter.call type: 'notify_admin_subscribed_plan',
receiver: User.admins,
attached_object: self
end
def notify_admin_subscription_canceled
NotificationCenter.call type: 'notify_admin_subscription_canceled',
2020-04-29 15:34:30 +02:00
receiver: User.admins_and_managers,
2016-03-23 18:39:41 +01:00
attached_object: self
end
def notify_member_subscription_canceled
NotificationCenter.call type: 'notify_member_subscription_canceled',
receiver: user,
attached_object: self
end
def notify_partner_subscribed_plan
NotificationCenter.call type: 'notify_partner_subscribed_plan',
receiver: plan.partners,
attached_object: self
end
def notify_subscription_extended(free_days)
meta_data = {}
meta_data[:free_days] = true if free_days
NotificationCenter.call type: :notify_member_subscription_extended,
receiver: user,
attached_object: self,
meta_data: meta_data
2016-03-23 18:39:41 +01:00
NotificationCenter.call type: :notify_admin_subscription_extended,
2020-04-29 15:34:30 +02:00
receiver: User.admins_and_managers,
attached_object: self,
meta_data: meta_data
2016-03-23 18:39:41 +01:00
end
2018-12-11 15:07:21 +01:00
def set_expiration_date
start_at = DateTime.current.in_time_zone
2018-12-11 15:07:21 +01:00
self.expiration_date = start_at + plan.duration
end
2016-03-23 18:39:41 +01:00
def of_partner_plan?
plan.is_a?(PartnerPlan)
end
2016-07-08 17:24:51 +02:00
def get_wallet_amount_debit
total = plan.amount
total = CouponService.new.apply(total, @coupon, user.id) if @coupon
2016-07-08 17:24:51 +02:00
wallet_amount = (user.wallet.amount * 100).to_i
wallet_amount >= total ? total : wallet_amount
2016-07-08 17:24:51 +02:00
end
def debit_user_wallet
return if !@wallet_amount_debit.present? || @wallet_amount_debit.zero?
amount = @wallet_amount_debit / 100.0
WalletService.new(user: user, wallet: user.wallet).debit(amount, self)
2016-07-08 17:24:51 +02:00
end
2016-03-23 18:39:41 +01:00
end