No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

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