<?php
namespace App\Controller;
use App\Constants\NovaConstants;
use App\Controller\Abstracts\AbstractFrontendController;
use App\Entity\Archive;
use App\Entity\Datatrans\ResponseObject;
use App\Entity\Employee;
use App\Entity\Order;
use App\Entity\PricingModel;
use App\Form\ProductSearchType;
use App\Repository\ArchiveRepository;
use App\Repository\EmployeeRepository;
use App\Repository\OrderRepository;
use App\Service\Datatrans\PaymentHandler;
use App\Service\Datatrans\ResponseHandler;
use App\Service\Employee\DidokService;
use App\Service\Employee\LocaleService;
use App\Service\Ngw\ContractService;
use App\Service\Nova\Services\GeschaeftspartnerService;
use App\Service\Nova\Services\VertragsService;
use App\Service\Nova\Services\VertriebsService;
use App\Service\Product\PriceInformation;
use App\Service\Product\SpecialAboPriceCalculator;
use App\Service\Product\UsedProductManager;
use App\Service\Sale\DepositManager;
use App\Service\SessionService;
use App\Service\SwissPass\SwissPassService;
use App\Utils\DataMapper;
use App\Utils\Nova;
use App\Utils\Utitlity;
use App\Validator\InputValidator;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
#[Route(
path: [
'de_CH' =>'/',
'de_DE' => '/de',
'it_CH' => '/it',
'fr_CH' => '/fr',
'en_CH' => '/en',
]
)]
class TravelcardController extends AbstractFrontendController
{
#[Route('/', name: 'app_travelcard')]
public function index(SwissPassService $swissPassService,Request $request): Response
{
$swissPassService->setLanguage(DataMapper::getLanguageKeyFromLocale($request->getLocale()));
$ckmNotValid = false;
if($swissPassService->isTokenEmpty()){
$swissPassService->clearSwissPassSessionData();
$authorizationUrl = $swissPassService->getAuthorizationUrl();
} else if($swissPassService->isTokenValid() && !$swissPassService->getUserTkid()) {
return $this->getSwissPassLoginTokenNotValidRoute($swissPassService);
} else if($swissPassService->isTokenValid() && $swissPassService->getUserTkid() && !$swissPassService->getUserCkm()){
$swissPassService->setCallbackUrl();
$authorizationUrl = '';
$ckmNotValid = true;
} else {
return $this->redirectToRoute('app_travelcard_show');
}
return $this->render('travelcard/index.html.twig', [
'authorizationUrl' => $authorizationUrl,
'forcedLogout' => $this->isForcedLogout($request),
'ckmNotValid' => $ckmNotValid,
'swissPassService' => $swissPassService,
]);
}
#[Route(path: [
'de_CH' => '/show',
'de_DE' => '/schule',
'it_CH' => '/show',
'fr_CH' => '/show',
'en_CH' => '/show'
],name: 'app_travelcard_show')]
public function show(
GeschaeftspartnerService $geschaeftspartnerService,
EmployeeRepository $employeeRepository,
SwissPassService $swissPassService,
DidokService $didokService,
UsedProductManager $usedProductManager,
Request $request,
LocaleService $localeService,
): Response
{
$swissPassService->setLanguage(DataMapper::getLanguageKeyFromLocale($request->getLocale()));
if(!$this->isSwissPassLoginPossible($swissPassService) && !$this->noLoginRequired()){
return $this->getSwissPassLoginTokenNotValidRoute($swissPassService);
} else {
if($this->noLoginRequired() && !empty($request->get('customerId'))){
$configuration = ['tkid' => $request->get('customerId')];
$parameters = ['customerId' => $request->get('customerId')];
} elseif(!empty($swissPassService->getUserCkm())) {
if($this->isSwissPassLoginPossible($swissPassService)){
$configuration = ['ckm' => $swissPassService->getUserCkm()];
$parameters = [];
} else {
return $this->getSwissPassLoginTokenNotValidRoute($swissPassService);
}
} else {
return $this->redirectToRoute('app_travelcard');
}
$novaUser = $geschaeftspartnerService->suchePartner($configuration);
if($novaUser){
$employee = $employeeRepository->findOneBy(['tkid'=>$novaUser->getTkid()]);
if(!$employee instanceof Employee){
return $this->redirectToRoute('app_travelcard_not_found');
}
if(!$employee->isPaymentPossible()){
return $this->redirectToRoute('app_travelcard_not_authorized',['employee' => $employee->getId()]);
}
$employee = $didokService->updateEmployeeDidokInformation($employee);
$currentDate = new \DateTime();
$currentDate->setTime(0,0,0);
$activeProducts = $usedProductManager->getActiveProductsByEmployee($employee);
if ($employee->getValidDate() instanceof \DateTime && $employee->getValidDate()->getTimestamp() >= $currentDate->getTimestamp()) {
$validDate = $employee->getValidDate();
} else {
$validDate = null;
}
$form = $this->createForm(ProductSearchType::class, null, [
'action' => $this->generateUrl('app_travelcard_update_offers', $parameters),
'method' => 'POST',
'attr'=> [
'novalidate' => true,
'id' => 'formOrderOptions',
'data-ajax' => 'true'
],
'validDate' => $validDate
]);
$localeService->updateLocale($employee, $request);
return $this->renderForm('travelcard/show.html.twig', [
'employee' => $employee,
'activeProducts' => $activeProducts,
'swissPassService' => $swissPassService,
'form' => $form,
'validDate' => $validDate
]);
} else {
return $this->renderForm('travelcard/error.html.twig', [
]);
}
}
}
#[Route('/offer/{employee}/{id}/{productNumber}',
methods: ['GET'],
name:'app_travelcard_offer')
]
public function offer(
Employee $employee,
string $id,
string $productNumber,
SwissPassService $swissPassService,
VertriebsService $vertriebsService,
PriceInformation $priceInformation,
OrderRepository $orderRepository,
PaymentHandler $paymentHandler,
ResponseHandler $responseHandler,
Request $request,
SpecialAboPriceCalculator $specialAboPriceCalculator,
LocaleService $localeService
): Response
{
$swissPassService->setLanguage(DataMapper::getLanguageKeyFromLocale($request->getLocale()));
if(!$employee->isPaymentPossible()){
return $this->redirectToRoute('app_travelcard_show',['customerId' => $employee->getTkid()]);
}
if(!$this->isSwissPassLoginPossible($swissPassService) && !$this->noLoginRequired()){
return $this->getSwissPassLoginTokenNotValidRoute($swissPassService);
} else {
$overrideConfiguration = $this->getOverrideConfiguration($employee->getTuInformation());
if(!$swissPassService->isTokenEmpty()) {
if (!$this->isSwissPassLoginPossible($swissPassService)) {
return $this->getSwissPassLoginTokenNotValidRoute($swissPassService);
}
}
$validDateCorrect = false;
if($overrideConfiguration && isset($overrideConfiguration['datatrans'])){
$paymentHandler->overrideApiHeaderOptions($overrideConfiguration['datatrans']);
}
$paymentHandler->setBaseUrl($this->getParameter('baseUrl') . $request->getPathInfo());
if(!empty($request->query->get('datatransTrxId'))){
$responseObject = $responseHandler->getResponse($request->query->get('datatransTrxId'));
} else {
$responseObject = null;
}
$customerConfiguration = [];
$customerConfiguration['tkid'] = $employee->getTkid();
$customerConfiguration['language'] = DataMapper::getLanguageKeyFromLocale($employee->getLocale());
if(Nova::isNationalProductCompareByProductNumber($productNumber)){
/*
if($employee->getAge() < 18){
$customerConfiguration['vertragsPartnerTkid'] = '0e50b759-ae3a-4f41-b0f0-11e11e12b814';//'489885a2-a262-426d-bc01-a58107eb683c';
} else {
$customerConfiguration['vertragsPartnerTkid'] = $employee->getTkid();
}
*/
$customerConfiguration['vertragsPartnerTkid'] = $employee->getTkid();
}
/*
if(Nova::isProofRequiredProduct($productNumber)){
$nachweisgueltigbis = new \DateTime();
$nachweisgueltigbis->modify('+100 days');
$customerConfiguration['nachweisgueltigbis'] = $nachweisgueltigbis->format('Y-m-d');
}
*/
if($overrideConfiguration){
$vertriebsService->overrideClientIdentifier($overrideConfiguration);
}
$offers = $vertriebsService->offeriereLeistungen([$id],$customerConfiguration);
$priceInformation->setEmployee($employee);
$priceInformation->setOrders($offers);
$order = $priceInformation->getBestOrder();
if($order instanceof Order){
if(
$employee->getValidDate() instanceof \DateTime &&
$order->getAusweisbarerZeitraumVon() instanceof \DateTime &&
$employee->getValidDate()->format('d.m.Y') == $order->getAusweisbarerZeitraumVon()->format('d.m.Y')){
$validDateCorrect = true;
}
$order->setBestellNummer($order->getProduktNummer().'-'.$order->getLeistungsReferenz());
$order->setAngebotsId($id);
$paymentForm = $paymentHandler->render($order,$employee);
if(isset($sessionOrder[0]) && $sessionOrder[0] instanceof Order){
$orderToRemove = $orderRepository->find($sessionOrder[0]->getId());
if($orderToRemove instanceof Order){
$orderRepository->remove($orderToRemove);
}
}
$order->checkMaxDiscount(Utitlity::checkRemainingBalance($employee));
$order->setTransactionId($paymentHandler->getTransactionId());
$order->setTkid($employee->getTkid());
if(Nova::isFreiePreiseingabeAboProduct($order)){
if($employee->getTuInformation() == NovaConstants::TU_INVIA){
$specialAboPriceCalculator->calculateBuegaFirmenAboPrice($employee);
} else {
$specialAboPriceCalculator->calculateOstwindFirmenAboPrice($employee);
}
$offer = $specialAboPriceCalculator->getOfferByClass($order->getKlasse());
if($offer instanceof Order){
$order->setBasePrice($offer->getBetrag());
//$order->setUpgradePrice($offer->getUpgradePrice());
}
$pricingModel = Utitlity::findPricingModel($employee);
if($pricingModel instanceof PricingModel){
$order->setPricingModelDiscount($pricingModel->getEmployeeDiscount());
}
}
$orderRepository->save($order, true);
$localeService->updateLocale($employee, $request);
return $this->render('travelcard/offer.html.twig', [
'employee' => $employee,
'priceInformation' => $priceInformation,
'paymentForm' => $paymentForm,
'responseObject' => $responseObject,
'validDateCorrect' => $validDateCorrect,
'order' => $order,
'swissPassService' => $swissPassService,
'invoiceData' => $paymentHandler->getInvoiceData(),
]);
} else {
return $this->redirectToRoute('app_travelcard');
}
}
}
#[Route('/update-offers', name: 'app_travelcard_update_offers')]
public function updateOffers(
GeschaeftspartnerService $geschaeftspartnerService,
VertragsService $vertragsService,
ContractService $contractService,
EmployeeRepository $employeeRepository,
SwissPassService $swissPassService,
PriceInformation $priceInformation,
DidokService $didokService,
Request $request
): Response
{
$swissPassService->setLanguage(DataMapper::getLanguageKeyFromLocale($request->getLocale()));
if(!$this->isSwissPassLoginPossible($swissPassService) && !$this->noLoginRequired()){
return $this->getSwissPassLoginTokenNotValidRoute($swissPassService);
} else {
$filter = [];
if(!empty($request->get('customerId'))){
$configuration = ['tkid' => $request->get('customerId')];
$parameters['customerId'] = $configuration['tkid'];
} else {
$configuration = ['tkid' => $swissPassService->getUserTkid()];
$parameters = [];
}
$novaUser = $geschaeftspartnerService->suchePartner($configuration);
if($novaUser instanceof Employee){
$employee = $employeeRepository->findOneBy(['tkid'=>$novaUser->getTkid()]);
if($employee instanceof Employee){
$employee = $didokService->updateEmployeeDidokInformation($employee);
if($request->get('product_search')) {
$productSearchOption = $request->get('product_search');
if(isset($productSearchOption['additionalZonen']) && !empty($productSearchOption['additionalZonen'])){
$employee->setAdditionalZones($productSearchOption['additionalZonen']);
} else {
$employee->setAdditionalZones(null);
}
if(isset($productSearchOption['zonenBuendels']) && !empty(trim($productSearchOption['zonenBuendels']))){
$zoneBundel = json_decode($productSearchOption['zonenBuendels'], true);
if(is_array($zoneBundel) && !empty($zoneBundel)){
$priceInformation->setZoneBundle($zoneBundel);
}
}
if(isset($productSearchOption['validDate']) && !empty(trim($productSearchOption['validDate']))){
$date = Nova::convertStringToDate($productSearchOption['validDate']);
if($date instanceof \DateTime){
$priceInformation->setValidDate($date);
$employee->setValidDate($date);
$employeeRepository->save($employee,true);
}
}
}
if(!$employee->isPaymentPossible()){
return $this->redirectToRoute('app_travelcard_not_authorized',['employee' => $employee->getId()]);
}
$priceInformation->setPriceInformation($employee);
if(!empty($filter) && !$priceInformation->isApiError()){
$priceInformation->setFilter($filter);
}
if($employee->getEnterprise()->isContractOption()){
$contracts = $vertragsService->leseVertragsInfos(['tkid' => $employee->getTkid()]);
if(!empty($contracts)){
$contracts = $contractService->getOnlyActiveContracts($contracts);
$contracts = $contractService->getOnlyOwnContracts($contracts,$employee->getTkid());
$contracts = $contractService->updateContractAmount($contracts);
$contracts = $contractService->updateContractDiscount($contracts,$priceInformation);
$productNumbers = $contractService->getProductNumbers($contracts);
if(!empty($productNumbers)){
$priceInformation->removeExcludeProducts($productNumbers);
}
}
} else {
$contracts = null;
}
$form = $this->createForm(ProductSearchType::class, null, [
'action' => $this->generateUrl('app_travelcard_update_offers', $parameters),
'method' => 'POST',
'attr'=> [
'novalidate' => true,
'id' => 'formOrderOptions',
'data-ajax' => 'true'
],
'zonenBuendels' => $priceInformation->getMoeglicheZonenBuendel(),
'zonen' => $priceInformation->getZonen(),
'validDate' => $employee->getValidDate()
]);
return $this->renderForm('travelcard/update_offers.html.twig', [
'priceInformation' => $priceInformation,
'contracts' => $contracts,
'predefinedOffer' => $priceInformation->getPredefinedOffer(),
'employee' => $employee,
'messages' => $priceInformation->getMeldungen(),
'form' => $form
]);
} else {
return $this->render('travelcard/errors/_offers.html.twig', [
]);
}
} else {
return $this->render('travelcard/errors/_offers.html.twig', [
'error' => $novaUser
]);
}
}
}
#[Route('/finish', name:'app_travelcard_finish')]
public function finish(
EmployeeRepository $employeeRepository,
OrderRepository $orderRepository,
ArchiveRepository $archiveRepository,
ResponseHandler $responseHandler,
Request $request,
SessionService $sessionService,
SwissPassService $swissPassService,
LocaleService $localeService,
): Response
{
$orders = null;
$employee = null;
$transactionId = '';
$responseObject = null;
$swissPassService->setLanguage(DataMapper::getLanguageKeyFromLocale($request->getLocale()));
if(!empty($request->query->get('datatransTrxId'))){
$transactionId = $request->query->get('datatransTrxId');
} elseif(!empty($request->query->get('transactionId'))) {
// No Datatrans Payment (100 Rabatt)
$transactionId = $request->query->get('transactionId');
$responseObject = new ResponseObject();
$responseObject->setTransactionId($request->query->get('transactionId'));
$responseObject->setSuccess(true);
}
if(!empty($transactionId)){
$tempArchive = $archiveRepository->findOneBy(['transactionId'=>$transactionId]);
if($tempArchive instanceof Archive){
$employee = $employeeRepository->findOneBy(['tkid'=>$tempArchive->getTkid()]);
} else {
$tempOrder = $orderRepository->findOneBy(['transactionId'=>$transactionId]);
if($tempOrder instanceof Order){
$employee = $employeeRepository->findOneBy(['tkid'=>$tempOrder->getTkid()]);
}
}
// Check if it is a Datatrans payment. If so, the TU configuration may need to be overwritten.
if(!$responseObject instanceof ResponseObject && $employee instanceof Employee){
$overrideConfiguration = $this->getOverrideConfiguration($employee->getTuInformation());
if($overrideConfiguration && isset($overrideConfiguration['datatrans'])){
$responseHandler->overrideApiHeaderOptions($overrideConfiguration['datatrans']);
}
$responseObject = $responseHandler->getResponse($transactionId);
}
if($responseObject instanceof ResponseObject && $responseObject->isSuccess()){
$orders = $archiveRepository->findBy(['transactionId'=>$transactionId]);
if(isset($orders[0]) && $orders[0] instanceof Archive){
$ordersToDelete = $orderRepository->findBy(['transactionId'=>$transactionId]);
foreach($ordersToDelete as $orderToDelete){
if($orderToDelete instanceof Order){
$orderRepository->remove($orderToDelete,1);
}
}
} else {
$orders = $orderRepository->findBy(['transactionId'=>$transactionId]);
if(isset($orders[0]) && $orders[0] instanceof Order){
$orders[0]->setLeistungsStatus($orders[0]::PAYED_NOTFINISHED);
$orderRepository->save($orders[0],true);
}
}
}
$sessionService->writeSession('employee',$employee);
}
// Expose the Employee for Enterprise/logo
if ($employee instanceof Employee) {
$request->attributes->set('employee', $employee);
$localeService->updateLocale($employee, $request);
}
return $this->render('travelcard/finish.html.twig', [
'orders' => $orders,
'employee' => $employee,
'datatransTrxId' => $transactionId,
'swissPassService' => $swissPassService,
]);
}
#[Route('/renew', name:'app_travelcard_renew')]
public function renew(Request $request, VertriebsService $vertriebsService, GeschaeftspartnerService $geschaeftspartnerService, EmployeeRepository $employeeRepository): Response
{
$queryParams = $request->query->all();
if(isset($queryParams['renewId']) && InputValidator::isUUID($queryParams['renewId'])){
$configuration['erneuerungsId'] = $queryParams['renewId'];
$result = $vertriebsService->sucheLeistung($configuration);
if(isset($result[0]) && $result[0] instanceof Order){
$order = $result[0];
if(InputValidator::tkidValidation($order->getTkid())){
$novaUser = $geschaeftspartnerService->suchePartner(['tkid'=>$order->getTkid()]);
$employee = $employeeRepository->findOneBy(['tkid'=>$novaUser->getTkid()]);
if(!$employee instanceof Employee){
return $this->redirectToRoute('app_travelcard_not_found');
}
if(!$employee->isPaymentPossible()){
if($employee->getApproved() <= $employee::INVITATION_SENT){
return $this->redirectToRoute('app_registration_employee',['enterprise' => $employee->getEnterprise()->getId(),'employee' => $employee->getId(),'_locale' => $employee->getLocale()]);
} else {
return $this->redirectToRoute('app_travelcard_not_authorized',['employee' => $employee->getId()]);
}
} else {
return $this->redirectToRoute('app_travelcard_show',['customerId' => $employee->getTkid()]);
}
}
}
}
return $this->redirectToRoute('app_travelcard');
}
#[Route('/notauthorized/{employee}', name: 'app_travelcard_not_authorized')]
public function notAuthorized(Request $request, Employee $employee,SwissPassService $swissPassService){
$swissPassService->setLanguage(DataMapper::getLanguageKeyFromLocale($request->getLocale()));
if(!$swissPassService->isTokenValid() && !$this->noLoginRequired()){
return $this->redirectToRoute('app_travelcard');
} else {
return $this->render('travelcard/not_authorized.html.twig', [
'employee' => $employee,
'swissPassService' => $swissPassService,
]);
}
}
#[Route('/nicht-gefunden', name: 'app_travelcard_not_found')]
public function notFound(Request $request,SwissPassService $swissPassService){
$swissPassService->setLanguage(DataMapper::getLanguageKeyFromLocale($request->getLocale()));
if(!$swissPassService->isTokenValid()){
return $this->redirectToRoute('app_travelcard');
} else {
return $this->render('travelcard/not_found.html.twig', [
'swissPassService' => $swissPassService
]);
}
}
}