mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-25 20:46:48 +00:00
227 lines
6.9 KiB
Ruby
227 lines
6.9 KiB
Ruby
require 'spree/core/controller_helpers/order_decorator'
|
|
require 'spree/core/controller_helpers/auth_decorator'
|
|
|
|
module Spree
|
|
class OrdersController < Spree::StoreController
|
|
include OrderCyclesHelper
|
|
layout 'darkswarm'
|
|
|
|
ssl_required :show
|
|
|
|
before_filter :check_authorization
|
|
rescue_from ActiveRecord::RecordNotFound, :with => :render_404
|
|
helper 'spree/products', 'spree/orders'
|
|
|
|
respond_to :html
|
|
respond_to :json
|
|
|
|
before_filter :update_distribution, only: :update
|
|
before_filter :filter_order_params, only: :update
|
|
before_filter :enable_embedded_shopfront
|
|
|
|
prepend_before_filter :require_order_authentication, only: :show
|
|
prepend_before_filter :require_order_cycle, only: :edit
|
|
prepend_before_filter :require_distributor_chosen, only: :edit
|
|
before_filter :check_hub_ready_for_checkout, only: :edit
|
|
before_filter :check_at_least_one_line_item, only: :update
|
|
|
|
def show
|
|
@order = Spree::Order.find_by_number!(params[:id])
|
|
end
|
|
|
|
def empty
|
|
if @order = current_order
|
|
@order.empty!
|
|
end
|
|
|
|
redirect_to main_app.cart_path
|
|
end
|
|
|
|
def check_authorization
|
|
session[:access_token] ||= params[:token]
|
|
order = Spree::Order.find_by_number(params[:id]) || current_order
|
|
|
|
if order
|
|
authorize! :edit, order, session[:access_token]
|
|
else
|
|
authorize! :create, Spree::Order
|
|
end
|
|
end
|
|
|
|
# Patching to redirect to shop if order is empty
|
|
def edit
|
|
@order = current_order(true)
|
|
@insufficient_stock_lines = @order.insufficient_stock_lines
|
|
@unavailable_order_variants = OrderCycleDistributedVariants.
|
|
new(current_order_cycle, current_distributor).unavailable_order_variants(@order)
|
|
|
|
if @order.line_items.empty?
|
|
redirect_to main_app.shop_path
|
|
else
|
|
associate_user
|
|
|
|
if @order.insufficient_stock_lines.present? || @unavailable_order_variants.present?
|
|
flash[:error] = t("spree.orders.error_flash_for_unavailable_items")
|
|
end
|
|
end
|
|
end
|
|
|
|
def update
|
|
@insufficient_stock_lines = []
|
|
@order = order_to_update
|
|
unless @order
|
|
flash[:error] = t(:order_not_found)
|
|
redirect_to(root_path) && return
|
|
end
|
|
|
|
if @order.update_attributes(params[:order])
|
|
discard_empty_line_items
|
|
with_open_adjustments { update_totals_and_taxes }
|
|
|
|
if @order == current_order
|
|
fire_event('spree.order.contents_changed')
|
|
else
|
|
@order.update_distribution_charge!
|
|
end
|
|
|
|
respond_with(@order) do |format|
|
|
format.html do
|
|
if params.key?(:checkout)
|
|
@order.next_transition.run_callbacks if @order.cart?
|
|
redirect_to checkout_state_path(@order.checkout_steps.first)
|
|
elsif @order.complete?
|
|
redirect_to order_path(@order)
|
|
else
|
|
redirect_to main_app.cart_path
|
|
end
|
|
end
|
|
end
|
|
else
|
|
# Show order with original values, not newly entered ones
|
|
@insufficient_stock_lines = @order.insufficient_stock_lines
|
|
@order.line_items(true)
|
|
respond_with(@order)
|
|
end
|
|
end
|
|
|
|
def update_distribution
|
|
@order = current_order(true)
|
|
|
|
if params[:commit] == 'Choose Hub'
|
|
distributor = Enterprise.is_distributor.find params[:order][:distributor_id]
|
|
@order.set_distributor! distributor
|
|
|
|
flash[:notice] = I18n.t(:order_choosing_hub_notice)
|
|
redirect_to request.referer
|
|
|
|
elsif params[:commit] == 'Choose Order Cycle'
|
|
@order.empty! # empty cart
|
|
order_cycle = OrderCycle.active.find params[:order][:order_cycle_id]
|
|
@order.set_order_cycle! order_cycle
|
|
|
|
flash[:notice] = I18n.t(:order_choosing_hub_notice)
|
|
redirect_to request.referer
|
|
end
|
|
end
|
|
|
|
def filter_order_params
|
|
if params[:order] && params[:order][:line_items_attributes]
|
|
params[:order][:line_items_attributes] =
|
|
remove_missing_line_items(params[:order][:line_items_attributes])
|
|
end
|
|
end
|
|
|
|
def remove_missing_line_items(attrs)
|
|
attrs.select do |_i, line_item|
|
|
Spree::LineItem.find_by_id(line_item[:id])
|
|
end
|
|
end
|
|
|
|
def clear
|
|
@order = current_order(true)
|
|
@order.empty!
|
|
@order.set_order_cycle! nil
|
|
redirect_to main_app.enterprise_path(@order.distributor.id)
|
|
end
|
|
|
|
def order_cycle_expired
|
|
@order_cycle = OrderCycle.find session[:expired_order_cycle_id]
|
|
end
|
|
|
|
def cancel
|
|
@order = Spree::Order.find_by_number!(params[:id])
|
|
authorize! :cancel, @order
|
|
|
|
if @order.cancel
|
|
flash[:success] = I18n.t(:orders_your_order_has_been_cancelled)
|
|
else
|
|
flash[:error] = I18n.t(:orders_could_not_cancel)
|
|
end
|
|
redirect_to request.referer || order_path(@order)
|
|
end
|
|
|
|
private
|
|
|
|
# Updates the various denormalized total attributes of the order and
|
|
# recalculates the shipment taxes
|
|
def update_totals_and_taxes
|
|
@order.updater.update_totals
|
|
@order.shipment.ensure_correct_adjustment_with_included_tax if @order.shipment
|
|
end
|
|
|
|
# Sets the adjustments to open to perform the block's action and restores
|
|
# their state to whatever the they had. Note that it does not change any new
|
|
# adjustments that might get created in the yielded block.
|
|
def with_open_adjustments
|
|
previous_states = @order.adjustments.each_with_object({}) do |adjustment, hash|
|
|
hash[adjustment.id] = adjustment.state
|
|
end
|
|
@order.adjustments.each(&:open)
|
|
|
|
yield
|
|
|
|
@order.adjustments.each do |adjustment|
|
|
previous_state = previous_states[adjustment.id]
|
|
adjustment.update_attribute(:state, previous_state) if previous_state
|
|
end
|
|
end
|
|
|
|
def discard_empty_line_items
|
|
@order.line_items = @order.line_items.select { |li| li.quantity > 0 }
|
|
end
|
|
|
|
def require_order_authentication
|
|
return if session[:access_token] || params[:token] || spree_current_user
|
|
|
|
flash[:error] = I18n.t("spree.orders.edit.login_to_view_order")
|
|
require_login_then_redirect_to request.env['PATH_INFO']
|
|
end
|
|
|
|
def order_to_update
|
|
return @order_to_update if defined? @order_to_update
|
|
return @order_to_update = current_order unless params[:id]
|
|
@order_to_update = changeable_order_from_number
|
|
end
|
|
|
|
# If a specific order is requested, return it if it is COMPLETE and
|
|
# changes are allowed and the user has access. Return nil if not.
|
|
def changeable_order_from_number
|
|
order = Spree::Order.complete.find_by_number(params[:id])
|
|
return nil unless order.andand.changes_allowed? && can?(:update, order)
|
|
order
|
|
end
|
|
|
|
def check_at_least_one_line_item
|
|
return unless order_to_update.andand.complete?
|
|
|
|
items = params[:order][:line_items_attributes]
|
|
.andand.select{ |_k, attrs| attrs["quantity"].to_i > 0 }
|
|
|
|
if items.empty?
|
|
flash[:error] = I18n.t(:orders_cannot_remove_the_final_item)
|
|
redirect_to order_path(order_to_update)
|
|
end
|
|
end
|
|
end
|
|
end
|