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?
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With