<?php
namespace App\Security\Voters;
use App\Entity\CustomerQuotations;
use App\Service\Constants\InvoiceStatus;
use App\Service\WorkflowHelper;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
class ShopVoter extends Voter
{
public const ORDER_IS_PAID = 'order.is_paid';
public const BEFORE_PAYMENT = 'order.before_payment';
public const AFTER_PAYMENT = 'order.after_payment';
public const ORDER_CAN_CUSTOMER_CONNECT = 'order.can_customer_connect';
public const ORDER_CAN_SAVE_FOR_LATER_SECURED = 'order.can_save_for_later_secured';
public const ORDER_NEED_INVOICE_PAYMENT_STAGE = 'order.need_invoice_payment_stage';
private const ATTRIBUTES = [
self::ORDER_IS_PAID,
self::BEFORE_PAYMENT,
self::AFTER_PAYMENT,
self::ORDER_CAN_CUSTOMER_CONNECT,
self::ORDER_CAN_SAVE_FOR_LATER_SECURED,
self::ORDER_NEED_INVOICE_PAYMENT_STAGE,
];
private Security $security;
private WorkflowHelper $workflowHelper;
public function __construct(
Security $security,
WorkflowHelper $workflowHelper
)
{
$this->security = $security;
$this->workflowHelper = $workflowHelper;
}
protected function supports($attribute, $subject): bool
{
return in_array($attribute, self::ATTRIBUTES);
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
{
switch ($attribute) {
case self::ORDER_IS_PAID:
case self::AFTER_PAYMENT:
return $this->orderIsPaid($subject);
case self::BEFORE_PAYMENT:
return !$this->orderIsPaid($subject);
case self::ORDER_CAN_CUSTOMER_CONNECT:
return $this->orderCanCustomerConnect($subject);
case self::ORDER_CAN_SAVE_FOR_LATER_SECURED:
return $this->orderCanSaveForLaterSecured($subject);
case self::ORDER_NEED_INVOICE_PAYMENT_STAGE:
return $this->needInvoicePaymentStage($subject);
}
throw new \LogicException('Invalid attribute: ' . $attribute);
}
private function orderIsPaid(CustomerQuotations $order): bool
{
if (!$this->workflowHelper->isSubjectStatusGreaterOrEqual($order, CustomerQuotations::STATUS_ACCEPTED)) {
return false;
}
if (!$order->getIsWebShopRelated()) {
return false;
}
foreach ($order->getInvoices() as $regInvoice) {
if ($regInvoice->getIsWebShopRelated()) {
if ($regInvoice->getStatus() === InvoiceStatus::INVOICE_STATUS_PAID_FULLY) {
return true;
}
}
}
return false;
}
private function orderCanCustomerConnect(CustomerQuotations $order): bool
{
if ($order->getCustomer()) {
return false;
}
if (!in_array($order->getStatus(), [
CustomerQuotations::STATUS_ACCEPTED,
CustomerQuotations::STATUS_WAITING_PAYMENT,
CustomerQuotations::STATUS_DRAFT
])) {
return false;
}
if (!$order->getIsWebShopRelated()) {
return false;
}
return true;
}
private function orderCanSaveForLaterSecured(CustomerQuotations $order): bool
{
if (!$order->getIsWebShopRelated()) {
return false;
}
if (!in_array($order->getStatus(), [
CustomerQuotations::STATUS_DRAFT
])) {
return false;
}
if ($order->getCustomer()) {
return $order->getCustomer() === $this->security->getUser()->getCustomer();
}
return true;
}
private function needInvoicePaymentStage(CustomerQuotations $order): bool
{
foreach ($order->getInvoices() as $regInvoice) {
if ($regInvoice->getIsWebShopRelated()) {
return false;
}
}
return true;
}
}