1414use Exception ;
1515use Psr \Log \LoggerInterface ;
1616use Ratepay \RpayPayments \Components \RatepayApi \Dto \OrderOperationData ;
17+ use Ratepay \RpayPayments \Components \RatepayApi \Service \Request \AbstractModifyRequest ;
1718use Ratepay \RpayPayments \Components \RatepayApi \Service \Request \PaymentCancelService ;
1819use Ratepay \RpayPayments \Components \RatepayApi \Service \Request \PaymentDeliverService ;
1920use Ratepay \RpayPayments \Components \RatepayApi \Service \Request \PaymentReturnService ;
2526use Shopware \Core \Checkout \Order \Aggregate \OrderDelivery \OrderDeliveryDefinition ;
2627use Shopware \Core \Checkout \Order \Aggregate \OrderDelivery \OrderDeliveryEntity ;
2728use Shopware \Core \Checkout \Order \Aggregate \OrderDelivery \OrderDeliveryStates ;
29+ use Shopware \Core \Checkout \Order \Aggregate \OrderTransaction \OrderTransactionDefinition ;
30+ use Shopware \Core \Checkout \Order \Aggregate \OrderTransaction \OrderTransactionEntity ;
31+ use Shopware \Core \Checkout \Order \Aggregate \OrderTransaction \OrderTransactionStates ;
2832use Shopware \Core \Checkout \Order \OrderEntity ;
2933use Shopware \Core \Framework \DataAbstractionLayer \EntityRepository ;
3034use Shopware \Core \Framework \DataAbstractionLayer \Search \Criteria ;
@@ -38,6 +42,7 @@ class TransitionSubscriber implements EventSubscriberInterface
3842
3943 public function __construct (
4044 private readonly EntityRepository $ orderDeliveryRepository ,
45+ private readonly EntityRepository $ orderTransactionRepository ,
4146 private readonly EntityRepository $ orderRepository ,
4247 private readonly PluginConfigService $ configService ,
4348 private readonly PaymentDeliverService $ paymentDeliverService ,
@@ -56,7 +61,60 @@ public static function getSubscribedEvents(): array
5661
5762 public function onTransition (StateMachineTransitionEvent $ event ): void
5863 {
59- if ($ event ->getEntityName () !== OrderDeliveryDefinition::ENTITY_NAME || !$ this ->configService ->isAutoOperationBasedOnDeliveryStatusEnabled ()) {
64+ if ($ event ->getEntityName () === OrderTransactionDefinition::ENTITY_NAME ) {
65+ $ this ->onTransactionStatusTransition ($ event );
66+ } else if ($ event ->getEntityName () === OrderDeliveryDefinition::ENTITY_NAME ) {
67+ $ this ->onDeliveryStatusTransition ($ event );
68+ }
69+ }
70+
71+ protected function onTransactionStatusTransition (StateMachineTransitionEvent $ event ): void
72+ {
73+ if ($ this ->configService ->getCaptureTrigger () !== 'pay ' ) {
74+ return ;
75+ }
76+
77+ /** @var ArrayStruct|null $struct */
78+ $ struct = $ event ->getContext ()->getExtension ('ratepay ' );
79+ if ($ struct ?->get(self ::PREVENT_BIDIRECTIONALITY ) === true ) {
80+ return ;
81+ }
82+
83+ /** @var OrderTransactionEntity $orderTransaction */
84+ $ orderTransaction = $ this ->orderTransactionRepository ->search (new Criteria ([$ event ->getEntityId ()]), $ event ->getContext ())->first ();
85+ /** @var OrderEntity $order */
86+ $ order = $ this ->orderRepository ->search (CriteriaHelper::getCriteriaForOrder ($ orderTransaction ->getOrderId ()), $ event ->getContext ())->first ();
87+
88+ if (!MethodHelper::isRatepayOrder ($ order )) {
89+ return ;
90+ }
91+
92+ $ ratepayData = $ order ->getExtension (OrderExtension::EXTENSION_NAME );
93+
94+ if (!$ ratepayData instanceof RatepayOrderDataEntity) {
95+ $ this ->logger ->warning ('Error during bidirectionality: No Ratepay Data was found. ' , [
96+ 'order ' => $ order ->getId (),
97+ 'orderNumber ' => $ order ->getOrderNumber (),
98+ ]);
99+ return ;
100+ }
101+
102+ switch ($ event ->getToPlace ()->getTechnicalName ()) {
103+ case OrderTransactionStates::STATE_PAID :
104+ $ operation = OrderOperationData::OPERATION_DELIVER ;
105+ $ service = $ this ->paymentDeliverService ;
106+ break ;
107+ default :
108+ // do nothing
109+ return ;
110+ }
111+
112+ $ this ->performOperation ($ event , $ order , $ operation , $ service , $ ratepayData );
113+ }
114+
115+ protected function onDeliveryStatusTransition (StateMachineTransitionEvent $ event ): void
116+ {
117+ if (!$ this ->configService ->isAutoOperationBasedOnDeliveryStatusEnabled ()) {
60118 return ;
61119 }
62120
@@ -79,30 +137,47 @@ public function onTransition(StateMachineTransitionEvent $event): void
79137
80138 if (!$ ratepayData instanceof RatepayOrderDataEntity) {
81139 $ this ->logger ->warning ('Error during bidirectionality: No Ratepay Data was found. ' , [
82- 'order ' => $ order ->getId (),
140+ 'order ' => $ order ->getId (),
83141 'orderNumber ' => $ order ->getOrderNumber (),
84142 ]);
85143 return ;
86144 }
87145
88146 switch ($ event ->getToPlace ()->getTechnicalName ()) {
89147 case OrderDeliveryStates::STATE_SHIPPED :
148+ if ($ this ->configService ->getCaptureTrigger () !== 'deliver ' ) {
149+ // do nothing
150+ return ;
151+ }
90152 $ operation = OrderOperationData::OPERATION_DELIVER ;
91- $ service = $ this ->paymentDeliverService ;
153+ $ service = $ this ->paymentDeliverService ;
92154 break ;
93155 case OrderDeliveryStates::STATE_CANCELLED :
156+ if (!$ this ->configService ->isTransactionRefundsOnDeliveryStatusChange ()) {
157+ // do nothing
158+ return ;
159+ }
94160 $ operation = OrderOperationData::OPERATION_CANCEL ;
95- $ service = $ this ->paymentCancelService ;
161+ $ service = $ this ->paymentCancelService ;
96162 break ;
97163 case OrderDeliveryStates::STATE_RETURNED :
164+ if (!$ this ->configService ->isTransactionRefundsOnDeliveryStatusChange ()) {
165+ // do nothing
166+ return ;
167+ }
98168 $ operation = OrderOperationData::OPERATION_RETURN ;
99- $ service = $ this ->paymentReturnService ;
169+ $ service = $ this ->paymentReturnService ;
100170 break ;
101171 default :
102172 // do nothing
103173 return ;
104174 }
175+ $ this ->performOperation ($ event , $ order , $ operation , $ service , $ ratepayData );
176+
177+ }
105178
179+ protected function performOperation (StateMachineTransitionEvent $ event , OrderEntity $ order , string $ operation , AbstractModifyRequest $ service , RatepayOrderDataEntity $ ratepayData ): void
180+ {
106181 // we need this to prevent endless recursion if update-delivery-status is enabled.
107182 // this should never happen, because shopware can not change the status to the actual status again and so this subscriber should never called again.
108183 $ event ->getContext ()->addExtension ('ratepay ' , new ArrayStruct ([
@@ -114,17 +189,17 @@ public function onTransition(StateMachineTransitionEvent $event): void
114189 $ response = $ service ->doRequest ($ orderOperationData );
115190 if (!$ response ->getResponse ()->isSuccessful ()) {
116191 $ this ->logger ->error ('Error during bidirectionality. (Exception: ' . $ response ->getResponse ()->getReasonMessage () . ') ' , [
117- 'order ' => $ order ->getId (),
118- 'transactionId ' => $ ratepayData ->getTransactionId (),
119- 'orderNumber ' => $ order ->getOrderNumber (),
192+ 'order ' => $ order ->getId (),
193+ 'transactionId ' => $ ratepayData ->getTransactionId (),
194+ 'orderNumber ' => $ order ->getOrderNumber (),
120195 'itemsToProcess ' => $ orderOperationData ->getItems (),
121196 ]);
122197 }
123198 } catch (Exception $ exception ) {
124199 $ this ->logger ->critical ('Exception during bidirectionality. (Exception: ' . $ exception ->getMessage () . ') ' , [
125- 'order ' => $ order ->getId (),
126- 'transactionId ' => $ ratepayData ->getTransactionId (),
127- 'orderNumber ' => $ order ->getOrderNumber (),
200+ 'order ' => $ order ->getId (),
201+ 'transactionId ' => $ ratepayData ->getTransactionId (),
202+ 'orderNumber ' => $ order ->getOrderNumber (),
128203 'itemsToProcess ' => $ orderOperationData ->getItems (),
129204 ]);
130205 }
0 commit comments