Class: SpreeCmCommissioner::PrivateSale

Inherits:
Base
  • Object
show all
Includes:
StoreMetadata
Defined in:
app/models/spree_cm_commissioner/private_sale.rb

Overview

A set of products sold to a named audience, until a given date, through one URL.

The stock itself is withheld separately — an operator moves units into an inventory item's locked pool (InventoryItems::MoveToLocked). This record answers the other half: WHO may buy from that pool, and WHICH products it covers. Neither is much use without the other; a private sale over products with nothing locked grants access to nothing.

The URL carries token verbatim, so revoking is immediate and editing needs no reissue.

Instance Method Summary collapse

Instance Method Details

#authorizes?(user) ⇒ Boolean

Returns:

  • (Boolean)


70
71
72
73
74
75
# File 'app/models/spree_cm_commissioner/private_sale.rb', line 70

def authorizes?(user)
  return false if user.nil?
  return true if open_to_anyone?

  user_ids.include?(user.id) || role_ids.intersect?(user.spree_roles.ids)
end

#covers?(variant) ⇒ Boolean

Every variant of every named product. A variant added to one of them later is covered too — scope is the product, not a frozen list of its variants.

A covered variant with nothing locked still returns true: the purchase then fails at the availability check rather than quietly falling back to public stock. Which is why the admin form only offers products that have locked stock.

Returns:

  • (Boolean)


60
61
62
63
64
# File 'app/models/spree_cm_commissioner/private_sale.rb', line 60

def covers?(variant)
  return false if variant.nil?

  product_ids.include?(variant.product_id)
end

#expired?Boolean

The form picks a DATE, which parses to midnight, so comparing the bare value would kill a sale set to "30 Nov" at 00:00 on the 30th — losing the operator the whole day the label promised. Reading it as the last moment of that day is what "Expires on" says. A record failing validation is re-rendered by the admin, and the edit view asks usable?. Without the nil guard a blank date turns a 422 into a 500.

Returns:

  • (Boolean)


48
49
50
51
52
# File 'app/models/spree_cm_commissioner/private_sale.rb', line 48

def expired?
  return false if expires_at.nil?

  expires_at.end_of_day.past?
end

#open_to_anyone?Boolean

Returns:

  • (Boolean)


66
67
68
# File 'app/models/spree_cm_commissioner/private_sale.rb', line 66

def open_to_anyone?
  user_ids.empty? && role_ids.empty?
end

#productsObject



86
87
88
# File 'app/models/spree_cm_commissioner/private_sale.rb', line 86

def products
  Spree::Product.where(id: product_ids)
end

#rolesObject



94
95
96
# File 'app/models/spree_cm_commissioner/private_sale.rb', line 94

def roles
  Spree::Role.where(id: role_ids)
end

#share_urlObject

The URL handed to a buyer.

Built from the STORE's host, not from the request: this is generated in the admin, whose host is the back office, while the link has to open the client app. Same construction as Taxon#event_url.



82
83
84
# File 'app/models/spree_cm_commissioner/private_sale.rb', line 82

def share_url
  "https://#{Spree::Store.default.url}/tickets?st=#{token}"
end

#usable?Boolean

Expired is not a status: it is a fact about the clock, so it is derived rather than stored and cannot go stale the way a nightly "mark expired" job would.

Returns:

  • (Boolean)


39
40
41
# File 'app/models/spree_cm_commissioner/private_sale.rb', line 39

def usable?
  active? && !expired?
end

#usersObject



90
91
92
# File 'app/models/spree_cm_commissioner/private_sale.rb', line 90

def users
  Spree::User.where(id: user_ids)
end