src/Controller/Backend/EaAdminController.php line 45

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Backend;
  3. use App\Entity\DocToSignModel;
  4. use App\Entity\DocumentDefinition;
  5. use App\Entity\DocumentDefinitionLink;
  6. use App\Entity\DocumentQuestion;
  7. use App\Entity\EngagementLetterData;
  8. use App\Entity\EngagementLetterDefinition;
  9. use App\Entity\EngagementLetterInstance;
  10. use App\Entity\ProductData;
  11. use App\Entity\ProductDefinition;
  12. use App\Entity\ProductQuestion;
  13. use App\Entity\Quote;
  14. use App\Form\DocumentDefinitionType;
  15. use App\Form\EngagementLetterDefinitionType;
  16. use App\Form\ImportISAGIArticlesType;
  17. use App\Form\ProductDefinitionType;
  18. use App\Form\UploadType;
  19. use App\Model\Entity\AccountInterface;
  20. use App\Service\ApodisFormsManager;
  21. use App\Service\ArticlesISAGIManager;
  22. use App\Service\DocToSignManager;
  23. use App\Service\EngagementLetterManager;
  24. use App\Service\MailchimpManager;
  25. use App\Service\SignatureManager;
  26. use App\Service\UserManager;
  27. use Craue\ConfigBundle\Util\Config;
  28. use JMS\Serializer\SerializerInterface as JMSSerializerInterface;
  29. use Swift_Mailer;
  30. use Swift_Message;
  31. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  32. use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
  33. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  34. use Symfony\Component\Form\Form;
  35. use Symfony\Component\Form\FormBuilder;
  36. use Symfony\Component\HttpFoundation\File\File;
  37. use Symfony\Component\HttpFoundation\Request;
  38. use Symfony\Component\HttpFoundation\Response;
  39. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  40. use Symfony\Component\Routing\Annotation\Route;
  41. use Twig\Environment;
  42. class EaAdminController extends EaBackendController
  43. {
  44.     protected $engagementLetterManager;
  45.     protected $signatureManager;
  46.     protected $serializer;
  47.     protected $formsManager;
  48.     protected $docToSignManager;
  49.     protected $twig;
  50.     protected $mailer;
  51.     protected $params;
  52.     protected $projectDir;
  53.     public function __construct(
  54.         EngagementLetterManager $engagementLetterManager,
  55.         SignatureManager $signatureManager,
  56.         UserManager $userManager,
  57.         ApodisFormsManager $formsManager,
  58.         DocToSignManager $docToSignManager,
  59.         JMSSerializerInterface $serializer,
  60.         Environment $twig,
  61.         Swift_Mailer $mailer,
  62.         ParameterBagInterface $params,
  63.         string $projectDir
  64.     ) {
  65.         parent::__construct($userManager);
  66.         $this->engagementLetterManager $engagementLetterManager;
  67.         $this->signatureManager $signatureManager;
  68.         $this->formsManager $formsManager;
  69.         $this->docToSignManager $docToSignManager;
  70.         $this->serializer $serializer;
  71.         $this->twig $twig;
  72.         $this->mailer $mailer;
  73.         $this->params $params;
  74.         $this->projectDir $projectDir;
  75.     }
  76.     public function send_signatureAction() {
  77.         $quote $this->em->find(Quote::class, $this->request->get('id'));
  78.         $pdf_paths $this->engagementLetterManager->prepareDocuments($quote);
  79.         $this->signatureManager->generateEngagementLetterEnvelope($quote->getEngagementLetterInstance(), $quote->getCustomer(), $pdf_pathstrue);
  80.         $quote->getEngagementLetterInstance()->setState(EngagementLetterInstance::STATE_CREATED);
  81.         $quote->setState(Quote::STATE_FINISHED);
  82.         $quote $this->em->merge($quote);
  83.         $this->em->flush();
  84.         $this->addFlash('success'"Le lien de signature a été envoyé à l'adhérent.");
  85.         return $this->redirectToRoute('easyadmin', [
  86.             'entity' => 'Quote',
  87.             'action' => 'list',
  88.             'menuIndex' => 1,
  89.             'submenuIndex' => 0,
  90.         ]);
  91.     }
  92.     public function downloadDocToSignAction() {
  93.         //\\@todo
  94.         return $this->redirectToRoute('easyadmin', [
  95.             'entity' => 'DocToSign',
  96.             'action' => 'list',
  97.             'menuIndex' => 2,
  98.             'submenuIndex' => 1,
  99.         ]);
  100.     }
  101.     public function downloadDocToSignModelAction() {
  102.         $do_to_sign $this->em->find(DocToSignModel::class, $this->request->get('id'));
  103.         $filepath $this->projectDir '/private/doc_to_sign_models/' $do_to_sign->getFilename();
  104.         if(!is_file($filepath)) {
  105.             throw new NotFoundHttpException();
  106.         }
  107.         $file = new File($filepath);
  108.         return $this->file($file);
  109.     }
  110.     protected function removeDocToSignModelEntity($entity) {
  111.         $this->docToSignManager->deleteDocModel($entity->getFilename());
  112.         parent::removeEntity($entity);
  113.     }
  114.     protected function updateDocToSignModelEntity(DocToSignModel $entityForm $form) {
  115.         $uploader_data $form->get('file_upload')->getData();
  116.         if($uploader_data['delete'] === true) {
  117.             $this->docToSignManager->deleteDocModel($entity->getFilename());
  118.         }
  119.         if(!empty($uploader_data['uploaded_file'])) {
  120.             $filename $this->docToSignManager->uploadDocModel($uploader_data['uploaded_file']);
  121.             $entity->setFilename($filename);
  122.         }
  123.         $entity->setUpdatedAt(new \Datetime()); // arbitrary data to force entity refresh
  124.         parent::updateEntity($entity);
  125.     }
  126.     protected function persistDocToSignModelEntity(DocToSignModel $entityForm $form) {
  127.         $filename $this->docToSignManager->uploadDocModel($form->get('file_upload')->getData()['uploaded_file']);
  128.         $entity->setFilename($filename);
  129.         parent::persistEntity($entity);
  130.     }
  131.     protected function createDocToSignModelEntityFormBuilder(DocToSignModel $entity$view): FormBuilder {
  132.         $builder parent::createEntityFormBuilder($entity$view);
  133.         if($view === 'edit') {
  134.             $options $builder->get('file_upload')->getOptions();
  135.             $options['data'] = [
  136.                 'filename' => $entity->getFilename(),
  137.             ];
  138.             $builder->add('file_upload'UploadType::class, $options);
  139.         }
  140.         return $builder;
  141.     }
  142.     protected function createCustomerAccountEntityFormBuilder($entity$view): FormBuilder {
  143.         $builder parent::createEntityFormBuilder($entity$view);
  144.         //--- Forms
  145.         $options $builder->get('forms_definitions')->getOptions();
  146.         $forms_definitions $this->formsManager->getFormsDefinitions();
  147.         $options['choices'] = [];
  148.         foreach($forms_definitions as $form_definition) {
  149.             $options['choices'][$form_definition['name']] = $form_definition['uuid'];
  150.         }
  151.         if($view === 'edit') {
  152.             $customer_forms $this->formsManager->getCustomerFormsList($entity->getUuid());
  153.             $options['data'] = [];
  154.             foreach($customer_forms as $form_instance) {
  155.                 $options['data'][] = $form_instance['formDefinition']['uuid'];
  156.             }
  157.         }
  158.         $builder->add('forms_definitions'ChoiceType::class, $options);
  159.         //--- Send mail
  160.         if($view === 'new') {
  161.             $options $builder->get('send_mail')->getOptions();
  162.             $options['data'] = true;
  163.             $builder->add('send_mail'CheckboxType::class, $options);
  164.         }
  165.         return $builder;
  166.     }
  167.     protected function persistManagerAccountEntity(AccountInterface $entity): void {
  168.         $entity->getUser()->setRole('ROLE_MANAGER');
  169.         parent::persistEntity($entity);
  170.     }
  171.     protected function persistAgentAccountEntity(AccountInterface $entity): void {
  172.         $entity->getUser()->setRole('ROLE_AGENT');
  173.         parent::persistEntity($entity);
  174.     }
  175.     protected function persistCustomerAccountEntity($entity) {
  176.         $entity->getUser()->setRole('ROLE_CUSTOMER');
  177.         parent::persistEntity($entity);
  178.         $this->updateCustomerAccountEntity($entity);
  179.     }
  180.     protected function updateCustomerAccountEntity($entity) {
  181.         $entity->getUser()->setRole('ROLE_CUSTOMER');
  182.         if(!empty($entity->getIdentifier())) {
  183.             $entity->getUser()->setUsername($entity->getIdentifier());
  184.         } else {
  185.             $entity->getUser()->setUsername(null);
  186.         }
  187.         if(array_key_exists('forms_definitions'$this->request->get('customeraccount'))) {
  188.             $this->formsManager->setCustomerFormsInstances($entity->getUuid(), $this->request->get('customeraccount')['forms_definitions']);
  189.         } else {
  190.             $this->formsManager->setCustomerFormsInstances($entity->getUuid());
  191.         }
  192.         parent::updateEntity($entity);
  193.         if(array_key_exists('send_mail'$this->request->get('customeraccount'))) {
  194.             $this->sendMailToCustomer($entity);
  195.         }
  196.     }
  197.     protected function sendMailToCustomer($entity$isNew false) {
  198.         $message = (new Swift_Message())
  199.             ->setSubject("Votre compte adhérent")
  200.             ->setFrom($this->params->get('swift_mail_from'))
  201.             ->setTo($entity->getEmail())
  202.             ->setBody(
  203.                 $this->twig->render('Mail/customer_account_infos.html.twig', [
  204.                     'is_new' => $isNew,
  205.                     'login' => $entity->getUser()->getUsername() ?? $entity->getUser()->getEmail(),
  206.                     'password' => $this->request->get('customeraccount')['user']['plainPassword']['first'] ?? null,
  207.                     'identifier' => $entity->getIdentifier() ?? null,
  208.                     'agent_name' => !empty($entity->getAgent()) ? $entity->getAgent()->getFullName() : null,
  209.                     'has_form' => array_key_exists('forms_definitions'$this->request->get('customeraccount')),
  210.                 ]),
  211.                 'text/html',
  212.                 'utf8'
  213.             )
  214.         ;
  215.         $this->mailer->send($message);
  216.     }
  217.     protected function newProductDefinitionAction(): Response {
  218.         return $this->editProductDefinitionAction();
  219.     }
  220.     protected function editProductDefinitionAction(): Response {
  221.         $product_definition null;
  222.         $previous_button false;
  223.         $next_button true;
  224.         $finish_button false;
  225.         $question_add_button false;
  226.         $question_previous_button false;
  227.         $question_next_button false;
  228.         $question_finish_button false;
  229.         $question_cancel_button false;
  230.         $op 'edit';
  231.         $current_step $this->request->request->get('product_definition')['current_step'] ?? 0;
  232.         $question_current_step $this->request->request->get('product_definition')['draftQuestion']['current_step'] ?? -1;
  233.         $stored_product_definition $this->request->request->get('product_definition')['stored_data'] ?? null;
  234.         if(!empty($stored_product_definition)) {
  235.             $product_definition $this->serializer->deserialize($stored_product_definitionProductDefinition::class, 'json');
  236.             //Doctrine can't merge non persisted entities (new questions). Such entities are considered as 'dirty'.
  237.             foreach($product_definition->getQuestions() as $product_question) {
  238.                 $product_question->setProductDefinition($product_definition);
  239.                 if($product_question->getId() == null) {
  240.                     $this->em->persist($product_question);
  241.                 }
  242.             }
  243.             foreach($product_definition->getPriceLinesDefinitions() as $price_line_def) {
  244.                 $price_line_def->setProductDefinition($product_definition);
  245.                 if($price_line_def->getId() == null) {
  246.                     $this->em->persist($price_line_def);
  247.                 }
  248.             }
  249.             foreach($product_definition->getDistributionLinesDefinitions() as $distribution_line_def) {
  250.                 $distribution_line_def->setProductDefinition($product_definition);
  251.                 if($distribution_line_def->getId() == null) {
  252.                     $this->em->persist($distribution_line_def);
  253.                 }
  254.             }
  255.             $product_definition $this->em->merge($product_definition); // from now, product definition is managed.
  256.             foreach($product_definition->getQuestions() as $product_question) {
  257.                 if($product_question->getRemoveFlag() === true) {
  258.                     $data_to_delete $this->em->getRepository(ProductData::class)->findBy(['productQuestion' => $product_question]);
  259.                     foreach($data_to_delete as $data) {
  260.                         $this->em->remove($data);
  261.                     }
  262.                     $this->em->remove($product_question);
  263.                 }
  264.             }
  265.             foreach($product_definition->getPriceLinesDefinitions() as $price_line_def) {
  266.                 if($price_line_def->getRemoveFlag() === true) {
  267.                     $this->em->remove($price_line_def);
  268.                 }
  269.             }
  270.             foreach($product_definition->getDistributionLinesDefinitions() as $distribution_line_def) {
  271.                 if($distribution_line_def->getRemoveFlag() === true) {
  272.                     $this->em->remove($distribution_line_def);
  273.                 }
  274.             }
  275.         } else {
  276.             if(!empty($this->request->get('id'))) {
  277.                 $product_definition $this->em->find(ProductDefinition::class, $this->request->get('id'));
  278.                 $stored_product_definition $this->serializer->serialize($product_definition'json');
  279.                 $current_step 1;
  280.             } else {
  281.                 $product_definition = new ProductDefinition();
  282.                 $this->em->persist($product_definition); // from now, product definition is managed.
  283.                 $product_definition->setDraftQuestion(new ProductQuestion());
  284.             }
  285.         }
  286.         if(empty($product_definition->getId())) {
  287.             $op 'new';
  288.         }
  289.         $form $this->createForm(ProductDefinitionType::class, $product_definition, [
  290.             'validation_groups' => [
  291.                 'Step_' $current_step '_' $op,
  292.                 'Question_step_' $question_current_step '_' $op,
  293.             ],
  294.         ]);
  295.         $form->get('current_step')->setData($current_step);  // has PRE_SET_DATA event listener
  296.         $form->get('stored_data')->setData($stored_product_definition);
  297.         if($form->has('draftQuestion')) {
  298.             $form->get('draftQuestion')->get('current_step')->setData($question_current_step); // has PRE_SET_DATA event listener
  299.         }
  300.         $form->handleRequest($this->request);
  301.         $next_step $current_step;
  302.         $question_next_step $question_current_step;
  303.         $submit_action $this->request->request->get('submit-action');
  304.         if($form->isSubmitted() &&
  305.             (in_array($submit_action, ['previous''question_previous''question_cancel']) || $form->isValid())) {
  306.             $product_definition $form->getData();
  307.             switch($submit_action) {
  308.                 case 'previous':
  309.                     $next_step $current_step 1;
  310.                     // Special case : ISA products definitions don't have questions. Skipping step 2.
  311.                     if($form->getData()->getProductType() == 'isa' && $next_step == 2) {
  312.                         $next_step 1;
  313.                     }
  314.                     if($next_step == 2) {
  315.                         $question_next_step 0;
  316.                     }
  317.                     break;
  318.                 case 'next':
  319.                     $next_step $current_step 1;
  320.                     // Special case : ISA products definitions don't have questions. Skipping step 2.
  321.                     if($form->getData()->getProductType() == 'isa' && $next_step == 2) {
  322.                         $next_step 3;
  323.                     }
  324.                     if($next_step == 2) {
  325.                         $question_next_step 0;
  326.                     }
  327.                     break;
  328.                 case 'finish':
  329.                     $this->em->flush();
  330.                     return $this->redirectToRoute('easyadmin', array('entity' => $this->entity['name'], 'action' => 'list'));
  331.                     break;
  332.                 case 'question_add':
  333.                     $question_next_step 1;
  334.                     break;
  335.                 case 'question_previous':
  336.                     $question_next_step $question_current_step 1;
  337.                     break;
  338.                 case 'question_next':
  339.                     $question_next_step $question_current_step 1;
  340.                     break;
  341.                 case 'question_cancel':
  342.                     $product_definition->setDraftQuestion(new ProductQuestion());
  343.                     $question_next_step 0;
  344.                     break;
  345.                 case 'question_finish':
  346.                     $draft_question $product_definition->getDraftQuestion();
  347.                     $question_index $draft_question->getIndex();
  348.                     if($question_index !== null) {
  349.                         $product_definition->getQuestions()->set($question_index$draft_question);
  350.                     } else {
  351.                         $product_definition->addQuestion($draft_question);
  352.                     }
  353.                     $product_definition->setDraftQuestion(new ProductQuestion());
  354.                     $question_next_step 0;
  355.                     break;
  356.                 // non-submit buttons
  357.                 default:
  358.                     switch($form->getClickedButton()->getName()) {
  359.                         case 'questionEdit':
  360.                             $product_question $form->getClickedButton()->getParent()->getData();
  361.                             $question_index $product_definition->getQuestions()->indexOf($product_question);
  362.                             $product_question->setIndex($question_index);
  363.                             $product_definition->setDraftQuestion($product_question);
  364.                             $question_next_step 1;
  365.                             break;
  366.                         case 'questionDelete':
  367.                             //\\@todo : add delete confirm dialog box
  368.                             $product_question $form->getClickedButton()->getParent()->getData();
  369.                             $product_question->setRemoveFlag(true);
  370.                             break;
  371.                         case "priceLineDefinitionDelete":
  372.                             //\\@todo : add delete confirm dialog box
  373.                             $price_line_def $form->getClickedButton()->getParent()->getData();
  374.                             $price_line_def->setRemoveFlag(true);
  375.                             break;
  376.                         case "distributionLineDefinitionDelete":
  377.                             //\\@todo : add delete confirm dialog box
  378.                             $distribution_line_def $form->getClickedButton()->getParent()->getData();
  379.                             $distribution_line_def->setRemoveFlag(true);
  380.                             break;
  381.                     }
  382.             }
  383.             $product_definition_serialized $this->serializer->serialize($product_definition'json');
  384.             $form $this->createForm(ProductDefinitionType::class, $product_definition, [
  385.                 'validation_groups' => [
  386.                     'Step_' $next_step '_' $op,
  387.                     'Question_step_' $question_next_step '_' $op,
  388.                 ],
  389.             ]);
  390.             $form->get('current_step')->setData($next_step);   // has PRE_SET_DATA event listener
  391.             $form->get('stored_data')->setData($product_definition_serialized);
  392.             if($form->has('draftQuestion')) {
  393.                 $form->get('draftQuestion')->get('current_step')->setData($question_next_step); // has PRE_SET_DATA event listener
  394.             }
  395.         }
  396.         if($next_step == 2) {
  397.             $question_steps_actions = [
  398.                 -=> [falsefalsefalsefalsefalse],  // Disable question form navigation
  399.                 => [truefalsefalsefalsefalse],    // Questions listing
  400.                 => [falsefalsetruefalsetrue],     // Filling basic question infos
  401.                 => [falsetruefalsetruetrue],      // Widget configuration
  402.             ];
  403.             list($question_add_button$question_previous_button$question_next_button$question_finish_button$question_cancel_button) = $question_steps_actions[$question_next_step];
  404.         }
  405.         $steps_actions = [
  406.             -=> [falsefalsefalse],// Disable main form navigation
  407.             => [falsetruefalse],  // Choosing product type
  408.             => [falsetruefalse],  // Filling basic product infos
  409.             => [truetruefalse],   // Adding question
  410.             => [truetruefalse],   // Price lines configuration
  411.             => [truetruefalse],   // Distribution lines definitions configuration
  412.             => [truefalsetrue],   // Activating product
  413.         ];
  414.         if($question_next_step 1) {
  415.             list($previous_button$next_button$finish_button) = $steps_actions[$next_step];
  416.         } else {
  417.             list($previous_button$next_button$finish_button) = $steps_actions[-1];
  418.         }
  419.         return $this->render('Backend/Admin/ProductDefinition/edit.html.twig', [
  420.             'form' => $form->createView(),
  421.             'op' => $op,
  422.             'previous_button' => $previous_button,
  423.             'next_button' => $next_button,
  424.             'finish_button' => $finish_button,
  425.             'question_add_button' => $question_add_button,
  426.             'question_previous_button' => $question_previous_button,
  427.             'question_next_button' => $question_next_button,
  428.             'question_finish_button' => $question_finish_button,
  429.             'question_cancel_button' => $question_cancel_button,
  430.         ]);
  431.     }
  432.     protected function newEngagementLetterDefinitionAction(): Response {
  433.         return $this->editEngagementLetterDefinitionAction();
  434.     }
  435.     protected function editEngagementLetterDefinitionAction(): Response {
  436.         $letter_definition null;
  437.         $previous_button false;
  438.         $next_button true;
  439.         $finish_button false;
  440.         $document_local_add_button false;
  441.         $document_local_previous_button false;
  442.         $document_local_next_button false;
  443.         $document_local_finish_button false;
  444.         $document_local_cancel_button false;
  445.         $question_add_button false;
  446.         $question_previous_button false;
  447.         $question_next_button false;
  448.         $question_finish_button false;
  449.         $question_cancel_button false;
  450.         $op 'edit';
  451.         $current_step $this->request->request->get('letter_definition')['current_step'] ?? 0;
  452.         $document_local_current_step $this->request->request->get('letter_definition')['draftDocument']['current_step'] ?? -1;
  453.         $question_current_step $this->request->request->get('letter_definition')['draftDocument']['draftQuestion']['current_step'] ?? -1;
  454.         $stored_letter_definition $this->request->request->get('letter_definition')['stored_data'] ?? null;
  455.         if(!empty($stored_letter_definition)) {
  456.             $letter_definition $this->serializer->deserialize($stored_letter_definitionEngagementLetterDefinition::class, 'json');
  457.             //Doctrine can't merge non persisted entities (new documents, new questions). Such entities are considered as 'dirty'.
  458.             foreach($letter_definition->getDocumentDefinitionLinks() as $document_definition_link) {
  459.                 $document_definition_link->setEngagementLetterDefinition($letter_definition);
  460.                 if($document_definition_link->getId() == null) {
  461.                     $this->em->persist($document_definition_link);
  462.                 }
  463.                 $document_definition $document_definition_link->getDocumentDefinition();
  464.                 if(!empty($document_definition)) {
  465.                     if($document_definition->getId() == null) {
  466.                         $this->em->persist($document_definition);
  467.                     }
  468.                     foreach($document_definition->getDocumentQuestions() as $document_question) {
  469.                         $document_question->setDocumentDefinition($document_definition);
  470.                         if($document_question->getId() == null) {
  471.                             $this->em->persist($document_question);
  472.                         }
  473.                     }
  474.                 }
  475.             }
  476.             foreach($letter_definition->getProductDefinitions() as $product_definition) {
  477.                 $product_definition->setEngagementLetterDefinition($letter_definition);
  478.             }
  479.             $letter_definition $this->em->merge($letter_definition); // from now, letter definition is managed.
  480.             foreach($letter_definition->getDocumentDefinitionLinks() as $document_definition_link) {
  481.                 $document_definition $document_definition_link->getDocumentDefinition();
  482.                 if(!empty($document_definition)) {
  483.                     foreach($document_definition->getDocumentQuestions() as $document_question) {
  484.                         if($document_question->getRemoveFlag() === true) {
  485.                             $data_to_delete $this->em->getRepository(EngagementLetterData::class)->findBy(['documentQuestion' => $document_question]);
  486.                             foreach($data_to_delete as $data) {
  487.                                 $this->em->remove($data);
  488.                             }
  489.                             $this->em->remove($document_question);
  490.                         }
  491.                     }
  492.                 }
  493.                 if($document_definition_link->getRemoveFlag() === true) {
  494.                     if($document_definition_link->getDocumentDefinition()->isGlobal() === false) {
  495.                         $this->em->remove($document_definition_link->getDocumentDefinition());
  496.                     }
  497.                     $this->em->remove($document_definition_link);
  498.                 }
  499.             }
  500.         } else {
  501.             if(!empty($this->request->get('id'))) {
  502.                 $letter_definition $this->em->find(EngagementLetterDefinition::class, $this->request->get('id'));
  503.                 $product_definitions_backup = [];
  504.                 foreach($letter_definition->getProductDefinitions() as $product_definition) {
  505.                     $product_definitions_backup[] = $product_definition->getId();
  506.                 }
  507.                 $letter_definition->setProductDefinitionsBackup($product_definitions_backup);
  508.                 $stored_letter_definition $this->serializer->serialize($letter_definition'json');
  509.             } else {
  510.                 $letter_definition = new EngagementLetterDefinition();
  511.                 $this->em->persist($letter_definition); // in order to manage the new instance
  512.                 $letter_definition->setDraftDocument(new DocumentDefinition());
  513.                 $letter_definition->getDraftDocument()->setDraftQuestion(new DocumentQuestion());
  514.             }
  515.         }
  516.         if(empty($letter_definition->getId())) {
  517.             $op 'new';
  518.         }
  519.         $form $this->createForm(EngagementLetterDefinitionType::class, $letter_definition, [
  520.             'validation_groups' => [
  521.                 'Step_' $current_step '_' $op,
  522.                 'Document_step_' $document_local_current_step '_' $op,
  523.                 'Question_step_' $question_current_step '_' $op,
  524.             ],
  525.         ]);
  526.         $form->get('current_step')->setData($current_step);  // has PRE_SET_DATA event listener
  527.         $form->get('stored_data')->setData($stored_letter_definition);
  528.         if($form->has('draftDocument')) {
  529.             $form->get('draftDocument')->get('current_step')->setData($document_local_current_step); // has PRE_SET_DATA event listener
  530.             if($form->get('draftDocument')->has('draftQuestion')) {
  531.                 $form->get('draftDocument')->get('draftQuestion')->get('current_step')->setData($question_current_step); // has PRE_SET_DATA event listener
  532.             }
  533.         }
  534.         $form->handleRequest($this->request);
  535.         $next_step $current_step;
  536.         $document_local_next_step $document_local_current_step;
  537.         $question_next_step $question_current_step;
  538.         $submit_action $this->request->request->get('submit-action');
  539.         if($form->isSubmitted() &&
  540.             (in_array($submit_action, ['previous''question_previous''question_cancel']) || $form->isValid())) {
  541.             $letter_definition $form->getData();
  542.             switch($submit_action) {
  543.                 case 'previous':
  544.                     $next_step $current_step 1;
  545.                     if($next_step == 1) {
  546.                         $question_next_step 0;
  547.                         $document_local_next_step 0;
  548.                     }
  549.                     break;
  550.                 case 'next':
  551.                     $next_step $current_step 1;
  552.                     if($next_step == 1) {
  553.                         $question_next_step 0;
  554.                         $document_local_next_step 0;
  555.                     }
  556.                     break;
  557.                 case 'finish':
  558.                     $product_definitions_backup $letter_definition->getProductDefinitionsBackup();
  559.                     $product_definitions_to_keep = [];
  560.                     foreach($letter_definition->getProductDefinitions() as $product_definition) {
  561.                         $product_definitions_to_keep[] = $product_definition->getId();
  562.                     }
  563.                     $product_definitions_to_remove array_diff($product_definitions_backup$product_definitions_to_keep);
  564.                     foreach($product_definitions_to_remove as $product_definition_id) {
  565.                         $product_definition $this->em->find(ProductDefinition::class, $product_definition_id);
  566.                         $product_definition->setEngagementLetterDefinition(null);
  567.                     }
  568.                     $this->em->flush();
  569.                     return $this->redirectToRoute('easyadmin', array('entity' => $this->entity['name'], 'action' => 'list'));
  570.                     break;
  571.                 case 'document_local_add':
  572.                     $document_local_next_step 1;
  573.                     $question_next_step 0;
  574.                     break;
  575.                 case 'document_local_finish':
  576.                     $draft_document $letter_definition->getDraftDocument();
  577.                     if($draft_document->getLinkIndex() !== null) {
  578.                         $document_definition_link $letter_definition->getDocumentDefinitionLinks()->get($draft_document->getLinkIndex());
  579.                         $document_definition_link->setDocumentDefinition($draft_document);
  580.                     } else {
  581.                         $document_definition_link = new DocumentDefinitionLink();
  582.                         $document_definition_link->setDocumentDefinition($draft_document);
  583.                         $letter_definition->addDocumentDefinitionLink($document_definition_link);
  584.                     }
  585.                     $letter_definition->setDraftDocument(new DocumentDefinition());
  586.                     $document_local_next_step 0;
  587.                     $question_next_step = -1;
  588.                     break;
  589.                 case 'document_local_cancel':
  590.                     $letter_definition->setDraftDocument(new DocumentDefinition());
  591.                     $document_local_next_step 0;
  592.                     $question_next_step = -1;
  593.                     break;
  594.                 case 'question_add':
  595.                     $question_next_step 1;
  596.                     break;
  597.                 case 'question_previous':
  598.                     $question_next_step $question_current_step 1;
  599.                     break;
  600.                 case 'question_next':
  601.                     $question_next_step $question_current_step 1;
  602.                     break;
  603.                 case 'question_cancel':
  604.                     $letter_definition->getDraftDocument()->setDraftQuestion(new DocumentQuestion());
  605.                     $question_next_step 0;
  606.                     break;
  607.                 case 'question_finish':
  608.                     $draft_question $letter_definition->getDraftDocument()->getDraftQuestion();
  609.                     $question_index $draft_question->getIndex();
  610.                     if($question_index !== null) {
  611.                         $letter_definition->getDraftDocument()->getDocumentQuestions()->set($question_index$draft_question);
  612.                     } else {
  613.                         $letter_definition->getDraftDocument()->addDocumentQuestion($draft_question);
  614.                     }
  615.                     $letter_definition->getDraftDocument()->setDraftQuestion(new DocumentQuestion());
  616.                     $question_next_step 0;
  617.                     break;
  618.                 // non-submit buttons
  619.                 default:
  620.                     switch($form->getClickedButton()->getName()) {
  621.                         case 'questionEdit':
  622.                             $document_question $form->getClickedButton()->getParent()->getData();
  623.                             $question_index $letter_definition->getDraftDocument()->getDocumentQuestions()->indexOf($document_question);
  624.                             $document_question->setIndex($question_index);
  625.                             $letter_definition->getDraftDocument()->setDraftQuestion($document_question);
  626.                             $question_next_step 1;
  627.                             break;
  628.                         case 'questionDelete':
  629.                             //\\@todo : add delete confirm dialog box
  630.                             $document_question $form->getClickedButton()->getParent()->getData();
  631.                             $document_question->setRemoveFlag(true);
  632.                             break;
  633.                         case 'documentEdit':
  634.                             $document_link $form->getClickedButton()->getParent()->getData();
  635.                             $document_link_index $letter_definition->getDocumentDefinitionLinks()->indexOf($document_link);
  636.                             $document $document_link->getDocumentDefinition();
  637.                             $document->setLinkIndex($document_link_index);
  638.                             $letter_definition->setDraftDocument($document);
  639.                             $document_local_next_step 1;
  640.                             $question_next_step 0;
  641.                             break;
  642.                         case 'documentDelete':
  643.                             //\\@todo : add delete confirm dialog box
  644.                             $document_link $form->getClickedButton()->getParent()->getData();
  645.                             $document_link->setRemoveFlag(true);
  646.                             break;
  647.                         case 'globalDocumentsAdd':
  648.                             $global_document $form->getClickedButton()->getParent()->get('globalDocumentsList')->getData();
  649.                             $global_document $this->em->merge($global_document);
  650.                             $document_link = new DocumentDefinitionLink();
  651.                             $document_link->setDocumentDefinition($global_document);
  652.                             $letter_definition->addDocumentDefinitionLink($document_link);
  653.                             break;
  654.                     }
  655.             }
  656.             $letter_definition_serialized $this->serializer->serialize($letter_definition'json');
  657.             $form $this->createForm(EngagementLetterDefinitionType::class, $letter_definition, [
  658.                 'validation_groups' => [
  659.                     'Step_' $next_step '_' $op,
  660.                     'Document_step_' $document_local_next_step '_' $op,
  661.                     'Question_step_' $question_next_step '_' $op,
  662.                 ],
  663.             ]);
  664.             $form->get('current_step')->setData($next_step);   // has PRE_SET_DATA event listener
  665.             $form->get('stored_data')->setData($letter_definition_serialized);
  666.             if($form->has('draftDocument')) {
  667.                 $form->get('draftDocument')->get('current_step')->setData($document_local_next_step); // has PRE_SET_DATA event listener
  668.                 if($form->get('draftDocument')->has('draftQuestion')) {
  669.                     $form->get('draftDocument')->get('draftQuestion')->get('current_step')->setData($question_next_step); // has PRE_SET_DATA event listener
  670.                 }
  671.             }
  672.         }
  673.         $steps_actions = [
  674.             -=> [falsefalsefalse],// Disable main form navigation
  675.             => [falsetruefalse],  // Filling basic letter infos
  676.             => [truefalsetrue]    // Adding documents
  677.         ];
  678.         list($previous_button$next_button$finish_button) = $steps_actions[$next_step];
  679.         if($next_step == 1) {
  680.             $documents_local_steps_actions = [
  681.                 -=> [falsefalsefalsefalsefalse],  // Disable local document form navigation
  682.                 => [truefalsefalsefalsefalse],    // Documents listing
  683.                 => [falsefalsefalsetruetrue],     // Document redaction
  684.             ];
  685.             list($document_local_add_button$document_local_previous_button$document_local_next_button$document_local_finish_button$document_local_cancel_button) = $documents_local_steps_actions[$document_local_next_step];
  686.             if($document_local_next_step == 1) {
  687.                 $question_steps_actions = [
  688.                     -=> [falsefalsefalsefalsefalse],  // Disable question form navigation
  689.                     => [truefalsefalsefalsefalse],    // Questions listing
  690.                     => [falsefalsetruefalsetrue],     // Filling basic question infos
  691.                     => [falsetruefalsetruetrue],      // Widget configuration
  692.                 ];
  693.                 list($question_add_button$question_previous_button$question_next_button$question_finish_button$question_cancel_button) = $question_steps_actions[$question_next_step];
  694.                 // Disable letter definition form navigation
  695.                 list($previous_button$next_button$finish_button) = $steps_actions[-1];
  696.                 if($question_next_step 0) {
  697.                     // Disable document definition form navigation
  698.                     list($document_local_add_button$document_local_previous_button$document_local_next_button$document_local_finish_button$document_local_cancel_button) = $documents_local_steps_actions[-1];
  699.                 }
  700.             }
  701.         }
  702.         return $this->render('Backend/Admin/EngagementLetterDefinition/edit.html.twig', [
  703.             'form' => $form->createView(),
  704.             'op' => $op,
  705.             'previous_button' => $previous_button,
  706.             'next_button' => $next_button,
  707.             'finish_button' => $finish_button,
  708.             'document_local_add_button' => $document_local_add_button,
  709.             'document_local_previous_button' => $document_local_previous_button,
  710.             'document_local_next_button' => $document_local_next_button,
  711.             'document_local_finish_button' => $document_local_finish_button,
  712.             'document_local_cancel_button' => $document_local_cancel_button,
  713.             'question_add_button' => $question_add_button,
  714.             'question_previous_button' => $question_previous_button,
  715.             'question_next_button' => $question_next_button,
  716.             'question_finish_button' => $question_finish_button,
  717.             'question_cancel_button' => $question_cancel_button,
  718.         ]);
  719.     }
  720.     protected function newGlobalDocumentDefinitionAction(): Response {
  721.         return $this->editGlobalDocumentDefinitionAction();
  722.     }
  723.     protected function editGlobalDocumentDefinitionAction(): Response {
  724.         $document_definition null;
  725.         $finish_button false;
  726.         $question_add_button false;
  727.         $question_previous_button false;
  728.         $question_next_button false;
  729.         $question_finish_button false;
  730.         $question_cancel_button false;
  731.         $op 'edit';
  732.         $question_current_step $this->request->request->get('document_definition')['draftQuestion']['current_step'] ?? 0;
  733.         $stored_document_definition $this->request->request->get('document_definition')['stored_data'] ?? null;
  734.         if(!empty($stored_document_definition)) {
  735.             $document_definition $this->serializer->deserialize($stored_document_definitionDocumentDefinition::class, 'json');
  736.             //Doctrine can't merge non persisted entities (new questions). Such entities are considered as 'dirty'.
  737.             foreach($document_definition->getDocumentQuestions() as $document_question) {
  738.                 $document_question->setDocumentDefinition($document_definition);
  739.                 if($document_question->getId() == null) {
  740.                     $this->em->persist($document_question);
  741.                 }
  742.             }
  743.             $document_definition $this->em->merge($document_definition); // from now, document definition is managed.
  744.             foreach($document_definition->getDocumentQuestions() as $document_question) {
  745.                 if($document_question->getRemoveFlag() === true) {
  746.                     $data_to_delete $this->em->getRepository(EngagementLetterData::class)->findBy(['documentQuestion' => $document_question]);
  747.                     foreach($data_to_delete as $data) {
  748.                         $this->em->remove($data);
  749.                     }
  750.                     $this->em->remove($document_question);
  751.                 }
  752.             }
  753.         } else {
  754.             if(!empty($this->request->get('id'))) {
  755.                 $document_definition $this->em->find(DocumentDefinition::class, $this->request->get('id'));
  756.                 $stored_document_definition $this->serializer->serialize($document_definition'json');
  757.             } else {
  758.                 $document_definition = new DocumentDefinition();
  759.                 $document_definition->setGlobal(true);
  760.                 $this->em->persist($document_definition); // from now, document definition is managed.
  761.                 $document_definition->setDraftQuestion(new DocumentQuestion());
  762.             }
  763.         }
  764.         if(empty($document_definition->getId())) {
  765.             $op 'new';
  766.         }
  767.         $form $this->createForm(DocumentDefinitionType::class, $document_definition, [
  768.             'validation_groups' => [
  769.                 'Step_1_' $op,
  770.                 'Question_step_' $question_current_step '_' $op,
  771.             ],
  772.         ]);
  773.         $form->get('current_step')->setData(1);  // has PRE_SET_DATA event listener
  774.         $form->get('stored_data')->setData($stored_document_definition);
  775.         if($form->has('draftQuestion')) {
  776.             $form->get('draftQuestion')->get('current_step')->setData($question_current_step); // has PRE_SET_DATA event listener
  777.         }
  778.         $form->handleRequest($this->request);
  779.         $question_next_step $question_current_step;
  780.         $submit_action $this->request->request->get('submit-action');
  781.         if($form->isSubmitted() &&
  782.             (in_array($submit_action, ['question_previous''question_cancel']) || $form->isValid())) {
  783.             $document_definition $form->getData();
  784.             switch($submit_action) {
  785.                 case 'finish':
  786.                     $this->em->flush();
  787.                     return $this->redirectToRoute('easyadmin', array('entity' => $this->entity['name'], 'action' => 'list'));
  788.                     break;
  789.                 case 'question_add':
  790.                     $question_next_step 1;
  791.                     break;
  792.                 case 'question_previous':
  793.                     $question_next_step $question_current_step 1;
  794.                     break;
  795.                 case 'question_next':
  796.                     $question_next_step $question_current_step 1;
  797.                     break;
  798.                 case 'question_cancel':
  799.                     $document_definition->setDraftQuestion(new DocumentQuestion());
  800.                     $question_next_step 0;
  801.                     break;
  802.                 case 'question_finish':
  803.                     $draft_question $document_definition->getDraftQuestion();
  804.                     $question_index $draft_question->getIndex();
  805.                     if($question_index !== null) {
  806.                         $document_definition->getDocumentQuestions()->set($question_index$draft_question);
  807.                     } else {
  808.                         $document_definition->addDocumentQuestion($draft_question);
  809.                     }
  810.                     $document_definition->setDraftQuestion(new DocumentQuestion());
  811.                     $question_next_step 0;
  812.                     break;
  813.                 // non-submit buttons
  814.                 default:
  815.                     switch($form->getClickedButton()->getName()) {
  816.                         case 'questionEdit':
  817.                             $document_question $form->getClickedButton()->getParent()->getData();
  818.                             $question_index $document_definition->getDocumentQuestions()->indexOf($document_question);
  819.                             $document_question->setIndex($question_index);
  820.                             $document_definition->setDraftQuestion($document_question);
  821.                             $question_next_step 1;
  822.                             break;
  823.                         case 'questionDelete':
  824.                             //\\@todo : add delete confirm dialog box
  825.                             $document_question $form->getClickedButton()->getParent()->getData();
  826.                             $document_question->setRemoveFlag(true);
  827.                             break;
  828.                     }
  829.             }
  830.             $document_definition_serialized $this->serializer->serialize($document_definition'json');
  831.             $form $this->createForm(DocumentDefinitionType::class, $document_definition, [
  832.                 'validation_groups' => [
  833.                     'Step_1_' $op,
  834.                     'Question_step_' $question_next_step '_' $op,
  835.                 ],
  836.             ]);
  837.             $form->get('current_step')->setData(1);   // has PRE_SET_DATA event listener
  838.             $form->get('stored_data')->setData($document_definition_serialized);
  839.             if($form->has('draftQuestion')) {
  840.                 $form->get('draftQuestion')->get('current_step')->setData($question_next_step); // has PRE_SET_DATA event listener
  841.             }
  842.         }
  843.         $question_steps_actions = [
  844.             => [truefalsefalsefalsefalse],    // Questions listing
  845.             => [falsefalsetruefalsetrue],     // Filling basic question infos
  846.             => [falsetruefalsetruetrue],      // Widget configuration
  847.         ];
  848.         list($question_add_button$question_previous_button$question_next_button$question_finish_button$question_cancel_button) = $question_steps_actions[$question_next_step];
  849.         if($question_next_step == 0) {
  850.             $finish_button true;
  851.         }
  852.         return $this->render('Backend/Admin/GlobalDocumentDefinition/edit.html.twig', [
  853.             'form' => $form->createView(),
  854.             'op' => $op,
  855.             'finish_button' => $finish_button,
  856.             'question_add_button' => $question_add_button,
  857.             'question_previous_button' => $question_previous_button,
  858.             'question_next_button' => $question_next_button,
  859.             'question_finish_button' => $question_finish_button,
  860.             'question_cancel_button' => $question_cancel_button,
  861.         ]);
  862.     }
  863.     /**
  864.      * @Route("/import-isagi-articles", name="import_isagi_articles")
  865.      */
  866.     public function importISAGIArticles(Request $requestArticlesISAGIManager $articles_manager): Response {
  867.         $current_step 0;
  868.         $next_button false;
  869.         $finish_button false;
  870.         $sample_data null;
  871.         $form $this->createForm(ImportISAGIArticlesType::class);
  872.         $form->get('current_step')->setData($current_step);
  873.         $form->handleRequest($request);
  874.         $next_step $current_step;
  875.         if($form->isSubmitted() && $form->isValid()) {
  876.             $submit_action $request->request->get('submit-action');
  877.             switch($submit_action) {
  878.                 case 'next':
  879.                     if($current_step === 0) {
  880.                         $articles_header_file $form->get('articlesHeader')->getData();
  881.                         $articles_header_file->move($this->get('kernel')->getProjectDir() . '/var/import/articles/''articles_header.ini');
  882.                         $articles_data_file $form->get('articlesData')->getData();
  883.                         $articles_data_file->move($this->get('kernel')->getProjectDir() . '/var/import/articles/''articles_data.txt');
  884.                         $articles_tarifs_header_file $form->get('articlesTarifsHeader')->getData();
  885.                         $articles_tarifs_header_file->move($this->get('kernel')->getProjectDir() . '/var/import/articles/''articles_tarifs_header.ini');
  886.                         $articles_tarifs_data_file $form->get('articlesTarifsData')->getData();
  887.                         $articles_tarifs_data_file->move($this->get('kernel')->getProjectDir() . '/var/import/articles/''articles_tarifs_data.txt');
  888.                         $articles_manager->setFilesPaths(
  889.                             'var/import/articles/articles_header.ini',
  890.                             'var/import/articles/articles_data.txt',
  891.                             'var/import/articles/articles_tarifs_header.ini',
  892.                             'var/import/articles/articles_tarifs_data.txt'
  893.                         );
  894.                         $sample_data $articles_manager->getSampleData(10);
  895.                     }
  896.                     $next_step += 1;
  897.                     break;
  898.                 case 'finish':
  899.                     $articles_manager->setFilesPaths(
  900.                         'var/import/articles/articles_header.ini',
  901.                         'var/import/articles/articles_data.txt',
  902.                         'var/import/articles/articles_tarifs_header.ini',
  903.                         'var/import/articles/articles_tarifs_data.txt'
  904.                     );
  905.                     $articles_manager->import();
  906.                     $this->addFlash('success'"Les articles ont été importés.");
  907.                     return $this->redirectToRoute('import_isagi_articles');
  908.                     break;
  909.             }
  910.             $form $this->createForm(ImportISAGIArticlesType::class);
  911.             $form->get('current_step')->setData($next_step);
  912.         }
  913.         $steps_actions = [
  914.             => [truefalse], // Files selections
  915.             => [falsetrue], // Data preview
  916.         ];
  917.         list($next_button$finish_button) = $steps_actions[$next_step];
  918.         return $this->render('Backend/Admin/Configuration/import_isagi_articles.html.twig', [
  919.             'form' => $form->createView(),
  920.             'sample_data' => $sample_data,
  921.             'next_button' => $next_button,
  922.             'finish_button' => $finish_button,
  923.         ]);
  924.     }
  925.     /**
  926.      * @Route("/docusign-configuration", name="docusign_configuration")
  927.      */
  928.     public function docusignConfiguration(Request $requestConfig $configSignatureManager $signatureManager) {
  929.         return $this->render('Backend/Admin/Configuration/docusign_configuration.html.twig', [
  930.             'docusign_status' => $signatureManager->checkServiceStatus(),
  931.             'docusign_status_text' => $signatureManager->getStatusText(),
  932.         ]);
  933.     }
  934.     /**
  935.      * @Route("/docusign-connect", name="docusign_oauth_connect")
  936.      */
  937.     public function docusignOauthConnect(SignatureManager $signatureManager) {
  938.         return $signatureManager->connect();
  939.     }
  940.     /**
  941.      * @Route("/docusign-oauth", name="docusign_oauth_callback")
  942.      */
  943.     public function docusignOauthCallback(Request $requestSignatureManager $signatureManager) {
  944.         $code $request->get('code');
  945.         if(empty($code)) {
  946.             throw $this->createAccessDeniedException();
  947.         }
  948.         $signatureManager->authorize();
  949.         return $this->redirectToRoute('docusign_configuration');
  950.     }
  951.     /**
  952.      * @Route("/synchronize-mailchimp", name="synchronize_mailchimp")
  953.      */
  954.     public function synchronizeMailchimp(Request $requestMailchimpManager $mailchimpManager) {
  955.         if($request->get('launch-synchronization') !== null) {
  956.             if($mailchimpManager->resetCustomersList() === true) {
  957.                 $this->addFlash('success'"La synchronisation s'est achevée sans erreur.");
  958.             }
  959.         } elseif($request->get('launch-ping') !== null) {
  960.             $response $mailchimpManager->ping();
  961.             $this->addFlash('success'"Mailchimp a répondu : \"" $response "\".");
  962.         }
  963.         return $this->render('Backend/Admin/Communication/synchronize_mailchimp.html.twig');
  964.     }
  965. }