Module: SpreeCmCommissioner::OrderStateMachine

Extended by:
ActiveSupport::Concern
Defined in:
app/models/concerns/spree_cm_commissioner/order_state_machine.rb

Instance Method Summary collapse

Instance Method Details

#accepted_by(user) ⇒ Object

allow authorized user to accept all requested line items



120
121
122
123
124
125
126
127
128
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 120

def accepted_by(user)
  transaction do
    accept!

    line_items.each do |line_item|
      line_item.accepted_by(user)
    end
  end
end

#can_accept_all?Boolean

can_accepted? already use by ransack/visitor.rb

Returns:

  • (Boolean)


209
210
211
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 209

def can_accept_all?
  approved? && requested?
end

#can_alert_request_to_vendor?Boolean

Returns:

  • (Boolean)


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

def can_alert_request_to_vendor?
  !accepted? && approved? && need_confirmation?
end

#can_reject_all?Boolean

Returns:

  • (Boolean)


213
214
215
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 213

def can_reject_all?
  approved? && requested?
end

#confirmation_delivered?Boolean

overrided not to send email yet to user if order needs confirmation it will send after vendors accepted.

Returns:

  • (Boolean)


115
116
117
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 115

def confirmation_delivered?
  confirmation_delivered || need_confirmation?
end

#generate_bib_numberObject



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 169

def generate_bib_number
  line_items.find_each(&:generate_remaining_guests)

  line_items.with_bib_prefix.each do |line_item|
    line_item.guests.none_bib.each do |guest|
      guest.generate_bib
      next if guest.save

      guest.errors.each do |msg|
        errors.add(:guests, msg)
      end
    end
  end

  errors.empty?
end

#generate_completion_steps!Object

This is called before complete, which is already wrapped by the transaction of unstock_inventory!



80
81
82
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 80

def generate_completion_steps!
  line_items.each(&:generate_completion_steps!)
end

#guest_incomplete?(guest) ⇒ Boolean

Returns:

  • (Boolean)


130
131
132
133
134
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 130

def guest_incomplete?(guest)
  (guest.pre_registration_fields? && !guest.pre_registration_completed?) ||
    (guest.post_registration_fields? && !guest.post_registration_completed?) ||
    (guest.during_check_in_fields? && !guest.check_in_completed?)
end

#has_incomplete_guest_info?Boolean

rubocop:disable Naming/PredicateName

Returns:

  • (Boolean)


105
106
107
108
109
110
111
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 105

def has_incomplete_guest_info? # rubocop:disable Naming/PredicateName
  line_items.any? do |line_item|
    line_item.guests.any? do |guest|
      guest_incomplete?(guest)
    end
  end
end

#mark_user_as_has_incomplete_guest_infoObject



90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 90

def mark_user_as_has_incomplete_guest_info
  user&.&.[]=('has_incomplete_guest_info', true)
  user&.save!

  line_items.each do |line_item|
    line_item.guests.each do |guest|
      guest.user ||= user
      guest.save!(validate: false) if guest.changed?
      guest.save_and_move_to_next_stage
      # send notification only for guests that still have incomplete dynamic fields
      SpreeCmCommissioner::GuestDynamicFieldNotificationSender.call(guest: guest) if guest_incomplete?(guest)
    end
  end
end

#need_confirmation?Boolean

Returns:

  • (Boolean)


225
226
227
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 225

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

#notify_order_complete_app_notification_to_userObject



242
243
244
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 242

def notify_order_complete_app_notification_to_user
  SpreeCmCommissioner::OrderCompleteNotificationSender.call(order: self)
end

#notify_order_complete_telegram_notification_to_userObject



246
247
248
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 246

def notify_order_complete_telegram_notification_to_user
  SpreeCmCommissioner::OrderCompleteTelegramSenderJob.perform_later(id) if user_id.present?
end

#precalculate_conversionObject



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

def precalculate_conversion
  line_items.each do |item|
    SpreeCmCommissioner::ConversionPreCalculatorJob.perform_later(item.product_id)
  end
end

#product_completion_steps_exist?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 75

def product_completion_steps_exist?
  product_completion_steps.any?
end

#rejected_by(user) ⇒ Object



186
187
188
189
190
191
192
193
194
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 186

def rejected_by(user)
  transaction do
    reject!

    line_items.each do |line_item|
      line_item.rejected_by(user)
    end
  end
end

#requested_state?Boolean

Returns:

  • (Boolean)


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

def requested_state?
  request_state == 'requested'
end

#restock_inventory!Object



162
163
164
165
166
167
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 162

def restock_inventory!
  ActiveRecord::Base.transaction do
    cancel_blocks!
    restock_inventory_in_redis!
  end
end

#send_order_accepted_app_notification_to_userObject



254
255
256
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 254

def send_order_accepted_app_notification_to_user
  SpreeCmCommissioner::OrderAcceptedNotificationSender.call(order: self)
end

#send_order_accepted_telegram_alert_to_storeObject



269
270
271
272
273
274
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 269

def send_order_accepted_telegram_alert_to_store
  title = '✅ --- [ORDER ACCEPTED BY VENDOR] ---'
  chat_id = store.preferred_telegram_order_request_alert_chat_id
  factory = OrderTelegramMessageFactory.new(title: title, order: self)
  TelegramNotificationSenderJob.perform_later(chat_id: chat_id, message: factory.message, parse_mode: factory.parse_mode)
end

#send_order_complete_telegram_alert_to_storeObject



283
284
285
286
287
288
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 283

def send_order_complete_telegram_alert_to_store
  title = '🎫 --- [NEW ORDER] ---'
  chat_id = store.preferred_telegram_order_alert_chat_id
  factory = OrderTelegramMessageFactory.new(title: title, order: self)
  TelegramNotificationSenderJob.perform_later(chat_id: chat_id, message: factory.message, parse_mode: factory.parse_mode)
end

#send_order_complete_telegram_alert_to_vendorsObject



231
232
233
234
235
236
237
238
239
240
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 231

def send_order_complete_telegram_alert_to_vendors
  vendor_list.each do |vendor|
    title = '🎫 --- [NEW ORDER FROM BOOKME+] ---'
    chat_id = vendor.preferred_telegram_chat_id
    if chat_id.present?
      factory = OrderTelegramMessageFactory.new(title: title, order: self, vendor: vendor)
      TelegramNotificationSenderJob.perform_later(chat_id: chat_id, message: factory.message, parse_mode: factory.parse_mode)
    end
  end
end

#send_order_rejected_app_notification_to_userObject



258
259
260
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 258

def send_order_rejected_app_notification_to_user
  SpreeCmCommissioner::OrderRejectedNotificationSender.call(order: self)
end

#send_order_rejected_telegram_alert_to_storeObject



276
277
278
279
280
281
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 276

def send_order_rejected_telegram_alert_to_store
  title = '❌ --- [ORDER REJECTED BY VENDOR] ---'
  chat_id = store.preferred_telegram_order_request_alert_chat_id
  factory = OrderTelegramMessageFactory.new(title: title, order: self)
  TelegramNotificationSenderJob.perform_later(chat_id: chat_id, message: factory.message, parse_mode: factory.parse_mode)
end

#send_order_request_telegram_confirmation_alert_to_vendorObject



229
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 229

def send_order_request_telegram_confirmation_alert_to_vendor; end

#send_order_requested_app_notification_to_userObject



250
251
252
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 250

def send_order_requested_app_notification_to_user
  SpreeCmCommissioner::OrderRequestedNotificationSender.call(order: self)
end

#send_order_requested_telegram_alert_to_storeObject



262
263
264
265
266
267
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 262

def send_order_requested_telegram_alert_to_store
  title = '🔔 --- [NEW REQUESTED BY USER] ---'
  chat_id = store.preferred_telegram_order_request_alert_chat_id
  factory = OrderTelegramMessageFactory.new(title: title, order: self)
  TelegramNotificationSenderJob.perform_later(chat_id: chat_id, message: factory.message, parse_mode: factory.parse_mode)
end

#send_transaction_email_to_userObject



196
197
198
199
200
201
202
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 196

def send_transaction_email_to_user
  line_items.each do |line_item|
    next if line_item.event.nil?

    SpreeCmCommissioner::EventTransactionalMailer.send_to_participant(line_item.event_id, user.id).deliver_later
  end
end

#unstock_inventory!Object



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 136

def unstock_inventory!
  ActiveRecord::Base.transaction do
    yield if block_given? # Equal to block.call

    # After the transition is complete, the following code will execute first before proceeding to other `after_transition` callbacks.
    # This ensures that if `reserve_blocks!` or `unstock_inventory_in_redis!` fails, the state will be rolled back,
    # and neither the `finalize!` method nor any notifications will be triggered.
    # The payment will be reversed in vPago gem, and `Spree::Checkout::Complete` will be called, which checks `order.reload.complete?`.
    # This is critical because if the order state is complete, the payment will be marked as paid.

    reserve_blocks!
    unstock_inventory_in_redis!

    # We rollback only order state, and we keep payment state as it is.
    # We implement payment in vPago gem, and it will be reversed in the gem.
    # Some bank has api for refund, but some don't have the api to refund yet. So we keep the payment state as it is and refund manually.
  end
rescue StandardError => e
  CmAppLogger.log(
    label: 'SpreeCmCommissioner::OrderStateMachine#reserve_inventory failed',
    data: { order_id: id, error: e.message, type: e.class.name, backtrace: e.backtrace&.first(5)&.join("\n") }
  )

  raise e
end

#user_has_email?Boolean

Returns:

  • (Boolean)


204
205
206
# File 'app/models/concerns/spree_cm_commissioner/order_state_machine.rb', line 204

def user_has_email?
  user.present? && user.email.present?
end