loadEligibleItem($orderItemId, $customerId, true); } public function getItemForLink(int $orderItemId, int $customerId): \Magento\Sales\Api\Data\OrderItemInterface { return $this->loadEligibleItem($orderItemId, $customerId, false); } private function loadEligibleItem(int $orderItemId, int $customerId, bool $checkExisting): \Magento\Sales\Api\Data\OrderItemInterface { $item = $this->items->get($orderItemId); $order = $item->getOrder(); if ((int)$order->getCustomerId() !== $customerId || (int)$item->getParentItemId() > 0) { throw new LocalizedException(__('This order item cannot be reviewed.')); } if ((float)$item->getQtyOrdered() - (float)$item->getQtyCanceled() <= 0 || !$this->isOrderEligible($order)) { throw new LocalizedException(__('This order is not yet eligible for review.')); } if ($checkExisting && $this->hasReviewed($customerId, (int)$item->getProductId())) { throw new LocalizedException(__('You have already reviewed this product.')); } return $item; } public function canReview(\Magento\Sales\Model\Order\Item $item, int $customerId): bool { try { $this->getItem((int)$item->getId(), $customerId); return true; } catch (\Throwable) { return false; } } public function hasReviewed(int $customerId, int $productId): bool { $connection = $this->resource->getConnection(); return (bool)$connection->fetchOne($connection->select()->from(['r' => $this->resource->getTableName('review')], ['review_id'])->join(['d' => $this->resource->getTableName('review_detail')], 'd.review_id = r.review_id', [])->where('r.entity_pk_value = ?', $productId)->where('d.customer_id = ?', $customerId)->limit(1)); } private function isOrderEligible(\Magento\Sales\Model\Order $order): bool { return (string)$order->getStatus() === 'received'; } }