src/Controller/Admin/ArticleBaseCrudController.php line 33

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Admin;
  3. use App\Entity\Article;
  4. use App\Service\Article\ArticleService;
  5. use App\Service\Center\CenterService;
  6. use App\Service\Spreadsheet\SpreadsheetService;
  7. use App\Service\User\UserService;
  8. use App\Service\Warehouse\WarehouseService;
  9. use App\Util\UserRole;
  10. use Doctrine\ORM\EntityManagerInterface;
  11. use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
  12. use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
  13. use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
  14. use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
  15. use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
  16. use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
  17. use EasyCorp\Bundle\EasyAdminBundle\Dto\BatchActionDto;
  18. use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
  19. use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
  20. use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField;
  21. use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField;
  22. use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
  23. use EasyCorp\Bundle\EasyAdminBundle\Filter\BooleanFilter;
  24. use EasyCorp\Bundle\EasyAdminBundle\Filter\EntityFilter;
  25. use EasyCorp\Bundle\EasyAdminBundle\Filter\TextFilter;
  26. use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
  27. use PhpOffice\PhpSpreadsheet\Writer\IWriter;
  28. use Symfony\Component\HttpFoundation\StreamedResponse;
  29. use Symfony\Contracts\Translation\TranslatorInterface;
  30. abstract class ArticleBaseCrudController extends AbstractCrudController
  31. {
  32.     use UserRole;
  33.     const LENGHTSHORTNAME 90;
  34.     private const CONTENT_TYPE 'application/vnd.ms-excel';
  35.     private const WRITER_TYPE 'Xlsx';
  36.     private const FILENAME_ARTICLES 'articles.xlsx';
  37.     private const HEADERS_ARTICLES =
  38.         [
  39.             'code' => 'Referencia interna',
  40.             'name' => 'Nombre completo',
  41.             'warehouse' => 'AlmacĂ©n central',
  42.             'active' => 'Activo',
  43.         ];
  44.     private $translator;
  45.     private $warehouseService;
  46.     private $adminUrlGenerator;
  47.     private $centerService;
  48.     private $articleService;
  49.     private $userService;
  50.     private SpreadsheetService $spreadsheetService;
  51.     public function __construct(
  52.         TranslatorInterface $translator,
  53.         AdminUrlGenerator $adminUrlGenerator,
  54.         WarehouseService $warehouseService,
  55.         CenterService $centerService,
  56.         ArticleService $articleService,
  57.         UserService $userService,
  58.         SpreadsheetService $spreadsheetService
  59.     ) {
  60.         $this->translator $translator;
  61.         $this->adminUrlGenerator $adminUrlGenerator;
  62.         $this->warehouseService $warehouseService;
  63.         $this->centerService $centerService;
  64.         $this->articleService $articleService;
  65.         $this->userService $userService;
  66.         $this->spreadsheetService $spreadsheetService;
  67.     }
  68.     public static function getEntityFqcn(): string
  69.     {
  70.         return Article::class;
  71.     }
  72.     public function configureCrud(Crud $crud): Crud
  73.     {
  74.         return $crud
  75.             ->setPageTitle(Crud::PAGE_INDEX$this->translator->trans('pages.article.index.title'))
  76.             ->setPageTitle(Crud::PAGE_NEW$this->translator->trans('pages.article.new.title'))
  77. /*            ->setPageTitle(Crud::PAGE_EDIT, fn (Article $article) => $this->translator->trans('pages.article.edit.title',
  78.                 [
  79.                     'article' => $article->getShortName(),
  80.                 ]))
  81.             ->setPageTitle(Crud::PAGE_DETAIL, fn (Article $article) => $this->translator->trans('pages.article.view.title',
  82.                 [
  83.                     'article' => $article->getShortName(),
  84.                 ]))*/
  85.             ->setEntityLabelInSingular($this->translator->trans('pages.article.common.article'))
  86.             ->setSearchFields(['code''completeName''warehouse.name''active'])
  87.             ->setDefaultSort(['id' => 'ASC'])
  88.             ->setPaginatorPageSize(250)
  89.             ->overrideTemplate('crud/index''admin/article/index.html.twig')
  90.             ;
  91.     }
  92.     public function configureActions(Actions $actions): Actions
  93.     {
  94.         //Permissions
  95.         $actions
  96.             ->setPermission(Action::DETAIL$this->getUser()->getRoles()[0])
  97.             ->setPermission(Action::EDIT$this->roleWarehouse)
  98.             ->setPermission(Action::NEW, $this->roleWarehouse)
  99.             ->setPermission(Action::DELETE$this->roleSuperAdmin)
  100.             ->setPermission(Action::BATCH_DELETE$this->roleSuperAdmin);
  101.         //Create custom Actions
  102.         $exchangeArticleAction =
  103.             Action::new('exchange_article'false'fas fa-exchange-alt')
  104.                 ->setHtmlAttributes(['title' => $this->translator->trans('pages.article.common.internal.exchange')])
  105.                 ->linkToCrudAction('exchangeArticleAction')
  106.                 ->displayIf(
  107.                     function ($entity) {
  108.                         return $this->roleHasPermission($entity);
  109.                     }
  110.                 );
  111.         $listLocations =
  112.             Action::new('list_locations'false'fas fa-map-marker-alt')
  113.                 ->linkToCrudAction('listLocationAction')
  114.                 ->setHtmlAttributes(['title' => $this->translator->trans('pages.article.common.internal.location')]);
  115.         $printAllArticleLocationsCustomAction =
  116.             Action::new('print_all_article_locations'false'fas fa-print')
  117.                 ->linkToCrudAction('printLabelAction')
  118.                 ->setHtmlAttributes(['title' => $this->translator->trans('pages.article.common.internal.print')]);
  119.         $exportExcelCustomBatchAction Action::new('export_excel_batch_action'false)
  120.             ->linkToCrudAction('exportExcelBatchAction')
  121.             ->setIcon('fa fa-file-excel');
  122.         //Set actions
  123.         $actions
  124.             ->add(Crud::PAGE_INDEX$exchangeArticleAction)
  125.             ->add(Crud::PAGE_INDEX$printAllArticleLocationsCustomAction)
  126.             ->add(Crud::PAGE_INDEX$listLocations)
  127.             ->add(Crud::PAGE_INDEXAction::DETAIL)
  128.             ->addBatchAction($exportExcelCustomBatchAction)
  129.             ->update(Crud::PAGE_INDEXAction::DETAIL, function (Action $action) {
  130.                 return $action->setIcon('fas fa-eye')->setLabel(false)
  131.                     ->setHtmlAttributes(['title' => $this->translator->trans('pages.article.common.internal.detail')])
  132.                     ;
  133.             })
  134.             ->update(Crud::PAGE_INDEXAction::EDIT, function (Action $action) {
  135.                 return $action->setIcon('fas fa-edit')->setLabel(false)
  136.                     ->setHtmlAttributes(['title' => $this->translator->trans('pages.article.common.internal.edit')])
  137.                     ->displayIf(
  138.                         function ($entity) {
  139.                             return $this->roleHasPermission($entity);
  140.                         }
  141.                     );
  142.             })
  143.             ->update(Crud::PAGE_INDEXAction::DELETE, function (Action $action) {
  144.                 return $action->setIcon('fas fa-trash-alt')->setLabel(false);
  145.             })
  146.             ->update(Crud::PAGE_INDEXAction::BATCH_DELETE, function (Action $action) {
  147.                 return $action->setIcon('fas fa-trash-alt')->setLabel(false);
  148.             })
  149.         ;
  150.         return $actions;
  151.     }
  152.     //This function will never run. Override in admin/level/index.html.twig
  153.     public function exchangeArticleAction(AdminContext $context)
  154.     {
  155.         $url $this->adminUrlGenerator
  156.             ->setController(ArticleCrudController::class)
  157.             ->setAction(Action::INDEX)
  158.             ->generateUrl();
  159.         return $this->redirect($url);
  160.     }
  161.     //This function will never run. Override in admin/location/index.html.twig
  162.     public function printLabelAction(AdminContext $context)
  163.     {
  164.         $url $this->adminUrlGenerator
  165.             ->setController(ArticleCrudController::class)
  166.             ->setAction(Action::INDEX)
  167.             ->generateUrl();
  168.         return $this->redirect($url);
  169.     }
  170.     public function configureFilters(Filters $filters): Filters
  171.     {
  172.         return $filters
  173.             ->add(TextFilter::new('code'$this->translator->trans('pages.article.index.filters.code')))
  174.             ->add(TextFilter::new('completeName'$this->translator->trans('pages.article.index.filters.completeName')))
  175.             ->add(EntityFilter::new('warehouse'$this->translator->trans('pages.article.index.filters.warehouse')))
  176.             ->add(BooleanFilter::new('active'$this->translator->trans('pages.article.index.filters.active')))
  177.             ;
  178.     }
  179.     public function configureFields(string $pageName): iterable
  180.     {
  181.         $fields = [];
  182.         $code TextField::new('code'$this->translator->trans('pages.article.common.code'))
  183.             ->setMaxLength(255)->setFormTypeOption('attr', ['maxlength' => 255]);
  184.         $warehouse AssociationField::new('warehouse'$this->translator->trans('pages.article.common.warehouse'));
  185.         $active BooleanField::new('active'$this->translator->trans('pages.article.common.active'));
  186.         if (Crud::PAGE_INDEX === $pageName) {
  187.             $fields[] = $code;
  188.             $fields[] = TextField::new('completeName'$this->translator->trans('pages.article.common.completeName'))
  189.                 ->setMaxLength(255);
  190.             $fields[] = $warehouse;
  191.             $fields[] = $active->setFormTypeOption('disabled''disabled');
  192.         } elseif (Crud::PAGE_NEW === $pageName || Crud::PAGE_EDIT === $pageName || Crud::PAGE_DETAIL === $pageName) {
  193.             $fields[] = $code->setRequired(true);
  194.             $fields[] = TextareaField::new('completeName'$this->translator->trans('pages.article.common.completeName'))
  195.                 ->setRequired(true)->setMaxLength(255)->setFormTypeOption('attr', ['maxlength' => 255]);
  196.             $fields[] = TextField::new('shortName'$this->translator->trans('pages.article.common.shortName'))
  197.                 ->setRequired(false)->setMaxLength(self::LENGHTSHORTNAME)->setFormTypeOption('attr', ['maxlength' => self::LENGHTSHORTNAME])
  198.                 ->setHelp($this->translator->trans('pages.article.common.help_shortName'));
  199.             $fields[] = $warehouse->setRequired(true)->renderAsNativeWidget(true)
  200.                 ->setFormTypeOption(
  201.                     'query_builder', function () {
  202.                         return $this->warehouseService->getWarehousesByUser($this->getUser());
  203.                     });
  204.             $fields[] = IntegerField::new('expirationPeriod'$this->translator->trans('pages.article.common.expirationPeriod'))
  205.                 ->setRequired(false)
  206.                 ->setHelp($this->translator->trans('pages.article.common.help_expirationPeriod'));
  207.             $fields[] = IntegerField::new('packingQuantity'$this->translator->trans('pages.article.common.packingQuantity'))
  208.                 ->setRequired(false);
  209. //            $fields[] = TextField::new('measurementUnit', $this->translator->trans('pages.article.common.measurementUnit'));
  210.             $fields[] = TextareaField::new('comments'$this->translator->trans('pages.article.common.comments'))
  211.                 ->setRequired(false)->setMaxLength(255)->setFormTypeOption('attr', ['maxlength' => 255]);
  212.             $fields[] = $active;
  213.         }
  214.         return $fields;
  215.     }
  216.     public function createEntity(string $entityFqcn)
  217.     {
  218.         return parent::createEntity($entityFqcn)
  219.             ->setMeasurementUnit($this->articleService->getMeasurementUnit());
  220.     }
  221.     public function index(AdminContext $context)
  222.     {
  223.         $context->getAssets()->addJsFile('js/article/article-index.js');
  224.         $context->getAssets()->addCssFile('css/exchange/article-index.css');
  225.         $context->getAssets()->addJsFile('js/common/modal-print.js');
  226.         $context->getAssets()->addCssFile('css/common/modal-print.css');
  227.         return parent::index($context);
  228.     }
  229.     public function persistEntity(EntityManagerInterface $entityManager$entityInstance): void
  230.     {
  231.         $this->setShortNameArticle($entityInstance);
  232.         parent::persistEntity($entityManager$entityInstance);
  233.     }
  234.     public function updateEntity(EntityManagerInterface $entityManager$entityInstance): void
  235.     {
  236.         $this->setShortNameArticle($entityInstance);
  237.         parent::updateEntity($entityManager$entityInstance);
  238.     }
  239.     public function deleteEntity(EntityManagerInterface $entityManager$entityInstance): void
  240.     {
  241.         if (count($entityInstance->getPacts())) {
  242.             $this->addFlash(
  243.                 'danger',
  244.                 $this->translator->trans('pages.article.common.flashMessage.errorDeletePact')
  245.             );
  246.         } elseif (count($entityInstance->getLocations())) {
  247.             $this->addFlash(
  248.                 'danger',
  249.                 $this->translator->trans('pages.article.common.flashMessage.errorDeleteLocation')
  250.             );
  251.         } else {
  252.             parent::deleteEntity($entityManager$entityInstance);
  253.         }
  254.     }
  255.     public function listLocationAction(AdminContext $context)
  256.     {
  257.         $url $this->adminUrlGenerator
  258.             ->setController(LocationCrudController::class)
  259.             ->setAction(Action::INDEX)
  260.             ->setEntityId(null)
  261.             ->set('articleId'$context->getEntity()->getInstance()->getId())
  262.             ->generateUrl();
  263.         return $this->redirect($url);
  264.     }
  265.     public function exportExcelBatchAction(BatchActionDto $batchActionDto)
  266.     {
  267.         $articles = [];
  268.         foreach ($batchActionDto->getEntityIds() as $id) {
  269.             $articles[] = $this->articleService->getExportArticleById($id);
  270.         }
  271.         array_unshift($articlesself::HEADERS_ARTICLES);
  272.         $writer $this->spreadsheetService->createWriter($articlesself::WRITER_TYPE);
  273.         return $this->generateStreamedResponse($writerself::FILENAME_ARTICLESself::CONTENT_TYPE);
  274.     }
  275.     private function generateStreamedResponse(IWriter $writerstring $fileNamestring $contentType): StreamedResponse
  276.     {
  277.         $response = new StreamedResponse(
  278.             function () use ($writer) {
  279.                 $writer->save('php://output');
  280.             }
  281.         );
  282.         $response->headers->set('Content-Type'$contentType);
  283.         $response->headers->set('Content-Disposition''attachment;filename="'.$fileName.'"');
  284.         $response->headers->set('Cache-Control''max-age=0');
  285.         return $response;
  286.     }
  287.     private function setShortNameArticle($entityInstance): void
  288.     {
  289.         if (!$entityInstance->getShortName()) {
  290.             $entityInstance->setShortName(substr($entityInstance->getCompleteName(), 0self::LENGHTSHORTNAME));
  291.         }
  292.     }
  293.     private function roleHasPermission(Article $entity)
  294.     {
  295.         if (
  296.             in_array($this->roleWarehouse$this->getUser()->getRoles()) &&
  297.             !$this->userService->checkIfHasWarehouse($entity->getWarehouse()
  298.             )
  299.         ) {
  300.             return false;
  301.         }
  302.         if (
  303.             in_array($this->roleAdmin$this->getUser()->getRoles()) &&
  304.             !$this->userService->checkIfHasWarehouse($entity->getWarehouse()
  305.             )
  306.         ) {
  307.             return false;
  308.         }
  309.         if (
  310.             in_array($this->roleService$this->getUser()->getRoles())
  311.         ) {
  312.             return false;
  313.         }
  314.         return true;
  315.     }
  316. }