# 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 # 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 def school_on_school? teacher.teacher.school && student.school && (teacher.teacher.school.id == student.school.id) end def bill_monthly(force = false) if school_on_school? success = true 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