Module: SpreeCmCommissioner::OrderDecorator
- Defined in:
- app/models/spree_cm_commissioner/order_decorator.rb
Class Method Summary collapse
-
.prepended(base) ⇒ Object
rubocop:disable Metrics/MethodLength,Metrics/AbcSize.
Instance Method Summary collapse
-
#associate_user!(user, override_email = true) ⇒ Object
overrided add phone_number trigger when update customer detail.
-
#collect_payment_methods(store = nil) ⇒ Object
override.
- #collect_payment_methods_for_early_adopter(store = nil) ⇒ Object
-
#create_default_payment_if_eligble ⇒ Object
assume check is default payment method for subscription.
- #customer_address ⇒ Object
-
#delivery_required? ⇒ Boolean
override.
- #display_outstanding_balance ⇒ Object
- #generate_png_qr(size = 120) ⇒ Object
- #generate_svg_qr ⇒ Object
-
#insufficient_stock_lines ⇒ Object
override spree use this method to check stock availability & consider whether :order can continue to next state.
- #mark_as_archive ⇒ Object
- #order_completed? ⇒ Boolean
-
#payment_host ⇒ Object
override spree_vpago method.
-
#payment_required? ⇒ Boolean
overrided.
-
#purchased_from_tenant? ⇒ Boolean
Returns true when the order was created under a tenant context.
- #qr_data ⇒ Object
-
#restart_checkout_flow ⇒ Object
Override spree_core behavior to intentionally avoid calling ‘next!`.
- #subscription? ⇒ Boolean
- #ticket_seller_user? ⇒ Boolean
-
#valid_promotion_ids ⇒ Object
overrided avoid raise error when source_id is nil.
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 76 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 3 def self.prepended(base) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize base.include SpreeCmCommissioner::StoreMetadata base.include SpreeCmCommissioner::PhoneNumberSanitizer base.include SpreeCmCommissioner::OrderSeatable base.include SpreeCmCommissioner::OrderStateMachine base.include SpreeCmCommissioner::RouteOrderCountable 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.has_many :product_completion_steps, class_name: 'SpreeCmCommissioner::ProductCompletionStep', through: :line_items 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
150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 150 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
123 124 125 126 127 128 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 123 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
130 131 132 133 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 130 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_eligble ⇒ Object
assume check is default payment method for subscription
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 184 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_address ⇒ Object
218 219 220 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 218 def customer_address bill_address || ship_address end |
#delivery_required? ⇒ Boolean
override
136 137 138 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 136 def delivery_required? line_items.any?(&:delivery_required?) end |
#display_outstanding_balance ⇒ Object
258 259 260 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 258 def display_outstanding_balance Spree::Money.new(outstanding_balance, currency: currency).to_s end |
#generate_png_qr(size = 120) ⇒ Object
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 238 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_qr ⇒ Object
226 227 228 229 230 231 232 233 234 235 236 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 226 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_lines ⇒ Object
override spree use this method to check stock availability & consider whether :order can continue to next state.
111 112 113 114 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 111 def insufficient_stock_lines checker = SpreeCmCommissioner::Stock::OrderAvailabilityChecker.new(self) checker.insufficient_stock_lines end |
#mark_as_archive ⇒ Object
163 164 165 166 167 168 169 170 171 172 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 163 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
222 223 224 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 222 def order_completed? complete? && need_confirmation? == false end |
#payment_host ⇒ Object
override spree_vpago method
263 264 265 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 263 def payment_host tenant&.host.presence || ENV.fetch('DEFAULT_URL_HOST') end |
#payment_required? ⇒ Boolean
overrided
141 142 143 144 145 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 141 def payment_required? return false if need_confirmation? super end |
#purchased_from_tenant? ⇒ Boolean
Returns true when the order was created under a tenant context.
214 215 216 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 214 def purchased_from_tenant? !tenant_id.nil? end |
#qr_data ⇒ Object
254 255 256 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 254 def qr_data "#{number}-#{token}" end |
#restart_checkout_flow ⇒ Object
Override spree_core behavior to intentionally avoid calling ‘next!`.
Goal: keep the order state at ‘cart’ when restarting checkout, especially when seats were held during the address step.
Flow summary:
-
User goes from cart -> address: we hold seats.
-
User navigates back from address: we call this method to cancel the holds. We do NOT call ‘next!` here; otherwise the order state machine would trigger `hold_blocks!` again and re-hold seats unnecessarily.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 88 def restart_checkout_flow ActiveRecord::Base.transaction do cancel_blocks! if should_manage_blocks? update_columns( # rubocop:disable Rails/SkipsModelValidations state: 'cart', updated_at: Time.current ) end rescue StandardError => e CmAppLogger.error( label: 'SpreeCmCommissioner::OrderDecorator#restart_checkout_flow failed', data: { order_id: id, error_class: e.class.name, error_message: e., backtrace: e.backtrace&.first(5)&.join("\n") } ) raise end |
#subscription? ⇒ Boolean
209 210 211 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 209 def subscription? subscription.present? end |
#ticket_seller_user? ⇒ Boolean
116 117 118 119 120 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 116 def ticket_seller_user? return false if user.nil? user.has_spree_role?('ticket_seller') end |
#valid_promotion_ids ⇒ Object
overrided avoid raise error when source_id is nil. github.com/channainfo/commissioner/pull/843
177 178 179 180 181 |
# File 'app/models/spree_cm_commissioner/order_decorator.rb', line 177 def valid_promotion_ids all_adjustments.eligible.nonzero.promotion .where.not(source_id: nil) .map { |a| a.source.promotion_id }.uniq end |