<?php
namespace BillingBundle\Security;
use AppBundle\Entity\User;
use BillingBundle\Entity\Invoice;
use BillingBundle\Enum\InvoiceStatusEnum;
use BillingBundle\Enum\PayableInvoiceStatusEnum;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
/**
* Class InvoiceVoter
*/
class InvoiceVoter extends Voter
{
const EDIT = 'EDIT';
const VIEW = 'VIEW';
const SAVE_TO_DRIVE = 'SAVE_TO_DRIVE';
const CAN_UPDATE_STATUS_IN_PAYED = 'CAN_UPDATE_STATUS_IN_PAYED';
const CAN_UPDATE_STATUS_IN_WAITING_FOR_PAYMENT = 'CAN_UPDATE_STATUS_IN_WAITING_FOR_PAYMENT';
/**
* @var AccessDecisionManagerInterface
*/
private $decisionManager;
/**
* DocumentWorkflowVoter constructor.
* @param AccessDecisionManagerInterface $decisionManager
*/
public function __construct(
AccessDecisionManagerInterface $decisionManager
) {
$this->decisionManager = $decisionManager;
}
/**
* {@inheritdoc}
*/
protected function supports($attribute, $subject)
{
return $subject instanceof Invoice && in_array($attribute, [
self::EDIT,
self::VIEW,
self::SAVE_TO_DRIVE,
self::CAN_UPDATE_STATUS_IN_PAYED,
self::CAN_UPDATE_STATUS_IN_WAITING_FOR_PAYMENT,
], true);
}
/**
* {@inheritdoc}
* @param Invoice $subject
*/
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
$user = $token->getUser();
if (!$user instanceof User) {
return false;
}
switch ($attribute) {
case self::EDIT:
return InvoiceStatusEnum::DRAFT === $subject->getStatus();
case self::VIEW:
return InvoiceStatusEnum::DRAFT !== $subject->getStatus();
case self::SAVE_TO_DRIVE:
return in_array($subject->getStatus(), PayableInvoiceStatusEnum::getInvoicesWithPdfStatuses());
case self::CAN_UPDATE_STATUS_IN_PAYED:
return $this->canUpdateStatusInPayed($subject, $token);
case self::CAN_UPDATE_STATUS_IN_WAITING_FOR_PAYMENT:
return $this->canUpdateStatusInWaitingForPayment($subject, $token);
default:
return false;
}
}
/**
* Check whether invoice can be updated in waiting for payment status or not
*
* @param Invoice $invoice
* @param TokenInterface $token
* @return boolean
*/
protected function canUpdateStatusInWaitingForPayment(Invoice $invoice, TokenInterface $token)
{
if (!$this->decisionManager->decide($token, ['ROLE_VALIDATE_INVOICE'])) {
return false;
}
$canBeUpdated = true;
if (!(
!$invoice->isAsset() &&
($invoice->isValidated() || ($invoice->isDraft() && $invoice->hasGeneratedFile())) &&
!$invoice->isFeePayedByTrust())
) {
$canBeUpdated = false;
}
return $canBeUpdated;
}
/**
* Check whether invoice can be updated in payed status or not
*
* @param Invoice $invoice
* @param TokenInterface $token
* @return boolean
*/
protected function canUpdateStatusInPayed(Invoice $invoice, TokenInterface $token)
{
if (!$this->decisionManager->decide($token, ['ROLE_VALIDATE_INVOICE'])) {
return false;
}
$canBeUpdated = true;
// Pour pouvoir passer en statut soldé il faut que la facture d'avoir
// soit validé ou en proforma avec le pdf généré
if (!(
($invoice->isAsset() && ($invoice->isValidated() || ($invoice->isDraft() && $invoice->hasGeneratedFile()))) || ($invoice->isFeePayedByTrust() && ($invoice->isValidated() || ($invoice->isDraft() && $invoice->hasGeneratedFile())))
)) {
$canBeUpdated = false;
}
return $canBeUpdated;
}
}