Module: SpreeCmCommissioner::OrderDecorator

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

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.prepended(base) ⇒ Object

rubocop:disable Metrics/MethodLength,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
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
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 3

def self.prepended(base) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
  base.include SpreeCmCommissioner::PhoneNumberSanitizer
  base.include SpreeCmCommissioner::OrderSeatable
  base.include SpreeCmCommissioner::OrderStateMachine
  base.include SpreeCmCommissioner::RouteOrderCountable
  base.include SpreeCmCommissioner::StoreMetadata

  base.scope :subscription, -> { where.not(subscription_id: nil) }
  base.scope :paid, -> { where(payment_state: :paid) }
  base.scope :complete_or_canceled, -> { complete.or(where(state: 'canceled')) }
  base.scope :payment, -> { incomplete.where(state: 'payment') }
  base.scope :archived, -> { where.not(archived_at: nil) }
  base.scope :not_archived, -> { where(archived_at: nil) }
  base.scope :without_user, -> { where(user_id: nil) }

  base.scope :filter_by_match_user_contact, lambda { |user|
    complete.where(
      '(email = :email OR intel_phone_number = :intel_phone_number) AND user_id IS NULL',
      email: user.email,
      intel_phone_number: user.intel_phone_number
    )
  }

  base.scope :filter_by_vendor, lambda { |vendor|
    joins(:line_items).where(spree_line_items: { vendor_id: vendor }).distinct
  }

  base.before_create :link_by_phone_number
  base.before_create :associate_customer
  base.before_create :set_tenant_id
  base.after_commit :increment_route_order_count, on: :create

  base. :preload_trip_ids, :array, default: []

  base.validates :promo_total, base::MONEY_VALIDATION
  base.validate :validate_channel_prefix, if: :channel_changed?
  base.validates :phone_number, presence: true, if: :require_phone_number

  base.has_one :invoice, dependent: :destroy, class_name: 'SpreeCmCommissioner::Invoice'
  base.has_one :customer, class_name: 'SpreeCmCommissioner::Customer', through: :subscription

  base.belongs_to :tenant, class_name: 'SpreeCmCommissioner::Tenant', optional: true
  base.belongs_to :subscription, class_name: 'SpreeCmCommissioner::Subscription', optional: true

  base.has_many :taxons, class_name: 'Spree::Taxon', through: :customer
  base.has_many :vendors, through: :products, class_name: 'Spree::Vendor'
  base.has_many :taxons, through: :products, class_name: 'Spree::Taxon'
  base.has_many :guests, through: :line_items, class_name: 'SpreeCmCommissioner::Guest'

  base.has_many :saved_guests,
                through: :guests,
                source: :saved_guest,
                class_name: 'SpreeCmCommissioner::SavedGuest'

  base.has_many :blocks, through: :guests, class_name: 'SpreeCmCommissioner::Block', source: :block
  base.has_many :reserved_blocks, through: :guests, class_name: 'SpreeCmCommissioner::ReservedBlock'
  base.has_many :guest_card_classes, class_name: 'SpreeCmCommissioner::GuestCardClass', through: :variants

  base.delegate :customer, to: :user, allow_nil: true

  base.whitelisted_ransackable_associations |= %w[customer taxon payments guests invoice]
  base.whitelisted_ransackable_attributes |= %w[intel_phone_number phone_number email number state]

  base.accepts_nested_attributes_for :saved_guests, allow_destroy: true

  def base.search_by_qr_data!(data)
    token = data.match(/^R\d{9,}-([A-Za-z0-9_\-]+)$/)&.captures

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

    find_by!(token: token)
  end
end

Instance Method Details

#associate_user!(user, override_email = true) ⇒ Object

overrided add phone_number trigger when update customer detail



118
119
120
121
122
123
124
125
126
127
128
129
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 118

def associate_user!(user, override_email = true) # rubocop:disable Style/OptionalBooleanParameter
  self.user           = user
  self.email          = user.email if override_email
  self.phone_number   = user.phone_number if user.phone_number.present?
  self.created_by   ||= user
  self.bill_address ||= user.bill_address.try(:clone)
  self.ship_address ||= user.ship_address.try(:clone)

  changes = slice(:user_id, :email, :phone_number, :created_by_id, :bill_address_id, :ship_address_id)

  self.class.unscoped.where(id: self).update_all(changes) # rubocop:disable Rails/SkipsModelValidations
end

#collect_payment_methods(store = nil) ⇒ Object

override



91
92
93
94
95
96
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 91

def collect_payment_methods(store = nil)
  return super if user.blank?
  return super unless user.early_adopter?

  collect_payment_methods_for_early_adopter(store)
end

#collect_payment_methods_for_early_adopter(store = nil) ⇒ Object



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

def collect_payment_methods_for_early_adopter(store = nil)
  store ||= self.store
  store.payment_methods.available_on_frontend_for_early_adopter.select { |pm| pm.available_for_order?(self) }
end

#create_default_payment_if_eligbleObject

assume check is default payment method for subscription



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 152

def create_default_payment_if_eligble
  return unless subscription?

  if covered_by_store_credit
    payment_method = Spree::PaymentMethod::StoreCredit.available_on_back_end.first_or_create! do |method|
      method.name ||= 'StoreCredit'
      method.stores = [Spree::Store.default] if method.stores.empty?
    end
    source_id = user.store_credit_ids.last
    source_type = 'Spree::StoreCredit'
  else
    payment_method = Spree::PaymentMethod::Check.available_on_back_end.first_or_create! do |method|
      method.name ||= 'Invoice'
      method.stores = [Spree::Store.default] if method.stores.empty?
    end
  end
  payments.create!(
    payment_method: payment_method,
    amount: total,
    source_id: source_id,
    source_type: source_type
  )
  Spree::Checkout::Advance.call(order: self)
end

#customer_addressObject



181
182
183
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 181

def customer_address
  bill_address || ship_address
end

#delivery_required?Boolean

override

Returns:

  • (Boolean)


104
105
106
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 104

def delivery_required?
  line_items.any?(&:delivery_required?)
end

#display_outstanding_balanceObject



221
222
223
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 221

def display_outstanding_balance
  Spree::Money.new(outstanding_balance, currency: currency).to_s
end

#generate_png_qr(size = 120) ⇒ Object



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 201

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



189
190
191
192
193
194
195
196
197
198
199
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 189

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

#insufficient_stock_linesObject

override spree use this method to check stock availability & consider whether :order can continue to next state.



79
80
81
82
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 79

def insufficient_stock_lines
  checker = SpreeCmCommissioner::Stock::OrderAvailabilityChecker.new(self)
  checker.insufficient_stock_lines
end

#mark_as_archiveObject



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

def mark_as_archive
  blocks_canceled = begin
    cancel_blocks!
    true
  rescue StandardError
    false
  end

  update(archived_at: Time.current) if blocks_canceled
end

#order_completed?Boolean

Returns:

  • (Boolean)


185
186
187
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 185

def order_completed?
  complete? && need_confirmation? == false
end

#payment_hostObject

override spree_vpago method



226
227
228
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 226

def payment_host
  tenant&.host.presence || ENV.fetch('DEFAULT_URL_HOST')
end

#payment_required?Boolean

overrided

Returns:

  • (Boolean)


109
110
111
112
113
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 109

def payment_required?
  return false if need_confirmation?

  super
end

#qr_dataObject



217
218
219
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 217

def qr_data
  "#{number}-#{token}"
end

#subscription?Boolean

Returns:

  • (Boolean)


177
178
179
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 177

def subscription?
  subscription.present?
end

#ticket_seller_user?Boolean

Returns:

  • (Boolean)


84
85
86
87
88
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 84

def ticket_seller_user?
  return false if user.nil?

  user.has_spree_role?('ticket_seller')
end

#valid_promotion_idsObject

overrided avoid raise error when source_id is nil. github.com/channainfo/commissioner/pull/843



145
146
147
148
149
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 145

def valid_promotion_ids
  all_adjustments.eligible.nonzero.promotion
                 .where.not(source_id: nil)
                 .map { |a| a.source.promotion_id }.uniq
end