58 lines
2.5 KiB
PHP
58 lines
2.5 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Esun\Review\Model\Order;
|
|
|
|
use Magento\Framework\App\ResourceConnection;
|
|
use Magento\Framework\Exception\LocalizedException;
|
|
use Magento\Sales\Api\OrderItemRepositoryInterface;
|
|
|
|
class ReviewEligibilityService
|
|
{
|
|
public function __construct(private readonly OrderItemRepositoryInterface $items, private readonly ResourceConnection $resource)
|
|
{
|
|
}
|
|
public function getItem(int $orderItemId, int $customerId): \Magento\Sales\Api\Data\OrderItemInterface
|
|
{
|
|
return $this->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';
|
|
}
|
|
}
|