src/Admin/UserAdmin.php line 41

  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Admin;
  4. use App\Entity\User;
  5. use App\Enum\RegionEnum;
  6. use App\Entity\Hierarchy;
  7. use App\Enum\EmployeeStatus;
  8. use Sonata\Form\Type\DatePickerType;
  9. use Sonata\Form\Type\CollectionType;
  10. use Sonata\Exporter\ExporterInterface;
  11. use Doctrine\ORM\EntityManagerInterface;
  12. use Sonata\AdminBundle\Admin\AbstractAdmin;
  13. use Symfony\Bundle\SecurityBundle\Security;
  14. use Sonata\AdminBundle\Form\Type\ModelType;
  15. use Sonata\AdminBundle\Datagrid\DatagridMapper;
  16. use Sonata\AdminBundle\Datagrid\ListMapper;
  17. use Sonata\AdminBundle\Form\FormMapper;
  18. use Sonata\AdminBundle\Show\ShowMapper;
  19. use Sonata\AdminBundle\Form\Type\ModelListType;
  20. use Sonata\AdminBundle\Filter\Model\FilterData;
  21. use Symfony\Bridge\Doctrine\Form\Type\EntityType;
  22. use Symfony\Component\Validator\Constraints\Regex;
  23. use Symfony\Component\HttpFoundation\RequestStack;
  24. use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
  25. use Sonata\DoctrineORMAdminBundle\Filter\CallbackFilter;
  26. use Sonata\DoctrineORMAdminBundle\Filter\ChoiceFilter;
  27. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  28. use Symfony\Component\Form\Extension\Core\Type\NumberType;
  29. use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
  30. use Symfony\Component\Form\Extension\Core\Type\PasswordType;
  31. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  32. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  33. final class UserAdmin extends AdminBase
  34. {
  35.     public function __construct($code$class$baseControllerName, protected EntityManagerInterface $entityManager, protected UserPasswordHasherInterface $passwordEncoder, protected AuthorizationCheckerInterface $securityChecker, protected Security $security, protected RequestStack $requestStack)
  36.     {
  37.         parent::__construct($code$class$baseControllerName);
  38.     }
  39.     protected function configureDatagridFilters(DatagridMapper $filter): void
  40.     {
  41.         $filter
  42.             ->add('id')
  43.             ->add('email')
  44.             ->add('firstName',null,  [
  45.                 'show_filter' => true
  46.             ])
  47.             ->add('lastName',null,  [
  48.                 'show_filter' => true
  49.             ])
  50.             ->add('employeeID',null,  [
  51.                 'show_filter' => true
  52.             ])
  53.             ->add('title')
  54.             ->add('hasGuaranteePayments'CallbackFilter::class, [
  55.                 'callback' => static function(ProxyQueryInterface $querystring $aliasstring $fieldFilterData $data): bool {
  56.                     if (!$data->hasValue()) {
  57.                         return false;
  58.                     }
  59.                     if($data->getValue() == 'Yes'){
  60.                         $query->andWhere($alias.'.guaranteeStartDate IS NOT NULL');
  61.                     }
  62.                     if($data->getValue() == 'No'){
  63.                         $query->andWhere($alias.'.guaranteeStartDate IS NULL');
  64.                     }
  65.                     return true;
  66.                 },
  67.                 'field_type' => ChoiceType::class,
  68.                 'field_options' => [
  69.                     'choices' => [
  70.                         'Yes' => 'Yes',
  71.                         'No' => 'No',
  72.                     ],
  73.                 ]
  74.             ])
  75.             ->add('roles',null, [
  76.                 'label' => 'Role',
  77.                 'field_type' => ChoiceType::class,
  78.                 'field_options' => [
  79.                     'choices' => array_flip(User::getRolesList()),
  80.                 ],
  81.             ])
  82.             ->add('employeeStatus'ChoiceFilter::class, [
  83.                 'label' => 'Employee Status',
  84.                 'field_type' => ChoiceType::class,
  85.                 'field_options' => [
  86.                     'choices' => EmployeeStatus::cases(),
  87.                     'choice_label' => function ($choicestring $keymixed $value) {
  88.                         return $choice->title();
  89.                     },
  90.                 ],
  91.                 'show_filter' => true
  92.             ])
  93.             ->add('commissionEligible'null, [
  94.                 'label' => 'Commissionable',
  95.                 'show_filter' => true
  96.             ])
  97.         ;
  98.     }
  99.     protected function configureListFields(ListMapper $list): void
  100.     {
  101.         $list
  102.             ->add('id')
  103.             ->add('rolesLabels''html', [
  104.                 'label' => 'Roles'
  105.             ])
  106.             ->add('title')
  107.             ->add('email')
  108.             ->add('firstName')
  109.             ->add('lastName')
  110.             ->add('managerName')
  111.             ->add('incentAccess')
  112.             ->add('creditEligible')
  113.             ->add('commissionEligible')
  114.             ->add('employeeID')
  115.             ->add('employeeStatus')
  116.             ->add('salary')
  117.             ->add('guaranteeStartDate')
  118.             ->add('guaranteePeriod'null, [
  119.                 'editable' => true,
  120.             ])
  121.             ->add('earningCommissionsStartDate')
  122.             ->add('earningCommissionsPeriod')
  123.             ->add('leaveOfAbsenceStartDate')
  124.             ->add('leaveOfAbsenceEndDate')
  125.             ->add('createdAt')
  126.             ->add(ListMapper::NAME_ACTIONSnull, [
  127.                 'actions' => [
  128.                     'show' => [],
  129.                     'edit' => [],
  130.                     'delete' => [],
  131.                     'impersonate' => [
  132.                         'template' => 'admin/user/impersonate.html.twig'
  133.                     ],
  134.                 ],
  135.             ]);
  136.     }
  137.     protected function configureFormFields(FormMapper $form): void
  138.     {
  139.         $form
  140.             ->tab('Profile')
  141.             ->with('Profile Details:', [
  142.                 'class'       => 'col-md-6',
  143.                 'box_class'   => 'box box-solid box-primary',
  144.             ])
  145.             ->add('roles'ChoiceType::class,[
  146.                 'choices' => array_flip(User::getRolesList()),
  147.                 'multiple' => true,
  148.             ])
  149.             ->add('email')
  150.             ->add('firstName')
  151.             ->add('lastName')
  152.             ->add('plainPassword'RepeatedType::class, [
  153.                 'type' => PasswordType::class,
  154.                 'invalid_message' => 'The password fields must match.',
  155.                 'options' => ['attr' => ['class' => 'password-field']],
  156.                 'required' => false,
  157.                 'first_options'  => ['label' => 'Password (Leave blank if not changing user\'s password)''help' => 'Your password must contain at least 1 uppercase letter, 1 lowercase letter, and 1 number. It must also be 8-20 characters long.'],
  158.                 'second_options' => ['label' => 'Confirm Password'],
  159.                 'constraints' => [
  160.                     new Regex([
  161.                         'pattern' => '/(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,20}/',
  162.                         'message' => 'Your password must contain at least 1 uppercase letter, 1 lowercase letter, and 1 number. It must also be 8-20 characters long.'
  163.                     ])
  164.                 ],
  165.             ])
  166.             ->end()
  167.             ->with('Employment Details:', [
  168.                 'class'       => 'col-md-6',
  169.                 'box_class'   => 'box box-solid box-primary',
  170.             ])
  171.             ->add('employeeID')
  172.             ->add('employeeStatus'ChoiceType::class,[
  173.                 'choices' => EmployeeStatus::cases(),
  174.                 'choice_label' => function ($choicestring $keymixed $value) {
  175.                     return $choice->title();
  176.                 },
  177.             ])
  178.             ->add('hireDate')
  179.             ->add('terminationDate')
  180.             ->end()
  181.             ->end()
  182.             ->tab('Compensation')
  183.             ->add('title')
  184.             ->add('plan')
  185.             ->add('salary')
  186.             ->add('creditEligible')
  187.             ->add('commissionEligible')
  188.             ->end()
  189.             ->end()
  190.             ->tab('Guarantee')
  191.             ->add('guaranteeStartDate'DatePickerType::class, [
  192.                 'required' => false,
  193.                 'label' => 'Guarantee Start Date',
  194.                 'attr' => [
  195.                     'placeholder' => '',
  196.                     'class' => 'w-full date-input'
  197.                 ],
  198.             ])
  199.             ->add('guaranteeAmount'NumberType::class, [
  200.                 'required' => false,
  201.                 'label' => 'Monthly Guarantee Amount ',
  202.                 'attr' => [
  203.                     'placeholder' => '',
  204.                     'class' => 'w-full date-input'
  205.                 ],
  206.             ])
  207.             ->add('guaranteePeriod')
  208.             ->add('earningCommissionsStartDate'DatePickerType::class, [
  209.                 'required' => false,
  210.                 'label' => 'Earning Commissions Start Date',
  211.                 'attr' => [
  212.                     'placeholder' => '',
  213.                     'class' => 'w-full date-input'
  214.                 ],
  215.             ])
  216.             ->add('earningCommissionsPeriod')
  217.             ->end()
  218.             ->end()
  219.             ->tab('Leave of Absence')
  220.             ->with('Leave of Absence Details:', [
  221.                 'class'       => 'col-md-6',
  222.                 'box_class'   => 'box box-solid box-primary',
  223.                 'description' => 'When an employee is on Leave of Absence, their commissions will show $0 on the Payroll Report during the leave period. Commissions earned during leave will be included in the first payroll report after the leave ends.',
  224.             ])
  225.             ->add('leaveOfAbsenceStartDate'DatePickerType::class, [
  226.                 'required' => false,
  227.                 'label' => 'Leave Start Date',
  228.                 'attr' => [
  229.                     'placeholder' => '',
  230.                     'class' => 'w-full date-input'
  231.                 ],
  232.             ])
  233.             ->add('leaveOfAbsenceEndDate'DatePickerType::class, [
  234.                 'required' => false,
  235.                 'label' => 'Leave End Date',
  236.                 'attr' => [
  237.                     'placeholder' => '',
  238.                     'class' => 'w-full date-input'
  239.                 ],
  240.             ])
  241.             ->end()
  242.             ->end()
  243.             ->tab('Regions')
  244.             ->add('userRegions'CollectionType::class, [
  245.                 'by_reference' => false,
  246.                 'type_options' => [
  247.                     'delete' => true,
  248.                 ],
  249.                 'btn_add' => 'Add Region',
  250.             ],[
  251.                 'edit'            => 'inline',
  252.                 'inline'          => 'table',
  253.                 'sortable'        => 'position',
  254.             ])
  255.             ->end()
  256.             ->end()
  257.             ->tab('Positions')
  258.             ->add('positions'CollectionType::class, [
  259.                 'by_reference' => false,
  260.                 'type_options' => [
  261.                     'delete' => true,
  262.                 ],
  263.                 'btn_add' => 'Add Position',
  264.             ],[
  265.                 'edit'            => 'inline',
  266.                 'inline'          => 'table',
  267.                 'sortable'        => 'position',
  268.             ])
  269.             ->end()
  270.             ->end()
  271.             ->tab('Hierarchy')
  272.             ->add('hierarchies'CollectionType::class, [
  273.                 'label' => false,
  274.                 'type_options' => [
  275.                     'delete' => true,
  276.                 ]
  277.             ],[
  278.                 'edit'            => 'inline',
  279.                 'inline'          => 'inline',
  280.                 'sortable'        => 'position',
  281.             ])
  282.             ->end()
  283.         ;
  284.     }
  285.     protected function configureShowFields(ShowMapper $show): void
  286.     {
  287.         $show
  288.             ->add('id')
  289.             ->add('email')
  290.             ->add('roles')
  291.             ->add('password')
  292.             ->add('incentAccess')
  293.             ->add('userRegions')
  294.             ->add('groupName')
  295.             ->add('creditEligible')
  296.             ->add('commissionEligible')
  297.             ->add('employeeID')
  298.             ->add('employeeStatus')
  299.             ->add('guaranteePeriod')
  300.             ->add('guaranteeStartDate')
  301.             ->add('firstName')
  302.             ->add('lastName')
  303.             ->add('managerName')
  304.             ->add('guaranteeAmount')
  305.             ->add('guaranteeAmountUnitType')
  306.             ->add('guaranteePeriodUnitType')
  307.             ->add('middleName')
  308.             ->add('effectiveStartDate')
  309.             ->add('description')
  310.             ->add('hireDate')
  311.             ->add('terminationDate')
  312.             ->add('personalTarget')
  313.             ->add('proratedPersonalTarget')
  314.             ->add('personalCurrency')
  315.             ->add('proratedSalary')
  316.             ->add('paymentCurrency')
  317.             ->add('salary')
  318.             ->add('salaryCurrency')
  319.             ->add('leaveOfAbsenceStartDate')
  320.             ->add('leaveOfAbsenceEndDate')
  321.         ;
  322.     }
  323.     public function preUpdate($object): void // $object is an instance of App\Entity\User as specified in services.yaml
  324.         $plainPassword $object->plainPassword;
  325.         if($plainPassword) {
  326.             $object->setPassword(
  327.                 $this->passwordEncoder->hashPassword(
  328.                     $object,
  329.                     $plainPassword
  330.                 )
  331.             );
  332.         }
  333.     }
  334.     public function prePersist($object): void // $object is an instance of App\Entity\User as specified in services.yaml
  335.         $plainPassword $object->plainPassword;
  336.         if(!$plainPassword){
  337.             $plainPassword uniqid();
  338.         }
  339.         $object->setPassword(
  340.             $this->passwordEncoder->hashPassword(
  341.                 $object,
  342.                 $plainPassword
  343.             )
  344.         );
  345.     }
  346.     public function configureExportFields(): array{
  347.         return [
  348.             'Id' => 'id',
  349.             'Title' => 'title',
  350.             'Email' => 'email',
  351.             'First Name' => 'firstName',
  352.             'Last Name' => 'lastName',
  353.             'Manager Name' => 'managerName',
  354.             'Incent Access' => 'incentAccess',
  355.             'Credit Eligible' => 'creditEligible',
  356.             'Commission Eligible' => 'commissionEligible',
  357.             'Employee ID' => 'employeeID',
  358.             'Employee Status' => 'employeeStatus',
  359.             'Guarantee Start Date' => 'guaranteeStartDate',
  360.             'Guarantee Period' => 'guaranteePeriod',
  361.             'Earning Commissions Start Date' => 'earningCommissionsStartDate',
  362.             'Earning Commissions Period' => 'earningCommissionsPeriod',
  363.             'Leave of Absence Start Date' => 'leaveOfAbsenceStartDate',
  364.             'Leave of Absence End Date' => 'leaveOfAbsenceEndDate',
  365.         ];
  366.     }
  367. }