<?php
namespace App\Security\Voters;
use App\Entity\CustomerQuotations;
use App\Entity\PriceInquiry;
use App\Service\WebPop\WebShopService;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
class QuotationVoter extends Voter
{
private Security $security;
public const CAN_OPEN_PORPOSAL = 'quotation.proposal.can_open';
public const CAN_OPEN_MF_OFFERS = 'quotation.mf_offers.can_open';
public const CAN_CHANGE_COMMISSION = 'quotation.commission.can_change';
public const CAN_DELETE_QUOTATION = 'quotation.can_delete';
public const CAN_OPEN_QUOTATION = 'quotation.can_open';
public const CAN_CREATE_INQUIRY = 'quotation.inquiry.can_create';
public const CAN_GENERATE_INQUIRIES = 'quotation.inquiry.can_generate';
public const IS_CUSTOMER_QUOTATION = 'quotation.is_customer';
public const CAN_BE_UPDATED_IN_CALCULATOR = 'quotation.can_be_updated_in_calculator';
public const CAN_BE_UPDATED_IN_WEB_POP = 'quotation.can_be_updated_in_web_pop';
public const CAN_CHANGE_MANAGER = 'quotation.can_change_manager';
public const CAN_ROLLBACK = 'quotation.can_rollback';
public const CAN_CREATE_CUSTOMER_FROM_SHOP_INVOICE = 'quotation.customer.create_from_shop_invoice';
private const ATTRIBUTES = [
self::CAN_OPEN_PORPOSAL,
self::CAN_OPEN_MF_OFFERS,
self::CAN_DELETE_QUOTATION,
self::CAN_CHANGE_COMMISSION,
self::CAN_CREATE_INQUIRY,
self::CAN_OPEN_QUOTATION,
self::CAN_GENERATE_INQUIRIES,
self::IS_CUSTOMER_QUOTATION,
self::CAN_BE_UPDATED_IN_CALCULATOR,
self::CAN_BE_UPDATED_IN_WEB_POP,
self::CAN_CHANGE_MANAGER,
self::CAN_ROLLBACK,
self::CAN_CREATE_CUSTOMER_FROM_SHOP_INVOICE
];
private WebShopService $shopService;
public function __construct(
Security $security,
WebShopService $shopService
)
{
$this->security = $security;
$this->shopService = $shopService;
}
protected function supports($attribute, $subject): bool
{
return in_array($attribute, self::ATTRIBUTES);
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
{
switch ($attribute) {
case self::CAN_OPEN_PORPOSAL:
return $this->canOpenProposal($subject);
case self::CAN_OPEN_MF_OFFERS:
return $this->canOpenMfOffers($subject);
case self::CAN_DELETE_QUOTATION:
return $this->canDeleteQuotation($subject);
case self::CAN_CHANGE_COMMISSION:
return $this->canChangeCommission($subject);
case self::CAN_CREATE_INQUIRY:
return $this->canCreateInquiry($subject);
case self::CAN_OPEN_QUOTATION:
return $this->canOpenQuotation($subject);
case self::CAN_GENERATE_INQUIRIES:
return $this->canGenerateInquiries($subject);
case self::IS_CUSTOMER_QUOTATION:
return $this->isCustomerQuotation($subject);
case self::CAN_BE_UPDATED_IN_CALCULATOR:
case self::CAN_BE_UPDATED_IN_WEB_POP:
return $this->canBeUpdatedInCalculator($subject);
case self::CAN_CHANGE_MANAGER:
return $this->canChangeManager($subject);
case self::CAN_ROLLBACK:
return $this->canRollback($subject);
case self::CAN_CREATE_CUSTOMER_FROM_SHOP_INVOICE:
return $this->canCreateCustomerFromShopInvoice($subject);
}
throw new \LogicException('Invalid attribute: ' . $attribute);
}
private function isCustomerQuotation(CustomerQuotations $quotation): bool
{
if ($quotation->getCreatedBy() && $quotation->getCreatedBy()->getCustomer()) {
return true;
}
return false;
}
private function canOpenProposal(CustomerQuotations $quotation): bool
{
foreach ($quotation->getPriceInquiries() as $inquiry) {
if (!$inquiry->getOfferVerifiedSM()) {
if (!$this->security->isGranted('ROLE_SALES_MANAGER')) {
continue;
}
}
if (in_array($inquiry->getStatus(), [PriceInquiry::STATUS_OFFER, PriceInquiry::STATUS_DECLINED, PriceInquiry::STATUS_ACCEPTED, PriceInquiry::STATUS_HOLD])) {
return true;
}
}
return false;
}
private function canOpenQuotation(CustomerQuotations $quotation): bool
{
if ($this->security->isGranted('ROLE_CAN_SEE_ALL_QUOTATIONS')) {
return true;
}
if ($this->security->getUser() !== null && $quotation->getManager() == $this->security->getUser()) {
return true;
}
if ($this->security->isGranted('ROLE_CAN_CREATE_INQUIRIES')
&& !in_array($quotation->getStatus(), [CustomerQuotations::STATUS_DRAFT,
CustomerQuotations::STATUS_NEW,
CustomerQuotations::STATUS_PROCESSING,
CustomerQuotations::STATUS_FINISHED,
CustomerQuotations::STATUS_REJECTED,
CustomerQuotations::STATUS_DELETED])) {
return true;
}
if ($quotation->getManager() === null) {
return true;
}
return false;
}
private function canChangeCommission(CustomerQuotations $quotation): bool
{
if (!$this->security->isGranted('ROLE_CAN_CHANGE_OFFER_COMMISSION')) {
return false;
}
if (!in_array($quotation->getStatus(), [CustomerQuotations::STATUS_READY, CustomerQuotations::STATUS_INQUIRIES_SENT, CustomerQuotations::STATUS_OFFERS_RECEIVED, CustomerQuotations::STATUS_OFFERS_PARTIALLY_RECEIVED])) {
return false;
}
return true;
}
private function canDeleteQuotation(CustomerQuotations $quotation): bool
{
if (!$this->security->isGranted('ROLE_QUOTATION_CAN_DELETE')) {
return false;
}
if (!in_array($quotation->getStatus(), [CustomerQuotations::STATUS_DRAFT, CustomerQuotations::STATUS_NEW])) {
return false;
}
return true;
}
private function canCreateInquiry(CustomerQuotations $quotation): bool
{
if (!$this->security->isGranted('ROLE_CAN_CREATE_INQUIRIES')) {
return false;
}
if (!in_array($quotation->getStatus(), [CustomerQuotations::STATUS_READY, CustomerQuotations::STATUS_INQUIRIES_SENT, CustomerQuotations::STATUS_OFFERS_RECEIVED, CustomerQuotations::STATUS_OFFERS_PARTIALLY_RECEIVED])) {
return false;
}
return true;
}
private function canGenerateInquiries(CustomerQuotations $quotation): bool
{
if ($quotation->getManager() == $this->security->getUser() && in_array($quotation->getStatus(), [CustomerQuotations::STATUS_NEW, CustomerQuotations::STATUS_READY])) {
return true;
}
return false;
}
private function canBeUpdatedInCalculator(CustomerQuotations $quotation): bool
{
if ($quotation->getStatus() === CustomerQuotations::STATUS_DRAFT) {
return true;
}
return false;
}
private function canChangeManager(CustomerQuotations $quotation): bool
{
if (!$this->security->isGranted('ROLE_QUOTATION_CAN_CHANGE_MANAGER')) {
return false;
}
// if ($quotation->getManager()) {
// return true;
// }
return true;
}
private function canOpenMfOffers(CustomerQuotations $quotation): bool
{
if (!$this->security->isGranted('ROLE_MANUFACTURING_MANAGER')) {
return false;
}
if (count($quotation->getPriceInquiries()) > 0) {
return true;
}
return false;
}
private function canRollback(CustomerQuotations $quotation): bool
{
if(!$this->security->isGranted('ROLE_CAN_ROLLBACK_QUOTATION')) {
return false;
}
if (in_array($quotation->getStatus(), [
CustomerQuotations::STATUS_DRAFT,
CustomerQuotations::STATUS_NEW,
// CustomerQuotations::STATUS_REJECTED,
CustomerQuotations::STATUS_DELETED,
CustomerQuotations::STATUS_HOLD
])) {
return false;
}
return true;
}
private function canCreateCustomerFromShopInvoice(CustomerQuotations $quotation): bool
{
if (!$this->shopService->findWebShopInvoice($quotation)) {
return false;
}
if ($quotation->getCustomer()) {
return false;
}
return true;
}
}