-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use Finite State Machine #1426
Use Finite State Machine #1426
Conversation
@winzou Awesome! Can't wait! |
@winzou Thank for starting this, does Finite support yml configuration? If no, I was thinking about implementing our own service for defining the state machine configuration, which could be easily overridden by the developer. |
We would just need a set of default transitions to be required. Used by Sylius internally. |
@pjedrzejewski @kayue here is how it looks like for now. Do you think of a better place / better way of loading finite machine configurations? It needs to be in the bundles as each bundle with states will depend on finite. I would even like to put it in components. What do you think? This is very basic implementation. Next steps are:
Btw this PR needs yohang/Finite#29 to be merged before passing tests :) |
@@ -0,0 +1,35 @@ | |||
finite_finite: | |||
sylius_payment: | |||
class: Sylius\Component\Payment\Model\PaymentInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why interface here, instead of class parameter like for the order? :)
Awesome work, I really like the flexibility of Finite. |
refunded: | ||
type: final | ||
transitions: | ||
submit: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we call it create
?
Guys, this Finite thing is just crazy, I see endless possibilities with it! |
throw new \InvalidArgumentException(sprintf('Unexpected inventory state "%s".', $state)); | ||
} | ||
$this->factory->get($unit, 'sylius_inventory_unit')->apply($transitionName); | ||
$this->factory->get($unit, 'sylius_shipping_unit')->apply($transitionName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The interface name implemented by InventoryUnit is ShippingItemInterface
, I think we should change sylius_shipping_unit
to sylius_shipping_item
, what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, maybe we should check if the given transition is available with the can
method? Or we should leave it and allow the exception to occur?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes for sylius_shipping_item
, don't know how this unit
fell here.
Regarding the check, this is indeed something we need to decide. But anyway, this particular listener will be so useless thanks to some events on transition!
Btw, side question, is this ShippingItem::getState
usefull? I see it just reflects the parent shipment state... The only state that could differ between Shipment and one of its ShipmentItem is returned
. But is it something we want to track in the ShippingState
? It is already tracked in the InventoryUnitState
and this seems more logical there. I'd like to delete it =)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need extra check. All we can do is to throw another
exception..
I believe the can
method is more useful when dealing with UI, it can tell
us what buttons we should show.
On Fri, Apr 25, 2014 at 3:49 PM, Alexandre Bacco
notifications@github.comwrote:
In src/Sylius/Bundle/CoreBundle/EventListener/InventoryUnitListener.php:
$unit->setShippingState(ShipmentInterface::STATE_ONHOLD);
- break;
case $unit::STATE_SOLD:
$unit->setShippingState(ShipmentInterface::STATE_READY);
- break;
case $unit::STATE_RETURNED:
$unit->setShippingState(ShipmentInterface::STATE_RETURNED);
- break;
default:
throw new \InvalidArgumentException(sprintf('Unexpected inventory state "%s".', $state));
}
$this->factory->get($unit, 'sylius_inventory_unit')->apply($transitionName);
$this->factory->get($unit, 'sylius_shipping_unit')->apply($transitionName);
Yes for sylius_shipping_item, don't know how this unit fell here.
Regarding the check, this is indeed something we need to decide. But
anyway, this particular listener will be so useless thanks to some events
on transition!Btw, side question, is this ShippingItem::getState usefull? I see it just
reflects the parent shipment state... The only state that could differ
between Shipment and one of its ShipmentItem is returned. But is it
something we want to track in the ShippingState? It is already tracked in
the InventoryUnitState and this seems more logical there. I'd like to
delete it =)—
Reply to this email directly or view it on GitHubhttps://github.com//pull/1426/files#r11986029
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@winzou Remember that it is Sylius implementation where InventoryUnit and ShipmentItem is the same thing. Shipping bundle can be used standalone, as well as Inventory. The inventory states indicates the availability of the particular product stock item, and the shipping state of unit represents what is happening regarding the shipment - is it ready to be packed, sometimes just one item is returned etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks really good. I am wondering if this could help streamlining processes. At the moment for example its not easy to keep track of all the possibile event sequences and listener actions when executing the checkout flow. Say I need to implement a different checkout flow ( for example "one click checkout" ) but still need to keep all events consistent with sylius architecture.
I need to go through all checkout steps, and write down a little graph of all events to make sure I don't miss something when I 'rearrange' the flow.
It would be nice if there was some class that could be responsable for handling this graph so I can look at it and see all possible graph path along with the events they trigger.
Do you think finite's transition functions could be a good place to centralize event triggering in a more readable way? (Maybe you have already been implying this and I missed it)
Sorry if I am getting a little OT here, but so far in extending Sylius for my own purposes understanding and keeping track of all events has been the most time consuming task :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will help you to track to object-centered workflow. This is where most of the business is done.
But it won't change all the checkout events, which are linked to the checkout workflow and not really to the object itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@winzou Yes I understand and it looks very good.
I guess you could consider the checkout process as an object as well :D, thats what I like about the flow bundle, processes become objects that have steps ( transitions and states ).
But maybe I am overcomplicating things.
Probably once the events are documented that will be enough to help people modifying the checkout process to their needs.
Thanks for your reply and sorry for the OT
@pjedrzejewski do you know where is Travis? edit: ok it was just incredibly slow to run |
I stop here for this PR. Good to review guys. |
- { resource: @SyliusShippingBundle/Resources/config/finite.yml } | ||
- { resource: @SyliusOrderBundle/Resources/config/finite.yml } | ||
- { resource: @SyliusInventoryBundle/Resources/config/finite.yml } | ||
- { resource: @SyliusCoreBundle/Resources/config/finite.yml } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should be moved to main.yml
file in CoreBundle.
Use Finite State Machine
I'll move the files in separate PR. Thank you Alexandre, you are awesome. 👍 |
Let's start the party now! 🎉 |
sylius_order_payment: | ||
class: %sylius.model.order.class% | ||
property_path: paymentState | ||
graph: sylius_order_payment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@winzou Are we missing OrderPaymentTransitions::GRAPH
?
Also should we use state machine in StateResolver
?
Sylius/src/Sylius/Component/Core/OrderProcessing/StateResolver.php
Lines 28 to 31 in 1f76020
public function resolvePaymentState(OrderInterface $order) | |
{ | |
$order->setPaymentState($order->getPayment()->getState()); | |
} |
Or even better, we can remove these StateResolver
and rely on the events triggered by state machine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes we are missing OrderPaymentTransitions::GRAPH as well as OrderShippingTransitions.
StateResolver is about to disappear. It's not using state machine right now indeed. I hope I can soon have the correct listeners to get rid of state resolver. Not ready yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, just want to confirm, thanks! 👍
Use Finite State Machine
to: partially_shipped | ||
return: | ||
from: [partially_shipped, shipped] | ||
to: returned |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Use Finite State Machine
Use Finite State Machine
Placeholder PR for finite state machine future implementation in Sylius.