Skip to content
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

Merged
merged 7 commits into from
Apr 28, 2014
Merged

Use Finite State Machine #1426

merged 7 commits into from
Apr 28, 2014

Conversation

winzou
Copy link
Contributor

@winzou winzou commented Apr 24, 2014

Q A
Bug fix? no
New feature? yes
BC breaks? yes
Deprecations? no
Fixed tickets #1037
License MIT
Doc PR -

Placeholder PR for finite state machine future implementation in Sylius.

@winzou winzou self-assigned this Apr 24, 2014
@kayue
Copy link
Contributor

kayue commented Apr 24, 2014

@winzou Awesome! Can't wait!

@pjedrzejewski
Copy link
Member

@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.

@pjedrzejewski
Copy link
Member

We would just need a set of default transitions to be required. Used by Sylius internally.

@winzou
Copy link
Contributor Author

winzou commented Apr 24, 2014

@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:

  1. Deploy this system everywhere in sylius
  2. Enhance the way states are managed thanks to all events/listeners/callback we can do with finite
  3. Enhance again with some transition logging, etc.

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
Copy link
Member

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? :)

@pjedrzejewski
Copy link
Member

Awesome work, I really like the flexibility of Finite.

refunded:
type: final
transitions:
submit:
Copy link
Contributor

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?

@winzou
Copy link
Contributor Author

winzou commented Apr 25, 2014

Guys, this Finite thing is just crazy, I see endless possibilities with it!
For now I just replaced setState with StateMachine->apply, and I won't go much further in this PR. But in next steps, we will be able to rework most of our events with Finite events, it will be so powerfull!

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);
Copy link
Member

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?

Copy link
Member

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?

Copy link
Contributor Author

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 =)

Copy link
Contributor

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
.

Copy link
Member

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.

Copy link
Contributor

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 :)

Copy link
Contributor Author

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.

Copy link
Contributor

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

@winzou
Copy link
Contributor Author

winzou commented Apr 25, 2014

@pjedrzejewski do you know where is Travis?

edit: ok it was just incredibly slow to run

@winzou winzou changed the title [WIP] Use Finite State Machine Use Finite State Machine Apr 27, 2014
@winzou
Copy link
Contributor Author

winzou commented Apr 27, 2014

I stop here for this PR. Good to review guys.
Can't wait for the next PRs I have in mind!

- { resource: @SyliusShippingBundle/Resources/config/finite.yml }
- { resource: @SyliusOrderBundle/Resources/config/finite.yml }
- { resource: @SyliusInventoryBundle/Resources/config/finite.yml }
- { resource: @SyliusCoreBundle/Resources/config/finite.yml }
Copy link
Member

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.

pjedrzejewski pushed a commit that referenced this pull request Apr 28, 2014
@pjedrzejewski pjedrzejewski merged commit 0b1bbba into Sylius:master Apr 28, 2014
@pjedrzejewski
Copy link
Member

I'll move the files in separate PR. Thank you Alexandre, you are awesome. 👍

@winzou winzou deleted the state-machine branch April 29, 2014 01:28
@winzou
Copy link
Contributor Author

winzou commented Apr 29, 2014

Let's start the party now! 🎉

sylius_order_payment:
class: %sylius.model.order.class%
property_path: paymentState
graph: sylius_order_payment
Copy link
Contributor

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?

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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! 👍

tomzx pushed a commit to tomzx/Sylius that referenced this pull request May 9, 2014
to: partially_shipped
return:
from: [partially_shipped, shipped]
to: returned
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@winzou Missing transitions to change shipping state to cancelled. Do you want to include this change in #1447?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

pamil pushed a commit to pamil/Sylius that referenced this pull request May 7, 2019
pamil pushed a commit to pamil/Sylius that referenced this pull request May 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement Minor issues and PRs improving the current solutions (optimizations, typo fixes, etc.). RFC Discussions about potential changes or new features.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants