Module: SpreeCmCommissioner::RoleDecorator

Defined in:
app/models/spree_cm_commissioner/role_decorator.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.prepended(base) ⇒ Object

rubocop:disable Metrics/AbcSize



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'app/models/spree_cm_commissioner/role_decorator.rb', line 3

def self.prepended(base) # rubocop:disable Metrics/AbcSize
  base.include SpreeCmCommissioner::StoreMetadata

  base.enum role_type: { internal: 0, external: 1, preview: 2, check_in: 3 }
  base.enum check_in_mode: { all: 0, include: 1, exclude: 2 }, _prefix: :check_in

  base.has_many :role_permissions, class_name: 'SpreeCmCommissioner::RolePermission'
  base.has_many :permissions, through: :role_permissions, class_name: 'SpreeCmCommissioner::Permission'
  base.has_many :preview_roles, class_name: 'SpreeCmCommissioner::PreviewRole'

  # Check-in Group scoping: a check_in role belongs to one event (taxon) and lists the products
  # (ticket types) it may check in, stored as a product_ids array — see #check_in_allows?.
  base. :product_ids, :array, default: []
  base.belongs_to :event, class_name: 'Spree::Taxon', optional: true

  base.belongs_to :vendor, optional: true

  base.scope :non_vendor, -> { where(vendor_id: nil) }
  base.scope :filter_by_vendor, lambda { |vendor|
    where(vendor_id: vendor)
  }
  base.scope :filter_external, -> { where(role_type: :external) }
  base.scope :filter_internal, -> { where(role_type: :internal) }
  base.scope :filter_preview, -> { where(role_type: :preview) }
  base.scope :filter_check_in, -> { where(role_type: :check_in) }

  base.accepts_nested_attributes_for :role_permissions, allow_destroy: true

  base.before_validation :generate_unique_name, if: -> { vendor_id.present? }

  base.validates :presentation, presence: true, if: -> { vendor_id.present? }
  base.validates :event_id, presence: true, if: -> { check_in? }
  # Permission roles are unique per vendor; check-in groups are unique per event, so two
  # events under the same vendor can each own a "VIP" group.
  base.validates :presentation, uniqueness: { scope: :vendor_id }, if: -> { vendor_id.present? && !check_in? }
  base.validates :presentation, uniqueness: { scope: %i[vendor_id event_id] }, if: -> { vendor_id.present? && check_in? }

  base.after_commit :sync_event_has_check_in_groups_flag, on: %i[create destroy], if: -> { check_in? }
end

Instance Method Details

#check_in_allows?(line_item) ⇒ Boolean

Whether this check-in group lets a crew check in the given line item. The group's mode decides how product_ids is read: all = everything, include = allowlist, exclude = blocklist. A group with no products behaves like "all" regardless of mode.

Returns:

  • (Boolean)


56
57
58
59
60
61
# File 'app/models/spree_cm_commissioner/role_decorator.rb', line 56

def check_in_allows?(line_item)
  return true if check_in_all? || product_ids.blank?

  matched = product_ids.include?(line_item.product_id)
  check_in_exclude? ? !matched : matched
end

#check_in_scoped_product_ids(event_product_ids) ⇒ Object

The concrete product ids this group covers, for scoping a data pull (the dashboard preview, the operator export). nil = unrestricted — an all-mode group or one with no products covers every ticket.



66
67
68
69
70
71
# File 'app/models/spree_cm_commissioner/role_decorator.rb', line 66

def check_in_scoped_product_ids(event_product_ids)
  return nil if check_in_all? || product_ids.blank?

  ids = product_ids.map(&:to_i)
  check_in_exclude? ? event_product_ids.map(&:to_i) - ids : ids
end

#generate_unique_nameObject



43
44
45
46
47
48
49
50
51
# File 'app/models/spree_cm_commissioner/role_decorator.rb', line 43

def generate_unique_name
  return if name.present?
  return if presentation.blank?

  slug = presentation.downcase.parameterize(separator: '-')
  # Include the event so a vendor can reuse a group name (e.g. "VIP") across events without
  # colliding on the globally-unique spree_roles.name.
  self.name = check_in? ? "#{vendor.slug}-event-#{event_id}-#{slug}" : "#{vendor.slug}-#{slug}"
end