-
-
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
The Events - Checkout Revolution #899
Conversation
@@ -278,7 +278,8 @@ | |||
</service> | |||
<service id="sylius.listener.order_user" class="%sylius.listener.order_user.class%"> | |||
<argument type="service" id="security.context" /> | |||
<tag name="kernel.event_listener" event="sylius_checkout_security.completed" method="setOrderUser" /> | |||
<tag name="kernel.event_listener" event="sylius_checkout_security.pre_complete" method="setOrderUser" /> | |||
<tag name="kernel.event_listener" event="sylius.cart.initialize" method="setOrderUser" /> |
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.
👍
Basically we have two types of events related to order.
Perhaps we should add another group of events which are more specific ... like "paid", "shipped", "returned", "cancelled"? What do you think @winzou? |
I was thinking like you:
Creation events and post-creation events go in an |
I think we should do this event changes together with the order creation in backend. Even most basic one, this will allow us to clearly separate the processing logic from checkout itself. (because there are several other ways to create orders, in my apps I've been importing them, generating and so on... and processing it properly was a bit harder than it should be with our cleanly decoupled processors) |
Uhm sorry I don't get your point. Once you import all cart data (order + order items + address + shipping method + payment method), you just need to dispatch each event one by one. On what rock did you fall with these decoupled processors? |
and dispatch order.pre_pay from where shipments are being prepared
I will stop here for this PR. I've updated the description to say what I've done.
Feedbacks welcome on this PR :) |
$payment = $event->getSubject(); | ||
|
||
if (!$payment instanceof PaymentInterface) { | ||
throw new \InvalidArgumentException(sprintf( |
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.
Maybe instead of such long checks, introduce new exception that do this in __construct()
instead? I.e.:
class InvalidEventArgumentException extends \InvalidArgumentException
{
public function __construct($listener, $passed, $expected)
{
$passed = is_object($passed) ? get_class($passed) : gettype($passed);
parent::__construct(sprintf('%s listener requires event subject to be instance of "%s", %s given.', $listener, $expected, $passed));
}
}
thrown new InvalidEventArgumentException('Order payment', $payment, 'Sylius\Bundle\PaymentsBundle\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.
Will fix in another PR.
For many of them, it will be naturaly fixed by custom Event class.
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, I'd prefer to do this with the custom event classes. I'm working on this for the resource refactoring PR.
Uhm regarding:
Do we want to consider an order placed but not paid as "completed"? We actually need to do some stuffs (set inventory units as sold, decrease stock, etc) even if order is not paid at the end, just to make sure we don't over use stocks, etc. But then we wait for the order to be paid before preparing shipments... I think we should consider the status "completed" when the order is placed. But in that case we need to handle properly the end of life when order is never paid, etc. (need to release inventory units). What do you think? |
@winzou When you say order is "completed", did you mean marking order as Just for your reference, we did the following modifications to order and inventory unit to make Sylius fit our workflow:
(please note order status is a new property we added to Sylius's order model) |
@kayue thanks for your doc, it's helpful we should have done that way earlier! Note that the order status already exists in sylius, defined in Here is a draft for Sylius: https://github.com/Sylius/Sylius/wiki/Status Please @Sylius feel free to improve it. The |
@stloyd I don't agree with your change of payment status from "new" to "processing". As long as we don't have any feedback from the payment gateway, we cannot say it's "processing". "New" seems better to me, and we keep "processing" for cases where payments are not instants (check validation, status not "OK" from paypal but "waiting", etc.). What do you think? |
@winzou I'm in favor of "new" as well, processing could be used when we're waiting for notification from paypal etc. |
@winzou @pjedrzejewski Agree, missed that there is one point missing where that |
@stloyd I've added a "payment cancelled/failed" workflow. The idea is not to drop the cart, as the visitor may want to re-trigger a payment, or change the cart before starting a new payment. |
@winzou Thanks for the wiki, super useful, exactly what I was looking for :) So are we introducing new order status? I can only found the following status
|
@kayue yes, the attribute already exists but its content needs to be completed. |
@winzou I'll have a final look today for sure, thank you so much for pushing this forward. |
@pjedrzejewski by |
* @var string | ||
*/ | ||
protected $identifier; | ||
|
||
public function __construct(Api $api, OrderRepositoryInterface $orderRepository, EventDispatcher $eventDispatcher, $identifier) | ||
public function __construct(Api $api, OrderRepositoryInterface $orderRepository, EventDispatcher $eventDispatcher, EntityManager $em, $identifier) |
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.
As we're not using anything ORM specific here, let's typehint ObjectManager
interface.
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.
agree
@pjedrzejewski correct, I must have been a bit lazy on this commit! Changed to |
* @var string | ||
*/ | ||
protected $identifier; | ||
|
||
public function __construct(Api $api, OrderRepositoryInterface $orderRepository, EventDispatcher $eventDispatcher, $identifier) | ||
public function __construct(Api $api, OrderRepositoryInterface $orderRepository, EventDispatcher $eventDispatcher, ObjectManager $objectManager, $identifier) |
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.
Please change also EventDispatcher
to use EventDispatcherInterface
to match other constructors.
@pjedrzejewski green and need to have it merged :) |
All this cool stuff, is it going to documented anywhere? |
I'm keeping it up to date: But sure documentation will be at the end the reference |
Dammit, am I really the only one annoyed by the new UI? It looks kinda cool, but unreadable so far ... The travis 5.4 failed for random reason. I am having final look and will merge in next few minutes. (most likely) |
* Constructor. | ||
* | ||
* @param PaymentProcessorInterface $paymentProcessor | ||
*/ | ||
public function __construct(PaymentProcessorInterface $paymentProcessor) | ||
public function __construct(PaymentProcessorInterface $paymentProcessor, EntityRepository $orderRepository, EventDispatcherInterface $dispatcher) |
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 be OrderRepositoryInterface
instead of EntityRepository.
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'll change it in another PR. Let's not delay this anymore.
The Events - Checkout Revolution
Great work Alexandre, thank you very much. I was expecting that our whole order flow will be clarifying when we move closer to basic feature-set. I'm happy. |
@pjedrzejewski no you are not the only one.. everything is too big |
The Events - Checkout Revolution
The Events - Checkout Revolution
The aim of this PR is to get these checkout events under control.
Better separation of checkout process / order creation events.
CompleteOrderListener
inOrderBundle
to do the$order->complete()
instead of having this inFinalizeStep
OrderPaymentListener
which listens topayment.pre_state_change
. So that when the state of a payment changes tocomplete
, this method is called and dispatches again theorder.pre_pay
event. (currently, nothing is done!)OrderStateListener
listen at every order post creation events, so that it updates its state accordingly (priority -100 to be called after all order modification)payment.pre_state
andpayment.post_state
so that modifications are persisted in db. This is done in allNotifyAction
inPayumBundle