src/Controller/TravelcardController.php line 51

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Constants\NovaConstants;
  4. use App\Controller\Abstracts\AbstractFrontendController;
  5. use App\Entity\Archive;
  6. use App\Entity\Datatrans\ResponseObject;
  7. use App\Entity\Employee;
  8. use App\Entity\Order;
  9. use App\Entity\PricingModel;
  10. use App\Form\ProductSearchType;
  11. use App\Repository\ArchiveRepository;
  12. use App\Repository\EmployeeRepository;
  13. use App\Repository\OrderRepository;
  14. use App\Service\Datatrans\PaymentHandler;
  15. use App\Service\Datatrans\ResponseHandler;
  16. use App\Service\Employee\DidokService;
  17. use App\Service\Employee\LocaleService;
  18. use App\Service\Ngw\ContractService;
  19. use App\Service\Nova\Services\GeschaeftspartnerService;
  20. use App\Service\Nova\Services\VertragsService;
  21. use App\Service\Nova\Services\VertriebsService;
  22. use App\Service\Product\PriceInformation;
  23. use App\Service\Product\SpecialAboPriceCalculator;
  24. use App\Service\Product\UsedProductManager;
  25. use App\Service\Sale\DepositManager;
  26. use App\Service\SessionService;
  27. use App\Service\SwissPass\SwissPassService;
  28. use App\Utils\DataMapper;
  29. use App\Utils\Nova;
  30. use App\Utils\Utitlity;
  31. use App\Validator\InputValidator;
  32. use Symfony\Component\HttpFoundation\Request;
  33. use Symfony\Component\HttpFoundation\Response;
  34. use Symfony\Component\Routing\Annotation\Route;
  35. #[Route(
  36. path: [
  37. 'de_CH' =>'/',
  38. 'de_DE' => '/de',
  39. 'it_CH' => '/it',
  40. 'fr_CH' => '/fr',
  41. 'en_CH' => '/en',
  42. ]
  43. )]
  44. class TravelcardController extends AbstractFrontendController
  45. {
  46. #[Route('/', name: 'app_travelcard')]
  47. public function index(SwissPassService $swissPassService,Request $request): Response
  48. {
  49. $swissPassService->setLanguage(DataMapper::getLanguageKeyFromLocale($request->getLocale()));
  50. $ckmNotValid = false;
  51. if($swissPassService->isTokenEmpty()){
  52. $swissPassService->clearSwissPassSessionData();
  53. $authorizationUrl = $swissPassService->getAuthorizationUrl();
  54. } else if($swissPassService->isTokenValid() && !$swissPassService->getUserTkid()) {
  55. return $this->getSwissPassLoginTokenNotValidRoute($swissPassService);
  56. } else if($swissPassService->isTokenValid() && $swissPassService->getUserTkid() && !$swissPassService->getUserCkm()){
  57. $swissPassService->setCallbackUrl();
  58. $authorizationUrl = '';
  59. $ckmNotValid = true;
  60. } else {
  61. return $this->redirectToRoute('app_travelcard_show');
  62. }
  63. return $this->render('travelcard/index.html.twig', [
  64. 'authorizationUrl' => $authorizationUrl,
  65. 'forcedLogout' => $this->isForcedLogout($request),
  66. 'ckmNotValid' => $ckmNotValid,
  67. 'swissPassService' => $swissPassService,
  68. ]);
  69. }
  70. #[Route(path: [
  71. 'de_CH' => '/show',
  72. 'de_DE' => '/schule',
  73. 'it_CH' => '/show',
  74. 'fr_CH' => '/show',
  75. 'en_CH' => '/show'
  76. ],name: 'app_travelcard_show')]
  77. public function show(
  78. GeschaeftspartnerService $geschaeftspartnerService,
  79. EmployeeRepository $employeeRepository,
  80. SwissPassService $swissPassService,
  81. DidokService $didokService,
  82. UsedProductManager $usedProductManager,
  83. Request $request,
  84. LocaleService $localeService,
  85. ): Response
  86. {
  87. $swissPassService->setLanguage(DataMapper::getLanguageKeyFromLocale($request->getLocale()));
  88. if(!$this->isSwissPassLoginPossible($swissPassService) && !$this->noLoginRequired()){
  89. return $this->getSwissPassLoginTokenNotValidRoute($swissPassService);
  90. } else {
  91. if($this->noLoginRequired() && !empty($request->get('customerId'))){
  92. $configuration = ['tkid' => $request->get('customerId')];
  93. $parameters = ['customerId' => $request->get('customerId')];
  94. } elseif(!empty($swissPassService->getUserCkm())) {
  95. if($this->isSwissPassLoginPossible($swissPassService)){
  96. $configuration = ['ckm' => $swissPassService->getUserCkm()];
  97. $parameters = [];
  98. } else {
  99. return $this->getSwissPassLoginTokenNotValidRoute($swissPassService);
  100. }
  101. } else {
  102. return $this->redirectToRoute('app_travelcard');
  103. }
  104. $novaUser = $geschaeftspartnerService->suchePartner($configuration);
  105. if($novaUser){
  106. $employee = $employeeRepository->findOneBy(['tkid'=>$novaUser->getTkid()]);
  107. if(!$employee instanceof Employee){
  108. return $this->redirectToRoute('app_travelcard_not_found');
  109. }
  110. if(!$employee->isPaymentPossible()){
  111. return $this->redirectToRoute('app_travelcard_not_authorized',['employee' => $employee->getId()]);
  112. }
  113. $employee = $didokService->updateEmployeeDidokInformation($employee);
  114. $currentDate = new \DateTime();
  115. $currentDate->setTime(0,0,0);
  116. $activeProducts = $usedProductManager->getActiveProductsByEmployee($employee);
  117. if ($employee->getValidDate() instanceof \DateTime && $employee->getValidDate()->getTimestamp() >= $currentDate->getTimestamp()) {
  118. $validDate = $employee->getValidDate();
  119. } else {
  120. $validDate = null;
  121. }
  122. $form = $this->createForm(ProductSearchType::class, null, [
  123. 'action' => $this->generateUrl('app_travelcard_update_offers', $parameters),
  124. 'method' => 'POST',
  125. 'attr'=> [
  126. 'novalidate' => true,
  127. 'id' => 'formOrderOptions',
  128. 'data-ajax' => 'true'
  129. ],
  130. 'validDate' => $validDate
  131. ]);
  132. $localeService->updateLocale($employee, $request);
  133. return $this->renderForm('travelcard/show.html.twig', [
  134. 'employee' => $employee,
  135. 'activeProducts' => $activeProducts,
  136. 'swissPassService' => $swissPassService,
  137. 'form' => $form,
  138. 'validDate' => $validDate
  139. ]);
  140. } else {
  141. return $this->renderForm('travelcard/error.html.twig', [
  142. ]);
  143. }
  144. }
  145. }
  146. #[Route('/offer/{employee}/{id}/{productNumber}',
  147. methods: ['GET'],
  148. name:'app_travelcard_offer')
  149. ]
  150. public function offer(
  151. Employee $employee,
  152. string $id,
  153. string $productNumber,
  154. SwissPassService $swissPassService,
  155. VertriebsService $vertriebsService,
  156. PriceInformation $priceInformation,
  157. OrderRepository $orderRepository,
  158. PaymentHandler $paymentHandler,
  159. ResponseHandler $responseHandler,
  160. Request $request,
  161. SpecialAboPriceCalculator $specialAboPriceCalculator,
  162. LocaleService $localeService
  163. ): Response
  164. {
  165. $swissPassService->setLanguage(DataMapper::getLanguageKeyFromLocale($request->getLocale()));
  166. if(!$employee->isPaymentPossible()){
  167. return $this->redirectToRoute('app_travelcard_show',['customerId' => $employee->getTkid()]);
  168. }
  169. if(!$this->isSwissPassLoginPossible($swissPassService) && !$this->noLoginRequired()){
  170. return $this->getSwissPassLoginTokenNotValidRoute($swissPassService);
  171. } else {
  172. $overrideConfiguration = $this->getOverrideConfiguration($employee->getTuInformation());
  173. if(!$swissPassService->isTokenEmpty()) {
  174. if (!$this->isSwissPassLoginPossible($swissPassService)) {
  175. return $this->getSwissPassLoginTokenNotValidRoute($swissPassService);
  176. }
  177. }
  178. $validDateCorrect = false;
  179. if($overrideConfiguration && isset($overrideConfiguration['datatrans'])){
  180. $paymentHandler->overrideApiHeaderOptions($overrideConfiguration['datatrans']);
  181. }
  182. $paymentHandler->setBaseUrl($this->getParameter('baseUrl') . $request->getPathInfo());
  183. if(!empty($request->query->get('datatransTrxId'))){
  184. $responseObject = $responseHandler->getResponse($request->query->get('datatransTrxId'));
  185. } else {
  186. $responseObject = null;
  187. }
  188. $customerConfiguration = [];
  189. $customerConfiguration['tkid'] = $employee->getTkid();
  190. $customerConfiguration['language'] = DataMapper::getLanguageKeyFromLocale($employee->getLocale());
  191. if(Nova::isNationalProductCompareByProductNumber($productNumber)){
  192. /*
  193. if($employee->getAge() < 18){
  194. $customerConfiguration['vertragsPartnerTkid'] = '0e50b759-ae3a-4f41-b0f0-11e11e12b814';//'489885a2-a262-426d-bc01-a58107eb683c';
  195. } else {
  196. $customerConfiguration['vertragsPartnerTkid'] = $employee->getTkid();
  197. }
  198. */
  199. $customerConfiguration['vertragsPartnerTkid'] = $employee->getTkid();
  200. }
  201. /*
  202. if(Nova::isProofRequiredProduct($productNumber)){
  203. $nachweisgueltigbis = new \DateTime();
  204. $nachweisgueltigbis->modify('+100 days');
  205. $customerConfiguration['nachweisgueltigbis'] = $nachweisgueltigbis->format('Y-m-d');
  206. }
  207. */
  208. if($overrideConfiguration){
  209. $vertriebsService->overrideClientIdentifier($overrideConfiguration);
  210. }
  211. $offers = $vertriebsService->offeriereLeistungen([$id],$customerConfiguration);
  212. $priceInformation->setEmployee($employee);
  213. $priceInformation->setOrders($offers);
  214. $order = $priceInformation->getBestOrder();
  215. if($order instanceof Order){
  216. if(
  217. $employee->getValidDate() instanceof \DateTime &&
  218. $order->getAusweisbarerZeitraumVon() instanceof \DateTime &&
  219. $employee->getValidDate()->format('d.m.Y') == $order->getAusweisbarerZeitraumVon()->format('d.m.Y')){
  220. $validDateCorrect = true;
  221. }
  222. $order->setBestellNummer($order->getProduktNummer().'-'.$order->getLeistungsReferenz());
  223. $order->setAngebotsId($id);
  224. $paymentForm = $paymentHandler->render($order,$employee);
  225. if(isset($sessionOrder[0]) && $sessionOrder[0] instanceof Order){
  226. $orderToRemove = $orderRepository->find($sessionOrder[0]->getId());
  227. if($orderToRemove instanceof Order){
  228. $orderRepository->remove($orderToRemove);
  229. }
  230. }
  231. $order->checkMaxDiscount(Utitlity::checkRemainingBalance($employee));
  232. $order->setTransactionId($paymentHandler->getTransactionId());
  233. $order->setTkid($employee->getTkid());
  234. if(Nova::isFreiePreiseingabeAboProduct($order)){
  235. if($employee->getTuInformation() == NovaConstants::TU_INVIA){
  236. $specialAboPriceCalculator->calculateBuegaFirmenAboPrice($employee);
  237. } else {
  238. $specialAboPriceCalculator->calculateOstwindFirmenAboPrice($employee);
  239. }
  240. $offer = $specialAboPriceCalculator->getOfferByClass($order->getKlasse());
  241. if($offer instanceof Order){
  242. $order->setBasePrice($offer->getBetrag());
  243. //$order->setUpgradePrice($offer->getUpgradePrice());
  244. }
  245. $pricingModel = Utitlity::findPricingModel($employee);
  246. if($pricingModel instanceof PricingModel){
  247. $order->setPricingModelDiscount($pricingModel->getEmployeeDiscount());
  248. }
  249. }
  250. $orderRepository->save($order, true);
  251. $localeService->updateLocale($employee, $request);
  252. return $this->render('travelcard/offer.html.twig', [
  253. 'employee' => $employee,
  254. 'priceInformation' => $priceInformation,
  255. 'paymentForm' => $paymentForm,
  256. 'responseObject' => $responseObject,
  257. 'validDateCorrect' => $validDateCorrect,
  258. 'order' => $order,
  259. 'swissPassService' => $swissPassService,
  260. 'invoiceData' => $paymentHandler->getInvoiceData(),
  261. ]);
  262. } else {
  263. return $this->redirectToRoute('app_travelcard');
  264. }
  265. }
  266. }
  267. #[Route('/update-offers', name: 'app_travelcard_update_offers')]
  268. public function updateOffers(
  269. GeschaeftspartnerService $geschaeftspartnerService,
  270. VertragsService $vertragsService,
  271. ContractService $contractService,
  272. EmployeeRepository $employeeRepository,
  273. SwissPassService $swissPassService,
  274. PriceInformation $priceInformation,
  275. DidokService $didokService,
  276. Request $request
  277. ): Response
  278. {
  279. $swissPassService->setLanguage(DataMapper::getLanguageKeyFromLocale($request->getLocale()));
  280. if(!$this->isSwissPassLoginPossible($swissPassService) && !$this->noLoginRequired()){
  281. return $this->getSwissPassLoginTokenNotValidRoute($swissPassService);
  282. } else {
  283. $filter = [];
  284. if(!empty($request->get('customerId'))){
  285. $configuration = ['tkid' => $request->get('customerId')];
  286. $parameters['customerId'] = $configuration['tkid'];
  287. } else {
  288. $configuration = ['tkid' => $swissPassService->getUserTkid()];
  289. $parameters = [];
  290. }
  291. $novaUser = $geschaeftspartnerService->suchePartner($configuration);
  292. if($novaUser instanceof Employee){
  293. $employee = $employeeRepository->findOneBy(['tkid'=>$novaUser->getTkid()]);
  294. if($employee instanceof Employee){
  295. $employee = $didokService->updateEmployeeDidokInformation($employee);
  296. if($request->get('product_search')) {
  297. $productSearchOption = $request->get('product_search');
  298. if(isset($productSearchOption['additionalZonen']) && !empty($productSearchOption['additionalZonen'])){
  299. $employee->setAdditionalZones($productSearchOption['additionalZonen']);
  300. } else {
  301. $employee->setAdditionalZones(null);
  302. }
  303. if(isset($productSearchOption['zonenBuendels']) && !empty(trim($productSearchOption['zonenBuendels']))){
  304. $zoneBundel = json_decode($productSearchOption['zonenBuendels'], true);
  305. if(is_array($zoneBundel) && !empty($zoneBundel)){
  306. $priceInformation->setZoneBundle($zoneBundel);
  307. }
  308. }
  309. if(isset($productSearchOption['validDate']) && !empty(trim($productSearchOption['validDate']))){
  310. $date = Nova::convertStringToDate($productSearchOption['validDate']);
  311. if($date instanceof \DateTime){
  312. $priceInformation->setValidDate($date);
  313. $employee->setValidDate($date);
  314. $employeeRepository->save($employee,true);
  315. }
  316. }
  317. }
  318. if(!$employee->isPaymentPossible()){
  319. return $this->redirectToRoute('app_travelcard_not_authorized',['employee' => $employee->getId()]);
  320. }
  321. $priceInformation->setPriceInformation($employee);
  322. if(!empty($filter) && !$priceInformation->isApiError()){
  323. $priceInformation->setFilter($filter);
  324. }
  325. if($employee->getEnterprise()->isContractOption()){
  326. $contracts = $vertragsService->leseVertragsInfos(['tkid' => $employee->getTkid()]);
  327. if(!empty($contracts)){
  328. $contracts = $contractService->getOnlyActiveContracts($contracts);
  329. $contracts = $contractService->getOnlyOwnContracts($contracts,$employee->getTkid());
  330. $contracts = $contractService->updateContractAmount($contracts);
  331. $contracts = $contractService->updateContractDiscount($contracts,$priceInformation);
  332. $productNumbers = $contractService->getProductNumbers($contracts);
  333. if(!empty($productNumbers)){
  334. $priceInformation->removeExcludeProducts($productNumbers);
  335. }
  336. }
  337. } else {
  338. $contracts = null;
  339. }
  340. $form = $this->createForm(ProductSearchType::class, null, [
  341. 'action' => $this->generateUrl('app_travelcard_update_offers', $parameters),
  342. 'method' => 'POST',
  343. 'attr'=> [
  344. 'novalidate' => true,
  345. 'id' => 'formOrderOptions',
  346. 'data-ajax' => 'true'
  347. ],
  348. 'zonenBuendels' => $priceInformation->getMoeglicheZonenBuendel(),
  349. 'zonen' => $priceInformation->getZonen(),
  350. 'validDate' => $employee->getValidDate()
  351. ]);
  352. return $this->renderForm('travelcard/update_offers.html.twig', [
  353. 'priceInformation' => $priceInformation,
  354. 'contracts' => $contracts,
  355. 'predefinedOffer' => $priceInformation->getPredefinedOffer(),
  356. 'employee' => $employee,
  357. 'messages' => $priceInformation->getMeldungen(),
  358. 'form' => $form
  359. ]);
  360. } else {
  361. return $this->render('travelcard/errors/_offers.html.twig', [
  362. ]);
  363. }
  364. } else {
  365. return $this->render('travelcard/errors/_offers.html.twig', [
  366. 'error' => $novaUser
  367. ]);
  368. }
  369. }
  370. }
  371. #[Route('/finish', name:'app_travelcard_finish')]
  372. public function finish(
  373. EmployeeRepository $employeeRepository,
  374. OrderRepository $orderRepository,
  375. ArchiveRepository $archiveRepository,
  376. ResponseHandler $responseHandler,
  377. Request $request,
  378. SessionService $sessionService,
  379. SwissPassService $swissPassService,
  380. LocaleService $localeService,
  381. ): Response
  382. {
  383. $orders = null;
  384. $employee = null;
  385. $transactionId = '';
  386. $responseObject = null;
  387. $swissPassService->setLanguage(DataMapper::getLanguageKeyFromLocale($request->getLocale()));
  388. if(!empty($request->query->get('datatransTrxId'))){
  389. $transactionId = $request->query->get('datatransTrxId');
  390. } elseif(!empty($request->query->get('transactionId'))) {
  391. // No Datatrans Payment (100 Rabatt)
  392. $transactionId = $request->query->get('transactionId');
  393. $responseObject = new ResponseObject();
  394. $responseObject->setTransactionId($request->query->get('transactionId'));
  395. $responseObject->setSuccess(true);
  396. }
  397. if(!empty($transactionId)){
  398. $tempArchive = $archiveRepository->findOneBy(['transactionId'=>$transactionId]);
  399. if($tempArchive instanceof Archive){
  400. $employee = $employeeRepository->findOneBy(['tkid'=>$tempArchive->getTkid()]);
  401. } else {
  402. $tempOrder = $orderRepository->findOneBy(['transactionId'=>$transactionId]);
  403. if($tempOrder instanceof Order){
  404. $employee = $employeeRepository->findOneBy(['tkid'=>$tempOrder->getTkid()]);
  405. }
  406. }
  407. // Check if it is a Datatrans payment. If so, the TU configuration may need to be overwritten.
  408. if(!$responseObject instanceof ResponseObject && $employee instanceof Employee){
  409. $overrideConfiguration = $this->getOverrideConfiguration($employee->getTuInformation());
  410. if($overrideConfiguration && isset($overrideConfiguration['datatrans'])){
  411. $responseHandler->overrideApiHeaderOptions($overrideConfiguration['datatrans']);
  412. }
  413. $responseObject = $responseHandler->getResponse($transactionId);
  414. }
  415. if($responseObject instanceof ResponseObject && $responseObject->isSuccess()){
  416. $orders = $archiveRepository->findBy(['transactionId'=>$transactionId]);
  417. if(isset($orders[0]) && $orders[0] instanceof Archive){
  418. $ordersToDelete = $orderRepository->findBy(['transactionId'=>$transactionId]);
  419. foreach($ordersToDelete as $orderToDelete){
  420. if($orderToDelete instanceof Order){
  421. $orderRepository->remove($orderToDelete,1);
  422. }
  423. }
  424. } else {
  425. $orders = $orderRepository->findBy(['transactionId'=>$transactionId]);
  426. if(isset($orders[0]) && $orders[0] instanceof Order){
  427. $orders[0]->setLeistungsStatus($orders[0]::PAYED_NOTFINISHED);
  428. $orderRepository->save($orders[0],true);
  429. }
  430. }
  431. }
  432. $sessionService->writeSession('employee',$employee);
  433. }
  434. // Expose the Employee for Enterprise/logo
  435. if ($employee instanceof Employee) {
  436. $request->attributes->set('employee', $employee);
  437. $localeService->updateLocale($employee, $request);
  438. }
  439. return $this->render('travelcard/finish.html.twig', [
  440. 'orders' => $orders,
  441. 'employee' => $employee,
  442. 'datatransTrxId' => $transactionId,
  443. 'swissPassService' => $swissPassService,
  444. ]);
  445. }
  446. #[Route('/renew', name:'app_travelcard_renew')]
  447. public function renew(Request $request, VertriebsService $vertriebsService, GeschaeftspartnerService $geschaeftspartnerService, EmployeeRepository $employeeRepository): Response
  448. {
  449. $queryParams = $request->query->all();
  450. if(isset($queryParams['renewId']) && InputValidator::isUUID($queryParams['renewId'])){
  451. $configuration['erneuerungsId'] = $queryParams['renewId'];
  452. $result = $vertriebsService->sucheLeistung($configuration);
  453. if(isset($result[0]) && $result[0] instanceof Order){
  454. $order = $result[0];
  455. if(InputValidator::tkidValidation($order->getTkid())){
  456. $novaUser = $geschaeftspartnerService->suchePartner(['tkid'=>$order->getTkid()]);
  457. $employee = $employeeRepository->findOneBy(['tkid'=>$novaUser->getTkid()]);
  458. if(!$employee instanceof Employee){
  459. return $this->redirectToRoute('app_travelcard_not_found');
  460. }
  461. if(!$employee->isPaymentPossible()){
  462. if($employee->getApproved() <= $employee::INVITATION_SENT){
  463. return $this->redirectToRoute('app_registration_employee',['enterprise' => $employee->getEnterprise()->getId(),'employee' => $employee->getId(),'_locale' => $employee->getLocale()]);
  464. } else {
  465. return $this->redirectToRoute('app_travelcard_not_authorized',['employee' => $employee->getId()]);
  466. }
  467. } else {
  468. return $this->redirectToRoute('app_travelcard_show',['customerId' => $employee->getTkid()]);
  469. }
  470. }
  471. }
  472. }
  473. return $this->redirectToRoute('app_travelcard');
  474. }
  475. #[Route('/notauthorized/{employee}', name: 'app_travelcard_not_authorized')]
  476. public function notAuthorized(Request $request, Employee $employee,SwissPassService $swissPassService){
  477. $swissPassService->setLanguage(DataMapper::getLanguageKeyFromLocale($request->getLocale()));
  478. if(!$swissPassService->isTokenValid() && !$this->noLoginRequired()){
  479. return $this->redirectToRoute('app_travelcard');
  480. } else {
  481. return $this->render('travelcard/not_authorized.html.twig', [
  482. 'employee' => $employee,
  483. 'swissPassService' => $swissPassService,
  484. ]);
  485. }
  486. }
  487. #[Route('/nicht-gefunden', name: 'app_travelcard_not_found')]
  488. public function notFound(Request $request,SwissPassService $swissPassService){
  489. $swissPassService->setLanguage(DataMapper::getLanguageKeyFromLocale($request->getLocale()));
  490. if(!$swissPassService->isTokenValid()){
  491. return $this->redirectToRoute('app_travelcard');
  492. } else {
  493. return $this->render('travelcard/not_found.html.twig', [
  494. 'swissPassService' => $swissPassService
  495. ]);
  496. }
  497. }
  498. }