<commit_before>module Spree
  module Core
    module Importer
      class Order

        def self.import(user, params)
          begin
            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]

            order = Spree::Order.create!
            order.associate_user!(user)

            create_shipments_from_params(params.delete(:shipments_attributes), 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)

            if completed_at = params.delete(:completed_at)
              order.completed_at = completed_at
              order.state = 'complete'
            end

            user_id = params.delete(:user_id)
            if user.has_spree_role? "admin"
              order.user_id = user_id
            end

            order.update_attributes!(params)

            # Really ensure that the order totals & states are correct
            order.updater.update_totals
            if order.completed?
              order.updater.update_payment_state
              order.updater.update_shipment_state
            end
            order.updater.persist_totals
            order.reload
          rescue Exception => e
            order.destroy if order && order.persisted?
            raise e.message
          end
        end

        def self.create_shipments_from_params(shipments_hash, order)
          return [] unless shipments_hash
          shipments_hash.each do |s|
            begin
              shipment = order.shipments.build
              shipment.tracking = s[:tracking]
              shipment.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)

                unit = shipment.inventory_units.build
                unit.order = order
                unit.variant_id = iu[:variant_id]
              end

              shipment.save!

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

            rescue Exception => e
              raise "Order import shipments: #{e.message} #{s}"
            end
          end
        end

        def self.create_line_items_from_params(line_items_hash, order)
          return {} unless line_items_hash
          line_items_hash.each_key do |k|
            begin
              line_item = line_items_hash[k]
              ensure_variant_id_from_params(line_item)

              extra_params = line_item.except(:variant_id, :quantity)
              line_item = order.contents.add(Spree::Variant.find(line_item[:variant_id]), line_item[:quantity])
              line_item.update_attributes(extra_params) unless extra_params.empty?
            rescue Exception => e
              raise "Order import line items: #{e.message} #{line_item}"
            end
          end
        end

        def self.create_adjustments_from_params(adjustments, order)
          return [] unless adjustments
          adjustments.each do |a|
            begin
              adjustment = order.adjustments.build(:amount => a[:amount].to_f,
                                                  :label => a[:label])
              adjustment.save!
              adjustment.close!
            rescue Exception => e
              raise "Order import adjustments: #{e.message} #{a}"
            end
          end
        end

        def self.create_payments_from_params(payments_hash, order)
          return [] unless payments_hash
          payments_hash.each do |p|
            begin
              payment = order.payments.build
              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]
              payment.payment_method = Spree::PaymentMethod.find_by_name!(p[:payment_method])
              payment.save!
            rescue Exception => e
              raise "Order import payments: #{e.message} #{p}"
            end
          end
        end

        def self.ensure_variant_id_from_params(hash)
          begin
            unless hash[:variant_id].present?
              hash[:variant_id] = Spree::Variant.active.find_by_sku!(hash[:sku]).id
              hash.delete(:sku)
            end
          rescue Exception => e
            raise "Ensure order import variant: #{e.message} #{hash}"
          end
        end

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

          begin
            search = {}
            if name = address[:country]['name']
              search[:name] = name<commit_msg>Add completed back as default state.<commit_after>module Spree
  module Core
    module Importer
      class Order

        def self.import(user, params)
          begin
            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]

            order = Spree::Order.create!
            order.associate_user!(user)

            create_shipments_from_params(params.delete(:shipments_attributes), 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)

            if completed_at = params.delete(:completed_at)
              order.completed_at = completed_at
              order.state = 'complete'
            end

            user_id = params.delete(:user_id)
            if user.has_spree_role? "admin"
              order.user_id = user_id
            end

            order.update_attributes!(params)

            # Really ensure that the order totals & states are correct
            order.updater.update_totals
            if order.completed?
              order.updater.update_payment_state
              order.updater.update_shipment_state
            end
            order.updater.persist_totals
            order.reload
          rescue Exception => e
            order.destroy if order && order.persisted?
            raise e.message
          end
        end

        def self.create_shipments_from_params(shipments_hash, order)
          return [] unless shipments_hash
          shipments_hash.each do |s|
            begin
              shipment = order.shipments.build
              shipment.tracking = s[:tracking]
              shipment.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)

                unit = shipment.inventory_units.build
                unit.order = order
                unit.variant_id = iu[:variant_id]
              end

              shipment.save!

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

            rescue Exception => e
              raise "Order import shipments: #{e.message} #{s}"
            end
          end
        end

        def self.create_line_items_from_params(line_items_hash, order)
          return {} unless line_items_hash
          line_items_hash.each_key do |k|
            begin
              line_item = line_items_hash[k]
              ensure_variant_id_from_params(line_item)

              extra_params = line_item.except(:variant_id, :quantity)
              line_item = order.contents.add(Spree::Variant.find(line_item[:variant_id]), line_item[:quantity])
              line_item.update_attributes(extra_params) unless extra_params.empty?
            rescue Exception => e
              raise "Order import line items: #{e.message} #{line_item}"
            end
          end
        end

        def self.create_adjustments_from_params(adjustments, order)
          return [] unless adjustments
          adjustments.each do |a|
            begin
              adjustment = order.adjustments.build(:amount => a[:amount].to_f,
                                                  :label => a[:label])
              adjustment.save!
              adjustment.close!
            rescue Exception => e
              raise "Order import adjustments: #{e.message} #{a}"
            end
          end
        end

        def self.create_payments_from_params(payments_hash, order)
          return [] unless payments_hash
          payments_hash.each do |p|
            begin
              payment = order.payments.build
              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.save!
            rescue Exception => e
              raise "Order import payments: #{e.message} #{p}"
            end
          end
        end

        def self.ensure_variant_id_from_params(hash)
          begin
            unless hash[:variant_id].present?
              hash[:variant_id] = Spree::Variant.active.find_by_sku!(hash[:sku]).id
              hash.delete(:sku)
            end
          rescue Exception => e
            raise "Ensure order import variant: #{e.message} #{hash}"
          end
        end

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

          begin
            search = {}
            if name = address[:country]['name']
              search[:name] = name
{'fraction_non_alphanumeric': 0.07758935083880379, 'fraction_numerical': 0.0, 'mean_word_length': 1.82633341922185, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4107752', 'n_tokens_mistral': 2823, 'n_tokens_neox': 2767, 'n_words': 577}