I'm struggling with customizing the transition of ...
# support
d
I'm struggling with customizing the transition of order states. I removed the checkout
delivery
state and now have the issue, that no shipments are getting created during checkout now. What I would like to do is somehow move the delivery state steps to the cart or address steps without having to duplicate the entire
Spree::Core::StateMachines::Order
module to avoid future update fiascos. I haven't found an answer by browsing through the guides / code. Is there an easy way to do this?
k
Assuming you want to remove the delivery step because you always have only one single choice, right?
e
what about using Spree::Event ? something like:
Copy code
# state machine decorator
after_transition do |order, transition|
  Spree::Event.fire "order_#{transition[:new_state}", order
end
then subscribe to those events
k
I was thinking that you could "hide" that step in the UI and just call
order.next!
programmatically so that the user doesn't know that a delivery step happened (the first shipment available will be selected)
d
Yes that's correct, I have only one choice.
@Edwin Cruz that was the original idea, although I'm not sure yet how I can achieve this with a decorator. Will play around a bit and report back.
@kennyadsl when I call
order.next!
in the console from the
address
state I still get transitioned to the
delivery
state, even with the
delivery
step disabled in the
checkout_flow
. Is that intended behaviour?
Ignore that, I can't replicate that anymore. Seems had some wrong setup code inheritance that caused the issue.
Ok, managed to extend the orders state machine as suggested by Edwin:
Copy code
module OrderDecorator
  def self.prepended(base)
    base.state_machine do
      after_transition do |order, transition|
        Spree::Event.fire "order_transitioned_to_#{<http://transition.to|transition.to>}", order: order
      end
    end
  end

  Spree::Order.prepend self
end
Now I'm just calling
order.next
during the
order_transitioned_to_delivery
event which works fine.
I think that's the most elegant solution as I can make use of the original delivery transition logic 👍
Now trying to figure out a way to hide the delivery step. Somehow having issues overwriting
Spree::CheckoutHelper#checkout_states
It works when I decorate
Spree::CheckoutController
and add a helper method for
checkout_states
. But no idea why it doesn't work by just decorating
Spree::CheckoutHelper
.
Copy code
module CheckoutControllerDecorator
  def self.prepended(base)
    base.helper_method :checkout_states
  end

  private

  def checkout_states
    @order.checkout_steps - ['delivery']
  end

  Spree::CheckoutController.prepend self
end
k
it's because
Spree::CheckoutHelper
is a module and not a class, so it's kinda useless to decorate it. You can just define a new helper in your own application and define a method with the same name into it, it should take precedence
d
Whoops. You're right. Weird thing is, I use a decorator for
Spree::ProductsHelper
and it works just fine 😅
k
you know, 🤷
d
Anyway, thanks a lot to both of you for pointing me into the right direction! 🙏
🙏 2