You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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