Class: Ticket

Inherits:
ApplicationRecord show all
Defined in:
app/models/ticket.rb

Overview

This model manage the Happening Ticket for each User

Relations

belongs to Happening belongs to User

Validates

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#by_editorAny

Returns attr_accessor, valorized if action is executed by an editor.

Returns:

  • (Any)

    attr_accessor, valorized if action is executed by an editor



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'app/models/ticket.rb', line 23

class Ticket < ApplicationRecord
  belongs_to :happening, counter_cache: true
  belongs_to :user
  has_many :answers, dependent: :destroy
  delegate :event, :event_id, :max_tickets, :max_tickets_for_user, :reserved?, :saleable?, :start_at, to: :happening, allow_nil: true
  delegate :member?, to: :user, allow_nil: true
  accepts_nested_attributes_for :answers, reject_if: :all_blank
  attr_accessor :by_editor
  after_create  -> { TicketMailer.confirm(self).deliver_later }
  before_destroy -> { TicketMailer.deleted(self).deliver }

  validates :happening, presence: true
  validates :user, presence: true
  with_options unless: :by_editor do
    validates :saleable?, inclusion: [ true ]
    validates :tickets_count, numericality: { only_integer: true, less_than_or_equal_to: :max_tickets }
    validates :tickets_for_user_count,
              numericality: { only_integer: true, less_than_or_equal_to: :max_tickets_for_user }
    validates :missing_answers, absence: true
    validates :member?, presence: true if :reserved?
    validate  :validate_frequency
  end

  scope :with_user, ->(user) { where user: }

  # check if exists {Event}'s {Ticket} for {User} in a time period
  # @return [Boolean] true if exist a ticket in the time range
  def event_ticket_exist?(period = nil)
    @when = { happenings: { start_at: period } } if period.present?
    event.tickets.where(@when).where(user:).exists?
  end

  # count total of each other happening ticket self included
  # @return [Integer] number of tickets
  def tickets_count
    total = happening.tickets_count
    total += 1 unless persisted?
    total
  end

  # count total of each other happening ticket from {User} self included
  # @return [Integer] number of tickets
  def tickets_for_user_count
    total = happening.tickets.where(user:).count
    total += 1 unless persisted?
    total
  end

  private

  # check {User}'s ticket presence based of {Event#tickets_frequency}
  def validate_frequency
    exist, message = case event.tickets_frequency
    when "single"
                       [ event_ticket_exist?, I18n.t("site.ticket.errors.single") ]
    when "daily"
                       [ event_ticket_exist?(start_at.beginning_of_day..start_at.end_of_day),
                        I18n.t("site.ticket.errors.daily") ]
    when "weekly"
                       [ event_ticket_exist?(start_at.-(7.days)..start_at.+(7.days)),
                        I18n.t("site.ticket.errors.weekly") ]
    when "monthly"
                       [ event_ticket_exist?(start_at.-(30.days)..start_at.+(30.days)),
                        I18n.t("site.ticket.errors.montly") ]
    else
                       return true
    end
    errors.add(:seats, message) if exist
  end

  # check if all mandatory {Question} are present
  def missing_answers
    happening.questions  .mandatory.pluck(:id) - answers.map { |a| a.question_id }
  end
end

#created_atDateTime

Returns when the record was created.

Returns:

  • (DateTime)

    when the record was created



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'app/models/ticket.rb', line 23

class Ticket < ApplicationRecord
  belongs_to :happening, counter_cache: true
  belongs_to :user
  has_many :answers, dependent: :destroy
  delegate :event, :event_id, :max_tickets, :max_tickets_for_user, :reserved?, :saleable?, :start_at, to: :happening, allow_nil: true
  delegate :member?, to: :user, allow_nil: true
  accepts_nested_attributes_for :answers, reject_if: :all_blank
  attr_accessor :by_editor
  after_create  -> { TicketMailer.confirm(self).deliver_later }
  before_destroy -> { TicketMailer.deleted(self).deliver }

  validates :happening, presence: true
  validates :user, presence: true
  with_options unless: :by_editor do
    validates :saleable?, inclusion: [ true ]
    validates :tickets_count, numericality: { only_integer: true, less_than_or_equal_to: :max_tickets }
    validates :tickets_for_user_count,
              numericality: { only_integer: true, less_than_or_equal_to: :max_tickets_for_user }
    validates :missing_answers, absence: true
    validates :member?, presence: true if :reserved?
    validate  :validate_frequency
  end

  scope :with_user, ->(user) { where user: }

  # check if exists {Event}'s {Ticket} for {User} in a time period
  # @return [Boolean] true if exist a ticket in the time range
  def event_ticket_exist?(period = nil)
    @when = { happenings: { start_at: period } } if period.present?
    event.tickets.where(@when).where(user:).exists?
  end

  # count total of each other happening ticket self included
  # @return [Integer] number of tickets
  def tickets_count
    total = happening.tickets_count
    total += 1 unless persisted?
    total
  end

  # count total of each other happening ticket from {User} self included
  # @return [Integer] number of tickets
  def tickets_for_user_count
    total = happening.tickets.where(user:).count
    total += 1 unless persisted?
    total
  end

  private

  # check {User}'s ticket presence based of {Event#tickets_frequency}
  def validate_frequency
    exist, message = case event.tickets_frequency
    when "single"
                       [ event_ticket_exist?, I18n.t("site.ticket.errors.single") ]
    when "daily"
                       [ event_ticket_exist?(start_at.beginning_of_day..start_at.end_of_day),
                        I18n.t("site.ticket.errors.daily") ]
    when "weekly"
                       [ event_ticket_exist?(start_at.-(7.days)..start_at.+(7.days)),
                        I18n.t("site.ticket.errors.weekly") ]
    when "monthly"
                       [ event_ticket_exist?(start_at.-(30.days)..start_at.+(30.days)),
                        I18n.t("site.ticket.errors.montly") ]
    else
                       return true
    end
    errors.add(:seats, message) if exist
  end

  # check if all mandatory {Question} are present
  def missing_answers
    happening.questions  .mandatory.pluck(:id) - answers.map { |a| a.question_id }
  end
end

#happening_idInteger

Returns identifier of related Happening.

Returns:

  • (Integer)

    identifier of related Happening



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'app/models/ticket.rb', line 23

class Ticket < ApplicationRecord
  belongs_to :happening, counter_cache: true
  belongs_to :user
  has_many :answers, dependent: :destroy
  delegate :event, :event_id, :max_tickets, :max_tickets_for_user, :reserved?, :saleable?, :start_at, to: :happening, allow_nil: true
  delegate :member?, to: :user, allow_nil: true
  accepts_nested_attributes_for :answers, reject_if: :all_blank
  attr_accessor :by_editor
  after_create  -> { TicketMailer.confirm(self).deliver_later }
  before_destroy -> { TicketMailer.deleted(self).deliver }

  validates :happening, presence: true
  validates :user, presence: true
  with_options unless: :by_editor do
    validates :saleable?, inclusion: [ true ]
    validates :tickets_count, numericality: { only_integer: true, less_than_or_equal_to: :max_tickets }
    validates :tickets_for_user_count,
              numericality: { only_integer: true, less_than_or_equal_to: :max_tickets_for_user }
    validates :missing_answers, absence: true
    validates :member?, presence: true if :reserved?
    validate  :validate_frequency
  end

  scope :with_user, ->(user) { where user: }

  # check if exists {Event}'s {Ticket} for {User} in a time period
  # @return [Boolean] true if exist a ticket in the time range
  def event_ticket_exist?(period = nil)
    @when = { happenings: { start_at: period } } if period.present?
    event.tickets.where(@when).where(user:).exists?
  end

  # count total of each other happening ticket self included
  # @return [Integer] number of tickets
  def tickets_count
    total = happening.tickets_count
    total += 1 unless persisted?
    total
  end

  # count total of each other happening ticket from {User} self included
  # @return [Integer] number of tickets
  def tickets_for_user_count
    total = happening.tickets.where(user:).count
    total += 1 unless persisted?
    total
  end

  private

  # check {User}'s ticket presence based of {Event#tickets_frequency}
  def validate_frequency
    exist, message = case event.tickets_frequency
    when "single"
                       [ event_ticket_exist?, I18n.t("site.ticket.errors.single") ]
    when "daily"
                       [ event_ticket_exist?(start_at.beginning_of_day..start_at.end_of_day),
                        I18n.t("site.ticket.errors.daily") ]
    when "weekly"
                       [ event_ticket_exist?(start_at.-(7.days)..start_at.+(7.days)),
                        I18n.t("site.ticket.errors.weekly") ]
    when "monthly"
                       [ event_ticket_exist?(start_at.-(30.days)..start_at.+(30.days)),
                        I18n.t("site.ticket.errors.montly") ]
    else
                       return true
    end
    errors.add(:seats, message) if exist
  end

  # check if all mandatory {Question} are present
  def missing_answers
    happening.questions  .mandatory.pluck(:id) - answers.map { |a| a.question_id }
  end
end

#idInteger

Returns unique identifier for Ticket.

Returns:

  • (Integer)

    unique identifier for Ticket



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'app/models/ticket.rb', line 23

class Ticket < ApplicationRecord
  belongs_to :happening, counter_cache: true
  belongs_to :user
  has_many :answers, dependent: :destroy
  delegate :event, :event_id, :max_tickets, :max_tickets_for_user, :reserved?, :saleable?, :start_at, to: :happening, allow_nil: true
  delegate :member?, to: :user, allow_nil: true
  accepts_nested_attributes_for :answers, reject_if: :all_blank
  attr_accessor :by_editor
  after_create  -> { TicketMailer.confirm(self).deliver_later }
  before_destroy -> { TicketMailer.deleted(self).deliver }

  validates :happening, presence: true
  validates :user, presence: true
  with_options unless: :by_editor do
    validates :saleable?, inclusion: [ true ]
    validates :tickets_count, numericality: { only_integer: true, less_than_or_equal_to: :max_tickets }
    validates :tickets_for_user_count,
              numericality: { only_integer: true, less_than_or_equal_to: :max_tickets_for_user }
    validates :missing_answers, absence: true
    validates :member?, presence: true if :reserved?
    validate  :validate_frequency
  end

  scope :with_user, ->(user) { where user: }

  # check if exists {Event}'s {Ticket} for {User} in a time period
  # @return [Boolean] true if exist a ticket in the time range
  def event_ticket_exist?(period = nil)
    @when = { happenings: { start_at: period } } if period.present?
    event.tickets.where(@when).where(user:).exists?
  end

  # count total of each other happening ticket self included
  # @return [Integer] number of tickets
  def tickets_count
    total = happening.tickets_count
    total += 1 unless persisted?
    total
  end

  # count total of each other happening ticket from {User} self included
  # @return [Integer] number of tickets
  def tickets_for_user_count
    total = happening.tickets.where(user:).count
    total += 1 unless persisted?
    total
  end

  private

  # check {User}'s ticket presence based of {Event#tickets_frequency}
  def validate_frequency
    exist, message = case event.tickets_frequency
    when "single"
                       [ event_ticket_exist?, I18n.t("site.ticket.errors.single") ]
    when "daily"
                       [ event_ticket_exist?(start_at.beginning_of_day..start_at.end_of_day),
                        I18n.t("site.ticket.errors.daily") ]
    when "weekly"
                       [ event_ticket_exist?(start_at.-(7.days)..start_at.+(7.days)),
                        I18n.t("site.ticket.errors.weekly") ]
    when "monthly"
                       [ event_ticket_exist?(start_at.-(30.days)..start_at.+(30.days)),
                        I18n.t("site.ticket.errors.montly") ]
    else
                       return true
    end
    errors.add(:seats, message) if exist
  end

  # check if all mandatory {Question} are present
  def missing_answers
    happening.questions  .mandatory.pluck(:id) - answers.map { |a| a.question_id }
  end
end

#updated_atDateTime

Returns when the record was created.

Returns:

  • (DateTime)

    when the record was created



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'app/models/ticket.rb', line 23

class Ticket < ApplicationRecord
  belongs_to :happening, counter_cache: true
  belongs_to :user
  has_many :answers, dependent: :destroy
  delegate :event, :event_id, :max_tickets, :max_tickets_for_user, :reserved?, :saleable?, :start_at, to: :happening, allow_nil: true
  delegate :member?, to: :user, allow_nil: true
  accepts_nested_attributes_for :answers, reject_if: :all_blank
  attr_accessor :by_editor
  after_create  -> { TicketMailer.confirm(self).deliver_later }
  before_destroy -> { TicketMailer.deleted(self).deliver }

  validates :happening, presence: true
  validates :user, presence: true
  with_options unless: :by_editor do
    validates :saleable?, inclusion: [ true ]
    validates :tickets_count, numericality: { only_integer: true, less_than_or_equal_to: :max_tickets }
    validates :tickets_for_user_count,
              numericality: { only_integer: true, less_than_or_equal_to: :max_tickets_for_user }
    validates :missing_answers, absence: true
    validates :member?, presence: true if :reserved?
    validate  :validate_frequency
  end

  scope :with_user, ->(user) { where user: }

  # check if exists {Event}'s {Ticket} for {User} in a time period
  # @return [Boolean] true if exist a ticket in the time range
  def event_ticket_exist?(period = nil)
    @when = { happenings: { start_at: period } } if period.present?
    event.tickets.where(@when).where(user:).exists?
  end

  # count total of each other happening ticket self included
  # @return [Integer] number of tickets
  def tickets_count
    total = happening.tickets_count
    total += 1 unless persisted?
    total
  end

  # count total of each other happening ticket from {User} self included
  # @return [Integer] number of tickets
  def tickets_for_user_count
    total = happening.tickets.where(user:).count
    total += 1 unless persisted?
    total
  end

  private

  # check {User}'s ticket presence based of {Event#tickets_frequency}
  def validate_frequency
    exist, message = case event.tickets_frequency
    when "single"
                       [ event_ticket_exist?, I18n.t("site.ticket.errors.single") ]
    when "daily"
                       [ event_ticket_exist?(start_at.beginning_of_day..start_at.end_of_day),
                        I18n.t("site.ticket.errors.daily") ]
    when "weekly"
                       [ event_ticket_exist?(start_at.-(7.days)..start_at.+(7.days)),
                        I18n.t("site.ticket.errors.weekly") ]
    when "monthly"
                       [ event_ticket_exist?(start_at.-(30.days)..start_at.+(30.days)),
                        I18n.t("site.ticket.errors.montly") ]
    else
                       return true
    end
    errors.add(:seats, message) if exist
  end

  # check if all mandatory {Question} are present
  def missing_answers
    happening.questions  .mandatory.pluck(:id) - answers.map { |a| a.question_id }
  end
end

#user_idInteger

Returns identifier of related User.

Returns:

  • (Integer)

    identifier of related User



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'app/models/ticket.rb', line 23

class Ticket < ApplicationRecord
  belongs_to :happening, counter_cache: true
  belongs_to :user
  has_many :answers, dependent: :destroy
  delegate :event, :event_id, :max_tickets, :max_tickets_for_user, :reserved?, :saleable?, :start_at, to: :happening, allow_nil: true
  delegate :member?, to: :user, allow_nil: true
  accepts_nested_attributes_for :answers, reject_if: :all_blank
  attr_accessor :by_editor
  after_create  -> { TicketMailer.confirm(self).deliver_later }
  before_destroy -> { TicketMailer.deleted(self).deliver }

  validates :happening, presence: true
  validates :user, presence: true
  with_options unless: :by_editor do
    validates :saleable?, inclusion: [ true ]
    validates :tickets_count, numericality: { only_integer: true, less_than_or_equal_to: :max_tickets }
    validates :tickets_for_user_count,
              numericality: { only_integer: true, less_than_or_equal_to: :max_tickets_for_user }
    validates :missing_answers, absence: true
    validates :member?, presence: true if :reserved?
    validate  :validate_frequency
  end

  scope :with_user, ->(user) { where user: }

  # check if exists {Event}'s {Ticket} for {User} in a time period
  # @return [Boolean] true if exist a ticket in the time range
  def event_ticket_exist?(period = nil)
    @when = { happenings: { start_at: period } } if period.present?
    event.tickets.where(@when).where(user:).exists?
  end

  # count total of each other happening ticket self included
  # @return [Integer] number of tickets
  def tickets_count
    total = happening.tickets_count
    total += 1 unless persisted?
    total
  end

  # count total of each other happening ticket from {User} self included
  # @return [Integer] number of tickets
  def tickets_for_user_count
    total = happening.tickets.where(user:).count
    total += 1 unless persisted?
    total
  end

  private

  # check {User}'s ticket presence based of {Event#tickets_frequency}
  def validate_frequency
    exist, message = case event.tickets_frequency
    when "single"
                       [ event_ticket_exist?, I18n.t("site.ticket.errors.single") ]
    when "daily"
                       [ event_ticket_exist?(start_at.beginning_of_day..start_at.end_of_day),
                        I18n.t("site.ticket.errors.daily") ]
    when "weekly"
                       [ event_ticket_exist?(start_at.-(7.days)..start_at.+(7.days)),
                        I18n.t("site.ticket.errors.weekly") ]
    when "monthly"
                       [ event_ticket_exist?(start_at.-(30.days)..start_at.+(30.days)),
                        I18n.t("site.ticket.errors.montly") ]
    else
                       return true
    end
    errors.add(:seats, message) if exist
  end

  # check if all mandatory {Question} are present
  def missing_answers
    happening.questions  .mandatory.pluck(:id) - answers.map { |a| a.question_id }
  end
end

Instance Method Details

#event_ticket_exist?(period = nil) ⇒ Boolean

check if exists Event‘s Ticket for User in a time period

Returns:

  • (Boolean)

    true if exist a ticket in the time range



50
51
52
53
# File 'app/models/ticket.rb', line 50

def event_ticket_exist?(period = nil)
  @when = { happenings: { start_at: period } } if period.present?
  event.tickets.where(@when).where(user:).exists?
end

#tickets_countInteger

count total of each other happening ticket self included

Returns:

  • (Integer)

    number of tickets



57
58
59
60
61
# File 'app/models/ticket.rb', line 57

def tickets_count
  total = happening.tickets_count
  total += 1 unless persisted?
  total
end

#tickets_for_user_countInteger

count total of each other happening ticket from User self included

Returns:

  • (Integer)

    number of tickets



65
66
67
68
69
# File 'app/models/ticket.rb', line 65

def tickets_for_user_count
  total = happening.tickets.where(user:).count
  total += 1 unless persisted?
  total
end