OrderStateMachine::groupByOrderAndState()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 13
nc 4
nop 3
dl 0
loc 21
rs 9.8333
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
namespace Spryker\Zed\Oms\Business\OrderStateMachine;
9
10
use DateTime;
11
use Exception;
12
use Generated\Shared\Transfer\MessageTransfer;
13
use Generated\Shared\Transfer\OmsCheckConditionsQueryCriteriaTransfer;
14
use Generated\Shared\Transfer\OmsEventTriggerResponseTransfer;
15
use Generated\Shared\Transfer\ReservationRequestTransfer;
16
use LogicException;
17
use Orm\Zed\Oms\Persistence\SpyOmsOrderItemState;
18
use Orm\Zed\Oms\Persistence\SpyOmsOrderItemStateQuery;
19
use Orm\Zed\Sales\Persistence\SpySalesOrderItem;
20
use Spryker\Shared\ErrorHandler\ErrorLogger;
21
use Spryker\Zed\Oms\Business\Notifier\EventTriggeredNotifierInterface;
22
use Spryker\Zed\Oms\Business\Process\ProcessInterface;
23
use Spryker\Zed\Oms\Business\Process\StateInterface;
24
use Spryker\Zed\Oms\Business\Util\ReadOnlyArrayObject;
25
use Spryker\Zed\Oms\Business\Util\ReservationInterface;
26
use Spryker\Zed\Oms\Business\Util\TransitionLogInterface;
27
use Spryker\Zed\Oms\Communication\Plugin\Oms\Command\CommandCollection;
28
use Spryker\Zed\Oms\Communication\Plugin\Oms\Command\CommandCollectionInterface;
29
use Spryker\Zed\Oms\Communication\Plugin\Oms\Condition\ConditionCollection;
30
use Spryker\Zed\Oms\Dependency\Plugin\Command\CommandByItemInterface;
31
use Spryker\Zed\Oms\Dependency\Plugin\Command\CommandByOrderInterface;
32
use Spryker\Zed\Oms\Dependency\Plugin\Command\CommandInterface;
33
use Spryker\Zed\Oms\Dependency\Plugin\Condition\ConditionCollectionInterface;
34
use Spryker\Zed\Oms\OmsConfig;
35
use Spryker\Zed\Oms\Persistence\OmsQueryContainerInterface;
36
use Spryker\Zed\Propel\Persistence\BatchProcessor\ActiveRecordBatchProcessorTrait;
37
use Spryker\Zed\PropelOrm\Business\Transaction\DatabaseTransactionHandlerTrait;
38
39
class OrderStateMachine implements OrderStateMachineInterface
40
{
41
    use DatabaseTransactionHandlerTrait;
0 ignored issues
show
Deprecated Code introduced by
The trait Spryker\Zed\PropelOrm\Bu...TransactionHandlerTrait has been deprecated: Use {@link \Spryker\Zed\Kernel\Persistence\EntityManager\TransactionTrait} instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

41
    use /** @scrutinizer ignore-deprecated */ DatabaseTransactionHandlerTrait;

This trait has been deprecated. The supplier of the trait has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the trait will be removed and what other trait to use instead.

Loading history...
42
    use ActiveRecordBatchProcessorTrait;
43
44
    /**
45
     * @var string
46
     */
47
    public const BY_ITEM = 'byItem';
48
49
    /**
50
     * @var string
51
     */
52
    public const BY_ORDER = 'byOrder';
53
54
    /**
55
     * @var int
56
     */
57
    public const MAX_EVENT_REPEATS = 10;
58
59
    /**
60
     * @deprecated Not in use anymore, will be removed in the next major.
61
     *
62
     * @var int
63
     */
64
    public const MAX_ON_ENTER = 50;
65
66
    /**
67
     * @var array
68
     */
69
    protected $eventCounter = [];
70
71
    /**
72
     * @var array
73
     */
74
    protected $returnData = [];
75
76
    /**
77
     * @var array
78
     */
79
    protected $processBuffer = [];
80
81
    /**
82
     * @var array
83
     */
84
    protected $states = [];
85
86
    /**
87
     * @var \Spryker\Zed\Oms\Persistence\OmsQueryContainerInterface
88
     */
89
    protected $queryContainer;
90
91
    /**
92
     * @var \Spryker\Zed\Oms\Business\OrderStateMachine\TimeoutInterface
93
     */
94
    protected $timeout;
95
96
    /**
97
     * @var \Spryker\Zed\Oms\Business\OrderStateMachine\BuilderInterface
98
     */
99
    protected $builder;
100
101
    /**
102
     * @var \Spryker\Zed\Oms\Business\Util\TransitionLogInterface
103
     */
104
    protected $transitionLog;
105
106
    /**
107
     * @var \Spryker\Zed\Oms\Business\Util\ReadOnlyArrayObject
108
     */
109
    protected $activeProcesses;
110
111
    /**
112
     * @var \Spryker\Zed\Oms\Dependency\Plugin\Condition\ConditionCollectionInterface
113
     */
114
    protected $conditions;
115
116
    /**
117
     * @var \Spryker\Zed\Oms\Dependency\Plugin\Command\CommandCollectionInterface
118
     */
119
    protected $commands;
120
121
    /**
122
     * @var \Spryker\Zed\Oms\Business\Util\ReservationInterface
123
     */
124
    protected $reservation;
125
126
    /**
127
     * @var \Spryker\Zed\Oms\OmsConfig
128
     */
129
    protected $omsConfig;
130
131
    /**
132
     * @var \Spryker\Zed\Oms\Business\Notifier\EventTriggeredNotifierInterface
133
     */
134
    protected EventTriggeredNotifierInterface $eventTriggeredNotifier;
135
136
    /**
137
     * @param \Spryker\Zed\Oms\Persistence\OmsQueryContainerInterface $queryContainer
138
     * @param \Spryker\Zed\Oms\Business\OrderStateMachine\BuilderInterface $builder
139
     * @param \Spryker\Zed\Oms\Business\Util\TransitionLogInterface $transitionLog
140
     * @param \Spryker\Zed\Oms\Business\OrderStateMachine\TimeoutInterface $timeout
141
     * @param \Spryker\Zed\Oms\Business\Util\ReadOnlyArrayObject $activeProcesses
142
     * @param \Spryker\Zed\Oms\Dependency\Plugin\Condition\ConditionCollectionInterface|array $conditions
143
     * @param \Spryker\Zed\Oms\Dependency\Plugin\Command\CommandCollectionInterface|array $commands
144
     * @param \Spryker\Zed\Oms\Business\Util\ReservationInterface $reservation
145
     * @param \Spryker\Zed\Oms\OmsConfig $omsConfig
146
     * @param \Spryker\Zed\Oms\Business\Notifier\EventTriggeredNotifierInterface $eventTriggeredNotifier
147
     */
148
    public function __construct(
149
        OmsQueryContainerInterface $queryContainer,
150
        BuilderInterface $builder,
151
        TransitionLogInterface $transitionLog,
152
        TimeoutInterface $timeout,
153
        ReadOnlyArrayObject $activeProcesses,
154
        $conditions,
155
        $commands,
156
        ReservationInterface $reservation,
157
        OmsConfig $omsConfig,
158
        EventTriggeredNotifierInterface $eventTriggeredNotifier
159
    ) {
160
        $this->queryContainer = $queryContainer;
161
        $this->builder = $builder;
162
        $this->transitionLog = $transitionLog;
163
        $this->timeout = $timeout;
164
        $this->activeProcesses = $activeProcesses;
165
        $this->setConditions($conditions);
166
        $this->setCommands($commands);
167
        $this->reservation = $reservation;
168
        $this->omsConfig = $omsConfig;
169
        $this->eventTriggeredNotifier = $eventTriggeredNotifier;
170
    }
171
172
    /**
173
     * Converts array to collection for BC
174
     *
175
     * @param \Spryker\Zed\Oms\Dependency\Plugin\Condition\ConditionCollectionInterface|array $conditions
176
     *
177
     * @return void
178
     */
179
    protected function setConditions($conditions)
180
    {
181
        if ($conditions instanceof ConditionCollectionInterface) {
182
            $this->conditions = $conditions;
183
184
            return;
185
        }
186
187
        $conditionCollection = new ConditionCollection();
188
        foreach ($conditions as $name => $condition) {
189
            $conditionCollection->add($condition, $name);
190
        }
191
192
        $this->conditions = $conditionCollection;
193
    }
194
195
    /**
196
     * Converts array to collection for BC
197
     *
198
     * @param \Spryker\Zed\Oms\Dependency\Plugin\Command\CommandCollectionInterface|array $commands
199
     *
200
     * @return void
201
     */
202
    protected function setCommands($commands)
203
    {
204
        if ($commands instanceof CommandCollectionInterface) {
205
            $this->commands = $commands;
206
207
            return;
208
        }
209
210
        $commandCollection = new CommandCollection();
211
        foreach ($commands as $name => $command) {
212
            $commandCollection->add($command, $name);
213
        }
214
215
        $this->commands = $commandCollection;
216
    }
217
218
    /**
219
     * @param string $eventId
220
     * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItems
221
     * @param \Spryker\Zed\Oms\Business\Util\ReadOnlyArrayObject|array $data
222
     *
223
     * @return array
224
     */
225
    public function triggerEvent($eventId, array $orderItems, $data)
226
    {
227
        $data = $this->makeDataReadOnly($data);
228
229
        $processes = $this->getProcesses($orderItems);
230
231
        $orderItems = $this->filterAffectedOrderItems($eventId, $orderItems, $processes);
232
233
        $log = $this->initTransitionLog($orderItems);
234
235
        $orderGroup = $this->groupByOrderAndState($eventId, $orderItems, $processes);
236
        $sourceStateBuffer = [];
237
238
        $allProcessedOrderItems = [];
239
        foreach ($orderGroup as $orderGroupKey => $groupedOrderItems) {
240
            if (!$this->checkOrderGroupForEventRepetitions($eventId, $orderGroupKey)) {
241
                continue;
242
            }
243
244
            $this->logSourceState($groupedOrderItems, $log);
245
246
            $processedOrderItems = $this->runCommand($eventId, $groupedOrderItems, $processes, $data, $log);
247
            if ($processedOrderItems === null) {
248
                continue;
249
            }
250
            $sourceStateBuffer = $this->updateStateByEvent($eventId, $processedOrderItems, $sourceStateBuffer, $log);
251
            $this->saveOrderItems($processedOrderItems, $log, $processes, $sourceStateBuffer);
252
253
            $currentOrderItemEntity = current($processedOrderItems);
254
255
            if ($currentOrderItemEntity) {
256
                $orderEntity = $currentOrderItemEntity->getOrder();
257
258
                $this->eventTriggeredNotifier->notifyOmsEventTriggeredListeners($eventId, $processedOrderItems, $orderEntity, $data);
259
            }
260
261
            $allProcessedOrderItems = array_merge($allProcessedOrderItems, $processedOrderItems);
262
        }
263
264
        $orderItemsWithOnEnterEvent = $this->filterItemsWithOnEnterEvent($allProcessedOrderItems, $processes, $sourceStateBuffer);
265
266
        $log->saveAll();
267
268
        $this->triggerOnEnterEvents($orderItemsWithOnEnterEvent, $data);
269
270
        return $this->returnData;
271
    }
272
273
    /**
274
     * @param string $eventId
275
     * @param array $orderItemIds
276
     * @param array<string, mixed> $data
277
     *
278
     * @return array
279
     */
280
    public function triggerEventForOrderItems($eventId, array $orderItemIds, $data)
281
    {
282
        $orderItems = $this->queryContainer
283
            ->querySalesOrderItems($orderItemIds)
284
            ->find()
285
            ->getData();
286
287
        return $this->triggerEvent($eventId, $orderItems, $data);
288
    }
289
290
    /**
291
     * @param string $eventId
292
     * @param int $orderItemId
293
     * @param array<string, mixed> $data
294
     *
295
     * @return array|null
296
     */
297
    public function triggerEventForOneOrderItem($eventId, $orderItemId, $data)
298
    {
299
        $orderItems = $this->queryContainer
300
            ->querySalesOrderItems([$orderItemId])
301
            ->find()
302
            ->getData();
303
304
        return $this->triggerEvent($eventId, $orderItems, $data);
305
    }
306
307
    /**
308
     * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItems
309
     * @param array<string, mixed> $data
310
     *
311
     * @return array
312
     */
313
    public function triggerEventForNewItem(array $orderItems, $data)
314
    {
315
        $data = $this->makeDataReadOnly($data);
316
        $sourceStateBuffer = [];
317
        $processes = $this->getProcesses($orderItems);
318
319
        $orderItemsWithOnEnterEvent = $this->filterItemsWithOnEnterEvent($orderItems, $processes, $sourceStateBuffer);
320
        $this->triggerOnEnterEvents($orderItemsWithOnEnterEvent, $data);
321
322
        $orderItemsWithTimeoutEvent = $this->filterItemsWithTimeoutEvent($orderItems, $processes);
323
        $this->saveTimeoutEvents($orderItemsWithTimeoutEvent);
324
325
        return $this->returnData;
326
    }
327
328
    /**
329
     * @param array<int> $orderItemIds
330
     * @param array<string, mixed> $data
331
     *
332
     * @return array
333
     */
334
    public function triggerEventForNewOrderItems(array $orderItemIds, $data)
335
    {
336
        $orderItems = $this->queryContainer
337
            ->querySalesOrderItems($orderItemIds)
338
            ->find()
339
            ->getData();
340
341
        return $this->triggerEventForNewItem($orderItems, $data);
342
    }
343
344
    /**
345
     * @param array $logContext
346
     * @param \Generated\Shared\Transfer\OmsCheckConditionsQueryCriteriaTransfer|null $omsCheckConditionsQueryCriteriaTransfer
347
     *
348
     * @return int
349
     */
350
    public function checkConditions(array $logContext = [], ?OmsCheckConditionsQueryCriteriaTransfer $omsCheckConditionsQueryCriteriaTransfer = null)
351
    {
352
        $affectedOrderItems = 0;
353
        foreach ($this->activeProcesses as $processName) {
354
            $process = $this->builder->createProcess($processName);
355
            $orderStateMachine = clone $this;
356
            $affectedOrderItems += $orderStateMachine->checkConditionsForProcess($process, $omsCheckConditionsQueryCriteriaTransfer);
357
        }
358
359
        return $affectedOrderItems;
360
    }
361
362
    /**
363
     * @param \Spryker\Zed\Oms\Business\Process\ProcessInterface $process
364
     * @param \Generated\Shared\Transfer\OmsCheckConditionsQueryCriteriaTransfer|null $omsCheckConditionsQueryCriteriaTransfer
365
     *
366
     * @return int
367
     */
368
    protected function checkConditionsForProcess(ProcessInterface $process, ?OmsCheckConditionsQueryCriteriaTransfer $omsCheckConditionsQueryCriteriaTransfer)
369
    {
370
        $transitions = $process->getAllTransitionsWithoutEvent();
371
372
        $stateToTransitionsMap = $this->createStateToTransitionMap($transitions);
373
374
        $orderItems = $this->getOrderItemsByState(array_keys($stateToTransitionsMap), $process, $omsCheckConditionsQueryCriteriaTransfer);
375
376
        $countAffectedItems = count($orderItems);
377
378
        if (count($orderItems) === 0) {
379
            return 0;
380
        }
381
382
        $log = $this->initTransitionLog($orderItems);
383
384
        $sourceStateBuffer = $this->updateStateByTransition($stateToTransitionsMap, $orderItems, [], $log);
385
386
        $processes = [$process->getName() => $process];
387
388
        $this->saveOrderItems($orderItems, $log, $processes, $sourceStateBuffer);
389
390
        $orderItemsWithOnEnterEvent = $this->filterItemsWithOnEnterEvent($orderItems, $processes, $sourceStateBuffer);
391
392
        $data = $this->makeDataReadOnly([]);
393
394
        $this->triggerOnEnterEvents($orderItemsWithOnEnterEvent, $data);
395
396
        return $countAffectedItems;
397
    }
398
399
    /**
400
     * @param array<\Spryker\Zed\Oms\Business\Process\TransitionInterface> $transitions
401
     * @param \Orm\Zed\Sales\Persistence\SpySalesOrderItem $orderItem
402
     * @param \Spryker\Zed\Oms\Business\Process\StateInterface $sourceState
403
     * @param \Spryker\Zed\Oms\Business\Util\TransitionLogInterface $log
404
     *
405
     * @throws \Exception
406
     *
407
     * @return \Spryker\Zed\Oms\Business\Process\StateInterface
408
     */
409
    protected function checkCondition(array $transitions, $orderItem, StateInterface $sourceState, TransitionLogInterface $log)
410
    {
411
        $possibleTransitions = [];
412
413
        foreach ($transitions as $transition) {
414
            if ($transition->hasCondition()) {
415
                $conditionString = $transition->getCondition();
416
                $conditionModel = $this->getCondition($conditionString);
417
418
                try {
419
                    $conditionCheck = $conditionModel->check($orderItem);
420
                } catch (Exception $e) {
421
                    $log->setIsError(true);
422
                    $log->setErrorMessage(get_class($e) . ' - ' . $e->getMessage());
423
                    $log->saveAll();
424
425
                    throw $e;
426
                }
427
428
                if ($conditionCheck === true) {
429
                    array_unshift($possibleTransitions, $transition);
430
                }
431
432
                $log->addCondition($orderItem, $conditionModel);
433
            } else {
434
                array_push($possibleTransitions, $transition);
435
            }
436
        }
437
438
        if (count($possibleTransitions) > 0) {
439
            /** @var \Spryker\Zed\Oms\Business\Process\TransitionInterface $selectedTransition */
440
            $selectedTransition = array_shift($possibleTransitions);
441
            $targetState = $selectedTransition->getTarget();
442
        } else {
443
            $targetState = $sourceState;
444
        }
445
446
        return $targetState;
447
    }
448
449
    /**
450
     * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItems
451
     *
452
     * @return array<\Spryker\Zed\Oms\Business\Process\ProcessInterface>
453
     */
454
    protected function getProcesses(array $orderItems)
455
    {
456
        $processes = [];
457
        foreach ($orderItems as $orderItem) {
458
            $processName = $orderItem->getProcess()->getName();
459
            if (array_key_exists($processName, $processes) === false) {
460
                $processes[$processName] = $this->builder->createProcess($processName);
461
            }
462
        }
463
464
        return $processes;
465
    }
466
467
    /**
468
     * Filters out all items that are not affected by the current event
469
     *
470
     * @param string $eventId
471
     * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItems
472
     * @param array<\Spryker\Zed\Oms\Business\Process\ProcessInterface> $processes
473
     *
474
     * @return array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem>
475
     */
476
    protected function filterAffectedOrderItems($eventId, array $orderItems, $processes)
477
    {
478
        $orderItemsFiltered = [];
479
        foreach ($orderItems as $orderItem) {
480
            $stateName = $orderItem->getState()->getName();
481
            $processName = $orderItem->getProcess()->getName();
482
            $process = $processes[$processName];
483
484
            $state = $process->getStateFromAllProcesses($stateName);
485
486
            if ($state->hasEvent($eventId)) {
487
                $orderItemsFiltered[] = $orderItem;
488
            }
489
        }
490
491
        return $orderItemsFiltered;
492
    }
493
494
    /**
495
     * @param string $eventId
496
     * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItems
497
     * @param array<\Spryker\Zed\Oms\Business\Process\ProcessInterface> $processes
498
     *
499
     * @return array
500
     */
501
    protected function groupByOrderAndState($eventId, array $orderItems, $processes)
502
    {
503
        $orderEventGroup = [];
504
        foreach ($orderItems as $orderItem) {
505
            $stateId = $orderItem->getState()->getName();
506
            $processId = $orderItem->getProcess()->getName();
507
            $process = $processes[$processId];
508
            $orderId = $orderItem->getOrder()->getIdSalesOrder();
509
510
            $state = $process->getStateFromAllProcesses($stateId);
511
512
            if ($state->hasEvent($eventId)) {
513
                $key = $orderId . '-' . $stateId;
514
                if (!isset($orderEventGroup[$key])) {
515
                    $orderEventGroup[$key] = [];
516
                }
517
                $orderEventGroup[$key][] = $orderItem;
518
            }
519
        }
520
521
        return $orderEventGroup;
522
    }
523
524
    /**
525
     * @param \Spryker\Zed\Oms\Dependency\Plugin\Command\CommandInterface $command
526
     *
527
     * @throws \LogicException
528
     *
529
     * @return string
530
     */
531
    protected function getCommandType(CommandInterface $command)
532
    {
533
        if ($command instanceof CommandByOrderInterface) {
534
            return static::BY_ORDER;
535
        }
536
        if ($command instanceof CommandByItemInterface) {
537
            return static::BY_ITEM;
538
        }
539
540
        throw new LogicException('Unknown type of command: ' . get_class($command));
541
    }
542
543
    /**
544
     * Specification:
545
     * - Performs commands on items
546
     * - All passing items should have the same event available
547
     * - For CommandByOrderInterface the command will be taken from the first order item
548
     *
549
     * @param string $eventId
550
     * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItems
551
     * @param array<\Spryker\Zed\Oms\Business\Process\ProcessInterface> $processes
552
     * @param \Spryker\Zed\Oms\Business\Util\ReadOnlyArrayObject $data
553
     * @param \Spryker\Zed\Oms\Business\Util\TransitionLogInterface $log
554
     *
555
     * @throws \LogicException
556
     *
557
     * @return array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem>|null
558
     */
559
    protected function runCommand($eventId, array $orderItems, array $processes, ReadOnlyArrayObject $data, TransitionLogInterface $log)
560
    {
561
        $processedOrderItems = [];
562
563
        /** @var \Orm\Zed\Sales\Persistence\SpySalesOrderItem $currentOrderItemEntity */
564
        $currentOrderItemEntity = current($orderItems);
565
        $orderEntity = $currentOrderItemEntity->getOrder();
566
567
        foreach ($orderItems as $orderItemEntity) {
568
            $stateId = $orderItemEntity->getState()->getName();
569
            $processId = $orderItemEntity->getProcess()->getName();
570
            $process = $processes[$processId];
571
            $state = $process->getStateFromAllProcesses($stateId);
572
            $event = $state->getEvent($eventId);
573
574
            $log->setEvent($event);
575
576
            if (!$event->hasCommand()) {
577
                $processedOrderItems[] = $orderItemEntity;
578
579
                continue;
580
            }
581
582
            /** @var \Spryker\Zed\Oms\Dependency\Plugin\Command\CommandByOrderInterface|\Spryker\Zed\Oms\Dependency\Plugin\Command\CommandByItemInterface|\Spryker\Zed\Oms\Dependency\Plugin\Command\CommandInterface $command */
583
            $command = $this->getCommand($event->getCommand());
584
            $type = $this->getCommandType($command);
585
586
            $log->addCommand($orderItemEntity, $command);
587
588
            $omsEventTriggerResponseTransfer = (new OmsEventTriggerResponseTransfer())->setIsSuccessful(true);
589
            $this->returnData[OmsConfig::OMS_EVENT_TRIGGER_RESPONSE] = $omsEventTriggerResponseTransfer;
590
591
            try {
592
                if ($command instanceof CommandByOrderInterface) {
593
                    $returnData = $command->run($orderItems, $orderEntity, $data);
594
                    if (is_array($returnData)) {
595
                        $this->returnData = array_merge($this->returnData, $returnData);
596
                    }
597
598
                    return $orderItems;
599
                }
600
601
                if ($command instanceof CommandByItemInterface) {
602
                    $returnData = $command->run($orderItemEntity, $data);
603
                    $this->returnData = array_merge($this->returnData, $returnData);
604
                    $processedOrderItems[] = $orderItemEntity;
605
                } else {
606
                    throw new LogicException('Unknown type of command: ' . get_class($command));
607
                }
608
            } catch (Exception $e) {
609
                $log->setIsError(true);
610
                $log->setErrorMessage(get_class($e) . ' - ' . $e->getMessage());
611
                $log->saveAll();
612
613
                ErrorLogger::getInstance()->log($e);
614
615
                $errorMessage = $e->getMessage() ?: 'Currently not executable.';
616
                $omsEventTriggerResponseTransfer
617
                    ->setIsSuccessful(false)
618
                    ->addMessage(
619
                        (new MessageTransfer())->setValue($errorMessage),
620
                    );
621
                $this->returnData[OmsConfig::OMS_EVENT_TRIGGER_RESPONSE] = $omsEventTriggerResponseTransfer;
622
623
                if ($type === static::BY_ORDER) {
624
                    return null; // intercept the processing of a grouped order items for the current order state
625
                }
626
            }
627
        }
628
629
        return $processedOrderItems;
630
    }
631
632
    /**
633
     * @param string $eventId
634
     * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItems
635
     * @param array $sourceStateBuffer
636
     * @param \Spryker\Zed\Oms\Business\Util\TransitionLogInterface $log
637
     *
638
     * @return array
639
     */
640
    protected function updateStateByEvent($eventId, array $orderItems, array $sourceStateBuffer, TransitionLogInterface $log)
641
    {
642
        $targetStateMap = [];
643
        foreach ($orderItems as $i => $orderItem) {
644
            $stateId = $orderItem->getState()->getName();
645
            $sourceStateBuffer[$orderItem->getIdSalesOrderItem()] = $stateId;
646
647
            $process = $this->builder->createProcess($orderItem->getProcess()->getName());
648
            $sourceState = $process->getStateFromAllProcesses($stateId);
649
650
            $log->addSourceState($orderItem, $sourceState->getName());
651
652
            $targetState = $sourceState;
653
            if ($eventId && $sourceState->hasEvent($eventId)) {
654
                $transitions = $sourceState->getEvent($eventId)->getTransitionsBySource($sourceState);
655
                $targetState = $this->checkCondition($transitions, $orderItem, $sourceState, $log);
656
                $log->addTargetState($orderItem, $targetState->getName());
657
            }
658
659
            $targetStateMap[$i] = $targetState->getName();
660
        }
661
662
        foreach ($orderItems as $i => $orderItem) {
663
            $this->setState($orderItems[$i], $targetStateMap[$i]);
664
        }
665
666
        return $sourceStateBuffer;
667
    }
668
669
    /**
670
     * @param array $stateToTransitionsMap
671
     * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItems
672
     * @param array $sourceStateBuffer
673
     * @param \Spryker\Zed\Oms\Business\Util\TransitionLogInterface $log
674
     *
675
     * @return array
676
     */
677
    protected function updateStateByTransition($stateToTransitionsMap, array $orderItems, array $sourceStateBuffer, TransitionLogInterface $log)
678
    {
679
        $targetStateMap = [];
680
        foreach ($orderItems as $i => $orderItem) {
681
            $stateId = $orderItem->getState()->getName();
682
            $sourceStateBuffer[$orderItem->getIdSalesOrderItem()] = $stateId;
683
            $process = $this->builder->createProcess($orderItem->getProcess()->getName());
684
            $sourceState = $process->getStateFromAllProcesses($stateId);
685
686
            $log->addSourceState($orderItem, $sourceState->getName());
687
688
            $transitions = $stateToTransitionsMap[$orderItem->getState()->getName()];
689
690
            $targetState = $sourceState;
691
            if (count($transitions) > 0) {
692
                $targetState = $this->checkCondition($transitions, $orderItem, $sourceState, $log);
693
            }
694
695
            $log->addTargetState($orderItem, $targetState->getName());
696
697
            $targetStateMap[$i] = $targetState->getName();
698
        }
699
700
        foreach ($orderItems as $i => $orderItem) {
701
            $this->setState($orderItems[$i], $targetStateMap[$i]);
702
        }
703
704
        return $sourceStateBuffer;
705
    }
706
707
    /**
708
     * @param \Orm\Zed\Sales\Persistence\SpySalesOrderItem $orderItem
709
     * @param string $stateName
710
     *
711
     * @return void
712
     */
713
    protected function setState($orderItem, $stateName)
714
    {
715
        if (isset($this->states[$stateName])) {
716
            $state = $this->states[$stateName];
717
        } else {
718
            $state = SpyOmsOrderItemStateQuery::create()->findOneByName($stateName);
719
            if ($state === null) {
720
                $state = new SpyOmsOrderItemState();
721
                $state->setName($stateName);
722
                $state->save();
723
            }
724
            $this->states[$stateName] = $state;
725
        }
726
        $orderItem->setState($state);
727
        $orderItem->setLastStateChange(new DateTime());
728
    }
729
730
    /**
731
     * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItems
732
     * @param array<\Spryker\Zed\Oms\Business\Process\ProcessInterface> $processes
733
     * @param array $sourceStateBuffer
734
     *
735
     * @throws \LogicException
736
     *
737
     * @return array<array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem>>
738
     */
739
    protected function filterItemsWithOnEnterEvent(array $orderItems, array $processes, array $sourceStateBuffer)
740
    {
741
        $orderItemsWithOnEnterEvent = [];
742
        foreach ($orderItems as $orderItem) {
743
            $stateId = $orderItem->getState()->getName();
744
            $processId = $orderItem->getProcess()->getName();
745
746
            if (!isset($processes[$processId])) {
747
                throw new LogicException("Unknown process $processId");
748
            }
749
750
            $process = $processes[$processId];
751
            $targetState = $process->getStateFromAllProcesses($stateId);
752
753
            if (isset($sourceStateBuffer[$orderItem->getIdSalesOrderItem()])) {
754
                $sourceState = $sourceStateBuffer[$orderItem->getIdSalesOrderItem()];
755
            } else {
756
                $sourceState = $process->getStateFromAllProcesses($orderItem->getState()->getName());
757
            }
758
759
            if ($sourceState === $targetState && $targetState->isReserved()) {
760
                $reservationRequestTransfer = (new ReservationRequestTransfer())
761
                    ->fromArray($orderItem->toArray(), true);
762
                $this->reservation->updateReservation($reservationRequestTransfer);
763
            }
764
765
            if (
766
                $sourceState !== $targetState->getName()
767
                && $targetState->hasOnEnterEvent()
768
            ) {
769
                $event = $targetState->getOnEnterEvent();
770
                if (array_key_exists($event->getName(), $orderItemsWithOnEnterEvent) === false) {
771
                    $orderItemsWithOnEnterEvent[$event->getName()] = [];
772
                }
773
                $orderItemsWithOnEnterEvent[$event->getName()][] = $orderItem;
774
            }
775
        }
776
777
        return $orderItemsWithOnEnterEvent;
778
    }
779
780
    /**
781
     * @param \Spryker\Zed\Oms\Business\Util\ReadOnlyArrayObject|array $data
782
     *
783
     * @return \Spryker\Zed\Oms\Business\Util\ReadOnlyArrayObject
784
     */
785
    protected function makeDataReadOnly($data)
786
    {
787
        if (is_array($data)) {
788
            $data = new ReadOnlyArrayObject($data);
789
        }
790
791
        return $data;
792
    }
793
794
    /**
795
     * To protect against loops, every event can only be used several times per order group.
796
     *
797
     * @param string $eventId
798
     * @param string $orderGroupKey
799
     *
800
     * @return bool
801
     */
802
    protected function checkOrderGroupForEventRepetitions(string $eventId, string $orderGroupKey): bool
803
    {
804
        if (!isset($this->eventCounter[$eventId][$orderGroupKey])) {
805
            $this->eventCounter[$eventId][$orderGroupKey] = 0;
806
        }
807
808
        $this->eventCounter[$eventId][$orderGroupKey]++;
809
810
        return $this->eventCounter[$eventId][$orderGroupKey] < static::MAX_EVENT_REPEATS;
811
    }
812
813
    /**
814
     * @param array<array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem>> $orderItemsWithOnEnterEvent
815
     * @param \Spryker\Zed\Oms\Business\Util\ReadOnlyArrayObject $data
816
     *
817
     * @return void
818
     */
819
    protected function triggerOnEnterEvents(array $orderItemsWithOnEnterEvent, ReadOnlyArrayObject $data)
820
    {
821
        if (count($orderItemsWithOnEnterEvent) > 0) {
822
            foreach ($orderItemsWithOnEnterEvent as $eventId => $orderItems) {
823
                $this->triggerEvent($eventId, $orderItems, $data);
824
            }
825
        }
826
    }
827
828
    /**
829
     * @param array<\Spryker\Zed\Oms\Business\Process\TransitionInterface> $transitions
830
     *
831
     * @return array
832
     */
833
    protected function createStateToTransitionMap(array $transitions)
834
    {
835
        $stateToTransitionsMap = [];
836
        foreach ($transitions as $transition) {
837
            $sourceId = $transition->getSource()->getName();
838
            if (array_key_exists($sourceId, $stateToTransitionsMap) === false) {
839
                $stateToTransitionsMap[$sourceId] = [];
840
            }
841
            $stateToTransitionsMap[$sourceId][] = $transition;
842
        }
843
844
        return $stateToTransitionsMap;
845
    }
846
847
    /**
848
     * @param array $states
849
     * @param \Spryker\Zed\Oms\Business\Process\ProcessInterface $process
850
     * @param \Generated\Shared\Transfer\OmsCheckConditionsQueryCriteriaTransfer|null $omsCheckConditionsQueryCriteriaTransfer
851
     *
852
     * @return array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem>
853
     */
854
    protected function getOrderItemsByState(
855
        array $states,
856
        ProcessInterface $process,
857
        ?OmsCheckConditionsQueryCriteriaTransfer $omsCheckConditionsQueryCriteriaTransfer
858
    ) {
859
        $omsCheckConditionsQueryCriteriaTransfer = $this->prepareOmsCheckConditionsQueryCriteriaTransfer($omsCheckConditionsQueryCriteriaTransfer);
860
861
        $storeName = $omsCheckConditionsQueryCriteriaTransfer->getStoreName();
862
        $limit = $omsCheckConditionsQueryCriteriaTransfer->getLimit();
863
864
        if ($storeName === null && $limit === null) {
865
            return $this->queryContainer
866
                ->querySalesOrderItemsByState($states, $process->getName())
867
                ->find()
868
                ->getData();
869
        }
870
871
        $omsProcessEntity = $this->queryContainer->queryProcess($process->getName())->findOne();
872
        /** @var \Propel\Runtime\Collection\ObjectCollection $omsOrderItemEntityCollection */
873
        $omsOrderItemEntityCollection = $this->queryContainer->querySalesOrderItemStatesByName($states)->find();
874
875
        if ($omsProcessEntity === null || $omsOrderItemEntityCollection->count() === 0) {
876
            return [];
877
        }
878
879
        return $this->queryContainer
880
            ->querySalesOrderItemsByProcessIdStateIdsAndQueryCriteria(
881
                $omsProcessEntity->getIdOmsOrderProcess(),
882
                $omsOrderItemEntityCollection->getPrimaryKeys(),
883
                $omsCheckConditionsQueryCriteriaTransfer,
884
            )
885
            ->find()
886
            ->getData();
887
    }
888
889
    /**
890
     * @param \Generated\Shared\Transfer\OmsCheckConditionsQueryCriteriaTransfer|null $omsCheckConditionsQueryCriteriaTransfer
891
     *
892
     * @return \Generated\Shared\Transfer\OmsCheckConditionsQueryCriteriaTransfer
893
     */
894
    protected function prepareOmsCheckConditionsQueryCriteriaTransfer(
895
        ?OmsCheckConditionsQueryCriteriaTransfer $omsCheckConditionsQueryCriteriaTransfer = null
896
    ): OmsCheckConditionsQueryCriteriaTransfer {
897
        if ($omsCheckConditionsQueryCriteriaTransfer === null) {
898
            $omsCheckConditionsQueryCriteriaTransfer = new OmsCheckConditionsQueryCriteriaTransfer();
899
        }
900
901
        if ($omsCheckConditionsQueryCriteriaTransfer->getLimit() === null) {
902
            $omsCheckConditionsQueryCriteriaTransfer->setLimit($this->omsConfig->getCheckConditionsQueryLimit());
903
        }
904
905
        return $omsCheckConditionsQueryCriteriaTransfer;
906
    }
907
908
    /**
909
     * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItems
910
     * @param \Spryker\Zed\Oms\Business\Util\TransitionLogInterface $log
911
     * @param array<\Spryker\Zed\Oms\Business\Process\ProcessInterface> $processes
912
     * @param array $sourceStateBuffer
913
     *
914
     * @return void
915
     */
916
    protected function saveOrderItems(array $orderItems, TransitionLogInterface $log, array $processes, array $sourceStateBuffer)
917
    {
918
        $currentTime = new DateTime('now');
919
        $timeoutModel = clone $this->timeout;
920
921
        $this->handleDatabaseTransaction(function () use ($orderItems, $processes, $sourceStateBuffer, $timeoutModel, $log, $currentTime) {
922
            $this->executeBulkSaveOrderItemTransaction(
923
                $orderItems,
924
                $processes,
925
                $sourceStateBuffer,
926
                $timeoutModel,
927
                $log,
928
                $currentTime,
929
            );
930
        });
931
    }
932
933
    /**
934
     * @deprecated Use {@link executeBulkSaveOrderItemTransaction()} instead.
935
     *
936
     * @param \Orm\Zed\Sales\Persistence\SpySalesOrderItem $orderItem
937
     * @param array $processes
938
     * @param array $sourceStateBuffer
939
     * @param \Spryker\Zed\Oms\Business\OrderStateMachine\TimeoutInterface $timeoutModel
940
     * @param \Spryker\Zed\Oms\Business\Util\TransitionLogInterface $log
941
     * @param \DateTime $currentTime
942
     *
943
     * @return void
944
     */
945
    protected function executeSaveOrderItemTransaction(
946
        SpySalesOrderItem $orderItem,
947
        array $processes,
948
        array $sourceStateBuffer,
949
        TimeoutInterface $timeoutModel,
950
        TransitionLogInterface $log,
951
        DateTime $currentTime
952
    ) {
953
        $process = $processes[$orderItem->getProcess()->getName()];
954
955
        $sourceState = $sourceStateBuffer[$orderItem->getIdSalesOrderItem()];
956
        $targetState = $orderItem->getState()->getName();
957
958
        if ($sourceState !== $targetState) {
959
            $timeoutModel->dropOldTimeout($process, $sourceState, $orderItem);
960
            $timeoutModel->setNewTimeout($process, $orderItem, $currentTime);
961
        }
962
963
        $orderItem->save();
964
        $this->updateOmsReservation($process, $sourceState, $targetState, $orderItem);
965
        $log->save($orderItem);
966
    }
967
968
    /**
969
     * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItemEntities
970
     * @param array<\Spryker\Zed\Oms\Business\Process\ProcessInterface> $processes
971
     * @param array<int, string> $sourceStateBuffer
972
     * @param \Spryker\Zed\Oms\Business\OrderStateMachine\TimeoutInterface $timeoutModel
973
     * @param \Spryker\Zed\Oms\Business\Util\TransitionLogInterface $log
974
     * @param \DateTime $currentTime
975
     *
976
     * @return void
977
     */
978
    protected function executeBulkSaveOrderItemTransaction(
979
        array $orderItemEntities,
980
        array $processes,
981
        array $sourceStateBuffer,
982
        TimeoutInterface $timeoutModel,
983
        TransitionLogInterface $log,
984
        DateTime $currentTime
985
    ) {
986
        $indexedOrderItemEntities = [];
987
        foreach ($orderItemEntities as $orderItemEntity) {
988
            $process = $processes[$orderItemEntity->getProcess()->getName()];
989
            $sourceState = $sourceStateBuffer[$orderItemEntity->getIdSalesOrderItem()];
990
            $targetState = $orderItemEntity->getState()->getName();
991
992
            if ($sourceState !== $targetState) {
993
                $timeoutModel->dropOldTimeout($process, $sourceState, $orderItemEntity);
994
                $timeoutModel->setNewTimeout($process, $orderItemEntity, $currentTime);
995
            }
996
            $indexedOrderItemEntities[$orderItemEntity->getIdSalesOrderItem()] = $orderItemEntity;
997
            $this->persist($orderItemEntity);
998
        }
999
1000
        $this->commit();
1001
1002
        foreach ($indexedOrderItemEntities as $orderItemEntity) {
1003
            $this->updateOmsReservation($process, $sourceState, $targetState, $orderItemEntity);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $targetState seems to be defined by a foreach iteration on line 987. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
Comprehensibility Best Practice introduced by
The variable $process seems to be defined by a foreach iteration on line 987. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
Comprehensibility Best Practice introduced by
The variable $sourceState seems to be defined by a foreach iteration on line 987. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
1004
            $log->save($orderItemEntity);
1005
        }
1006
    }
1007
1008
    /**
1009
     * @param string $command
1010
     *
1011
     * @return \Spryker\Zed\Oms\Dependency\Plugin\Command\CommandInterface
1012
     */
1013
    protected function getCommand($command)
1014
    {
1015
        return $this->commands->get($command);
1016
    }
1017
1018
    /**
1019
     * @param string $condition
1020
     *
1021
     * @return \Spryker\Zed\Oms\Dependency\Plugin\Condition\ConditionInterface
1022
     */
1023
    protected function getCondition($condition)
1024
    {
1025
        return $this->conditions->get($condition);
1026
    }
1027
1028
    /**
1029
     * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItems
1030
     *
1031
     * @return \Spryker\Zed\Oms\Business\Util\TransitionLogInterface
1032
     */
1033
    protected function initTransitionLog(array $orderItems)
1034
    {
1035
        $log = clone $this->transitionLog;
1036
1037
        $log->init($orderItems);
1038
1039
        return $log;
1040
    }
1041
1042
    /**
1043
     * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItems
1044
     * @param \Spryker\Zed\Oms\Business\Util\TransitionLogInterface $log
1045
     *
1046
     * @return void
1047
     */
1048
    protected function logSourceState($orderItems, TransitionLogInterface $log)
1049
    {
1050
        foreach ($orderItems as $orderItem) {
1051
            $stateName = $orderItem->getState()->getName();
1052
            $log->addSourceState($orderItem, $stateName);
1053
        }
1054
    }
1055
1056
    /**
1057
     * @deprecated Use {@link updateOmsReservation()} instead.
1058
     *
1059
     * @param \Spryker\Zed\Oms\Business\Process\ProcessInterface $process
1060
     * @param string $sourceStateId
1061
     * @param string $targetStateId
1062
     * @param string $sku
1063
     *
1064
     * @return void
1065
     */
1066
    protected function updateReservation(ProcessInterface $process, $sourceStateId, $targetStateId, $sku)
1067
    {
1068
        $sourceStateIsReserved = $process->getStateFromAllProcesses($sourceStateId)->isReserved();
1069
        $targetStateIsReserved = $process->getStateFromAllProcesses($targetStateId)->isReserved();
1070
1071
        if ($sourceStateIsReserved !== $targetStateIsReserved) {
1072
            $this->reservation->updateReservationQuantity($sku);
1073
        }
1074
    }
1075
1076
    /**
1077
     * @param \Spryker\Zed\Oms\Business\Process\ProcessInterface $process
1078
     * @param string $sourceState
1079
     * @param string $targetState
1080
     * @param \Orm\Zed\Sales\Persistence\SpySalesOrderItem $salesOrderItem
1081
     *
1082
     * @return void
1083
     */
1084
    protected function updateOmsReservation(
1085
        ProcessInterface $process,
1086
        string $sourceState,
1087
        string $targetState,
1088
        SpySalesOrderItem $salesOrderItem
1089
    ): void {
1090
        $sourceStateIsReserved = $process->getStateFromAllProcesses($sourceState)->isReserved();
1091
        $targetStateIsReserved = $process->getStateFromAllProcesses($targetState)->isReserved();
1092
1093
        if ($sourceStateIsReserved !== $targetStateIsReserved) {
1094
            $reservationRequestTransfer = (new ReservationRequestTransfer())
1095
                ->fromArray($salesOrderItem->toArray(), true);
1096
            $this->reservation->updateReservation($reservationRequestTransfer);
1097
        }
1098
    }
1099
1100
    /**
1101
     * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItems
1102
     * @param array<\Spryker\Zed\Oms\Business\Process\ProcessInterface> $processes
1103
     *
1104
     * @throws \LogicException
1105
     *
1106
     * @return array
1107
     */
1108
    protected function filterItemsWithTimeoutEvent(array $orderItems, array $processes)
1109
    {
1110
        $orderItemsWithTimeoutEvent = [];
1111
        foreach ($orderItems as $orderItem) {
1112
            $stateId = $orderItem->getState()->getName();
1113
            $processId = $orderItem->getProcess()->getName();
1114
1115
            if (!isset($processes[$processId])) {
1116
                throw new LogicException("Unknown process $processId");
1117
            }
1118
1119
            $process = $processes[$processId];
1120
            $targetState = $process->getStateFromAllProcesses($stateId);
1121
1122
            if ($targetState->hasTimeoutEvent()) {
1123
                $events = $targetState->getTimeoutEvents();
1124
                foreach ($events as $event) {
1125
                    $orderItemKey = sprintf('%s_%s', $orderItem->getIdSalesOrderItem(), $orderItem->getFkOmsOrderItemState());
1126
                    if (!isset($orderItemsWithTimeoutEvent[$event->getName()][$orderItemKey])) {
1127
                        $orderItemsWithTimeoutEvent[$event->getName()][$orderItemKey] = $orderItem;
1128
                    }
1129
                }
1130
            }
1131
        }
1132
1133
        return $orderItemsWithTimeoutEvent;
1134
    }
1135
1136
    /**
1137
     * @param array $orderItemsWithTimeoutEvent
1138
     *
1139
     * @return void
1140
     */
1141
    protected function saveTimeoutEvents(array $orderItemsWithTimeoutEvent)
1142
    {
1143
        foreach ($orderItemsWithTimeoutEvent as $eventId => $orderItems) {
1144
            $this->saveTimeoutEvent($eventId, $orderItems);
1145
        }
1146
    }
1147
1148
    /**
1149
     * @param string $eventId
1150
     * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItems
1151
     *
1152
     * @return void
1153
     */
1154
    protected function saveTimeoutEvent($eventId, array $orderItems)
1155
    {
1156
        $processes = $this->getProcesses($orderItems);
1157
        $orderItems = $this->filterAffectedOrderItems($eventId, $orderItems, $processes);
1158
        $sourceStateBuffer = $this->getStateByEvent($orderItems);
1159
        $orderGroup = $this->groupByOrderAndState($eventId, $orderItems, $processes);
1160
1161
        foreach ($orderGroup as $orderGroupKey => $groupedOrderItems) {
1162
            if (!$this->checkOrderGroupForEventRepetitions($eventId, $orderGroupKey)) {
1163
                return;
1164
            }
1165
1166
            $this->saveOrderItemsTimeout($groupedOrderItems, $processes, $sourceStateBuffer);
1167
        }
1168
    }
1169
1170
    /**
1171
     * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItems
1172
     *
1173
     * @return array
1174
     */
1175
    protected function getStateByEvent(array $orderItems)
1176
    {
1177
        $sourceStateBuffer = [];
1178
        foreach ($orderItems as $orderItem) {
1179
            $stateId = $orderItem->getState()->getName();
1180
            $sourceStateBuffer[$orderItem->getIdSalesOrderItem()] = $stateId;
1181
        }
1182
1183
        return $sourceStateBuffer;
1184
    }
1185
1186
    /**
1187
     * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItems
1188
     * @param array<\Spryker\Zed\Oms\Business\Process\ProcessInterface> $processes
1189
     * @param array $sourceStateBuffer
1190
     *
1191
     * @return void
1192
     */
1193
    protected function saveOrderItemsTimeout(array $orderItems, array $processes, array $sourceStateBuffer)
1194
    {
1195
        $currentTime = new DateTime('now');
1196
1197
        $this->timeout->dropOldTimeouts($orderItems, $processes, $sourceStateBuffer);
1198
        $this->timeout->setNewTimeouts($orderItems, $currentTime, $processes);
1199
    }
1200
}
1201