111 lines
3.4 KiB
Ruby
111 lines
3.4 KiB
Ruby
class Subscription < ApplicationRecord
|
|
include Recentable
|
|
belongs_to :employer
|
|
|
|
belongs_to :series_successor, class_name: "Subscription", foreign_key: :series_successor_id, optional: true, inverse_of: :series_predecessor
|
|
has_one :series_predecessor, -> { readonly }, class_name: "Subscription", foreign_key: :series_successor_id, inverse_of: :series_successor, dependent: :nullify
|
|
|
|
validates :name, length: { in: 2..255, allow_nil: true }
|
|
validates :autorenew_duration, numericality: { greater_than: 0 }
|
|
validates :starts_at, presence: true
|
|
validate :ends_at_after_starts_at
|
|
validate :ends_at_before_successor_starts
|
|
validate :starts_at_after_predecessor_ends
|
|
validate :autorenew_voided_at_after_starts_at
|
|
validate :terminated_at_after_starts_at
|
|
validate :autorenew_deadline_after_starts_at_and_before_ends_at
|
|
validates :billing_frequency, presence: true
|
|
|
|
def ends_at_after_starts_at
|
|
return if ends_at.blank? || starts_at.blank?
|
|
|
|
if ends_at < starts_at
|
|
errors.add(:ends_at, "must be after the start date")
|
|
end
|
|
end
|
|
|
|
def ends_at_before_successor_starts
|
|
return if series_successor.blank?
|
|
|
|
if ends_at.blank?
|
|
errors.add(:ends_at, "is required for renewed records")
|
|
return
|
|
end
|
|
|
|
if ends_at >= series_successor.starts_at
|
|
errors.add(:ends_at, "must be before its renewal's start date")
|
|
end
|
|
end
|
|
|
|
def starts_at_after_predecessor_ends
|
|
return if series_predecessor.blank?
|
|
|
|
if starts_at.blank?
|
|
errors.add(:starts_at, "is required for records with predecessors")
|
|
return
|
|
end
|
|
|
|
if starts_at <= series_predecessor.ends_at
|
|
errors.add(:starts_at, "must be after its predecessor's end date")
|
|
end
|
|
end
|
|
|
|
# Either percentage or flat fare discount type must be set if product is in travel vertical
|
|
def discount_type_set
|
|
# If product not yet set, can't assume discount type not being set is an error
|
|
return if !product
|
|
|
|
if has_percentage_discount_type.blank? && has_flat_fare_discount_type.blank?
|
|
errors.add(:has_percentage_discount_type, "- At least one of has_percentage_discount_type and has_flat_fare_discount_type must be true")
|
|
end
|
|
end
|
|
|
|
# HACK: this is a temporary fix to work around the lack of atomic updates
|
|
# for subscriptions and cycles.
|
|
# TODO: https://concertiv.atlassian.net/browse/ENG-266 - fix by using Form Objects
|
|
def sync_effective_at
|
|
return if self.cycles.empty?
|
|
|
|
if self.cycles.length == 1
|
|
self.cycles.first.effective_at = self.starts_at
|
|
end
|
|
end
|
|
|
|
def terminated_at_after_starts_at
|
|
return if terminated_at.blank? || starts_at.blank?
|
|
|
|
if terminated_at < starts_at
|
|
errors.add(:terminated_at, "must be after the start date")
|
|
end
|
|
end
|
|
|
|
def autorenew_voided_at_after_starts_at
|
|
return if !is_autorenew
|
|
return if autorenew_voided_at.blank? || starts_at.blank?
|
|
|
|
if autorenew_voided_at < starts_at
|
|
errors.add(:autorenew_voided_at, "must be after the start date")
|
|
end
|
|
end
|
|
|
|
def autorenew_deadline_after_starts_at_and_before_ends_at
|
|
return if !is_autorenew
|
|
|
|
if autorenew_deadline.blank?
|
|
errors.add(:autorenew_deadline, "must be a valid date")
|
|
|
|
return
|
|
end
|
|
|
|
if !starts_at.blank? && autorenew_deadline < starts_at
|
|
errors.add(:autorenew_deadline, "must be after the start date")
|
|
end
|
|
|
|
if !ends_at.blank? && autorenew_deadline > ends_at
|
|
errors.add(:autorenew_deadline, "must be before the end date")
|
|
end
|
|
end
|
|
|
|
|
|
end
|