WIP on master: 6046eef ttSearch iframe 5500px

This commit is contained in:
Kevin Adametz 2018-09-03 13:34:03 +02:00
commit 9a3eb0f7fd
11 changed files with 376 additions and 20 deletions

View file

@ -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 }}

View file

@ -79,7 +79,7 @@
</tr>
<tr>
<td>Reisezeitraum</td>
<td>{{ travel_date.start|date }} - {{ travel_date.end|date }} ({{ travel_date.name }})</td>
<td style="">{{ travel_date.start|date }} - {{ travel_date.end|date }} <br class="hidden visible-xs">({{ travel_date.name }})</td>
</tr>
<tr>
<td>{{ form_label(form.departure, 'Abflugort') }}</td>
@ -301,9 +301,13 @@
{% if departure.flightTime[travel_date.startWeekday] is defined %}
<div class="flight_times_ele" id="flight_time_{{ departure.id }}" style="display: none;">
<h3>Von {{ departure.name }}</h3>
{# travel_date.end|date #}
{# travel_date.end|date #}
{{ departure.flightTime[travel_date.startWeekday] }}
<ul class="c1">
{% for flightTime in departure.flightTime[travel_date.startWeekday]|split('\n') %}
{% if flightTime != "" %}
<li>{{ flightTime|raw }}</li>
{% endif %}
{% endfor %}
</ul>
</div>
{% endif %}

View file

@ -92,7 +92,7 @@
</td>
<td data-title="Verfügbarkeit">
<img src="/images/icons/available-{{ travel_date.effectiveStatus }}.png"
<img src="/images/icons/available-{{ travel_date.effectiveStatus }}.png" style="height: 24px; width: 24px;vertical-align:middle"
alt="Verfügbarkeit">
</td>

View file

@ -624,9 +624,9 @@ class BookingController extends Controller
//ROOMS
if(count($tempRoomHTML) > 0){
foreach ($tempRoomHTML as $item) {
$label = '<strong>'.$item['count'].'</strong> x '.$item['label_first'].'<strong> ['.$item['label_last'].']</strong>';
$label = '<strong>'.$item['count'].'</strong> x '.$item['label_first'].'<strong> ['.$item['label_last'].'</strong>';
if($item['childCount'] > 0){
$label .= ' <strong>[ + Kind: '.$item['price_child'];
$label .= '] <strong>[ + Kind: '.$item['price_child'];
}
$label .= ']</strong>';
$outHtmlSummary[] =[
@ -641,7 +641,7 @@ class BookingController extends Controller
foreach ($tempComfortHTML as $item) {
$outHtmlSummary[] =[
'value' => $item['value'],
'label' => '<strong>'.$item['count'].'</strong> x '.$item['label_first'].'<strong> ['.$item['label_last'].' ]</strong>',
'label' => '<strong>'.$item['count'].'</strong> x '.$item['label_first'].'<strong> ['.$item['label_last'].']</strong>',
];
}
}
@ -651,7 +651,7 @@ class BookingController extends Controller
foreach ($tempDepartureHTML as $item) {
$outHtmlSummary[] =[
'value' => $item['value'],
'label' => '<strong>'.$item['count'].'</strong> x '.$item['label_first'].'<strong> ['.$item['label_last'].' ]</strong>',
'label' => '<strong>'.$item['count'].'</strong> x '.$item['label_first'].'<strong> ['.$item['label_last'].']</strong>',
];
}
}
@ -661,7 +661,7 @@ class BookingController extends Controller
foreach ($tempDiscountHTML as $item) {
$insuranceHtmlSummary[] =[
'value' => $item['value'],
'label' => '<strong>'.$item['count'].'</strong> x '.$item['label_first'].'<strong> ['.$item['label_last'].' ]</strong>',
'label' => '<strong>'.$item['count'].'</strong> x '.$item['label_first'].'<strong> ['.$item['label_last'].']</strong>',
];
}
}
@ -685,7 +685,7 @@ class BookingController extends Controller
foreach ($tempInsuranceHTML as $item) {
$insuranceHtmlSummary[] =[
'value' => $item['value'],
'label' => '<strong>'.$item['count'].'</strong> x '.$item['label_first'].'<strong> ['.$item['label_last'].' ]</strong>',
'label' => '<strong>'.$item['count'].'</strong> x '.$item['label_first'].'<strong> ['.$item['label_last'].']</strong>',
];
}
}

View file

@ -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(),
]));
}

View file

@ -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');

View file

@ -1,6 +1,8 @@
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Query\Expr\OrderBy;
/**
@ -11,6 +13,12 @@ use Doctrine\ORM\Query\Expr\OrderBy;
*/
class FewoLodgingRepository extends \Doctrine\ORM\EntityRepository
{
function __construct(EntityManager $em, ClassMetadata $class)
{
parent::__construct($em, $class);
}
/**
* @param FewoLodging $lodging
*
@ -28,4 +36,199 @@ class FewoLodgingRepository extends \Doctrine\ORM\EntityRepository
return $qb->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 "<br>";
}
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();
}
}

View file

@ -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'

View file

@ -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())
{

View file

@ -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%;
}
}

View file

@ -4206,6 +4206,7 @@ a,
vertical-align: middle;
position: relative;
padding-left: 5px;
white-space: normal;
}
.radio label::before {
content: "";