<?php
namespace App\Voters;
use App\Entity\Clinic\Clinic;
use App\Entity\Clinic\PriceTier\PriceTier;
use App\Entity\Organisation\Organisation;
use App\Entity\Person\Admin;
use App\Entity\Person\SuperClinicAdmin;
use App\Entity\Person\User;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\User\UserInterface;
class ClinicsVoter extends OrganisationVoter
{
const VIEW_EXTERNAL = 'view_external';
const VIEW_CALENDAR = 'view_calendar';
const VIEW_DAY_SHEET = 'view_day_sheet';
const VIEW_DAY_SHEET_EDIT = 'view_day_sheet_edit';
const DAY_SHEET_BY_TIER = 'day_sheet_by_tier';
const CREATE_BOARD = 'create_board';
const VIEW_STOCK = 'view_stock';
const VIEW_STOCK_EDIT = 'view_stock_edit';
const VIEW_EXTERNAL_INVOICE = 'view_external_invoice';
const VIEW_CREATE_TEAM_MEMBER = 'create_team_member';
const VIEW_NOTIFICATION = 'notification';
const VIEW_NOTIFICATION_TWILIO = 'notification_twilio';
const VIEW_PROSPECTS = 'prospects';
const VIEW_WAITING_LIST = 'waiting_list';
const VIEW_REPORT = 'report';
const VIEW_LIBRARY = 'library';
const REMOVE = 'remove';
const ROOM = 'room';
const EQUIPMENT = 'equipment';
const ONLINE_BOOKING = 'online_booking';
protected function supports($attribute, $subject = null)
{
return $subject instanceof Clinic && in_array(
$attribute,
[
self::VIEW,
self::CREATE,
self::EDIT,
self::VIEW_EXTERNAL,
self::VIEW_STOCK,
self::VIEW_STOCK_EDIT,
self::VIEW_EXTERNAL_INVOICE,
self::VIEW_CREATE_TEAM_MEMBER,
self::VIEW_NOTIFICATION,
self::VIEW_NOTIFICATION_TWILIO,
self::VIEW_PROSPECTS,
self::VIEW_WAITING_LIST,
self::VIEW_REPORT,
self::VIEW_LIBRARY,
self::REMOVE,
self::VIEW_DAY_SHEET,
self::VIEW_DAY_SHEET_EDIT,
self::CREATE_BOARD,
self::VIEW_CALENDAR,
self::ROOM,
self::EQUIPMENT,
self::DAY_SHEET_BY_TIER,
self::ONLINE_BOOKING,
],
true
);
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
$user = $token->getUser();
/** @var Clinic $clinic */
$clinic = $subject;
/** @var Organisation $organisation */
$organisation = $clinic->getOrganisation();
if (!$user instanceof UserInterface) {
return false;
}
switch ($attribute) {
case self::VIEW:
if ($user instanceof Admin) {
return true;
}
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
return $user->getClinic()->getId() === $clinic->getId();
break;
case self::CREATE:
if ($this->decisionManager->decide($token, [User::ROLE_SUB_STOCK])) {
if ($clinic !== $user->getClinic() && ($user->isClinicAdmin() || $user->isClinicReceptionist())) {
return false;
}
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
break;
case self::VIEW_CREATE_TEAM_MEMBER:
if ($this->decisionManager->decide($token, [User::ROLE_SUB_CREATE_USERS])) {
if ($user instanceof Admin) {
return true;
}
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
return $user->getClinic()->getId() === $clinic->getId();
}
break;
case self::VIEW_PROSPECTS:
if ($this->decisionManager->decide($token, [User::ROLE_SUB_LEAD_CAPTURE])) {
if ($user instanceof Admin) {
return false;
}
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
return $user->getClinic()->getId() === $clinic->getId();
}
break;
case self::VIEW_WAITING_LIST:
if ($this->decisionManager->decide($token, [User::ROLE_SUB_WAITING_LIST])) {
if ($user instanceof Admin) {
return false;
}
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
return $user->getClinic()->getId() === $clinic->getId();
}
break;
case self::VIEW_REPORT:
if ($this->decisionManager->decide($token, [User::ROLE_SUB_REPORTING])) {
if ($user instanceof Admin) {
return true;
}
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
return $user->getClinic()->getId() === $clinic->getId();
}
break;
case self::VIEW_LIBRARY:
if ($this->decisionManager->decide($token, [User::ROLE_SUB_LIBRARY])) {
if ($user instanceof Admin) {
return true;
}
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
return $user->getClinic()->getId() === $clinic->getId();
}
break;
case self::EDIT:
if ($this->decisionManager->decide($token, [User::ROLE_SUB_CLINIC_SETUP])) {
if ($user instanceof Admin) {
return true;
}
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
return $user->getClinic()->getId() === $clinic->getId();
}
break;
case self::REMOVE:
if ($this->decisionManager->decide($token, [User::ROLE_SUB_CLINIC_SETUP])) {
if ($user instanceof Admin) {
return true;
}
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
return false;
}
break;
case self::VIEW_NOTIFICATION:
if ($this->decisionManager->decide($token, [User::TYPE_SUPER_CLINIC_ADMIN, User::ROLE_CLINIC_ADMIN])) {
if ($user instanceof Admin) {
return true;
}
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
return $user->getClinic()->getId() === $clinic->getId();
}
break;
case self::VIEW_NOTIFICATION_TWILIO:
if ($this->decisionManager->decide($token, [User::ROLE_SUB_CLINIC_SETUP])) {
if ($user instanceof Admin) {
return true;
}
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
return $user->getClinic()->getId() === $clinic->getId();
}
break;
case self::VIEW_EXTERNAL:
if ($user instanceof Admin) {
return false;
}
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
return $user->getClinic()->getId() === $clinic->getId();
break;
case self::VIEW_CALENDAR:
if ($user instanceof Admin) {
return false;
}
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
if ($user->isCoordinator()) {
return false;
}
return $user->getClinic()->getId() === $clinic->getId();
break;
case self::VIEW_DAY_SHEET:
if ($user instanceof Admin) {
return false;
}
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
return ($this->decisionManager->decide($token, [User::ROLE_CLINIC_ADMIN, User::ROLE_PRACTITIONER, User::ROLE_RECEPTIONIST, User::ROLE_BOOKER, User::ROLE_COORDINATOR]))
&& $user->getClinic()->getId() === $clinic->getId();
break;
case self::VIEW_DAY_SHEET_EDIT:
if ($user instanceof Admin) {
return false;
}
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
return ($this->decisionManager->decide($token, [User::ROLE_CLINIC_ADMIN, User::ROLE_RECEPTIONIST, User::ROLE_BOOKER, User::ROLE_COORDINATOR]))
&& $user->getClinic()->getId() === $clinic->getId();
break;
case self::VIEW_STOCK:
if ($this->decisionManager->decide($token, [User::ROLE_SUB_STOCK])) {
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
return $user->getClinic()->getId() === $clinic->getId();
}
break;
case self::VIEW_STOCK_EDIT:
if ($this->decisionManager->decide($token, [User::ROLE_SUB_STOCK])) {
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
if ($user->isBooker() || $user->isCoordinator()) {
return false;
}
return $user->getClinic()->getId() === $clinic->getId();
}
break;
case self::VIEW_EXTERNAL_INVOICE:
if ($user instanceof Admin) {
return false;
}
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
return ($this->decisionManager->decide($token, [User::ROLE_SUB_INVOICE])) && $user->getClinic()->getId() === $clinic->getId();
break;
case self::CREATE_BOARD:
if ($user instanceof Admin) {
return false;
}
if ($user instanceof SuperClinicAdmin) {
return parent::voteOnAttribute(self::VIEW, $organisation, $token);
}
return ($this->decisionManager->decide($token, [User::ROLE_CLINIC_ADMIN])) && $user->getClinic()->getId() === $clinic->getId();
break;
case self::ROOM:
if ($clinic->getPriceTier()->getType() !== PriceTier::TYPE_STARTER) {
return true;
}
return false;
break;
case self::EQUIPMENT:
if ($clinic->getPriceTier()->getType() !== PriceTier::TYPE_STARTER) {
return true;
}
return false;
break;
case self::DAY_SHEET_BY_TIER:
if ($clinic->getPriceTier()->getType() === PriceTier::TYPE_ENTERPRISE) {
return true;
}
return false;
break;
case self::ONLINE_BOOKING:
if ($clinic->getPriceTier()->getType() !== PriceTier::TYPE_STARTER) {
return true;
}
return false;
break;
}
return false;
}
}