jam-cloud/ruby/lib/jam_ruby/models/lesson_package_purchase.rb

173 lines
5.3 KiB
Ruby

# represents the purchase of a LessonPackage
module JamRuby
class LessonPackagePurchase < ActiveRecord::Base
@@log = Logging.logger[LessonPackagePurchase]
delegate :sent_billing_notices, :last_billing_attempt_at, :billing_attempts, :billing_should_retry, :billed, :billed_at, :billing_error_detail, :billing_error_reason, :is_card_declined?, :is_card_expired?, :last_billed_at_date, :sent_billing_notices, to: :lesson_payment_charge
delegate :test_drive_count, to: :lesson_package_type
# who purchased the lesson package?
belongs_to :user, class_name: "JamRuby::User", :foreign_key => "user_id", inverse_of: :lesson_purchases
belongs_to :lesson_package_type, class_name: "JamRuby::LessonPackageType"
belongs_to :teacher, class_name: "JamRuby::User"
belongs_to :lesson_booking, class_name: "JamRuby::LessonBooking"
belongs_to :lesson_payment_charge, class_name: "JamRuby::LessonPaymentCharge", foreign_key: :charge_id
has_one :teacher_distribution, class_name: "JamRuby::TeacherDistribution"
has_one :sale_line_item, class_name: "JamRuby::SaleLineItem"
validates :user, presence: true
validates :lesson_package_type, presence: true
validates :price, presence: true
validate :validate_test_drive, on: :create
after_create :add_test_drives
after_create :create_charge
def validate_test_drive
if user
if lesson_package_type.is_test_drive? && !user.can_buy_test_drive?
errors.add(:user, "can not buy test drive right now because you have already purchased it within the last year")
end
end
end
def create_charge
if !school_on_school? && lesson_booking && lesson_booking.is_monthly_payment?
self.lesson_payment_charge = LessonPaymentCharge.new
lesson_payment_charge.user = user
lesson_payment_charge.amount_in_cents = 0
lesson_payment_charge.fee_in_cents = 0
lesson_payment_charge.lesson_package_purchase = self
lesson_payment_charge.save!
end
end
def add_test_drives
if self.lesson_package_type.is_test_drive?
new_test_drives = user.remaining_test_drives + lesson_package_type.test_drive_count
User.where(id: user.id).update_all(remaining_test_drives: new_test_drives)
user.remaining_test_drives = new_test_drives
end
end
def name
lesson_package_type.sale_display
end
def amount_charged
lesson_payment_charge.amount_in_cents / 100.0
end
def self.create(user, lesson_booking, lesson_package_type, year = nil, month = nil)
purchase = LessonPackagePurchase.new
purchase.user = user
purchase.lesson_booking = lesson_booking
purchase.teacher = lesson_booking.teacher if lesson_booking
if year
purchase.year = year
purchase.month = month
purchase.recurring = true
if lesson_booking && lesson_booking.requires_teacher_distribution?(purchase)
purchase.teacher_distribution = TeacherDistribution.create_for_lesson_package_purchase(purchase)
# price should always match the teacher_distribution, if there is one
purchase.price = purchase.teacher_distribution.amount_in_cents / 100
end
else
purchase.recurring = false
end
if lesson_booking
purchase.lesson_package_type = lesson_package_type ? lesson_package_type : lesson_booking.lesson_package_type
purchase.price = lesson_booking.booked_price if purchase.price.nil?
else
purchase.lesson_package_type = lesson_package_type
purchase.price = lesson_package_type.price if purchase.price.nil?
end
purchase.save
purchase
end
def price_in_cents
(price * 100).to_i
end
def description(lesson_booking)
lesson_package_type.description(lesson_booking)
end
def stripe_description(lesson_booking)
description(lesson_booking)
end
def timed_description
"Lessons for the month of #{self.month_name} with #{self.lesson_booking.student.name}"
end
def month_name
if recurring
Date.new(year, month, 1).strftime('%B')
else
'non-monthly paid lesson'
end
end
def student
user
end
# test drive purchase doesn't have a tea
def school_on_school?
if teacher
teacher.teacher.school && student.school && (teacher.teacher.school.id == student.school.id)
else
false
end
end
def bill_monthly(force = false)
if school_on_school?
raise "school-on-school: should not be here"
else
lesson_payment_charge.charge(force)
success = lesson_payment_charge.billed
end
if success
self.sent_notices = true
self.sent_notices_at = Time.now
self.post_processed = true
self.post_processed_at = Time.now
self.save(:validate => false)
end
end
def is_card_declined?
billed == false && billing_error_reason == 'card_declined'
end
def is_card_expired?
billed == false && billing_error_reason == 'card_expired'
end
def last_billed_at_date
last_billing_attempt_at.strftime("%B %d, %Y") if last_billing_attempt_at
end
def update_payment_url
APP_CONFIG.external_root_url + "/client#/jamclass/update-payment"
end
end
end