Class: SpreeCmCommissioner::DraftOrder::Create

Inherits:
Object
  • Object
show all
Includes:
Spree::ServiceModule::Base
Defined in:
app/services/spree_cm_commissioner/draft_order/create.rb

Instance Method Summary collapse

Instance Method Details

#build_line_item!(order, store, line_item_params) ⇒ Object

Builds (unsaved) an order.line_items member — persisted together with the order via order.save's cascading autosave of new has_many records, same as TransitOrder::Create.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'app/services/spree_cm_commissioner/draft_order/create.rb', line 61

def build_line_item!(order, store, line_item_params)
  variant = store.variants.find(line_item_params[:variant_id])
  options = (line_item_params[:options] || {}).to_h.with_indifferent_access
  permitted_opts = ::Spree::PermittedAttributes.line_item_attributes.flatten.index_with { |attribute| options[attribute] }
  opts = permitted_opts.merge(currency: order.currency).compact

  order.line_items.new(
    variant: variant,
    quantity: line_item_params[:quantity],
    options: opts,
    public_metadata: (line_item_params[:public_metadata] || {}).to_h,
    private_metadata: (line_item_params[:private_metadata] || {}).to_h
  )
end

#call(line_items:, user: nil, store: nil, currency: nil, tenant: nil) ⇒ Object



30
31
32
33
34
35
36
37
# File 'app/services/spree_cm_commissioner/draft_order/create.rb', line 30

def call(line_items:, user: nil, store: nil, currency: nil, tenant: nil)
  return failure(nil, I18n.t('spree_cm_commissioner.draft_order.line_items_missing')) if line_items.blank?

  order = create_order!(line_items, user, store, currency, tenant)
  success(order: order)
rescue StandardError => e
  failure(nil, e.message)
end

#create_order!(line_items_params, user, store, currency, tenant) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'app/services/spree_cm_commissioner/draft_order/create.rb', line 39

def create_order!(line_items_params, user, store, currency, tenant)
  store ||= Spree::Store.default
  currency ||= store&.default_currency
  order = Spree::Order.new(state: 'cart', use_billing: true, user: user, store: store, currency: currency, tenant: tenant)
  line_items_params.each { |line_item_params| build_line_item!(order, store, line_item_params) }

  ActiveRecord::Base.transaction do
    raise StandardError, order_error_message(order) unless order.save

    order.update_with_updater!

    # Build blank guests per line item so the client can render guest fields offline.
    order.line_items.each(&:generate_remaining_guests)

    raise StandardError, order_error_message(order) if order.has_checkout_step?('address') && !order.next
  end

  order
end

#order_error_message(order) ⇒ Object

order.errors already includes line item errors (accepts_nested_attributes_for autosaves them in). Skip full_message's attribute prefix when the validator already wrote a full sentence, e.g. before: "Quantity Not enough stock" -> after: "Not enough stock".



79
80
81
82
83
# File 'app/services/spree_cm_commissioner/draft_order/create.rb', line 79

def order_error_message(order)
  order.errors.map do |error|
    error.raw_type.is_a?(String) || error.options[:message].is_a?(String) ? error.message : error.full_message
  end.uniq.to_sentence
end