Class: Spree::Core::Importer::Order

Inherits:
Object
  • Object
show all
Defined in:
lib/spree/core/importer/order.rb

Class Method Summary (collapse)

Class Method Details

+ (Object) create_adjustments_from_params(adjustments, order)



113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/spree/core/importer/order.rb', line 113

def self.create_adjustments_from_params(adjustments, order)
  return [] unless adjustments
  adjustments.each do |a|
    adjustment = order.adjustments.build(
      order:  order,
      amount: a[:amount].to_d,
      label:  a[:label]
    )
    adjustment.save!
    adjustment.finalize!
  end
end

+ (Object) create_line_items_from_params(line_items_hash, order)



98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/spree/core/importer/order.rb', line 98

def self.create_line_items_from_params(line_items_hash, order)
  return {} unless line_items_hash
  line_items_hash.each_key do |k|
    extra_params = line_items_hash[k].except(:variant_id, :quantity, :sku)
    line_item = ensure_variant_id_from_params(line_items_hash[k])
    line_item = order.contents.add(Spree::Variant.find(line_item[:variant_id]), line_item[:quantity])
    # Raise any errors with saving to prevent import succeeding with line items failing silently.
    if extra_params.present?
      line_item.update_attributes!(extra_params)
    else
      line_item.save!
    end
  end
end

+ (Object) create_payments_from_params(payments_hash, order)



126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/spree/core/importer/order.rb', line 126

def self.create_payments_from_params(payments_hash, order)
  return [] unless payments_hash
  payments_hash.each do |p|
    payment = order.payments.build order: order
    payment.amount = p[:amount].to_f
    # Order API should be using state as that's the normal payment field.
    # spree_wombat serializes payment state as status so imported orders should fall back to status field.
    payment.state = p[:state] || p[:status] || 'completed'
    payment.payment_method = Spree::PaymentMethod.find_by_name!(p[:payment_method])
    payment.source = create_source_payment_from_params(p[:source], payment) if p[:source]
    payment.save!
  end
end

+ (Object) create_shipments_from_params(shipments_hash, order)



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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/spree/core/importer/order.rb', line 51

def self.create_shipments_from_params(shipments_hash, order)
  return [] unless shipments_hash

  shipments_hash.each do |s|
    shipment = Shipment.new
    shipment.tracking       = s[:tracking]
    shipment.stock_location = Spree::StockLocation.find_by_admin_name(s[:stock_location]) || Spree::StockLocation.find_by_name!(s[:stock_location])

    inventory_units = s[:inventory_units] || []
    inventory_units.each do |iu|
      ensure_variant_id_from_params(iu)

      unless line_item = order.line_items.find_by(variant_id: iu[:variant_id])
        line_item = order.contents.add(Spree::Variant.find(iu[:variant_id]), 1)
      end

      # Spree expects a Inventory Unit to always reference a line
      # item and variant otherwise users might get exceptions when
      # trying to view these units. Note the Importer might not be
      # able to find the line item if line_item.variant_id |= iu.variant_id
      shipment.inventory_units.new(
        order: order,
        variant_id: iu[:variant_id],
        line_item: line_item
      )
    end

    # Mark shipped if it should be.
    if s[:shipped_at].present?
      shipment.shipped_at = s[:shipped_at]
      shipment.state      = 'shipped'
      shipment.inventory_units.each do |unit|
        unit.state = 'shipped'
      end
    end

    order.shipments << shipment
    shipment.save!

    shipping_method = Spree::ShippingMethod.find_by_name(s[:shipping_method]) || Spree::ShippingMethod.find_by_admin_name!(s[:shipping_method])
    rate = shipment.shipping_rates.create!(shipping_method: shipping_method,
                                           cost: s[:cost])
    shipment.selected_shipping_rate_id = rate.id
    shipment.update_amounts
  end
end

+ (Object) create_source_payment_from_params(source_hash, payment)



140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/spree/core/importer/order.rb', line 140

def self.create_source_payment_from_params(source_hash, payment)
  Spree::CreditCard.create(
    month: source_hash[:month],
    year: source_hash[:year],
    cc_type: source_hash[:cc_type],
    last_digits: source_hash[:last_digits],
    name: source_hash[:name],
    payment_method: payment.payment_method,
    gateway_customer_profile_id: source_hash[:gateway_customer_profile_id],
    gateway_payment_profile_id: source_hash[:gateway_payment_profile_id],
    imported: true
  )
end

+ (Object) ensure_country_id_from_params(address)



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/spree/core/importer/order.rb', line 162

def self.ensure_country_id_from_params(address)
  return if address.nil? || address[:country_id].present? || address[:country].nil?

  search = {}
  if name = address[:country]['name']
    search[:name] = name
  elsif iso_name = address[:country]['iso_name']
    search[:iso_name] = iso_name.upcase
  elsif iso = address[:country]['iso']
    search[:iso] = iso.upcase
  elsif iso3 = address[:country]['iso3']
    search[:iso3] = iso3.upcase
  end

  address.delete(:country)
  address[:country_id] = Spree::Country.where(search).first!.id
end

+ (Object) ensure_state_id_from_params(address)



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/spree/core/importer/order.rb', line 180

def self.ensure_state_id_from_params(address)
  return if address.nil? || address[:state_id].present? || address[:state].nil?

  search = {}
  if name = address[:state]['name']
    search[:name] = name
  elsif abbr = address[:state]['abbr']
    search[:abbr] = abbr.upcase
  end

  address.delete(:state)
  search[:country_id] = address[:country_id]

  if state = Spree::State.where(search).first
    address[:state_id] = state.id
  else
    address[:state_name] = search[:name] || search[:abbr]
  end
end

+ (Object) ensure_variant_id_from_params(hash)



154
155
156
157
158
159
160
# File 'lib/spree/core/importer/order.rb', line 154

def self.ensure_variant_id_from_params(hash)
  sku = hash.delete(:sku)
  unless hash[:variant_id].present?
    hash[:variant_id] = Spree::Variant.with_prices.find_by_sku!(sku).id
  end
  hash
end

+ (Object) import(user, params)



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
# File 'lib/spree/core/importer/order.rb', line 5

def self.import(user, params)
  params = params.to_h
  ActiveRecord::Base.transaction do
    ensure_country_id_from_params params[:ship_address_attributes]
    ensure_state_id_from_params params[:ship_address_attributes]
    ensure_country_id_from_params params[:bill_address_attributes]
    ensure_state_id_from_params params[:bill_address_attributes]

    create_params = params.slice :currency
    order = Spree::Order.create! create_params
    order.store ||= Spree::Store.default
    order.associate_user!(user)
    order.save!

    shipments_attrs = params.delete(:shipments_attributes)

    create_shipments_from_params(shipments_attrs, order)
    create_line_items_from_params(params.delete(:line_items_attributes), order)
    create_adjustments_from_params(params.delete(:adjustments_attributes), order)
    create_payments_from_params(params.delete(:payments_attributes), order)

    params.delete(:user_id) unless user.try(:has_spree_role?, "admin") && params.key?(:user_id)

    completed_at = params.delete(:completed_at)

    order.update_attributes!(params)

    order.create_proposed_shipments unless shipments_attrs.present?

    if completed_at
      order.completed_at = completed_at
      order.state = 'complete'
      order.save!
    end

    # Really ensure that the order totals & states are correct
    order.updater.update
    if shipments_attrs.present?
      order.shipments.each_with_index do |shipment, index|
        shipment.update_columns(cost: shipments_attrs[index][:cost].to_f) if shipments_attrs[index][:cost].present?
      end
    end
    order.reload
  end
end