diff --git a/trunk/app/Resources/views/default/components/sidebar.html.twig b/trunk/app/Resources/views/default/components/sidebar.html.twig index a333c7bd..8b2e6a31 100644 --- a/trunk/app/Resources/views/default/components/sidebar.html.twig +++ b/trunk/app/Resources/views/default/components/sidebar.html.twig @@ -13,9 +13,7 @@ {% elseif page is defined %} {# #HACK Dont display the search in FEWO #} - {% if page.title != 'Ferienwohnungen' %} {{ render(controller('AppBundle:Component:searchSidebarWidget', {page: page})) }} - {% endif %} {% endif %} {% else %} {{ search_sidebar_widget_block|raw }} diff --git a/trunk/app/Resources/views/default/pages/booking.html.twig b/trunk/app/Resources/views/default/pages/booking.html.twig index 064292a9..09bd9bd3 100644 --- a/trunk/app/Resources/views/default/pages/booking.html.twig +++ b/trunk/app/Resources/views/default/pages/booking.html.twig @@ -79,7 +79,7 @@ Reisezeitraum - {{ travel_date.start|date }} - {{ travel_date.end|date }} ({{ travel_date.name }}) + {{ travel_date.start|date }} - {{ travel_date.end|date }} ({{ travel_date.name }}) {{ form_label(form.departure, 'Abflugort') }} @@ -301,9 +301,13 @@ {% if departure.flightTime[travel_date.startWeekday] is defined %} {% endif %} diff --git a/trunk/app/Resources/views/default/pages/search.html.twig b/trunk/app/Resources/views/default/pages/search.html.twig index 7c73017d..8776958e 100644 --- a/trunk/app/Resources/views/default/pages/search.html.twig +++ b/trunk/app/Resources/views/default/pages/search.html.twig @@ -92,7 +92,7 @@ - Verfügbarkeit diff --git a/trunk/src/AppBundle/Controller/BookingController.php b/trunk/src/AppBundle/Controller/BookingController.php index 075dd29d..2e5b429c 100644 --- a/trunk/src/AppBundle/Controller/BookingController.php +++ b/trunk/src/AppBundle/Controller/BookingController.php @@ -624,9 +624,9 @@ class BookingController extends Controller //ROOMS if(count($tempRoomHTML) > 0){ foreach ($tempRoomHTML as $item) { - $label = ''.$item['count'].' x '.$item['label_first'].' ['.$item['label_last'].']'; + $label = ''.$item['count'].' x '.$item['label_first'].' ['.$item['label_last'].''; if($item['childCount'] > 0){ - $label .= ' [ + Kind: '.$item['price_child']; + $label .= '] [ + Kind: '.$item['price_child']; } $label .= ']'; $outHtmlSummary[] =[ @@ -641,7 +641,7 @@ class BookingController extends Controller foreach ($tempComfortHTML as $item) { $outHtmlSummary[] =[ 'value' => $item['value'], - 'label' => ''.$item['count'].' x '.$item['label_first'].' ['.$item['label_last'].' ]', + 'label' => ''.$item['count'].' x '.$item['label_first'].' ['.$item['label_last'].']', ]; } } @@ -651,7 +651,7 @@ class BookingController extends Controller foreach ($tempDepartureHTML as $item) { $outHtmlSummary[] =[ 'value' => $item['value'], - 'label' => ''.$item['count'].' x '.$item['label_first'].' ['.$item['label_last'].' ]', + 'label' => ''.$item['count'].' x '.$item['label_first'].' ['.$item['label_last'].']', ]; } } @@ -661,7 +661,7 @@ class BookingController extends Controller foreach ($tempDiscountHTML as $item) { $insuranceHtmlSummary[] =[ 'value' => $item['value'], - 'label' => ''.$item['count'].' x '.$item['label_first'].' ['.$item['label_last'].' ]', + 'label' => ''.$item['count'].' x '.$item['label_first'].' ['.$item['label_last'].']', ]; } } @@ -685,7 +685,7 @@ class BookingController extends Controller foreach ($tempInsuranceHTML as $item) { $insuranceHtmlSummary[] =[ 'value' => $item['value'], - 'label' => ''.$item['count'].' x '.$item['label_first'].' ['.$item['label_last'].' ]', + 'label' => ''.$item['count'].' x '.$item['label_first'].' ['.$item['label_last'].']', ]; } } diff --git a/trunk/src/AppBundle/Controller/CmsController.php b/trunk/src/AppBundle/Controller/CmsController.php index 352010dc..3bf3c0a9 100644 --- a/trunk/src/AppBundle/Controller/CmsController.php +++ b/trunk/src/AppBundle/Controller/CmsController.php @@ -8,13 +8,16 @@ namespace AppBundle\Controller; use AppBundle\Entity\Page; +use AppBundle\Entity\SearchFewoRequest; use AppBundle\Entity\SunstarTravelProgram; use AppBundle\Entity\FewoLodgingGroup; +use AppBundle\Form\SearchFewoType; use AppBundle\Form\TtSearchRequestType; use AppBundle\Listener\KernelControllerListener; use Doctrine\ORM\EntityManager; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use AppBundle\Util; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** @@ -50,7 +53,6 @@ class CmsController extends Controller public function overviewAction(Page $page) { - $settings = $page->getCmsSettings(); if (!is_array($settings)) { @@ -65,6 +67,73 @@ class CmsController extends Controller 'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR, 'page' => $page, 'lodgingGroups' => $lodgingGroups, + 'show_search_sidebar_widget' => false, + + ])); + } + + public function overviewCalenderAction(Request $request, Page $page) + { + + $settings = $page->getCmsSettings(); + if (!is_array($settings)) { + $settings = []; + } + + if (empty($request->get('from'))) { + $from = new \DateTime('+5 day'); + }else{ + $from = \DateTime::createFromFormat('d.m.Y', $request->get('from')); + + $now = new \DateTime(); + if ($from < $now) + { + $from = $now; + } + + $request->query->set('$from', $from); + } + + if (empty($request->get('to'))) { + $to = new \DateTime('+19 day'); + }else{ + $to = \DateTime::createFromFormat('d.m.Y', $request->get('to')); + if($to <= $from){ + $to = clone $from; + $to->modify('+1 week'); + } + $request->query->set('to', $to); + } + + $searchFewoRequest = new SearchFewoRequest(); + $searchFewoRequest->setFrom($from); + $searchFewoRequest->setTo($to); + $form = $this->createForm(SearchFewoType::class, $searchFewoRequest); + + $form->handleRequest($request); + + + + if ($request->getMethod() == 'POST') + { + $data = $form->getData(); + // $latestSeason = $this->em->getRepository('AppBundle:FewoLodging')->findLatestSeasonEndForLodging($lodging); + $r = $this->getDoctrine()->getRepository('AppBundle:FewoLodging')->getFewoLodingWithOutBookingDatesForTimePeriod($data->getFrom(), $data->getTo()); + count($r); + die(); + } + else + { + $r = []; + } + + + return $this->render('default/pages/cms/overviewCalender.html.twig', array_merge($settings, [ + 'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR, + 'page' => $page, + 'show_search_sidebar_widget' => false, + //'fewo_lodgings' => $r, + 'search_form' => $form->createView(), ])); } diff --git a/trunk/src/AppBundle/Controller/ComponentController.php b/trunk/src/AppBundle/Controller/ComponentController.php index 361b4dde..fba2af4d 100644 --- a/trunk/src/AppBundle/Controller/ComponentController.php +++ b/trunk/src/AppBundle/Controller/ComponentController.php @@ -4,6 +4,7 @@ namespace AppBundle\Controller; use AppBundle\Entity\Page; use AppBundle\Entity\TravelCountry; +use AppBundle\Form\SearchFewoType; use AppBundle\Form\SearchRequestType; use AppBundle\Util; use Doctrine\ORM\EntityManager; @@ -114,6 +115,15 @@ class ComponentController extends Controller ]); } + /* public function searchFewoCalenderAction(Page $page) + { + return $this->render('default/components/searchFewoWidget.html.twig', [ + 'search_form' => $this->createForm(SearchFewoType::class, [])->createView() + ]); + }*/ + + + public function travelGuideSidebarWidgetAction(TravelCountry $country) { $repo = $this->getEntityManager()->getRepository('AppBundle:Page'); diff --git a/trunk/src/AppBundle/Entity/FewoLodgingRepository.php b/trunk/src/AppBundle/Entity/FewoLodgingRepository.php index d9f455a2..085280d6 100644 --- a/trunk/src/AppBundle/Entity/FewoLodgingRepository.php +++ b/trunk/src/AppBundle/Entity/FewoLodgingRepository.php @@ -1,6 +1,8 @@ getQuery()->getOneOrNullResult(); } + + public function getFewoLodingWithOutBookingDatesForTimePeriod($startDate, $endDate) + { + $startDateStr = $startDate->format('Y-m-d'); + $endDateStr = $endDate->format('Y-m-d'); + + $qb = $this->getEntityManager()->createQueryBuilder() + ->from('AppBundle:FewoLodging', 'fl', 'fl.id') + ->addSelect('fl'); + $qb->innerJoin('fl.reservations', 'fr'); + // $qb->where($qb->expr()->eq('fl.lodging', $lodging->getId()));*/ + $qb->where("('$startDateStr.' BETWEEN fr.from_date AND fr.to_date)"); + + $all = $qb->getQuery()->getResult(); + + foreach ($all as $a){ + var_dump($a->getName()); + echo "
"; + } + die(); + /* return $this->createQueryBuilder('tp') + ->innerJoin('tp.page', 'page') + ->addSelect('page') + ->leftJoin('tp.countries', 'country') + ->addSelect('country') + ->leftJoin('country.destinations', 'destination') + ->addSelect('destination') + ->leftJoin('tp.options', 'option') + ->addSelect('option') + ->leftJoin('tp.images', 'image', Expr\Join::WITH, 'image.type = 1') + ->addSelect('image') + ->where('tp.status = 1') + ->andWhere('tp.programType = '. TravelProgram::ORGANIZED_PROGRAM_TYPE) + ->getQuery() + ->execute() + ; + + + $qb = $this->createQueryBuilder(); + + $qb->select('fl'); + $qb->from('AppBundle:FewoLodging', 'fl'); + //$qb->innerJoin('fl.reservations', 'fr'); + // $qb->where($qb->expr()->eq('fl.lodging', $lodging->getId()));*/ + + + + // ->where('fl.status > 0'); + + // Limit time period for seasons and travel dates + // $qb->addSelect('fr'); + + // $qb->where("('$startDateStr' BETWEEN fr.from_date AND fr.to_date)"); + + /* $qb->where("((fr.from_date >= '$startDateStr' AND fr.to_date <= '$endDateStr') OR". + " (p.isSeason = 1 AND d.endDate >= '$startDateStr' AND". + " DATE_ADD(d.startDate, tp.programDuration, 'DAY') <= '$endDateStr' AND p.status > 0))"); + */ + + // Prices + // Instead of a single join to prices we add one join per price type. This reduces the execution time by + // 150ms on the development system + /* $priceTypes = $this->getEntityManager()->getRepository('AppBundle:TravelPeriodPriceType')->findAll(); + foreach ($priceTypes as $priceType) + { + $priceTypeKey = 'price_'. $priceType->getId(); + $qb->leftJoin('p.prices', $priceTypeKey, Expr\Join::WITH, + $priceTypeKey .'.priceType = '. $priceType->getId(), $priceTypeKey .'.priceTypeId'); + $qb->addSelect($priceTypeKey); + } + $qb->leftJoin('p.discounts', 'discount'); + $qb->addSelect('discount'); + + $qb->leftJoin('p.departures', 'p_dep', Expr\Join::WITH, 'tp.programType = '. + TravelProgram::MEDIATED_PROGRAM_TYPE); + $qb->addSelect('p_dep'); + + // Destinations + if (!empty($destinationIds) && is_array($destinationIds)) + { + //$qb->innerJoin('AppBundle:TravelProgramCountry', 'tpc', Expr\Join::WITH, + // 'tpc.program = tp AND IDENTITY(tpc.country) IN ('. implode(', ', $destinationIds) .')'); + $qb->innerJoin('tp.countries', 'tc', Expr\Join::WITH, + 'tc.id IN ('. implode(', ', $destinationIds) .')'); + if ($combi) + { + //$qb->having('COUNT(DISTINCT tpc.country) = '. count($destinationIds)); + $qb->having('COUNT(DISTINCT tc) = '. count($destinationIds)); + } + } + $qb->groupBy('p.id, p_dep.id, d.id'); + + // Travel class + $qb->innerJoin('p.class', 'cls', Expr\Join::WITH, 'cls.standard = 1'); + + // Image + $qb->leftJoin('tp.images', 'tp_image', Expr\Join::WITH, 'tp_image.type = 2') + ->addSelect('tp_image'); + + // Sort travel programs + $qb->addSelect('COALESCE(tp.position, 0) as HIDDEN position_sort_key'); + $qb->orderBy('position_sort_key'); + //$qb->addOrderBy('LENGTH(tp.title)'); // Emulate natural sort + $qb->addOrderBy('tp.title'); + $qb->addOrderBy('tp.id'); + // Sort: Real travel dates have higher priority than virtual travel dates. Sort travel programs + $qb->addOrderBy('p.isSeason, p.id'); +*/ + /** @var TravelProgram[]|array $travelPrograms */ + /* $travelPrograms = $qb->getQuery()->getResult(); + + if (empty($travelPrograms)) + { + return $travelPrograms; + } + + // Collect arrival point IDs for non mediated travel programs + $isUsedArrivalPointById = []; + foreach ($travelPrograms as $travelProgram) + { + $isUsedTravelProgramById[$travelProgram->getId()] = true; + if (!$travelProgram->getIsMediated()) + { + $isUsedArrivalPointById[$travelProgram->getTravelArrivalPoint()->getId()] = true; + } + } + $usedArrivalPointIds = array_keys($isUsedArrivalPointById); + + // Find flight periods and related departures + $flightPeriods = empty($isUsedArrivalPointById) ? [] + : $this->getEntityManager()->getRepository('AppBundle:FlightPeriod') + ->getIndexedFlightPeriodsForTimePeriod($startDate, $endDate, $usedArrivalPointIds); + + // Find default departures and classify by-program or by-arrival-point + // We could've simply left joined them to get an equal result. But we're reducing the number of rows returned + // in the first travel program query above drastically with this solution. This doesn't hurt performance. + // Of course, we have to link departures of travel programs manually later. + $defDepsByArrivalPointId = []; + $qb = $this->getEntityManager()->createQueryBuilder() + ->from('AppBundle:TravelDeparturePoint', 'dep') + ->addSelect('dep') + ->where($qb->expr()->in('IDENTITY(dep.program)', array_keys($travelPrograms))); + if (!empty($isUsedArrivalPointById)) + { + $qb->orWhere($qb->expr()->in('IDENTITY(dep.travelArrivalPoint)', $usedArrivalPointIds)); + } + /** @var TravelDeparturePoint[]|array $defaultDepartures */ + /* $defaultDepartures = $qb->getQuery()->execute(); + foreach ($defaultDepartures as $defaultDeparture) + { + if ($defaultDeparture->getProgram()) + { + $travelProgram = $travelPrograms[$defaultDeparture->getProgram()->getId()]; + if ($travelProgram->getDepartures() instanceof PersistentCollection) + { + Util::reAttachRelatedCollection($travelProgram, 'departures', $travelProgram->getDepartures()->unwrap()); + } + $travelProgram->addDeparture($defaultDeparture); + } + elseif ($defaultDeparture->getTravelArrivalPoint()) + { + if (!isset($defDepsByArrivalPointId[$defaultDeparture->getTravelArrivalPoint()->getId()])) + { + $defDepsByArrivalPointId[$defaultDeparture->getTravelArrivalPoint()->getId()] = []; + } + $defDepsByArrivalPointId[$defaultDeparture->getTravelArrivalPoint()->getId()][] = $defaultDeparture; + } + } + + foreach ($travelPrograms as $k => $travelProgram) + { + $flightPeriod = null; + if (!$travelProgram->getIsMediated()) + { + $arrivalPointId = $travelProgram->getTravelArrivalPoint()->getId(); + // Manually link separately fetched default departures + $travelProgram->getTravelArrivalPoint()->__setDepartures( + isset($defDepsByArrivalPointId[$arrivalPointId]) + ? $defDepsByArrivalPointId[$arrivalPointId] + : [] + ); + } + + $this->addTravelDatesToProgram($travelProgram, $travelProgram->getPeriods(), $flightPeriods, + $startDate, $endDate); + + if (!$travelProgram->hasTravelDates()) + { + unset($travelPrograms[$k]); + } + }*/ + + return $qb->getQuery()->getResult(); + } + } diff --git a/trunk/src/AppBundle/Export/SternToursCrmExporter.php b/trunk/src/AppBundle/Export/SternToursCrmExporter.php index 9a9b2a6e..50c4e421 100644 --- a/trunk/src/AppBundle/Export/SternToursCrmExporter.php +++ b/trunk/src/AppBundle/Export/SternToursCrmExporter.php @@ -12,7 +12,7 @@ use Monolog\Logger; abstract class SternToursCrmExporter { - const API_URL = 'https://www.cms.stern-tours.net/api'; + const API_URL = 'https://cms.stern-tours.net/api'; //const API_URL = 'http://cms-stern-tours.local/api'; const API_KEY = 'f6077389c9ce710e554763a5de02c8ec'; const API_USER_ID = 15; // 'apiuser' diff --git a/trunk/src/AppBundle/Listener/KernelControllerListener.php b/trunk/src/AppBundle/Listener/KernelControllerListener.php index 038c7c11..e632e8a2 100644 --- a/trunk/src/AppBundle/Listener/KernelControllerListener.php +++ b/trunk/src/AppBundle/Listener/KernelControllerListener.php @@ -63,9 +63,8 @@ class KernelControllerListener $pathArray = explode('/', $path); $i = 0; - while (!empty($pathArray)) - { - $restOfPath = '/'. implode('/', $pathArray); + while (!empty($pathArray)) { + $restOfPath = '/' . implode('/', $pathArray); $slug = array_shift($pathArray); @@ -75,8 +74,7 @@ class KernelControllerListener $qb->setParameter('slug', $slug); if ($node != null) - { - $qb->andWhere($qb->expr()->between('p.lft', $node->getLft(), $node->getRgt())); + {$qb->andWhere($qb->expr()->between('p.lft', $node->getLft(), $node->getRgt())); } $qb->setMaxResults(1); $childNode = $qb->getQuery()->getOneOrNullResult(); @@ -163,6 +161,7 @@ class KernelControllerListener { $handler = $node->getTemplate() ? ucfirst($node->getTemplate()) : 'Default'; + $request->attributes->set('_controller', 'AppBundle:Cms:'. $handler); if ($node->getTemplate()) { diff --git a/trunk/src/AppBundle/Resources/public/css/booking.css b/trunk/src/AppBundle/Resources/public/css/booking.css index e9f8d697..f7c49ba5 100644 --- a/trunk/src/AppBundle/Resources/public/css/booking.css +++ b/trunk/src/AppBundle/Resources/public/css/booking.css @@ -20,3 +20,75 @@ content: " *"; } + +.radio label { + display: inline-block; + vertical-align: middle; + position: relative; + padding-left: 5px; + white-space: normal; +} + + +.checkbox label { + display: inline-block; + vertical-align: middle; + position: relative; + padding-left: 5px; + white-space: normal; +} + + +/*@media (max-width: 420px) { + .radio label { + width: 360px; + } + .checkbox label { + width: 360px; + } +} + +@media (max-width: 375px) { + .radio label { + width: 310px; + } + .checkbox label { + width: 310px; + } +} + +@media (max-width: 340px) { + .radio label { + width: 260px; + } + .checkbox label { + width: 260px; + } +}*/ + +.bootstrap-select.btn-group .dropdown-toggle .filter-option { + white-space: normal; +} + + +@media (max-width: 786px) { + .booking_form .table > tbody > tr > td { + width: 100%; + } + .booking_form .table.first-table .bootstrap-select:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) { + width: 100%; + } + .st-traveller-index { + white-space: normal; + height: auto !important; + } +} +@media (max-width: 320px) { + .st-traveller-index { + white-space: normal; + height: auto !important; + } + .booking_form .table.first-table .bootstrap-select:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) { + width: 100%; + } +} \ No newline at end of file diff --git a/trunk/src/AppBundle/Resources/public/css/custom.css b/trunk/src/AppBundle/Resources/public/css/custom.css index e7e20dde..2be11727 100644 --- a/trunk/src/AppBundle/Resources/public/css/custom.css +++ b/trunk/src/AppBundle/Resources/public/css/custom.css @@ -4206,6 +4206,7 @@ a, vertical-align: middle; position: relative; padding-left: 5px; + white-space: normal; } .radio label::before { content: "";