Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Skip Checkout Step but make associations

I try to modify my CheckoutSteps. Our Customers can't choose Shipping or Payment, since it's the same for all Orders. (Shipping Rate is 5€ except Orders above 100€, then its free). Payment is always Eruopean BankTransfer (which we notice the customer inside the order-email about).

So i removed state ":delivery" from my Order. The step is skipped but there is no assigment to shipping.

I struggle with assigning it automatically inside the Controller.

I see that the normal assigment is nested_attribute but i struggle to make these associations by myself. I tried to debug the Controllers and Models, but i can't find the right associations and find a way to set them manually. Params are

"order"=>{"shipments_attributes"=>{"0"=>{"selected_shipping_rate_id"=>"16", "id"=>"20"}}},

but i cant't find any code where i can make the Adjustments by myself. If we step into the checkout process,

Spree::Order.last.shipments
=> []

but as soon we enter the "delivery" page

Spree::Order.last.shipments
 => #<ActiveRecord::Associations::CollectionProxy [#<Spree::Shipment id: 28, tracking: nil, number: "H43150550345", cost: #<BigDecimal:ff44afc,'0.0',9(18)>, .............

so there is a shipping with costs 0.0

Spree::Order.last.shipments.first.cost.to_f => 0

but when we selec the shipping method at the webpage my shipping is calculated correctly.

Spree::Order.last.shipments.first.cost.to_f => 5.0

so my question is, how can i make this behavior programatically, without user_interaction?

i don't get whats going on and the docs aren't helping. Can anyone help me out?

//edit

played with some model functions and found create_proposed_shipments and shipments.update_amounts. ist that the "right way"? can't get it working

checkout_flow do
    go_to_state :address
    #go_to_state :delivery #kicked out
    go_to_state :payment, if: ->(order) { 
      order.create_proposed_shipments #create the shipping
      order.shipments.first.update_amounts #"accept" the shipping

      order.payment_required?      
    }
like image 243
Tim Kretschmer Avatar asked Feb 13 '23 11:02

Tim Kretschmer


1 Answers

Okay, i got it running perfectly, without touching the flow

First: Your order needs to decide if user can select shipping method (or our store does it)

Spree::Order.class_eval do
  def needs_delivery?
    #your logic goes here
    return false
  end
end

then we need the function that our order itself can select its shippingrate

Spree::Order.class_eval do        
  def select_default_shipping
    #clone_billing_address #uncomment if user just types in one address
    create_proposed_shipments #creates the shippings
    shipments.first.update_amounts #uses the first shippings
    update_totals #updates the order
  end
end

next step is to hijack the checkout_controller technicall after address it will always go into the delivery step, where we have our logic inside before_delivery

Spree::CheckoutController.class_eval do     
  def before_delivery
    if @order.needs_delivery?
      #user needs to select shipping, default behaviour
      @order.create_proposed_shipments
    else
      #we select the shipping for the user
      @order.select_default_shipping 
      @order.next #go to next step          
      #default logic for finalizing unless he can't select payment_method
      if @order.completed?
        session[:order_id] = nil
        flash.notice = Spree.t(:order_processed_successfully)
        flash[:commerce_tracking] = "nothing special"
        redirect_to completion_route
      else
        redirect_to checkout_state_path(@order.state)
      end
    end    
  end    
end

Costs me lot of times, hope that saves somebody else time.

like image 93
Tim Kretschmer Avatar answered Feb 23 '23 22:02

Tim Kretschmer