vendor/extensions/shipping/app/controllers/shipments_controller.rb in spree-0.5.1 vs vendor/extensions/shipping/app/controllers/shipments_controller.rb in spree-0.6.0

- old
+ new

@@ -1,84 +1,96 @@ -class ShipmentsController < Admin::BaseController +class ShipmentsController < Spree::BaseController before_filter :login_required - before_filter :state_check - before_filter :check_existing, :only => :new - before_filter :load_data, :only => [:new, :edit] - layout 'application' + before_filter :load_data, :except => :country_changed + before_filter :load_shipping_methods, :only => :edit + before_filter :prevent_orphaned_shipments, :only => [:new, :create] resource_controller - belongs_to :order - create.response do |wants| - wants.html do - next_step + belongs_to :order + actions :new, :create + + # override r_c defaults so we can handle special presenter logic + def create + build_object + load_object + state_check("shipment") + unless @shipment_presenter.valid? + render :action => "new" and return end + @shipment = @order.shipments.new(:address => @shipment_presenter.address) + # choose first shipping method just as a starting point (user can change in next step) + @shipment.shipping_method = @shipment.shipping_methods.first + @shipment.save + @order.next! + redirect_to edit_order_shipment_url(@order, @shipment) end - - create.before do - # add the specified shipping method to the shipment, before it's saved. - @shipment.update_attribute(:shipping_method, ShippingMethod.find(params[:method_id])) - end - update.response do |wants| - wants.html do - next_step + # override r_c defaults so we can handle special presenter logic + def update + if params[:method_id] + state_check("shipping_method") + shipping_method = ShippingMethod.find(params[:method_id]) + @shipment.update_attribute(:shipping_method, shipping_method) + calculator = @shipment.shipping_method.shipping_calculator.constantize.new + @order.update_attribute(:ship_amount, calculator.calculate_shipping(@shipment)) + @order.next! end + redirect_to checkout_order_url(@order) + end + + def country_changed + country_id = params[:shipment_presenter][:address_country_id] + @states = State.find_all_by_country_id(country_id, :order => 'name') + render :partial => "shared/states", :locals => {:presenter_type => "shipment"} end - - update.after do - @shipment.update_attribute(:shipping_method, ShippingMethod.find(params[:method_id])) - end - def fail + private + def build_object + @object ||= end_of_association_chain.send parent? ? :build : :new, object_params + if params[:shipment_presenter] + @shipment_presenter = ShipmentPresenter.new(params[:shipment_presenter]) + else + @shipment_presenter = ShipmentPresenter.new(:address => Address.new(:country_id => @selected_country_id)) + end end - private - def build_object - find_shipment - end - - def object - return find_shipment if param.blank? - @object ||= end_of_association_chain.find(param) unless param.nil? - end - - def find_shipment - @object = parent_object.shipments.first - @object ||= Shipment.new(:order => parent_object) - end - - def check_existing + def load_data load_object - redirect_to edit_order_shipment_url(@order, @shipment) unless @order.shipments.empty? + @selected_country_id = params[:shipment_presenter][:address_country_id].to_i if params.has_key?('shipment_presenter') + @selected_country_id ||= Spree::Config[:default_country_id] + @states = State.find_all_by_country_id(@selected_country_id, :order => 'name') + @countries = @order.shipping_countries end - def next_step - @order.next! - redirect_to checkout_order_url(@order) - end - - def state_check - load_object + def state_check(state) if @order.checkout_complete + # if order has already completed user shouldn't be able to edit shipping information redirect_to checkout_order_url(@order) and return + else + # reset the state to the appropriate value (in case user has hit back button from some other state) + @order.update_attribute("state", state) unless @order.state == state end - # set the state to shipment (in case user has hit back button from some other state) - @order.update_attribute(:state, "shipment") end - - def load_data - @shipping_methods = @order.shipping_methods - # check that the price of each method is available - if we encounter an error, we can inform the user gracefully - # (instead of having the next view just crash when asked the price) + + def prevent_orphaned_shipments + # right now we assume only one shipment and we're going to clear out any existing (abandoned) shipments + # in case user has edited cart in the meantime (or perhaps they have started the checkout process over) + @order.shipments.clear + end + + def load_shipping_methods + @shipping_methods = @shipment.shipping_methods + # check that the rate for each method is available - if we encounter an error, we can inform the user gracefully + # (instead of having the next view just crash when asked the rate) begin @shipping_methods.each do |shipping_method| - rate = shipping_method.calculate_shipping(@order) - @default_method ||= shipping_method unless rate.nil? + rate = shipping_method.calculate_shipping(@shipment) end rescue Spree::ShippingError => se # We cannot recover from this error (for now.) Send back to the previous step (and alert the user) flash[:error] = se.message redirect_to fatal_shipping_order_url(@order) end end + end \ No newline at end of file