| Total Complexity | 42 |
| Total Lines | 204 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like OrderRoute often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use OrderRoute, and based on these observations, apply Extract Interface, too.
| 1 | <?php declare(strict_types=1); |
||
| 32 | class OrderRoute extends AbstractOrderRoute |
||
| 33 | { |
||
| 34 | /** |
||
| 35 | * @var EntityRepositoryInterface |
||
| 36 | */ |
||
| 37 | private $orderRepository; |
||
| 38 | |||
| 39 | /** |
||
| 40 | * @var RequestCriteriaBuilder |
||
| 41 | */ |
||
| 42 | private $requestCriteriaBuilder; |
||
| 43 | |||
| 44 | /** |
||
| 45 | * @var OrderDefinition |
||
| 46 | */ |
||
| 47 | private $orderDefinition; |
||
| 48 | |||
| 49 | /** |
||
| 50 | * @var EntityRepositoryInterface |
||
| 51 | */ |
||
| 52 | private $promotionRepository; |
||
| 53 | |||
| 54 | public function __construct( |
||
| 55 | EntityRepositoryInterface $orderRepository, |
||
| 56 | RequestCriteriaBuilder $requestCriteriaBuilder, |
||
| 57 | OrderDefinition $salesChannelOrderDefinition, |
||
| 58 | EntityRepositoryInterface $promotionRepository |
||
| 59 | ) { |
||
| 60 | $this->orderRepository = $orderRepository; |
||
| 61 | $this->requestCriteriaBuilder = $requestCriteriaBuilder; |
||
| 62 | $this->orderDefinition = $salesChannelOrderDefinition; |
||
| 63 | $this->promotionRepository = $promotionRepository; |
||
| 64 | } |
||
| 65 | |||
| 66 | public function getDecorated(): AbstractOrderRoute |
||
| 67 | { |
||
| 68 | throw new DecorationPatternException(self::class); |
||
| 69 | } |
||
| 70 | |||
| 71 | /** |
||
| 72 | * @Since("6.2.0.0") |
||
| 73 | * @Entity("order") |
||
| 74 | * @OA\Post( |
||
| 75 | * path="/order", |
||
| 76 | * summary="Listing orders", |
||
| 77 | * operationId="readOrder", |
||
| 78 | * tags={"Store API", "Order"}, |
||
| 79 | * @OA\Parameter(name="Api-Basic-Parameters"), |
||
| 80 | * @OA\RequestBody( |
||
| 81 | * required=true, |
||
| 82 | * @OA\JsonContent( |
||
| 83 | * @OA\Property(property="checkPromotion", description="Wether to check the Promotions of orders", type="string"), |
||
| 84 | * ) |
||
| 85 | * ), |
||
| 86 | * @OA\Response( |
||
| 87 | * response="200", |
||
| 88 | * description="", |
||
| 89 | * @OA\JsonContent(type="array", @OA\Items(ref="#/components/schemas/order_flat")) |
||
| 90 | * ) |
||
| 91 | * ) |
||
| 92 | * @Route(path="/store-api/v{version}/order", name="store-api.order", methods={"GET", "POST"}) |
||
| 93 | */ |
||
| 94 | public function load(Request $request, SalesChannelContext $context, ?Criteria $criteria = null): OrderRouteResponse |
||
| 95 | { |
||
| 96 | // @deprecated tag:v6.4.0 - Criteria will be required |
||
| 97 | if (!$criteria) { |
||
| 98 | $criteria = $this->requestCriteriaBuilder->handleRequest($request, new Criteria(), $this->orderDefinition, $context->getContext()); |
||
| 99 | } |
||
| 100 | |||
| 101 | $criteria->addFilter(new EqualsFilter('order.salesChannelId', $context->getSalesChannel()->getId())); |
||
| 102 | |||
| 103 | $criteria->getAssociation('documents') |
||
| 104 | ->addFilter(new EqualsFilter('config.displayInCustomerAccount', 'true')) |
||
| 105 | ->addFilter(new EqualsFilter('sent', true)); |
||
| 106 | |||
| 107 | $criteria->addAssociation('billingAddress'); |
||
| 108 | |||
| 109 | if ($context->getCustomer()) { |
||
| 110 | $criteria->addFilter(new EqualsFilter('order.orderCustomer.customerId', $context->getCustomer()->getId())); |
||
| 111 | } elseif (!$criteria->hasEqualsFilter('deepLinkCode')) { |
||
| 112 | throw new CustomerNotLoggedInException(); |
||
| 113 | } |
||
| 114 | |||
| 115 | $orders = $this->orderRepository->search($criteria, $context->getContext()); |
||
| 116 | |||
| 117 | if ($criteria->hasEqualsFilter('deepLinkCode')) { |
||
| 118 | $orders = $this->filterOldOrders($orders); |
||
| 119 | } |
||
| 120 | |||
| 121 | // Handle guest authentication if deeplink is set |
||
| 122 | if (!$context->getCustomer() && $criteria->hasEqualsFilter('deepLinkCode')) { |
||
| 123 | /** @var OrderEntity $order */ |
||
| 124 | $order = $orders->first(); |
||
| 125 | $this->checkGuestAuth($order, $request); |
||
| 126 | } |
||
| 127 | |||
| 128 | $response = new OrderRouteResponse($orders); |
||
| 129 | if ($request->get('checkPromotion') === true) { |
||
| 130 | /** @var OrderEntity $order */ |
||
| 131 | foreach ($orders as $order) { |
||
| 132 | $promotions = $this->getActivePromotions($order, $context); |
||
|
|
|||
| 133 | $changeable = true; |
||
| 134 | foreach ($promotions as $promotion) { |
||
| 135 | $changeable = $this->checkPromotion($promotion); |
||
| 136 | if ($changeable === true) { |
||
| 137 | break; |
||
| 138 | } |
||
| 139 | } |
||
| 140 | $response->addPaymentChangeable([$order->getId() => $changeable]); |
||
| 141 | } |
||
| 142 | } |
||
| 143 | |||
| 144 | return $response; |
||
| 145 | } |
||
| 146 | |||
| 147 | private function getActivePromotions(OrderEntity $order, SalesChannelContext $context): PromotionCollection |
||
| 148 | { |
||
| 149 | $promotionIds = []; |
||
| 150 | foreach ($order->getLineItems() ?? [] as $lineItem) { |
||
| 151 | $payload = $lineItem->getPayload(); |
||
| 152 | if (isset($payload['promotionId']) && $payload['promotionId'] !== null) { |
||
| 153 | $promotionIds[] = $payload['promotionId']; |
||
| 154 | } |
||
| 155 | } |
||
| 156 | |||
| 157 | $promotions = new PromotionCollection(); |
||
| 158 | |||
| 159 | if (!empty($promotionIds)) { |
||
| 160 | $criteria = new Criteria($promotionIds); |
||
| 161 | $criteria->addAssociation('cartRules'); |
||
| 162 | /** @var PromotionCollection $promotions */ |
||
| 163 | $promotions = $this->promotionRepository->search($criteria, $context->getContext())->getEntities(); |
||
| 164 | } |
||
| 165 | |||
| 166 | return $promotions; |
||
| 167 | } |
||
| 168 | |||
| 169 | private function checkRuleType(Container $rule): bool |
||
| 170 | { |
||
| 171 | foreach ($rule->getRules() as $nestedRule) { |
||
| 172 | if ($nestedRule instanceof Container && $this->checkRuleType($nestedRule) === false) { |
||
| 173 | return false; |
||
| 174 | } |
||
| 175 | if ($nestedRule instanceof PaymentMethodRule) { |
||
| 176 | return false; |
||
| 177 | } |
||
| 178 | } |
||
| 179 | |||
| 180 | return true; |
||
| 181 | } |
||
| 182 | |||
| 183 | private function checkPromotion(PromotionEntity $promotion): bool |
||
| 184 | { |
||
| 185 | foreach ($promotion->getCartRules() as $cartRule) { |
||
| 186 | if ($this->checkCartRule($cartRule) === false) { |
||
| 187 | return false; |
||
| 188 | } |
||
| 189 | } |
||
| 190 | |||
| 191 | return true; |
||
| 192 | } |
||
| 193 | |||
| 194 | private function checkCartRule(RuleEntity $cartRule): bool |
||
| 195 | { |
||
| 196 | $payload = $cartRule->getPayload(); |
||
| 197 | foreach ($payload->getRules() as $rule) { |
||
| 198 | if ($this->checkRuleType($rule) === false) { |
||
| 199 | return false; |
||
| 200 | } |
||
| 201 | } |
||
| 202 | |||
| 203 | return true; |
||
| 204 | } |
||
| 205 | |||
| 206 | private function filterOldOrders(EntitySearchResult $orders): EntitySearchResult |
||
| 207 | { |
||
| 208 | // Search with deepLinkCode needs updatedAt Filter |
||
| 209 | $latestOrderDate = (new \DateTime())->setTimezone(new \DateTimeZone('UTC'))->modify(-abs(30) . ' Day'); |
||
| 210 | $orders = $orders->filter(function (OrderEntity $order) use ($latestOrderDate) { |
||
| 211 | return $order->getCreatedAt() > $latestOrderDate || $order->getUpdatedAt() > $latestOrderDate; |
||
| 212 | }); |
||
| 213 | |||
| 214 | return $orders; |
||
| 215 | } |
||
| 216 | |||
| 217 | private function checkGuestAuth(OrderEntity $order, Request $request): void |
||
| 236 | } |
||
| 237 | } |
||
| 238 | } |
||
| 239 |