Module: SpreeCmCommissioner::LineItemDecorator

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

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.include_modules(base) ⇒ Object



58
59
60
61
62
63
64
65
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 58

def self.include_modules(base)
  base.include Spree::Core::NumberGenerator.new(prefix: 'L')
  base.include SpreeCmCommissioner::LineItemDurationable
  base.include SpreeCmCommissioner::LineItemsFilterScope
  base.include SpreeCmCommissioner::LineItemGuestsConcern
  base.include SpreeCmCommissioner::ProductDelegation
  base.include SpreeCmCommissioner::KycBitwise
end

.pending_guests_queryObject



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

def self.pending_guests_query
  lambda {
    left_outer_joins(:id_card)
      .where(upload_later: true, id_card: { front_image: nil })
  }
end

.prepended(base) ⇒ Object

rubocop:disable Metrics/MethodLength



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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 3

def self.prepended(base) # rubocop:disable Metrics/MethodLength
  include_modules(base)

  base.belongs_to :accepter, class_name: 'Spree::User', optional: true
  base.belongs_to :rejecter, class_name: 'Spree::User', optional: true
  base.belongs_to :event, class_name: 'Spree::Taxon', optional: true, inverse_of: :line_items

  base.has_one :google_wallet, class_name: 'SpreeCmCommissioner::GoogleWallet', through: :product

  base.has_many :option_types, through: :product
  base.has_many :taxons, class_name: 'Spree::Taxon', through: :product
  base.has_many :guests, class_name: 'SpreeCmCommissioner::Guest', dependent: :destroy
  base.has_many :pending_guests, pending_guests_query, class_name: 'SpreeCmCommissioner::Guest', dependent: :destroy
  base.has_many :product_completion_steps, class_name: 'SpreeCmCommissioner::ProductCompletionStep', through: :product
  base.has_many :line_item_seats, class_name: 'SpreeCmCommissioner::LineItemSeat', dependent: :destroy

  base.before_save :update_vendor_id
  base.before_save :update_quantity, if: :transit?

  base.validate :validate_seats_reservation, if: :transit?

  base.before_create :add_due_date, if: :subscription?

  base.validate :ensure_not_exceed_max_quantity_per_order, if: -> { variant&.max_quantity_per_order.present? }

  base.whitelisted_ransackable_associations |= %w[guests order]
  base.whitelisted_ransackable_attributes |= %w[number to_date from_date vendor_id]

  base.delegate :delivery_required?, :permanent_stock?, :high_demand, :transit?,
                to: :variant
  base.delegate :discontinue_on, :product_type, :accommodation?, :service?, :ecommerce?, :need_confirmation,
                to: :product

  base.accepts_nested_attributes_for :guests, allow_destroy: true
  base.accepts_nested_attributes_for :line_item_seats, allow_destroy: true

  def base.json_api_columns
    json_api_columns = column_names.reject { |c| c.match(/_id$|id|preferences|(.*)password|(.*)token|(.*)api_key/) }
    json_api_columns << :options_text
    json_api_columns << :vendor_id
  end

  def base.search_by_qr_data!(data)
    matches = data.match(/(R\d+)-([A-Za-z0-9_\-]+)-(L\d+)/)&.captures

    raise ActiveRecord::RecordNotFound, "Couldn't find Spree::LineItem with QR data: #{data}" unless matches

    order_number, order_token, line_item_id = matches
    line_item_id = line_item_id.delete('L').to_i

    Spree::LineItem.joins(:order)
                   .find_by(id: line_item_id, spree_orders: { number: order_number, token: order_token })
  end
end

Instance Method Details

#accepted?Boolean

Returns:

  • (Boolean)


114
115
116
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 114

def accepted?
  accepted_at.present?
end

#accepted_by(user) ⇒ Object



122
123
124
125
126
127
128
129
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 122

def accepted_by(user)
  return if accepted_at.present? && accepter_id.present?

  update(
    accepted_at: Time.current,
    accepter: user
  )
end

#allowed_self_check_in?Boolean

Returns:

  • (Boolean)


98
99
100
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 98

def allowed_self_check_in?
  allow_self_check_in?
end

#amountObject

date_unit could be number of nights, or days or hours depending on usecases For example:

  • accomodation uses number of nights.

  • appointment uses number of hours, etc.

override



88
89
90
91
92
93
94
95
96
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 88

def amount
  base_price = price * quantity

  if permanent_stock? && date_unit.present?
    base_price * date_unit
  else
    base_price
  end
end

#amount_per_guestObject



106
107
108
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 106

def amount_per_guest
  amount / quantity
end

#commission_rateObject



110
111
112
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 110

def commission_rate
  product.commission_rate || vendor&.commission_rate || 0
end

#completion_stepsObject



174
175
176
177
178
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 174

def completion_steps
  @completion_steps ||= product_completion_steps.map do |completion_step|
    completion_step.construct_hash(line_item: self)
  end
end

#generate_png_qr(size = 120) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 152

def generate_png_qr(size = 120)
  qrcode = RQRCode::QRCode.new(qr_data)
  qrcode.as_png(
    bit_depth: 1,
    border_modules: 1,
    color_mode: ChunkyPNG::COLOR_GRAYSCALE,
    color: 'black',
    file: nil,
    fill: 'white',
    module_px_size: 4,
    resize_exactly_to: false,
    resize_gte_to: false,
    size: size
  )
end

#generate_svg_qrObject



140
141
142
143
144
145
146
147
148
149
150
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 140

def generate_svg_qr
  qrcode = RQRCode::QRCode.new(qr_data)
  qrcode.as_svg(
    color: '000',
    shape_rendering: 'crispEdges',
    module_size: 5,
    standalone: true,
    use_path: true,
    viewbox: '0 0 20 10'
  )
end

#jwt_tokenObject



191
192
193
194
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 191

def jwt_token
  payload = { order_number: order.number, line_item_id: id }
  SpreeCmCommissioner::OrderJwtToken.encode(payload, order.token)
end

#kycObject



67
68
69
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 67

def kyc
  variant.kyc || product.kyc
end

#monthObject



187
188
189
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 187

def month
  to_date.strftime('%B %Y')
end

#qr_dataObject



168
169
170
171
172
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 168

def qr_data
  return nil if order.nil?

  "#{order.number}-#{order.token}-L#{id}"
end

#rejected?Boolean

Returns:

  • (Boolean)


118
119
120
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 118

def rejected?
  rejected_at.present?
end

#rejected_by(user) ⇒ Object



131
132
133
134
135
136
137
138
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 131

def rejected_by(user)
  return if rejected_at.present? && rejecter_id.present?

  update(
    rejected_at: Time.current,
    rejecter: user
  )
end

#required_self_check_in_location?Boolean

Returns:

  • (Boolean)


102
103
104
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 102

def required_self_check_in_location?
  required_self_check_in_location
end

#reservation?Boolean

Returns:

  • (Boolean)


78
79
80
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 78

def reservation?
  date_present? && !subscription?
end

#sufficient_stock?Boolean

override

Returns:

  • (Boolean)


181
182
183
184
185
# File 'app/models/spree_cm_commissioner/line_item_decorator.rb', line 181

def sufficient_stock?
  return transit_sufficient_stock? if variant.product.product_type == 'transit'

  SpreeCmCommissioner::Stock::LineItemAvailabilityChecker.new(self).can_supply?(quantity)
end