<?php
namespace App\Controller\Backend;
use App\Entity\DocToSignModel;
use App\Entity\DocumentDefinition;
use App\Entity\DocumentDefinitionLink;
use App\Entity\DocumentQuestion;
use App\Entity\EngagementLetterData;
use App\Entity\EngagementLetterDefinition;
use App\Entity\EngagementLetterInstance;
use App\Entity\ProductData;
use App\Entity\ProductDefinition;
use App\Entity\ProductQuestion;
use App\Entity\Quote;
use App\Form\DocumentDefinitionType;
use App\Form\EngagementLetterDefinitionType;
use App\Form\ImportISAGIArticlesType;
use App\Form\ProductDefinitionType;
use App\Form\UploadType;
use App\Model\Entity\AccountInterface;
use App\Service\ApodisFormsManager;
use App\Service\ArticlesISAGIManager;
use App\Service\DocToSignManager;
use App\Service\EngagementLetterManager;
use App\Service\MailchimpManager;
use App\Service\SignatureManager;
use App\Service\UserManager;
use Craue\ConfigBundle\Util\Config;
use JMS\Serializer\SerializerInterface as JMSSerializerInterface;
use Swift_Mailer;
use Swift_Message;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Twig\Environment;
class EaAdminController extends EaBackendController
{
protected $engagementLetterManager;
protected $signatureManager;
protected $serializer;
protected $formsManager;
protected $docToSignManager;
protected $twig;
protected $mailer;
protected $params;
protected $projectDir;
public function __construct(
EngagementLetterManager $engagementLetterManager,
SignatureManager $signatureManager,
UserManager $userManager,
ApodisFormsManager $formsManager,
DocToSignManager $docToSignManager,
JMSSerializerInterface $serializer,
Environment $twig,
Swift_Mailer $mailer,
ParameterBagInterface $params,
string $projectDir
) {
parent::__construct($userManager);
$this->engagementLetterManager = $engagementLetterManager;
$this->signatureManager = $signatureManager;
$this->formsManager = $formsManager;
$this->docToSignManager = $docToSignManager;
$this->serializer = $serializer;
$this->twig = $twig;
$this->mailer = $mailer;
$this->params = $params;
$this->projectDir = $projectDir;
}
public function send_signatureAction() {
$quote = $this->em->find(Quote::class, $this->request->get('id'));
$pdf_paths = $this->engagementLetterManager->prepareDocuments($quote);
$this->signatureManager->generateEngagementLetterEnvelope($quote->getEngagementLetterInstance(), $quote->getCustomer(), $pdf_paths, true);
$quote->getEngagementLetterInstance()->setState(EngagementLetterInstance::STATE_CREATED);
$quote->setState(Quote::STATE_FINISHED);
$quote = $this->em->merge($quote);
$this->em->flush();
$this->addFlash('success', "Le lien de signature a été envoyé à l'adhérent.");
return $this->redirectToRoute('easyadmin', [
'entity' => 'Quote',
'action' => 'list',
'menuIndex' => 1,
'submenuIndex' => 0,
]);
}
public function downloadDocToSignAction() {
//\\@todo
return $this->redirectToRoute('easyadmin', [
'entity' => 'DocToSign',
'action' => 'list',
'menuIndex' => 2,
'submenuIndex' => 1,
]);
}
public function downloadDocToSignModelAction() {
$do_to_sign = $this->em->find(DocToSignModel::class, $this->request->get('id'));
$filepath = $this->projectDir . '/private/doc_to_sign_models/' . $do_to_sign->getFilename();
if(!is_file($filepath)) {
throw new NotFoundHttpException();
}
$file = new File($filepath);
return $this->file($file);
}
protected function removeDocToSignModelEntity($entity) {
$this->docToSignManager->deleteDocModel($entity->getFilename());
parent::removeEntity($entity);
}
protected function updateDocToSignModelEntity(DocToSignModel $entity, Form $form) {
$uploader_data = $form->get('file_upload')->getData();
if($uploader_data['delete'] === true) {
$this->docToSignManager->deleteDocModel($entity->getFilename());
}
if(!empty($uploader_data['uploaded_file'])) {
$filename = $this->docToSignManager->uploadDocModel($uploader_data['uploaded_file']);
$entity->setFilename($filename);
}
$entity->setUpdatedAt(new \Datetime()); // arbitrary data to force entity refresh
parent::updateEntity($entity);
}
protected function persistDocToSignModelEntity(DocToSignModel $entity, Form $form) {
$filename = $this->docToSignManager->uploadDocModel($form->get('file_upload')->getData()['uploaded_file']);
$entity->setFilename($filename);
parent::persistEntity($entity);
}
protected function createDocToSignModelEntityFormBuilder(DocToSignModel $entity, $view): FormBuilder {
$builder = parent::createEntityFormBuilder($entity, $view);
if($view === 'edit') {
$options = $builder->get('file_upload')->getOptions();
$options['data'] = [
'filename' => $entity->getFilename(),
];
$builder->add('file_upload', UploadType::class, $options);
}
return $builder;
}
protected function createCustomerAccountEntityFormBuilder($entity, $view): FormBuilder {
$builder = parent::createEntityFormBuilder($entity, $view);
//--- Forms
$options = $builder->get('forms_definitions')->getOptions();
$forms_definitions = $this->formsManager->getFormsDefinitions();
$options['choices'] = [];
foreach($forms_definitions as $form_definition) {
$options['choices'][$form_definition['name']] = $form_definition['uuid'];
}
if($view === 'edit') {
$customer_forms = $this->formsManager->getCustomerFormsList($entity->getUuid());
$options['data'] = [];
foreach($customer_forms as $form_instance) {
$options['data'][] = $form_instance['formDefinition']['uuid'];
}
}
$builder->add('forms_definitions', ChoiceType::class, $options);
//--- Send mail
if($view === 'new') {
$options = $builder->get('send_mail')->getOptions();
$options['data'] = true;
$builder->add('send_mail', CheckboxType::class, $options);
}
return $builder;
}
protected function persistManagerAccountEntity(AccountInterface $entity): void {
$entity->getUser()->setRole('ROLE_MANAGER');
parent::persistEntity($entity);
}
protected function persistAgentAccountEntity(AccountInterface $entity): void {
$entity->getUser()->setRole('ROLE_AGENT');
parent::persistEntity($entity);
}
protected function persistCustomerAccountEntity($entity) {
$entity->getUser()->setRole('ROLE_CUSTOMER');
parent::persistEntity($entity);
$this->updateCustomerAccountEntity($entity);
}
protected function updateCustomerAccountEntity($entity) {
$entity->getUser()->setRole('ROLE_CUSTOMER');
if(!empty($entity->getIdentifier())) {
$entity->getUser()->setUsername($entity->getIdentifier());
} else {
$entity->getUser()->setUsername(null);
}
if(array_key_exists('forms_definitions', $this->request->get('customeraccount'))) {
$this->formsManager->setCustomerFormsInstances($entity->getUuid(), $this->request->get('customeraccount')['forms_definitions']);
} else {
$this->formsManager->setCustomerFormsInstances($entity->getUuid());
}
parent::updateEntity($entity);
if(array_key_exists('send_mail', $this->request->get('customeraccount'))) {
$this->sendMailToCustomer($entity);
}
}
protected function sendMailToCustomer($entity, $isNew = false) {
$message = (new Swift_Message())
->setSubject("Votre compte adhérent")
->setFrom($this->params->get('swift_mail_from'))
->setTo($entity->getEmail())
->setBody(
$this->twig->render('Mail/customer_account_infos.html.twig', [
'is_new' => $isNew,
'login' => $entity->getUser()->getUsername() ?? $entity->getUser()->getEmail(),
'password' => $this->request->get('customeraccount')['user']['plainPassword']['first'] ?? null,
'identifier' => $entity->getIdentifier() ?? null,
'agent_name' => !empty($entity->getAgent()) ? $entity->getAgent()->getFullName() : null,
'has_form' => array_key_exists('forms_definitions', $this->request->get('customeraccount')),
]),
'text/html',
'utf8'
)
;
$this->mailer->send($message);
}
protected function newProductDefinitionAction(): Response {
return $this->editProductDefinitionAction();
}
protected function editProductDefinitionAction(): Response {
$product_definition = null;
$previous_button = false;
$next_button = true;
$finish_button = false;
$question_add_button = false;
$question_previous_button = false;
$question_next_button = false;
$question_finish_button = false;
$question_cancel_button = false;
$op = 'edit';
$current_step = $this->request->request->get('product_definition')['current_step'] ?? 0;
$question_current_step = $this->request->request->get('product_definition')['draftQuestion']['current_step'] ?? -1;
$stored_product_definition = $this->request->request->get('product_definition')['stored_data'] ?? null;
if(!empty($stored_product_definition)) {
$product_definition = $this->serializer->deserialize($stored_product_definition, ProductDefinition::class, 'json');
//Doctrine can't merge non persisted entities (new questions). Such entities are considered as 'dirty'.
foreach($product_definition->getQuestions() as $product_question) {
$product_question->setProductDefinition($product_definition);
if($product_question->getId() == null) {
$this->em->persist($product_question);
}
}
foreach($product_definition->getPriceLinesDefinitions() as $price_line_def) {
$price_line_def->setProductDefinition($product_definition);
if($price_line_def->getId() == null) {
$this->em->persist($price_line_def);
}
}
foreach($product_definition->getDistributionLinesDefinitions() as $distribution_line_def) {
$distribution_line_def->setProductDefinition($product_definition);
if($distribution_line_def->getId() == null) {
$this->em->persist($distribution_line_def);
}
}
$product_definition = $this->em->merge($product_definition); // from now, product definition is managed.
foreach($product_definition->getQuestions() as $product_question) {
if($product_question->getRemoveFlag() === true) {
$data_to_delete = $this->em->getRepository(ProductData::class)->findBy(['productQuestion' => $product_question]);
foreach($data_to_delete as $data) {
$this->em->remove($data);
}
$this->em->remove($product_question);
}
}
foreach($product_definition->getPriceLinesDefinitions() as $price_line_def) {
if($price_line_def->getRemoveFlag() === true) {
$this->em->remove($price_line_def);
}
}
foreach($product_definition->getDistributionLinesDefinitions() as $distribution_line_def) {
if($distribution_line_def->getRemoveFlag() === true) {
$this->em->remove($distribution_line_def);
}
}
} else {
if(!empty($this->request->get('id'))) {
$product_definition = $this->em->find(ProductDefinition::class, $this->request->get('id'));
$stored_product_definition = $this->serializer->serialize($product_definition, 'json');
$current_step = 1;
} else {
$product_definition = new ProductDefinition();
$this->em->persist($product_definition); // from now, product definition is managed.
$product_definition->setDraftQuestion(new ProductQuestion());
}
}
if(empty($product_definition->getId())) {
$op = 'new';
}
$form = $this->createForm(ProductDefinitionType::class, $product_definition, [
'validation_groups' => [
'Step_' . $current_step . '_' . $op,
'Question_step_' . $question_current_step . '_' . $op,
],
]);
$form->get('current_step')->setData($current_step); // has PRE_SET_DATA event listener
$form->get('stored_data')->setData($stored_product_definition);
if($form->has('draftQuestion')) {
$form->get('draftQuestion')->get('current_step')->setData($question_current_step); // has PRE_SET_DATA event listener
}
$form->handleRequest($this->request);
$next_step = $current_step;
$question_next_step = $question_current_step;
$submit_action = $this->request->request->get('submit-action');
if($form->isSubmitted() &&
(in_array($submit_action, ['previous', 'question_previous', 'question_cancel']) || $form->isValid())) {
$product_definition = $form->getData();
switch($submit_action) {
case 'previous':
$next_step = $current_step - 1;
// Special case : ISA products definitions don't have questions. Skipping step 2.
if($form->getData()->getProductType() == 'isa' && $next_step == 2) {
$next_step = 1;
}
if($next_step == 2) {
$question_next_step = 0;
}
break;
case 'next':
$next_step = $current_step + 1;
// Special case : ISA products definitions don't have questions. Skipping step 2.
if($form->getData()->getProductType() == 'isa' && $next_step == 2) {
$next_step = 3;
}
if($next_step == 2) {
$question_next_step = 0;
}
break;
case 'finish':
$this->em->flush();
return $this->redirectToRoute('easyadmin', array('entity' => $this->entity['name'], 'action' => 'list'));
break;
case 'question_add':
$question_next_step = 1;
break;
case 'question_previous':
$question_next_step = $question_current_step - 1;
break;
case 'question_next':
$question_next_step = $question_current_step + 1;
break;
case 'question_cancel':
$product_definition->setDraftQuestion(new ProductQuestion());
$question_next_step = 0;
break;
case 'question_finish':
$draft_question = $product_definition->getDraftQuestion();
$question_index = $draft_question->getIndex();
if($question_index !== null) {
$product_definition->getQuestions()->set($question_index, $draft_question);
} else {
$product_definition->addQuestion($draft_question);
}
$product_definition->setDraftQuestion(new ProductQuestion());
$question_next_step = 0;
break;
// non-submit buttons
default:
switch($form->getClickedButton()->getName()) {
case 'questionEdit':
$product_question = $form->getClickedButton()->getParent()->getData();
$question_index = $product_definition->getQuestions()->indexOf($product_question);
$product_question->setIndex($question_index);
$product_definition->setDraftQuestion($product_question);
$question_next_step = 1;
break;
case 'questionDelete':
//\\@todo : add delete confirm dialog box
$product_question = $form->getClickedButton()->getParent()->getData();
$product_question->setRemoveFlag(true);
break;
case "priceLineDefinitionDelete":
//\\@todo : add delete confirm dialog box
$price_line_def = $form->getClickedButton()->getParent()->getData();
$price_line_def->setRemoveFlag(true);
break;
case "distributionLineDefinitionDelete":
//\\@todo : add delete confirm dialog box
$distribution_line_def = $form->getClickedButton()->getParent()->getData();
$distribution_line_def->setRemoveFlag(true);
break;
}
}
$product_definition_serialized = $this->serializer->serialize($product_definition, 'json');
$form = $this->createForm(ProductDefinitionType::class, $product_definition, [
'validation_groups' => [
'Step_' . $next_step . '_' . $op,
'Question_step_' . $question_next_step . '_' . $op,
],
]);
$form->get('current_step')->setData($next_step); // has PRE_SET_DATA event listener
$form->get('stored_data')->setData($product_definition_serialized);
if($form->has('draftQuestion')) {
$form->get('draftQuestion')->get('current_step')->setData($question_next_step); // has PRE_SET_DATA event listener
}
}
if($next_step == 2) {
$question_steps_actions = [
-1 => [false, false, false, false, false], // Disable question form navigation
0 => [true, false, false, false, false], // Questions listing
1 => [false, false, true, false, true], // Filling basic question infos
2 => [false, true, false, true, true], // Widget configuration
];
list($question_add_button, $question_previous_button, $question_next_button, $question_finish_button, $question_cancel_button) = $question_steps_actions[$question_next_step];
}
$steps_actions = [
-1 => [false, false, false],// Disable main form navigation
0 => [false, true, false], // Choosing product type
1 => [false, true, false], // Filling basic product infos
2 => [true, true, false], // Adding question
3 => [true, true, false], // Price lines configuration
4 => [true, true, false], // Distribution lines definitions configuration
5 => [true, false, true], // Activating product
];
if($question_next_step < 1) {
list($previous_button, $next_button, $finish_button) = $steps_actions[$next_step];
} else {
list($previous_button, $next_button, $finish_button) = $steps_actions[-1];
}
return $this->render('Backend/Admin/ProductDefinition/edit.html.twig', [
'form' => $form->createView(),
'op' => $op,
'previous_button' => $previous_button,
'next_button' => $next_button,
'finish_button' => $finish_button,
'question_add_button' => $question_add_button,
'question_previous_button' => $question_previous_button,
'question_next_button' => $question_next_button,
'question_finish_button' => $question_finish_button,
'question_cancel_button' => $question_cancel_button,
]);
}
protected function newEngagementLetterDefinitionAction(): Response {
return $this->editEngagementLetterDefinitionAction();
}
protected function editEngagementLetterDefinitionAction(): Response {
$letter_definition = null;
$previous_button = false;
$next_button = true;
$finish_button = false;
$document_local_add_button = false;
$document_local_previous_button = false;
$document_local_next_button = false;
$document_local_finish_button = false;
$document_local_cancel_button = false;
$question_add_button = false;
$question_previous_button = false;
$question_next_button = false;
$question_finish_button = false;
$question_cancel_button = false;
$op = 'edit';
$current_step = $this->request->request->get('letter_definition')['current_step'] ?? 0;
$document_local_current_step = $this->request->request->get('letter_definition')['draftDocument']['current_step'] ?? -1;
$question_current_step = $this->request->request->get('letter_definition')['draftDocument']['draftQuestion']['current_step'] ?? -1;
$stored_letter_definition = $this->request->request->get('letter_definition')['stored_data'] ?? null;
if(!empty($stored_letter_definition)) {
$letter_definition = $this->serializer->deserialize($stored_letter_definition, EngagementLetterDefinition::class, 'json');
//Doctrine can't merge non persisted entities (new documents, new questions). Such entities are considered as 'dirty'.
foreach($letter_definition->getDocumentDefinitionLinks() as $document_definition_link) {
$document_definition_link->setEngagementLetterDefinition($letter_definition);
if($document_definition_link->getId() == null) {
$this->em->persist($document_definition_link);
}
$document_definition = $document_definition_link->getDocumentDefinition();
if(!empty($document_definition)) {
if($document_definition->getId() == null) {
$this->em->persist($document_definition);
}
foreach($document_definition->getDocumentQuestions() as $document_question) {
$document_question->setDocumentDefinition($document_definition);
if($document_question->getId() == null) {
$this->em->persist($document_question);
}
}
}
}
foreach($letter_definition->getProductDefinitions() as $product_definition) {
$product_definition->setEngagementLetterDefinition($letter_definition);
}
$letter_definition = $this->em->merge($letter_definition); // from now, letter definition is managed.
foreach($letter_definition->getDocumentDefinitionLinks() as $document_definition_link) {
$document_definition = $document_definition_link->getDocumentDefinition();
if(!empty($document_definition)) {
foreach($document_definition->getDocumentQuestions() as $document_question) {
if($document_question->getRemoveFlag() === true) {
$data_to_delete = $this->em->getRepository(EngagementLetterData::class)->findBy(['documentQuestion' => $document_question]);
foreach($data_to_delete as $data) {
$this->em->remove($data);
}
$this->em->remove($document_question);
}
}
}
if($document_definition_link->getRemoveFlag() === true) {
if($document_definition_link->getDocumentDefinition()->isGlobal() === false) {
$this->em->remove($document_definition_link->getDocumentDefinition());
}
$this->em->remove($document_definition_link);
}
}
} else {
if(!empty($this->request->get('id'))) {
$letter_definition = $this->em->find(EngagementLetterDefinition::class, $this->request->get('id'));
$product_definitions_backup = [];
foreach($letter_definition->getProductDefinitions() as $product_definition) {
$product_definitions_backup[] = $product_definition->getId();
}
$letter_definition->setProductDefinitionsBackup($product_definitions_backup);
$stored_letter_definition = $this->serializer->serialize($letter_definition, 'json');
} else {
$letter_definition = new EngagementLetterDefinition();
$this->em->persist($letter_definition); // in order to manage the new instance
$letter_definition->setDraftDocument(new DocumentDefinition());
$letter_definition->getDraftDocument()->setDraftQuestion(new DocumentQuestion());
}
}
if(empty($letter_definition->getId())) {
$op = 'new';
}
$form = $this->createForm(EngagementLetterDefinitionType::class, $letter_definition, [
'validation_groups' => [
'Step_' . $current_step . '_' . $op,
'Document_step_' . $document_local_current_step . '_' . $op,
'Question_step_' . $question_current_step . '_' . $op,
],
]);
$form->get('current_step')->setData($current_step); // has PRE_SET_DATA event listener
$form->get('stored_data')->setData($stored_letter_definition);
if($form->has('draftDocument')) {
$form->get('draftDocument')->get('current_step')->setData($document_local_current_step); // has PRE_SET_DATA event listener
if($form->get('draftDocument')->has('draftQuestion')) {
$form->get('draftDocument')->get('draftQuestion')->get('current_step')->setData($question_current_step); // has PRE_SET_DATA event listener
}
}
$form->handleRequest($this->request);
$next_step = $current_step;
$document_local_next_step = $document_local_current_step;
$question_next_step = $question_current_step;
$submit_action = $this->request->request->get('submit-action');
if($form->isSubmitted() &&
(in_array($submit_action, ['previous', 'question_previous', 'question_cancel']) || $form->isValid())) {
$letter_definition = $form->getData();
switch($submit_action) {
case 'previous':
$next_step = $current_step - 1;
if($next_step == 1) {
$question_next_step = 0;
$document_local_next_step = 0;
}
break;
case 'next':
$next_step = $current_step + 1;
if($next_step == 1) {
$question_next_step = 0;
$document_local_next_step = 0;
}
break;
case 'finish':
$product_definitions_backup = $letter_definition->getProductDefinitionsBackup();
$product_definitions_to_keep = [];
foreach($letter_definition->getProductDefinitions() as $product_definition) {
$product_definitions_to_keep[] = $product_definition->getId();
}
$product_definitions_to_remove = array_diff($product_definitions_backup, $product_definitions_to_keep);
foreach($product_definitions_to_remove as $product_definition_id) {
$product_definition = $this->em->find(ProductDefinition::class, $product_definition_id);
$product_definition->setEngagementLetterDefinition(null);
}
$this->em->flush();
return $this->redirectToRoute('easyadmin', array('entity' => $this->entity['name'], 'action' => 'list'));
break;
case 'document_local_add':
$document_local_next_step = 1;
$question_next_step = 0;
break;
case 'document_local_finish':
$draft_document = $letter_definition->getDraftDocument();
if($draft_document->getLinkIndex() !== null) {
$document_definition_link = $letter_definition->getDocumentDefinitionLinks()->get($draft_document->getLinkIndex());
$document_definition_link->setDocumentDefinition($draft_document);
} else {
$document_definition_link = new DocumentDefinitionLink();
$document_definition_link->setDocumentDefinition($draft_document);
$letter_definition->addDocumentDefinitionLink($document_definition_link);
}
$letter_definition->setDraftDocument(new DocumentDefinition());
$document_local_next_step = 0;
$question_next_step = -1;
break;
case 'document_local_cancel':
$letter_definition->setDraftDocument(new DocumentDefinition());
$document_local_next_step = 0;
$question_next_step = -1;
break;
case 'question_add':
$question_next_step = 1;
break;
case 'question_previous':
$question_next_step = $question_current_step - 1;
break;
case 'question_next':
$question_next_step = $question_current_step + 1;
break;
case 'question_cancel':
$letter_definition->getDraftDocument()->setDraftQuestion(new DocumentQuestion());
$question_next_step = 0;
break;
case 'question_finish':
$draft_question = $letter_definition->getDraftDocument()->getDraftQuestion();
$question_index = $draft_question->getIndex();
if($question_index !== null) {
$letter_definition->getDraftDocument()->getDocumentQuestions()->set($question_index, $draft_question);
} else {
$letter_definition->getDraftDocument()->addDocumentQuestion($draft_question);
}
$letter_definition->getDraftDocument()->setDraftQuestion(new DocumentQuestion());
$question_next_step = 0;
break;
// non-submit buttons
default:
switch($form->getClickedButton()->getName()) {
case 'questionEdit':
$document_question = $form->getClickedButton()->getParent()->getData();
$question_index = $letter_definition->getDraftDocument()->getDocumentQuestions()->indexOf($document_question);
$document_question->setIndex($question_index);
$letter_definition->getDraftDocument()->setDraftQuestion($document_question);
$question_next_step = 1;
break;
case 'questionDelete':
//\\@todo : add delete confirm dialog box
$document_question = $form->getClickedButton()->getParent()->getData();
$document_question->setRemoveFlag(true);
break;
case 'documentEdit':
$document_link = $form->getClickedButton()->getParent()->getData();
$document_link_index = $letter_definition->getDocumentDefinitionLinks()->indexOf($document_link);
$document = $document_link->getDocumentDefinition();
$document->setLinkIndex($document_link_index);
$letter_definition->setDraftDocument($document);
$document_local_next_step = 1;
$question_next_step = 0;
break;
case 'documentDelete':
//\\@todo : add delete confirm dialog box
$document_link = $form->getClickedButton()->getParent()->getData();
$document_link->setRemoveFlag(true);
break;
case 'globalDocumentsAdd':
$global_document = $form->getClickedButton()->getParent()->get('globalDocumentsList')->getData();
$global_document = $this->em->merge($global_document);
$document_link = new DocumentDefinitionLink();
$document_link->setDocumentDefinition($global_document);
$letter_definition->addDocumentDefinitionLink($document_link);
break;
}
}
$letter_definition_serialized = $this->serializer->serialize($letter_definition, 'json');
$form = $this->createForm(EngagementLetterDefinitionType::class, $letter_definition, [
'validation_groups' => [
'Step_' . $next_step . '_' . $op,
'Document_step_' . $document_local_next_step . '_' . $op,
'Question_step_' . $question_next_step . '_' . $op,
],
]);
$form->get('current_step')->setData($next_step); // has PRE_SET_DATA event listener
$form->get('stored_data')->setData($letter_definition_serialized);
if($form->has('draftDocument')) {
$form->get('draftDocument')->get('current_step')->setData($document_local_next_step); // has PRE_SET_DATA event listener
if($form->get('draftDocument')->has('draftQuestion')) {
$form->get('draftDocument')->get('draftQuestion')->get('current_step')->setData($question_next_step); // has PRE_SET_DATA event listener
}
}
}
$steps_actions = [
-1 => [false, false, false],// Disable main form navigation
0 => [false, true, false], // Filling basic letter infos
1 => [true, false, true] // Adding documents
];
list($previous_button, $next_button, $finish_button) = $steps_actions[$next_step];
if($next_step == 1) {
$documents_local_steps_actions = [
-1 => [false, false, false, false, false], // Disable local document form navigation
0 => [true, false, false, false, false], // Documents listing
1 => [false, false, false, true, true], // Document redaction
];
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];
if($document_local_next_step == 1) {
$question_steps_actions = [
-1 => [false, false, false, false, false], // Disable question form navigation
0 => [true, false, false, false, false], // Questions listing
1 => [false, false, true, false, true], // Filling basic question infos
2 => [false, true, false, true, true], // Widget configuration
];
list($question_add_button, $question_previous_button, $question_next_button, $question_finish_button, $question_cancel_button) = $question_steps_actions[$question_next_step];
// Disable letter definition form navigation
list($previous_button, $next_button, $finish_button) = $steps_actions[-1];
if($question_next_step > 0) {
// Disable document definition form navigation
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];
}
}
}
return $this->render('Backend/Admin/EngagementLetterDefinition/edit.html.twig', [
'form' => $form->createView(),
'op' => $op,
'previous_button' => $previous_button,
'next_button' => $next_button,
'finish_button' => $finish_button,
'document_local_add_button' => $document_local_add_button,
'document_local_previous_button' => $document_local_previous_button,
'document_local_next_button' => $document_local_next_button,
'document_local_finish_button' => $document_local_finish_button,
'document_local_cancel_button' => $document_local_cancel_button,
'question_add_button' => $question_add_button,
'question_previous_button' => $question_previous_button,
'question_next_button' => $question_next_button,
'question_finish_button' => $question_finish_button,
'question_cancel_button' => $question_cancel_button,
]);
}
protected function newGlobalDocumentDefinitionAction(): Response {
return $this->editGlobalDocumentDefinitionAction();
}
protected function editGlobalDocumentDefinitionAction(): Response {
$document_definition = null;
$finish_button = false;
$question_add_button = false;
$question_previous_button = false;
$question_next_button = false;
$question_finish_button = false;
$question_cancel_button = false;
$op = 'edit';
$question_current_step = $this->request->request->get('document_definition')['draftQuestion']['current_step'] ?? 0;
$stored_document_definition = $this->request->request->get('document_definition')['stored_data'] ?? null;
if(!empty($stored_document_definition)) {
$document_definition = $this->serializer->deserialize($stored_document_definition, DocumentDefinition::class, 'json');
//Doctrine can't merge non persisted entities (new questions). Such entities are considered as 'dirty'.
foreach($document_definition->getDocumentQuestions() as $document_question) {
$document_question->setDocumentDefinition($document_definition);
if($document_question->getId() == null) {
$this->em->persist($document_question);
}
}
$document_definition = $this->em->merge($document_definition); // from now, document definition is managed.
foreach($document_definition->getDocumentQuestions() as $document_question) {
if($document_question->getRemoveFlag() === true) {
$data_to_delete = $this->em->getRepository(EngagementLetterData::class)->findBy(['documentQuestion' => $document_question]);
foreach($data_to_delete as $data) {
$this->em->remove($data);
}
$this->em->remove($document_question);
}
}
} else {
if(!empty($this->request->get('id'))) {
$document_definition = $this->em->find(DocumentDefinition::class, $this->request->get('id'));
$stored_document_definition = $this->serializer->serialize($document_definition, 'json');
} else {
$document_definition = new DocumentDefinition();
$document_definition->setGlobal(true);
$this->em->persist($document_definition); // from now, document definition is managed.
$document_definition->setDraftQuestion(new DocumentQuestion());
}
}
if(empty($document_definition->getId())) {
$op = 'new';
}
$form = $this->createForm(DocumentDefinitionType::class, $document_definition, [
'validation_groups' => [
'Step_1_' . $op,
'Question_step_' . $question_current_step . '_' . $op,
],
]);
$form->get('current_step')->setData(1); // has PRE_SET_DATA event listener
$form->get('stored_data')->setData($stored_document_definition);
if($form->has('draftQuestion')) {
$form->get('draftQuestion')->get('current_step')->setData($question_current_step); // has PRE_SET_DATA event listener
}
$form->handleRequest($this->request);
$question_next_step = $question_current_step;
$submit_action = $this->request->request->get('submit-action');
if($form->isSubmitted() &&
(in_array($submit_action, ['question_previous', 'question_cancel']) || $form->isValid())) {
$document_definition = $form->getData();
switch($submit_action) {
case 'finish':
$this->em->flush();
return $this->redirectToRoute('easyadmin', array('entity' => $this->entity['name'], 'action' => 'list'));
break;
case 'question_add':
$question_next_step = 1;
break;
case 'question_previous':
$question_next_step = $question_current_step - 1;
break;
case 'question_next':
$question_next_step = $question_current_step + 1;
break;
case 'question_cancel':
$document_definition->setDraftQuestion(new DocumentQuestion());
$question_next_step = 0;
break;
case 'question_finish':
$draft_question = $document_definition->getDraftQuestion();
$question_index = $draft_question->getIndex();
if($question_index !== null) {
$document_definition->getDocumentQuestions()->set($question_index, $draft_question);
} else {
$document_definition->addDocumentQuestion($draft_question);
}
$document_definition->setDraftQuestion(new DocumentQuestion());
$question_next_step = 0;
break;
// non-submit buttons
default:
switch($form->getClickedButton()->getName()) {
case 'questionEdit':
$document_question = $form->getClickedButton()->getParent()->getData();
$question_index = $document_definition->getDocumentQuestions()->indexOf($document_question);
$document_question->setIndex($question_index);
$document_definition->setDraftQuestion($document_question);
$question_next_step = 1;
break;
case 'questionDelete':
//\\@todo : add delete confirm dialog box
$document_question = $form->getClickedButton()->getParent()->getData();
$document_question->setRemoveFlag(true);
break;
}
}
$document_definition_serialized = $this->serializer->serialize($document_definition, 'json');
$form = $this->createForm(DocumentDefinitionType::class, $document_definition, [
'validation_groups' => [
'Step_1_' . $op,
'Question_step_' . $question_next_step . '_' . $op,
],
]);
$form->get('current_step')->setData(1); // has PRE_SET_DATA event listener
$form->get('stored_data')->setData($document_definition_serialized);
if($form->has('draftQuestion')) {
$form->get('draftQuestion')->get('current_step')->setData($question_next_step); // has PRE_SET_DATA event listener
}
}
$question_steps_actions = [
0 => [true, false, false, false, false], // Questions listing
1 => [false, false, true, false, true], // Filling basic question infos
2 => [false, true, false, true, true], // Widget configuration
];
list($question_add_button, $question_previous_button, $question_next_button, $question_finish_button, $question_cancel_button) = $question_steps_actions[$question_next_step];
if($question_next_step == 0) {
$finish_button = true;
}
return $this->render('Backend/Admin/GlobalDocumentDefinition/edit.html.twig', [
'form' => $form->createView(),
'op' => $op,
'finish_button' => $finish_button,
'question_add_button' => $question_add_button,
'question_previous_button' => $question_previous_button,
'question_next_button' => $question_next_button,
'question_finish_button' => $question_finish_button,
'question_cancel_button' => $question_cancel_button,
]);
}
/**
* @Route("/import-isagi-articles", name="import_isagi_articles")
*/
public function importISAGIArticles(Request $request, ArticlesISAGIManager $articles_manager): Response {
$current_step = 0;
$next_button = false;
$finish_button = false;
$sample_data = null;
$form = $this->createForm(ImportISAGIArticlesType::class);
$form->get('current_step')->setData($current_step);
$form->handleRequest($request);
$next_step = $current_step;
if($form->isSubmitted() && $form->isValid()) {
$submit_action = $request->request->get('submit-action');
switch($submit_action) {
case 'next':
if($current_step === 0) {
$articles_header_file = $form->get('articlesHeader')->getData();
$articles_header_file->move($this->get('kernel')->getProjectDir() . '/var/import/articles/', 'articles_header.ini');
$articles_data_file = $form->get('articlesData')->getData();
$articles_data_file->move($this->get('kernel')->getProjectDir() . '/var/import/articles/', 'articles_data.txt');
$articles_tarifs_header_file = $form->get('articlesTarifsHeader')->getData();
$articles_tarifs_header_file->move($this->get('kernel')->getProjectDir() . '/var/import/articles/', 'articles_tarifs_header.ini');
$articles_tarifs_data_file = $form->get('articlesTarifsData')->getData();
$articles_tarifs_data_file->move($this->get('kernel')->getProjectDir() . '/var/import/articles/', 'articles_tarifs_data.txt');
$articles_manager->setFilesPaths(
'var/import/articles/articles_header.ini',
'var/import/articles/articles_data.txt',
'var/import/articles/articles_tarifs_header.ini',
'var/import/articles/articles_tarifs_data.txt'
);
$sample_data = $articles_manager->getSampleData(10);
}
$next_step += 1;
break;
case 'finish':
$articles_manager->setFilesPaths(
'var/import/articles/articles_header.ini',
'var/import/articles/articles_data.txt',
'var/import/articles/articles_tarifs_header.ini',
'var/import/articles/articles_tarifs_data.txt'
);
$articles_manager->import();
$this->addFlash('success', "Les articles ont été importés.");
return $this->redirectToRoute('import_isagi_articles');
break;
}
$form = $this->createForm(ImportISAGIArticlesType::class);
$form->get('current_step')->setData($next_step);
}
$steps_actions = [
0 => [true, false], // Files selections
1 => [false, true], // Data preview
];
list($next_button, $finish_button) = $steps_actions[$next_step];
return $this->render('Backend/Admin/Configuration/import_isagi_articles.html.twig', [
'form' => $form->createView(),
'sample_data' => $sample_data,
'next_button' => $next_button,
'finish_button' => $finish_button,
]);
}
/**
* @Route("/docusign-configuration", name="docusign_configuration")
*/
public function docusignConfiguration(Request $request, Config $config, SignatureManager $signatureManager) {
return $this->render('Backend/Admin/Configuration/docusign_configuration.html.twig', [
'docusign_status' => $signatureManager->checkServiceStatus(),
'docusign_status_text' => $signatureManager->getStatusText(),
]);
}
/**
* @Route("/docusign-connect", name="docusign_oauth_connect")
*/
public function docusignOauthConnect(SignatureManager $signatureManager) {
return $signatureManager->connect();
}
/**
* @Route("/docusign-oauth", name="docusign_oauth_callback")
*/
public function docusignOauthCallback(Request $request, SignatureManager $signatureManager) {
$code = $request->get('code');
if(empty($code)) {
throw $this->createAccessDeniedException();
}
$signatureManager->authorize();
return $this->redirectToRoute('docusign_configuration');
}
/**
* @Route("/synchronize-mailchimp", name="synchronize_mailchimp")
*/
public function synchronizeMailchimp(Request $request, MailchimpManager $mailchimpManager) {
if($request->get('launch-synchronization') !== null) {
if($mailchimpManager->resetCustomersList() === true) {
$this->addFlash('success', "La synchronisation s'est achevée sans erreur.");
}
} elseif($request->get('launch-ping') !== null) {
$response = $mailchimpManager->ping();
$this->addFlash('success', "Mailchimp a répondu : \"" . $response . "\".");
}
return $this->render('Backend/Admin/Communication/synchronize_mailchimp.html.twig');
}
}