src/AtechNet/CoreBundle/Controller/CustomerController.php line 2249

Open in your IDE?
  1. <?php
  2. namespace App\AtechNet\CoreBundle\Controller;
  3. use App\AtechNet\CoreBundle\Entity\Claim;
  4. use App\AtechNet\CoreBundle\Entity\ClaimMedia;
  5. use App\AtechNet\CoreBundle\Entity\ClaimStatus;
  6. use App\AtechNet\CoreBundle\Entity\ClaimTest;
  7. use App\AtechNet\CoreBundle\Entity\Customer;
  8. use App\AtechNet\CoreBundle\Entity\CustomerAddress;
  9. use App\AtechNet\CoreBundle\Entity\CustomerBillingoData;
  10. use App\AtechNet\CoreBundle\Entity\Document;
  11. use App\AtechNet\CoreBundle\Entity\DocumentGroup;
  12. use App\AtechNet\CoreBundle\Entity\DocumentItem;
  13. use App\AtechNet\CoreBundle\Entity\Domain;
  14. use App\AtechNet\CoreBundle\Entity\DomainPaymentType;
  15. use App\AtechNet\CoreBundle\Entity\DomainShippingType;
  16. use App\AtechNet\CoreBundle\Entity\Notification;
  17. use App\AtechNet\CoreBundle\Entity\NotificationConfig;
  18. use App\AtechNet\CoreBundle\Entity\Order;
  19. use App\AtechNet\CoreBundle\Entity\OrderItem;
  20. use App\AtechNet\CoreBundle\Entity\OrderSetting;
  21. use App\AtechNet\CoreBundle\Entity\PickupPoint;
  22. use App\AtechNet\CoreBundle\Entity\ProductCommission;
  23. use App\AtechNet\CoreBundle\Entity\ProductType;
  24. use App\AtechNet\CoreBundle\Entity\StockMovement;
  25. use App\AtechNet\CoreBundle\Entity\StockItem;
  26. use App\AtechNet\CoreBundle\Entity\StockMovementItem;
  27. use App\AtechNet\CoreBundle\Entity\UnasTranslator;
  28. use App\AtechNet\CoreBundle\Entity\User;
  29. use App\AtechNet\CoreBundle\Enum\PaymentType;
  30. use App\AtechNet\CoreBundle\Form\CustomerAddressType;
  31. use App\AtechNet\CoreBundle\Form\CustomerClaimType;
  32. use App\AtechNet\CoreBundle\Form\CustomerEditType;
  33. use App\AtechNet\CoreBundle\Form\CustomerForgotPasswordType;
  34. use App\AtechNet\CoreBundle\Form\CustomerLoginType;
  35. use App\AtechNet\CoreBundle\Form\CustomerType;
  36. use App\AtechNet\CoreBundle\Form\CustomerWithdrawalType;
  37. use App\AtechNet\CoreBundle\Form\NewsletterType;
  38. use App\AtechNet\CoreBundle\Helper\BillingoOperation;
  39. use App\AtechNet\CoreBundle\Helper\Furbify\MultiStore;
  40. use App\AtechNet\CoreBundle\Helper\Furbify\OrderHelper;
  41. use App\AtechNet\CoreBundle\Helper\Furbify\Registration;
  42. use App\AtechNet\CoreBundle\Helper\KlaviyoConnect;
  43. use App\AtechNet\CoreBundle\Helper\Security as SecurityHelper;
  44. use Doctrine\ORM\Exception\NotSupported;
  45. use Doctrine\ORM\OptimisticLockException;
  46. use Doctrine\ORM\ORMException;
  47. use Mpdf\Mpdf;
  48. use Mpdf\MpdfException;
  49. use Psr\SimpleCache\InvalidArgumentException;
  50. use Symfony\Bridge\Twig\Mime\TemplatedEmail;
  51. use Symfony\Component\EventDispatcher\EventDispatcher;
  52. use Symfony\Component\Form\FormError;
  53. use Symfony\Component\HttpFoundation\JsonResponse;
  54. use Symfony\Component\HttpFoundation\RedirectResponse;
  55. use Symfony\Component\HttpFoundation\Request;
  56. use Symfony\Component\HttpFoundation\Response;
  57. use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
  58. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  59. use Symfony\Component\Routing\Annotation\Route;
  60. use Symfony\Component\Routing\Exception\InvalidParameterException;
  61. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  62. use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
  63. use Symfony\Component\Security\Core\Security;
  64. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  65. use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
  66. use App\AtechNet\CoreBundle\Service\FinstatService;
  67. class CustomerController extends AbstractController
  68. {
  69.     public const INVOICE_TYPE_CENTRALIS = 1;
  70.     public const INVOICE_TYPE_BILLINGO = 2;
  71.     /**
  72.      * @Route("/registration", name="customer_registration", defaults={"_locale":""})
  73.      * @Route("/{_locale<%supported_locales%>?}/registration", name="customer_registration_locale", defaults={"_locale":""})
  74.      * @param Request $request
  75.      * @param UserPasswordHasherInterface $passwordHasher
  76.      * @return RedirectResponse|Response
  77.      * @throws InvalidArgumentException
  78.      * @throws OptimisticLockException
  79.      */
  80.     public function registrationAction(Request $request, UserPasswordHasherInterface $passwordHasher)
  81.     {
  82.         $data = $this->registrationBaseData($request, $passwordHasher);
  83.         return is_array($data) ? $this->render('AtechNetCoreBundle/Customer/registration.html.twig', $data) : $data;
  84.     }
  85.     /**
  86.      * @param Request $request
  87.      * @param UserPasswordHasherInterface $passwordHasher
  88.      * @return array|RedirectResponse
  89.      * @throws InvalidArgumentException
  90.      * @throws OptimisticLockException
  91.      * @throws ORMException
  92.      */
  93.     private function registrationBaseData(Request $request, UserPasswordHasherInterface $passwordHasher)
  94.     {
  95.         if ($this->getLoginHelper($request)->isLoggedIn()) {
  96.             return $this->redirectToRoute('homepage');
  97.         }
  98.         $data = [];
  99.         $data['hideChat'] = true;
  100.         $data['heading_title'] = $this->getTranslator()->trans('Create account');
  101.         $multiStoreHelper = $this->getMultiStoreHelper($request);
  102.         $domain = $multiStoreHelper->getDomain();
  103.         $translator = $this->getTranslator();
  104.         $languageCode = $multiStoreHelper->getLanguage()->getCode();
  105.         $domainLanguageCode = $defaultLanguageCode = $multiStoreHelper->getDefaultLanguage()->getCode();
  106.         if ($domainLanguageCode == 'en') {
  107.             $domainLanguageCode = 'eu';
  108.         }
  109.         $customer = new Customer();
  110.         $customer->setCountry(strtoupper($domainLanguageCode));
  111.         $customer->setType((int)$request->get('type') ?: 0);
  112.         $form = $this->createForm(CustomerType::class, $customer, [
  113.             'action' => $this->generateUrl('customer_registration'),
  114.             'locale' => $languageCode,
  115.             'defaultLocale' => $defaultLanguageCode,
  116.         ]);
  117.         $form->handleRequest($request);
  118.         $data['errorMessage'] = '';
  119.         if ($form->isSubmitted()) {
  120.             if (!empty($form->get('password')->getData()) && SecurityHelper::insecure($form->get('password')->getData())) {
  121.                 $form->get('password')->addError(new FormError($translator->trans('Unfortunately, the password provided is not secure, therefore it cannot be used in our webshop')));
  122.             }
  123.         }
  124.         if ($form->isSubmitted() && $form->isValid()) {
  125.             $entityManager = $this->getEntityManager();
  126.             if ($form->get('type')->getData() == 0) {
  127.                 $customerType = MultiStore::CUSTOMER_TYPE_RETAIL;
  128.             } else {
  129.                 $customerType = $form->get('type')->getData();
  130.             }
  131.             $setCountry = false;
  132.             switch ($domain->getId()) {
  133.                 case Domain::DOMAIN_ID_RT_SK:
  134.                     $domainsToCheck = '1,2';
  135.                     break;
  136.                 case Domain::DOMAIN_ID_RT_HU:
  137.                     $domainsToCheck = '3,4';
  138.                     break;
  139.                 case Domain::DOMAIN_ID_RT_CZ:
  140.                     $domainsToCheck = '9,5';
  141.                     break;
  142.                 case Domain::DOMAIN_ID_RT_EU:
  143.                     $domainsToCheck = '7,11';
  144.                     $setCountry = true;
  145.                     break;
  146.                 default:
  147.                     $domainsToCheck = '';
  148.             }
  149.             if ($setCountry) {
  150.                 $customer->setCountry(strtoupper($form->get('country')->getData()));
  151.             }
  152.             $domain = $entityManager->getRepository(Domain::class)->findOneById(MultiStore::defineDomainId($customerType, $request->getHttpHost()));
  153.             $duplicateCustomerCheck = $this->getEntityManager()
  154.                 ->createQuery("SELECT c
  155.                   FROM AtechNetCoreBundle:Customer c
  156.                   WHERE c.email = :email AND c.domain IN (" . $domainsToCheck . ")")
  157.                 ->setParameter('email', $form->get('email')->getData())
  158.                 ->getResult();
  159.             $captchaResponse = $request->request->get('g-recaptcha-response');
  160.             $captchaResult = $this->verifyGoogleCaptcha($captchaResponse);
  161.             if ($captchaResult) {
  162.                 if (count($duplicateCustomerCheck) < 2) {
  163.                     $itWasAGuestCustomer = false;
  164.                     if (count($duplicateCustomerCheck) == 1) {
  165.                         $newPassword = $customer->getPassword();
  166.                         /**
  167.                          * @var Customer $customer
  168.                          */
  169.                         $customer = $duplicateCustomerCheck[0];
  170.                         $itWasAGuestCustomer = true;
  171.                         $registration = new Registration($this->getEntityManager(), $request, $passwordHasher);
  172.                         $registration->saveGuestAsNewCustomer($customer, $newPassword);
  173.                     } else {
  174.                         $registration = new Registration($this->getEntityManager(), $request, $passwordHasher);
  175.                         $registration->save($customer, $domain);
  176.                     }
  177.                     if ($this->getEnvironment() == 'prod') {
  178.                         $contactInfos = $this->getContactInfos();
  179.                         switch ($domain->getId()) {
  180.                             case Domain::DOMAIN_ID_RT_SK:
  181.                             case Domain::DOMAIN_ID_WS_SK:
  182.                             case Domain::DOMAIN_ID_RT_CZ:
  183.                             case Domain::DOMAIN_ID_WS_CZ:
  184.                                 $facebookLink = 'https://www.facebook.com/furbify.atechnet/';
  185.                                 $instagramLink = 'https://www.instagram.com/furbify.sk';
  186.                                 break;
  187.                             case Domain::DOMAIN_ID_RT_HU:
  188.                             case Domain::DOMAIN_ID_WS_HU:
  189.                                 $facebookLink = 'https://www.facebook.com/furbify.hu/';
  190.                                 $instagramLink = 'https://www.instagram.com/furbify.hu';
  191.                                 break;
  192.                             default:
  193.                                 $facebookLink = '';
  194.                                 $instagramLink = '';
  195.                         }
  196.                         // Mailer
  197.                         $mailer = $this->getMailer();
  198.                         // Email
  199.                         $email = (new TemplatedEmail())
  200.                             ->subject($this->getTranslator()->trans('Thank you for registering'))
  201.                             ->to($customer->getEmail())
  202.                             ->replyTo($this->getParameter('mailer_reply_to'))
  203.                             ->htmlTemplate('AtechNetCoreBundle/Email/registration.html.twig')
  204.                             ->context([
  205.                                 'retail' => $customerType == MultiStore::CUSTOMER_TYPE_RETAIL,
  206.                                 'domainLanguageCode' => $domainLanguageCode,
  207.                                 'greetingName' => $customer->getFirstname(),
  208.                                 'companyName' => $contactInfos['company.' . $defaultLanguageCode . '.name'],
  209.                                 'companySteet' => $contactInfos['company.' . $defaultLanguageCode . '.street'],
  210.                                 'companyCity' => $contactInfos['company.' . $defaultLanguageCode . '.city'],
  211.                                 'companyCountry' => $contactInfos['company.' . $defaultLanguageCode . '.country'],
  212.                                 'companyBusinessId' => $contactInfos['company.' . $defaultLanguageCode . '.id'],
  213.                                 'companyVatId' => $contactInfos['company.' . $defaultLanguageCode . '.vatId'],
  214.                                 'phoneNumber' => $contactInfos['phone.webshop.' . $defaultLanguageCode . '.' . $domain->getType()],
  215.                                 'shopEmail' => $contactInfos['mail.webshop.' . $defaultLanguageCode . '.' . $domain->getType()],
  216.                                 'facebookLink' => $facebookLink,
  217.                                 'instagramLink' => $instagramLink,
  218.                             ])
  219.                         ;
  220.                         // Send Notification
  221.                         $mailer->send($email);
  222.                         if ($customerType == MultiStore::CUSTOMER_TYPE_WHOLESALE) {
  223.                             $emailTo = $domain->getId() != Domain::DOMAIN_ID_WS_EU ? $customer->getSalesManager()->getEmail() : 'export@furbify.eu';
  224.                             $email = (new TemplatedEmail())
  225.                                 ->subject('New registration to activate ' . $customer->getDomain()->getShortTitle() . ' - ' . $customer->getBusinessName())
  226.                                 ->to($emailTo)
  227.                                 ->html('New registration on ' . $customer->getDomain()->getShortTitle() . ' - ' . $customer->getBusinessName());
  228.                             $mailer->send($email);
  229.                             $email = (new TemplatedEmail())
  230.                                 ->subject($this->getTranslator()->trans('wholesaleEmail.subject'))
  231.                                 ->to($customer->getEmail())
  232.                                 ->replyTo($this->getParameter('mailer_reply_to'))
  233.                                 ->htmlTemplate('AtechNetCoreBundle/Email/wholesaleRegistration.html.twig')
  234.                                 ->context([])
  235.                             ;
  236.                             $mailer->send($email);
  237.                         }
  238.                     }
  239.                     $customer->setWantsNewsletter(true);
  240.                     $entityManager->flush();
  241.                     $this->getKlaviyoConnect($request)->createProfile($customer);
  242.                     if ($customerType != MultiStore::CUSTOMER_TYPE_WHOLESALE && !$itWasAGuestCustomer) {
  243.                         // "main" is the name of the firewall at security.yml
  244.                         $token = new UsernamePasswordToken($customer, $customer->getPassword(), 'main', $customer->getRoles());
  245.                         $this->container->get('security.token_storage')->setToken($token);
  246.                         $event = new InteractiveLoginEvent($request, $token);
  247.                         $dispatcher = new EventDispatcher();
  248.                         $dispatcher->dispatch($event, "security.interactive_login");
  249.                         $login = $this->getLoginHelper($request);
  250.                         $login->login($customer->getEmail());
  251.                     }
  252.                     return $this->redirectToRoute('customer_registration_successful', [
  253.                         'customerType' => $customerType,
  254.                     ]);
  255.                 } else {
  256.                     $data['errorMessage'] = $this->getTranslator()->trans('E-Mail Address is already registered');
  257.                     if ($this->getEnvironment() == 'prod' && $domain->getId() == Domain::DOMAIN_ID_WS_EU) {
  258.                         $mailer = $this->getMailer();
  259.                         $customerEmail = $form->get('email')->getData();
  260.                         $email = (new TemplatedEmail())
  261.                             ->subject('New registration attempt on WS EU - ' . $customerEmail)
  262.                             ->to('timea.osziova@furbify.eu')
  263.                             ->replyTo($this->getParameter('mailer_reply_to'))
  264.                             ->html('New registration attempt on WS EU - ' . $customerEmail);
  265.                         $mailer->send($email);
  266.                     }
  267.                 }
  268.             } else {
  269.                 $data['errorMessage'] = $this->getTranslator()->trans('Captcha check failed, please try again!');
  270.             }
  271.         }
  272.         $data['breadcrumbs'] = [];
  273.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  274.         $data['breadcrumbs'][] = [
  275.             'text' => $translator->trans('Account'),
  276.             'href' => $this->generateUrl('customer_account'),
  277.         ];
  278.         $data['breadcrumbs'][] = [
  279.             'text' => $translator->trans('Create account'),
  280.             'href' => $this->generateUrl('customer_registration'),
  281.         ];
  282.         $legalLinks = $this->getLegalLinks($request, $domain->getId());
  283.         $data['privacy_policy_link'] = $legalLinks['terms_conditions'];
  284.         $data['form'] = $form->createView();
  285.         $data['header'] = $this->getHeader($request);
  286.         $data['footer'] = $this->getFooter($request);
  287.         $data['contentBottom'] = $this->getContentBottom($request);
  288.         if ($defaultLanguageCode == 'cz') {
  289.             $data['callingCountryCode'] = '+420';
  290.         } elseif ($defaultLanguageCode == 'hu') {
  291.             $data['callingCountryCode'] = '+36';
  292.         } else {
  293.             $data['callingCountryCode'] = '+421';
  294.         }
  295.         $data['insecurePasswords'] = SecurityHelper::getMostCommonPasswords();
  296.         return $data;
  297.     }
  298.     #[Route('/check-existing-email', name: 'check_existing_email')]
  299.     public function checkExistingEmailAction(Request $request): JsonResponse
  300.     {
  301.         $data = $request->request->get('customer');
  302.         if (!is_array($data)) {
  303.             return new JsonResponse(false);
  304.         }
  305.         $email = $data['email'];
  306.         $domainId = $request->getSession()->get('domainId');
  307.         $customer = $this->getEntityManager()->getRepository(Customer::class)->findOneBy([
  308.             'email'  => $email,
  309.             'domain' => [$domainId, Domain::getRetailWholesaleDomainPairs()[$domainId]],
  310.         ]);
  311.         return new JsonResponse(!((bool) $customer));
  312.     }
  313.     /**
  314.      * @Route("/registration-successful/{customerType}", name="customer_registration_successful", defaults={"_locale":""})
  315.      * @Route("/{_locale<%supported_locales%>?}/registration-successful/{customerType}", name="customer_registration_successful_locale", defaults={"_locale":""})
  316.      * @param Request $request
  317.      * @param int $customerType
  318.      * @return Response
  319.      * @throws InvalidArgumentException
  320.      */
  321.     public function registrationSuccessfulAction(Request $request, int $customerType): Response
  322.     {
  323.         $translator = $this->getTranslator();
  324.         $data = [];
  325.         $data['heading_title'] = $translator->trans('Successful registration');
  326.         $data['breadcrumbs'] = [];
  327.         $data['customerType'] = $customerType;
  328.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  329.         $data['breadcrumbs'][] = [
  330.             'text' => $translator->trans('Account'),
  331.             'href' => $this->generateUrl('customer_account'),
  332.         ];
  333.         $data['breadcrumbs'][] = [
  334.             'text' => $translator->trans('Successful registration'),
  335.             'href' => $this->generateUrl('customer_registration_successful', [
  336.                 'customerType' => $customerType,
  337.             ]),
  338.         ];
  339.         $data['header'] = $this->getHeader($request);
  340.         $data['footer'] = $this->getFooter($request);
  341.         $data['contentBottom'] = $this->getContentBottom($request);
  342.         return $this->render('AtechNetCoreBundle/Customer/registrationSuccessful.html.twig', $data);
  343.     }
  344.     /**
  345.      * @Route("/login", name="customer_login", defaults={"_locale":""})
  346.      * @Route("/{_locale<%supported_locales%>?}/login", name="customer_login_locale", defaults={"_locale":""})
  347.      * @param AuthenticationUtils $authenticationUtils
  348.      * @param Request $request
  349.      * @return Response
  350.      * @throws InvalidArgumentException
  351.      * @throws OptimisticLockException
  352.      */
  353.     public function loginAction(AuthenticationUtils $authenticationUtils, Request $request)
  354.     {
  355.         $error = $authenticationUtils->getLastAuthenticationError(false);
  356.         if ($error) {
  357.             $this->addFlash(
  358.                 'danger',
  359.                 $this->getTranslator()->trans(
  360.                     $this->getLoginHelper($request)->handleRequestError($error)
  361.                 )
  362.             );
  363.             $request->getSession()->remove(Security::AUTHENTICATION_ERROR);
  364.             $referer = $request->headers->get('referer');
  365.             if (str_contains($referer, 'partner-login')) {
  366.                 return $this->redirectToRoute('partner_login');
  367.             }
  368.         }
  369.         $loginData = $this->loginBaseData($request);
  370.         if (is_array($loginData)) {
  371.             return $this->render('AtechNetCoreBundle/Customer/login.html.twig', $loginData);
  372.         } else {
  373.             return $loginData;
  374.         }
  375.     }
  376.     /**
  377.      * @Route("/partner-login", name="partner_login", defaults={"_locale":""})
  378.      * @Route("/{_locale<%supported_locales%>?}/partner-login", name="partner_login_locale", defaults={"_locale":""})
  379.      * @param AuthenticationUtils $authenticationUtils
  380.      * @param Request $request
  381.      * @return array|Response
  382.      * @throws InvalidArgumentException
  383.      * @throws OptimisticLockException
  384.      */
  385.     public function partnerLoginAction(Request $request)
  386.     {
  387.         $data = $this->loginBaseData($request);
  388.         if (is_array($data)) {
  389.             $multiStore = $this->getMultiStoreHelper($request);
  390.             $domain = $multiStore->getDomain();
  391.             $domainLanguage = $domain->getLanguage();
  392.             $entityManager = $this->getEntityManager();
  393.             // get the wholesale type of current language domain
  394.             $domain = $entityManager->getRepository(Domain::class)->findOneBy([
  395.                 'language' => $domainLanguage,
  396.                 'type' => Domain::TYPE_WHOLESALE,
  397.             ]);
  398.             $data['warrantyYear'] = $this->getWarrantyForNonProductText($domain->getId());
  399.             // default salesManager
  400.             $data['salesManager'] = $domain->getDefaultSalesManager();
  401.             if ($domainLanguage->getCode() == 'sk') {
  402.                 $data['salesManager1'] = $entityManager->getRepository(User::class)->findOneById(231);
  403.                 $data['salesManager2'] = $entityManager->getRepository(User::class)->findOneById(224);
  404.             }
  405.             $data['languageCode'] = $domainLanguage->getCode();
  406.             return $this->render('AtechNetCoreBundle/Customer/partnerLogin.html.twig', $data);
  407.         } else {
  408.             return $data;
  409.         }
  410.     }
  411.     /**
  412.      * @param Request $request
  413.      * @return array|RedirectResponse
  414.      * @throws InvalidArgumentException
  415.      * @throws OptimisticLockException
  416.      */
  417.     private function loginBaseData(Request $request)
  418.     {
  419.         if ($this->getLoginHelper($request)->isLoggedIn()) {
  420.             return $this->redirectToRoute('customer_account');
  421.         }
  422.         $translator = $this->getTranslator();
  423.         $data = [];
  424.         $data['hideChat'] = true;
  425.         $data['heading_title'] = $translator->trans('Login');
  426.         $data['breadcrumbs'] = [];
  427.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  428.         $data['breadcrumbs'][] = [
  429.             'text' => $translator->trans('Account'),
  430.             'href' => $this->generateUrl('customer_account'),
  431.         ];
  432.         $data['breadcrumbs'][] = [
  433.             'text' => $translator->trans('Login'),
  434.             'href' => $this->generateUrl('customer_login'),
  435.         ];
  436.         $targetPath = !is_null($request->get('_target_path')) ? $request->get('_target_path') : '';
  437.         $data['targetPath'] = $targetPath;
  438.         $customer = new Customer();
  439.         $form = $this->createForm(CustomerLoginType::class, $customer, [
  440.             'action' => $this->generateUrl('customer_login'),
  441.         ]);
  442.         $form->handleRequest($request);
  443.         $data['form'] = $form->createView();
  444.         $data['header'] = $this->getHeader($request);
  445.         $data['footer'] = $this->getFooter($request);
  446.         $data['contentBottom'] = $this->getContentBottom($request);
  447.         return $data;
  448.     }
  449.     /**
  450.      * @Route("/account", name="customer_account", defaults={"_locale":""})
  451.      * @Route("/{_locale<%supported_locales%>?}/account", name="customer_account_locale", defaults={"_locale":""})
  452.      * @param Request $request
  453.      * @return Response
  454.      * @throws \Exception
  455.      */
  456.     public function accountAction(Request $request): Response
  457.     {
  458.         if (!$this->getLoginHelper($request)->isLoggedIn()) {
  459.             return $this->redirectToRoute('customer_login');
  460.         }
  461.         $multiStore = $this->getMultiStoreHelper($request);
  462.         $translator = $this->getTranslator();
  463.         $customerTypeId = $request->getSession()->get('customerTypeId');
  464.         $data = [];
  465.         $data['heading_title'] = $this->getTranslator()->trans('My Account');
  466.         $data['breadcrumbs'] = [];
  467.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  468.         $data['breadcrumbs'][] = [
  469.             'text' => $translator->trans('My Account'),
  470.             'href' => $this->generateUrl('customer_account'),
  471.         ];
  472.         $customer = $this->getLoginHelper($request)->getLoggedInCustomer();
  473.         $data['name'] = $customerTypeId == MultiStore::CUSTOMER_TYPE_RETAIL ? $customer->getFullName() : $customer->getBusinessName();
  474.         $domain = $multiStore->getDomain();
  475.         $data['currency'] = $domain->getCurrency();
  476.         $data['precision'] = $domain->getPricePrecision();
  477.         // Orders under processing
  478.         $data['orders'] = [];
  479.         $queryBuilder = $this->getEntityManager()->createQueryBuilder();
  480.         $queryBuilder
  481.             ->select('o')
  482.             ->from('AtechNetCoreBundle:Order', 'o')
  483.             ->andWhere('o.customer = :customerId')
  484.             ->setParameter(':customerId', $customer->getId())
  485.             ->andWhere(
  486.                 $queryBuilder->expr()->notIn('o.status', [Order::STATUS_CANCELED, Order::STATUS_FINISHED])
  487.             )
  488.             ->andWhere('o.domain = :domainId')
  489.             ->setParameter(':domainId', $domain->getId())
  490.             ->orderBy('o.created', 'DESC')
  491.             ->setFirstResult(0);
  492.         $query = $queryBuilder->getQuery();
  493.         $results = $query->getResult();
  494.         foreach ($results as $result) {
  495.             $data['orders'][] = [
  496.                 'orderId' => $result->getId(),
  497.                 'dateAdded' => $result->getCreated()->format($this->getTranslator()->trans('datetime.format')),
  498.                 'status' => $result->getStatus() > 0 ? $result->getStatusTitle($this->getDatabaseTranslator($request)) : '',
  499.                 'statusId' => $result->getStatus(),
  500.                 'total' => $result->getFullPrice(),
  501.                 'view' => $this->generateUrl('customer_order_show', [
  502.                     'orderId' => $result->getId(),
  503.                 ]),
  504.             ];
  505.         }
  506.         $data['commissionCount'] = $this->getCommissionsCount($request);
  507.         $data['header'] = $this->getHeader($request);
  508.         $data['footer'] = $this->getFooter($request);
  509.         $data['contentBottom'] = $this->getContentBottom($request);
  510.         return $this->render('AtechNetCoreBundle/Customer/account.html.twig', $data);
  511.     }
  512.     /**
  513.      * @Route("/account/edit", name="customer_account_edit", defaults={"_locale":""})
  514.      * @Route("/{_locale<%supported_locales%>?}/account/edit", name="customer_account_edit_locale", defaults={"_locale":""})
  515.      * @param Request $request
  516.      * @param UserPasswordHasherInterface $passwordHasher
  517.      * @return Response
  518.      * @throws InvalidArgumentException
  519.      */
  520.     public function accountEditAction(Request $request, UserPasswordHasherInterface $passwordHasher): Response
  521.     {
  522.         if (!$this->getLoginHelper($request)->isLoggedIn()) {
  523.             return $this->redirectToRoute('customer_login');
  524.         }
  525.         $multiStore = $this->getMultiStoreHelper($request);
  526.         $translator = $this->getTranslator();
  527.         $data = [];
  528.         $data['heading_title'] = $translator->trans('Account Details');
  529.         $data['breadcrumbs'] = [];
  530.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  531.         $data['breadcrumbs'][] = [
  532.             'text' => $translator->trans('My Account'),
  533.             'href' => $this->generateUrl('customer_account'),
  534.         ];
  535.         $data['breadcrumbs'][] = [
  536.             'text' => $translator->trans('Account Details'),
  537.             'href' => $this->generateUrl('customer_account_edit'),
  538.         ];
  539.         // Logged in Customer
  540.         $customer = $this->getLoginHelper($request)->getLoggedInCustomer();
  541.         // Billing Address
  542.         $billingAddress = null;
  543.         foreach ($customer->getAddresses() as $address) {
  544.             if ($address->getType() == CustomerAddress::AddressType_Billing_Id) {
  545.                 $billingAddress = $address;
  546.                 break;
  547.             }
  548.         }
  549.         // Doman Language Code
  550.         $domainLanguageCode = $multiStore->getDomain()->getLanguage()->getCode();
  551.         // Phone Number
  552.         $phoneNumber = $customer->getPhone();
  553.         // Remove non-numeric characters
  554.         $_phoneNumber = preg_replace('/[^0-9]/', '', $phoneNumber);
  555.         // Add plus sign if was removed
  556.         if (substr($phoneNumber, 0, 1) == '+') {
  557.             $_phoneNumber = '+' . $_phoneNumber;
  558.         }
  559.         // Remove calling codes to prevent duplication
  560.         if ($domainLanguageCode == 'cz') {
  561.             $phoneNumber = preg_replace('/^(\+420|00420)/', '', $_phoneNumber);
  562.         } elseif ($domainLanguageCode == 'hu') {
  563.             $phoneNumber = preg_replace('/^(\+36|0036|06)/', '', $_phoneNumber);
  564.         } else {
  565.             $phoneNumber = preg_replace('/^(\+421|00421|0)/', '', $_phoneNumber);
  566.         }
  567.         // Build Form
  568.         $defaultData = [
  569.             'email' => $customer->getEmail(),
  570.             'phoneNumber' => $phoneNumber,
  571.             'firstName' => $customer->getFirstName(),
  572.             'lastName' => $customer->getLastName(),
  573.             'address' => !is_null($billingAddress) ? $billingAddress->getStreet() : '',
  574.             'postalCode' => !is_null($billingAddress) ? $billingAddress->getZip() : '',
  575.             'city' => !is_null($billingAddress) ? $billingAddress->getCity() : '',
  576.             'country' => !is_null($billingAddress) ? $billingAddress->getCountry() : $multiStore->getDefaultCountry(),
  577.             'businessName' => $customer->getBusinessName(),
  578.             'businessId' => $customer->getBusinessId(),
  579.             'taxId' => $customer->getTaxId(),
  580.             'vatNumber' => $customer->getVatId(),
  581.         ];
  582.         $form = $this->createForm(CustomerEditType::class, $defaultData, [
  583.             'locale' => $request->getLocale(),
  584.             'customer' => $customer,
  585.             'passwordHasher' => $passwordHasher,
  586.         ]);
  587.         $originalEmail = $customer->getEmail();
  588.         $form->handleRequest($request);
  589.         if ($form->isSubmitted()) {
  590.             if (!empty($form->get('password')->get('first')->getData()) && SecurityHelper::insecure($form->get('password')->get('first')->getData())) {
  591.                 $form->get('password')->get('first')->addError(new FormError($translator->trans('Unfortunately, the password provided is not secure, therefore it cannot be used in our webshop')));
  592.             }
  593.         }
  594.         if ($form->isSubmitted() && $form->isValid()) {
  595.             $entityManager = $this->getEntityManager();
  596.             // Billing Address
  597.             if (is_null($billingAddress)) { // Insert New
  598.                 $billingAddress = new CustomerAddress();
  599.                 $billingAddress->setCustomer($customer);
  600.                 $billingAddress->setType(CustomerAddress::AddressType_Billing_Id);
  601.                 $billingAddress->setTitle('');
  602.                 $billingAddress->setFirstName($form->get('firstName')->getData());
  603.                 $billingAddress->setLastName($form->get('lastName')->getData());
  604.                 $billingAddress->setBusinessName($form->get('businessName')->getData());
  605.                 $billingAddress->setStreet($form->get('address')->getData());
  606.                 $billingAddress->setCity($form->get('city')->getData());
  607.                 $billingAddress->setZip($form->get('postalCode')->getData());
  608.                 $billingAddress->setCountry($form->get('country')->getData());
  609.                 // District
  610.                 $billingAddress->setDistrict(OrderHelper::findDistrict($billingAddress->getZip(), $billingAddress->getCountry(), $request));
  611.                 $billingAddress->setPhone('');
  612.                 $billingAddress->setEmail('');
  613.                 $entityManager->persist($billingAddress);
  614.                 $entityManager->flush();
  615.             } else { // Update Existing
  616.                 $billingAddress->setFirstName($form->get('firstName')->getData());
  617.                 $billingAddress->setLastName($form->get('lastName')->getData());
  618.                 $billingAddress->setBusinessName($form->get('businessName')->getData());
  619.                 $billingAddress->setStreet($form->get('address')->getData());
  620.                 $billingAddress->setCity($form->get('city')->getData());
  621.                 $billingAddress->setZip($form->get('postalCode')->getData());
  622.                 $billingAddress->setCountry($form->get('country')->getData());
  623.                 // District
  624.                 $billingAddress->setDistrict(OrderHelper::findDistrict($billingAddress->getZip(), $billingAddress->getCountry(), $request));
  625.                 $entityManager->flush();
  626.             }
  627.             // Update Customer
  628.             $customer->setFirstName($form->get('firstName')->getData());
  629.             $customer->setLastName($form->get('lastName')->getData());
  630.             $customer->setBusinessName($form->get('businessName')->getData());
  631.             $customer->setBusinessId(str_replace([' ', '-'], '', $form->get('businessId')->getData()));
  632.             $customer->setTaxId($form->get('taxId')->getData());
  633.             $customer->setVatId($form->get('vatNumber')->getData());
  634.             // Phone Number
  635.             $phoneNumber = $form->get('phoneNumber')->getData();
  636.             // Remove non-numeric characters
  637.             $_phoneNumber = preg_replace('/[^0-9]/', '', $phoneNumber);
  638.             // Add plus sign if was removed
  639.             if (substr($phoneNumber, 0, 1) == '+') {
  640.                 $_phoneNumber = '+' . $_phoneNumber;
  641.             }
  642.             // Remove calling codes to prevent duplication
  643.             if ($domainLanguageCode == 'cz') {
  644.                 $phoneNumber = '+420' . preg_replace('/^(\+420|00420)/', '', $_phoneNumber);
  645.             } elseif ($domainLanguageCode == 'hu') {
  646.                 $phoneNumber = '+36' . preg_replace('/^(\+36|0036|06)/', '', $_phoneNumber);
  647.             } elseif ($domainLanguageCode == 'sk') {
  648.                 $phoneNumber = '+421' . preg_replace('/^(\+421|00421|0)/', '', $_phoneNumber);
  649.             } else {
  650.                 $phoneNumber = $_phoneNumber;
  651.             }
  652.             $customer->setPhone($phoneNumber);
  653.             // Update Password
  654.             if (!empty($form->get('password')->get('first')->getData())) {
  655.                 $password = Registration::encodePassword(
  656.                     $form->get('password')->get('first')->getData(),
  657.                     $customer,
  658.                     $passwordHasher
  659.                 );
  660.                 $customer->setPassword($password);
  661.             }
  662.             $entityManager->flush();
  663.             if ($this->getEnvironment() == 'prod') {
  664.                 $klaviyo = $this->getKlaviyoConnect($request);
  665.                 if ($originalEmail && $originalEmail != $customer->getEmail()) {
  666.                     $klaviyoProfile = $klaviyo->getProfileWithFilter(['email' => $originalEmail]);
  667.                 }
  668.                 else {
  669.                     $klaviyoProfile = $klaviyo->getProfileWithFilter(['email' => $customer->getEmail()]);
  670.                 }
  671.                 if (isset($klaviyoProfile[0])) {
  672.                     $klaviyo->updateProfile($customer, $klaviyoProfile[0]);
  673.                 } else if ($customer->isWantsNewsletter()) {
  674.                     $klaviyo->createProfile($customer);
  675.                 }
  676.             }
  677.             $this->addFlash(
  678.                 'success',
  679.                 $this->getTranslator()->trans('Your account has been successfully updated')
  680.             );
  681.             return $this->redirectToRoute('customer_account_edit');
  682.         }
  683.         $data['form'] = $form->createView();
  684.         $data['commissionCount'] = $this->getCommissionsCount($request);
  685.         $data['header'] = $this->getHeader($request);
  686.         $data['footer'] = $this->getFooter($request);
  687.         $data['contentBottom'] = $this->getContentBottom($request);
  688.         if ($domainLanguageCode == 'cz') {
  689.             $data['callingCountryCode'] = '+420';
  690.         } elseif ($domainLanguageCode == 'hu') {
  691.             $data['callingCountryCode'] = '+36';
  692.         } else {
  693.             $data['callingCountryCode'] = '+421';
  694.         }
  695.         $data['domainLanguageCode'] = $domainLanguageCode;
  696.         $data['insecurePasswords'] = SecurityHelper::getMostCommonPasswords();
  697.         return $this->render('AtechNetCoreBundle/Customer/accountEdit.html.twig', $data);
  698.     }
  699.     /**
  700.      * @Route("/account/address", name="customer_address", defaults={"_locale":""})
  701.      * @Route("/{_locale<%supported_locales%>?}/account/address", name="customer_address_locale", defaults={"_locale":""})
  702.      * @param Request $request
  703.      * @return Response
  704.      * @throws \Exception
  705.      */
  706.     public function addressAction(Request $request): Response
  707.     {
  708.         if (!$this->getLoginHelper($request)->isLoggedIn()) {
  709.             return $this->redirectToRoute('customer_login');
  710.         }
  711.         $translator = $this->getTranslator();
  712.         $data = [];
  713.         $data['breadcrumbs'] = [];
  714.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  715.         $data['breadcrumbs'][] = [
  716.             'text' => $translator->trans('My Account'),
  717.             'href' => $this->generateUrl('customer_account'),
  718.         ];
  719.         $data['breadcrumbs'][] = [
  720.             'text' => $translator->trans('Shipping Addresses'),
  721.             'href' => $this->generateUrl('customer_address'),
  722.         ];
  723.         $data['heading_title'] = $translator->trans('Shipping Addresses');
  724.         // Logged in Customer
  725.         $customer = $this->getLoginHelper($request)->getLoggedInCustomer();
  726.         // Countries
  727.         $countries = $this->getMultiStoreHelper($request)->getDomain()->getId() == 11
  728.                     ? CustomerAddress::EU_COUNTRIES
  729.                     : CustomerAddress::getCountries();
  730.         // Shipping Addresses
  731.         $data['addresses'] = [];
  732.         foreach ($customer->getAddresses() as $address) {
  733.             if ($address->getType() == CustomerAddress::AddressType_Shipping_Id) {
  734.                 if (!empty($address->getTitle())) {
  735.                     $format = '{title}' . "\n\n" . '{firstname} {lastname}' . "\n" . '{street}' . "\n" . '{postalcode} {city}' . "\n" . '{country}';
  736.                 } else {
  737.                     $format = '{firstname} {lastname}' . "\n" . '{street}' . "\n" . '{postalcode} {city}' . "\n" . '{country}';
  738.                 }
  739.                 $find = [
  740.                     '{title}',
  741.                     '{firstname}',
  742.                     '{lastname}',
  743.                     '{street}',
  744.                     '{city}',
  745.                     '{postalcode}',
  746.                     '{country}',
  747.                 ];
  748.                 $replace = [
  749.                     'title' => '<strong>' . $address->getTitle() . '</strong>',
  750.                     'firstname' => $address->getFirstName(),
  751.                     'lastname' => $address->getLastName(),
  752.                     'street' => $address->getStreet(),
  753.                     'city' => $address->getCity(),
  754.                     'postalcode' => $address->getZip(),
  755.                     'country' => $countries[$address->getCountry()],
  756.                 ];
  757.                 $data['addresses'][] = [
  758.                     'addressId' => $address->getId(),
  759.                     'address' => str_replace(
  760.                         ["\r\n", "\r", "\n"],
  761.                         '<br />',
  762.                         preg_replace(
  763.                             ["/\s\s+/", "/\r\r+/", "/\n\n+/"],
  764.                             '<br />',
  765.                             trim(str_replace($find, $replace, $format))
  766.                         )
  767.                     ),
  768.                     'edit' => $this->generateUrl('customer_address_edit', [
  769.                         'addressId' => $address->getId(),
  770.                     ]),
  771.                     'delete' => $this->generateUrl('customer_address_delete', [
  772.                         'addressId' => $address->getId(),
  773.                     ]),
  774.                 ];
  775.             }
  776.         }
  777.         $data['commissionCount'] = $this->getCommissionsCount($request);
  778.         $data['header'] = $this->getHeader($request);
  779.         $data['footer'] = $this->getFooter($request);
  780.         $data['contentBottom'] = $this->getContentBottom($request);
  781.         return $this->render('AtechNetCoreBundle/Customer/address.html.twig', $data);
  782.     }
  783.     /**
  784.      * @Route("/account/address/add", name="customer_address_add", defaults={"_locale":""})
  785.      * @Route("/{_locale<%supported_locales%>?}/account/address/add", name="customer_address_add_locale", defaults={"_locale":""})
  786.      * @param Request $request
  787.      * @return Response
  788.      * @throws \Exception
  789.      */
  790.     public function addressAddAction(Request $request): Response
  791.     {
  792.         if (!$this->getLoginHelper($request)->isLoggedIn()) {
  793.             return $this->redirectToRoute('customer_login');
  794.         }
  795.         $multiStore = $this->getMultiStoreHelper($request);
  796.         $translator = $this->getTranslator();
  797.         $data = [];
  798.         $data['breadcrumbs'] = [];
  799.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  800.         $data['breadcrumbs'][] = [
  801.             'text' => $translator->trans('My Account'),
  802.             'href' => $this->generateUrl('customer_account'),
  803.         ];
  804.         $data['breadcrumbs'][] = [
  805.             'text' => $translator->trans('Shipping Addresses'),
  806.             'href' => $this->generateUrl('customer_address'),
  807.         ];
  808.         $data['breadcrumbs'][] = [
  809.             'text' => $translator->trans('Add new address'),
  810.             'href' => $this->generateUrl('customer_address_add'),
  811.         ];
  812.         $data['heading_title'] = $translator->trans('Add new address');
  813.         // Logged in Customer
  814.         $customer = $this->getLoginHelper($request)->getLoggedInCustomer();
  815.         // Add new Address
  816.         $customerAddress = new CustomerAddress();
  817.         if ($this->getMultiStoreHelper($request)->getDomain()->getId() != 11) {
  818.             // Set Default Country, if the domain is not EU
  819.             $customerAddress->setCountry($multiStore->getDefaultCountry());
  820.         }
  821.         $form = $this->createForm(CustomerAddressType::class, $customerAddress, [
  822.             'locale' => $request->getLocale(),
  823.             'isEuDomain' => $this->getMultiStoreHelper($request)->getDomain()->getId() == 11,
  824.         ]);
  825.         $form->handleRequest($request);
  826.         if ($form->isSubmitted() && $form->isValid()) {
  827.             $entityManager = $this->getEntityManager();
  828.             $customerAddress->setCustomer($customer);
  829.             $customerAddress->setType(CustomerAddress::AddressType_Shipping_Id);
  830.             $entityManager->persist($customerAddress);
  831.             $entityManager->flush();
  832.             if ($this->getEnvironment() == 'prod') {
  833.                 $klaviyo = $this->getKlaviyoConnect($request);
  834.                 $klaviyoProfile = $klaviyo->getProfileWithFilter(['email' => $customer->getEmail()]);
  835.                 if (isset($klaviyoProfile[0])) {
  836.                     $klaviyo->updateProfile($customer, $klaviyoProfile[0]);
  837.                 } else if ($customer->isWantsNewsletter()) {
  838.                     $klaviyo->createProfile($customer);
  839.                 }
  840.             }
  841.             $this->addFlash(
  842.                 'success',
  843.                 $translator->trans('Your address has been successfully added')
  844.             );
  845.             return $this->redirectToRoute('customer_address');
  846.         }
  847.         $data['form'] = $form->createView();
  848.         $data['commissionCount'] = $this->getCommissionsCount($request);
  849.         $data['header'] = $this->getHeader($request);
  850.         $data['footer'] = $this->getFooter($request);
  851.         $data['contentBottom'] = $this->getContentBottom($request);
  852.         return $this->render('AtechNetCoreBundle/Customer/addressForm.html.twig', $data);
  853.     }
  854.     /**
  855.      * @Route("/account/address/{addressId}/edit", name="customer_address_edit", defaults={"_locale":""})
  856.      * @Route("/{_locale<%supported_locales%>?}/account/address/{addressId}/edit", name="customer_address_edit_locale", defaults={"_locale":""})
  857.      * @param int $addressId
  858.      * @param Request $request
  859.      * @return Response
  860.      * @throws \Exception
  861.      */
  862.     public function addressEditAction(int $addressId, Request $request): Response
  863.     {
  864.         if (!$this->getLoginHelper($request)->isLoggedIn()) {
  865.             return $this->redirectToRoute('customer_login');
  866.         }
  867.         $translator = $this->getTranslator();
  868.         $customerAddress = $this->getEntityManager()->getRepository(CustomerAddress::class)->findOneById($addressId);
  869.         if ($customerAddress) {
  870.             $data = [];
  871.             $data['breadcrumbs'] = [];
  872.             $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  873.             $data['breadcrumbs'][] = [
  874.                 'text' => $translator->trans('My Account'),
  875.                 'href' => $this->generateUrl('customer_account'),
  876.             ];
  877.             $data['breadcrumbs'][] = [
  878.                 'text' => $translator->trans('Shipping Addresses'),
  879.                 'href' => $this->generateUrl('customer_address'),
  880.             ];
  881.             $data['breadcrumbs'][] = [
  882.                 'text' => $translator->trans('Edit Address'),
  883.                 'href' => $this->generateUrl('customer_address_edit', [
  884.                     'addressId' => $customerAddress->getId(),
  885.                 ]),
  886.             ];
  887.             $data['heading_title'] = $translator->trans('Edit Address');
  888.             // Edit Address
  889.             $form = $this->createForm(CustomerAddressType::class, $customerAddress, [
  890.                 'locale' => $request->getLocale(),
  891.                 'isEuDomain' => $this->getMultiStoreHelper($request)->getDomain()->getId() == 11,
  892.             ]);
  893.             $form->handleRequest($request);
  894.             if ($form->isSubmitted() && $form->isValid()) {
  895.                 $entityManager = $this->getEntityManager();
  896.                 $entityManager->persist($customerAddress);
  897.                 $entityManager->flush();
  898.                 if ($this->getEnvironment() == 'prod') {
  899.                     $customer = $customerAddress->getCustomer();
  900.                     $klaviyo = $this->getKlaviyoConnect($request);
  901.                     $klaviyoProfile = $klaviyo->getProfileWithFilter(['email' => $customer->getEmail()]);
  902.                     if (isset($klaviyoProfile[0])) {
  903.                         $klaviyo->updateProfile($customer, $klaviyoProfile[0]);
  904.                     } else if ($customer->isWantsNewsletter()) {
  905.                         $klaviyo->createProfile($customer);
  906.                     }
  907.                 }
  908.                 $this->addFlash(
  909.                     'success',
  910.                     $translator->trans('Your address has been successfully edited')
  911.                 );
  912.                 return $this->redirectToRoute('customer_address');
  913.             }
  914.             $data['form'] = $form->createView();
  915.             $data['commissionCount'] = $this->getCommissionsCount($request);
  916.             $data['header'] = $this->getHeader($request);
  917.             $data['footer'] = $this->getFooter($request);
  918.             $data['contentBottom'] = $this->getContentBottom($request);
  919.             return $this->render('AtechNetCoreBundle/Customer/addressForm.html.twig', $data);
  920.         }
  921.         $this->addFlash(
  922.             'error',
  923.             $translator->trans('Your address has not been found:')
  924.         );
  925.         return $this->redirectToRoute('customer_address');
  926.     }
  927.     /**
  928.      * @Route("/account/address/{addressId}/delete", name="customer_address_delete", defaults={"_locale":""})
  929.      * @Route("/{_locale<%supported_locales%>?}/account/address/{addressId}/delete", name="customer_address_delete_locale", defaults={"_locale":""})
  930.      * @param int $addressId
  931.      * @param Request $request
  932.      * @return Response
  933.      */
  934.     public function addressDeleteAction(int $addressId, Request $request): Response
  935.     {
  936.         if (!$this->getLoginHelper($request)->isLoggedIn()) {
  937.             return $this->redirectToRoute('customer_login');
  938.         }
  939.         $translator = $this->getTranslator();
  940.         $customerAddress = $this->getEntityManager()->getRepository(CustomerAddress::class)->findOneById($addressId);
  941.         if ($customerAddress) {
  942.             $entityManager = $this->getEntityManager();
  943.             $customerId = $customerAddress->getCustomer()->getId();
  944.             $entityManager->remove($customerAddress);
  945.             $entityManager->flush();
  946.             if ($this->getEnvironment() == 'prod') {
  947.                 $customer = $entityManager->getRepository(Customer::class)->findOneById($customerId);
  948.                 $klaviyo = $this->getKlaviyoConnect($request);
  949.                 $klaviyoProfile = $klaviyo->getProfileWithFilter(['email' => $customer->getEmail()]);
  950.                 if (isset($klaviyoProfile[0])) {
  951.                     $klaviyo->updateProfile($customer, $klaviyoProfile[0]);
  952.                 } else if ($customer->isWantsNewsletter()) {
  953.                     $klaviyo->createProfile($customer);
  954.                 }
  955.             }
  956.             $this->addFlash(
  957.                 'success',
  958.                 $translator->trans('Your address has been successfully deleted')
  959.             );
  960.             return $this->redirectToRoute('customer_address');
  961.         }
  962.         $this->addFlash(
  963.             'error',
  964.             $translator->trans('Your address has not been found:')
  965.         );
  966.         return $this->redirectToRoute('customer_address');
  967.     }
  968.     /**
  969.      * @Route("/account/newsletter", name="customer_newsletter", defaults={"_locale":""})
  970.      * @Route("/{_locale<%supported_locales%>?}/account/newsletter", name="customer_newsletter_locale", defaults={"_locale":""})
  971.      * @param Request $request
  972.      * @return Response
  973.      * @throws \Exception
  974.      */
  975.     public function newsletterAction(Request $request): Response
  976.     {
  977.         if (!$this->getLoginHelper($request)->isLoggedIn()) {
  978.             return $this->redirectToRoute('customer_login');
  979.         }
  980.         $translator = $this->getTranslator();
  981.         $data = [];
  982.         $data['breadcrumbs'] = [];
  983.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  984.         $data['breadcrumbs'][] = [
  985.             'text' => $translator->trans('My Account'),
  986.             'href' => $this->generateUrl('customer_account'),
  987.         ];
  988.         $data['breadcrumbs'][] = [
  989.             'text' => $translator->trans('Newsletter Subscription'),
  990.             'href' => $this->generateUrl('customer_newsletter'),
  991.         ];
  992.         $data['heading_title'] = $translator->trans('Newsletter Subscription');
  993.         // Logged in Customer
  994.         $customer = $this->getLoginHelper($request)->getLoggedInCustomer();
  995.         $entityManager = $this->getEntityManager();
  996.         // Edit Subscription
  997.         $form = $this->createForm(
  998.             NewsletterType::class,
  999.             [
  1000.                 'subscribe' => $customer->isWantsNewsletter(),
  1001.             ],
  1002.             [
  1003.                 'locale' => $request->getLocale(),
  1004.             ]
  1005.         );
  1006.         $form->handleRequest($request);
  1007.         if ($form->isSubmitted() && $form->isValid()) {
  1008.             $customer->setWantsNewsletter($form->get('subscribe')->getData());
  1009.             if ($this->getEnvironment() == 'prod') {
  1010.                 $klaviyo = $this->getKlaviyoConnect($request);
  1011.                 $klaviyoProfile = $klaviyo->getProfileWithFilter(['email' => $customer->getEmail()]);
  1012.                 if (isset($klaviyoProfile[0])) {
  1013.                     $klaviyo->updateProfile(
  1014.                         $customer,
  1015.                         $klaviyoProfile[0],
  1016.                         $customer->isWantsNewsletter()
  1017.                     );
  1018.                 }
  1019.             }
  1020.             $entityManager->persist($customer);
  1021.             $entityManager->flush();
  1022.             $this->addFlash(
  1023.                 'success',
  1024.                 $translator->trans('Your newsletter subscription has been successfully updated')
  1025.             );
  1026.             return $this->redirectToRoute('customer_newsletter');
  1027.         }
  1028.         $data['form'] = $form->createView();
  1029.         $data['commissionCount'] = $this->getCommissionsCount($request);
  1030.         $data['header'] = $this->getHeader($request);
  1031.         $data['footer'] = $this->getFooter($request);
  1032.         $data['contentBottom'] = $this->getContentBottom($request);
  1033.         return $this->render('AtechNetCoreBundle/Customer/newsletter.html.twig', $data);
  1034.     }
  1035.     /**
  1036.      * @Route("/account/order", name="customer_orders", defaults={"_locale":""})
  1037.      * @Route("/{_locale<%supported_locales%>?}/account/order", name="customer_orders_locale", defaults={"_locale":""})
  1038.      * @param Request $request
  1039.      * @return Response
  1040.      * @throws \Exception
  1041.      */
  1042.     public function orderAction(Request $request): Response
  1043.     {
  1044.         if (!$this->getLoginHelper($request)->isLoggedIn()) {
  1045.             return $this->redirectToRoute('customer_login');
  1046.         }
  1047.         $multiStore = $this->getMultiStoreHelper($request);
  1048.         $domainId = $multiStore->getDomainId();
  1049.         $customer = $this->getLoginHelper($request)->getLoggedInCustomer();
  1050.         $translator = $this->getTranslator();
  1051.         $data = [];
  1052.         $data['heading_title'] = $translator->trans('Orders');
  1053.         $data['breadcrumbs'] = [];
  1054.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  1055.         $data['breadcrumbs'][] = [
  1056.             'text' => $translator->trans('Account'),
  1057.             'href' => $this->generateUrl('customer_account'),
  1058.         ];
  1059.         $data['breadcrumbs'][] = [
  1060.             'text' => $translator->trans('Orders'),
  1061.             'href' => $this->generateUrl('customer_orders'),
  1062.         ];
  1063.         if ($request->get('page')) {
  1064.             $page = $request->get('page');
  1065.         } else {
  1066.             $page = 1;
  1067.         }
  1068.         $limit = 15;
  1069.         $domain = $multiStore->getDomain();
  1070.         $data['currency'] = $domain->getCurrency();
  1071.         $data['precision'] = $domain->getPricePrecision();
  1072.         $data['orders'] = [];
  1073.         $results = $this->getEntityManager()->getRepository(Order::class)->findBy(
  1074.             [
  1075.                 'customer' => $customer->getId(),
  1076.                 'domain' => $domain->getId(),
  1077.             ],
  1078.             [
  1079.                 'created' => 'DESC',
  1080.             ],
  1081.             $limit,
  1082.             (($page - 1) * $limit)
  1083.         );
  1084.         $total = $this->getEntityManager()->getRepository(Order::class)->findBy([
  1085.             'customer' => $customer->getId(),
  1086.             'domain' => $domain->getId(),
  1087.         ]);
  1088.         /**
  1089.          * @var Order $result
  1090.          * @var Document $document
  1091.          * @var CustomerBillingoData $billingoDocument
  1092.          */
  1093.         foreach ($results as $result) {
  1094.             $invoiceLink = '';
  1095.             if ($result->getStatus() == Order::STATUS_FINISHED) {
  1096.                 if ($result->getDocuments()->count() > 0 || $result->getBillingoDocuments()->count() > 0) {
  1097.                     if (in_array($domainId, [1, 2, 5, 9, 3, 4]) && $result->getDocuments()->count() > 0) { // Centralis documents
  1098.                         $invoiceId = 0;
  1099.                         foreach ($result->getDocuments() as $document) {
  1100.                             if ($invoiceId == 0) {
  1101.                                 $invoiceId = $document->getId();
  1102.                             } elseif ($invoiceId != 0 && $document->getGroup()->getType() == DocumentGroup::TYPE_INVOICE_OUT) {
  1103.                                 $invoiceId = $document->getId();
  1104.                             }
  1105.                         }
  1106.                         $invoiceLink = $this->generateUrl('customer_invoice_pdf', [
  1107.                             'id' => $invoiceId,
  1108.                             'type' => self::INVOICE_TYPE_CENTRALIS,
  1109.                         ]);
  1110.                     } elseif (in_array($domainId, [3, 4]) || $result->getBillingoDocuments()->count()) { // Billingo documents
  1111.                         $invoiceId = 0;
  1112.                         foreach ($result->getBillingoDocuments() as $billingoDocument) {
  1113.                             if ($invoiceId == 0) {
  1114.                                 $invoiceId = $billingoDocument->getId();
  1115.                             } elseif ($invoiceId != 0 && $billingoDocument->getType() == BillingoOperation::TYPE_NORMAL) {
  1116.                                 $invoiceId = $billingoDocument->getId();
  1117.                             }
  1118.                         }
  1119.                         $invoiceLink = $this->generateUrl('customer_invoice_pdf', [
  1120.                             'id' => $invoiceId,
  1121.                             'type' => self::INVOICE_TYPE_BILLINGO,
  1122.                         ]);
  1123.                     }
  1124.                 }
  1125.             }
  1126.             $statusTitle = '';
  1127.             $waitingStatuses = [
  1128.                 Order::STATUS_TRIAGE,
  1129.                 Order::STATUS_WAITING,
  1130.                 Order::STATUS_WAITING_FOR_PARTNER,
  1131.                 Order::STATUS_WAITING_FOR_PRODUCTION,
  1132.                 Order::STATUS_WAITING_FOR_PRODUCTION_SALES,
  1133.                 Order::STATUS_WAITING_FOR_PRODUCTION_QUARANTINE,
  1134.                 Order::STATUS_WAITING_FOR_PRODUCTION_AIKEN,
  1135.                 Order::STATUS_WAITING_FOR_ANSWER_SALES,
  1136.                 Order::STATUS_WAITING_FOR_ANSWER_SERVICE,
  1137.                 Order::STATUS_WAITING_FOR_ANSWER_ADMIN,
  1138.                 Order::STATUS_WAITING_FOR_ANSWER,
  1139.             ];
  1140.             if ($result->getStatus() > 0) {
  1141.                 if (
  1142.                     $result->getStatus() <= Order::STATUS_WAITING_FOR_ANSWER_SALES
  1143.                     || in_array($result->getStatus(), $waitingStatuses)
  1144.                 ) {
  1145.                     $statusTitle = $this->getTranslator()->trans('Processing');
  1146.                 } else {
  1147.                     $statusTitle = $this->getTranslator()->trans($result->getStatusTitle());
  1148.                 }
  1149.             }
  1150.             if ($result->getPickupPointSetting()) {
  1151.                 $pickupPointId = $result->getPickupPointSetting()->getValue();
  1152.                 $pickupPoint = $this->getEntityManager()->getRepository(PickupPoint::class)->findOneById($pickupPointId);
  1153.                 $statusTitle .= ' - ' . $pickupPoint->getStreet() . ', ' . $pickupPoint->getCity() . ', ' . $pickupPoint->getZip() . ', ' . CustomerAddress::getCountries()[$pickupPoint->getCountry()];
  1154.             }
  1155.             $data['orders'][] = [
  1156.                 'orderId' => $result->getId(),
  1157.                 'dateAdded' => $result->getCreated()->format($this->getTranslator()->trans('datetime.format')),
  1158.                 'status' => $statusTitle,
  1159.                 'statusId' => $result->getStatus(),
  1160.                 'total' => $result->getFullPrice(),
  1161.                 'view' => $this->generateUrl('customer_order_show', [
  1162.                     'orderId' => $result->getId(),
  1163.                 ]),
  1164.                 'invoiceLink' => $invoiceLink,
  1165.             ];
  1166.         }
  1167.         $data['pagination'] = [
  1168.             'total' => count($total),
  1169.             'page' => $page,
  1170.             'limit' => $limit,
  1171.             'url' => $this->generateUrl('customer_orders', [
  1172.                 'page' => '{page}',
  1173.             ]),
  1174.             'noInfinite' => 1,
  1175.         ];
  1176.         $data['commissionCount'] = $this->getCommissionsCount($request);
  1177.         $data['header'] = $this->getHeader($request);
  1178.         $data['footer'] = $this->getFooter($request);
  1179.         $data['contentBottom'] = $this->getContentBottom($request);
  1180.         return $this->render('AtechNetCoreBundle/Customer/orders.html.twig', $data);
  1181.     }
  1182.     /**
  1183.      * @Route("/account/invoice/{id}/{type}/{token}", name="customer_invoice_pdf", defaults={"_locale":""})
  1184.      * @Route("/{_locale<%supported_locales%>?}/account/invoice/{id}/{type}/{token}", name="customer_invoice_pdf_locale", defaults={"_locale":""})
  1185.      * @param Request $request
  1186.      * @param int $id
  1187.      * @param int $type
  1188.      * @param string|null $token
  1189.      * @return RedirectResponse|Response
  1190.      * @throws \Mpdf\MpdfException
  1191.      */
  1192.     public function downloadInvoiceAction(Request $request, int $id, int $type, ?string $token = null): RedirectResponse|Response
  1193.     {
  1194.         // Order Repository
  1195.         $orderRepository = $this->getEntityManager()->getRepository(Order::class);
  1196.         // Show Public Order
  1197.         if (!is_null($token)) {
  1198.             $publicOrder = $orderRepository->decodePublicLinkToken($token);
  1199.             if (is_null($publicOrder) || !isset($publicOrder['orderId']) || !isset($publicOrder['documentId']) || !isset($publicOrder['type']) || (isset($publicOrder['documentId']) && $id !== (int)$publicOrder['documentId']) || (isset($publicOrder['type']) && $type !== (int)$publicOrder['type'])) {
  1200.                 return $this->redirectToRoute('not_found');
  1201.             }
  1202.         } elseif (!$this->getLoginHelper($request)->isLoggedIn()) { // Otherwise: Logged-in Customer
  1203.             return $this->redirectToRoute('customer_login');
  1204.         }
  1205.         $entityManager = $this->getEntityManager();
  1206.         $customer = $this->getLoginHelper($request)->getLoggedInCustomer();
  1207.         if (!is_numeric($id)) {
  1208.             throw new InvalidParameterException();
  1209.         }
  1210.         if ($type == self::INVOICE_TYPE_CENTRALIS) {
  1211.             if (!is_null($token)) {
  1212.                 $document = $entityManager->getRepository(Document::class)->findOneBy([
  1213.                     'id' => $id,
  1214.                 ]);
  1215.             } else {
  1216.                 $document = $entityManager->getRepository(Document::class)->findOneBy([
  1217.                     'id' => $id,
  1218.                     'customer' => $customer,
  1219.                 ]);
  1220.             }
  1221.             if ($document) {
  1222.                 // Validate public link
  1223.                 if (isset($publicOrder['orderId']) && $document->getOrder()->getId() !== (int)$publicOrder['orderId']) {
  1224.                     return $this->redirectToRoute('not_found');
  1225.                 }
  1226.                 $documentRepo = $entityManager->getRepository(Document::class);
  1227.                 $pdf = $documentRepo->createPdf($document, 0, $this->getSquarePay());
  1228.                 return new Response(
  1229.                     $pdf->output(sprintf(
  1230.                         '%s-%s-%d.pdf',
  1231.                         ($document->getBusinessName() != '' ? $document->getBusinessName() : $document->getFirstName() . '-' . $document->getLastName()),
  1232.                         strtolower(
  1233.                             iconv(
  1234.                                 'utf-8',
  1235.                                 'us-ascii//TRANSLIT',
  1236.                                 $this->getTranslator()->trans(DocumentGroup::TYPES[$document->getGroup()->getType()])
  1237.                             )
  1238.                         ),
  1239.                         $document->getCode()
  1240.                     ), 'I'),
  1241.                     Response::HTTP_OK,
  1242.                     [
  1243.                         'content-type' => 'application/pdf',
  1244.                     ]
  1245.                 );
  1246.             }
  1247.         } elseif ($type == self::INVOICE_TYPE_BILLINGO) {
  1248.             /**
  1249.              * @var CustomerBillingoData $billingoInvoice
  1250.              */
  1251.             if (!is_null($token)) {
  1252.                 $billingoInvoice = $entityManager->getRepository(CustomerBillingoData::class)->findOneBy([
  1253.                     'id' => $id,
  1254.                 ]);
  1255.             } else {
  1256.                 $billingoInvoice = $entityManager->getRepository(CustomerBillingoData::class)->findOneBy([
  1257.                     'id' => $id,
  1258.                     'customer' => $customer,
  1259.                 ]);
  1260.             }
  1261.             if ($billingoInvoice) {
  1262.                 // Validate public link
  1263.                 if (isset($publicOrder['orderId']) && $billingoInvoice->getOrder()->getId() !== (int)$publicOrder['orderId']) {
  1264.                     return $this->redirectToRoute('not_found');
  1265.                 }
  1266.                 return new Response(
  1267.                     $this->getBillingo()->downloadDocument($billingoInvoice->getInvoiceV3Id()),
  1268.                     200,
  1269.                     [
  1270.                         'Content-type' => 'application/pdf',
  1271.                     ]
  1272.                 );
  1273.             }
  1274.         }
  1275.         return $this->redirectToRoute('not_found');
  1276.     }
  1277.     /**
  1278.      * @Route("/account/order/{orderId}/{token}", name="customer_order_show", defaults={"_locale":""})
  1279.      * @Route("/{_locale<%supported_locales%>?}/account/order/{orderId}/{token}", name="customer_order_show_locale", defaults={"_locale":""})
  1280.      *
  1281.      * @param Request $request
  1282.      * @param int $orderId
  1283.      * @param string|null $token
  1284.      * @return Response
  1285.      * @throws \Exception
  1286.      */
  1287.     public function showOrderAction(Request $request, int $orderId, ?string $token = null): Response
  1288.     {
  1289.         // Order Repository
  1290.         $orderRepository = $this->getEntityManager()->getRepository(Order::class);
  1291.         // Show Public Order
  1292.         if (!is_null($token)) {
  1293.             $publicOrder = $orderRepository->decodePublicLinkToken($token);
  1294.             if (is_null($publicOrder) || !isset($publicOrder['orderId']) || (isset($publicOrder['orderId']) && $orderId !== (int)$publicOrder['orderId'])) {
  1295.                 return $this->redirectToRoute('not_found');
  1296.             }
  1297.             // Put Order ID to the Session for later use on Payment Result Page
  1298.             $request->getSession()->set('paymentOrderId', $orderId);
  1299.         } // Otherwise: Logged-in Customer
  1300.         elseif (!$this->getLoginHelper($request)->isLoggedIn()) {
  1301.             return $this->redirectToRoute('customer_login');
  1302.         }
  1303.         $multiStore = $this->getMultiStoreHelper($request);
  1304.         $productHelper = $this->getProductHelper($request);
  1305.         $customer = $this->getLoginHelper($request)->getLoggedInCustomer();
  1306.         $translator = $this->getTranslator();
  1307.         $seoUrlHelper = $this->getSeoUrlHelper($request);
  1308.         $domainId = $multiStore->getDomainId();
  1309.         $data = [];
  1310.         $data['errorMessage'] = '';
  1311.         $data['heading_title'] = $translator->trans('Order') . ': ' . $orderId;
  1312.         $data['breadcrumbs'] = [];
  1313.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  1314.         $data['breadcrumbs'][] = [
  1315.             'text' => $translator->trans('Account'),
  1316.             'href' => $this->generateUrl('customer_account'),
  1317.         ];
  1318.         $data['breadcrumbs'][] = [
  1319.             'text' => $translator->trans('Orders'),
  1320.             'href' => $this->generateUrl('customer_orders'),
  1321.         ];
  1322.         $data['breadcrumbs'][] = [
  1323.             'text' => $translator->trans('Order') . ': ' . $orderId,
  1324.             'href' => $this->generateUrl('customer_order_show', [
  1325.                 'orderId' => $orderId,
  1326.             ]),
  1327.         ];
  1328.         $domain = $multiStore->getDomain();
  1329.         $data['currency'] = $domain->getCurrency();
  1330.         $data['precision'] = $domain->getPricePrecision();
  1331.         $entityManager = $this->getEntityManager();
  1332.         if (!is_null($token)) {
  1333.             /**
  1334.              * @var Order $order
  1335.              */
  1336.             $order = $entityManager->getRepository(Order::class)->findOneBy([
  1337.                 'id' => $orderId,
  1338.                 'domain' => $domain->getId(),
  1339.             ]);
  1340.         } else {
  1341.             /**
  1342.              * @var Order $order
  1343.              */
  1344.             $order = $entityManager->getRepository(Order::class)->findOneBy([
  1345.                 'id' => $orderId,
  1346.                 'customer' => $customer->getId(),
  1347.                 'domain' => $domain->getId(),
  1348.             ]);
  1349.         }
  1350.         if ($order) {
  1351.             // Countries
  1352.             $countries = CustomerAddress::getCountries();
  1353.             $data['orderId'] = $order->getId();
  1354.             $data['orderStatusTitle'] = '';
  1355.             $orderStatus = $order->getStatus();
  1356.             if ($orderStatus > 0) {
  1357.                 if ((Order::STATUS_PRE_PROCESSING_ISSUE <= $orderStatus && $orderStatus <= Order::STATUS_WAITING_FOR_ANSWER) || $orderStatus == Order::STATUS_TRIAGE || $orderStatus == Order::STATUS_PROCESSING_ISSUES) {
  1358.                     $data['orderStatusTitle'] = $this->getTranslator()->trans('Processing');
  1359.                 } else {
  1360.                     $data['orderStatusTitle'] = $this->getTranslator()->trans($order->getStatusTitle());
  1361.                 }
  1362.             }
  1363.             $warrantyEnd = $order->getWarrantyEnd();
  1364.             $data['orderInWarranty'] = (new \DateTime()) < $warrantyEnd;
  1365.             $data['productInWarranty'] = (new \DateTime()) < $warrantyEnd;
  1366.             $data['warrantyEnd'] = $warrantyEnd->format($translator->trans('datetime.format'));
  1367.             $data['dateAdded'] = $order->getCreated()->format($translator->trans('datetime.format'));
  1368.             $defaultFormat = '{firstname} {lastname}' . "\n" . '{street}' . "\n" . '{postalcode} {city}' . "\n" . '{country}';
  1369.             $format = false;
  1370.             $find = [
  1371.                 '{firstname}',
  1372.                 '{lastname}',
  1373.                 '{street}',
  1374.                 '{city}',
  1375.                 '{postalcode}',
  1376.                 '{country}',
  1377.                 '{company}',
  1378.             ];
  1379.             if ($order->getShippingBusinessName() != '') {
  1380.                 $format = '{company}' . "\n" . $defaultFormat;
  1381.             }
  1382.             $countrySelection = CustomerAddress::getCountries();
  1383.             $country = $countrySelection[$order->getShippingCountry()] ?? $order->getShippingCountry();
  1384.             $replace = [
  1385.                 'firstname' => $order->getShippingFirstName(),
  1386.                 'lastname' => $order->getShippingLastName(),
  1387.                 'street' => $order->getShippingStreet(),
  1388.                 'city' => $order->getShippingCity(),
  1389.                 'postalcode' => $order->getShippingZip(),
  1390.                 'country' => $country,
  1391.                 'company' => $order->getShippingBusinessName(),
  1392.             ];
  1393.             $data['shippingAddress'] = str_replace(
  1394.                 ["\r\n", "\r", "\n"],
  1395.                 '<br />',
  1396.                 preg_replace(
  1397.                     ["/\s\s+/", "/\r\r+/", "/\n\n+/"],
  1398.                     '<br />',
  1399.                     trim(str_replace(
  1400.                         $find,
  1401.                         $replace,
  1402.                         ($format ? $format : $defaultFormat)
  1403.                     ))
  1404.                 )
  1405.             );
  1406.             $translationKey = 'shipping.method.type.' . $order->getShippingType();
  1407.             if (($data['shippingMethod'] = $translator->trans($translationKey)) == $translationKey) {
  1408.                 $data['shippingMethod'] = $translator->trans('Delivery method');
  1409.             }
  1410.             $data['shippingCost'] = $order->getShippingPrice();
  1411.             if ($order->getBillingBusinessName() != '') {
  1412.                 $format = '{company}' . "\n" . $defaultFormat;
  1413.             } else {
  1414.                 $format = $defaultFormat;
  1415.             }
  1416.             $replace = [
  1417.                 'firstname' => $order->getBillingFirstName(),
  1418.                 'lastname' => $order->getBillingLastName(),
  1419.                 'street' => $order->getBillingStreet(),
  1420.                 'city' => $order->getBillingCity(),
  1421.                 'postalcode' => $order->getBillingZip(),
  1422.                 'country' => in_array($domainId, [Domain::DOMAIN_ID_RT_EU, Domain::DOMAIN_ID_WS_EU]) ? CustomerAddress::EU_COUNTRIES[$order->getBillingCountry()] : $countries[$order->getBillingCountry()],
  1423.                 'company' => $order->getBillingBusinessName(),
  1424.             ];
  1425.             $data['billingAddress'] = str_replace(
  1426.                 ["\r\n", "\r", "\n"],
  1427.                 '<br />',
  1428.                 preg_replace(
  1429.                     ["/\s\s+/", "/\r\r+/", "/\n\n+/"],
  1430.                     '<br />',
  1431.                     trim(str_replace($find, $replace, ($format ? $format : $defaultFormat)))
  1432.                 )
  1433.             );
  1434.             if ($order->getDomain()->getId() == Domain::DOMAIN_ID_WS_HU && $order->getPaymentType() == PaymentType::BankTransfer->value) {
  1435.                 $translationKey = 'payment.method.type.' . $order->getPaymentType() . '.wshu';
  1436.             } else {
  1437.                 $translationKey = 'payment.method.type.' . $order->getPaymentType();
  1438.             }
  1439.             if (($data['paymentMethod'] = $translator->trans($translationKey)) == $translationKey) {
  1440.                 $data['paymentMethod'] = $translator->trans('Payment method');
  1441.             }
  1442.             $data['paymentCost'] = $order->getPaymentPrice();
  1443.             $data['products'] = [];
  1444.             $dbTranslator = $this->getDatabaseTranslator($request);
  1445.             /** @var OrderItem $item */
  1446.             foreach ($order->getOrderItems() as $item) {
  1447.                 if ($item->getParent() == null) {
  1448.                     $itemProduct = $item->getProduct();
  1449.                     $product = $productHelper->getStructuredDataForProduct($itemProduct, 'cart');
  1450.                     if ($product) {
  1451.                         $options = [];
  1452.                         foreach ($item->getItemAttributes() as $attribute) {
  1453.                             $option = $attribute->getAttributeOption();
  1454.                             $optionMeta = $option->getDomainMeta($domain);
  1455.                             if ($optionMeta) {
  1456.                                 $optionValue = $option->getLongTitle($dbTranslator);
  1457.                                 if (!$optionValue) {
  1458.                                     $optionValue = $option->getTitle($dbTranslator);
  1459.                                 }
  1460.                                 $optionTitle = $option->getAttribute()->getTitle();
  1461.                                 //-> Warranty
  1462.                                 $warranty = false;
  1463.                                 if ($option->getId() == 2226) { // +1 year
  1464.                                     $warranty = (clone $warrantyEnd)->add(new \DateInterval('P1Y'));
  1465.                                 } elseif ($option->getId() == 2227) { // +2 year
  1466.                                     $warranty = (clone $warrantyEnd)->add(new \DateInterval('P2Y'));
  1467.                                 } elseif ($option->getId() == 2228) { // +3 year
  1468.                                     $warranty = (clone $warrantyEnd)->add(new \DateInterval('P3Y'));
  1469.                                 }
  1470.                                 if ($data['productInWarranty'] === false) {
  1471.                                     $data['productInWarranty'] = (new \DateTime()) < $warranty;
  1472.                                 }
  1473.                                 //<- Warranty
  1474.                                 $options[] = [
  1475.                                     'id' => $attribute->getId(),
  1476.                                     'title' => $optionTitle,
  1477.                                     'value' => $optionValue,
  1478.                                     'warranty' => ($warranty !== false ? $warranty->format($translator->trans('datetime.format')) : false),
  1479.                                     'inWarranty' => ($warranty !== false && $warrantyEnd !== $warranty && (new \DateTime()) < $warranty),
  1480.                                 ];
  1481.                             }
  1482.                         }
  1483.                         $data['items'][] = [
  1484.                             'id' => $item->getId(),
  1485.                             'code' => $product['code'],
  1486.                             'href' => $seoUrlHelper->link('product', [
  1487.                                 'product_id' => $product['id'],
  1488.                                 'isBazaar'   => $product['isBazaar'] ?? 0
  1489.                             ]),
  1490.                             'name' => ($product['vendor'] !== '' && $product['vendor'] !== 'VARIOUS' ? $product['vendor'] . ' ' : '') . $product['title'],
  1491.                             'description' => !is_null($item->getCustomConfiguration()) && $item->getCustomConfiguration() != '' ? $item->getCustomConfiguration() : $product['shortDescription'],
  1492.                             'quantity' => $item->getQuantity(),
  1493.                             'price' => $item->getItemFullPrice(),
  1494.                             'options' => $options,
  1495.                         ];
  1496.                     }
  1497.                 }
  1498.             }
  1499.             if (!empty($order->getCouponCode())) {
  1500.                 $data['coupon'] = $order->getCouponCode();
  1501.                 $coupon = $order->getCouponCodeSetting();
  1502.                 if ($coupon) {
  1503.                     $data['discount'] = $coupon->getValue();
  1504.                 } else {
  1505.                     $data['discount'] = 0;
  1506.                 }
  1507.             } else {
  1508.                 $data['coupon'] = '';
  1509.                 $data['discount'] = 0;
  1510.             }
  1511.             // Payment Status
  1512.             $data['paymentStatus'] = -1;
  1513.             if (in_array((int)$order->getPaymentType(), [PaymentType::DebitCard->value, PaymentType::DebitCard3Percent->value])) {
  1514.                 $data['paymentStatus'] = (int)$order->getPaymentStatus();
  1515.                 if ((int)$order->getPaymentStatus() == Order::PAYMENT_STATUS_PAID) {
  1516.                     // GoPay
  1517.                     if (in_array((int)$order->getDomain()->getId(), [Domain::DOMAIN_ID_RT_HU, Domain::DOMAIN_ID_WS_HU, Domain::DOMAIN_ID_RT_SK, Domain::DOMAIN_ID_WS_SK, Domain::DOMAIN_ID_RT_CZ, Domain::DOMAIN_ID_WS_CZ, Domain::DOMAIN_ID_B2C_EU])) {
  1518.                         $orderSetting = $order->getGoPayTransactionIdSetting();
  1519.                         if ($orderSetting) {
  1520.                             $data['datePaid'] = $orderSetting->getCreated()->format($translator->trans('datetime.format'));
  1521.                         }
  1522.                     }
  1523.                 } elseif (in_array((int)$order->getPaymentStatus(), [Order::PAYMENT_STATUS_PENDING, Order::PAYMENT_STATUS_FAILED])) {
  1524.                     // GoPay
  1525.                     if (in_array((int)$order->getDomain()->getId(), [Domain::DOMAIN_ID_RT_HU, Domain::DOMAIN_ID_WS_HU, Domain::DOMAIN_ID_RT_SK, Domain::DOMAIN_ID_WS_SK, Domain::DOMAIN_ID_RT_CZ, Domain::DOMAIN_ID_WS_CZ, Domain::DOMAIN_ID_B2C_EU, Domain::DOMAIN_ID_RT_EU, Domain::DOMAIN_ID_WS_EU])) {
  1526.                         // Helper
  1527.                         $gopayHelper = $this->getGopayHelper($request);
  1528.                         // Payment
  1529.                         $data['gopay_data'] = $gopayHelper->getInlineGatewayDataForOrder($order);
  1530.                     }
  1531.                 }
  1532.             }
  1533.             if ($order->getPaymentType() == PaymentType::Klarna->value) {
  1534.                 $data['paymentStatus'] = (int)$order->getPaymentStatus();
  1535.                 $orderSetting = $order->getKlarnaPaymentSessionIdSetting();
  1536.                 if ($orderSetting) {
  1537.                     if ((int)$order->getPaymentStatus() == Order::PAYMENT_STATUS_PAID) {
  1538.                         $klarnaOrderId = $order->getKlarnaOrderIdSetting();
  1539.                         $data['datePaid'] = $klarnaOrderId->getCreated()->format($translator->trans('datetime.format'));
  1540.                         $data['klarna_order_id'] = $klarnaOrderId->getValue();
  1541.                     } elseif (in_array((int)$order->getPaymentStatus(), [Order::PAYMENT_STATUS_PENDING, Order::PAYMENT_STATUS_FAILED])) {
  1542.                         $klarna = $this->getKlarna($domainId, $request, $order->getShippingCountry());
  1543.                         $klarnaSession = $klarna->getKlarnaSession($orderSetting->getValue());
  1544.                         if ($klarna->isValidKlarnaSession($klarnaSession, $order->getShippingCountry())) {
  1545.                             $data['klarna_data'] = $klarnaSession;
  1546.                         }
  1547.                     }
  1548.                 }
  1549.             }
  1550.             if ($order->getPaymentType() == PaymentType::PayPal->value) {
  1551.                 $data['paymentStatus'] = (int)$order->getPaymentStatus();
  1552.                 if ((int)$order->getPaymentStatus() == Order::PAYMENT_STATUS_PENDING) {
  1553.                     $orderItems = [];
  1554.                     /** @var OrderItem $oi */
  1555.                     foreach ($order->getOrderItems() as $oi) {
  1556.                         $orderItems[] = [
  1557.                             'id'       => $oi->getProduct()->getCode(),
  1558.                             'quantity' => $oi->getQuantity(),
  1559.                         ];
  1560.                     }
  1561.                     $data['paypal_data'] = [
  1562.                         'items'      => $orderItems,
  1563.                         'totalPrice' => $order->getFullPrice(),
  1564.                         'scriptSrc'  => $this->getPaypal()->getScriptSrc($order),
  1565.                         'currency'   => $order->getDomain()->getCurrencyTextCode(),
  1566.                     ];
  1567.                 }
  1568.             }
  1569.             /*if ($order->getPaymentType() == PaymentType::Milpay->value && $order->getPaymentStatus() == Order::PAYMENT_STATUS_ID_PENDING) {
  1570.                 $milpay = $this->getMilpay($domain->getLanguage()->getCode());
  1571.                 $application = $milpay->getApplicationStatus($order->getMilpayApplicationIdSetting()->getValue());
  1572.                 $data['milpay_data'] = [
  1573.                     'redirect_url' => $milpay->getRedirectToMerchantUrl($application['publicId'], $application['financier'])
  1574.                 ];
  1575.                 dd($milpay->cancelApplication($order));
  1576.             }*/
  1577.             $data['subTotal'] = $order->getSubTotal();
  1578.             $data['total'] = $order->getFullPrice();
  1579.             // Invoice Link
  1580.             $data['invoiceLink'] = '';
  1581.             if ($order->getStatus() == Order::STATUS_FINISHED) {
  1582.                 if ($order->getDocuments()->count() > 0 || $order->getBillingoDocuments()->count() > 0) {
  1583.                     if (in_array($domainId, [1, 2, 5, 9, 3, 4]) && $order->getDocuments()->count() > 0) { // Centralis documents
  1584.                         $invoiceId = 0;
  1585.                         foreach ($order->getDocuments() as $document) {
  1586.                             if ($invoiceId == 0) {
  1587.                                 $invoiceId = $document->getId();
  1588.                             } elseif ($invoiceId != 0 && $document->getGroup()->getType() == DocumentGroup::TYPE_INVOICE_OUT) {
  1589.                                 $invoiceId = $document->getId();
  1590.                             }
  1591.                         }
  1592.                         $data['invoiceLink'] = $this->generateUrl('customer_invoice_pdf', [
  1593.                             'id' => $invoiceId,
  1594.                             'type' => self::INVOICE_TYPE_CENTRALIS,
  1595.                             'token' => $orderRepository->generatePublicLinkToken([
  1596.                                 'orderId' => $order->getId(),
  1597.                                 'documentId' => $invoiceId,
  1598.                                 'type' => self::INVOICE_TYPE_CENTRALIS,
  1599.                             ]),
  1600.                         ]);
  1601.                     } elseif (in_array($domainId, [3, 4]) || $order->getBillingoDocuments()->count()) { // Billingo documents
  1602.                         $invoiceId = 0;
  1603.                         foreach ($order->getBillingoDocuments() as $billingoDocument) {
  1604.                             if ($invoiceId == 0) {
  1605.                                 $invoiceId = $billingoDocument->getId();
  1606.                             } elseif ($invoiceId != 0 && $billingoDocument->getType() == BillingoOperation::TYPE_NORMAL) {
  1607.                                 $invoiceId = $billingoDocument->getId();
  1608.                             }
  1609.                         }
  1610.                         $data['invoiceLink'] = $this->generateUrl('customer_invoice_pdf', [
  1611.                             'id' => $invoiceId,
  1612.                             'type' => self::INVOICE_TYPE_BILLINGO,
  1613.                             'token' => $orderRepository->generatePublicLinkToken([
  1614.                                 'orderId' => $order->getId(),
  1615.                                 'documentId' => $invoiceId,
  1616.                                 'type' => self::INVOICE_TYPE_BILLINGO,
  1617.                             ]),
  1618.                         ]);
  1619.                     }
  1620.                 } else {
  1621.                     $data['invoiceLink'] = 'alert';
  1622.                 }
  1623.             }
  1624.         } else {
  1625.             $data['errorMessage'] = $translator->trans('The order you requested could not be found');
  1626.         }
  1627.         $data['commissionCount'] = $this->getCommissionsCount($request);
  1628.         $data['header'] = $this->getHeader($request);
  1629.         $data['footer'] = $this->getFooter($request);
  1630.         $data['contentBottom'] = $this->getContentBottom($request);
  1631.         return $this->render('AtechNetCoreBundle/Customer/showOrder.html.twig', $data);
  1632.     }
  1633.     /**
  1634.      * @Route("/forgotten-password", name="customer_forgot_password", defaults={"_locale":""})
  1635.      * @Route("/{_locale<%supported_locales%>?}/forgotten-password", name="customer_forgot_password_locale", defaults={"_locale":""})
  1636.      * @param Request $request
  1637.      * @param UserPasswordHasherInterface $passwordHasher
  1638.      * @return Response
  1639.      * @throws InvalidArgumentException
  1640.      */
  1641.     public function forgotPasswordAction(Request $request, UserPasswordHasherInterface $passwordHasher): Response
  1642.     {
  1643.         if ($this->getLoginHelper($request)->isLoggedIn()) {
  1644.             return $this->redirectToRoute('customer_account');
  1645.         }
  1646.         $translator = $this->getTranslator();
  1647.         $data = [];
  1648.         $data['heading_title'] = $translator->trans('Forgotten password');
  1649.         $data['breadcrumbs'] = [];
  1650.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  1651.         $data['breadcrumbs'][] = [
  1652.             'text' => $translator->trans('Account'),
  1653.             'href' => $this->generateUrl('customer_account'),
  1654.         ];
  1655.         $data['breadcrumbs'][] = [
  1656.             'text' => $translator->trans('Forgotten password'),
  1657.             'href' => $this->generateUrl('customer_forgot_password'),
  1658.         ];
  1659.         $data['errorMessage'] = '';
  1660.         $customer = new Customer();
  1661.         $form = $this->createForm(CustomerForgotPasswordType::class, $customer, [
  1662.             'action' => $this->generateUrl('customer_forgot_password'),
  1663.         ]);
  1664.         $form->handleRequest($request);
  1665.         if ($form->isSubmitted()) {
  1666.             $email = $form->get('email')->getData();
  1667.             $registration = new Registration($this->getEntityManager(), $request, $passwordHasher);
  1668.             $passwordResetResult = $registration->resetPassword(
  1669.                 $email,
  1670.                 $this->getTranslator(),
  1671.                 $this->getMailer(),
  1672.                 $this->getParameter('mailer_reply_to')
  1673.             );
  1674.             if ($passwordResetResult['success']) {
  1675.                 return $this->redirectToRoute('customer_password_reset');
  1676.             }
  1677.             $data['errorMessage'] = $passwordResetResult['errorMessage'];
  1678.         }
  1679.         $data['form'] = $form->createView();
  1680.         $data['header'] = $this->getHeader($request);
  1681.         $data['footer'] = $this->getFooter($request);
  1682.         $data['contentBottom'] = $this->getContentBottom($request);
  1683.         return $this->render('AtechNetCoreBundle/Customer/forgotPassword.html.twig', $data);
  1684.     }
  1685.     /**
  1686.      * @Route("/password-reset", name="customer_password_reset", defaults={"_locale":""})
  1687.      * @Route("/{_locale<%supported_locales%>?}/password-reset", name="customer_password_reset_locale", defaults={"_locale":""})
  1688.      * @param Request $request
  1689.      * @return Response
  1690.      * @throws \Exception
  1691.      */
  1692.     public function passwordResetAction(Request $request): Response
  1693.     {
  1694.         if ($this->getLoginHelper($request)->isLoggedIn()) {
  1695.             return $this->redirectToRoute('customer_account');
  1696.         }
  1697.         $translator = $this->getTranslator();
  1698.         $data = [];
  1699.         $data['heading_title'] = $translator->trans('Forgotten password');
  1700.         $data['breadcrumbs'] = [];
  1701.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  1702.         $data['breadcrumbs'][] = [
  1703.             'text' => $translator->trans('Account'),
  1704.             'href' => $this->generateUrl('customer_account'),
  1705.         ];
  1706.         $data['breadcrumbs'][] = [
  1707.             'text' => $translator->trans('Forgotten password'),
  1708.             'href' => $this->generateUrl('customer_password_reset'),
  1709.         ];
  1710.         $data['header'] = $this->getHeader($request);
  1711.         $data['footer'] = $this->getFooter($request);
  1712.         $data['contentBottom'] = $this->getContentBottom($request);
  1713.         return $this->render('AtechNetCoreBundle/Customer/passwordReset.html.twig', $data);
  1714.     }
  1715.     /**
  1716.      * @Route("/logout", name="customer_logout", defaults={"_locale":""})
  1717.      * @Route("/{_locale<%supported_locales%>?}/logout", name="customer_logout_locale", defaults={"_locale":""})
  1718.      * @param Request $request
  1719.      * @return JsonResponse
  1720.      * @throws OptimisticLockException
  1721.      */
  1722.     public function logoutAction(Request $request): Response
  1723.     {
  1724.         $this->getLoginHelper($request)->logout();
  1725.         $request->getSession()->invalidate();
  1726.         return new JsonResponse([]);
  1727.     }
  1728.     /**
  1729.      * @Route("/account/claims", name="customer_claims", defaults={"_locale":""})
  1730.      * @Route("/{_locale<%supported_locales%>?}/account/claims", name="customer_claims_locale", defaults={"_locale":""})
  1731.      * @param Request $request
  1732.      * @return RedirectResponse|Response
  1733.      * @throws \Exception
  1734.      */
  1735.     public function claimsAction(Request $request)
  1736.     {
  1737.         if (!$this->getLoginHelper($request)->isLoggedIn()) {
  1738.             return $this->redirectToRoute('customer_login');
  1739.         }
  1740.         $translator = $this->getTranslator();
  1741.         $data = [];
  1742.         $data['heading_title'] = $translator->trans('Claims');
  1743.         $data['breadcrumbs'] = [];
  1744.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  1745.         $data['breadcrumbs'][] = [
  1746.             'text' => $translator->trans('Account'),
  1747.             'href' => $this->generateUrl('customer_account'),
  1748.         ];
  1749.         $data['breadcrumbs'][] = [
  1750.             'text' => $translator->trans('Claims'),
  1751.             'href' => $this->generateUrl('customer_claims'),
  1752.         ];
  1753.         $claims = $this->getEntityManager()->getRepository(Claim::class)->findBy(
  1754.             [
  1755.                 'customer' => $this->getLoginHelper($request)->getLoggedInCustomer(),
  1756.                 'type'     => [
  1757.                     Claim::TYPE_CLAIM,
  1758.                     Claim::TYPE_CLAIM_REMOTE,
  1759.                     Claim::TYPE_COMMISSION,
  1760.                     Claim::TYPE_UNCLAIMED_PACKAGE,
  1761.                 ],
  1762.             ],
  1763.             [
  1764.                 'created' => 'DESC',
  1765.             ]
  1766.         );
  1767.         $data['claims'] = [];
  1768.         $claimStatusTypes = ClaimStatus::getStatusChoices();
  1769.         $receiveTypes = Claim::getReceiveTypeChoices();
  1770.         /**
  1771.          * @var Claim $claim
  1772.          */
  1773.         foreach ($claims as $claim) {
  1774.             $data['claims'][] = [
  1775.                 'id'          => $claim->getId(),
  1776.                 'code'        => $claim->getCode(),
  1777.                 'created'     => $claim->getCreated(),
  1778.                 'status'      => ($claim->getLastStatus() ? $claimStatusTypes[$claim->getLastStatus()->getStatusType()] : ''),
  1779.                 'receiveType' => $receiveTypes[$claim->getReceiveType()],
  1780.                 'customerId'  => $claim->getCustomer()->getId(),
  1781.             ];
  1782.         }
  1783.         $data['commissionCount'] = $this->getCommissionsCount($request);
  1784.         $data['header'] = $this->getHeader($request);
  1785.         $data['footer'] = $this->getFooter($request);
  1786.         $data['contentBottom'] = $this->getContentBottom($request);
  1787.         return $this->render('AtechNetCoreBundle/Customer/claims.html.twig', $data);
  1788.     }
  1789.     /**
  1790.      * @Route("/account/claims/new/{orderItemId}", name="customer_claims_new", defaults={"_locale":""})
  1791.      * @Route("/{_locale<%supported_locales%>?}/account/claims/new/{orderItemId}", name="customer_claims_new_locale", defaults={"_locale":""})
  1792.      * @param Request $request
  1793.      * @param $orderItemId
  1794.      * @return RedirectResponse|Response
  1795.      * @throws InvalidArgumentException
  1796.      */
  1797.     public function claimsNewAction(Request $request, int $orderItemId = 0)
  1798.     {
  1799.         $data = [];
  1800.         $entityManager = $this->getEntityManager();
  1801.         $multistore = $this->getMultiStoreHelper($request);
  1802.         $domain = $multistore->getDomain();
  1803.         $defaultLocale = $multistore->getDefaultLocale();
  1804.         // Domain Language Code
  1805.         $domainLanguageCode = $domain->getLanguage()->getCode();
  1806.         $country = '';
  1807.         $invoiceCode = $request->request->get('customer_claim')['invoiceCode'] ?? null;
  1808.         $document = $entityManager->getRepository(Document::class)->findOneBy(['code' => $invoiceCode]);
  1809.         if ($this->getLoginHelper($request)->isLoggedIn()) {
  1810.             $customer = $this->getLoginHelper($request)->getLoggedInCustomer();
  1811.             $data['isLoggedIn'] = true;
  1812.             if ($domain->getId()) {
  1813.                 switch ($domain->getId()) {
  1814.                     case Domain::DOMAIN_ID_RT_SK:
  1815.                         $country = 'SK';
  1816.                         break;
  1817.                     case Domain::DOMAIN_ID_RT_HU:
  1818.                         $country = 'HU';
  1819.                         break;
  1820.                     case Domain::DOMAIN_ID_RT_CZ:
  1821.                         $country = 'CZ';
  1822.                         break;
  1823.                 }
  1824.             }
  1825.         } else {
  1826.             $customer = null;
  1827.             if (!is_null($request->request->get('customer_claim'))) {
  1828.                 $email = $request->request->get('customer_claim')['email'];
  1829.                 if ($email) {
  1830.                     $customer = $entityManager->getRepository(Customer::class)->findOneBy([
  1831.                         'email' => $email,
  1832.                         'domain' => $domain->getId(),
  1833.                     ]);
  1834.                 }
  1835.             }
  1836.             if (is_null($customer) && !is_null($request->request->get('customer_claim'))
  1837.                 && strlen($request->request->get('customer_claim')['order_id']) == "9") {
  1838.                 $orderId = $request->request->get('customer_claim')['order_id'];
  1839.                 $order = $entityManager->getRepository(Order::class)->findOneById($orderId);
  1840.                 $customer = $order ? $order->getCustomer() : null;
  1841.             }
  1842.             //if $orderItemId != 0 than I get the customer when the order is found below â†“
  1843.             if (!$customer) {
  1844.                 switch ($domain->getId()) {
  1845.                     case Domain::DOMAIN_ID_RT_SK:
  1846.                         $customerId = MultiStore::GUEST_CUSTOMER_ID_SK;
  1847.                         $country = 'SK';
  1848.                         break;
  1849.                     case Domain::DOMAIN_ID_RT_HU:
  1850.                         $customerId = MultiStore::GUEST_CUSTOMER_ID_HU;
  1851.                         $country = 'HU';
  1852.                         break;
  1853.                     case Domain::DOMAIN_ID_RT_CZ:
  1854.                         $customerId = MultiStore::GUEST_CUSTOMER_ID_CZ;
  1855.                         $country = 'CZ';
  1856.                         break;
  1857.                     default:
  1858.                         $customerId = false;
  1859.                 }
  1860.                 if (!$customerId && $orderItemId == 0) {
  1861.                     return $this->redirectToRoute('customer_login');
  1862.                 }
  1863.                 $customer = $entityManager->getRepository(Customer::class)->findOneById($customerId);
  1864.             }
  1865.             $data['isLoggedIn'] = false;
  1866.         }
  1867.         $translator = $this->getTranslator();
  1868.         $data['heading_title'] = $translator->trans('Create claim');
  1869.         $data['breadcrumbs'] = [];
  1870.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  1871.         $data['breadcrumbs'][] = [
  1872.             'text' => $translator->trans('Account'),
  1873.             'href' => $this->generateUrl('customer_account'),
  1874.         ];
  1875.         $data['breadcrumbs'][] = [
  1876.             'text' => $translator->trans('Create claim'),
  1877.             'href' => $this->generateUrl('customer_claims_new'),
  1878.         ];
  1879.         $data['orderItemId'] = $orderItemId;
  1880.         if ($defaultLocale != 'en') {
  1881.             $data['packetaApiKey'] = $this->getParameter('packeta')['api_key'];
  1882.             $data['shippingCountry'] = $defaultLocale;
  1883.         }
  1884.         $claim = new Claim();
  1885.         if (is_null($request->request->get('customer_claim')) || is_null($request->request->get('customer_claim')['firstName'])) {
  1886.             /**
  1887.              * @var Order $order
  1888.              */
  1889.             $orderItem = false;
  1890.             $order = false;
  1891.             if ($orderItemId != 0) {
  1892.                 $orderItem = $entityManager->getRepository(OrderItem::class)->findOneById($orderItemId);
  1893.                 if ($orderItem) {
  1894.                     $order = $orderItem->getOrder();
  1895.                     $claim->setBoughtDate($order->getCreated()->format('Y-m-d'));
  1896.                     $customer = $order->getCustomer();
  1897.                 }
  1898.             }
  1899.             if ($order) {
  1900.                 $data['orderNumber'] = $order->getId();
  1901.                 $claim->setOrder($order);
  1902.                 if ($order->useBillingAddressAsShippingAddress()) {
  1903.                     $claim->setCountry($order->getBillingCountry());
  1904.                     $claim->setStreet($order->getBillingStreet());
  1905.                     $claim->setCity($order->getBillingCity());
  1906.                     $claim->setZip($order->getBillingZip());
  1907.                 } else {
  1908.                     $claim->setCountry($order->getShippingCountry());
  1909.                     $claim->setStreet($order->getShippingStreet());
  1910.                     $claim->setCity($order->getShippingCity());
  1911.                     $claim->setZip($order->getShippingZip());
  1912.                 }
  1913.             } else {
  1914.                 /**
  1915.                  * @var CustomerAddress $customerAddress
  1916.                  */
  1917.                 $customerAddress = is_null($customer->getAddresses()) && !in_array($customer->getId(), [MultiStore::GUEST_CUSTOMER_ID_SK, MultiStore::GUEST_CUSTOMER_ID_HU, MultiStore::GUEST_CUSTOMER_ID_CZ]) ? false : $customer->getAddresses()->first();
  1918.                 if ($customerAddress) {
  1919.                     $claim->setCountry($customerAddress->getCountry());
  1920.                     $claim->setStreet($customerAddress->getStreet());
  1921.                     $claim->setCity($customerAddress->getCity());
  1922.                     $claim->setZip($customerAddress->getZip());
  1923.                 } else {
  1924.                     $claim->setCountry($customer->getCountry());
  1925.                 }
  1926.             }
  1927.             if (in_array($customer->getId(), [MultiStore::GUEST_CUSTOMER_ID_SK, MultiStore::GUEST_CUSTOMER_ID_HU, MultiStore::GUEST_CUSTOMER_ID_CZ])) {
  1928.                 $claim->setFirstName('');
  1929.                 $claim->setLastName('');
  1930.                 $claim->setBusinessName('');
  1931.                 $claim->setPhone('');
  1932.                 $claim->setEmail('');
  1933.                 $claim->setBoughtDate((new \DateTime())->format('Y-m-d'));
  1934.             } else {
  1935.                 $claim->setFirstName($customer->getFirstName());
  1936.                 $claim->setLastName($customer->getLastName());
  1937.                 $claim->setBusinessName($customer->getBusinessName());
  1938.                 // Phone Number
  1939.                 $phoneNumber = $customer->getPhone();
  1940.                 // Remove non-numeric characters
  1941.                 $_phoneNumber = preg_replace('/[^0-9]/', '', $phoneNumber);
  1942.                 // Add plus sign if was removed
  1943.                 if (substr($phoneNumber, 0, 1) == '+') {
  1944.                     $_phoneNumber = '+' . $_phoneNumber;
  1945.                 }
  1946.                 // Remove calling codes to prevent duplication
  1947.                 if ($domainLanguageCode == 'cz') {
  1948.                     $phoneNumber = preg_replace('/^(\+420|00420)/', '', $_phoneNumber);
  1949.                 } elseif ($domainLanguageCode == 'hu') {
  1950.                     $phoneNumber = preg_replace('/^(\+36|0036|06)/', '', $_phoneNumber);
  1951.                 } else {
  1952.                     $phoneNumber = preg_replace('/^(\+421|00421|0)/', '', $_phoneNumber);
  1953.                 }
  1954.                 $claim->setPhone($phoneNumber);
  1955.                 $claim->setEmail($customer->getEmail());
  1956.                 $claim->setBoughtDate((new \DateTime())->format('Y-m-d'));
  1957.             }
  1958.             if ($orderItem) {
  1959.                 if (!is_null($orderItem->getStockMovementItem()) && $orderItem->getStockMovementItem()->getItems()->count() > 0) {
  1960.                     $claim->setSerialNumber($orderItem->getStockMovementItem()->getItems()->first()->getSerialNumber());
  1961.                 }
  1962.                 $claim->setBoughtDate($order->getCreated()->format('Y-m-d'));
  1963.                 $product = $orderItem->getProduct();
  1964.                 if ($product) {
  1965.                     $claim->setProductTitle($product->getVendor()->getName() . ' ' . $product->getName());
  1966.                     switch ($product->getType()->getId()) {
  1967.                         case ProductType::PRODUCT_TYPE_ID_PC:
  1968.                         case ProductType::PRODUCT_TYPE_ID_ALL_IN_ONE:
  1969.                             $claim->setProductType(Claim::PRODUCT_TYPE_PC);
  1970.                             break;
  1971.                         case ProductType::PRODUCT_TYPE_ID_NOTEBOOK:
  1972.                             $claim->setProductType(Claim::PRODUCT_TYPE_NOTEBOOK);
  1973.                             break;
  1974.                         case ProductType::PRODUCT_TYPE_ID_MONITOR:
  1975.                             $claim->setProductType(Claim::PRODUCT_TYPE_MONITOR);
  1976.                             break;
  1977.                         case ProductType::PRODUCT_TYPE_ID_PRINTER:
  1978.                             $claim->setProductType(Claim::PRODUCT_TYPE_PRINTER);
  1979.                             break;
  1980.                         default:
  1981.                             $claim->setProductType(Claim::PRODUCT_TYPE_COMPONENT);
  1982.                     }
  1983.                 }
  1984.                 if ($order->getBillingoDocuments()->count() > 0) {
  1985.                     $claim->setInvoiceCode($order->getBillingoDocuments()->first()->getInvoiceCode());
  1986.                 }
  1987.                 if ($order->getDocuments()->count() > 0) {
  1988.                     $claim->setInvoiceCode($order->getDocuments()->first()->getCode());
  1989.                 }
  1990.             }
  1991.         }
  1992.         $form = $this->createForm(CustomerClaimType::class, $claim, [
  1993.             'locale' => $request->getLocale(),
  1994.             'defaultLocale' => $defaultLocale,
  1995.             'domainType' => $domain->getType(),
  1996.         ]);
  1997.         $form->handleRequest($request);
  1998.         if ($form->isSubmitted() && $form->isValid() && !is_null($request->request->get('g-recaptcha-response'))) {
  1999.             $captchaResponse = $request->request->get('g-recaptcha-response');
  2000.             $captchaResult = $this->verifyGoogleCaptcha($captchaResponse);
  2001.             if ($captchaResult) {
  2002.                 $claim->setBoughtDate(str_replace('.', '-', $claim->getBoughtDate()));
  2003.                 $boughtDateArray = explode('-', $claim->getBoughtDate());
  2004.                 $boughDate = (new \DateTime())->setDate($boughtDateArray[0], $boughtDateArray[1], $boughtDateArray[2]);
  2005.                 $claim->setBoughtDate($boughDate);
  2006.                 $claim->setCustomer($customer);
  2007.                 $claim->setReceiveType(Claim::RECEIVE_TYPE_SHIPPED_BY_PARCEL);
  2008.                 $claim->setReturnType(Claim::RETURN_TYPE_PARCEL);
  2009.                 $countryData = $form->has('country') ? $form->get('country')->getData() : null;
  2010.                 $claim->setCountry(
  2011.                     $country == ''
  2012.                         ? (array_key_exists($countryData, CustomerAddress::EU_COUNTRIES) ? $countryData : strtoupper($domain->getLanguage()->getCode()))
  2013.                         : $country
  2014.                 );
  2015.                 // Phone Number
  2016.                 $phoneNumber = $form->get('phone')->getData();
  2017.                 // Remove non-numeric characters
  2018.                 $_phoneNumber = preg_replace('/[^0-9]/', '', $phoneNumber);
  2019.                 // Add plus sign if was removed
  2020.                 if (substr($phoneNumber, 0, 1) == '+') {
  2021.                     $_phoneNumber = '+' . $_phoneNumber;
  2022.                 }
  2023.                 // Remove calling codes to prevent duplication
  2024.                 if ($domainLanguageCode == 'cz') {
  2025.                     $phoneNumber = '+420' . preg_replace('/^(\+420|00420)/', '', $_phoneNumber);
  2026.                 } elseif ($domainLanguageCode == 'hu') {
  2027.                     $phoneNumber = '+36' . preg_replace('/^(\+36|0036|06)/', '', $_phoneNumber);
  2028.                 } elseif ($domainLanguageCode == 'sk') {
  2029.                     $phoneNumber = '+421' . preg_replace('/^(\+421|00421|0)/', '', $_phoneNumber);
  2030.                 } else {
  2031.                     $phoneNumber = $_phoneNumber;
  2032.                 }
  2033.                 $claim->setPhone($phoneNumber);
  2034.                 if ($defaultLocale != 'en') {
  2035.                     $claim->setIncomingPacketaBranchId((int)$form->getViewData()->getIncomingPacketaBranchId());
  2036.                     $claim->setIncomingPacketaBranchLabel((string)$form->getViewData()->getIncomingPacketaBranchLabel());
  2037.                 }
  2038.                 $claim->setCode($entityManager->getRepository(Claim::class)->createCode($claim));
  2039.                 if ($document) {
  2040.                     $claim->setDocument($document);
  2041.                     $claim->setInvoiceCode('');
  2042.                 }
  2043.                 $claim->setLastStatusId(ClaimStatus::STATUS_TYPE_REGISTERED);
  2044.                 $entityManager->persist($claim);
  2045.                 $entityManager->flush();
  2046.                 $claimStatus = new ClaimStatus();
  2047.                 $claimStatus->setClaim($claim);
  2048.                 $claimStatus->setStatusType(ClaimStatus::STATUS_TYPE_REGISTERED);
  2049.                 $entityManager->persist($claimStatus);
  2050.                 $notificationIds = [785, 3055];
  2051.                 foreach ($notificationIds as $notificationId) {
  2052.                     $notificationConfig = $entityManager->getRepository(NotificationConfig::class)->findOneById($notificationId);
  2053.                     $notification = new Notification();
  2054.                     $notification->setText('New claim #' . $claim->getCode());
  2055.                     $notification->setNotificationConfig($notificationConfig);
  2056.                     $notification->setActive(true);
  2057.                     $notification->setUrl('https://www.atechcomp.eu/centralis/web/claim/edit/' . $claim->getId());
  2058.                     $entityManager->persist($notification);
  2059.                 }
  2060.                 $entityManager->flush();
  2061.                 if ($customer->getDomain()->getType() == 'wholesale' && $this->getEnvironment() == 'prod' && in_array($claim->getType(), [Claim::TYPE_CLAIM, Claim::TYPE_WITHDRAWAL])) {
  2062.                     $mailer = $this->getMailer();
  2063.                     $emailTo = $customer->getDomain()->getId() != Domain::DOMAIN_ID_WS_EU ? $customer->getSalesManager()->getEmail() : 'export@furbify.eu';
  2064.                     $email = (new TemplatedEmail())
  2065.                         ->subject('New claim ' . $customer->getDomain()->getShortTitle() . ' - ' . $customer->getBusinessName())
  2066.                         ->to($emailTo)
  2067.                         ->html('New claim on ' . $customer->getDomain()->getShortTitle() . ' - ' . $customer->getBusinessName() . '<br> https://www.atechcomp.eu/centralis/web/claim/edit/' . $claim->getId());
  2068.                     $mailer->send($email);
  2069.                 }
  2070.                 $subDirectory = 'claim-images/' . $claim->getId();
  2071.                 $files = $request->files->get('claimMedias');
  2072.                 $fileCount = 0;
  2073.                 foreach ($files as $file) {
  2074.                     $response = $this->uploadFile($file, $subDirectory, ['image/jpeg', 'image/jpg', 'image/png']);
  2075.                     if ($response && $fileCount < 3) {
  2076.                         $claimMedia = new ClaimMedia();
  2077.                         $claimMedia->setClaim($claim);
  2078.                         $claimMedia->setFilename($response['filename']);
  2079.                         $claimMedia->setDirectory('uploads/' . $subDirectory);
  2080.                         $claimMedia->setMimeType($response['mimeType']);
  2081.                         // Upload Image to DigitalOcean Space
  2082.                         if ($this->getEnvironment() == 'prod') {
  2083.                             $result = $this->getDigitalOceanSpace()->claimMedia($claimMedia, 'upload');
  2084.                             // Update DigitalOcean Flag
  2085.                             if (!empty($result['success'])) {
  2086.                                 $claimMedia->setDigitalOcean(true);
  2087.                                 // Delete Local File - Enable after the test period
  2088.                                 // @unlink(DigitalOceanSpaces::getUploadDirectory() . $subDirectory . '/' . $response['filename']);
  2089.                             }
  2090.                         }
  2091.                         $entityManager->persist($claimMedia);
  2092.                         $fileCount++;
  2093.                     }
  2094.                 }
  2095.                 if ($claim->getIncomingPacketaBranchId() == 0) {
  2096.                     $mailer = $this->getMailer();
  2097.                     $emailTo = 'katarina.jobbagyova@furbify.eu';
  2098.                     $email = (new TemplatedEmail())
  2099.                         ->subject(
  2100.                             'New claim '
  2101.                             . $customer->getDomain()->getShortTitle()
  2102.                             . ' - '
  2103.                             . $customer->getBusinessName()
  2104.                             . ' (GLS courier service)'
  2105.                         )
  2106.                         ->to($emailTo)
  2107.                         ->html(
  2108.                             'New <a href="https://www.atechcomp.eu/centralis/web/claim/edit/' . $claim->getId() . '">claim</a> on ' . $customer->getDomain()->getShortTitle() . ' - ' . $customer->getBusinessName() . '<br>' .
  2109.                             '<br>' .
  2110.                             '<b>Please note:</b> You need to order <b> GLS courier service</b>.'
  2111.                         );
  2112.                     $mailer->send($email);
  2113.                 }
  2114.                 $entityManager->flush();
  2115.                 if ($this->getEnvironment() == 'prod') {
  2116.                     $this->getKlaviyoConnect($request)->createNewClaimEvent($claim);
  2117.                 }
  2118.                 $this->addFlash(
  2119.                     'success',
  2120.                     $translator->trans('Your claim has been successfully added. Please print the protocol and send it with the product!')
  2121.                 );
  2122.                 return $this->redirectToRoute('customer_claims_success', [
  2123.                     'id' => $claim->getId(),
  2124.                     'customerId' => $customer->getId(),
  2125.                 ]);
  2126.             } else {
  2127.                 $this->addFlash(
  2128.                     'error',
  2129.                     $translator->trans('Captcha check failed, please try again!')
  2130.                 );
  2131.             }
  2132.         }
  2133.         $data['form'] = $form->createView();
  2134.         $data['domainId'] = $domain->getId();
  2135.         $data['commissionCount'] = $this->getCommissionsCount($request);
  2136.         $data['header'] = $this->getHeader($request);
  2137.         $data['footer'] = $this->getFooter($request);
  2138.         $data['contentBottom'] = $this->getContentBottom($request);
  2139.         $data['precision'] = $domain->getPricePrecision();
  2140.         $data['currency'] = $domain->getCurrency();
  2141.         $data['deliveryPrice'] = [
  2142.             Domain::DOMAIN_ID_RT_SK => 5.90,
  2143.             Domain::DOMAIN_ID_WS_SK => 5.90,
  2144.             Domain::DOMAIN_ID_RT_HU => 2790,
  2145.             Domain::DOMAIN_ID_WS_HU => 2790,
  2146.             Domain::DOMAIN_ID_RT_CZ => 149,
  2147.             Domain::DOMAIN_ID_WS_CZ => 149,
  2148.             Domain::DOMAIN_ID_RT_EU => 10,
  2149.             Domain::DOMAIN_ID_WS_EU => 10,
  2150.         ];
  2151.         if ($domainLanguageCode == 'cz') {
  2152.             $data['callingCountryCode'] = '+420';
  2153.         } elseif ($domainLanguageCode == 'hu') {
  2154.             $data['callingCountryCode'] = '+36';
  2155.         } else {
  2156.             $data['callingCountryCode'] = '+421';
  2157.         }
  2158.         $data['domainLanguageCode'] = $domainLanguageCode;
  2159.         return $this->render('AtechNetCoreBundle/Customer/claimsNew.html.twig', $data);
  2160.     }
  2161.     /**
  2162.      * @Route("/account/claims/{id}/pdf/{customerId}", name="customer_claims_pdf", defaults={"_locale":""})
  2163.      * @Route("/{_locale<%supported_locales%>?}/account/claims/{id}/pdf/{customerId}", name="customer_claims_pdf_locale", defaults={"_locale":""})
  2164.      * @param Request $request
  2165.      * @param int $id
  2166.      * @param null $customerId
  2167.      * @return Response
  2168.      * @throws \Mpdf\MpdfException
  2169.      */
  2170.     public function claimsPdfAction(Request $request, int $id, $customerId = null): Response
  2171.     {
  2172.         $entityManager = $this->getEntityManager();
  2173.         if (!is_null($customerId)) {
  2174.             $customer = $entityManager->getRepository(Customer::class)->findOneById($customerId);
  2175.         } else {
  2176.             $customer = $this->getLoginHelper($request)->getLoggedInCustomer();
  2177.         }
  2178.         if (!$customer) {
  2179.             return $this->redirectToRoute('customer_login');
  2180.         }
  2181.         $claim = $entityManager->getRepository(Claim::class)->findOneBy([
  2182.             'id' => $id,
  2183.             'customer' => $customer,
  2184.         ]);
  2185.         if (!$claim) {
  2186.             return $this->redirectToRoute('not_found');
  2187.         }
  2188.         $data = [];
  2189.         /**
  2190.          * @var Claim $claim
  2191.          */
  2192.         $data['claim'] = $claim;
  2193.         $data['customerAddress'] = $claim->getCustomer()->getAddresses()->first();
  2194.         $data['statusChoices'] = ClaimStatus::getStatusChoices();
  2195.         $data['testTypes'] = ClaimTest::getTestTypes();
  2196.         $data['testStates'] = ClaimTest::getTestStates();
  2197.         $data['packetaCode'] = $claim->getIncomingPacketaBranchId() > 0 ? DomainShippingType::getPacketaReturnCodeForDomain($claim->getCustomer()->getDomain()) : false;
  2198.         $html = $this->render('AtechNetCoreBundle/PDF/claims.html.twig', $data);
  2199.         $pdf = new Mpdf([
  2200.             'mode' => '',
  2201.             'format' => 'A4',
  2202.             'default_font_size' => 9,
  2203.             'defualt_font' => 'dejavusans',
  2204.             'mgl' => 10,
  2205.             'mgr' => 10,
  2206.         ]);
  2207.         $pdf->shrink_tables_to_fit = false;
  2208.         $pdf->WriteHTML($html);
  2209.         return new Response(
  2210.             $pdf->output(
  2211.                 $this->getTranslator()->trans('Claim') . '_furbify_' . $request->getLocale() . '_' . $claim->getCode() . '.pdf',
  2212.                 'I'
  2213.             ),
  2214.             Response::HTTP_OK,
  2215.             [
  2216.                 'content-type' => 'application/pdf',
  2217.             ]
  2218.         );
  2219.     }
  2220.     /**
  2221.      * @Route("/account/claims/success/{id}/{customerId}", name="customer_claims_success", defaults={"_locale":""})
  2222.      * @Route("/{_locale<%supported_locales%>?}/account/claims/success/{id}/{customerId}", name="customer_claims_success_locale", defaults={"_locale":""})
  2223.      * @param Request $request
  2224.      * @param int $id
  2225.      * @param int $customerId
  2226.      * @return Response
  2227.      * @throws InvalidArgumentException
  2228.      */
  2229.     public function claimsSuccessAction(Request $request, int $id, int $customerId): Response
  2230.     {
  2231.         $data = [];
  2232.         $translator = $this->getTranslator();
  2233.         if ($this->getLoginHelper($request)->isLoggedIn()) {
  2234.             $data['isLoggedIn'] = true;
  2235.         } else {
  2236.             $data['isLoggedIn'] = false;
  2237.         }
  2238.         $data['heading_title'] = $translator->trans('Claim created');
  2239.         $data['breadcrumbs'] = [];
  2240.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  2241.         $data['breadcrumbs'][] = [
  2242.             'text' => $translator->trans('Account'),
  2243.             'href' => $this->generateUrl('customer_account'),
  2244.         ];
  2245.         $data['breadcrumbs'][] = [
  2246.             'text' => $translator->trans('Claim created'),
  2247.             'href' => $this->generateUrl('customer_claims_success', [
  2248.                 'id' => $id,
  2249.                 'customerId' => $customerId,
  2250.             ]),
  2251.         ];
  2252.         $entityManager = $this->getEntityManager();
  2253.         $customer = $entityManager->getRepository(Customer::class)->findOneById($customerId);
  2254.         $claim = $entityManager->getRepository(Claim::class)->findOneBy([
  2255.             'id' => $id,
  2256.             'customer' => $customer,
  2257.         ]);
  2258.         $data['claimId'] = $claim->getCode();
  2259.         $data['claimPdfUrl'] = $this->generateUrl('customer_claims_pdf', [
  2260.             'id' => $id,
  2261.             'customerId' => $customerId,
  2262.         ]);
  2263.         $data['claimTrackingUrl'] = $this->generateUrl('customer_claim_tracking', [
  2264.             'token' => $this->getEntityManager()->getRepository(Claim::class)->createClaimToken($claim),
  2265.         ], UrlGeneratorInterface::ABSOLUTE_URL);
  2266.         $data['commissionCount'] = $this->getCommissionsCount($request);
  2267.         $data['header'] = $this->getHeader($request);
  2268.         $data['footer'] = $this->getFooter($request);
  2269.         $data['contentBottom'] = $this->getContentBottom($request);
  2270.         return $this->render('AtechNetCoreBundle/Customer/claimsSuccess.html.twig', $data);
  2271.     }
  2272.     /**
  2273.      * @Route("/account/withdrawal/new", name="customer_withdrawal_new", defaults={"_locale":""})
  2274.      * @Route("/{_locale<%supported_locales%>?}/account/withdrawal/new", name="customer_withdrawal_new_locale", defaults={"_locale":""})
  2275.      * @param Request $request
  2276.      * @return RedirectResponse|Response
  2277.      * @throws InvalidArgumentException
  2278.      */
  2279.     public function withdrawalNewAction(Request $request)
  2280.     {
  2281.         $data = [];
  2282.         $translator = $this->getTranslator();
  2283.         $entityManager = $this->getEntityManager();
  2284.         $multistore = $this->getMultiStoreHelper($request);
  2285.         $domain = $multistore->getDomain();
  2286.         // Doman Language Code
  2287.         $domainLanguageCode = $domain->getLanguage()->getCode();
  2288.         $country = '';
  2289.         if ($this->getLoginHelper($request)->isLoggedIn()) {
  2290.             $customer = $this->getLoginHelper($request)->getLoggedInCustomer();
  2291.             $data['isLoggedIn'] = true;
  2292.             if ($domain->getId()) {
  2293.                 switch ($domain->getId()) {
  2294.                     case Domain::DOMAIN_ID_RT_SK:
  2295.                         $country = 'SK';
  2296.                         break;
  2297.                     case Domain::DOMAIN_ID_RT_HU:
  2298.                         $country = 'HU';
  2299.                         break;
  2300.                     case Domain::DOMAIN_ID_RT_CZ:
  2301.                         $country = 'CZ';
  2302.                         break;
  2303.                 }
  2304.             }
  2305.         } else {
  2306.             switch ($domain->getId()) {
  2307.                 case Domain::DOMAIN_ID_RT_SK:
  2308.                     $customerId = MultiStore::GUEST_CUSTOMER_ID_SK;
  2309.                     $country = 'SK';
  2310.                     break;
  2311.                 case Domain::DOMAIN_ID_RT_HU:
  2312.                     $customerId = MultiStore::GUEST_CUSTOMER_ID_HU;
  2313.                     $country = 'HU';
  2314.                     break;
  2315.                 case Domain::DOMAIN_ID_RT_CZ:
  2316.                     $customerId = MultiStore::GUEST_CUSTOMER_ID_CZ;
  2317.                     $country = 'CZ';
  2318.                     break;
  2319.                 default:
  2320.                     $customerId = false;
  2321.             }
  2322.             if (!$customerId) {
  2323.                 return $this->redirectToRoute('customer_login');
  2324.             }
  2325.             $customer = $entityManager->getRepository(Customer::class)->findOneById($customerId);
  2326.             $data['isLoggedIn'] = false;
  2327.         }
  2328.         $data['shippingCountry'] = $domain->getLanguage()->getCode();
  2329.         $data['packetaApiKey'] = $this->getParameter('packeta')['api_key'];
  2330.         $data['heading_title'] = $translator->trans('Create withdrawal');
  2331.         $data['breadcrumbs'] = [];
  2332.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  2333.         $data['breadcrumbs'][] = [
  2334.             'text' => $translator->trans('Account'),
  2335.             'href' => $this->generateUrl('customer_account'),
  2336.         ];
  2337.         $data['breadcrumbs'][] = [
  2338.             'text' => $translator->trans('Create claim'),
  2339.             'href' => $this->generateUrl('customer_claims_new'),
  2340.         ];
  2341.         $claim = new Claim();
  2342.         // Step
  2343.         $step = $request->request->get('step', 1);
  2344.         // First Step Form
  2345.         if ( $step == 1 ) {
  2346.             $firstStepForm = $this->createForm(CustomerWithdrawalType::class, $claim, [
  2347.                 'locale'        => $request->getLocale(), 
  2348.                 'defaultLocale' => $multistore->getDefaultLocale(), 
  2349.                 'domainType'    => $domain->getType(), 
  2350.                 'step'          => 1
  2351.             ]);
  2352.             $data['step'] = 1;
  2353.             $firstStepForm->handleRequest($request);
  2354.             if ( $firstStepForm->isSubmitted() && $firstStepForm->isValid() ) {
  2355.                 /** @var Document $document */
  2356.                 $document = $entityManager->getRepository(Document::class)->findOneByCode($claim->getInvoiceCode());
  2357.                 if ( is_null($document) ) {
  2358.                     /** @var Order $order */
  2359.                     $order = $entityManager->getRepository(Order::class)->find($claim->getInvoiceCode());
  2360.                     if ( $order ) {
  2361.                         /** @var Document $_document */
  2362.                         foreach ( $order->getDocuments() as $_document ) {
  2363.                             if ( $_document->getGroup()->getType() == DocumentGroup::TYPE_INVOICE_OUT ) {
  2364.                                 $document = $_document;
  2365.                                 break;
  2366.                             }
  2367.                         }
  2368.                     }
  2369.                 }
  2370.                 if ( $document ) {
  2371.                     // Email
  2372.                     if ( $document->getEmail() !== $claim->getEmail() ) {
  2373.                         $this->addFlash('error', $translator->trans('No order was found in the system based on the information provided. Please check the order number/invoice number and email address.'));
  2374.                     }
  2375.                     // Captcha
  2376.                     $captchaResponse = $request->request->get('g-recaptcha-response');
  2377.                     if ( !is_null($captchaResponse) ) {
  2378.                         $captchaResult = $this->verifyGoogleCaptcha($captchaResponse);
  2379.                         if ( $captchaResult ) {
  2380.                             $captchaIsOK = true;
  2381.                         } else {
  2382.                             $captchaIsOK = false;
  2383.                         }
  2384.                     } else {
  2385.                         $captchaIsOK = true;
  2386.                     }
  2387.                     // Check Date
  2388.                     if ( $captchaIsOK ) {
  2389.                         // Created
  2390.                         $invoiceCreated = $document->getCreated();
  2391.                         // Start
  2392.                         $withdrawalStart = clone $invoiceCreated;
  2393.                         for ( $i = 0; $i < 3; $i++ ) {
  2394.                             $withdrawalStart->modify('+1 weekday');
  2395.                         }
  2396.                         // End
  2397.                         $withdrawalEnd = clone $withdrawalStart;
  2398.                         $withdrawalEnd->modify('+14 days');
  2399.                         $withdrawalEnd->setTime(23, 59, 59);
  2400.                         // Today
  2401.                         $today = new \DateTime();
  2402.                         if ( $today <= $withdrawalEnd ) {
  2403.                             // Next Step
  2404.                             $step = 2;
  2405.                             // Fill Claim from document
  2406.                             $claim->setFirstName($document->getFirstName());
  2407.                             $claim->setLastName($document->getLastName());
  2408.                             $claim->setBusinessName($document->getBusinessName());
  2409.                             $claim->setStreet($document->getStreet());
  2410.                             $claim->setCity($document->getCity());
  2411.                             $claim->setZip($document->getZip());
  2412.                             $claim->setBoughtDate($document->getOrder()?->getCreated());
  2413.                             // Phone Number
  2414.                             $phoneNumber = $document->getOrder()?->getBillingPhone();
  2415.                             // Remove non-numeric characters
  2416.                             $_phoneNumber = preg_replace('/[^0-9]/', '', $phoneNumber);
  2417.                             // Add plus sign if was removed
  2418.                             if (substr($phoneNumber, 0, 1) == '+') {
  2419.                                 $_phoneNumber = '+' . $_phoneNumber;
  2420.                             }
  2421.                             // Remove calling codes to prevent duplication
  2422.                             if ($domainLanguageCode == 'cz') {
  2423.                                 $phoneNumber = preg_replace('/^(\+420|00420)/', '', $_phoneNumber);
  2424.                             } elseif ($domainLanguageCode == 'hu') {
  2425.                                 $phoneNumber = preg_replace('/^(\+36|0036|06)/', '', $_phoneNumber);
  2426.                             } else {
  2427.                                 $phoneNumber = preg_replace('/^(\+421|00421|0)/', '', $_phoneNumber);
  2428.                             }
  2429.                             $claim->setPhone($phoneNumber);
  2430.                             // Products
  2431.                             $data['products'] = [];
  2432.                             /** @var DocumentItem $documentItem */
  2433.                             foreach ( $document->getItems() as $documentItem ) {
  2434.                                 if ( $documentItem->getParent() ) {
  2435.                                     continue;
  2436.                                 }
  2437.                                 if ( $documentItem->getStockMovementItem() ) {
  2438.                                     if ( $documentItem->getStockMovementItem()->getItems()->count() > 0 ) {
  2439.                                         /** @var StockItem $stockItem */
  2440.                                         foreach ( $documentItem->getStockMovementItem()->getItems() as $stockItem ) {
  2441.                                             if ( !in_array($documentItem->getProduct()->getType()->getId(), [ ProductType::PRODUCT_TYPE_ID_PC, ProductType::PRODUCT_TYPE_ID_PC_SET, ProductType::PRODUCT_TYPE_ID_ALL_IN_ONE, ProductType::PRODUCT_TYPE_ID_NOTEBOOK, ProductType::PRODUCT_TYPE_ID_MONITOR, ProductType::PRODUCT_TYPE_ID_PRINTER, ProductType::PRODUCT_TYPE_ID_SMARTPHONE ]) ) {
  2442.                                                 continue;
  2443.                                             }
  2444.                                             $data['products'][] = [
  2445.                                                 'id'            => $documentItem->getId(), 
  2446.                                                 'productId'     => $documentItem->getProduct()->getId(), 
  2447.                                                 'stockItemId'   => $stockItem->getId(), 
  2448.                                                 'product'       => $documentItem->getProduct()->getFullTitle(), 
  2449.                                                 'typeId'        => $documentItem->getProduct()->getType()->getId(), 
  2450.                                                 'serialNumber'  => $stockItem->getSerialNumber(), 
  2451.                                                 'quantity'      => 1, 
  2452.                                                 'entity'        => $documentItem->getProduct()
  2453.                                             ];
  2454.                                         }
  2455.                                     } else {
  2456.                                         if ( !in_array($documentItem->getProduct()->getType()->getId(), [ ProductType::PRODUCT_TYPE_ID_PC, ProductType::PRODUCT_TYPE_ID_PC_SET, ProductType::PRODUCT_TYPE_ID_ALL_IN_ONE, ProductType::PRODUCT_TYPE_ID_NOTEBOOK, ProductType::PRODUCT_TYPE_ID_MONITOR, ProductType::PRODUCT_TYPE_ID_PRINTER, ProductType::PRODUCT_TYPE_ID_SMARTPHONE ]) ) {
  2457.                                             continue;
  2458.                                         }
  2459.                                         $data['products'][] = [
  2460.                                             'id'        => $documentItem->getId(), 
  2461.                                             'productId' => $documentItem->getProduct()->getId(), 
  2462.                                             'product'   => $documentItem->getProduct()->getFullTitle(), 
  2463.                                             'typeId'    => $documentItem->getProduct()->getType()->getId(), 
  2464.                                             'code'      => $documentItem->getProduct()->getCode(), 
  2465.                                             'quantity'  => $documentItem->getQuantity(), 
  2466.                                             'entity'    => $documentItem->getProduct()
  2467.                                         ];
  2468.                                     }
  2469.                                 }
  2470.                             }
  2471.                             if ( count($data['products']) == 1 ) {
  2472.                                 $product = $data['products'][0];
  2473.                                 $claim->setProductTitle($product['product']);
  2474.                                 $claim->setSerialNumber($product['serialNumber']);
  2475.                                 switch ( $product['typeId'] ) {
  2476.                                     case ProductType::PRODUCT_TYPE_ID_PC: 
  2477.                                     case ProductType::PRODUCT_TYPE_ID_PC_SET: 
  2478.                                     case ProductType::PRODUCT_TYPE_ID_ALL_IN_ONE: 
  2479.                                         $claim->setProductType(Claim::PRODUCT_TYPE_PC);
  2480.                                     break;
  2481.                                     case ProductType::PRODUCT_TYPE_ID_NOTEBOOK: 
  2482.                                         $claim->setProductType(Claim::PRODUCT_TYPE_NOTEBOOK);
  2483.                                     break;
  2484.                                     case ProductType::PRODUCT_TYPE_ID_MONITOR: 
  2485.                                         $claim->setProductType(Claim::PRODUCT_TYPE_MONITOR);
  2486.                                     break;
  2487.                                     case ProductType::PRODUCT_TYPE_ID_PRINTER: 
  2488.                                         $claim->setProductType(Claim::PRODUCT_TYPE_PRINTER);
  2489.                                     break;
  2490.                                     default:
  2491.                                         $claim->setProductType(Claim::PRODUCT_TYPE_COMPONENT);
  2492.                                 }
  2493.                                 $claim->setProduct($product['entity'] ?? null);
  2494.                             } elseif ( empty($data['products']) ) {
  2495.                                 $step = 1;
  2496.                                 $this->addFlash('error', $translator->trans('Something went wrong during getting debtor status. Please contact customer support'));
  2497.                             }
  2498.                         } else {
  2499.                             $this->addFlash('error', $translator->trans('Unfortunately, but the 30-day return period has expired.'));
  2500.                         }
  2501.                     } else {
  2502.                         $this->addFlash('error', $translator->trans('Captcha check failed, please try again!'));
  2503.                     }
  2504.                 } else {
  2505.                     $this->addFlash('error', $translator->trans('No order was found in the system based on the information provided. Please check the order number/invoice number and email address.'));
  2506.                 }
  2507.             }
  2508.             $data['form'] = $firstStepForm->createView();
  2509.         }
  2510.         // Second Step Form
  2511.         if ( $step == 2 ) {
  2512.             $data['step'] = 2;
  2513.             $secondStepForm = $this->createForm(CustomerWithdrawalType::class, $claim, [
  2514.                 'locale'        => $request->getLocale(), 
  2515.                 'defaultLocale' => $multistore->getDefaultLocale(), 
  2516.                 'domainType'    => $domain->getType(), 
  2517.                 'step'          => 2
  2518.             ]);
  2519.             if ( $request->request->has('customer_withdrawal') && isset($request->request->all()['customer_withdrawal']['bankAccountHolder']) ) {
  2520.                 $secondStepForm->handleRequest($request);
  2521.                 if ( $secondStepForm->isSubmitted() && $secondStepForm->isValid() ) {
  2522.                     // Captcha
  2523.                     $captchaResponse = $request->request->get('g-recaptcha-response');
  2524.                     if ( !is_null($captchaResponse) ) {
  2525.                         $captchaResult = $this->verifyGoogleCaptcha($captchaResponse);
  2526.                         if ( $captchaResult ) {
  2527.                             $captchaIsOK = true;
  2528.                         } else {
  2529.                             $captchaIsOK = false;
  2530.                         }
  2531.                     } else {
  2532.                         $captchaIsOK = true;
  2533.                     }
  2534.                     if ( $captchaIsOK ) {
  2535.                         /** @var Document $document */
  2536.                         $document = $entityManager->getRepository(Document::class)->findOneByCode($claim->getInvoiceCode());
  2537.                         if ( is_null($document) ) {
  2538.                             /** @var Order $order */
  2539.                             $order = $entityManager->getRepository(Order::class)->find($claim->getInvoiceCode());
  2540.                             if ( $order ) {
  2541.                                 /** @var Document $_document */
  2542.                                 foreach ( $order->getDocuments() as $_document ) {
  2543.                                     if ( $_document->getGroup()->getType() == DocumentGroup::TYPE_INVOICE_OUT ) {
  2544.                                         $document = $_document;
  2545.                                         break;
  2546.                                     }
  2547.                                 }
  2548.                             }
  2549.                         }
  2550.                         if ( $document ) {
  2551.                             // Created
  2552.                             $invoiceCreated = $document->getCreated();
  2553.                             // Start
  2554.                             $withdrawalStart = clone $invoiceCreated;
  2555.                             for ( $i = 0; $i < 3; $i++ ) {
  2556.                                 $withdrawalStart->modify('+1 weekday');
  2557.                             }
  2558.                             // End
  2559.                             $withdrawalEnd = clone $withdrawalStart;
  2560.                             $withdrawalEnd->modify('+14 days');
  2561.                             $withdrawalEnd->setTime(23, 59, 59);
  2562.                             // Today
  2563.                             $today = new \DateTime();
  2564.                             // Date
  2565.                             if ( $today > $withdrawalEnd ) {
  2566.                                 $this->addFlash('error', $translator->trans('Unfortunately, but the 30-day return period has expired.'));
  2567.                             }
  2568.                             // Check Email
  2569.                             elseif ( $document->getEmail() !== $claim->getEmail() ) {
  2570.                                 $this->addFlash('error', $translator->trans('No order was found in the system based on the information provided. Please check the order number/invoice number and email address.'));
  2571.                             } 
  2572.                             // Process Claim
  2573.                             else {
  2574.                                 $customer = $document->getOrder()?->getCustomer();
  2575.                                 $claim->setInvoiceCode($document->getCode());
  2576.                                 $claim->setType(Claim::TYPE_WITHDRAWAL);
  2577.                                 $claim->setReceiveType(Claim::RECEIVE_TYPE_SHIPPED_BY_PARCEL);
  2578.                                 $claim->setReturnType(Claim::RETURN_TYPE_PARCEL);
  2579.                                 $claim->setCustomer($customer);
  2580.                                 $claim->setCountry($document->getCountry());
  2581.                                 $claim->setIncomingPacketaBranchId((int)$secondStepForm->getViewData()->getIncomingPacketaBranchId());
  2582.                                 $claim->setIncomingPacketaBranchLabel((string)$secondStepForm->getViewData()->getIncomingPacketaBranchLabel());
  2583.                                 $claim->setDocument($document);
  2584.                                 $claim->setOrder($document->getOrder());
  2585.                                 // Phone Number
  2586.                                 $phoneNumber = $claim->getPhone();
  2587.                                 // Remove non-numeric characters
  2588.                                 $_phoneNumber = preg_replace('/[^0-9]/', '', $phoneNumber);
  2589.                                 // Add plus sign if was removed
  2590.                                 if (substr($phoneNumber, 0, 1) == '+') {
  2591.                                     $_phoneNumber = '+' . $_phoneNumber;
  2592.                                 }
  2593.                                 // Remove calling codes to prevent duplication
  2594.                                 if ($domainLanguageCode == 'cz') {
  2595.                                     $phoneNumber = '+420' . preg_replace('/^(\+420|00420)/', '', $_phoneNumber);
  2596.                                 } elseif ($domainLanguageCode == 'hu') {
  2597.                                     $phoneNumber = '+36' . preg_replace('/^(\+36|0036|06)/', '', $_phoneNumber);
  2598.                                 } else {
  2599.                                     $phoneNumber = '+421' . preg_replace('/^(\+421|00421|0)/', '', $_phoneNumber);
  2600.                                 }
  2601.                                 $claim->setPhone($phoneNumber);
  2602.                                 $claim->setLastStatusId(ClaimStatus::STATUS_TYPE_REGISTERED);
  2603.                                 if ( 
  2604.                                     empty($request->request->get('stockItems')) && 
  2605.                                     empty($request->request->get('products')) && 
  2606.                                     !empty($claim->getProductType()) && 
  2607.                                     !empty($claim->getProductTitle()) 
  2608.                                 ) {
  2609.                                     $claim->setCode($entityManager->getRepository(Claim::class)->createCode($claim));
  2610.                                     // Check claim product title length
  2611.                                     $title = $secondStepForm->getViewData()->getProductTitle();
  2612.                                     if ( mb_strlen($title) > 128 ) {
  2613.                                         $claim->setProductTitle(mb_substr($title, 0, 128));
  2614.                                     }
  2615.                                     // Save
  2616.                                     $entityManager->persist($claim);
  2617.                                     $entityManager->flush();
  2618.                                     // Status
  2619.                                     $claimStatus = new ClaimStatus();
  2620.                                     $claimStatus->setClaim($claim);
  2621.                                     $claimStatus->setStatusType(ClaimStatus::STATUS_TYPE_REGISTERED);
  2622.                                     $entityManager->persist($claimStatus);
  2623.                                     $notificationIds = [785, 3055];
  2624.                                     foreach ( $notificationIds as $notificationId ) {
  2625.                                         $notificationConfig = $entityManager->getRepository(NotificationConfig::class)->findOneById($notificationId);
  2626.                                         if ( $notificationConfig ) {
  2627.                                             $notification = new Notification();
  2628.                                             $notification->setText('New withdrawal #' . $claim->getCode());
  2629.                                             $notification->setNotificationConfig($notificationConfig);
  2630.                                             $notification->setActive(true);
  2631.                                             $notification->setUrl('https://www.atechcomp.eu/centralis/web/claim/edit/' . $claim->getId());
  2632.                                             $entityManager->persist($notification);
  2633.                                         }
  2634.                                     }
  2635.                                     $entityManager->flush();
  2636.                                     $this->addFlash('success', $translator->trans('Your withdrawal has been successfully added. Please print the protocol and send it with the product!'));
  2637.                                     return $this->redirectToRoute('customer_withdrawal_success', [
  2638.                                         'id'            => $claim->getId(), 
  2639.                                         'customerId'    => $customer->getId()
  2640.                                     ]);
  2641.                                 }
  2642.                                 else {
  2643.                                     $products = [];
  2644.                                     if ( !empty($request->request->get('stockItems')) ) {
  2645.                                         foreach ( (array)$request->request->get('stockItems', []) as $stockItemId ) {
  2646.                                             $documentItemId = $request->request->get('stockItemDocument', [])[$stockItemId] ?? 0;
  2647.                                             if ( $documentItemId ) {
  2648.                                                 /** @var DocumentItem $documentItem */
  2649.                                                 foreach ( $document->getItems() as $documentItem ) {
  2650.                                                     if ( $documentItem->getId() == $documentItemId ) {
  2651.                                                         if ( $documentItem->getStockMovementItem() ) {
  2652.                                                             /** @var StockItem $stockItem */
  2653.                                                             foreach ( $documentItem->getStockMovementItem()->getItems() as $stockItem ) {
  2654.                                                                 if ( $stockItem->getId() == $stockItemId ) {
  2655.                                                                     $products[] = [
  2656.                                                                         'serialNumber'  => $stockItem->getSerialNumber(), 
  2657.                                                                         'typeId'        => $documentItem->getProduct()->getType()->getId(), 
  2658.                                                                         'title'         => $documentItem->getProduct()?->getFullTitle(), 
  2659.                                                                         'entity'        => $documentItem->getProduct()
  2660.                                                                     ];
  2661.                                                                     break;
  2662.                                                                 }
  2663.                                                             }
  2664.                                                         }
  2665.                                                     }
  2666.                                                 }
  2667.                                             }
  2668.                                         }
  2669.                                     }
  2670.                                     if ( !empty($request->request->get('products')) ) {
  2671.                                         foreach ( (array)$request->request->get('products', []) as $productId ) {
  2672.                                             $documentItemId = $request->request->get('productDocument', [])[$productId] ?? 0;
  2673.                                             if ( $documentItemId ) {
  2674.                                                 /** @var DocumentItem $documentItem */
  2675.                                                 foreach ( $document->getItems() as $documentItem ) {
  2676.                                                     if ( $documentItem->getId() == $documentItemId && $documentItem->getProduct()?->getId() == $productId ) {
  2677.                                                         $products[] = [
  2678.                                                             'serialNumber'  => '', 
  2679.                                                             'typeId'        => $documentItem->getProduct()->getType()->getId(), 
  2680.                                                             'title'         => $documentItem->getProduct()?->getFullTitle(), 
  2681.                                                             'entity'        => $documentItem->getProduct()
  2682.                                                         ];
  2683.                                                     }
  2684.                                                 }
  2685.                                             }
  2686.                                         }
  2687.                                     }
  2688.                                     if ( empty($products) ) {
  2689.                                         $this->addFlash('error', $translator->trans('No product selected.'));
  2690.                                     } else {
  2691.                                         foreach ( $products as $product ) {
  2692.                                             $_claim = clone $claim;
  2693.                                             $_claim->setProductTitle($product['title']);
  2694.                                             $_claim->setSerialNumber($product['serialNumber']);
  2695.                                             switch ( $product['typeId'] ) {
  2696.                                                 case ProductType::PRODUCT_TYPE_ID_PC: 
  2697.                                                 case ProductType::PRODUCT_TYPE_ID_PC_SET: 
  2698.                                                 case ProductType::PRODUCT_TYPE_ID_ALL_IN_ONE: 
  2699.                                                     $_claim->setProductType(Claim::PRODUCT_TYPE_PC);
  2700.                                                 break;
  2701.                                                 case ProductType::PRODUCT_TYPE_ID_NOTEBOOK: 
  2702.                                                     $_claim->setProductType(Claim::PRODUCT_TYPE_NOTEBOOK);
  2703.                                                 break;
  2704.                                                 case ProductType::PRODUCT_TYPE_ID_MONITOR: 
  2705.                                                     $_claim->setProductType(Claim::PRODUCT_TYPE_MONITOR);
  2706.                                                 break;
  2707.                                                 case ProductType::PRODUCT_TYPE_ID_PRINTER: 
  2708.                                                     $_claim->setProductType(Claim::PRODUCT_TYPE_PRINTER);
  2709.                                                 break;
  2710.                                                 default:
  2711.                                                     $_claim->setProductType(Claim::PRODUCT_TYPE_COMPONENT);
  2712.                                             }
  2713.                                             $_claim->setCode($entityManager->getRepository(Claim::class)->createCode($_claim));
  2714.                                             // Check claim product title length
  2715.                                             $title = $_claim->getProductTitle();
  2716.                                             if ( mb_strlen($title) > 128 ) {
  2717.                                                 $_claim->setProductTitle(mb_substr($title, 0, 128));
  2718.                                             }
  2719.                                             $_claim->setProduct($product['entity'] ?? null);
  2720.                                             // Save
  2721.                                             $entityManager->persist($_claim);
  2722.                                             $entityManager->flush();
  2723.                                             // Status
  2724.                                             $claimStatus = new ClaimStatus();
  2725.                                             $claimStatus->setClaim($_claim);
  2726.                                             $claimStatus->setStatusType(ClaimStatus::STATUS_TYPE_REGISTERED);
  2727.                                             $entityManager->persist($claimStatus);
  2728.                                             $notificationIds = [785, 3055];
  2729.                                             foreach ( $notificationIds as $notificationId ) {
  2730.                                                 $notificationConfig = $entityManager->getRepository(NotificationConfig::class)->findOneById($notificationId);
  2731.                                                 if ( $notificationConfig ) {
  2732.                                                     $notification = new Notification();
  2733.                                                     $notification->setText('New withdrawal #' . $_claim->getCode());
  2734.                                                     $notification->setNotificationConfig($notificationConfig);
  2735.                                                     $notification->setActive(true);
  2736.                                                     $notification->setUrl('https://www.atechcomp.eu/centralis/web/claim/edit/' . $_claim->getId());
  2737.                                                     $entityManager->persist($notification);
  2738.                                                 }
  2739.                                             }
  2740.                                             $entityManager->flush();
  2741.                                         }
  2742.                                         $entityManager->flush();
  2743.                                         $this->addFlash('success', $translator->trans('Your withdrawal has been successfully added. Please print the protocol and send it with the product!'));
  2744.                                         return $this->redirectToRoute('customer_withdrawal_success', [
  2745.                                             'id'            => $_claim->getId() ?? 0, 
  2746.                                             'customerId'    => $customer->getId()
  2747.                                         ]);
  2748.                                     }
  2749.                                 }
  2750.                             }
  2751.                         } else {
  2752.                             $this->addFlash('error', $translator->trans('No order was found in the system based on the information provided. Please check the order number/invoice number and email address.'));
  2753.                         }
  2754.                     } else {
  2755.                         $this->addFlash('error', $translator->trans('Captcha check failed, please try again!'));
  2756.                     }
  2757.                 }
  2758.             }
  2759.             $data['form'] = $secondStepForm->createView();
  2760.         }
  2761.         if ( $domainLanguageCode == 'cz' ) {
  2762.             $data['callingCountryCode'] = '+420';
  2763.         } elseif ( $domainLanguageCode == 'hu' ) {
  2764.             $data['callingCountryCode'] = '+36';
  2765.         } else {
  2766.             $data['callingCountryCode'] = '+421';
  2767.         }
  2768.         // Carrier
  2769.         $carrierExpressShippingType = $entityManager->getRepository(DomainShippingType::class)->findOneBy([
  2770.             'domain'        => $domain->getId(), 
  2771.             'activeOnWeb'   => true, 
  2772.             'type'          => DomainShippingType::SHIPPING_TYPE_CARRIER_EXPRESS_ID
  2773.         ]);
  2774.         if ( $carrierExpressShippingType ) {
  2775.             $data['deliveryPrice'] = $carrierExpressShippingType->getPrice() . ' ' . $domain->getCurrency();
  2776.         } else {
  2777.             $data['deliveryPrice'] = '0 ' . $domain->getCurrency();
  2778.         }
  2779.         $data['precision'] = $domain->getPricePrecision();
  2780.         $data['currency'] = $domain->getCurrency();
  2781.         $data['domainLanguageCode'] = $domainLanguageCode;
  2782.         // Common
  2783.         $data['header'] = $this->getHeader($request);
  2784.         $data['footer'] = $this->getFooter($request);
  2785.         $data['commissionCount'] = $this->getCommissionsCount($request);
  2786.         $data['contentBottom'] = $this->getContentBottom($request);
  2787.         return $this->render('AtechNetCoreBundle/Customer/withdrawalNew.html.twig', $data);
  2788.     }
  2789.     /**
  2790.      * @Route("/ajax-check-order-number", name="ajax_check_order_number", defaults={"_locale":""})
  2791.      * @Route("/{_locale<%supported_locales%>?}/ajax-check-order-number", name="ajax_check_order_number_locale", defaults={"_locale":""})
  2792.      * @param Request $request
  2793.      * @return JsonResponse|null
  2794.      */
  2795.     public function ajaxCheckOrderNumber(Request $request): ?JsonResponse
  2796.     {
  2797.         $orderId = $request->request->get('orderNumber');
  2798.         /**
  2799.          * @var $order Order
  2800.          */
  2801.         $order = $this->getEntityManager()->getRepository(Order::class)->findOneById($orderId);
  2802.         if (is_null($order)) {
  2803.             return new JsonResponse([
  2804.                 'success' => false,
  2805.                 'message' => $this->getTranslator()->trans('order_number_alert.order_not_found'),
  2806.             ]);
  2807.         } elseif ($order->getWarrantyEnd() < new \DateTime()) {
  2808.             return new JsonResponse([
  2809.                 'success' => false,
  2810.                 'message' => $this->getTranslator()->trans('order_number_alert.warranty_is_ended'),
  2811.             ]);
  2812.         }
  2813.         return new JsonResponse([
  2814.             'success' => true,
  2815.         ]);
  2816.     }
  2817.     /**
  2818.      * @Route("/account/withdrawal/success/{id}/{customerId}", name="customer_withdrawal_success", defaults={"_locale":""})
  2819.      * @Route("/{_locale<%supported_locales%>?}/account/withdrawal/success/{id}/{customerId}", name="customer_withdrawal_success_locale", defaults={"_locale":""})
  2820.      * @param Request $request
  2821.      * @param int $id
  2822.      * @param int $customerId
  2823.      * @return Response
  2824.      * @throws InvalidArgumentException
  2825.      */
  2826.     public function withdrawalSuccessAction(Request $request, int $id, int $customerId): Response
  2827.     {
  2828.         $data = [];
  2829.         $translator = $this->getTranslator();
  2830.         if ($this->getLoginHelper($request)->isLoggedIn()) {
  2831.             $data['isLoggedIn'] = true;
  2832.         } else {
  2833.             $data['isLoggedIn'] = false;
  2834.         }
  2835.         $data['heading_title'] = $translator->trans('Withdrawal created');
  2836.         $data['breadcrumbs'] = [];
  2837.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  2838.         $data['breadcrumbs'][] = [
  2839.             'text' => $translator->trans('Account'),
  2840.             'href' => $this->generateUrl('customer_account'),
  2841.         ];
  2842.         $data['breadcrumbs'][] = [
  2843.             'text' => $translator->trans('Withdrawal created'),
  2844.             'href' => $this->generateUrl('customer_withdrawal_success', [
  2845.                 'id' => $id,
  2846.                 'customerId' => $customerId,
  2847.             ]),
  2848.         ];
  2849.         $entityManager = $this->getEntityManager();
  2850.         $customer = $entityManager->getRepository(Customer::class)->findOneById($customerId);
  2851.         $withdrawal = $entityManager->getRepository(Claim::class)->findOneBy([
  2852.             'id' => $id,
  2853.             'customer' => $customer,
  2854.         ]);
  2855.         $data['withdrawalId'] = $withdrawal->getCode();
  2856.         $data['withdrawalPdfUrl'] = $this->generateUrl('customer_withdrawal_pdf', [
  2857.             'id' => $id,
  2858.             'customerId' => $customerId,
  2859.         ]);
  2860.         $data['commissionCount'] = $this->getCommissionsCount($request);
  2861.         $data['header'] = $this->getHeader($request);
  2862.         $data['footer'] = $this->getFooter($request);
  2863.         $data['contentBottom'] = $this->getContentBottom($request);
  2864.         return $this->render('AtechNetCoreBundle/Customer/withdrawalSuccess.html.twig', $data);
  2865.     }
  2866.     /**
  2867.      * @Route("/account/withdrawal/{id}/pdf/{customerId}", name="customer_withdrawal_pdf", defaults={"_locale":""})
  2868.      * @Route("/{_locale<%supported_locales%>?}/account/withdrawal/{id}/pdf/{customerId}", name="customer_withdrawal_pdf_locale", defaults={"_locale":""})
  2869.      * @param Request $request
  2870.      * @param int $id
  2871.      * @param int|null $customerId
  2872.      * @return Response
  2873.      * @throws MpdfException
  2874.      */
  2875.     public function withdrawalPdfAction(Request $request, int $id, int $customerId = null): Response
  2876.     {
  2877.         $entityManager = $this->getEntityManager();
  2878.         if (!is_null($customerId)) {
  2879.             $customer = $entityManager->getRepository(Customer::class)->findOneById($customerId);
  2880.         } else {
  2881.             $customer = $this->getLoginHelper($request)->getLoggedInCustomer();
  2882.         }
  2883.         if (!$customer) {
  2884.             return $this->redirectToRoute('customer_login');
  2885.         }
  2886.         $withdrawal = $entityManager->getRepository(Claim::class)->findOneBy([
  2887.             'id' => $id,
  2888.             'customer' => $customer,
  2889.         ]);
  2890.         if (!$withdrawal) {
  2891.             return $this->redirectToRoute('not_found');
  2892.         }
  2893.         $data = [];
  2894.         /**
  2895.          * @var Claim $withdrawal
  2896.          */
  2897.         $data['withdrawal'] = $withdrawal;
  2898.         $data['customerAddress'] = $withdrawal->getCustomer()->getAddresses()->first();
  2899.         $data['statusChoices'] = ClaimStatus::getStatusChoices();
  2900.         $data['withdrawalReasonChoices'] = Claim::getWithdrawalReasonChoices();
  2901.         $html = $this->render('AtechNetCoreBundle/PDF/withdrawal.html.twig', $data);
  2902.         $pdf = new Mpdf([
  2903.             'mode' => '',
  2904.             'format' => 'A4',
  2905.             'default_font_size' => 9,
  2906.             'defualt_font' => 'dejavusans',
  2907.             'mgl' => 10,
  2908.             'mgr' => 10,
  2909.         ]);
  2910.         $pdf->shrink_tables_to_fit = false;
  2911.         $pdf->WriteHTML($html);
  2912.         return new Response(
  2913.             $pdf->output(
  2914.                 $this->getTranslator()->trans('Withdrawal') . '_furbify_' . $request->getLocale() . '_' . $withdrawal->getCode() . '.pdf',
  2915.                 'I'
  2916.             ),
  2917.             Response::HTTP_OK,
  2918.             [
  2919.                 'content-type' => 'application/pdf',
  2920.             ]
  2921.         );
  2922.     }
  2923.     /**
  2924.      * @Route("/account/claim/{claimId}", name="customer_claim_show", defaults={"_locale":""})
  2925.      * @Route("/{_locale<%supported_locales%>?}/account/claim/{claimId}", name="customer_claim_show_locale", defaults={"_locale":""})
  2926.      * @param Request $request
  2927.      * @param int $claimId
  2928.      * @return Response
  2929.      * @throws InvalidArgumentException
  2930.      */
  2931.     public function showClaimAction(Request $request, int $claimId): Response
  2932.     {
  2933.         if (!$this->getLoginHelper($request)->isLoggedIn()) {
  2934.             return $this->redirectToRoute('customer_login');
  2935.         }
  2936.         $translator = $this->getTranslator();
  2937.         $multiStore = $this->getMultiStoreHelper($request);
  2938.         $customer = $this->getLoginHelper($request)->getLoggedInCustomer();
  2939.         $data = [];
  2940.         $data['breadcrumbs'] = [];
  2941.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  2942.         $data['breadcrumbs'][] = [
  2943.             'text' => $translator->trans('Account'),
  2944.             'href' => $this->generateUrl('customer_account'),
  2945.         ];
  2946.         $data['breadcrumbs'][] = [
  2947.             'text' => $translator->trans('Claims'),
  2948.             'href' => $this->generateUrl('customer_claims'),
  2949.         ];
  2950.         $domain = $multiStore->getDomain();
  2951.         $data['languageCode'] = $domain->getLanguage()->getCode();
  2952.         $data['currency'] = $domain->getCurrency();
  2953.         $data['precision'] = $domain->getPricePrecision();
  2954.         $claim = $this->getEntityManager()->getRepository(Claim::class)->findOneBy([
  2955.             'id' => $claimId,
  2956.             'customer' => $customer->getId(),
  2957.         ]);
  2958.         if ($claim) {
  2959.             $data['heading_title'] = $translator->trans('Claim') . ': ' . $claim->getCode();
  2960.             $data['breadcrumbs'][] = [
  2961.                 'text' => $translator->trans('Claim') . ': ' . $claim->getCode(),
  2962.                 'href' => $this->generateUrl('customer_claim_show', [
  2963.                     'claimId' => $claimId,
  2964.                 ]),
  2965.             ];
  2966.             // Claim Details
  2967.             $data['claimCode'] = $claim->getCode();
  2968.             $data['dateAdded'] = $claim->getCreated()->format($translator->trans('datetime.format'));
  2969.             $data['returnType'] = $claim->getReturnType();
  2970.             $data['receiveType'] = $claim->getReceiveType();
  2971.             // Customer Details
  2972.             $data['firstName'] = $claim->getFirstName();
  2973.             $data['lastName'] = $claim->getLastName();
  2974.             $data['address'] = $claim->getStreet();
  2975.             $data['city'] = $claim->getCity();
  2976.             $data['postalCode'] = $claim->getZip();
  2977.             $data['telephone'] = $claim->getPhone();
  2978.             $data['email'] = $claim->getEmail();
  2979.             // Order & Product Details
  2980.             if (!is_null($claim->getBoughtDate())) {
  2981.                 $data['boughtDate'] = $claim->getBoughtDate()->format($translator->trans('datetime.format'));
  2982.             } else {
  2983.                 $data['boughtDate'] = '-';
  2984.             }
  2985.             $data['invoiceCode'] = $claim->getInvoiceCode();
  2986.             $data['productType'] = $claim->getProductType();
  2987.             $data['productTitle'] = $claim->getProductTitle();
  2988.             $data['serialNumber'] = $claim->getSerialNumber();
  2989.             $data['cable'] = $claim->isCable();
  2990.             $data['customerNote'] = $claim->getCustomerNote();
  2991.             // Claim Status
  2992.             $data['technicianNote'] = $claim->getTechnicNote();
  2993.             $data['solution'] = $claim->getSolution();
  2994.             $lastStatus = $claim->getLastStatus();
  2995.             if ($lastStatus) {
  2996.                 if ($lastStatus->getStatusType() >= ClaimStatus::STATUS_TYPE_WAITING_FOR_SALES
  2997.                     && $lastStatus->getStatusType() <= ClaimStatus::STATUS_TYPE_WAITING_FOR_REFUND) {
  2998.                     $data['status'] = 'Waiting';
  2999.                 }
  3000.                 else {
  3001.                     $data['status'] = ClaimStatus::getStatusChoices()[$lastStatus->getStatusType()];
  3002.                 }
  3003.             } else {
  3004.                 $data['status'] = '';
  3005.             }
  3006.             $data['updated'] = '-';
  3007.             if (!is_null($claim->getUpdated()) && $claim->getCreated() != $claim->getUpdated()) {
  3008.                 $data['updated'] = $claim->getUpdated()->format($translator->trans('datetime.format'));
  3009.             }
  3010.             $data['hasTest'] = $claim->hasTest();
  3011.             $data['returnTypeChoices'] = Claim::getReturnTypeChoices();
  3012.             $data['receiveTypeChoices'] = Claim::getReceiveTypeChoices();
  3013.             $data['productTypeChoices'] = Claim::getProductTypeChoices();
  3014.             $data['solutionChoices'] = Claim::getSolutionChoices();
  3015.             $data['commissionCount'] = $this->getCommissionsCount($request);
  3016.             $data['header'] = $this->getHeader($request);
  3017.             $data['footer'] = $this->getFooter($request);
  3018.             $data['contentBottom'] = $this->getContentBottom($request);
  3019.             return $this->render('AtechNetCoreBundle/Customer/showClaim.html.twig', $data);
  3020.         }
  3021.         return $this->forward('App\AtechNet\CoreBundle\Controller\DefaultController::notFoundAction', []);
  3022.     }
  3023.     /**
  3024.      * @Route("/claim/tracking/{token}", name="customer_claim_tracking", defaults={"_locale":""})
  3025.      * @Route("/{_locale<%supported_locales%>?}/claim/tracking/{token}", name="customer_claim_tracking_locale", defaults={"_locale":""})
  3026.      * @param Request $request
  3027.      * @param string $token
  3028.      * @return Response
  3029.      * @throws InvalidArgumentException
  3030.      */
  3031.     public function claimTrackingAction(Request $request, string $token): Response
  3032.     {
  3033.         $claim = $this->getEntityManager()->getRepository(Claim::class)->findOneById(
  3034.             $this->getEntityManager()->getRepository(Claim::class)->getClaimIdFromToken($token)
  3035.         );
  3036.         if ($claim) {
  3037.             if ($this->getEntityManager()->getRepository(Claim::class)->validateClaimToken($claim, $token)) {
  3038.                 $translator = $this->getTranslator();
  3039.                 $multiStore = $this->getMultiStoreHelper($request);
  3040.                 $data = [];
  3041.                 $data['breadcrumbs'] = [];
  3042.                 $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  3043.                 $data['breadcrumbs'][] = [
  3044.                     'text' => $translator->trans('Account'),
  3045.                     'href' => $this->generateUrl('customer_account'),
  3046.                 ];
  3047.                 $data['breadcrumbs'][] = [
  3048.                     'text' => $translator->trans('Guest'),
  3049.                     'href' => $this->generateUrl('customer_account'),
  3050.                 ];
  3051.                 $domain = $multiStore->getDomain();
  3052.                 $data['languageCode'] = $domain->getLanguage()->getCode();
  3053.                 $data['heading_title'] = $translator->trans('Claim') . ': ' . $claim->getCode();
  3054.                 $data['breadcrumbs'][] = [
  3055.                     'text' => $translator->trans('Claim') . ': ' . $claim->getCode(),
  3056.                     'href' => $this->generateUrl('customer_claim_tracking', [
  3057.                         'token' => $token,
  3058.                     ]),
  3059.                 ];
  3060.                 // Claim Details
  3061.                 $data['claimCode'] = $claim->getCode();
  3062.                 $data['dateAdded'] = $claim->getCreated()->format($translator->trans('datetime.format'));
  3063.                 $data['returnType'] = $claim->getReturnType();
  3064.                 $data['receiveType'] = $claim->getReceiveType();
  3065.                 // Customer Details
  3066.                 $data['firstName'] = $claim->getFirstName();
  3067.                 $data['lastName'] = $claim->getLastName();
  3068.                 $data['address'] = $claim->getStreet();
  3069.                 $data['city'] = $claim->getCity();
  3070.                 $data['postalCode'] = $claim->getZip();
  3071.                 $data['telephone'] = $claim->getPhone();
  3072.                 $data['email'] = $claim->getEmail();
  3073.                 // Order & Product Details
  3074.                 if (!is_null($claim->getBoughtDate())) {
  3075.                     $data['boughtDate'] = $claim->getBoughtDate()->format($translator->trans('datetime.format'));
  3076.                 } else {
  3077.                     $data['boughtDate'] = '-';
  3078.                 }
  3079.                 $data['invoiceCode'] = $claim->getInvoiceCode();
  3080.                 $data['productType'] = $claim->getProductType();
  3081.                 $data['productTitle'] = $claim->getProductTitle();
  3082.                 $data['serialNumber'] = $claim->getSerialNumber();
  3083.                 $data['cable'] = $claim->isCable();
  3084.                 $data['customerNote'] = $claim->getCustomerNote();
  3085.                 // Claim Status
  3086.                 $data['technicianNote'] = $claim->getTechnicNote();
  3087.                 $data['solution'] = $claim->getSolution();
  3088.                 $lastStatus = $claim->getLastStatus();
  3089.                 if ($lastStatus) {
  3090.                     if ($lastStatus->getStatusType() >= ClaimStatus::STATUS_TYPE_WAITING_FOR_SALES
  3091.                         && $lastStatus->getStatusType() <= ClaimStatus::STATUS_TYPE_WAITING_FOR_REFUND) {
  3092.                         $data['status'] = 'Waiting';
  3093.                     }
  3094.                     else {
  3095.                         $data['status'] = ClaimStatus::getStatusChoices()[$lastStatus->getStatusType()];
  3096.                     }
  3097.                 } else {
  3098.                     $data['status'] = '';
  3099.                 }
  3100.                 $data['updated'] = '-';
  3101.                 if (!is_null($claim->getUpdated()) && $claim->getCreated() != $claim->getUpdated()) {
  3102.                     $data['updated'] = $claim->getUpdated()->format($translator->trans('datetime.format'));
  3103.                 }
  3104.                 $data['hasTest'] = $claim->hasTest();
  3105.                 $data['tests'] = $claim->getTests();
  3106.                 $data['returnTypeChoices'] = Claim::getReturnTypeChoices();
  3107.                 $data['receiveTypeChoices'] = Claim::getReceiveTypeChoices();
  3108.                 $data['productTypeChoices'] = Claim::getProductTypeChoices();
  3109.                 $data['solutionChoices'] = Claim::getSolutionChoices();
  3110.                 $data['testTypes'] = ClaimTest::getTestTypes();
  3111.                 $data['testStates'] = ClaimTest::getTestStates();
  3112.                 $data['commissionCount'] = $this->getCommissionsCount($request);
  3113.                 $data['header'] = $this->getHeader($request);
  3114.                 $data['footer'] = $this->getFooter($request);
  3115.                 $data['contentBottom'] = $this->getContentBottom($request);
  3116.                 $data['guest'] = true;
  3117.                 return $this->render('AtechNetCoreBundle/Customer/showClaim.html.twig', $data);
  3118.             }
  3119.         }
  3120.         return $this->forward('App\AtechNet\CoreBundle\Controller\DefaultController::notFoundAction', []);
  3121.     }
  3122.     /**
  3123.      * @Route("/account/commissions", name="customer_commissions", defaults={"_locale":""})
  3124.      * @Route("/{_locale<%supported_locales%>?}/account/commissions", name="customer_commissions_locale", defaults={"_locale":""})
  3125.      * @param Request $request
  3126.      * @return RedirectResponse|Response
  3127.      * @throws \Exception
  3128.      */
  3129.     public function commissionsAction(Request $request)
  3130.     {
  3131.         if (!$this->getLoginHelper($request)->isLoggedIn()) {
  3132.             return $this->redirectToRoute('customer_login');
  3133.         }
  3134.         if ($request->getSession()->get('customerTypeId') != MultiStore::CUSTOMER_TYPE_WHOLESALE) {
  3135.             return $this->redirectToRoute('homepage');
  3136.         }
  3137.         $customer = $this->getLoginHelper($request)->getLoggedInCustomer();
  3138.         $translator = $this->getTranslator();
  3139.         $entityManager = $this->getEntityManager();
  3140.         $filterStatus = ProductCommission::Status_AtPartner;
  3141.         if (!is_null($request->get('filter-status')) && is_numeric($request->get('filter-status'))) {
  3142.             $filterStatus = $request->get('filter-status');
  3143.         }
  3144.         if (!is_null($request->request->get('commission-status-change'))
  3145.             && is_numeric($request->request->get('commission-status-change'))
  3146.             && $request->request->get('commission-status-change') != ProductCommission::Status_Returned
  3147.             && !is_null($request->request->get('commission-status-change-id'))
  3148.             && is_numeric($request->request->get('commission-status-change-id'))) {
  3149.             $commissionId = $request->request->get('commission-status-change-id');
  3150.             $commission = $entityManager->getRepository(ProductCommission::class)->findOneBy([
  3151.                 'id' => $commissionId,
  3152.                 'customer' => $customer,
  3153.             ]);
  3154.             if ($commission) {
  3155.                 $commission->setStatus($request->request->get('commission-status-change'));
  3156.                 $this->getEntityManager()->flush();
  3157.                 if ($commission->getChildren()->count() > 0) {
  3158.                     foreach ($commission->getChildren() as $child) {
  3159.                         $child->setStatus($request->request->get('commission-status-change'));
  3160.                         $this->getEntityManager()->flush();
  3161.                     }
  3162.                 }
  3163.                 $this->addFlash(
  3164.                     'success',
  3165.                     $this->getTranslator()->trans('Your commission staus was successfully changed!')
  3166.                 );
  3167.                 $mailer = $this->getMailer();
  3168.                 $subject = 'Commission status change for ' . $customer->getFirstName() . ' ' . $customer->getLastName() . ' (' . $customer->getBusinessName() . ') ID: ' . $commission->getId();
  3169.                 $email = (new TemplatedEmail())
  3170.                     ->subject($subject)
  3171.                     ->to('webshop@furbify.eu')
  3172.                     ->addTo($customer->getSalesManager()->getEmail())
  3173.                     ->replyTo($this->getParameter('mailer_reply_to'))
  3174.                     ->html('New commission set to ' . ProductCommission::getStatusChoices()[$commission->getStatus()] . ': <a href="https://www.atechcomp.eu/centralis/web/product/commission/edit/' . $commission->getId() . '">LINK</a>');
  3175.                 $mailer->send($email);
  3176.             }
  3177.         }
  3178.         $data = [];
  3179.         $data['heading_title'] = $translator->trans('Commissions');
  3180.         $data['breadcrumbs'] = [];
  3181.         $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  3182.         $data['breadcrumbs'][] = [
  3183.             'text' => $translator->trans('Account'),
  3184.             'href' => $this->generateUrl('customer_account'),
  3185.         ];
  3186.         $data['breadcrumbs'][] = [
  3187.             'text' => $translator->trans('Commissions'),
  3188.             'href' => $this->generateUrl('customer_commissions'),
  3189.         ];
  3190.         $commissionCounts = $this->getEntityManager()
  3191.             ->createQuery("SELECT pc.status, COUNT(pc.id) AS statusCount
  3192.                 FROM AtechNetCoreBundle:ProductCommission pc
  3193.                 WHERE pc.customer = :customer AND pc.parent IS NULL
  3194.                 GROUP BY pc.status")
  3195.             ->setParameters([
  3196.                 'customer' => $customer,
  3197.             ])
  3198.             ->getResult();
  3199.         $data['statusCounts'] = [];
  3200.         foreach ($commissionCounts as $commissionCount) {
  3201.             $data['statusCounts'][$commissionCount['status']] = $commissionCount['statusCount'];
  3202.         }
  3203.         $commissions = $entityManager->getRepository(ProductCommission::class)->findBy(
  3204.             [
  3205.                 'customer' => $customer,
  3206.                 'status' => $filterStatus,
  3207.                 'parent' => null,
  3208.             ],
  3209.             [
  3210.                 'created' => 'DESC',
  3211.             ]
  3212.         );
  3213.         $data['commissionCount'] = $this->getCommissionsCount($request);
  3214.         $data['commissions'] = [];
  3215.         $dbTranslator = $this->getDatabaseTranslator($request);
  3216.         /**
  3217.          * @var ProductCommission $commission
  3218.          */
  3219.         foreach ($commissions as $commission) {
  3220.             $productTypeTitle = $commission->getProduct()->getType()->getTitle($dbTranslator);
  3221.             if (!isset($data['commissions'][$productTypeTitle])) {
  3222.                 $data['commissions'][$productTypeTitle] = [];
  3223.             }
  3224.             // Product
  3225.             $product = $commission->getProduct();
  3226.             // Price
  3227.             $price = 0;
  3228.             // Stock Movement Price
  3229.             if ($commission->getStockMovement()) {
  3230.                 foreach ($commission->getStockMovement()->getMovementItems() as $stockMovementItem) {
  3231.                     if ($stockMovementItem->getProduct()->getId() == $product->getId()) {
  3232.                         // Scannable Product
  3233.                         if ($stockMovementItem->getItems()) {
  3234.                             foreach ($stockMovementItem->getItems() as $stockItem) {
  3235.                                 if ($commission->getSerialNumber() == $stockItem->getSerialNumber()) {
  3236.                                     $price = $stockMovementItem->getVatPricePerItem();
  3237.                                     break 2;
  3238.                                 }
  3239.                             }
  3240.                         } // Non-scannable Product
  3241.                         else {
  3242.                             $price = $stockMovementItem->getVatPricePerItem();
  3243.                             break;
  3244.                         }
  3245.                     }
  3246.                 }
  3247.             }
  3248.             // Product Container Children have Neutral Stock Movement
  3249.             $neutralStockMovement = false;
  3250.             // Children Price
  3251.             $childrenPrice = 0;
  3252.             // Children
  3253.             $children = [];
  3254.             if ($commission->getChildren()->count() > 0) {
  3255.                 foreach ($commission->getChildren() as $child) {
  3256.                     // Product
  3257.                     $productChild = $child->getProduct();
  3258.                     // Price
  3259.                     $priceChild = 0;
  3260.                     if ($child->getStockMovement()) {
  3261.                         foreach ($child->getStockMovement()->getMovementItems() as $mic) {
  3262.                             if ($mic->getProduct()->getId() == $productChild->getId()) {
  3263.                                 $priceChild = $mic->getVatPricePerItem();
  3264.                             }
  3265.                         }
  3266.                         if ($child->getStockMovement()->getType() == StockMovement::TYPE_NEUTRAL) {
  3267.                             $neutralStockMovement = true;
  3268.                         }
  3269.                     }
  3270.                     // Child
  3271.                     $children[] = [
  3272.                         'id' => $child->getId(),
  3273.                         'productId' => $productChild->getId(),
  3274.                         'productCode' => $productChild->getCode(),
  3275.                         'productTitle' => $productChild->getFullTitle($dbTranslator),
  3276.                         'productDescription' => $productChild->getDescription(),
  3277.                         'price' => $priceChild . ' ' . $child->getCustomer()->getDomain()->getCurrency(),
  3278.                         'serialNumber' => $child->getSerialNumber(),
  3279.                         'statusId' => $child->getStatus(),
  3280.                         'created' => $child->getCreated(),
  3281.                         'updated' => $child->getUpdated(),
  3282.                     ];
  3283.                     $childrenPrice += $priceChild;
  3284.                 }
  3285.             }
  3286.             if ($childrenPrice > 0 && $price <= 0) {
  3287.                 $price = $childrenPrice;
  3288.             }
  3289.             //-> Order Item
  3290.             $orderItem = null;
  3291.             // Determine Order Item only for parent Product Containers and Product Containers with neutral Stock Movement
  3292.             if (is_null($commission->getParent()) && ((!is_null($commission->getStockMovement()) && $commission->getStockMovement()->getType() == StockMovement::TYPE_NEUTRAL) || ($commission->isContainer() && $neutralStockMovement))) {
  3293.                 // Determine Order Item of Product Container
  3294.                 if (!is_null($commission->getChildren()) && $commission->getChildren()->count() > 0) {
  3295.                     foreach ($commission->getChildren() as $child) {
  3296.                         // Child Product
  3297.                         $childProduct = $child->getProduct();
  3298.                         if ($child->getStockMovement()) {
  3299.                             foreach ($child->getStockMovement()->getMovementItems() as $childStockMovementItem) {
  3300.                                 if ($childStockMovementItem->getProduct()->getId() == $childProduct->getId()) {
  3301.                                     // Scannable Product
  3302.                                     if ($childStockMovementItem->getItems()) {
  3303.                                         foreach ($childStockMovementItem->getItems() as $childStockItem) {
  3304.                                             if ($child->getSerialNumber() == $childStockItem->getSerialNumber()) {
  3305.                                                 $childOrderItem = $childStockMovementItem->getOrderItem();
  3306.                                                 if ($childOrderItem) {
  3307.                                                     $orderItem = $childOrderItem->getParent();
  3308.                                                     break 3;
  3309.                                                 }
  3310.                                             }
  3311.                                         }
  3312.                                     } // Non-scannable Product
  3313.                                     else {
  3314.                                         $childOrderItem = $childStockMovementItem->getOrderItem();
  3315.                                         if ($childOrderItem) {
  3316.                                             $orderItem = $childOrderItem->getParent();
  3317.                                             break 2;
  3318.                                         }
  3319.                                     }
  3320.                                 }
  3321.                             }
  3322.                         }
  3323.                     }
  3324.                 } // Determine Order Item of single Product
  3325.                 elseif ($commission->getStockMovement()) {
  3326.                     foreach ($commission->getStockMovement()->getMovementItems() as $stockMovementItem) {
  3327.                         if ($stockMovementItem->getProduct()->getId() == $product->getId()) {
  3328.                             // Scannable Product
  3329.                             if ($stockMovementItem->getItems()) {
  3330.                                 foreach ($stockMovementItem->getItems() as $stockItem) {
  3331.                                     if ($commission->getSerialNumber() == $stockItem->getSerialNumber()) {
  3332.                                         $orderItem = $stockMovementItem->getOrderItem();
  3333.                                         break 2;
  3334.                                     }
  3335.                                 }
  3336.                             } // Non-scannable Product
  3337.                             else {
  3338.                                 $orderItem = $stockMovementItem->getOrderItem();
  3339.                                 break;
  3340.                             }
  3341.                         }
  3342.                     }
  3343.                 }
  3344.             }
  3345.             //<- Order Item
  3346.             // Container Accessories Price
  3347.             $accessoriesPrice = 0;
  3348.             // Container Accessories
  3349.             $containerAccessories = [];
  3350.             foreach ($commission->getAccessories() as $commissionAccessory) {
  3351.                 // Accessory Price
  3352.                 $accessoryPrice = 0;
  3353.                 // Determine Stock Movement Item based on Order Item
  3354.                 $stockMovementItem = null;
  3355.                 if (!is_null($orderItem) && $orderItem->getItemAttributes()) {
  3356.                     foreach ($orderItem->getItemAttributes() as $orderItemAttribute) {
  3357.                         $attributeOption = $orderItemAttribute->getAttributeOption();
  3358.                         if ($attributeOption) {
  3359.                             $attributeOptionProduct = $attributeOption->getProduct();
  3360.                             if ($attributeOptionProduct) {
  3361.                                 if ($commissionAccessory->getProduct()->getId() == $attributeOptionProduct->getId()) {
  3362.                                     $stockMovementItem = $orderItemAttribute->getStockMovementItem();
  3363.                                     break;
  3364.                                 }
  3365.                             }
  3366.                         }
  3367.                     }
  3368.                 }
  3369.                 if (!is_null($stockMovementItem)) {
  3370.                     $accessoryPrice = $stockMovementItem->getVatPricePerItem();
  3371.                 } else {
  3372.                     $stockMovement = $commissionAccessory->getStockMovement();
  3373.                     if ($stockMovement) {
  3374.                         foreach ($stockMovement->getMovementItems() as $stockMovementItem) {
  3375.                             if ($stockMovementItem->getProduct()->getId() == $commissionAccessory->getProduct()->getId()) {
  3376.                                 $accessoryPrice = $stockMovementItem->getVatPricePerItem();
  3377.                                 break;
  3378.                             }
  3379.                         }
  3380.                     }
  3381.                 }
  3382.                 $containerAccessories[] = [
  3383.                     'title' => $commissionAccessory->getProduct()->getFullTitle(),
  3384.                     'price' => $accessoryPrice . ' ' . $commission->getCustomer()->getDomain()->getCurrency(),
  3385.                 ];
  3386.                 $accessoriesPrice += $accessoryPrice;
  3387.             }
  3388.             if ($accessoriesPrice > 0) {
  3389.                 $price += $accessoriesPrice;
  3390.             }
  3391.             $data['commissions'][$productTypeTitle][] = [
  3392.                 'id' => $commission->getId(),
  3393.                 'productId' => $product->getId(),
  3394.                 'productCode' => $product->getCode(),
  3395.                 'productTitle' => $product->getFullTitle($dbTranslator),
  3396.                 'productDescription' => $product->getDescription(),
  3397.                 'price' => $price . ' ' . $commission->getCustomer()->getDomain()->getCurrency(),
  3398.                 'serialNumber' => $commission->getSerialNumber(),
  3399.                 'statusId' => $commission->getStatus(),
  3400.                 'created' => $commission->getCreated(),
  3401.                 'updated' => $commission->getUpdated(),
  3402.                 'children' => $children,
  3403.                 'accessories' => $containerAccessories,
  3404.             ];
  3405.         }
  3406.         $data['statuses'] = ProductCommission::getStatusChoices();
  3407.         $data['filterStatus'] = $filterStatus;
  3408.         $data['header'] = $this->getHeader($request);
  3409.         $data['footer'] = $this->getFooter($request);
  3410.         $data['contentBottom'] = $this->getContentBottom($request);
  3411.         $data['userWithZeroVat'] = $customer && $customer->useZeroVat($customer->getVatId());
  3412.         return $this->render('AtechNetCoreBundle/Customer/commission.html.twig', $data);
  3413.     }
  3414.     /**
  3415.      * @Route("/order/payment-check/{orderId}/{paymentId}", name="customer_payment_check", defaults={"_locale":""})
  3416.      * @Route("/{_locale<%supported_locales%>?}/order/payment-check/{orderId}/{paymentId}", name="customer_payment_check_locale", defaults={"_locale":""})
  3417.      * @param Request $request
  3418.      * @param $orderId
  3419.      * @param $paymentId
  3420.      * @return mixed
  3421.      * @throws \Exception
  3422.      */
  3423.     public function orderPaymentStatusAction(Request $request, $orderId, $paymentId)
  3424.     {
  3425.         $entityManager = $this->getEntityManager();
  3426.         $translator = $this->getTranslator();
  3427.         $order = $entityManager->getRepository(Order::class)->findOneBy([
  3428.             'id' => $orderId,
  3429.             'customer' => $this->getLoginHelper($request)->getLoggedInCustomer(),
  3430.         ]);
  3431.         if ($order) {
  3432.             $gopayHelper = $this->getGopayHelper($request);
  3433.             $data['payment_status'] = $gopayHelper->checkPaymentStatus($paymentId);
  3434.             $data['heading_title'] = $translator->trans('Check payment') . ' - ' . $translator->trans('Order') . ' #' . $orderId;
  3435.             $data['breadcrumbs'] = [];
  3436.             $data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
  3437.             $data['breadcrumbs'][] = [
  3438.                 'text' => $translator->trans('Account'),
  3439.                 'href' => $this->generateUrl('customer_account'),
  3440.             ];
  3441.             $data['breadcrumbs'][] = [
  3442.                 'text' => $translator->trans('Orders'),
  3443.                 'href' => $this->generateUrl('customer_orders'),
  3444.             ];
  3445.             $data['breadcrumbs'][] = [
  3446.                 'text' => $translator->trans('Check payment') . ' - ' . $translator->trans('Order') . ' #' . $orderId,
  3447.                 'href' => $this->generateUrl('customer_payment_check', [
  3448.                     'orderId' => $orderId,
  3449.                     'paymentId' => $paymentId,
  3450.                 ]),
  3451.             ];
  3452.             $data['header'] = $this->getHeader($request);
  3453.             $data['footer'] = $this->getFooter($request);
  3454.             $data['contentBottom'] = $this->getContentBottom($request);
  3455.             return $this->render('AtechNetCoreBundle/Customer/orderCheckPayment.html.twig', $data);
  3456.         } else {
  3457.             return $this->forward('App\AtechNet\CoreBundle\Controller\DefaultController::notFoundAction', []);
  3458.         }
  3459.     }
  3460.     /**
  3461.      * @Route("/customer/find-postal-code-or-city", name="customer_find_postal_code_city", defaults={"_locale":""})
  3462.      * @Route("/{_locale<%supported_locales%>?}/customer/find-postal-code-or-city", name="customer_find_postal_code_city_locale", defaults={"_locale":""})
  3463.      * @param Request $request
  3464.      * @return JsonResponse
  3465.      */
  3466.     public function findPostalCodeOrCityAction(Request $request): JsonResponse
  3467.     {
  3468.         // Multi-Store
  3469.         $multiStoreHelper = $this->getMultiStoreHelper($request);
  3470.         // Load Database
  3471.         $database = $this->getPostalCodeAndCityDatabaseByDomain(
  3472.             $multiStoreHelper->getDomainId(),
  3473.             $multiStoreHelper->getDefaultLocale()
  3474.         );
  3475.         // Find Cities By Postal Code
  3476.         if ($request->request->get('filterPostalCode')) {
  3477.             $postalCode = urldecode($request->request->get('filterPostalCode'));
  3478.             $postalCode = str_replace(' ', '', $postalCode);
  3479.             $response = array_filter($database, function ($row) use ($postalCode) {
  3480.                 return preg_match('/^(' . $postalCode . ')/', $row['postalCode']) == 1;
  3481.             });
  3482.         }
  3483.         // Find Postal Codes by City
  3484.         if ($request->request->get('filterCity')) {
  3485.             $city = str_replace(' ', '', $request->request->get('filterCity'));
  3486.             $response = array_filter($database, function ($row) use ($city) {
  3487.                 return preg_match('/^(' . $city . ')/', $row['city']) == 1;
  3488.             });
  3489.         }
  3490.         return new JsonResponse(array_values($response));
  3491.     }
  3492.     /**
  3493.      * @Route("/customer/check-valid-postal-code", name="customer_check_valid_postal_code")
  3494.      * @param Request $request
  3495.      *
  3496.      * @return Response
  3497.      */
  3498.     public function checkValidPostalCodeAction(Request $request): Response
  3499.     {
  3500.         $checkout = $request->query->get('checkout');
  3501.         if (!is_array($checkout) && (!isset($checkout['shippingPostalCode']) && !isset($checkout['billingPostalCode']))) {
  3502.             return new JsonResponse([
  3503.                 'valid' => false,
  3504.             ]);
  3505.         }
  3506.         $postalCode = $checkout['shippingPostalCode'] ?? $checkout['billingPostalCode'];
  3507.         $postalCode = str_replace(' ', '', $postalCode);
  3508.         $multiStoreHelper = $this->getMultiStoreHelper($request);
  3509.         $data = $this->getPostalCodeAndCityDatabaseByDomain(
  3510.             $multiStoreHelper->getDomainId(),
  3511.             $multiStoreHelper->getDefaultLocale()
  3512.         );
  3513.         unset($data[0]);
  3514.         foreach ($data as $row) {
  3515.             if ($row['postalCode'] == $postalCode) {
  3516.                 return new JsonResponse([
  3517.                     'valid' => true,
  3518.                 ]);
  3519.             }
  3520.         }
  3521.         return new JsonResponse([
  3522.             'valid' => false,
  3523.         ]);
  3524.     }
  3525.     /**
  3526.      * @Route("/check-unique-business-id", name="check_unique_business_id", defaults={"_locale":""})
  3527.      * @Route("/{_locale<%supported_locales%>?}/check-unique-business-id", name="check_unique_business_id_locale", defaults={"_locale":""})
  3528.      * @param $request
  3529.      * return JsonResponse
  3530.      */
  3531.     public function checkUniqueBusinessIdAction(Request $request): JsonResponse
  3532.     {
  3533.         $businessId = $request->get('businessId') ?? 0;
  3534.         if ($businessId === 0) {
  3535.             return new JsonResponse([
  3536.                 'error' => 'Missing business id',
  3537.             ]);
  3538.         }
  3539.         $multiStore = $this->getMultiStoreHelper($request);
  3540.         $domainLanguage = $multiStore->getDomain()->getLanguage();
  3541.         $duplicateBusinessIdCheck = $this->getEntityManager()
  3542.             ->createQuery("SELECT c.id
  3543.                 FROM AtechNetCoreBundle:Customer c
  3544.                 LEFT JOIN c.domain d
  3545.                 WHERE (c.businessId = :businessId OR c.businessId = :trimmedBusinessId) AND d.language = :domainLanguage")
  3546.             ->setParameters([
  3547.                 'businessId' => $businessId,
  3548.                 'trimmedBusinessId' => str_replace(' ', '', $businessId),
  3549.                 'domainLanguage' => $domainLanguage,
  3550.             ])
  3551.             ->getResult();
  3552.         return new JsonResponse([
  3553.             'state' => (count($duplicateBusinessIdCheck) > 0 ? 'error' : 'success'),
  3554.         ]);
  3555.     }
  3556.     /**
  3557.      * @Route("/customer/finstat-lookup", name="customer_finstat_lookup", defaults={"_locale":""})
  3558.      * @Route("/{_locale<%supported_locales%>?}/customer/finstat-lookup", name="customer_finstat_lookup_locale", defaults={"_locale":""})
  3559.      * @param Request $request
  3560.      * @return JsonResponse
  3561.      */
  3562.     public function finstatLookupAction(Request $request, FinstatService $finstatService): JsonResponse
  3563.     {
  3564.         $businessId = trim((string) $request->get('businessId'));
  3565.         if ($businessId === '') {
  3566.             return new JsonResponse(['error' => 'Missing businessId'], Response::HTTP_BAD_REQUEST);
  3567.         }
  3568.         $multiStore = $this->getMultiStoreHelper($request);
  3569.         $country = strtoupper($multiStore->getDefaultLanguage()->getCode());
  3570.         if (!in_array($country, ['SK', 'CZ'], true)) {
  3571.             return new JsonResponse(['error' => 'Not supported for this domain'], Response::HTTP_BAD_REQUEST);
  3572.         }
  3573.         $result = $finstatService->getVatAndTaxIdByBusinessId($country, $businessId);
  3574.         if ($result === null) {
  3575.             return new JsonResponse(['error' => 'Not found'], Response::HTTP_NOT_FOUND);
  3576.         }
  3577.         return new JsonResponse([
  3578.             'vatId' => $result['vatId'],
  3579.             'taxId' => $result['taxId'],
  3580.         ]);
  3581.     }
  3582.     /**
  3583.      * @Route("/customer/vat-number-check", name="atech_net_core_customer_vat_number_check", defaults={"_locale":""})
  3584.      * @Route("/{_locale<%supported_locales%>?}/customer/vat-number-check", name="atech_net_core_customer_vat_number_check_locale", defaults={"_locale":""})
  3585.      * @param Request $request
  3586.      * @return JsonResponse
  3587.      * @throws \Exception
  3588.      */
  3589.     public function vatNumberCheckAction(Request $request): JsonResponse
  3590.     {
  3591.         if ($request->request->get('countryCode') == 'GR') {
  3592.             $countryCode = 'EL';
  3593.         } else {
  3594.             $countryCode = $request->request->get('countryCode');
  3595.         }
  3596.         $valid = $this->getEntityManager()->getRepository(Customer::class)->isVatNumberValid(
  3597.             $countryCode,
  3598.             $request->request->get('vatNumber')
  3599.         );
  3600.         return new JsonResponse([
  3601.             'state' => $valid ? 'valid' : 'invalid',
  3602.         ]);
  3603.     }
  3604.     /**
  3605.      * @Route("/customer/generate-new-klarna-session/{orderId}", name="atech_net_core_customer_generate_new_klarna_session")
  3606.      */
  3607.     public function  generateNewKlarnaSession(Request $request, $orderId){
  3608.         $order = $this->getEntityManager()->getRepository(Order::class)->findOneById($orderId);
  3609.         $domain = $order->getDomain();
  3610.         $orderSetting = $order->getKlarnaPaymentSessionIdSetting();
  3611.         $klarna = $this->getKlarna($domain->getId(), $request, $order->getShippingCountry());
  3612.         $klarnaSessionData = $klarna->getKlarnaSession($orderSetting->getValue());
  3613.         $newKlarnaSession = $klarna->createNewKlarnaSessionFromTheOldOne($klarnaSessionData);
  3614.         $redirectUrl = $this->generateUrl('checkout_payment_check', [
  3615.             'paymentTypeId' => PaymentType::Klarna->value,
  3616.             'orderId' => $order->getId(),
  3617.         ]);
  3618.         if (!isset($newKlarnaSession['session_id'])){
  3619.             return $this->redirect($redirectUrl);
  3620.         }
  3621.         $klarnaUrl = $klarna->createKlarnaUrl($redirectUrl, $newKlarnaSession['session_id']);
  3622.         $newOrderSetting = new OrderSetting();
  3623.         $newOrderSetting->setOrder($order);
  3624.         $newOrderSetting->setType(OrderSetting::TYPE_KLARNA_PAYMENT_SESSION_ID);
  3625.         $newOrderSetting->setValue($newKlarnaSession['session_id']);
  3626.         $entityManager = $this->getEntityManager();
  3627.         $entityManager->persist($newOrderSetting);
  3628.         $entityManager->flush();
  3629.         return $this->redirect($klarnaUrl['redirect_url']);
  3630.     }
  3631.     //KLAVIYO WEBHOOK
  3632.     /**
  3633.      * @Route("/customer/klaviyo/bnpl-check/{token}", name="app_atechnet_core_customer_klaviyobnplcheckwebhook")
  3634.      *
  3635.      * @param string $token
  3636.      * @param Request $request
  3637.      *
  3638.      * @return JsonResponse
  3639.      * @throws NotSupported
  3640.      */
  3641.     public function klaviyoBnplCheckWebhookAction(string $token, Request $request): JsonResponse
  3642.     {
  3643.         if ($token !== KlaviyoConnect::WEBHOOK_TOKEN) {
  3644.             return new JsonResponse('Invalid token', Response::HTTP_FORBIDDEN);
  3645.         }
  3646.         $data = json_decode($request->getContent(), true);
  3647.         if (!isset($data['bnpl_value']) || !in_array($data['bnpl_value'], PaymentType::getBnplPaymentTypeIds())) {
  3648.             return new JsonResponse('Invalid or missing BNPL value', Response::HTTP_BAD_REQUEST);
  3649.         }
  3650.         if (!isset($data['order_id']) || !is_numeric($data['order_id'])) {
  3651.             return new JsonResponse('Invalid or missing order_id', Response::HTTP_BAD_REQUEST);
  3652.         }
  3653.         $entityManager = $this->getEntityManager();
  3654.         $order = $entityManager->getRepository(Order::class)->findOneById($data['order_id']);
  3655.         if (!$order || $order->getPaymentType() != $data['bnpl_value']) {
  3656.             return new JsonResponse('Order not found or payment type mismatch', Response::HTTP_NOT_FOUND);
  3657.         }
  3658.         if ($order->getPaymentStatus() == Order::PAYMENT_STATUS_PAID) {
  3659.             return new JsonResponse('Payment already completed', Response::HTTP_OK);
  3660.         }
  3661.         // Generate Furbify link
  3662.         $orderRepository = $entityManager->getRepository(Order::class);
  3663.         $orderLink = $order->getDomain()->getUrl() . '/account/order/' . $order->getId() . '/' .
  3664.             $orderRepository->generatePublicLinkToken([
  3665.                 'orderId' => $order->getId(),
  3666.             ], (7 * 24 * 60 * 60));
  3667.         // Send to Klaviyo
  3668.         $this->getKlaviyoConnect($request)->createBnplNotPayedEvent(
  3669.             $order,
  3670.             PaymentType::from($data['bnpl_value']),
  3671.             $orderLink
  3672.         );
  3673.         return new JsonResponse('Success', Response::HTTP_OK);
  3674.     }
  3675.     /**
  3676.      * @Route("/customer/klaviyo/rental-email-send/{token}", name="app_atechnet_core_customer_klaviyorentalnotificationwebhook")
  3677.      * @param string $token
  3678.      * @param Request $request
  3679.      *
  3680.      * @return JsonResponse
  3681.      * @throws TransportExceptionInterface
  3682.      */
  3683.     public function klaviyoRentalNotificationWebhookAction(string $token, Request $request): JsonResponse
  3684.     {
  3685.         if ($token !== KlaviyoConnect::WEBHOOK_TOKEN) {
  3686.             return new JsonResponse('Invalid token', Response::HTTP_FORBIDDEN);
  3687.         }
  3688.         $data = json_decode($request->getContent(), true);
  3689.         $mailer = $this->getMailer();
  3690.         // Email
  3691.         $email = (new TemplatedEmail())
  3692.             ->subject('Rental notification from ' . $data['data']['domain'] . ' domain')
  3693.             ->to('webshop@furbify.eu')
  3694.             ->cc(['katarina.jobbagyova@furbify.eu'])
  3695.             ->replyTo($data['email'])
  3696.             ->htmlTemplate('AtechNetCoreBundle/Email/rentalNotification.html.twig')
  3697.             ->context(['data' => $data]);
  3698.         // Send Notification
  3699.         $mailer->send($email);
  3700.         return new JsonResponse('Success', Response::HTTP_OK);
  3701.     }
  3702.     #[Route('/customer/klaviyo/unas/claim-form/{token}', name: 'app_atechnet_core_customer_klaviyorentalunasclaimformwebhook')]
  3703.     public function klaviyoClaimFormWebhookAction(string $token, Request $request): JsonResponse
  3704.     {
  3705.         if ($token !== KlaviyoConnect::WEBHOOK_TOKEN) {
  3706.             return new JsonResponse('Invalid token', Response::HTTP_FORBIDDEN);
  3707.         }
  3708.         $entityManager = $this->getEntityManager();
  3709.         $data = json_decode($request->getContent(), true);
  3710.         $formId = $data['formId'];
  3711.         $claimTYpe = KlaviyoConnect::getClaimTypeFromFormId($formId);
  3712.         $language = KlaviyoConnect::getLanguageFromFormId($formId);
  3713.         $country = strtoupper($language);
  3714.         $customer = $entityManager->getRepository(Customer::class)->findOneBy([
  3715.             'email' => $data['email'],
  3716.         ]);
  3717.         $order = $entityManager->getRepository(Order::class)->createQueryBuilder('o')
  3718.             ->where('o.id = :orderId or o.externalOrderCode = :orderId')
  3719.             ->setParameter('orderId', $data['orderNumber'])
  3720.             ->getQuery()->getOneOrNullResult();
  3721.         if (!$customer && $order) {
  3722.             $customer = $order->getCustomer();
  3723.         }
  3724.         $claim = new Claim();
  3725.         $claim->setType($claimTYpe);
  3726.         $claim->setProductTitle($data['productName']);
  3727.         $claim->setProductType($data['productType']);
  3728.         $claim->setSerialNumber($data['serialNumber']);
  3729.         if ($claimTYpe == Claim::TYPE_WITHDRAWAL) {
  3730.             $comment = "Comment: {$data['returnComment']} \n";
  3731.             $returnReason = html_entity_decode($data['returnReason'] ?? '', ENT_QUOTES | ENT_HTML5, 'UTF-8');
  3732.             $comment .= "Return reasons: $returnReason";
  3733.             $claim->setBankAccount($data['bankAccount']);
  3734.             $claim->setBankAccountHolder($data['bankAccountHolder']);
  3735.         }
  3736.         else {
  3737.             $comment = $data['issueDescription'];
  3738.         }
  3739.         $claim->setCustomerNote($comment);
  3740.         if ($order) {
  3741.             $claim->setOrder($order);
  3742.             if ($order->useBillingAddressAsShippingAddress()) {
  3743.                 $claim->setCountry($order->getBillingCountry());
  3744.                 $claim->setStreet($order->getBillingStreet());
  3745.                 $claim->setCity($order->getBillingCity());
  3746.                 $claim->setZip($order->getBillingZip());
  3747.             } else {
  3748.                 $claim->setCountry($order->getShippingCountry());
  3749.                 $claim->setStreet($order->getShippingStreet());
  3750.                 $claim->setCity($order->getShippingCity());
  3751.                 $claim->setZip($order->getShippingZip());
  3752.             }
  3753.             if ($order->getBillingoDocuments()->count() > 0) {
  3754.                 $claim->setInvoiceCode($order->getBillingoDocuments()->first()->getInvoiceCode());
  3755.             }
  3756.             if ($order->getDocuments()->count() > 0) {
  3757.                 $claim->setInvoiceCode($order->getDocuments()->first()->getCode());
  3758.             }
  3759.         } else {
  3760.             /**
  3761.              * @var CustomerAddress $customerAddress
  3762.              */
  3763.             $customerAddress = is_null($customer->getAddresses()) ? false : $customer->getAddresses()->first();
  3764.             if ($customerAddress) {
  3765.                 $claim->setCountry($customerAddress->getCountry());
  3766.                 $claim->setStreet($customerAddress->getStreet());
  3767.                 $claim->setCity($customerAddress->getCity());
  3768.                 $claim->setZip($customerAddress->getZip());
  3769.             } else {
  3770.                 $claim->setCountry($customer->getCountry());
  3771.             }
  3772.             $claim->setInvoiceCode($data['invoiceNumber']);
  3773.         }
  3774.         $claim->setFirstName($customer->getFirstName());
  3775.         $claim->setLastName($customer->getLastName());
  3776.         $claim->setBusinessName($customer->getBusinessName());
  3777.         // Phone Number
  3778.         $phoneNumber = $customer->getPhone();
  3779.         // Remove non-numeric characters
  3780.         $_phoneNumber = preg_replace('/[^0-9]/', '', $phoneNumber);
  3781.         // Add plus sign if was removed
  3782.         if (substr($phoneNumber, 0, 1) == '+') {
  3783.             $_phoneNumber = '+' . $_phoneNumber;
  3784.         }
  3785.         $claim->setPhone($_phoneNumber);
  3786.         $claim->setEmail($customer->getEmail());
  3787.         $claim->setBoughtDate((new \DateTime($data['orderDate'])));
  3788.         $claim->setCustomer($customer);
  3789.         $claim->setReceiveType(Claim::RECEIVE_TYPE_SHIPPED_BY_PARCEL);
  3790.         $claim->setReturnType(Claim::RETURN_TYPE_PARCEL);
  3791.         if ($order) {
  3792.             $claim->setCountry($order->getShippingCountry());
  3793.         }
  3794.         else {
  3795.             $claim->setCountry($country);
  3796.         }
  3797.         $claim->setCode($entityManager->getRepository(Claim::class)->createCode($claim));
  3798.         $claim->setLastStatusId(ClaimStatus::STATUS_TYPE_REGISTERED);
  3799.         $entityManager->persist($claim);
  3800.         $entityManager->flush();
  3801.         $claimStatus = new ClaimStatus();
  3802.         $claimStatus->setClaim($claim);
  3803.         $claimStatus->setStatusType(1);
  3804.         $entityManager->persist($claimStatus);
  3805.         $notificationIds = [785, 3055];
  3806.         foreach ($notificationIds as $notificationId) {
  3807.             $notificationConfig = $entityManager->getRepository(NotificationConfig::class)->findOneById($notificationId);
  3808.             if ($notificationConfig) {
  3809.                 $notification = new Notification();
  3810.                 $notification->setText('New withdrawal #' . $claim->getCode());
  3811.                 $notification->setNotificationConfig($notificationConfig);
  3812.                 $notification->setActive(true);
  3813.                 $notification->setUrl('https://www.atechcomp.eu/centralis/web/claim/edit/' . $claim->getId());
  3814.                 $entityManager->persist($notification);
  3815.             }
  3816.         }
  3817.         $entityManager->flush();
  3818.         $this->getKlaviyoConnect($request)
  3819.             ->createNewExpansionClaimEvent($claim, $formId);
  3820.         return new JsonResponse([$claim->getId()], Response::HTTP_OK);
  3821.     }
  3822. }