require 'ruleby'
class OrderController < ApplicationController
include Ruleby
before_filter :can_create_order?, :only => :create
before_filter :special_offer, :only => [:new, :create, :update_transporter]
before_filter :voucher, :only =>[:new, :create, :update_transporter]
#before_filter :shipping_methods, :only => :new
# Save in session address_invoice_id and address_delivery_id.
# Returns false if miss an address or if shipping_method is not validate by user, returns true else
def valid_shipment(action=true)
current_cart.options[:address_invoice_id] = params[:address_invoice_id] if params[:address_invoice_id]
current_cart.options[:address_delivery_id] = params[:address_delivery_id] if params[:address_delivery_id]
# AddressInvoice and AddressDelivery is obligatory for valid an order
if !current_cart.address_invoice || !current_cart.address_delivery
flash[:warning] = I18n.t('address', :count=>2).capitalize
redirect_to(:action => 'new')
return false
end
current_cart.options[:transporter_rule_id] = params[:transporter_rule_id] if params[:transporter_rule_id]
unless current_cart.transporter or current_cart.free_shipping
flash[:warning] = I18n.t('shipping_method',:count=>1).capitalize
redirect_to(:action => 'new')
return false
end
current_cart.save
redirect_to(:action => 'payment') if action
return true
end
# Payment integration
def payment
# TODO - include ActiveMerchant
#valid_shipment(false)
end
# Subscribe or edit user's informations
# Link render with partials of user's views
# session[:return_to] is initialize with {:controller => 'order', :action => 'new'}
def informations
session[:return_to] = {:controller => 'order', :action => 'new'}
end
# Final step, this action is accessible only if session[:order_confirmation] is true
def confirmation
redirect_to(:action => 'payment') unless session[:order_confirmation]
session[:order_confirmation] = nil
end
def new
return redirect_to(:action => 'informations') unless current_user
end
def create
valid = valid_shipment(false)
return false unless valid
@order = Order.from_cart(current_cart)
flash[:notice] = I18n.t('thank_you').capitalize
session[:order_confirmation] = true
redirect_to(:action => 'payment')
end
def add_address
render(:update) do |page|
page.replace_html("order", :partial => 'form_address')
end
end
def update_total
#special_offer
transporter_price = 0
if current_cart.transporter
offer_delivery = false
transporter_price = current_cart.transporter.variables.to_f unless offer_delivery and current_cart.transporter.nil?
end
order_total = current_cart.total + transporter_price
render(:update) do |page|
#page.replace_html('order_total_price', "#{order_total} #{current_currency.html}")
page.replace_html('transporter_price', "#{current_cart.total + transporter_price} #{current_currency.html}")
page.visual_effect :highlight, 'transporter_price'
page.visual_effect :highlight, 'order_total_price'
end
end
def update_transporter
@transporter_rule = TransporterRule.find_by_id(params[:id])
current_cart.options[:transporter_rule_id] = @transporter_rule.id if @transporter_rule
shipping_methods
update_total
end
# form to addresses
def back_addresses
render(:update) do |page|
page.replace_html("order", :partial => 'new')
page.replace_html("order_address_#{@address.class.to_s}", display_address(@address)) if @address
end
end
# Change select_tag address
def change_address
@address = Address.find_by_id(params[:id])
render(:update) do |page|
page.replace_html("order_address_#{@address.class.to_s}", display_address(@address))
page.visual_effect :highlight, "order_address_#{@address.class.to_s}"
end
end
# Go to form address
def update_address
@address = Address.find_by_id(params[:id])
render(:update) do |page|
page.replace_html("order", :partial => 'form_address', :locals => { :address => @address })
end
end
# Make or update Address and back to addresses
def create_address
@address = Address.find_by_id(params[:id])
if @address
@address.update_attributes(params[:address])
else
if current_user.addresses.size == 0
[AddressDelivery, AddressInvoice].each do |type|
current_user.addresses << type.create(params[:address])
end
else
#type = (params[:address][:kind] == 'AddressDelivery') ? AddressDelivery : AddressInvoice
current_user.addresses << AddressDelivery.create(params[:address])
current_user.addresses << AddressInvoice.create(params[:address])
end
end
back_addresses
end
private
def can_create_order?
if current_cart.nil? || current_cart.cart_items.empty?
flash[:error] = I18n.t('your_cart_is_empty').capitalize
redirect_to_home
end
end
# for an interface user-friendly...
def must_to_be_logged
unless logged_in?
if flash.nil?
flash[:warning] = I18n.t('you_must_be_connected').capitalize
else
flash[:error] = flash[:error]
flash[:user] = flash[:user]
end
redirect_to(:action => 'informations')
end
end
# check special offer rules
def special_offer
begin
engine :special_offer_engine do |e|
rule_builder = SpecialOffer.new(e)
rule_builder.cart = current_cart
@free_product_ids = []
rule_builder.free_product_ids = @free_product_ids
rule_builder.rules
current_cart.cart_items.each do |cart_product|
e.assert cart_product.product
end
e.assert current_cart
e.match
end
current_cart.options[:free_product_ids] = @free_product_ids
current_cart.options[:free_shipping] = current_cart.free_shipping
current_cart.save
rescue Exception
end
end
# check voucher rules
def voucher
begin
engine :voucher_engine do |e|
rule_builder = Voucher.new(e)
rule_builder.cart = current_cart
rule_builder.code = current_cart.options[:voucher_code]
rule_builder.free_product_ids = @free_product_ids
rule_builder.rules
current_cart.cart_items.each do |cart_product|
e.assert cart_product.product
end
e.assert current_cart
e.match
end
current_cart.options[:free_product_ids] = @free_product_ids
current_cart.save
rescue Exception
end
end
protected
def shipping_methods
@transporter_ids = []
begin
engine :transporter_engine do |e|
rule_builder = Transporter.new(e)
rule_builder.transporter_ids = @transporter_ids
rule_builder.rules
current_cart.cart_items.each do |cart_product|
e.assert cart_product.product
end
e.assert current_cart
e.match
end
rescue Exception
end
end
end