Kind of related to the above - but what is the cor...
# support
t
Kind of related to the above - but what is the correct way to handle digital-only goods in checkout flow? It seems like the Solidus state machine requires a shipping address to be present before an order can transition into the
:delivery
state. I know that stock locations can be marked as
fulfillable
or not to help support this, but I don't see any exemptions in the checkout state machine looking for that property.
c
https://edgeguides.solidus.io/cookbook/redefining-checkout-steps You can override the checkout flow using that DSL. If you have a way to detect that the entire order is digital, you can skip shipping.
t
Thanks - that's very helpful. It looks like other parts of the flow (like selecting shipping rates) may not work fully if there is no address present, though.
c
If you set the No Shipping profile up on the digital products, it shouldn’t be an issue.
t
Oh? How do you do that? I'm not sure I follow what "No shipping profile" means.
c
In your admin, create a “No Shipping” or “Shipping not required” shipping category, then set that on the product:
t
So I've done that - but in the estimator, it fails to find shipping rates for that category.
c
Did you add the
remove_checkout_step
above? You shouldn’t even see the shipment method if so.
Here’s how checkout looks for me w/digital:
t
Hmm - I didn't remove the checkout step, but as a temporary thing I updated the
Order.ensure_shipping_address
to return true if the order is all digital.
Which checkout step are you removing -
address
or
delivery
?
c
Throw this in a decorator and try checkout again. If you’re mixing digital/physical products, you’ll want to add a method to determine if you need shipping.
Copy code
module Spree
  module OrderDecorator
    Spree::Order.class_eval do
      remove_checkout_step :delivery
    end
  end
end
Just delivery
t
Interesting - let me give that a try. Thanks, Chris!
👍🏻 1
Hmm - it doesn't look like
remove_checkout_step
supports an options block. Is there something I can read a bit further about the pattern of conditionally removing the step?
Or would it basically look like...
Copy code
remove_checkout_step :delivery
insert_checkout_step :delivery { if: :my_method }
It looks like
remove
followed by
insert
seems to work. So something like this:
Copy code
base.remove_checkout_step :delivery
base.insert_checkout_step :delivery, {
  before: :payment, if: -> (order) { order.requires_shipping? }
}
c
yep
was just typing that!