<commit_before>require 'open_food_network/address_finder'

class CheckoutController < Spree::StoreController
  layout 'darkswarm'

  include CheckoutHelper
  include OrderCyclesHelper
  include EnterprisesHelper

  ssl_required

  # We need pessimistic locking to avoid race conditions.
  # Otherwise we fail on duplicate indexes or end up with negative stock.
  prepend_around_filter CurrentOrderLocker, only: :update

  prepend_before_filter :check_hub_ready_for_checkout
  prepend_before_filter :check_order_cycle_expiry
  prepend_before_filter :require_order_cycle
  prepend_before_filter :require_distributor_chosen

  before_filter :load_order

  before_filter :ensure_order_not_completed
  before_filter :ensure_checkout_allowed
  before_filter :ensure_sufficient_stock_lines

  before_filter :associate_user
  before_filter :check_authorization
  before_filter :enable_embedded_shopfront

  helper 'spree/orders'

  rescue_from Spree::Core::GatewayError, with: :rescue_from_spree_gateway_error

  def edit
    # This is only required because of spree_paypal_express. If we implement
    # a version of paypal that uses this controller, and more specifically
    # the #update_failed method, then we can remove this call
    RestartCheckout.new(@order).call
  end

  def update
    shipping_method_id = object_params.delete(:shipping_method_id)

    return update_failed unless @order.update_attributes(object_params)

    fire_event('spree.checkout.update')

    checkout_workflow(shipping_method_id)
  rescue Spree::Core::GatewayError => e
    rescue_from_spree_gateway_error(e)
  rescue StandardError => e
    Bugsnag.notify(e)
    flash[:error] = I18n.t("checkout.failed")
    update_failed
  end

  def checkout_workflow(shipping_method_id)
    while @order.state != "complete"
      if @order.state == "payment"
        return if redirect_to_paypal_express_form_if_needed
      end

      if @order.state == "delivery"
        @order.select_shipping_method(shipping_method_id)
      end

      next if advance_order_state(@order)

      flash[:error] = if @order.errors.present?
                        @order.errors.full_messages.to_sentence
                      else
                        t(:payment_processing_failed)
                      end
      return update_failed
    end

    if @order.completed?
      update_succeeded
    else
      update_failed
    end
  end

  def update_succeeded
    set_default_bill_address
    set_default_ship_address

    ResetOrderService.new(self, current_order).call
    session[:access_token] = current_order.token

    respond_to_update_succeeded
  end

  def respond_to_update_succeeded
    flash[:notice] = t(:order_processed_successfully)
    respond_to do |format|
      format.html do
        respond_with(@order, location: order_path(@order))
      end
      format.json do
        render json: { path: order_path(@order) }, status: :ok
      end
    end
  end

  # Clears the cached order. Required for #current_order to return a new order
  # to serve as cart. See https://github.com/spree/spree/blob/1-3-stable/core/lib/spree/core/controller_helpers/order.rb#L14
  # for details.
  def expire_current_order
    session[:order_id] = nil<commit_msg>Extracted two methods from checkout_workflow to fix rubocop issues<commit_after>require 'open_food_network/address_finder'

class CheckoutController < Spree::StoreController
  layout 'darkswarm'

  include CheckoutHelper
  include OrderCyclesHelper
  include EnterprisesHelper

  ssl_required

  # We need pessimistic locking to avoid race conditions.
  # Otherwise we fail on duplicate indexes or end up with negative stock.
  prepend_around_filter CurrentOrderLocker, only: :update

  prepend_before_filter :check_hub_ready_for_checkout
  prepend_before_filter :check_order_cycle_expiry
  prepend_before_filter :require_order_cycle
  prepend_before_filter :require_distributor_chosen

  before_filter :load_order

  before_filter :ensure_order_not_completed
  before_filter :ensure_checkout_allowed
  before_filter :ensure_sufficient_stock_lines

  before_filter :associate_user
  before_filter :check_authorization
  before_filter :enable_embedded_shopfront

  helper 'spree/orders'

  rescue_from Spree::Core::GatewayError, with: :rescue_from_spree_gateway_error

  def edit
    # This is only required because of spree_paypal_express. If we implement
    # a version of paypal that uses this controller, and more specifically
    # the #update_failed method, then we can remove this call
    RestartCheckout.new(@order).call
  end

  def update
    shipping_method_id = object_params.delete(:shipping_method_id)

    return update_failed unless @order.update_attributes(object_params)

    fire_event('spree.checkout.update')

    checkout_workflow(shipping_method_id)
  rescue Spree::Core::GatewayError => e
    rescue_from_spree_gateway_error(e)
  rescue StandardError => e
    Bugsnag.notify(e)
    flash[:error] = I18n.t("checkout.failed")
    update_failed
  end

  def checkout_workflow(shipping_method_id)
    while @order.state != "complete"
      if @order.state == "payment"
        return if redirect_to_paypal_express_form_if_needed
      end

      @order.select_shipping_method(shipping_method_id) if @order.state == "delivery"

      next if advance_order_state(@order)

      flash[:error] = order_workflow_error
      return update_failed
    end

    update_result
  end

  def update_result
    if @order.completed?
      update_succeeded
    else
      update_failed
    end
  end

  def update_succeeded
    set_default_bill_address
    set_default_ship_address

    ResetOrderService.new(self, current_order).call
    session[:access_token] = current_order.token

    respond_to_update_succeeded
  end

  def respond_to_update_succeeded
    flash[:notice] = t(:order_processed_successfully)
    respond_to do |format|
      format.html do
        respond_with(@order, location: order_path(@order))
      end
      format.json do
        render json: { path: order_path(@order) }, status: :ok
      end
    end
  end

  def order_workflow_error
    if @order.errors.present?
      @order.errors.full_messages.to_sentence
    else
      t(:payment_processing_failed)
    end
  end

  # Clears the cached order. Required for #current_order to return a new order
  # to serve as cart. See https://github.com/spree/spree/blob/1-3-stable/core/lib/spree/core/controller_helpers/order.rb#L14
  # for details.
  def expire_current_order
    session[:order_id] = nil
{'fraction_non_alphanumeric': 0.06277888905985536, 'fraction_numerical': 0.0018464379135251577, 'mean_word_length': 3.887218045112782, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1994895', 'n_tokens_mistral': 2047, 'n_tokens_neox': 1949, 'n_words': 448}