選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

356 行
16KB

  1. <?php
  2. namespace Lc\CaracoleBundle\Controller;
  3. use Doctrine\ORM\EntityManagerInterface;
  4. use Doctrine\ORM\QueryBuilder;
  5. use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection;
  6. use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection;
  7. use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
  8. use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
  9. use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
  10. use EasyCorp\Bundle\EasyAdminBundle\Config\KeyValueStore;
  11. use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
  12. use EasyCorp\Bundle\EasyAdminBundle\Exception\ForbiddenActionException;
  13. use EasyCorp\Bundle\EasyAdminBundle\Exception\InsufficientEntityPermissionException;
  14. use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
  15. use EasyCorp\Bundle\EasyAdminBundle\Security\Permission;
  16. use Lc\CaracoleBundle\Container\Address\AddressContainer;
  17. use Lc\CaracoleBundle\Container\Config\TaxRateContainer;
  18. use Lc\CaracoleBundle\Container\Config\UnitContainer;
  19. use Lc\CaracoleBundle\Container\Credit\CreditHistoryContainer;
  20. use Lc\CaracoleBundle\Container\File\DocumentContainer;
  21. use Lc\CaracoleBundle\Container\Merchant\MerchantContainer;
  22. use Lc\CaracoleBundle\Container\Order\OrderPaymentContainer;
  23. use Lc\CaracoleBundle\Container\Order\OrderProductContainer;
  24. use Lc\CaracoleBundle\Container\Order\OrderProductReductionCatalogContainer;
  25. use Lc\CaracoleBundle\Container\Order\OrderProductRefundContainer;
  26. use Lc\CaracoleBundle\Container\Order\OrderReductionCartContainer;
  27. use Lc\CaracoleBundle\Container\Order\OrderReductionCreditContainer;
  28. use Lc\CaracoleBundle\Container\Order\OrderRefundContainer;
  29. use Lc\CaracoleBundle\Container\Order\OrderShopContainer;
  30. use Lc\CaracoleBundle\Container\Order\OrderStatusContainer;
  31. use Lc\CaracoleBundle\Container\Order\OrderStatusHistoryContainer;
  32. use Lc\CaracoleBundle\Container\PointSale\PointSaleContainer;
  33. use Lc\CaracoleBundle\Container\Product\ProductCategoryContainer;
  34. use Lc\CaracoleBundle\Container\Product\ProductContainer;
  35. use Lc\CaracoleBundle\Container\Product\ProductFamilyContainer;
  36. use Lc\CaracoleBundle\Container\Reduction\ReductionCartContainer;
  37. use Lc\CaracoleBundle\Container\Reduction\ReductionCatalogContainer;
  38. use Lc\CaracoleBundle\Container\Reduction\ReductionCreditContainer;
  39. use Lc\CaracoleBundle\Container\Section\OpeningContainer;
  40. use Lc\CaracoleBundle\Container\Section\SectionContainer;
  41. use Lc\CaracoleBundle\Container\Setting\MerchantSettingContainer;
  42. use Lc\CaracoleBundle\Container\Setting\SectionSettingContainer;
  43. use Lc\CaracoleBundle\Container\User\UserMerchantContainer;
  44. use Lc\CaracoleBundle\Container\User\UserPointSaleContainer;
  45. use Lc\CaracoleBundle\Container\User\VisitorContainer;
  46. use Lc\CaracoleBundle\Doctrine\Extension\FilterMerchantInterface;
  47. use Lc\CaracoleBundle\Doctrine\Extension\FilterMultipleMerchantsInterface;
  48. use Lc\CaracoleBundle\Doctrine\Extension\FilterSectionInterface;
  49. use Lc\CaracoleBundle\Factory\User\UserMerchantFactory;
  50. use Lc\CaracoleBundle\Form\Merchant\DuplicateToOtherMerchantFormType;
  51. use Lc\CaracoleBundle\Form\Section\DuplicateToOtherSectionFormType;
  52. use Lc\CaracoleBundle\Repository\Reduction\ReductionCatalogStore;
  53. use Lc\CaracoleBundle\Resolver\MerchantResolver;
  54. use Lc\CaracoleBundle\Resolver\SectionResolver;
  55. use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
  56. use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto;
  57. use Lc\SovBundle\Component\EntityComponent;
  58. use Lc\SovBundle\Container\File\FileContainer;
  59. use Lc\SovBundle\Container\Newsletter\NewsletterContainer;
  60. use Lc\SovBundle\Container\Reminder\ReminderContainer;
  61. use Lc\SovBundle\Container\Setting\SiteSettingContainer;
  62. use Lc\SovBundle\Container\Site\NewsContainer;
  63. use Lc\SovBundle\Container\Site\PageContainer;
  64. use Lc\SovBundle\Container\Site\SiteContainer;
  65. use Lc\SovBundle\Container\Ticket\TicketContainer;
  66. use Lc\SovBundle\Container\Ticket\TicketMessageContainer;
  67. use Lc\SovBundle\Container\User\GroupUserContainer;
  68. use Lc\SovBundle\Container\User\UserContainer;
  69. use Lc\SovBundle\Factory\User\UserFactory;
  70. use Lc\SovBundle\Translation\TranslatorAdmin;
  71. use Symfony\Component\HttpFoundation\Response;
  72. trait AdminControllerTrait
  73. {
  74. public static function getSubscribedServices()
  75. {
  76. return array_merge(
  77. parent::getSubscribedServices(),
  78. [
  79. 'merchant_resolver' => MerchantResolver::class,
  80. 'section_resolver' => SectionResolver::class,
  81. 'user_factory' => UserFactory::class,
  82. 'user_merchant_factory' => UserMerchantFactory::class,
  83. MerchantResolver::class => MerchantResolver::class,
  84. SectionResolver::class => SectionResolver::class,
  85. AddressContainer::class => AddressContainer::class,
  86. TaxRateContainer::class => TaxRateContainer::class,
  87. UnitContainer::class => UnitContainer::class,
  88. CreditHistoryContainer::class => CreditHistoryContainer::class,
  89. DocumentContainer::class => DocumentContainer::class,
  90. MerchantContainer::class => MerchantContainer::class,
  91. OrderPaymentContainer::class => OrderPaymentContainer::class,
  92. OrderProductContainer::class => OrderProductContainer::class,
  93. OrderProductReductionCatalogContainer::class => OrderProductReductionCatalogContainer::class,
  94. OrderProductRefundContainer::class => OrderProductRefundContainer::class,
  95. OrderReductionCartContainer::class => OrderReductionCartContainer::class,
  96. OrderReductionCreditContainer::class => OrderReductionCreditContainer::class,
  97. OrderRefundContainer::class => OrderRefundContainer::class,
  98. OrderShopContainer::class => OrderShopContainer::class,
  99. OrderStatusContainer::class => OrderStatusContainer::class,
  100. OrderStatusHistoryContainer::class => OrderStatusHistoryContainer::class,
  101. PointSaleContainer::class => PointSaleContainer::class,
  102. ProductCategoryContainer::class => ProductCategoryContainer::class,
  103. ProductContainer::class => ProductContainer::class,
  104. ProductFamilyContainer::class => ProductFamilyContainer::class,
  105. ReductionCartContainer::class => ReductionCartContainer::class,
  106. ReductionCatalogContainer::class => ReductionCatalogContainer::class,
  107. ReductionCreditContainer::class => ReductionCreditContainer::class,
  108. OpeningContainer::class => OpeningContainer::class,
  109. SectionContainer::class => SectionContainer::class,
  110. MerchantSettingContainer::class => MerchantSettingContainer::class,
  111. SectionSettingContainer::class => SectionSettingContainer::class,
  112. UserMerchantContainer::class => UserMerchantContainer::class,
  113. UserPointSaleContainer::class => UserPointSaleContainer::class,
  114. VisitorContainer::class => VisitorContainer::class
  115. ]
  116. );
  117. }
  118. public function configureResponseParameters(KeyValueStore $responseParameters): KeyValueStore
  119. {
  120. $responseParameters = parent::configureResponseParameters($responseParameters);
  121. // affichage du filtre sur section
  122. if ($this->isInstanceOf(FilterSectionInterface::class)) {
  123. $responseParameters->set('display_switch_section', true);
  124. }
  125. return $responseParameters;
  126. }
  127. public function createIndexQueryBuilder(
  128. SearchDto $searchDto,
  129. EntityDto $entityDto,
  130. FieldCollection $fields,
  131. FilterCollection $filters
  132. ): QueryBuilder {
  133. $queryBuilder = parent::createIndexQueryBuilder(
  134. $searchDto,
  135. $entityDto,
  136. $fields,
  137. $filters
  138. );
  139. //TODO Gérer depuis les événements
  140. if ($this->isInstanceOf(FilterMerchantInterface::class)) {
  141. $queryBuilder->andWhereMerchant('entity', $this->get('merchant_resolver')->getCurrent());
  142. }
  143. if ($this->isInstanceOf(FilterMultipleMerchantsInterface::class)) {
  144. $queryBuilder->andWhere(':merchant MEMBER OF entity.merchants');
  145. $queryBuilder->setParameter('merchant', $this->get('merchant_resolver')->getCurrent());
  146. }
  147. if ($this->isInstanceOf(FilterSectionInterface::class)) {
  148. $queryBuilder->andWhereSection('entity', $this->get('section_resolver')->getCurrent());
  149. }
  150. return $queryBuilder;
  151. }
  152. public function duplicateToOtherMerchant(
  153. AdminContext $context,
  154. EntityComponent $entityComponent,
  155. TranslatorAdmin $translatorAdmin,
  156. EntityManagerInterface $em
  157. ) {
  158. if (!$this->isGranted(
  159. Permission::EA_EXECUTE_ACTION,
  160. ['action' => "duplicate", 'entity' => $context->getEntity()]
  161. )) {
  162. throw new ForbiddenActionException($context);
  163. }
  164. if (!$context->getEntity()->isAccessible()) {
  165. throw new InsufficientEntityPermissionException($context);
  166. }
  167. if (!$this->isInstanceOf(FilterMerchantInterface::class)) {
  168. throw new \ErrorException('L\entité n\'est pas lié à un merchant.');
  169. }
  170. $duplicateOtherMerchantForm = $this->createForm(
  171. DuplicateToOtherMerchantFormType::class,
  172. null,
  173. array(
  174. 'entityClass' => $context->getEntity()->getFqcn(),
  175. 'entityId' => $context->getEntity()->getInstance()->getId(),
  176. 'action' => $context->getRequest()->getUri(),
  177. 'attr' => ['id' => 'duplicate-other-merchant-form'],
  178. )
  179. );
  180. $duplicateOtherMerchantForm->handleRequest($context->getRequest());
  181. if ($duplicateOtherMerchantForm->isSubmitted() && $duplicateOtherMerchantForm->isValid()) {
  182. $newEntity = $entityComponent->duplicateEntity($context->getEntity()->getInstance());
  183. $em->create($newEntity);
  184. $merchant = $duplicateOtherMerchantForm->get('merchants')->getData();
  185. $newEntity->setMerchant($merchant);
  186. $em->update($newEntity);
  187. $em->flush();
  188. $url = $this->get(AdminUrlGenerator::class)
  189. ->setAction(Action::EDIT)
  190. ->setEntityId($newEntity->getId())
  191. ->generateUrl();
  192. $this->addFlash(
  193. 'success',
  194. $translatorAdmin->transFlashMessage(
  195. 'duplicateToOtherMerchant',
  196. ['%merchant%' => $merchant->getTitle()]
  197. ),
  198. array()
  199. );
  200. //TODO switch merchant route
  201. return $this->redirect($url);
  202. }
  203. if ($context->getRequest()->isXmlHttpRequest()) {
  204. $response['data'] = $this->renderView(
  205. '@LcCaracole/admin/merchant/modal/duplicate_entity_to_other_merchant.html.twig',
  206. array(
  207. 'form_duplicate_entity_to_other_merchant' => $duplicateOtherMerchantForm->createView(),
  208. )
  209. );
  210. return new Response(json_encode($response));
  211. } else {
  212. throw new \ErrorException('La requête doit être effectué en ajax');
  213. }
  214. }
  215. public function duplicateToOtherSection(
  216. AdminContext $context,
  217. EntityComponent $entityComponent,
  218. TranslatorAdmin $translatorAdmin,
  219. EntityManagerInterface $em
  220. ) {
  221. if (!$this->isGranted(
  222. Permission::EA_EXECUTE_ACTION,
  223. ['action' => "duplicate", 'entity' => $context->getEntity()]
  224. )) {
  225. throw new ForbiddenActionException($context);
  226. }
  227. if (!$context->getEntity()->isAccessible()) {
  228. throw new InsufficientEntityPermissionException($context);
  229. }
  230. if (!$this->isInstanceOf(FilterSectionInterface::class)) {
  231. throw new \ErrorException('L\entité n\'est pas lié à un merchant.');
  232. }
  233. $duplicateOtherSectionForm = $this->createForm(
  234. DuplicateToOtherSectionFormType::class,
  235. null,
  236. array(
  237. 'entityClass' => $context->getEntity()->getFqcn(),
  238. 'entityId' => $context->getEntity()->getInstance()->getId(),
  239. 'action' => $context->getRequest()->getUri(),
  240. 'attr' => ['id' => 'duplicate-other-section-form'],
  241. )
  242. );
  243. $duplicateOtherSectionForm->handleRequest($context->getRequest());
  244. if ($duplicateOtherSectionForm->isSubmitted() && $duplicateOtherSectionForm->isValid()) {
  245. $newEntity = $entityComponent->duplicateEntity($context->getEntity()->getInstance());
  246. $em->create($newEntity);
  247. $section = $duplicateOtherSectionForm->get('sections')->getData();
  248. $newEntity->setSection($section);
  249. $em->update($newEntity);
  250. $em->flush();
  251. $url = $this->get(AdminUrlGenerator::class)
  252. ->setAction(Action::EDIT)
  253. ->setEntityId($newEntity->getId())
  254. ->generateUrl();
  255. $this->addFlash(
  256. 'success',
  257. $translatorAdmin->transFlashMessage(
  258. 'duplicateToOtherSection',
  259. ['%section%' => $section->getTitle()]
  260. ),
  261. array()
  262. );
  263. //TODO switch merchant route
  264. return $this->redirect($url);
  265. }
  266. if ($context->getRequest()->isXmlHttpRequest()) {
  267. $response['data'] = $this->renderView(
  268. '@LcCaracole/admin/merchant/modal/duplicate_entity_to_other_section.html.twig',
  269. array(
  270. 'form_duplicate_entity_to_other_section' => $duplicateOtherSectionForm->createView(),
  271. )
  272. );
  273. return new Response(json_encode($response));
  274. } else {
  275. throw new \ErrorException('La requête doit être effectué en ajax');
  276. }
  277. }
  278. public function buildIndexActions(Actions $actions): void
  279. {
  280. parent::buildIndexActions($actions);
  281. if ($this->isInstanceOf(FilterMerchantInterface::class)) {
  282. $actions->add(Crud::PAGE_INDEX, $this->getDuplicateToOhterMerchantAction());
  283. }
  284. if ($this->isInstanceOf(FilterSectionInterface::class)) {
  285. $actions->add(Crud::PAGE_INDEX, $this->getDuplicateToOhterSectionAction());
  286. }
  287. }
  288. public function getDuplicateToOhterMerchantAction(): Action
  289. {
  290. $duplicateAction = Action::new(
  291. 'duplicateToOtherMerchant',
  292. $this->get('translator_admin')->transAction('duplicateToOtherMerchant'),
  293. 'fa fa-fw fa-copy'
  294. )
  295. ->linkToCrudAction('duplicateToOtherMerchant')
  296. ->setCssClass('text-info in-dropdown duplicate-to-other-merchant duplicate-modal-action');
  297. return $duplicateAction;
  298. }
  299. public function getDuplicateToOhterSectionAction(): Action
  300. {
  301. $duplicateAction = Action::new(
  302. 'duplicateToOtherSection',
  303. $this->get('translator_admin')->transAction('duplicateToOtherSection'),
  304. 'fa fa-fw fa-copy'
  305. )
  306. ->linkToCrudAction('duplicateToOtherSection')
  307. ->setCssClass('text-info in-dropdown duplicate-to-other-section duplicate-modal-action');
  308. return $duplicateAction;
  309. }
  310. }