diff --git a/app/Resources/views/base.html.twig b/app/Resources/views/base.html.twig index 62a0e3ed..55d8ef21 100644 --- a/app/Resources/views/base.html.twig +++ b/app/Resources/views/base.html.twig @@ -52,9 +52,9 @@ - + - + {% block canonical_tag %} @@ -88,6 +88,17 @@ gtag('config', 'G-Y1Y779PDME'); + {% block stylesheets %} {% endblock stylesheets %} @@ -99,7 +110,12 @@
@@ -116,7 +132,7 @@
- Top Kundenservice + Top Kundenservice
  • Spezialist für Kulturreisen
  • @@ -152,7 +168,9 @@
@@ -184,14 +195,14 @@ {{ render(controller('AppBundle:Component:footer')) }} - +
{% embed 'default/components/embed/modal.html.twig' with {id: 'default'} %}{% endembed %} - + {% block javascripts %} @@ -206,7 +217,6 @@ }); }); - {% endblock javascripts %} diff --git a/app/Resources/views/default/components/footer.html.twig b/app/Resources/views/default/components/footer.html.twig index ff3a4911..e785b190 100644 --- a/app/Resources/views/default/components/footer.html.twig +++ b/app/Resources/views/default/components/footer.html.twig @@ -1,95 +1,106 @@ -
-
- -
- -
- -

030 - 700 94 100

-

{% if(content.available.phone.active) %} - erreichbar - {% else %} - erreichbar - {% endif %} - {{ content.available.phone.content }}

-
- -
- -

stern@sterntours.de

-

schreiben Sie uns jederzeit

-
- -
- -

Kontaktformular

-

oder nutzen Sie einfach unser:

-
- -
- -

Über uns

-

Erfahren Sie mehr über unser Reisebüro.

-
- -
- -
-
- - -
-
-
-
-

STERN TOURS © {{ 'now'|date('Y') }}

-
- - -
-
-
\ No newline at end of file +
+
+ +
+ +
+ +

030 - 700 94 100

+

{% if(content.available.phone.active) %} + erreichbar + {% else %} + erreichbar + {% endif %} + {{ content.available.phone.content }}

+
+ +
+ +

stern@sterntours.de

+

schreiben Sie uns jederzeit

+
+ +
+ +

Kontaktformular

+

oder nutzen Sie einfach unser:

+
+ +
+ +

Über uns

+

Erfahren Sie mehr über unser Reisebüro.

+
+ +
+ +
+
+ + +
+
+
+
+

STERN TOURS © {{ 'now'|date('Y') }}

+
+ + +
+
+
+ + + + +
+ \ No newline at end of file diff --git a/app/Resources/views/default/components/header.html.twig b/app/Resources/views/default/components/header.html.twig index 7d049414..5a06c86c 100644 --- a/app/Resources/views/default/components/header.html.twig +++ b/app/Resources/views/default/components/header.html.twig @@ -187,7 +187,7 @@ {# @var nav_page \AppBundle\Entity\Page #} diff --git a/app/Resources/views/default/components/home/dev_slider.html.twig b/app/Resources/views/default/components/home/dev_slider.html.twig index 0440e26c..73a5392b 100644 --- a/app/Resources/views/default/components/home/dev_slider.html.twig +++ b/app/Resources/views/default/components/home/dev_slider.html.twig @@ -1,5 +1,71 @@ {% form_theme search_form 'default/form/theme.html.twig' %} + +
@@ -22,12 +88,48 @@
diff --git a/app/Resources/views/default/components/multiPageBoxCarousel.html.twig b/app/Resources/views/default/components/multiPageBoxCarousel.html.twig index e14a4ae1..57700f88 100644 --- a/app/Resources/views/default/components/multiPageBoxCarousel.html.twig +++ b/app/Resources/views/default/components/multiPageBoxCarousel.html.twig @@ -1,32 +1,42 @@ - -

Unsere beliebtesten Kulturreisen

+ {% set homepage_offer_heading = homepage_offer_title|default('beliebtesten Kulturreisen') %} + {% if '%count%' in homepage_offer_heading %} +

{{ homepage_offer_heading|replace({'%count%': homepage_offer_pages|length}) }}

+ {% elseif homepage_offer_heading|slice(0, 6) == 'Unsere' %} +

{{ homepage_offer_heading }}

+ {% else %} +

Unsere {{ homepage_offer_pages|length }} {{ homepage_offer_heading|replace({'Beliebte': 'beliebtesten', 'beliebte': 'beliebtesten'}) }}

+ {% endif %}
{% if homepage_offer_pages is not empty %} - {% include 'default/components/multiPageBoxCarousel.html.twig' with {pages: homepage_offer_pages} %} + {% include 'default/components/multiPageBoxCarousel.html.twig' with { + pages: homepage_offer_pages, + show_item_counter: true, + new_page_ids: homepage_offer_new_page_ids|default([]) + } %} {% else %}

Aktuell konnten keine kuratierten Reiseangebote geladen werden.

{% endif %} @@ -64,28 +135,54 @@
-
+

Lieber näher zuhause? Ferienwohnungen auf Usedom

- Neben unseren Kulturreisen bieten wir acht Ferienwohnungen in zwei Häusern auf Usedom. + Neben unseren Kulturreisen bieten wir 8 Ferienwohnungen in zwei Häusern auf Usedom. Ideal für alle, die kurzfristig, individuell und nah an der Ostsee Urlaub machen möchten.

Ferienwohnungen ansehen +

-
-

- Der Block macht Usedom als zweites Standbein sichtbar, ohne die Kulturreisen zu verdrängen. - Bilder und Reihenfolge können nach Sichtung des vorhandenen Bildpools noch feinjustiert werden. -

+
+
+ Ferienwohnungen auf Usedom +
- +
+
+ {% if fewo_lodgings is not empty %} -
+ {% endif %} @@ -104,16 +201,100 @@

STERN TOURS - Ihr Kulturreise-Spezialist aus Berlin

Herzlich willkommen bei STERN TOURS, Ihrem Reiseveranstalter für ausgewählte Kulturreisen. - In der aktuellen Startseitenfassung stehen besonders die Reiseziele im Vordergrund, die - derzeit gut planbar und verkaufbar sind: Ägypten, Marokko, Usbekistan und Oman. + Seit 1998 beraten wir Reisende zu den historischen Schätzen des Orients, Nordafrikas und + Zentralasiens. In der aktuellen Startseitenfassung stehen besonders die Reiseziele im + Vordergrund, die derzeit gut planbar und verkaufbar sind: Ägypten, Marokko, Usbekistan + und Oman. Bei Destinationen mit angespannter Lage kommunizieren wir bewusst transparent + und beraten persönlich, statt Reisen unkritisch in den Vordergrund zu stellen.

-

Kulturreisen mit Erfahrung und persönlicher Beratung

+
+

Ägypten - Land der Pyramiden und Pharaonen

- Seit 1998 beraten wir Reisende zu Kulturreisen in den Orient und angrenzende Regionen. - Die neue Frontseite soll Orientierung geben, buchbare Reisen sichtbar machen und zugleich - verantwortungsvoll mit Destinationen umgehen, bei denen die Lage eine vorsichtigere - Kommunikation erfordert. + Ägypten bleibt eines der klassischen STERN TOURS Ziele: Pyramiden, Luxor, das Tal der Könige, + Kairo und der Nil verbinden große Geschichte mit gut planbaren Kulturreisen. Unsere Programme + führen zu den wichtigsten Stätten des alten Ägypten und lassen sich je nach Reiseverlauf mit + einer Nilkreuzfahrt oder erholsamen Tagen am Roten Meer verbinden. + Hier finden Sie unsere Ägypten Rundreisen.

+ +

Marokko - Königsstädte, Wüste und lebendige Kultur

+

+ Marokko verbindet orientalische Atmosphäre mit einer guten Erreichbarkeit: Marrakesch, Fès, + Rabat und Meknès stehen für Königsstädte, Handwerk, Märkte und eindrucksvolle Architektur. + Ausflüge in den Atlas und in die Wüstenlandschaften machen Marokko zu einem vielseitigen Ziel + für Kulturreisende, die derzeit eine gut planbare Alternative im nordafrikanischen Raum suchen. + Hier finden Sie unsere Marokko Rundreisen. +

+ +

Usbekistan - entlang der Seidenstraße nach Samarkand

+

+ Usbekistan ist ein junges Reiseland mit einer sehr alten Kultur. Samarkand, Buchara und Chiwa + stehen für die Seidenstraße, prachtvolle Medresen, türkisfarbene Kuppeln und Oasenstädte, die + bis heute von Handel, Handwerk und Geschichte erzählen. Für kulturinteressierte Gäste ist + Usbekistan aktuell eines der spannendsten und zugleich gut vermittelbaren Ziele im Programm. + Hier finden Sie unsere Usbekistan Rundreisen. +

+ +

Oman - Wüstenschlösser, Naturschauspiele und Badestrände

+

+ Der Oman bietet Wüsten, Gebirge, Oasen, Küsten und eine wohltuend ruhige Form orientalischer + Gastfreundschaft. Maskat, Nizwa, traditionelle Souks, Forts und Fahrten durch eindrucksvolle + Landschaften machen das Sultanat zu einem hochwertigen Kulturreiseziel. Wer eine planbare Reise + mit Natur, Geschichte und Erholung verbinden möchte, findet im Oman eine starke Alternative. + Hier finden Sie unsere Oman Rundreisen. +

+ +

Türkei - Kultur zwischen Europa und Asien

+

+ Die Türkei bietet mit Istanbul, Ephesus, Kappadokien und vielen antiken Stätten ein großes + kulturelles Spektrum. Auf der aktuellen Startseite bleibt sie bewusst im Hintergrund, da der + Fokus auf den derzeit wichtigsten STERN TOURS Zielen liegt. + Hier finden Sie unsere Türkei Rundreisen. +

+ +

Jordanien - Petra, Wadi Rum und persönliche Beratung

+
+ Aktuelle Einordnung: + Reisen nach Jordanien sind grundsätzlich weiterhin möglich. Aufgrund der angespannten Lage in + der Region empfehlen wir eine persönliche Beratung und eine sorgfältige Prüfung von Reisezeitraum + und Verfügbarkeit. +
+

+ Jordanien bleibt kulturell eines der eindrucksvollsten Ziele der Region: die Felsenstadt Petra, + Wadi Rum, Amman, Jerash und das Tote Meer prägen viele Reiseverläufe. Auf der Startseite wird + Jordanien derzeit bewusst weniger prominent beworben; Interessierte beraten wir gern individuell. + Hier finden Sie unsere Jordanien Rundreisen. +

+ +

Israel - große Religionsgeschichte mit aktueller Lageprüfung

+
+ Aktuelle Einordnung: + Die Lage in der Region ist angespannt. Wir empfehlen, geplante Reisen nach Israel sorgfältig zu + prüfen und sich vor einer Buchung persönlich beraten zu lassen. +
+

+ Israel ist ein Land von herausragender religiöser und kultureller Bedeutung: Jerusalem, Galiläa, + das Tote Meer, Haifa und Akko stehen für Geschichte, Begegnung und Vielfalt. Aufgrund der + aktuellen Situation tritt Israel auf der Startseite nicht in den Vordergrund; Anfragen mit + längerem Vorlauf behandeln wir individuell und verantwortungsvoll. + Hier finden Sie unsere Israel Rundreisen. +

+ +

Iran - Kulturschätze Persiens, derzeit nicht im Vordergrund

+
+ Aktuelle Einordnung: + Aufgrund der aktuellen Lage sind Iran-Reisen derzeit nicht als aktive Buchungsempfehlung auf der + Startseite platziert. Interessierte können sich vormerken lassen und werden informiert, sobald + Reisen wieder verantwortungsvoll planbar sind. +
+

+ Der Iran blickt auf Jahrtausende Kulturgeschichte zurück: Isfahan, Schiras, Yazd und Persepolis + gehören zu den großen Namen persischer Geschichte. Diese Faszination bleibt bestehen, wird aber + aktuell bewusst nicht verkaufsstark beworben. Der Schwerpunkt liegt auf transparenter Information + und späterer Wiederaufnahme, sobald die Rahmenbedingungen es erlauben. + Hier finden Sie unsere Iran Rundreisen. +

+
diff --git a/src/AppBundle/Controller/BookingController.php b/src/AppBundle/Controller/BookingController.php index d1fd73a3..500ec679 100644 --- a/src/AppBundle/Controller/BookingController.php +++ b/src/AppBundle/Controller/BookingController.php @@ -1,1090 +1,1052 @@ - - * @date 12/08/2016 - */ - -namespace AppBundle\Controller; - - -use AppBundle\Entity\BookingRequest; -use AppBundle\Entity\BreadcrumbEntry; -use AppBundle\Entity\Page; -use AppBundle\Entity\TravelDate; -use AppBundle\Entity\Traveler; -use AppBundle\Entity\TravelPeriodPrice; -use AppBundle\Entity\TravelPeriodPriceType; -use AppBundle\Form\BookingRequestType; -use AppBundle\Util; -use Doctrine\ORM\Query; -use Symfony\Bundle\FrameworkBundle\Controller\Controller; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -class BookingController extends Controller -{ - /** @var TravelPeriodPriceType[] $priceTypeById */ - private $priceTypeById; - - /** - * The routing for this action is entirely controlled by KernelControllerListener! - * - * @param Page $travelProgramPage - * @param Request $request - * @param $action - * - * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response - * @throws \Exception - */ - - private function getErrorMessages(\Symfony\Component\Form\Form $form) { - $errors = array(); - - foreach ($form->getErrors() as $key => $error) { - if ($form->isRoot()) { - $errors['#'][] = $error->getMessage(); - } else { - $errors[] = $error->getMessage(); - } - } - - foreach ($form->all() as $child) { - if (!$child->isValid()) { - $errors[$child->getName()] = $this->getErrorMessages($child); - } - } - - return $errors; - } - public function getEntityManager() - { - return $this->getDoctrine()->getManager(); - } - - public function indexAction(Page $travelProgramPage, $action, Request $request) - { - - if($action == '/show_nationality_country_text') - { - - $ret = ""; - $nationality_id = $request->request->get('nationality_id'); - $country_ids = $request->request->get('country_ids'); - - - foreach ($country_ids as $country_id){ - - $country = $this->getEntityManager()->getRepository('AppBundle:TravelCountry')->findOneBy(['id' => $country_id]); - - $req = $this->getDoctrine()->getRepository('AppBundle:TravelNationalityRequirement')->findOneByCountryAndNationality($country_id, $nationality_id); - - - if($req && $country){ - - $setC = !empty($country->getName()) ? $country->getName() : "Einreiseland"; - $setT = !empty($req->getText()) ? $req->getText() : "Die Einreisebestimmungen erhalten Sie nach der Bestätigung Ihrer Anfrage."; - $ret .= "

".$setC."

"; - $ret .= "

".$setT."

"; - $ret .= "
"; - } - } - echo $ret; - die(); - } - - $travelProgram = $travelProgramPage->getTravelProgram(); - if (!$request->query->has('nr')) - { - return $this->redirect($travelProgramPage->getUrlPath()); - } - $this->getDoctrine()->getRepository('AppBundle:TravelPeriod')->getTrueTravelPeriods($travelProgram); - - $this->priceTypeById = $this->getDoctrine()->getRepository('AppBundle:TravelPeriodPriceType')->findAllIndexedById(); - - // #TODO Consider changing key of travel dates - foreach ($travelProgram->getTravelDates() as $curTravelDate) - { - if($curTravelDate->getStatus() != 0){ - if ($curTravelDate->getName() == $request->query->get('nr')) - { - $travelDate = $curTravelDate; - break; - } - } - } - - if (!isset($travelDate)) - { - throw $this->createNotFoundException(); - } - $now = new \DateTime(); - if ($travelDate->getStart() <= $now) - { - throw $this->createNotFoundException(); - } - - /**/ - $nationalities = $this->getDoctrine() - ->getRepository('AppBundle:TravelNationality') - ->createQueryBuilder('n') - ->where('n.active = true') - ->getQuery()->getResult(Query::HYDRATE_ARRAY); - - /** @var BookingRequest $bookingRequest */ - $bookingRequest = new BookingRequest(); - if ($request->getMethod() != 'POST') - { - $bookingRequest->setRoomCount(0); - } - $form = $this->createForm(BookingRequestType::class, $bookingRequest, [ - 'travel_date' => $travelDate, - 'travel_program' => $travelProgram, - 'nationalities' => $nationalities - ]); - if ($request->getMethod() == 'POST') - { - $form->handleRequest($request); - $bookingRequest = $form->getData(); - } - - $htmlSummary = []; - $bookingPriceInfo = []; - $totalPrice = $this->calculatePrice($travelDate, $bookingRequest, $travelProgram->getCategory()->getId(), $travelProgram->getDepositPercent(), $htmlSummary, $bookingPriceInfo); - - if ($action == '/buchen') - { - $breadcrumbEntries = Util::createBreadcrumb($travelProgramPage); - $breadcrumbEntries[] = new BreadcrumbEntry('Buchen'); - - if ($request->getMethod() === 'POST' && $form->isValid()) - { - $errors = array(); - foreach ($form as $fieldName => $formField) { - foreach ($formField->getErrors(true) as $error) { - $errors[$fieldName] = $error->getMessage(); - } - } - - $booking = $this->getDoctrine()->getRepository('AppBundle:TravelBooking')->createFromBookingRequest( - $bookingRequest, $travelDate, $bookingPriceInfo); - - $em = $this->getDoctrine()->getManager(); - $em->persist($booking); - $em->flush(); - - $ret = Util::loadFromApi('booking/import', ['travel_booking_id' => $booking->getId()]); - $error_crm = 'CRM Fehler: | interne travel_booking ID: '.$booking->getId(); - - $this->get('mailer')->send(\Swift_Message::newInstance() - ->setSubject('Ihr Buchungsauftrag bei STERN TOURS') - ->setFrom('stern@stern-tours.de', 'STERN TOURS') - ->setTo($bookingRequest->getEmail()) // - ->setBody( - $this->renderView('default/email/bookingConfirmationEmail.txt.twig', [ - 'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR, - 'booking_request' => $bookingRequest, - 'booking_price_info' => $bookingPriceInfo, - 'travel_date' => $travelDate, - 'breadcrumb_entries' => $breadcrumbEntries, - 'nationalities' => $nationalities, - 'summary' => $htmlSummary, - - ]), - 'text/plain', 'utf-8' - ) - ); - - $this->get('mailer')->send(\Swift_Message::newInstance() - ->setSubject('BUCHUNG: '. $travelProgram->getTitle() .'('. $travelDate->getName() .')') - ->setFrom('stern@stern-tours.de', 'STERN TOURS') - ->setTo("stern@stern-tours.de") - ->setBody( - $this->renderView('default/email/bookingServiceEmail.txt.twig', [ - 'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR, - 'crm_v1_url' => isset($ret->url_v1) ? $ret->url_v1 : $error_crm, - 'crm_v3_url' => isset($ret->url_v3) ? $ret->url_v3 : $error_crm, - 'lead_id' => isset($ret->lead_id) ? $ret->lead_id : '', - 'travel_program_url' => Util::getBaseUrl() . $travelProgramPage->getUrlPath(), - 'booking_request' => $bookingRequest, - 'booking_price_info' => $bookingPriceInfo, - 'travel_date' => $travelDate, - 'breadcrumb_entries' => $breadcrumbEntries, - 'nationalities' => $nationalities, - 'summary' => $htmlSummary, - - ]), - 'text/plain', 'utf-8' - ) - ); - - // #TODO This will lead to multiple bookings due to multiple form submission. Redirect instead! - return $this->render('default/pages/bookingConfirmation.html.twig', [ - 'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR, - 'site_loading' => 'bookingconfirm', - 'page' => $travelProgramPage, - 'booking_request' => $bookingRequest, - 'breadcrumb_entries' => $breadcrumbEntries, - 'show_nav_sidebar_about' => "notshow", - 'show_nav_sidebar_widget' => false, - 'show_travel_guide_sidebar_widget' => false, - 'show_travel_magazine_sidebar_widget' => false, - 'show_offers_sidebar_widget' => false, - 'show_search_sidebar_widget' => false, - 'show_feedbacks_sidebar_widget' => false, - 'show_seal_of_approval' => true, - 'booking' => $booking, - 'travel_program' => $travelProgram, - 'summary' => $htmlSummary, - 'total_price' => $totalPrice, - 'nationalities' => $nationalities, - 'booking_price_info' => $bookingPriceInfo, - - ]); - } - - return $this->render('default/pages/booking.html.twig', [ - 'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR, - 'site_loading' => 'booking', - 'page' => $travelProgramPage, - 'breadcrumb_entries' => $breadcrumbEntries, - 'show_nav_sidebar_about' => "notshow", - 'show_nav_sidebar_widget' => false, - 'show_travel_guide_sidebar_widget' => false, - 'show_travel_magazine_sidebar_widget' => false, - 'show_offers_sidebar_widget' => false, - 'show_search_sidebar_widget' => false, - 'show_feedbacks_sidebar_widget' => false, - 'show_seal_of_approval' => true, - 'travel_program' => $travelProgram, - 'travel_date' => $travelDate, - 'form' => $form->createView(), - 'price_type_by_id' => $this->priceTypeById, - 'summary' => $htmlSummary, - 'total_price' => $totalPrice, - 'nationalities' => $nationalities, - 'booking_price_info' => $bookingPriceInfo, - 'mediator_terms_filename' => $travelProgram->getIsMediated() - ? $this->getDoctrine()->getRepository('AppBundle:TravelOrganizer')->find(1)->getFileName() - : null - ]); - } - - elseif ($action == '/berechne-gesamtpreis') - { - - return $this->render('default/components/booking/summary.html.twig', [ - 'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR, - 'summary' => $htmlSummary, - 'total_price' => $totalPrice, - 'booking_price_info' => $bookingPriceInfo, - 'show_detail' => true, - - ]); - } - throw new \Exception('Unknow BookingController action: '. $action); - } - - private function calcNumTravelerLabel($number) - { - $ret = 0; - if($number > 0) - $ret = 1; - - return $ret; - } - - public function calculatePrice(TravelDate $travelDate, BookingRequest $bookingRequest, $categoryId, $depositPercent = null, &$outHtmlSummary = null, &$outPriceInfo = null) - { - $ret = 0; - $insuranceAssessmentBasis = 0; - $insuranceAssessmentChildBasis = 0; - - $travelerCount = $bookingRequest->getTravelerCount(); - - $singleRoomCount = $bookingRequest->getSingleRoomCount(); - $doubleRoomCount = $bookingRequest->getDoubleRoomCount(); - $tripleRoomCount = $bookingRequest->getTripleRoomCount(); - - $singleRoomChildCount = $bookingRequest->getSingleRoomChildCount(); - $doubleRoomChildCount = $bookingRequest->getDoubleRoomChildCount(); - $tripleRoomChildCount = $bookingRequest->getTripleRoomChildCount(); - - $childrenCount = $bookingRequest->getChildrenCount(); - - if (isset($outHtmlSummary)) - { - $insuranceHtmlSummary = []; - } - - if (isset($outPriceInfo)) - { - $outPriceInfo['rooms'] = []; - $outPriceInfo['insurances'] = []; - $outPriceInfo['insurancesOut'] = []; - $outPriceInfo['options'] = []; - $outPriceInfo['classOptions'] = []; - $outPriceInfo['departure'] = 0; - $outPriceInfo['departure_extra'] = 0; - $outPriceInfo['flight_price'] = 0; - $outPriceInfo['final_payment_date'] = $travelDate->getFinalPaymentDate(); - $outPriceInfo['final_payment_date_str'] = $travelDate->getFinalPaymentDateStr(); - $outPriceInfo['discount'] = []; - $outPriceInfo['booking_before'] = []; - $outPriceInfo['booking_after'] = []; - - } - - $tempDepartureHTML = array(); - //ABFLUG - if($bookingRequest->getDeparture() != null) - { - $departure = Util\DepartureUtil::limitIndividualArrivalPrice($bookingRequest->getDeparture(), - $travelDate->getFlightPrice()); - if (isset($outPriceInfo)) - { - $outPriceInfo['departure'] = $departure; - } - - if ($departure->getExtraCharge() != 0) - { - $insuranceAssessmentBasis += $departure->getExtraCharge(); - $insuranceAssessmentChildBasis += $departure->getExtraCharge(); - $a = ($travelerCount + $childrenCount) * $departure->getExtraCharge(); - $ret += $a; - $outPriceInfo['departure_extra'] += $a; - - if (isset($outHtmlSummary)) - { - $key = $departure->getExtraCharge(); - if(!empty($tempDepartureHTML[$key])) { - $tempDepartureHTML[$key]['count'] = $tempDepartureHTML[$key]['count'] + ($travelerCount + $childrenCount); - $tempDepartureHTML[$key]['value'] = $tempDepartureHTML[$key]['value'] + $a; - }else{ - $tempDepartureHTML[$key] = array( - 'value' => $a, - 'label_first' => ($departure->getExtraCharge() > 0 ? 'Aufschlag' : 'Abzug') . ' für Abfahrts-/Abflugort "'. $departure->getName(), - 'label_last' => Util::formatPrice($departure->getExtraCharge()) . ' pro Person', - 'count' => ($travelerCount + $childrenCount), - ); - } - } - } - } - - //OPTIONEN - $tempOptionHTML = array(); - foreach ($bookingRequest->getTravelOptions() as $travelOption) - { - $insuranceAssessmentBasis += $travelOption->getPrice(); - $insuranceAssessmentChildBasis += $travelOption->getPriceChildren(); - $a = $travelerCount * $travelOption->getPrice(); - $a += $childrenCount * $travelOption->getPriceChildren(); - $ret += $a; - //OPTIONS - if (isset($outHtmlSummary)) - { - $key = $travelOption->getId(); - if(!empty($tempOptionHTML[$key])) { - // $tempOptionHTML[$key]['count'] = $tempOptionHTML[$key]['count'] + $travelerCount; - $tempOptionHTML[$key]['value'] = $tempOptionHTML[$key]['value'] + $a; - }else{ - $tempOptionHTML[$key] = array( - 'value' => $a, - 'label_first' => $travelOption->getName(), - 'label_last' => Util::formatPrice($travelOption->getPrice()) . ' pro Person', - 'count' => $travelerCount + $childrenCount, - 'childCount' => $childrenCount, - 'price_child' => Util::formatPrice($travelOption->getPriceChildren()) . ' pro Kind', - ); - } - } - if (isset($outPriceInfo)) - { - $outPriceInfo['options'][] = $travelOption; - } - } - - $persons = [ - 'total' => $travelerCount, - 'adults' => $travelerCount, - 'singleRoomPersons' => $singleRoomCount, - 'singleRoomChildPersons' => $singleRoomChildCount, - 'doubleRoomPersons' => $doubleRoomCount * 2, - 'doubleRoomChildPersons' => $doubleRoomChildCount * 2, - 'tripleRoomPersons' => $tripleRoomCount * 3, - 'tripleRoomChildPersons' => $tripleRoomChildCount * 3, - 'children' => 0 //TODO - ]; - - $insuranceTotal = 0; - $tempInsuranceHTML = array(); - $tempRoomHTML = array(); - $tempDiscountHTML = array(); - - $tempExtraDaysBeforeHTML = array(); - $newExtraDaysTravelDate = [ - 'change' => 0, - 'start' => $travelDate->getStart()->format('d.m.Y'), - 'end' => $travelDate->getEnd()->format('d.m.Y'), - ]; - - //Komfort - $possibleRooms = $this->getRooms($travelDate->getPrices(), $persons); - $tempComfortHTML = array(); - - if ($bookingRequest->getComfort()) - { - foreach ($possibleRooms as $room) - { - $insuranceAssessmentBasis += $room['price']->getEffectiveComfortPrice(); - $insuranceAssessmentChildBasis += $room['price']->getEffectiveComfortPrice(); - - $adultCount = $room['persons']['adults']; - $childrenCount = $room['persons']['children']; - - $a = $adultCount * $room['price']->getEffectiveComfortPrice();; - $b = $childrenCount * $room['price']->getEffectiveComfortPrice(); - $ret += $a + $b; - - if (isset($outHtmlSummary)) - { - $key = intval($room['price']->getEffectiveComfortPrice()); - if(!empty($tempComfortHTML[$key])) { - $tempComfortHTML[$key]['count'] = $tempComfortHTML[$key]['count'] + $adultCount + $childrenCount; - $tempComfortHTML[$key]['value'] = $tempComfortHTML[$key]['value'] + $a + $b; - }else{ - $tempComfortHTML[$key] = array( - 'value' => $a + $b, - 'label_first' => 'Komfort-Kategorie', - 'label_last' => Util::formatPrice($room['price']->getEffectiveComfortPrice()) . ' pro Person', - 'count' => $adultCount + $childrenCount, - ); - } - } - if (isset($outPriceInfo)) - { - $outPriceInfo['classOptions'][] = [ - 'count' => $room['persons']['total'], - 'name' => 'Komfort (4 Sterne)', - 'price' => $room['price']->getEffectiveComfortPrice() - ]; - } - } - } - - //days before - if($bookingRequest->getExtraBookingDaysBefore()){ - - $newDay = clone $travelDate->getStart(); - $newDay->modify('-'.$bookingRequest->getExtraBookingDaysBefore().' day'); - $newExtraDaysTravelDate['change'] = 1; - $newExtraDaysTravelDate['start'] = $newDay->format('d.m.Y'); - - foreach ($possibleRooms as $room) { - $key = $room['priceType']->getId(); - - $adultCount = $room['persons']['adults']; - $childrenCount = $room['persons']['children']; - - if ($bookingRequest->getComfort()){ - $singleExtraFullPrice = $room['price']->getEffectiveExtraComfortPrice(); - }else{ - $singleExtraFullPrice = $room['price']->getEffectiveExtraPrice(); - } - $childExtraPrice = $room['price']->getEffectiveExtraChildPrice(); - - $insuranceAssessmentBasis += $singleExtraFullPrice * $bookingRequest->getExtraBookingDaysBefore(); - $insuranceAssessmentChildBasis += $childExtraPrice * $bookingRequest->getExtraBookingDaysBefore(); - - $roomPrice = (($singleExtraFullPrice * $adultCount) + ($childExtraPrice * $childrenCount)) * $bookingRequest->getExtraBookingDaysBefore(); - - $ret += $roomPrice; - - $outPriceInfo['booking_before'][] = [ - 'name' => "Verlängerung vor der Reise " . $room['priceType']->getName() . "", - 'adults' => $adultCount, - 'children' => $childrenCount, - 'price' => $singleExtraFullPrice, - 'price_children' => $childExtraPrice, - 'price_total' => $roomPrice, - 'days' => $bookingRequest->getExtraBookingDaysBefore() - ]; - - - - if (!empty($tempExtraDaysBeforeHTML[$key])) { - $tempExtraDaysBeforeHTML[$key]['count'] = $tempExtraDaysBeforeHTML[$key]['count'] + 1; - $tempExtraDaysBeforeHTML[$key]['value'] = $tempExtraDaysBeforeHTML[$key]['value'] + $roomPrice; - } else { - $tempExtraDaysBeforeHTML[$key] = array( - 'value' => $roomPrice, - 'label_first' => "Verlängerung vor der Reise " . $room['priceType']->getName() . "", - 'label_last' => Util::formatPrice($singleExtraFullPrice) . ' pro Person/Tag', - 'count' => 1, - 'days' => $bookingRequest->getExtraBookingDaysBefore(), - 'childCount' => $room['persons']['children'], - 'price_child' => Util::formatPrice($room['price']->getEffectiveExtraChildPrice()), - ); - } - } - - - } - - $tempExtraDaysAfterHTML = array(); - //days after - if($bookingRequest->getExtraBookingDaysAfter()){ - - $newDay = clone $travelDate->getEnd(); - $newDay->modify('+'.$bookingRequest->getExtraBookingDaysAfter().' day'); - $newExtraDaysTravelDate['change'] = 1; - $newExtraDaysTravelDate['end'] = $newDay->format('d.m.Y'); - - foreach ($possibleRooms as $room) { - $key = $room['priceType']->getId(); - - $adultCount = $room['persons']['adults']; - $childrenCount = $room['persons']['children']; - - if ($bookingRequest->getComfort()){ - $singleExtraFullPrice = $room['price']->getEffectiveExtraComfortPrice(); - }else{ - $singleExtraFullPrice = $room['price']->getEffectiveExtraPrice(); - } - $childExtraPrice = $room['price']->getEffectiveExtraChildPrice(); - - $insuranceAssessmentBasis += $singleExtraFullPrice * $bookingRequest->getExtraBookingDaysAfter(); - $insuranceAssessmentChildBasis += $childExtraPrice * $bookingRequest->getExtraBookingDaysAfter(); - - $roomPrice = (($singleExtraFullPrice * $adultCount) + ($childExtraPrice * $childrenCount)) * $bookingRequest->getExtraBookingDaysAfter(); - - $ret += $roomPrice; - - $outPriceInfo['booking_after'][] = [ - 'name' => "Verlängerung nach der Reise " . $room['priceType']->getName() . "", - 'adults' => $adultCount, - 'children' => $childrenCount, - 'price' => $singleExtraFullPrice, - 'price_children' => $childExtraPrice, - 'price_total' => $roomPrice, - 'days' => $bookingRequest->getExtraBookingDaysAfter() - ]; - - - - if (!empty($tempExtraDaysAfterHTML[$key])) { - $tempExtraDaysAfterHTML[$key]['count'] = $tempExtraDaysAfterHTML[$key]['count'] + 1; - $tempExtraDaysAfterHTML[$key]['value'] = $tempExtraDaysAfterHTML[$key]['value'] + $roomPrice; - } else { - $tempExtraDaysAfterHTML[$key] = array( - 'value' => $roomPrice, - 'label_first' => "Verlängerung nach der Reise " . $room['priceType']->getName() . "", - 'label_last' => Util::formatPrice($singleExtraFullPrice) . ' pro Person/Tag', - 'count' => 1, - 'days' => $bookingRequest->getExtraBookingDaysAfter(), - 'childCount' => $room['persons']['children'], - 'price_child' => Util::formatPrice($room['price']->getEffectiveExtraChildPrice()), - ); - } - } - - - } - - - //ROOMS DISCOUNT Versicherungen - foreach ($possibleRooms as $room) - { - $adultCount = $room['persons']['adults']; - $childrenCount = $room['persons']['children']; - - $singleFullPrice = $room['price']->getEffectivePrice(); - $childPrice = $room['price']->getEffectiveChildPrice(); - - $roomPrice = ($singleFullPrice * $adultCount) + ($childPrice * $room['persons']['children']); - - - $singleDiscountPrice = $room['price']->getEffectiveDiscountPrice(); - $singleChildDiscountPrice = $room['price']->getEffectiveChildDiscountPrice(); - $discount = ($singleDiscountPrice === null) ? 0 : ($adultCount * ($singleDiscountPrice - $singleFullPrice)); - $childDiscount = ($singleChildDiscountPrice === null) ? 0 : ($childrenCount * ($singleChildDiscountPrice - $childPrice)); - - $ret += $roomPrice + $discount + $childDiscount; - - $singel_flight_price = $travelDate->getFlightCalcPrice(); - $outPriceInfo['flight_price'] += (($singel_flight_price * $adultCount) + ($singel_flight_price * $room['persons']['children'])); - - //Room price - if (isset($outPriceInfo)) - { - $price = $singleDiscountPrice ?? $singleFullPrice; - $price += $singleChildDiscountPrice ?? $childPrice; - - $outPriceInfo['rooms'][] = [ - 'name' => $room['priceType']->getName(), - 'adults' => $adultCount, - 'children' => $childrenCount, - 'price' => $singleDiscountPrice ?? $singleFullPrice, - 'price_children' => $singleChildDiscountPrice ?? $childPrice, - 'price_total' => $roomPrice + $discount + $childDiscount, - 'price_full' => $singleFullPrice, - 'price_children_full' => $childPrice, - 'price_total_full' => $roomPrice, - ]; - } - - - //Room html - if (isset($outHtmlSummary)) - { - //ROOMS - $key = $room['priceType']->getId(); - if(!empty($tempRoomHTML[$key])) { - $tempRoomHTML[$key]['count'] = $tempRoomHTML[$key]['count'] + 1; - $tempRoomHTML[$key]['value'] = $tempRoomHTML[$key]['value'] + $roomPrice; - }else{ - $tempRoomHTML[$key] = array( - 'value' => $roomPrice, - 'label_first' => $room['priceType']->getName(), - 'label_last' => Util::formatPrice($singleFullPrice) . ' pro Person', - 'count' => 1, - 'childCount' => $room['persons']['children'], - 'price_child' => Util::formatPrice($room['price']->getEffectiveChildPrice()), - ); - } - - //DISCOUNT - if ($singleDiscountPrice !== null) - { - $key = intval(($singleFullPrice - $singleDiscountPrice)*100); - if(!empty($tempDiscountHTML[$key])) { - $tempDiscountHTML[$key]['count'] = $tempDiscountHTML[$key]['count'] + $adultCount; - $tempDiscountHTML[$key]['value'] = $tempDiscountHTML[$key]['value'] + $discount; - }else{ - $tempDiscountHTML[$key] = array( - 'value' => $discount, - 'label_first' => 'Rabatt', - 'label_last' => Util::formatPrice($singleFullPrice - $singleDiscountPrice) . ' pro Person', - 'count' => $adultCount, - ); - } - if($childDiscount > 0){ - $key = intval(($childPrice - $singleChildDiscountPrice)*100); - if(!empty($tempDiscountHTML[$key])) { - $tempDiscountHTML[$key]['count'] = $tempDiscountHTML[$key]['count'] + $childrenCount; - $tempDiscountHTML[$key]['value'] = $tempDiscountHTML[$key]['value'] + $childDiscount; - }else{ - $tempDiscountHTML[$key] = array( - 'value' => $childDiscount, - 'label_first' => 'Rabatt', - 'label_last' => Util::formatPrice($childPrice - $singleChildDiscountPrice) . ' pro Person', - 'count' => $childrenCount, - ); - } - } - if (isset($outPriceInfo)) - { - $key = intval(($singleFullPrice - $singleDiscountPrice)*100); - if(!empty($outPriceInfo['discount'][$key])) { - $outPriceInfo['discount'][$key]['count'] = $outPriceInfo['discount'][$key]['count'] + $adultCount; - $outPriceInfo['discount'][$key]['value'] = $outPriceInfo['discount'][$key]['value'] + $discount; - }else{ - $outPriceInfo['discount'][$key] = array( - 'value' => $discount, - 'price_discount' => ($singleFullPrice - $singleDiscountPrice), - 'label_first' => 'Rabatt', - 'label_last' => Util::formatPrice($singleFullPrice - $singleDiscountPrice) . ' pro Person', - 'count' => $adultCount, - ); - } - if($childDiscount > 0){ - $key = intval(($childPrice - $singleChildDiscountPrice)*100); - if(!empty($outPriceInfo['discount'][$key])) { - $outPriceInfo['discount'][$key]['count'] = $outPriceInfo['discount'][$key]['count'] + $childrenCount; - $outPriceInfo['discount'][$key]['value'] = $outPriceInfo['discount'][$key]['value'] + $childDiscount; - }else{ - $outPriceInfo['discount'][$key] = array( - 'value' => $childDiscount, - 'label_first' => 'Rabatt', - 'label_last' => Util::formatPrice($childPrice - $singleChildDiscountPrice) . ' pro Person', - 'count' => $childrenCount, - ); - } - } - } - - } - - //Versicherung price + html - if ($bookingRequest->getInsurance() && $adultCount > 0) - { - - $curAssessmentBasis = $insuranceAssessmentBasis + ($singleDiscountPrice ?? $singleFullPrice); - $curAssessmentChildBasis = $insuranceAssessmentChildBasis + ($singleChildDiscountPrice ?? $childPrice); - $insurancePrice = $this->getDoctrine()->getRepository('AppBundle:TravelInsurancePrice') - ->findOneByInsuranceIdAndAssessmentBasis($bookingRequest->getInsurance()->getId(), $curAssessmentBasis); - - $insuranceChildPrice = $this->getDoctrine()->getRepository('AppBundle:TravelInsurancePrice') - ->findOneByInsuranceIdAndAssessmentBasis($bookingRequest->getInsurance()->getId(), $curAssessmentChildBasis); - - $insurancePriceValue = $insurancePrice->getPrice() > 0 ? $insurancePrice->getPrice() : round($insurancePrice->getPercent() * $curAssessmentBasis / 100, 2); - $insuranceChildPriceValue = $insuranceChildPrice->getPrice() > 0 ? $insuranceChildPrice->getPrice() : round($insuranceChildPrice->getPercent() * $curAssessmentChildBasis / 100, 2); - - - $a = $adultCount * $insurancePriceValue; - $b = $childrenCount * $insuranceChildPriceValue; - $insuranceTotal += $a + $b; - $ret += $a + $b; - - if (isset($insuranceHtmlSummary)) - { - if(!empty($tempInsuranceHTML[$insurancePriceValue])){ - $tempInsuranceHTML[$insurancePriceValue]['count'] = intval($tempInsuranceHTML[$insurancePriceValue]['count']) + $adultCount; - $tempInsuranceHTML[$insurancePriceValue]['value'] = $tempInsuranceHTML[$insurancePriceValue]['value'] + $a; - }else{ - $tempInsuranceHTML[$insurancePriceValue] = array( - 'value' => $a, - 'label_first' => 'RV '. $bookingRequest->getInsurance()->getName() .' ('. $insurancePrice->getCode() .') ', - 'label_last' => Util::formatPrice($insurancePriceValue) . ' pro Person', - 'count' => $adultCount, - - ); - } - if($b > 0){ - if(!empty($tempInsuranceHTML[$insuranceChildPriceValue])){ - $tempInsuranceHTML[$insuranceChildPriceValue]['count'] = intval($tempInsuranceHTML[$insuranceChildPriceValue]['count']) + $childrenCount; - $tempInsuranceHTML[$insuranceChildPriceValue]['value'] = $tempInsuranceHTML[$insuranceChildPriceValue]['value'] + $b; - }else{ - $tempInsuranceHTML[$insuranceChildPriceValue] = array( - 'value' => $b, - 'label_first' => 'RV '. $bookingRequest->getInsurance()->getName() .' ('. $insuranceChildPrice->getCode() .') ', - 'label_last' => Util::formatPrice($insuranceChildPriceValue) . ' pro Kind', - 'count' => $childrenCount, - - ); - } - } - } - if (isset($outPriceInfo)) - { - if(!empty($outPriceInfo['insurancesOut'][$insurancePriceValue])){ - $outPriceInfo['insurancesOut'][$insurancePriceValue]['count'] = intval($outPriceInfo['insurancesOut'][$insurancePriceValue]['count']) + $childrenCount; - $outPriceInfo['insurancesOut'][$insurancePriceValue]['value'] = $outPriceInfo['insurancesOut'][$insurancePriceValue]['value'] + $b; - }else{ - $outPriceInfo['insurancesOut'][$insurancePriceValue] = [ - 'value' => $a, - 'label_first' => 'RV '. $bookingRequest->getInsurance()->getName() .' ('. $insurancePrice->getCode() .') ', - 'label_last' => Util::formatPrice($insurancePriceValue) . ' pro Person', - 'count' => $adultCount, - ]; - } - if($b > 0){ - if(!empty($outPriceInfo['insurancesOut'][$insuranceChildPriceValue])){ - $outPriceInfo['insurancesOut'][$insuranceChildPriceValue]['count'] = intval($outPriceInfo['insurancesOut'][$insuranceChildPriceValue]['count']) + $childrenCount; - $outPriceInfo['insurancesOut'][$insuranceChildPriceValue]['value'] = $outPriceInfo['insurancesOut'][$insuranceChildPriceValue]['value'] + $b; - }else{ - $outPriceInfo['insurancesOut'][$insuranceChildPriceValue] = [ - 'value' => $b, - 'label_first' => 'RV '. $bookingRequest->getInsurance()->getName() .' ('. $insuranceChildPrice->getCode() .') ', - 'label_last' => Util::formatPrice($insuranceChildPriceValue) . ' pro Kind', - 'count' => $childrenCount, - ]; - } - } - - $outPriceInfo['insurances'][] = [ - 'insurance' => $bookingRequest->getInsurance(), - 'insurancePriceValue' => $insurancePriceValue, - 'insurancePrice' => $insurancePrice, - 'count' => $adultCount, - 'insuranceChildPriceValue' => $insuranceChildPriceValue, - 'insuranceChildPrice' => $insuranceChildPrice, - 'countChild' => $childrenCount, - ]; - } - } - } - } - - - //ROOMS - if(count($tempRoomHTML) > 0){ - foreach ($tempRoomHTML as $item) { - $label = ''.$item['count'].' x '.$item['label_first'].' ['.$item['label_last'].']'; - if($item['childCount'] > 0){ - $label .= ' [ + Kind: '.$item['price_child']; - } - $label .= ']'; - $outHtmlSummary[] =[ - 'value' => $item['value'], - 'label' => $label, - ]; - } - } - - //Comfort - if(count($tempComfortHTML) > 0){ - foreach ($tempComfortHTML as $item) { - $outHtmlSummary[] =[ - 'value' => $item['value'], - 'label' => ''.$item['count'].' x '.$item['label_first'].' ['.$item['label_last'].' ]', - ]; - } - } - - //Departure - if(count($tempDepartureHTML) > 0){ - foreach ($tempDepartureHTML as $item) { - $outHtmlSummary[] =[ - 'value' => $item['value'], - 'label' => ''.$item['count'].' x '.$item['label_first'].' ['.$item['label_last'].' ]', - ]; - } - } - - //DISCOUNT - if(count($tempDiscountHTML) > 0){ - foreach ($tempDiscountHTML as $item) { - $insuranceHtmlSummary[] =[ - 'value' => $item['value'], - 'label' => ''.$item['count'].' x '.$item['label_first'].' ['.$item['label_last'].' ]', - ]; - } - } - //options - if(count($tempOptionHTML) > 0){ - foreach ($tempOptionHTML as $item) { - $label = ''.$item['count'].' x '.$item['label_first'].' ['.$item['label_last'].']'; - if($item['childCount'] > 0){ - $label .= ' ['.$item['price_child'].']'; - } - $outHtmlSummary[] =[ - 'value' => $item['value'], - 'label' => $label, - ]; - } - } - - //extra days before - if(count($tempExtraDaysBeforeHTML) > 0){ - foreach ($tempExtraDaysBeforeHTML as $item) { - $setDays = $item['days'] . ($item['days'] == 1 ? ' Tag' : ' Tage'); - $label = ''.$item['count'].' x '.$setDays.' '.$item['label_first'].' ['.$item['label_last'].']'; - if($item['childCount'] > 0){ - $label .= ' [+ Kind: '.$item['price_child'].']'; - } - $outHtmlSummary[] =[ - 'value' => $item['value'], - 'label' => $label, - ]; - } - } - - //extra days after - if(count($tempExtraDaysAfterHTML) > 0){ - foreach ($tempExtraDaysAfterHTML as $item) { - $setDays = $item['days'] . ($item['days'] == 1 ? ' Tag' : ' Tage'); - $label = ''.$item['count'].' x '.$setDays.' '.$item['label_first'].' ['.$item['label_last'].']'; - if($item['childCount'] > 0){ - $label .= ' [+ Kind: '.$item['price_child'].']'; - } - $outHtmlSummary[] =[ - 'value' => $item['value'], - 'label' => $label, - ]; - } - } - - - //Versicherungen - if(count($tempInsuranceHTML) > 0 ){ - foreach ($tempInsuranceHTML as $item) { - $insuranceHtmlSummary[] =[ - 'value' => $item['value'], - 'label' => ''.$item['count'].' x '.$item['label_first'].' ['.$item['label_last'].' ]', - ]; - } - } - - - - - if (isset($insuranceHtmlSummary)) - { - $outHtmlSummary = array_merge($outHtmlSummary, $insuranceHtmlSummary); - } - if($newExtraDaysTravelDate['change'] == 1){ - $outHtmlSummary[] = [ - 'value' => '!', - 'label' => "Geänderter Reisezeitraum: ".$newExtraDaysTravelDate['start']." - ".$newExtraDaysTravelDate['end'], - ]; - } - - if (isset($outPriceInfo)) - { - $outPriceInfo['total'] = $ret; - $outPriceInfo['totalWithoutInsurance'] = $ret - $insuranceTotal; - $outPriceInfo['totalInsurance'] = $insuranceTotal; - - if($outPriceInfo['departure_extra'] >= 0){ - $outPriceInfo['flight_price'] = $outPriceInfo['flight_price'] + $outPriceInfo['departure_extra']; - }else{ - $outPriceInfo['flight_price'] = 0; - } - - if($depositPercent === null) { - $depositPercent = 20; - } - //Aeqypten (20% from price) - if($categoryId == 1){ - $deposit = ($outPriceInfo['totalWithoutInsurance'] / 100 * $depositPercent); - $outPriceInfo['deposit_total'] = $deposit; - $outPriceInfo['final_payment'] = ($outPriceInfo['totalWithoutInsurance'] - $outPriceInfo['deposit_total']); - }else{ - //all 100% vom Flugpreis und 20% von der Landleistung. - $deposit = (($outPriceInfo['totalWithoutInsurance'] - $outPriceInfo['flight_price']) / 100 * $depositPercent); - $outPriceInfo['deposit_total'] = ($deposit + $outPriceInfo['flight_price']); - $outPriceInfo['final_payment'] = ($outPriceInfo['totalWithoutInsurance'] - $outPriceInfo['deposit_total']); - } - } - - return $ret; - } - - /** - * @param TravelPeriodPrice[] $prices - * @param $persons - * - * @return array - */ - private function getRooms($prices, $persons) - { - $ret = []; - - foreach($prices as $price) - { - $priceTypeId = $price->getPriceTypeId(); - //with children - $priceType = $this->priceTypeById[$priceTypeId]; - - if($priceTypeId == 1 && $persons['singleRoomPersons'] > 0) - { - for($i = 0; $i < $persons['singleRoomPersons']; $i++) - { - $currentPersons = [ - 'total' => 1, - 'adults' => 1, - 'children' => 0 //TODO - ]; - - $ret[] = [ - 'priceType' => $priceType, - 'persons' => $currentPersons, - 'price' => $price - ]; - } - } - - if($priceTypeId == 1 && $persons['singleRoomChildPersons'] > 0) - { - $priceTypeId = 2; - $priceType = $this->priceTypeById[$priceTypeId]; - - for($i = 0; $i < $persons['singleRoomChildPersons']; $i++) - { - $currentPersons = [ - 'total' => 1, - 'adults' => 1, - 'children' => 1 - ]; - - $ret[] = [ - 'priceType' => $priceType, - 'persons' => $currentPersons, - 'price' => $price - ]; - } - } - - if($priceTypeId == 3 && $persons['doubleRoomPersons'] > 0) - { - for($j = 0; $j < ($persons['doubleRoomPersons'] / 2); $j++) - { - $currentPersons = [ - 'total' => 2, - 'adults' => 2, - 'children' => 0 - ]; - - $ret[] = [ - 'priceType' => $priceType, - 'persons' => $currentPersons, - 'price' => $price - ]; - } - } - - if($priceTypeId == 3 && $persons['doubleRoomChildPersons'] > 0) - { - $priceTypeId = 4; - $priceType = $this->priceTypeById[$priceTypeId]; - - for($j = 0; $j < ($persons['doubleRoomChildPersons'] / 2); $j++) - { - $currentPersons = [ - 'total' => 2, - 'adults' => 2, - 'children' => 1 - ]; - - $ret[] = [ - 'priceType' => $priceType, - 'persons' => $currentPersons, - 'price' => $price - ]; - } - } - - if($priceTypeId == 5 && $persons['tripleRoomPersons'] > 0) - { - for($k = 0; $k < ($persons['tripleRoomPersons'] / 3); $k++) - { - $currentPersons = [ - 'total' => 3, - 'adults' => 3, - 'children' => 0 - ]; - - $ret[] = [ - 'priceType' => $priceType, - 'persons' => $currentPersons, - 'price' => $price - ]; - } - } - - if($priceTypeId == 5 && $persons['tripleRoomChildPersons'] > 0) - { - $priceTypeId = 7; - $priceType = $this->priceTypeById[$priceTypeId]; - - for($k = 0; $k < ($persons['tripleRoomChildPersons'] / 3); $k++) - { - $currentPersons = [ - 'total' => 3, - 'adults' => 3, - 'children' => 1 - ]; - - $ret[] = [ - 'priceType' => $priceType, - 'persons' => $currentPersons, - 'price' => $price - ]; - } - } - } - - return $ret; - } -} \ No newline at end of file + + * @date 12/08/2016 + */ + +namespace AppBundle\Controller; + + +use AppBundle\Entity\BookingRequest; +use AppBundle\Entity\BreadcrumbEntry; +use AppBundle\Entity\Page; +use AppBundle\Entity\TravelDate; +use AppBundle\Entity\Traveler; +use AppBundle\Entity\TravelPeriodPrice; +use AppBundle\Entity\TravelPeriodPriceType; +use AppBundle\Form\BookingRequestType; +use AppBundle\Util; +use Doctrine\ORM\Query; +use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +class BookingController extends Controller +{ + /** @var TravelPeriodPriceType[] $priceTypeById */ + private $priceTypeById; + + /** + * The routing for this action is entirely controlled by KernelControllerListener! + * + * @param Page $travelProgramPage + * @param Request $request + * @param $action + * + * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response + * @throws \Exception + */ + + private function getErrorMessages(\Symfony\Component\Form\Form $form) + { + $errors = array(); + + foreach ($form->getErrors() as $key => $error) { + if ($form->isRoot()) { + $errors['#'][] = $error->getMessage(); + } else { + $errors[] = $error->getMessage(); + } + } + + foreach ($form->all() as $child) { + if (!$child->isValid()) { + $errors[$child->getName()] = $this->getErrorMessages($child); + } + } + + return $errors; + } + public function getEntityManager() + { + return $this->getDoctrine()->getManager(); + } + + public function indexAction(Page $travelProgramPage, $action, Request $request) + { + + if ($action == '/show_nationality_country_text') { + + $ret = ""; + $nationality_id = $request->request->get('nationality_id'); + $country_ids = $request->request->get('country_ids'); + + + foreach ($country_ids as $country_id) { + + $country = $this->getEntityManager()->getRepository('AppBundle:TravelCountry')->findOneBy(['id' => $country_id]); + + $req = $this->getDoctrine()->getRepository('AppBundle:TravelNationalityRequirement')->findOneByCountryAndNationality($country_id, $nationality_id); + + + if ($req && $country) { + + $setC = !empty($country->getName()) ? $country->getName() : "Einreiseland"; + $setT = !empty($req->getText()) ? $req->getText() : "Die Einreisebestimmungen erhalten Sie nach der Bestätigung Ihrer Anfrage."; + $ret .= "

" . $setC . "

"; + $ret .= "

" . $setT . "

"; + $ret .= "
"; + } + } + echo $ret; + die(); + } + + $travelProgram = $travelProgramPage->getTravelProgram(); + if (!$request->query->has('nr')) { + return $this->redirect($travelProgramPage->getUrlPath()); + } + $this->getDoctrine()->getRepository('AppBundle:TravelPeriod')->getTrueTravelPeriods($travelProgram); + + $this->priceTypeById = $this->getDoctrine()->getRepository('AppBundle:TravelPeriodPriceType')->findAllIndexedById(); + + // #TODO Consider changing key of travel dates + foreach ($travelProgram->getTravelDates() as $curTravelDate) { + if ($curTravelDate->getStatus() != 0) { + if ($curTravelDate->getName() == $request->query->get('nr')) { + $travelDate = $curTravelDate; + break; + } + } + } + + if (!isset($travelDate)) { + throw $this->createNotFoundException(); + } + $now = new \DateTime(); + if ($travelDate->getStart() <= $now) { + throw $this->createNotFoundException(); + } + + /**/ + $nationalities = $this->getDoctrine() + ->getRepository('AppBundle:TravelNationality') + ->createQueryBuilder('n') + ->where('n.active = true') + ->getQuery()->getResult(Query::HYDRATE_ARRAY); + + /** @var BookingRequest $bookingRequest */ + $bookingRequest = new BookingRequest(); + if ($request->getMethod() != 'POST') { + $bookingRequest->setRoomCount(0); + } + $form = $this->createForm(BookingRequestType::class, $bookingRequest, [ + 'travel_date' => $travelDate, + 'travel_program' => $travelProgram, + 'nationalities' => $nationalities + ]); + if ($request->getMethod() == 'POST') { + $form->handleRequest($request); + $bookingRequest = $form->getData(); + } + + $htmlSummary = []; + $bookingPriceInfo = []; + $totalPrice = $this->calculatePrice($travelDate, $bookingRequest, $travelProgram->getCategory()->getId(), $travelProgram->getDepositPercent(), $htmlSummary, $bookingPriceInfo); + + if ($action == '/buchen') { + $breadcrumbEntries = Util::createBreadcrumb($travelProgramPage); + $breadcrumbEntries[] = new BreadcrumbEntry('Buchen'); + $errors = []; + + if ($request->getMethod() === 'POST') { + foreach ($form as $fieldName => $formField) { + foreach ($formField->getErrors(true) as $error) { + $errors[$fieldName] = $error->getMessage(); + } + } + if (!$bookingRequest->checkIsRoomSelected()) { + $errors['room'] = 'Bitte wählen Sie mindestens ein Zimmer aus.'; + } + } + + if ($request->getMethod() === 'POST' && $form->isValid() && count($errors) == 0) { + $booking = $this->getDoctrine()->getRepository('AppBundle:TravelBooking')->createFromBookingRequest( + $bookingRequest, + $travelDate, + $bookingPriceInfo + ); + + $em = $this->getDoctrine()->getManager(); + $em->persist($booking); + $em->flush(); + + $ret = Util::loadFromApi('booking/import', ['travel_booking_id' => $booking->getId()]); + $error_crm = 'CRM Fehler: | interne travel_booking ID: ' . $booking->getId(); + + $this->get('mailer')->send( + \Swift_Message::newInstance() + ->setSubject('Ihr Buchungsauftrag bei STERN TOURS') + ->setFrom('stern@stern-tours.de', 'STERN TOURS') + ->setTo($bookingRequest->getEmail()) // + ->setBody( + $this->renderView('default/email/bookingConfirmationEmail.txt.twig', [ + 'base_dir' => realpath($this->getParameter('kernel.root_dir') . '/..') . DIRECTORY_SEPARATOR, + 'booking_request' => $bookingRequest, + 'booking_price_info' => $bookingPriceInfo, + 'travel_date' => $travelDate, + 'breadcrumb_entries' => $breadcrumbEntries, + 'nationalities' => $nationalities, + 'summary' => $htmlSummary, + + ]), + 'text/plain', + 'utf-8' + ) + ); + + $this->get('mailer')->send( + \Swift_Message::newInstance() + ->setSubject('BUCHUNG: ' . $travelProgram->getTitle() . '(' . $travelDate->getName() . ')') + ->setFrom('stern@stern-tours.de', 'STERN TOURS') + ->setTo("stern@stern-tours.de") + ->setBody( + $this->renderView('default/email/bookingServiceEmail.txt.twig', [ + 'base_dir' => realpath($this->getParameter('kernel.root_dir') . '/..') . DIRECTORY_SEPARATOR, + 'crm_v1_url' => isset($ret->url_v1) ? $ret->url_v1 : $error_crm, + 'crm_v3_url' => isset($ret->url_v3) ? $ret->url_v3 : $error_crm, + 'lead_id' => isset($ret->lead_id) ? $ret->lead_id : '', + 'travel_program_url' => Util::getBaseUrl() . $travelProgramPage->getUrlPath(), + 'booking_request' => $bookingRequest, + 'booking_price_info' => $bookingPriceInfo, + 'travel_date' => $travelDate, + 'breadcrumb_entries' => $breadcrumbEntries, + 'nationalities' => $nationalities, + 'summary' => $htmlSummary, + + ]), + 'text/plain', + 'utf-8' + ) + ); + + // #TODO This will lead to multiple bookings due to multiple form submission. Redirect instead! + return $this->render('default/pages/bookingConfirmation.html.twig', [ + 'base_dir' => realpath($this->getParameter('kernel.root_dir') . '/..') . DIRECTORY_SEPARATOR, + 'site_loading' => 'bookingconfirm', + 'page' => $travelProgramPage, + 'booking_request' => $bookingRequest, + 'breadcrumb_entries' => $breadcrumbEntries, + 'show_nav_sidebar_about' => "notshow", + 'show_nav_sidebar_widget' => false, + 'show_travel_guide_sidebar_widget' => false, + 'show_travel_magazine_sidebar_widget' => false, + 'show_offers_sidebar_widget' => false, + 'show_search_sidebar_widget' => false, + 'show_feedbacks_sidebar_widget' => false, + 'show_seal_of_approval' => true, + 'booking' => $booking, + 'travel_program' => $travelProgram, + 'summary' => $htmlSummary, + 'total_price' => $totalPrice, + 'nationalities' => $nationalities, + 'booking_price_info' => $bookingPriceInfo, + + ]); + } + + return $this->render('default/pages/booking.html.twig', [ + 'base_dir' => realpath($this->getParameter('kernel.root_dir') . '/..') . DIRECTORY_SEPARATOR, + 'site_loading' => 'booking', + 'page' => $travelProgramPage, + 'breadcrumb_entries' => $breadcrumbEntries, + 'show_nav_sidebar_about' => "notshow", + 'show_nav_sidebar_widget' => false, + 'show_travel_guide_sidebar_widget' => false, + 'show_travel_magazine_sidebar_widget' => false, + 'show_offers_sidebar_widget' => false, + 'show_search_sidebar_widget' => false, + 'show_feedbacks_sidebar_widget' => false, + 'show_seal_of_approval' => true, + 'travel_program' => $travelProgram, + 'travel_date' => $travelDate, + 'form' => $form->createView(), + 'price_type_by_id' => $this->priceTypeById, + 'summary' => $htmlSummary, + 'total_price' => $totalPrice, + 'nationalities' => $nationalities, + 'booking_price_info' => $bookingPriceInfo, + 'errors' => count($errors) ? $errors : null, + 'mediator_terms_filename' => $travelProgram->getIsMediated() + ? $this->getDoctrine()->getRepository('AppBundle:TravelOrganizer')->find(1)->getFileName() + : null + ]); + } elseif ($action == '/berechne-gesamtpreis') { + + return $this->render('default/components/booking/summary.html.twig', [ + 'base_dir' => realpath($this->getParameter('kernel.root_dir') . '/..') . DIRECTORY_SEPARATOR, + 'summary' => $htmlSummary, + 'total_price' => $totalPrice, + 'booking_price_info' => $bookingPriceInfo, + 'show_detail' => true, + + ]); + } + throw new \Exception('Unknow BookingController action: ' . $action); + } + + private function calcNumTravelerLabel($number) + { + $ret = 0; + if ($number > 0) + $ret = 1; + + return $ret; + } + + public function calculatePrice(TravelDate $travelDate, BookingRequest $bookingRequest, $categoryId, $depositPercent = null, &$outHtmlSummary = null, &$outPriceInfo = null) + { + $ret = 0; + $insuranceAssessmentBasis = 0; + $insuranceAssessmentChildBasis = 0; + + $travelerCount = $bookingRequest->getTravelerCount(); + + $singleRoomCount = $bookingRequest->getSingleRoomCount(); + $doubleRoomCount = $bookingRequest->getDoubleRoomCount(); + $tripleRoomCount = $bookingRequest->getTripleRoomCount(); + + $singleRoomChildCount = $bookingRequest->getSingleRoomChildCount(); + $doubleRoomChildCount = $bookingRequest->getDoubleRoomChildCount(); + $tripleRoomChildCount = $bookingRequest->getTripleRoomChildCount(); + + $childrenCount = $bookingRequest->getChildrenCount(); + + if (isset($outHtmlSummary)) { + $insuranceHtmlSummary = []; + } + + if (isset($outPriceInfo)) { + $outPriceInfo['rooms'] = []; + $outPriceInfo['insurances'] = []; + $outPriceInfo['insurancesOut'] = []; + $outPriceInfo['options'] = []; + $outPriceInfo['classOptions'] = []; + $outPriceInfo['departure'] = 0; + $outPriceInfo['departure_extra'] = 0; + $outPriceInfo['flight_price'] = 0; + $outPriceInfo['final_payment_date'] = $travelDate->getFinalPaymentDate(); + $outPriceInfo['final_payment_date_str'] = $travelDate->getFinalPaymentDateStr(); + $outPriceInfo['discount'] = []; + $outPriceInfo['booking_before'] = []; + $outPriceInfo['booking_after'] = []; + } + + $tempDepartureHTML = array(); + //ABFLUG + if ($bookingRequest->getDeparture() != null) { + $departure = Util\DepartureUtil::limitIndividualArrivalPrice( + $bookingRequest->getDeparture(), + $travelDate->getFlightPrice() + ); + if (isset($outPriceInfo)) { + $outPriceInfo['departure'] = $departure; + } + + if ($departure->getExtraCharge() != 0) { + $insuranceAssessmentBasis += $departure->getExtraCharge(); + $insuranceAssessmentChildBasis += $departure->getExtraCharge(); + $a = ($travelerCount + $childrenCount) * $departure->getExtraCharge(); + $ret += $a; + $outPriceInfo['departure_extra'] += $a; + + if (isset($outHtmlSummary)) { + $key = $departure->getExtraCharge(); + if (!empty($tempDepartureHTML[$key])) { + $tempDepartureHTML[$key]['count'] = $tempDepartureHTML[$key]['count'] + ($travelerCount + $childrenCount); + $tempDepartureHTML[$key]['value'] = $tempDepartureHTML[$key]['value'] + $a; + } else { + $tempDepartureHTML[$key] = array( + 'value' => $a, + 'label_first' => ($departure->getExtraCharge() > 0 ? 'Aufschlag' : 'Abzug') . ' für Abfahrts-/Abflugort "' . $departure->getName(), + 'label_last' => Util::formatPrice($departure->getExtraCharge()) . ' pro Person', + 'count' => ($travelerCount + $childrenCount), + ); + } + } + } + } + + //OPTIONEN + $tempOptionHTML = array(); + foreach ($bookingRequest->getTravelOptions() as $travelOption) { + $insuranceAssessmentBasis += $travelOption->getPrice(); + $insuranceAssessmentChildBasis += $travelOption->getPriceChildren(); + $a = $travelerCount * $travelOption->getPrice(); + $a += $childrenCount * $travelOption->getPriceChildren(); + $ret += $a; + //OPTIONS + if (isset($outHtmlSummary)) { + $key = $travelOption->getId(); + if (!empty($tempOptionHTML[$key])) { + // $tempOptionHTML[$key]['count'] = $tempOptionHTML[$key]['count'] + $travelerCount; + $tempOptionHTML[$key]['value'] = $tempOptionHTML[$key]['value'] + $a; + } else { + $tempOptionHTML[$key] = array( + 'value' => $a, + 'label_first' => $travelOption->getName(), + 'label_last' => Util::formatPrice($travelOption->getPrice()) . ' pro Person', + 'count' => $travelerCount + $childrenCount, + 'childCount' => $childrenCount, + 'price_child' => Util::formatPrice($travelOption->getPriceChildren()) . ' pro Kind', + ); + } + } + if (isset($outPriceInfo)) { + $outPriceInfo['options'][] = $travelOption; + } + } + + $persons = [ + 'total' => $travelerCount, + 'adults' => $travelerCount, + 'singleRoomPersons' => $singleRoomCount, + 'singleRoomChildPersons' => $singleRoomChildCount, + 'doubleRoomPersons' => $doubleRoomCount * 2, + 'doubleRoomChildPersons' => $doubleRoomChildCount * 2, + 'tripleRoomPersons' => $tripleRoomCount * 3, + 'tripleRoomChildPersons' => $tripleRoomChildCount * 3, + 'children' => 0 //TODO + ]; + + $insuranceTotal = 0; + $tempInsuranceHTML = array(); + $tempRoomHTML = array(); + $tempDiscountHTML = array(); + + $tempExtraDaysBeforeHTML = array(); + $newExtraDaysTravelDate = [ + 'change' => 0, + 'start' => $travelDate->getStart()->format('d.m.Y'), + 'end' => $travelDate->getEnd()->format('d.m.Y'), + ]; + + //Komfort + $possibleRooms = $this->getRooms($travelDate->getPrices(), $persons); + $tempComfortHTML = array(); + + if ($bookingRequest->getComfort()) { + foreach ($possibleRooms as $room) { + $insuranceAssessmentBasis += $room['price']->getEffectiveComfortPrice(); + $insuranceAssessmentChildBasis += $room['price']->getEffectiveComfortPrice(); + + $adultCount = $room['persons']['adults']; + $childrenCount = $room['persons']['children']; + + $a = $adultCount * $room['price']->getEffectiveComfortPrice();; + $b = $childrenCount * $room['price']->getEffectiveComfortPrice(); + $ret += $a + $b; + + if (isset($outHtmlSummary)) { + $key = intval($room['price']->getEffectiveComfortPrice()); + if (!empty($tempComfortHTML[$key])) { + $tempComfortHTML[$key]['count'] = $tempComfortHTML[$key]['count'] + $adultCount + $childrenCount; + $tempComfortHTML[$key]['value'] = $tempComfortHTML[$key]['value'] + $a + $b; + } else { + $tempComfortHTML[$key] = array( + 'value' => $a + $b, + 'label_first' => 'Komfort-Kategorie', + 'label_last' => Util::formatPrice($room['price']->getEffectiveComfortPrice()) . ' pro Person', + 'count' => $adultCount + $childrenCount, + ); + } + } + if (isset($outPriceInfo)) { + $outPriceInfo['classOptions'][] = [ + 'count' => $room['persons']['total'], + 'name' => 'Komfort (4 Sterne)', + 'price' => $room['price']->getEffectiveComfortPrice() + ]; + } + } + } + + //days before + if ($bookingRequest->getExtraBookingDaysBefore()) { + + $newDay = clone $travelDate->getStart(); + $newDay->modify('-' . $bookingRequest->getExtraBookingDaysBefore() . ' day'); + $newExtraDaysTravelDate['change'] = 1; + $newExtraDaysTravelDate['start'] = $newDay->format('d.m.Y'); + + foreach ($possibleRooms as $room) { + $key = $room['priceType']->getId(); + + $adultCount = $room['persons']['adults']; + $childrenCount = $room['persons']['children']; + + if ($bookingRequest->getComfort()) { + $singleExtraFullPrice = $room['price']->getEffectiveExtraComfortPrice(); + } else { + $singleExtraFullPrice = $room['price']->getEffectiveExtraPrice(); + } + $childExtraPrice = $room['price']->getEffectiveExtraChildPrice(); + + $insuranceAssessmentBasis += $singleExtraFullPrice * $bookingRequest->getExtraBookingDaysBefore(); + $insuranceAssessmentChildBasis += $childExtraPrice * $bookingRequest->getExtraBookingDaysBefore(); + + $roomPrice = (($singleExtraFullPrice * $adultCount) + ($childExtraPrice * $childrenCount)) * $bookingRequest->getExtraBookingDaysBefore(); + + $ret += $roomPrice; + + $outPriceInfo['booking_before'][] = [ + 'name' => "Verlängerung vor der Reise " . $room['priceType']->getName() . "", + 'adults' => $adultCount, + 'children' => $childrenCount, + 'price' => $singleExtraFullPrice, + 'price_children' => $childExtraPrice, + 'price_total' => $roomPrice, + 'days' => $bookingRequest->getExtraBookingDaysBefore() + ]; + + + + if (!empty($tempExtraDaysBeforeHTML[$key])) { + $tempExtraDaysBeforeHTML[$key]['count'] = $tempExtraDaysBeforeHTML[$key]['count'] + 1; + $tempExtraDaysBeforeHTML[$key]['value'] = $tempExtraDaysBeforeHTML[$key]['value'] + $roomPrice; + } else { + $tempExtraDaysBeforeHTML[$key] = array( + 'value' => $roomPrice, + 'label_first' => "Verlängerung vor der Reise " . $room['priceType']->getName() . "", + 'label_last' => Util::formatPrice($singleExtraFullPrice) . ' pro Person/Tag', + 'count' => 1, + 'days' => $bookingRequest->getExtraBookingDaysBefore(), + 'childCount' => $room['persons']['children'], + 'price_child' => Util::formatPrice($room['price']->getEffectiveExtraChildPrice()), + ); + } + } + } + + $tempExtraDaysAfterHTML = array(); + //days after + if ($bookingRequest->getExtraBookingDaysAfter()) { + + $newDay = clone $travelDate->getEnd(); + $newDay->modify('+' . $bookingRequest->getExtraBookingDaysAfter() . ' day'); + $newExtraDaysTravelDate['change'] = 1; + $newExtraDaysTravelDate['end'] = $newDay->format('d.m.Y'); + + foreach ($possibleRooms as $room) { + $key = $room['priceType']->getId(); + + $adultCount = $room['persons']['adults']; + $childrenCount = $room['persons']['children']; + + if ($bookingRequest->getComfort()) { + $singleExtraFullPrice = $room['price']->getEffectiveExtraComfortPrice(); + } else { + $singleExtraFullPrice = $room['price']->getEffectiveExtraPrice(); + } + $childExtraPrice = $room['price']->getEffectiveExtraChildPrice(); + + $insuranceAssessmentBasis += $singleExtraFullPrice * $bookingRequest->getExtraBookingDaysAfter(); + $insuranceAssessmentChildBasis += $childExtraPrice * $bookingRequest->getExtraBookingDaysAfter(); + + $roomPrice = (($singleExtraFullPrice * $adultCount) + ($childExtraPrice * $childrenCount)) * $bookingRequest->getExtraBookingDaysAfter(); + + $ret += $roomPrice; + + $outPriceInfo['booking_after'][] = [ + 'name' => "Verlängerung nach der Reise " . $room['priceType']->getName() . "", + 'adults' => $adultCount, + 'children' => $childrenCount, + 'price' => $singleExtraFullPrice, + 'price_children' => $childExtraPrice, + 'price_total' => $roomPrice, + 'days' => $bookingRequest->getExtraBookingDaysAfter() + ]; + + + + if (!empty($tempExtraDaysAfterHTML[$key])) { + $tempExtraDaysAfterHTML[$key]['count'] = $tempExtraDaysAfterHTML[$key]['count'] + 1; + $tempExtraDaysAfterHTML[$key]['value'] = $tempExtraDaysAfterHTML[$key]['value'] + $roomPrice; + } else { + $tempExtraDaysAfterHTML[$key] = array( + 'value' => $roomPrice, + 'label_first' => "Verlängerung nach der Reise " . $room['priceType']->getName() . "", + 'label_last' => Util::formatPrice($singleExtraFullPrice) . ' pro Person/Tag', + 'count' => 1, + 'days' => $bookingRequest->getExtraBookingDaysAfter(), + 'childCount' => $room['persons']['children'], + 'price_child' => Util::formatPrice($room['price']->getEffectiveExtraChildPrice()), + ); + } + } + } + + + //ROOMS DISCOUNT Versicherungen + foreach ($possibleRooms as $room) { + $adultCount = $room['persons']['adults']; + $childrenCount = $room['persons']['children']; + + $singleFullPrice = $room['price']->getEffectivePrice(); + $childPrice = $room['price']->getEffectiveChildPrice(); + + $roomPrice = ($singleFullPrice * $adultCount) + ($childPrice * $room['persons']['children']); + + + $singleDiscountPrice = $room['price']->getEffectiveDiscountPrice(); + $singleChildDiscountPrice = $room['price']->getEffectiveChildDiscountPrice(); + $discount = ($singleDiscountPrice === null) ? 0 : ($adultCount * ($singleDiscountPrice - $singleFullPrice)); + $childDiscount = ($singleChildDiscountPrice === null) ? 0 : ($childrenCount * ($singleChildDiscountPrice - $childPrice)); + + $ret += $roomPrice + $discount + $childDiscount; + + $singel_flight_price = $travelDate->getFlightCalcPrice(); + $outPriceInfo['flight_price'] += (($singel_flight_price * $adultCount) + ($singel_flight_price * $room['persons']['children'])); + + //Room price + if (isset($outPriceInfo)) { + $price = $singleDiscountPrice ?? $singleFullPrice; + $price += $singleChildDiscountPrice ?? $childPrice; + + $outPriceInfo['rooms'][] = [ + 'name' => $room['priceType']->getName(), + 'adults' => $adultCount, + 'children' => $childrenCount, + 'price' => $singleDiscountPrice ?? $singleFullPrice, + 'price_children' => $singleChildDiscountPrice ?? $childPrice, + 'price_total' => $roomPrice + $discount + $childDiscount, + 'price_full' => $singleFullPrice, + 'price_children_full' => $childPrice, + 'price_total_full' => $roomPrice, + ]; + } + + + //Room html + if (isset($outHtmlSummary)) { + //ROOMS + $key = $room['priceType']->getId(); + if (!empty($tempRoomHTML[$key])) { + $tempRoomHTML[$key]['count'] = $tempRoomHTML[$key]['count'] + 1; + $tempRoomHTML[$key]['value'] = $tempRoomHTML[$key]['value'] + $roomPrice; + } else { + $tempRoomHTML[$key] = array( + 'value' => $roomPrice, + 'label_first' => $room['priceType']->getName(), + 'label_last' => Util::formatPrice($singleFullPrice) . ' pro Person', + 'count' => 1, + 'childCount' => $room['persons']['children'], + 'price_child' => Util::formatPrice($room['price']->getEffectiveChildPrice()), + ); + } + + //DISCOUNT + if ($singleDiscountPrice !== null) { + $key = intval(($singleFullPrice - $singleDiscountPrice) * 100); + if (!empty($tempDiscountHTML[$key])) { + $tempDiscountHTML[$key]['count'] = $tempDiscountHTML[$key]['count'] + $adultCount; + $tempDiscountHTML[$key]['value'] = $tempDiscountHTML[$key]['value'] + $discount; + } else { + $tempDiscountHTML[$key] = array( + 'value' => $discount, + 'label_first' => 'Rabatt', + 'label_last' => Util::formatPrice($singleFullPrice - $singleDiscountPrice) . ' pro Person', + 'count' => $adultCount, + ); + } + if ($childDiscount > 0) { + $key = intval(($childPrice - $singleChildDiscountPrice) * 100); + if (!empty($tempDiscountHTML[$key])) { + $tempDiscountHTML[$key]['count'] = $tempDiscountHTML[$key]['count'] + $childrenCount; + $tempDiscountHTML[$key]['value'] = $tempDiscountHTML[$key]['value'] + $childDiscount; + } else { + $tempDiscountHTML[$key] = array( + 'value' => $childDiscount, + 'label_first' => 'Rabatt', + 'label_last' => Util::formatPrice($childPrice - $singleChildDiscountPrice) . ' pro Person', + 'count' => $childrenCount, + ); + } + } + if (isset($outPriceInfo)) { + $key = intval(($singleFullPrice - $singleDiscountPrice) * 100); + if (!empty($outPriceInfo['discount'][$key])) { + $outPriceInfo['discount'][$key]['count'] = $outPriceInfo['discount'][$key]['count'] + $adultCount; + $outPriceInfo['discount'][$key]['value'] = $outPriceInfo['discount'][$key]['value'] + $discount; + } else { + $outPriceInfo['discount'][$key] = array( + 'value' => $discount, + 'price_discount' => ($singleFullPrice - $singleDiscountPrice), + 'label_first' => 'Rabatt', + 'label_last' => Util::formatPrice($singleFullPrice - $singleDiscountPrice) . ' pro Person', + 'count' => $adultCount, + ); + } + if ($childDiscount > 0) { + $key = intval(($childPrice - $singleChildDiscountPrice) * 100); + if (!empty($outPriceInfo['discount'][$key])) { + $outPriceInfo['discount'][$key]['count'] = $outPriceInfo['discount'][$key]['count'] + $childrenCount; + $outPriceInfo['discount'][$key]['value'] = $outPriceInfo['discount'][$key]['value'] + $childDiscount; + } else { + $outPriceInfo['discount'][$key] = array( + 'value' => $childDiscount, + 'label_first' => 'Rabatt', + 'label_last' => Util::formatPrice($childPrice - $singleChildDiscountPrice) . ' pro Person', + 'count' => $childrenCount, + ); + } + } + } + } + + //Versicherung price + html + if ($bookingRequest->getInsurance() && $adultCount > 0) { + + $curAssessmentBasis = $insuranceAssessmentBasis + ($singleDiscountPrice ?? $singleFullPrice); + $curAssessmentChildBasis = $insuranceAssessmentChildBasis + ($singleChildDiscountPrice ?? $childPrice); + $insurancePrice = $this->getDoctrine()->getRepository('AppBundle:TravelInsurancePrice') + ->findOneByInsuranceIdAndAssessmentBasis($bookingRequest->getInsurance()->getId(), $curAssessmentBasis); + + $insuranceChildPrice = $this->getDoctrine()->getRepository('AppBundle:TravelInsurancePrice') + ->findOneByInsuranceIdAndAssessmentBasis($bookingRequest->getInsurance()->getId(), $curAssessmentChildBasis); + + $insurancePriceValue = $insurancePrice->getPrice() > 0 ? $insurancePrice->getPrice() : round($insurancePrice->getPercent() * $curAssessmentBasis / 100, 2); + $insuranceChildPriceValue = $insuranceChildPrice->getPrice() > 0 ? $insuranceChildPrice->getPrice() : round($insuranceChildPrice->getPercent() * $curAssessmentChildBasis / 100, 2); + + + $a = $adultCount * $insurancePriceValue; + $b = $childrenCount * $insuranceChildPriceValue; + $insuranceTotal += $a + $b; + $ret += $a + $b; + + if (isset($insuranceHtmlSummary)) { + if (!empty($tempInsuranceHTML[$insurancePriceValue])) { + $tempInsuranceHTML[$insurancePriceValue]['count'] = intval($tempInsuranceHTML[$insurancePriceValue]['count']) + $adultCount; + $tempInsuranceHTML[$insurancePriceValue]['value'] = $tempInsuranceHTML[$insurancePriceValue]['value'] + $a; + } else { + $tempInsuranceHTML[$insurancePriceValue] = array( + 'value' => $a, + 'label_first' => 'RV ' . $bookingRequest->getInsurance()->getName() . ' (' . $insurancePrice->getCode() . ') ', + 'label_last' => Util::formatPrice($insurancePriceValue) . ' pro Person', + 'count' => $adultCount, + + ); + } + if ($b > 0) { + if (!empty($tempInsuranceHTML[$insuranceChildPriceValue])) { + $tempInsuranceHTML[$insuranceChildPriceValue]['count'] = intval($tempInsuranceHTML[$insuranceChildPriceValue]['count']) + $childrenCount; + $tempInsuranceHTML[$insuranceChildPriceValue]['value'] = $tempInsuranceHTML[$insuranceChildPriceValue]['value'] + $b; + } else { + $tempInsuranceHTML[$insuranceChildPriceValue] = array( + 'value' => $b, + 'label_first' => 'RV ' . $bookingRequest->getInsurance()->getName() . ' (' . $insuranceChildPrice->getCode() . ') ', + 'label_last' => Util::formatPrice($insuranceChildPriceValue) . ' pro Kind', + 'count' => $childrenCount, + + ); + } + } + } + if (isset($outPriceInfo)) { + if (!empty($outPriceInfo['insurancesOut'][$insurancePriceValue])) { + $outPriceInfo['insurancesOut'][$insurancePriceValue]['count'] = intval($outPriceInfo['insurancesOut'][$insurancePriceValue]['count']) + $childrenCount; + $outPriceInfo['insurancesOut'][$insurancePriceValue]['value'] = $outPriceInfo['insurancesOut'][$insurancePriceValue]['value'] + $b; + } else { + $outPriceInfo['insurancesOut'][$insurancePriceValue] = [ + 'value' => $a, + 'label_first' => 'RV ' . $bookingRequest->getInsurance()->getName() . ' (' . $insurancePrice->getCode() . ') ', + 'label_last' => Util::formatPrice($insurancePriceValue) . ' pro Person', + 'count' => $adultCount, + ]; + } + if ($b > 0) { + if (!empty($outPriceInfo['insurancesOut'][$insuranceChildPriceValue])) { + $outPriceInfo['insurancesOut'][$insuranceChildPriceValue]['count'] = intval($outPriceInfo['insurancesOut'][$insuranceChildPriceValue]['count']) + $childrenCount; + $outPriceInfo['insurancesOut'][$insuranceChildPriceValue]['value'] = $outPriceInfo['insurancesOut'][$insuranceChildPriceValue]['value'] + $b; + } else { + $outPriceInfo['insurancesOut'][$insuranceChildPriceValue] = [ + 'value' => $b, + 'label_first' => 'RV ' . $bookingRequest->getInsurance()->getName() . ' (' . $insuranceChildPrice->getCode() . ') ', + 'label_last' => Util::formatPrice($insuranceChildPriceValue) . ' pro Kind', + 'count' => $childrenCount, + ]; + } + } + + $outPriceInfo['insurances'][] = [ + 'insurance' => $bookingRequest->getInsurance(), + 'insurancePriceValue' => $insurancePriceValue, + 'insurancePrice' => $insurancePrice, + 'count' => $adultCount, + 'insuranceChildPriceValue' => $insuranceChildPriceValue, + 'insuranceChildPrice' => $insuranceChildPrice, + 'countChild' => $childrenCount, + ]; + } + } + } + } + + + //ROOMS + if (count($tempRoomHTML) > 0) { + foreach ($tempRoomHTML as $item) { + $label = '' . $item['count'] . ' x ' . $item['label_first'] . ' [' . $item['label_last'] . ']'; + if ($item['childCount'] > 0) { + $label .= ' [ + Kind: ' . $item['price_child']; + } + $label .= ']'; + $outHtmlSummary[] = [ + 'value' => $item['value'], + 'label' => $label, + ]; + } + } + + //Comfort + if (count($tempComfortHTML) > 0) { + foreach ($tempComfortHTML as $item) { + $outHtmlSummary[] = [ + 'value' => $item['value'], + 'label' => '' . $item['count'] . ' x ' . $item['label_first'] . ' [' . $item['label_last'] . ' ]', + ]; + } + } + + //Departure + if (count($tempDepartureHTML) > 0) { + foreach ($tempDepartureHTML as $item) { + $outHtmlSummary[] = [ + 'value' => $item['value'], + 'label' => '' . $item['count'] . ' x ' . $item['label_first'] . ' [' . $item['label_last'] . ' ]', + ]; + } + } + + //DISCOUNT + if (count($tempDiscountHTML) > 0) { + foreach ($tempDiscountHTML as $item) { + $insuranceHtmlSummary[] = [ + 'value' => $item['value'], + 'label' => '' . $item['count'] . ' x ' . $item['label_first'] . ' [' . $item['label_last'] . ' ]', + ]; + } + } + //options + if (count($tempOptionHTML) > 0) { + foreach ($tempOptionHTML as $item) { + $label = '' . $item['count'] . ' x ' . $item['label_first'] . ' [' . $item['label_last'] . ']'; + if ($item['childCount'] > 0) { + $label .= ' [' . $item['price_child'] . ']'; + } + $outHtmlSummary[] = [ + 'value' => $item['value'], + 'label' => $label, + ]; + } + } + + //extra days before + if (count($tempExtraDaysBeforeHTML) > 0) { + foreach ($tempExtraDaysBeforeHTML as $item) { + $setDays = $item['days'] . ($item['days'] == 1 ? ' Tag' : ' Tage'); + $label = '' . $item['count'] . ' x ' . $setDays . ' ' . $item['label_first'] . ' [' . $item['label_last'] . ']'; + if ($item['childCount'] > 0) { + $label .= ' [+ Kind: ' . $item['price_child'] . ']'; + } + $outHtmlSummary[] = [ + 'value' => $item['value'], + 'label' => $label, + ]; + } + } + + //extra days after + if (count($tempExtraDaysAfterHTML) > 0) { + foreach ($tempExtraDaysAfterHTML as $item) { + $setDays = $item['days'] . ($item['days'] == 1 ? ' Tag' : ' Tage'); + $label = '' . $item['count'] . ' x ' . $setDays . ' ' . $item['label_first'] . ' [' . $item['label_last'] . ']'; + if ($item['childCount'] > 0) { + $label .= ' [+ Kind: ' . $item['price_child'] . ']'; + } + $outHtmlSummary[] = [ + 'value' => $item['value'], + 'label' => $label, + ]; + } + } + + + //Versicherungen + if (count($tempInsuranceHTML) > 0) { + foreach ($tempInsuranceHTML as $item) { + $insuranceHtmlSummary[] = [ + 'value' => $item['value'], + 'label' => '' . $item['count'] . ' x ' . $item['label_first'] . ' [' . $item['label_last'] . ' ]', + ]; + } + } + + + + + if (isset($insuranceHtmlSummary)) { + $outHtmlSummary = array_merge($outHtmlSummary, $insuranceHtmlSummary); + } + if ($newExtraDaysTravelDate['change'] == 1) { + $outHtmlSummary[] = [ + 'value' => '!', + 'label' => "Geänderter Reisezeitraum: " . $newExtraDaysTravelDate['start'] . " - " . $newExtraDaysTravelDate['end'], + ]; + } + + if (isset($outPriceInfo)) { + $outPriceInfo['total'] = $ret; + $outPriceInfo['totalWithoutInsurance'] = $ret - $insuranceTotal; + $outPriceInfo['totalInsurance'] = $insuranceTotal; + + if ($outPriceInfo['departure_extra'] >= 0) { + $outPriceInfo['flight_price'] = $outPriceInfo['flight_price'] + $outPriceInfo['departure_extra']; + } else { + $outPriceInfo['flight_price'] = 0; + } + + if ($depositPercent === null) { + $depositPercent = 20; + } + //Aeqypten (20% from price) + if ($categoryId == 1) { + $deposit = ($outPriceInfo['totalWithoutInsurance'] / 100 * $depositPercent); + $outPriceInfo['deposit_total'] = $deposit; + $outPriceInfo['final_payment'] = ($outPriceInfo['totalWithoutInsurance'] - $outPriceInfo['deposit_total']); + } else { + //all 100% vom Flugpreis und 20% von der Landleistung. + $deposit = (($outPriceInfo['totalWithoutInsurance'] - $outPriceInfo['flight_price']) / 100 * $depositPercent); + $outPriceInfo['deposit_total'] = ($deposit + $outPriceInfo['flight_price']); + $outPriceInfo['final_payment'] = ($outPriceInfo['totalWithoutInsurance'] - $outPriceInfo['deposit_total']); + } + } + + return $ret; + } + + /** + * @param TravelPeriodPrice[] $prices + * @param $persons + * + * @return array + */ + private function getRooms($prices, $persons) + { + $ret = []; + + foreach ($prices as $price) { + $priceTypeId = $price->getPriceTypeId(); + //with children + $priceType = $this->priceTypeById[$priceTypeId]; + + if ($priceTypeId == 1 && $persons['singleRoomPersons'] > 0) { + for ($i = 0; $i < $persons['singleRoomPersons']; $i++) { + $currentPersons = [ + 'total' => 1, + 'adults' => 1, + 'children' => 0 //TODO + ]; + + $ret[] = [ + 'priceType' => $priceType, + 'persons' => $currentPersons, + 'price' => $price + ]; + } + } + + if ($priceTypeId == 1 && $persons['singleRoomChildPersons'] > 0) { + $priceTypeId = 2; + $priceType = $this->priceTypeById[$priceTypeId]; + + for ($i = 0; $i < $persons['singleRoomChildPersons']; $i++) { + $currentPersons = [ + 'total' => 1, + 'adults' => 1, + 'children' => 1 + ]; + + $ret[] = [ + 'priceType' => $priceType, + 'persons' => $currentPersons, + 'price' => $price + ]; + } + } + + if ($priceTypeId == 3 && $persons['doubleRoomPersons'] > 0) { + for ($j = 0; $j < ($persons['doubleRoomPersons'] / 2); $j++) { + $currentPersons = [ + 'total' => 2, + 'adults' => 2, + 'children' => 0 + ]; + + $ret[] = [ + 'priceType' => $priceType, + 'persons' => $currentPersons, + 'price' => $price + ]; + } + } + + if ($priceTypeId == 3 && $persons['doubleRoomChildPersons'] > 0) { + $priceTypeId = 4; + $priceType = $this->priceTypeById[$priceTypeId]; + + for ($j = 0; $j < ($persons['doubleRoomChildPersons'] / 2); $j++) { + $currentPersons = [ + 'total' => 2, + 'adults' => 2, + 'children' => 1 + ]; + + $ret[] = [ + 'priceType' => $priceType, + 'persons' => $currentPersons, + 'price' => $price + ]; + } + } + + if ($priceTypeId == 5 && $persons['tripleRoomPersons'] > 0) { + for ($k = 0; $k < ($persons['tripleRoomPersons'] / 3); $k++) { + $currentPersons = [ + 'total' => 3, + 'adults' => 3, + 'children' => 0 + ]; + + $ret[] = [ + 'priceType' => $priceType, + 'persons' => $currentPersons, + 'price' => $price + ]; + } + } + + if ($priceTypeId == 5 && $persons['tripleRoomChildPersons'] > 0) { + $priceTypeId = 7; + $priceType = $this->priceTypeById[$priceTypeId]; + + for ($k = 0; $k < ($persons['tripleRoomChildPersons'] / 3); $k++) { + $currentPersons = [ + 'total' => 3, + 'adults' => 3, + 'children' => 1 + ]; + + $ret[] = [ + 'priceType' => $priceType, + 'persons' => $currentPersons, + 'price' => $price + ]; + } + } + } + + return $ret; + } +} diff --git a/src/AppBundle/Controller/ComponentController.php b/src/AppBundle/Controller/ComponentController.php index bffc6671..c60beac9 100644 --- a/src/AppBundle/Controller/ComponentController.php +++ b/src/AppBundle/Controller/ComponentController.php @@ -32,10 +32,32 @@ class ComponentController extends Controller if(!$this->headerContent){ $this->headerContent = Util::loadFromApi('cms/header/info', ['url'=>""]); } + if (!$this->headerContent) { + $this->headerContent = $this->getEmptyHeaderContent(); + } return $this->headerContent; } + private function getEmptyHeaderContent() + { + $inactive = (object) ['active' => 0, 'content' => '']; + + return (object) [ + 'info' => (object) [ + 'office_important_note_active' => 0, + 'office_important_note' => '', + 'office_appointment' => '', + ], + 'available' => (object) [ + 'phone' => $inactive, + 'local' => $inactive, + ], + 'local' => (object) [], + 'phone' => (object) [], + ]; + } + public function getHeaderTravelProgram($page){ $programmes = [ @@ -344,6 +366,18 @@ class ComponentController extends Controller ]); } + public function newsSidebarWidgetAction($title = 'News', $limit = 3) + { + $limit = max(1, min(12, (int) $limit)); + + return $this->render('default/components/sidebar/pageSliderSidebarWidget.html.twig', [ + 'slider_title' => $title, + 'target_widget' => 'news-widget', + 'pages' => $this->getEntityManager()->getRepository('AppBundle:Page')->findHomepageNews($limit), + 'theme' => 'gray-box', + ]); + } + public function makeSidebarWidgetAction($site_loading = 'default', Page $page = null, $api=null, $search_form = null){ $show_seal_of_approval = false; diff --git a/src/AppBundle/Controller/DefaultController.php b/src/AppBundle/Controller/DefaultController.php index 6567e588..2a08f508 100644 --- a/src/AppBundle/Controller/DefaultController.php +++ b/src/AppBundle/Controller/DefaultController.php @@ -99,12 +99,30 @@ class DefaultController extends Controller } $pageRepo = $this->getEntityManager()->getRepository('AppBundle:Page'); + $sidebarWidgetRepo = $this->getEntityManager()->getRepository('AppBundle:SidebarWidget'); + $plannableTripsWidget = $sidebarWidgetRepo->findActiveWidgetByComponent('homepagePlannableTrips'); + $popularTripsWidget = $sidebarWidgetRepo->findActiveWidgetByComponent('homepagePopularTrips'); + $newsWidget = $sidebarWidgetRepo->findActiveWidgetByComponent('newsSidebarWidget', 'home'); + $homepageOfferPages = $popularTripsWidget + ? $pageRepo->findActiveTravelPagesByIds($popularTripsWidget->getConfigPageIds()) + : []; + $devHomeSidebarOfferPages = $plannableTripsWidget + ? $pageRepo->findActiveTravelPagesByIds($plannableTripsWidget->getConfigPageIds()) + : []; + + if (empty($homepageOfferPages)) { + $homepageOfferPages = $pageRepo->findHomepageOffers(); + } + if (empty($devHomeSidebarOfferPages)) { + $devHomeSidebarOfferPages = $pageRepo->findHomepageOffers(4); + } + $fewoLodgings = []; $lodgingGroups = $this->getEntityManager()->getRepository('AppBundle:FewoLodgingGroup')->findAll(); foreach ($lodgingGroups as $lodgingGroup) { foreach ($lodgingGroup->getLodgings() as $lodging) { $fewoLodgings[] = $lodging; - if (count($fewoLodgings) >= 3) { + if (count($fewoLodgings) >= 8) { break 2; } } @@ -121,9 +139,18 @@ class DefaultController extends Controller 'e' => $search_request_e ? $search_request_e : null, ])->createView(), 'tt_search_form' => $this->createForm(TtSearchRequestType::class)->createView(), - 'homepage_offer_pages' => $pageRepo->findHomepageOffers(), + 'homepage_offer_pages' => $homepageOfferPages, + 'homepage_offer_title' => $popularTripsWidget && $popularTripsWidget->getName() ? $popularTripsWidget->getName() : 'beliebtesten Kulturreisen', + 'homepage_offer_new_page_ids' => $popularTripsWidget ? $popularTripsWidget->getConfigNewPageIds() : [], 'country_pages' => $pageRepo->findHomepageCountryPages(), 'fewo_lodgings' => $fewoLodgings, + 'dev_home_sidebar' => true, + 'dev_home_sidebar_offer_title' => $plannableTripsWidget && $plannableTripsWidget->getName() ? $plannableTripsWidget->getName() : 'Aktuell planbare Reisen', + 'dev_home_sidebar_offer_pages' => $devHomeSidebarOfferPages, + 'dev_home_sidebar_new_badge_active' => $plannableTripsWidget ? $plannableTripsWidget->getConfigNewBadgeActive() : false, + 'dev_home_sidebar_new_page_ids' => $plannableTripsWidget ? $plannableTripsWidget->getConfigNewPageIds() : [], + 'dev_home_sidebar_news_title' => $newsWidget && $newsWidget->getName() ? $newsWidget->getName() : 'Reisenews', + 'dev_home_sidebar_news_pages' => $pageRepo->findHomepageNews($newsWidget ? $newsWidget->getConfigNewsLimit() : 3), ]); } diff --git a/src/AppBundle/Entity/BookingRequest.php b/src/AppBundle/Entity/BookingRequest.php index aca69090..8597f518 100644 --- a/src/AppBundle/Entity/BookingRequest.php +++ b/src/AppBundle/Entity/BookingRequest.php @@ -1,968 +1,991 @@ - - * @date 12/16/2016 - */ - -namespace AppBundle\Entity; - -use Symfony\Component\Validator\Constraints as Assert; -use AppBundle\Validator\Constraints as AppBundleAssert; -use Symfony\Component\Validator\Context\ExecutionContextInterface; - -/** - * Class BookingRequest - * @package AppBundle\Entity - * @AppBundleAssert\BookingRequest - */ -class BookingRequest -{ - // Used in SternToursCrmBookingExports, expected to be equivalent to sex (as defined in Traveler) - const MR = 1; - const MRS = 2; - const DIV = 3; - - - /** - * @var TravelDeparturePoint $departure - */ - private $departure; - - private $singleRoomCount; - - private $doubleRoomCount; - - private $tripleRoomCount; - - private $singleRoomChildCount; - - private $doubleRoomChildCount; - - private $tripleRoomChildCount; - - - private $extraBookingDaysBefore; - - private $extraBookingDaysAfter; - - private $roomCount; - - /** - * @var TravelInsurance $insurance - */ - private $insurance; - - private $comfort = false; - - private $travelOptions = []; - - private $salutation; - - private $insuranceOffer; - - /** - * @Assert\NotBlank() - */ - private $firstName; - - /** - * @Assert\NotBlank() - */ - private $lastName; - - /** - * @Assert\NotBlank() - */ - private $streetAddress; - - /** - * @Assert\NotBlank() - */ - private $zipCode; - - /** - * @Assert\NotBlank() - */ - private $city; - - private $nation; - - /** - * @Assert\NotBlank() - */ - private $phone; - - private $mobile; - - /** - * @Assert\NotBlank() - */ - private $email; - - private $travelers = []; - - private $singleRooms = []; - private $doubleRooms = []; - private $tripleRooms = []; - - private $singleChildRooms = []; - private $doubleChildRooms = []; - private $tripleChildRooms = []; - - private $notes; - - /** - * @Assert\IsTrue() - */ - private $acceptTerms = false; - - private $acceptLegalRights = false; - - private $acceptPrivacy = false; - - /** - * BookingRequest constructor. - */ - public function __construct() - { - for($i = 0; $i < 4; ++$i) - { - $this->singleRooms[] = new Room(1); - } - for($i = 0; $i < 4; ++$i) - { - $this->singleChildRooms[] = new Room(4); - } - for($i = 0; $i < 3; ++$i) - { - $this->doubleRooms[] = new Room(2); - } - for($i = 0; $i < 3; ++$i) - { - $this->doubleChildRooms[] = new Room(5); - } - for($i = 0; $i < 2; ++$i) - { - $this->tripleRooms[] = new Room(3); - } - for($i = 0; $i < 2; ++$i) - { - $this->tripleChildRooms[] = new Room(6); - } - } - - /** - * @return TravelDeparturePoint - */ - public function getDeparture() - { - return $this->departure; - } - - /** - * @param TravelDeparturePoint $departure - */ - public function setDeparture(TravelDeparturePoint $departure) - { - $this->departure = $departure; - } - - /** - * @return mixed - */ - public function getTravelerCount() - { - $allUsedTravelersCount = 0; - for($i = 0; $i < $this->singleRoomCount; ++$i) - { - $allUsedTravelersCount += $this->singleRooms[$i]->getTravelerCount(); - } - for($i = 0; $i < $this->singleRoomChildCount; ++$i) - { - $allUsedTravelersCount += $this->singleChildRooms[$i]->getTravelerCount(); - } - - for($i = 0; $i < $this->doubleRoomCount; ++$i) - { - $allUsedTravelersCount += $this->doubleRooms[$i]->getTravelerCount(); - } - for($i = 0; $i < $this->doubleRoomChildCount; ++$i) - { - $allUsedTravelersCount += $this->doubleChildRooms[$i]->getTravelerCount(); - } - for($i = 0; $i < $this->tripleRoomCount; ++$i) - { - $allUsedTravelersCount += $this->tripleRooms[$i]->getTravelerCount(); - } - for($i = 0; $i < $this->tripleRoomChildCount; ++$i) - { - $allUsedTravelersCount += $this->tripleChildRooms[$i]->getTravelerCount(); - } - - return $allUsedTravelersCount; - } - - public function getChildrenCount() - { - $allUsedChildrenCount = 0; - for($i = 0; $i < $this->singleRoomCount; ++$i) - { - $allUsedChildrenCount += 0;//$this->singleRooms[$i]->getTravelerCount(); - } - for($i = 0; $i < $this->singleRoomChildCount; ++$i) - { - $allUsedChildrenCount += 1;//$this->singleRooms[$i]->getTravelerCount(); - } - for($i = 0; $i < $this->doubleRoomCount; ++$i) - { - $allUsedChildrenCount += 0;//$this->singleRooms[$i]->getTravelerCount(); - } - for($i = 0; $i < $this->doubleRoomChildCount; ++$i) - { - $allUsedChildrenCount += 1;//$this->singleRooms[$i]->getTravelerCount(); - } - for($i = 0; $i < $this->tripleRoomCount; ++$i) - { - $allUsedChildrenCount += 0;//$this->singleRooms[$i]->getTravelerCount(); - } - for($i = 0; $i < $this->tripleRoomChildCount; ++$i) - { - $allUsedChildrenCount += 1;//$this->singleRooms[$i]->getTravelerCount(); - } - - return $allUsedChildrenCount; - } - - /** - * @param mixed $travelerCount - */ - public function setTravelerCount($travelerCount) - { - $this->travelerCount = $travelerCount; - } - - /** - * @return mixed - */ - public function getRoomCount() - { - return $this->roomCount; - } - - /** - * @param mixed $travelers - */ - public function setRoomCount($travelers) - { - // nicht so kompliziert - // übliche Anzahl der Reisenden war 2 -> Standardraum: 1 Doppelzimmer - $this->travelerCount = $travelers; - if($travelers % 2 != 0) - { - $times = ($travelers - 1) / 2; - $this->singleRoomCount = 1; - $this->doubleRoomCount = $times; - $this->tripleRoomCount = 0; - $this->roomCount = $times + 1; - } - else - { - $times = $travelers / 2; - $this->singleRoomCount = 0; - $this->doubleRoomCount = $times; - $this->tripleRoomCount = 0; - $this->roomCount = $times; - } - } - - /** - * @return mixed - */ - public function getSingleRoomCount() - { - return $this->singleRoomCount; - } - - /** - * @param mixed $singleRoomCount - */ - public function setSingleRoomCount($singleRoomCount) - { - $this->singleRoomCount = $singleRoomCount; - } - - /** - * @return mixed - */ - public function getDoubleRoomCount() - { - return $this->doubleRoomCount; - } - - /** - * @param mixed $doubleRoomCount - */ - public function setDoubleRoomCount($doubleRoomCount) - { - $this->doubleRoomCount = $doubleRoomCount; - } - - /** - * @return mixed - */ - public function getTripleRoomCount() - { - return $this->tripleRoomCount; - } - - /** - * @param mixed $tripleRoomCount - */ - public function setTripleRoomCount($tripleRoomCount) - { - $this->tripleRoomCount = $tripleRoomCount; - } - - - /** - * @return mixed - */ - public function getSingleRoomChildCount() - { - return $this->singleRoomChildCount; - } - - /** - * @param mixed $singleRoomChildCount - */ - public function setSingleRoomChildCount($singleRoomChildCount) - { - $this->singleRoomChildCount = $singleRoomChildCount; - } - - /** - * @return mixed - */ - public function getDoubleRoomChildCount() - { - return $this->doubleRoomChildCount; - } - - /** - * @param mixed $doubleRoomChildCount - */ - public function setDoubleRoomChildCount($doubleRoomChildCount) - { - $this->doubleRoomChildCount = $doubleRoomChildCount; - } - - /** - * @return mixed - */ - public function getTripleRoomChildCount() - { - return $this->tripleRoomChildCount; - } - - /** - * @param mixed $tripleRoomChildCount - */ - public function setTripleRoomChildCount($tripleRoomChildCount) - { - $this->tripleRoomChildCount = $tripleRoomChildCount; - } - - /** - * @return mixed - */ - public function getExtraBookingDaysBefore() - { - return $this->extraBookingDaysBefore; - } - - /** - * @param mixed $extraBookingDaysBefore - */ - public function setExtraBookingDaysBefore($extraBookingDaysBefore) - { - $this->extraBookingDaysBefore = $extraBookingDaysBefore; - } - - /** - * @return mixed - */ - public function getExtraBookingDaysAfter() - { - return $this->extraBookingDaysAfter; - } - - /** - * @param mixed $extraBookingDaysAfter - */ - public function setExtraBookingDaysAfter($extraBookingDaysAfter) - { - $this->extraBookingDaysAfter = $extraBookingDaysAfter; - } - - - /** - * @return TravelInsurance - */ - public function getInsurance() - { - return $this->insurance; - } - - /** - * @param TravelInsurance $insurance - */ - public function setInsurance(TravelInsurance $insurance) - { - $this->insurance = $insurance; - } - - - /** - * @return mixed - */ - public function getComfort() - { - return $this->comfort; - } - - /** - * @param mixed $comfort - */ - public function setComfort($comfort) - { - $this->comfort = $comfort; - } - - /** - * @return TravelOption[] - */ - public function getTravelOptions() - { - return $this->travelOptions; - } - - /** - * @param mixed $travelOptions - */ - public function setTravelOptions($travelOptions) - { - $this->travelOptions = $travelOptions; - } - - /** - * @return int - */ - public function getSalutation() - { - return $this->salutation; - } - - /** - * @param int $salutation - */ - public function setSalutation($salutation) - { - $this->salutation = $salutation; - } - - public function getSalutationName() - { - switch ($this->salutation) { - case 1: - return 'Herr'; - break; - case 2: - return 'Frau'; - break; - case 3: - return 'Divers/keine Anrede'; - break; - } - return ''; - } - - public function getSalutationDear() - { - switch ($this->salutation) { - case 1: - return 'geehrter'; - break; - case 2: - return 'geehrte'; - break; - case 3: - return 'geehrte:r'; - break; - } - return ''; - } - - public function getSalutationApplicant() - { - switch ($this->salutation) { - case 1: - return 'Reiseanmelder'; - break; - case 2: - return 'Reiseanmelderin'; - break; - case 3: - return 'Reiseanmelder:in'; - break; - } - return ''; - } - - - /** - * @return string - */ - public function getFirstName() - { - return $this->firstName; - } - - /** - * @param string $firstName - */ - public function setFirstName($firstName) - { - $this->firstName = $firstName; - } - - /** - * @return string - */ - public function getLastName() - { - return $this->lastName; - } - - /** - * @param string $lastName - */ - public function setLastName($lastName) - { - $this->lastName = $lastName; - } - - /** - * @return string - */ - public function getStreetAddress() - { - return $this->streetAddress; - } - - /** - * @param string $streetAddress - */ - public function setStreetAddress($streetAddress) - { - $this->streetAddress = $streetAddress; - } - - /** - * @return string - */ - public function getZipCode() - { - return $this->zipCode; - } - - /** - * @param string $zipCode - */ - public function setZipCode($zipCode) - { - $this->zipCode = $zipCode; - } - - /** - * @return string - */ - public function getCity() - { - return $this->city; - } - - /** - * @param string $city - */ - public function setCity($city) - { - $this->city = $city; - } - - /** - * @return int - */ - public function getNation() - { - return $this->nation; - } - - /** - * @param int $nation - */ - public function setNation($nation) - { - $this->nation = $nation; - } - - /** - * @return int - */ - public function getInsuranceOffer() - { - return $this->insuranceOffer; - } - - /** - * @param int $insuranceOffer - */ - public function setInsuranceOffer($insuranceOffer) - { - $this->insuranceOffer = $insuranceOffer; - } - - /** - * @return string - */ - public function getPhone() - { - return $this->phone; - } - - /** - * @param string $phone - */ - public function setPhone($phone) - { - $this->phone = $phone; - } - - /** - * @return string - */ - public function getMobile() - { - return $this->mobile; - } - - /** - * @param string $mobile - */ - public function setMobile($mobile) - { - $this->mobile = $mobile; - } - - /** - * @return string - */ - public function getEmail() - { - return $this->email; - } - - /** - * @param string $email - */ - public function setEmail($email) - { - $this->email = $email; - } - - // get und set der Travelers liegt jetzt in Room; sollte so nicht mehr verwendet werden! - /** - * @return Traveler[] - */ - public function getTravelers() - { - $allUsedTravelers = []; - - // könnte man eventuell in eine for-Schleife packen, wenn man garantiert, dass es immer gleich viele Räume von jedem Typ gibt - for ($i = 0; $i < $this->singleRoomCount; ++$i) - { - $allUsedTravelers = array_merge($allUsedTravelers, $this->singleRooms[$i]->getTravelers()); - } - for ($i = 0; $i < $this->singleRoomChildCount; ++$i) - { - $allUsedTravelers = array_merge($allUsedTravelers, $this->singleChildRooms[$i]->getTravelers()); - } - - for ($i = 0; $i < $this->doubleRoomCount; ++$i) - { - $allUsedTravelers = array_merge($allUsedTravelers, $this->doubleRooms[$i]->getTravelers()); - } - for ($i = 0; $i < $this->doubleRoomChildCount; ++$i) - { - $allUsedTravelers = array_merge($allUsedTravelers, $this->doubleChildRooms[$i]->getTravelers()); - } - for ($i = 0; $i < $this->tripleRoomCount; ++$i) - { - $allUsedTravelers = array_merge($allUsedTravelers, $this->tripleRooms[$i]->getTravelers()); - } - for ($i = 0; $i < $this->tripleRoomChildCount; ++$i) - { - $allUsedTravelers = array_merge($allUsedTravelers, $this->tripleChildRooms[$i]->getTravelers()); - } - -// $this->travelers = $allUsedTravelers; // schlecht, getter sollte kein setter sein -// return $this->travelers; // aber wenn man es so verwenden würde, dann sollte man auch das verwenden - return $allUsedTravelers; - } - - /** - * @param Traveler[] $travelers - */ - public function setTravelers($travelers) - { - $this->travelers = $travelers; - } - - /** - * @return Room[] - */ - public function getSingleRooms() - { - return $this->singleRooms; - } - - /** - * @param Room[] $singleRooms - */ - public function setSingleRooms($singleRooms) - { - $this->singleRooms = $singleRooms; - } - - /** - * @return Room[] - */ - public function getDoubleRooms() - { - return $this->doubleRooms; - } - - /** - * @param Room[] $doubleRooms - */ - public function setDoubleRooms($doubleRooms) - { - $this->doubleRooms = $doubleRooms; - } - - /** - * @return Room[] - */ - public function getTripleRooms() - { - return $this->tripleRooms; - } - - /** - * @param Room[] $tripleRooms - */ - public function setTripleRooms($tripleRooms) - { - $this->tripleRooms = $tripleRooms; - } - - /** - * @return Room[] - */ - public function getSingleChildRooms() - { - return $this->singleChildRooms; - } - - /** - * @param Room[] $singleChildRooms - */ - public function setSingleChildRooms($singleChildRooms) - { - $this->singleChildRooms = $singleChildRooms; - } - - /** - * @return Room[] - */ - public function getDoubleChildRooms() - { - return $this->doubleChildRooms; - } - - /** - * @param Room[] $doubleChildRooms - */ - public function setDoubleChildRooms($doubleChildRooms) - { - $this->doubleChildRooms = $doubleChildRooms; - } - - /** - * @return Room[] - */ - public function getTripleChildRooms() - { - return $this->tripleChildRooms; - } - - /** - * @param Room[] $tripleChildRooms - */ - public function setTripleChildRooms($tripleChildRooms) - { - $this->tripleChildRooms = $tripleChildRooms; - } - - /** - * @return Room[] - */ - public function getRooms() - { - $allRooms = []; - $allRooms = array_merge($allRooms, $this->singleRooms); - $allRooms = array_merge($allRooms, $this->singleChildRooms); - $allRooms = array_merge($allRooms, $this->doubleRooms); - $allRooms = array_merge($allRooms, $this->doubleChildRooms); - $allRooms = array_merge($allRooms, $this->tripleRooms); - $allRooms = array_merge($allRooms, $this->tripleChildRooms); - - return $allRooms; - } - - /** - * @param Room[] $tripleRooms - */ - public function setRooms($rooms) - { - // falls man es braucht, nachziehen und oder umstrukturieren (booking.html.twig) - } - - public function getOccupiedRooms() - { - $allRooms = []; - for($i = 0; $i < $this->singleRoomCount; $i++) - { - $allRooms[] = $this->singleRooms[$i]; - //$allRooms = array_push($allRooms, $this->singleRooms[$i]); - } - for($i = 0; $i < $this->singleRoomChildCount; $i++) - { - $allRooms[] = $this->singleChildRooms[$i]; - //$allChildRooms = array_push($allChildRooms, $this->singleChildRooms[$i]); - } - for($i = 0; $i < $this->doubleRoomCount; $i++) - { - $allRooms[] = $this->doubleRooms[$i]; - //$allRooms = array_push($allRooms, $this->doubleRooms[$i]); - } - for($i = 0; $i < $this->doubleRoomChildCount; $i++) - { - $allRooms[] = $this->doubleChildRooms[$i]; - //$allChildRooms = array_push($allChildRooms, $this->doubleChildRooms[$i]); - } - for($i = 0; $i < $this->tripleRoomCount; $i++) - { - $allRooms[] = $this->tripleRooms[$i]; - //$allRooms = array_push($allRooms, $this->tripleRooms[$i]); - } - for($i = 0; $i < $this->tripleRoomChildCount; $i++) - { - $allRooms[] = $this->tripleChildRooms[$i]; - //$allChildRooms = array_push($allChildRooms, $this->tripleChildRooms[$i]); - } - return $allRooms; - } - - /* - public function addTraveler(Traveler $traveler) - { - $this->travelers[] = $traveler; - } - */ - - /** - * @return string - */ - public function getNotes() - { - return $this->notes; - } - - /** - * @param string $notes - */ - public function setNotes($notes) - { - $this->notes = $notes; - } - - /** - * @return bool - */ - public function isAcceptTerms() - { - return $this->acceptTerms; - } - - /** - * @param bool $acceptTerms - */ - public function setAcceptTerms($acceptTerms) - { - $this->acceptTerms = $acceptTerms; - } - - /** - * @return mixed - */ - - public function isAcceptLegalRights() - { - return $this->acceptLegalRights; - } - - /** - * @param mixed $acceptLegalRights - */ - - public function setAcceptLegalRights($acceptLegalRights) - { - $this->acceptLegalRights = $acceptLegalRights; - } - - - /** - * @return mixed - */ - public function isAcceptPrivacy() - { - return $this->acceptPrivacy; - } - - /** - * @param mixed $acceptPrivacy - */ - public function setAcceptPrivacy($acceptPrivacy) - { - $this->acceptPrivacy = $acceptPrivacy; - } - - - /** - * @Assert\Callback - */ - public function validate(ExecutionContextInterface $context, $payload) - { - //$context-> - } + + * @date 12/16/2016 + */ + +namespace AppBundle\Entity; + +use Symfony\Component\Validator\Constraints as Assert; +use AppBundle\Validator\Constraints as AppBundleAssert; +use Symfony\Component\Validator\Context\ExecutionContextInterface; + +/** + * Class BookingRequest + * @package AppBundle\Entity + * @AppBundleAssert\BookingRequest + */ +class BookingRequest +{ + // Used in SternToursCrmBookingExports, expected to be equivalent to sex (as defined in Traveler) + const MR = 1; + const MRS = 2; + const DIV = 3; + + + /** + * @var TravelDeparturePoint $departure + */ + private $departure; + + private $singleRoomCount; + + private $doubleRoomCount; + + private $tripleRoomCount; + + private $singleRoomChildCount; + + private $doubleRoomChildCount; + + private $tripleRoomChildCount; + + + private $extraBookingDaysBefore; + + private $extraBookingDaysAfter; + + private $roomCount; + + /** + * @var TravelInsurance $insurance + */ + private $insurance; + + private $comfort = false; + + private $travelOptions = []; + + private $salutation; + + private $insuranceOffer; + + /** + * @Assert\NotBlank() + */ + private $firstName; + + /** + * @Assert\NotBlank() + */ + private $lastName; + + /** + * @Assert\NotBlank() + */ + private $streetAddress; + + /** + * @Assert\NotBlank() + */ + private $zipCode; + + /** + * @Assert\NotBlank() + */ + private $city; + + private $nation; + + /** + * @Assert\NotBlank() + */ + private $phone; + + private $mobile; + + /** + * @Assert\NotBlank() + */ + private $email; + + private $travelers = []; + + private $singleRooms = []; + private $doubleRooms = []; + private $tripleRooms = []; + + private $singleChildRooms = []; + private $doubleChildRooms = []; + private $tripleChildRooms = []; + + private $notes; + + /** + * @Assert\IsTrue() + */ + private $acceptTerms = false; + + private $acceptLegalRights = false; + + private $acceptPrivacy = false; + + /** + * BookingRequest constructor. + */ + public function __construct() + { + for($i = 0; $i < 4; ++$i) + { + $this->singleRooms[] = new Room(1); + } + for($i = 0; $i < 4; ++$i) + { + $this->singleChildRooms[] = new Room(4); + } + for($i = 0; $i < 3; ++$i) + { + $this->doubleRooms[] = new Room(2); + } + for($i = 0; $i < 3; ++$i) + { + $this->doubleChildRooms[] = new Room(5); + } + for($i = 0; $i < 2; ++$i) + { + $this->tripleRooms[] = new Room(3); + } + for($i = 0; $i < 2; ++$i) + { + $this->tripleChildRooms[] = new Room(6); + } + } + + /** + * @return TravelDeparturePoint + */ + public function getDeparture() + { + return $this->departure; + } + + /** + * @param TravelDeparturePoint $departure + */ + public function setDeparture(TravelDeparturePoint $departure) + { + $this->departure = $departure; + } + + /** + * @return mixed + */ + public function getTravelerCount() + { + $allUsedTravelersCount = 0; + for($i = 0; $i < $this->singleRoomCount; ++$i) + { + $allUsedTravelersCount += $this->singleRooms[$i]->getTravelerCount(); + } + for($i = 0; $i < $this->singleRoomChildCount; ++$i) + { + $allUsedTravelersCount += $this->singleChildRooms[$i]->getTravelerCount(); + } + + for($i = 0; $i < $this->doubleRoomCount; ++$i) + { + $allUsedTravelersCount += $this->doubleRooms[$i]->getTravelerCount(); + } + for($i = 0; $i < $this->doubleRoomChildCount; ++$i) + { + $allUsedTravelersCount += $this->doubleChildRooms[$i]->getTravelerCount(); + } + for($i = 0; $i < $this->tripleRoomCount; ++$i) + { + $allUsedTravelersCount += $this->tripleRooms[$i]->getTravelerCount(); + } + for($i = 0; $i < $this->tripleRoomChildCount; ++$i) + { + $allUsedTravelersCount += $this->tripleChildRooms[$i]->getTravelerCount(); + } + + return $allUsedTravelersCount; + } + + public function getChildrenCount() + { + $allUsedChildrenCount = 0; + for($i = 0; $i < $this->singleRoomCount; ++$i) + { + $allUsedChildrenCount += 0;//$this->singleRooms[$i]->getTravelerCount(); + } + for($i = 0; $i < $this->singleRoomChildCount; ++$i) + { + $allUsedChildrenCount += 1;//$this->singleRooms[$i]->getTravelerCount(); + } + for($i = 0; $i < $this->doubleRoomCount; ++$i) + { + $allUsedChildrenCount += 0;//$this->singleRooms[$i]->getTravelerCount(); + } + for($i = 0; $i < $this->doubleRoomChildCount; ++$i) + { + $allUsedChildrenCount += 1;//$this->singleRooms[$i]->getTravelerCount(); + } + for($i = 0; $i < $this->tripleRoomCount; ++$i) + { + $allUsedChildrenCount += 0;//$this->singleRooms[$i]->getTravelerCount(); + } + for($i = 0; $i < $this->tripleRoomChildCount; ++$i) + { + $allUsedChildrenCount += 1;//$this->singleRooms[$i]->getTravelerCount(); + } + + return $allUsedChildrenCount; + } + + /** + * @param mixed $travelerCount + */ + public function setTravelerCount($travelerCount) + { + $this->travelerCount = $travelerCount; + } + + /** + * @return mixed + */ + public function getRoomCount() + { + return $this->roomCount; + } + + /** + * @param mixed $travelers + */ + public function setRoomCount($travelers) + { + // nicht so kompliziert + // übliche Anzahl der Reisenden war 2 -> Standardraum: 1 Doppelzimmer + $this->travelerCount = $travelers; + if($travelers % 2 != 0) + { + $times = ($travelers - 1) / 2; + $this->singleRoomCount = 1; + $this->doubleRoomCount = $times; + $this->tripleRoomCount = 0; + $this->roomCount = $times + 1; + } + else + { + $times = $travelers / 2; + $this->singleRoomCount = 0; + $this->doubleRoomCount = $times; + $this->tripleRoomCount = 0; + $this->roomCount = $times; + } + } + + /** + * @return mixed + */ + public function getSingleRoomCount() + { + return $this->singleRoomCount; + } + + /** + * @param mixed $singleRoomCount + */ + public function setSingleRoomCount($singleRoomCount) + { + $this->singleRoomCount = $singleRoomCount; + } + + /** + * @return mixed + */ + public function getDoubleRoomCount() + { + return $this->doubleRoomCount; + } + + /** + * @param mixed $doubleRoomCount + */ + public function setDoubleRoomCount($doubleRoomCount) + { + $this->doubleRoomCount = $doubleRoomCount; + } + + /** + * @return mixed + */ + public function getTripleRoomCount() + { + return $this->tripleRoomCount; + } + + /** + * @param mixed $tripleRoomCount + */ + public function setTripleRoomCount($tripleRoomCount) + { + $this->tripleRoomCount = $tripleRoomCount; + } + + + /** + * @return mixed + */ + public function getSingleRoomChildCount() + { + return $this->singleRoomChildCount; + } + + /** + * @param mixed $singleRoomChildCount + */ + public function setSingleRoomChildCount($singleRoomChildCount) + { + $this->singleRoomChildCount = $singleRoomChildCount; + } + + /** + * @return mixed + */ + public function getDoubleRoomChildCount() + { + return $this->doubleRoomChildCount; + } + + /** + * @param mixed $doubleRoomChildCount + */ + public function setDoubleRoomChildCount($doubleRoomChildCount) + { + $this->doubleRoomChildCount = $doubleRoomChildCount; + } + + /** + * @return mixed + */ + public function getTripleRoomChildCount() + { + return $this->tripleRoomChildCount; + } + + /** + * @param mixed $tripleRoomChildCount + */ + public function setTripleRoomChildCount($tripleRoomChildCount) + { + $this->tripleRoomChildCount = $tripleRoomChildCount; + } + + /** + * @return mixed + */ + public function getExtraBookingDaysBefore() + { + return $this->extraBookingDaysBefore; + } + + /** + * @param mixed $extraBookingDaysBefore + */ + public function setExtraBookingDaysBefore($extraBookingDaysBefore) + { + $this->extraBookingDaysBefore = $extraBookingDaysBefore; + } + + /** + * @return mixed + */ + public function getExtraBookingDaysAfter() + { + return $this->extraBookingDaysAfter; + } + + /** + * @param mixed $extraBookingDaysAfter + */ + public function setExtraBookingDaysAfter($extraBookingDaysAfter) + { + $this->extraBookingDaysAfter = $extraBookingDaysAfter; + } + + + /** + * @return TravelInsurance + */ + public function getInsurance() + { + return $this->insurance; + } + + /** + * @param TravelInsurance $insurance + */ + public function setInsurance(TravelInsurance $insurance) + { + $this->insurance = $insurance; + } + + + /** + * @return mixed + */ + public function getComfort() + { + return $this->comfort; + } + + /** + * @param mixed $comfort + */ + public function setComfort($comfort) + { + $this->comfort = $comfort; + } + + /** + * @return TravelOption[] + */ + public function getTravelOptions() + { + return $this->travelOptions; + } + + /** + * @param mixed $travelOptions + */ + public function setTravelOptions($travelOptions) + { + $this->travelOptions = $travelOptions; + } + + /** + * @return int + */ + public function getSalutation() + { + return $this->salutation; + } + + /** + * @param int $salutation + */ + public function setSalutation($salutation) + { + $this->salutation = $salutation; + } + + public function getSalutationName() + { + switch ($this->salutation) { + case 1: + return 'Herr'; + break; + case 2: + return 'Frau'; + break; + case 3: + return 'Divers/keine Anrede'; + break; + } + return ''; + } + + public function getSalutationDear() + { + switch ($this->salutation) { + case 1: + return 'geehrter'; + break; + case 2: + return 'geehrte'; + break; + case 3: + return 'geehrte:r'; + break; + } + return ''; + } + + public function getSalutationApplicant() + { + switch ($this->salutation) { + case 1: + return 'Reiseanmelder'; + break; + case 2: + return 'Reiseanmelderin'; + break; + case 3: + return 'Reiseanmelder:in'; + break; + } + return ''; + } + + + /** + * @return string + */ + public function getFirstName() + { + return $this->firstName; + } + + /** + * @param string $firstName + */ + public function setFirstName($firstName) + { + $this->firstName = $firstName; + } + + /** + * @return string + */ + public function getLastName() + { + return $this->lastName; + } + + /** + * @param string $lastName + */ + public function setLastName($lastName) + { + $this->lastName = $lastName; + } + + /** + * @return string + */ + public function getStreetAddress() + { + return $this->streetAddress; + } + + /** + * @param string $streetAddress + */ + public function setStreetAddress($streetAddress) + { + $this->streetAddress = $streetAddress; + } + + /** + * @return string + */ + public function getZipCode() + { + return $this->zipCode; + } + + /** + * @param string $zipCode + */ + public function setZipCode($zipCode) + { + $this->zipCode = $zipCode; + } + + /** + * @return string + */ + public function getCity() + { + return $this->city; + } + + /** + * @param string $city + */ + public function setCity($city) + { + $this->city = $city; + } + + /** + * @return int + */ + public function getNation() + { + return $this->nation; + } + + /** + * @param int $nation + */ + public function setNation($nation) + { + $this->nation = $nation; + } + + /** + * @return int + */ + public function getInsuranceOffer() + { + return $this->insuranceOffer; + } + + /** + * @param int $insuranceOffer + */ + public function setInsuranceOffer($insuranceOffer) + { + $this->insuranceOffer = $insuranceOffer; + } + + /** + * @return string + */ + public function getPhone() + { + return $this->phone; + } + + /** + * @param string $phone + */ + public function setPhone($phone) + { + $this->phone = $phone; + } + + /** + * @return string + */ + public function getMobile() + { + return $this->mobile; + } + + /** + * @param string $mobile + */ + public function setMobile($mobile) + { + $this->mobile = $mobile; + } + + /** + * @return string + */ + public function getEmail() + { + return $this->email; + } + + /** + * @param string $email + */ + public function setEmail($email) + { + $this->email = $email; + } + + // get und set der Travelers liegt jetzt in Room; sollte so nicht mehr verwendet werden! + /** + * @return Traveler[] + */ + public function getTravelers() + { + $allUsedTravelers = []; + + // könnte man eventuell in eine for-Schleife packen, wenn man garantiert, dass es immer gleich viele Räume von jedem Typ gibt + for ($i = 0; $i < $this->singleRoomCount; ++$i) + { + $allUsedTravelers = array_merge($allUsedTravelers, $this->singleRooms[$i]->getTravelers()); + } + for ($i = 0; $i < $this->singleRoomChildCount; ++$i) + { + $allUsedTravelers = array_merge($allUsedTravelers, $this->singleChildRooms[$i]->getTravelers()); + } + + for ($i = 0; $i < $this->doubleRoomCount; ++$i) + { + $allUsedTravelers = array_merge($allUsedTravelers, $this->doubleRooms[$i]->getTravelers()); + } + for ($i = 0; $i < $this->doubleRoomChildCount; ++$i) + { + $allUsedTravelers = array_merge($allUsedTravelers, $this->doubleChildRooms[$i]->getTravelers()); + } + for ($i = 0; $i < $this->tripleRoomCount; ++$i) + { + $allUsedTravelers = array_merge($allUsedTravelers, $this->tripleRooms[$i]->getTravelers()); + } + for ($i = 0; $i < $this->tripleRoomChildCount; ++$i) + { + $allUsedTravelers = array_merge($allUsedTravelers, $this->tripleChildRooms[$i]->getTravelers()); + } + +// $this->travelers = $allUsedTravelers; // schlecht, getter sollte kein setter sein +// return $this->travelers; // aber wenn man es so verwenden würde, dann sollte man auch das verwenden + return $allUsedTravelers; + } + + /** + * @param Traveler[] $travelers + */ + public function setTravelers($travelers) + { + $this->travelers = $travelers; + } + + /** + * @return Room[] + */ + public function getSingleRooms() + { + return $this->singleRooms; + } + + /** + * @param Room[] $singleRooms + */ + public function setSingleRooms($singleRooms) + { + $this->singleRooms = $singleRooms; + } + + /** + * @return Room[] + */ + public function getDoubleRooms() + { + return $this->doubleRooms; + } + + /** + * @param Room[] $doubleRooms + */ + public function setDoubleRooms($doubleRooms) + { + $this->doubleRooms = $doubleRooms; + } + + /** + * @return Room[] + */ + public function getTripleRooms() + { + return $this->tripleRooms; + } + + /** + * @param Room[] $tripleRooms + */ + public function setTripleRooms($tripleRooms) + { + $this->tripleRooms = $tripleRooms; + } + + /** + * @return Room[] + */ + public function getSingleChildRooms() + { + return $this->singleChildRooms; + } + + /** + * @param Room[] $singleChildRooms + */ + public function setSingleChildRooms($singleChildRooms) + { + $this->singleChildRooms = $singleChildRooms; + } + + /** + * @return Room[] + */ + public function getDoubleChildRooms() + { + return $this->doubleChildRooms; + } + + /** + * @param Room[] $doubleChildRooms + */ + public function setDoubleChildRooms($doubleChildRooms) + { + $this->doubleChildRooms = $doubleChildRooms; + } + + /** + * @return Room[] + */ + public function getTripleChildRooms() + { + return $this->tripleChildRooms; + } + + /** + * @param Room[] $tripleChildRooms + */ + public function setTripleChildRooms($tripleChildRooms) + { + $this->tripleChildRooms = $tripleChildRooms; + } + + /** + * @return Room[] + */ + public function getRooms() + { + $allRooms = []; + $allRooms = array_merge($allRooms, $this->singleRooms); + $allRooms = array_merge($allRooms, $this->singleChildRooms); + $allRooms = array_merge($allRooms, $this->doubleRooms); + $allRooms = array_merge($allRooms, $this->doubleChildRooms); + $allRooms = array_merge($allRooms, $this->tripleRooms); + $allRooms = array_merge($allRooms, $this->tripleChildRooms); + + return $allRooms; + } + + /** + * @param Room[] $tripleRooms + */ + public function setRooms($rooms) + { + // falls man es braucht, nachziehen und oder umstrukturieren (booking.html.twig) + } + + public function getOccupiedRooms() + { + $allRooms = []; + for($i = 0; $i < $this->singleRoomCount; $i++) + { + $allRooms[] = $this->singleRooms[$i]; + //$allRooms = array_push($allRooms, $this->singleRooms[$i]); + } + for($i = 0; $i < $this->singleRoomChildCount; $i++) + { + $allRooms[] = $this->singleChildRooms[$i]; + //$allChildRooms = array_push($allChildRooms, $this->singleChildRooms[$i]); + } + for($i = 0; $i < $this->doubleRoomCount; $i++) + { + $allRooms[] = $this->doubleRooms[$i]; + //$allRooms = array_push($allRooms, $this->doubleRooms[$i]); + } + for($i = 0; $i < $this->doubleRoomChildCount; $i++) + { + $allRooms[] = $this->doubleChildRooms[$i]; + //$allChildRooms = array_push($allChildRooms, $this->doubleChildRooms[$i]); + } + for($i = 0; $i < $this->tripleRoomCount; $i++) + { + $allRooms[] = $this->tripleRooms[$i]; + //$allRooms = array_push($allRooms, $this->tripleRooms[$i]); + } + for($i = 0; $i < $this->tripleRoomChildCount; $i++) + { + $allRooms[] = $this->tripleChildRooms[$i]; + //$allChildRooms = array_push($allChildRooms, $this->tripleChildRooms[$i]); + } + return $allRooms; + } + + /* + public function addTraveler(Traveler $traveler) + { + $this->travelers[] = $traveler; + } + */ + + /** + * @return string + */ + public function getNotes() + { + return $this->notes; + } + + /** + * @param string $notes + */ + public function setNotes($notes) + { + $this->notes = $notes; + } + + /** + * @return bool + */ + public function isAcceptTerms() + { + return $this->acceptTerms; + } + + /** + * @param bool $acceptTerms + */ + public function setAcceptTerms($acceptTerms) + { + $this->acceptTerms = $acceptTerms; + } + + /** + * @return mixed + */ + + public function isAcceptLegalRights() + { + return $this->acceptLegalRights; + } + + /** + * @param mixed $acceptLegalRights + */ + + public function setAcceptLegalRights($acceptLegalRights) + { + $this->acceptLegalRights = $acceptLegalRights; + } + + + /** + * @return mixed + */ + public function isAcceptPrivacy() + { + return $this->acceptPrivacy; + } + + /** + * @param mixed $acceptPrivacy + */ + public function setAcceptPrivacy($acceptPrivacy) + { + $this->acceptPrivacy = $acceptPrivacy; + } + + + /** + * @Assert\Callback + */ + public function validate(ExecutionContextInterface $context, $payload) + { + //$context-> + } + + public function checkIsRoomSelected() + { + if ($this->singleRoomCount > 0) { + return true; + } + if ($this->doubleRoomCount > 0) { + return true; + } + if ($this->tripleRoomCount > 0) { + return true; + } + if ($this->singleRoomChildCount > 0) { + return true; + } + if ($this->doubleRoomChildCount > 0) { + return true; + } + if ($this->tripleRoomChildCount > 0) { + return true; + } + return false; + } } \ No newline at end of file diff --git a/src/AppBundle/Entity/Page.php b/src/AppBundle/Entity/Page.php index 10129d74..f8bd7738 100644 --- a/src/AppBundle/Entity/Page.php +++ b/src/AppBundle/Entity/Page.php @@ -996,6 +996,22 @@ class Page { return $this->country; } + + public function getHomepageCountryName() + { + if ($this->country) { + return $this->country->getName(); + } + + if ($this->travelProgram) { + foreach ($this->travelProgram->getCountries() as $country) { + return $country->getName(); + } + } + + return null; + } + /** * Constructor */ @@ -1286,6 +1302,20 @@ class Page return $this; } + /** + * Get boxBody / Image USED for Box Image by v3 CMS + * + * @return array|false + */ + public function getBoxBodyImage() + { + if($this->boxBody != ""){ + $boxBodyImage = json_decode($this->boxBody, true); + return $boxBodyImage; + } + return false; + } + /** * Get boxBody * diff --git a/src/AppBundle/Entity/PageRepository.php b/src/AppBundle/Entity/PageRepository.php index a8a2cc20..202100bf 100644 --- a/src/AppBundle/Entity/PageRepository.php +++ b/src/AppBundle/Entity/PageRepository.php @@ -134,6 +134,42 @@ class PageRepository extends NestedTreeRepository return array_slice($pages, 0, $limit); } + public function findActiveTravelPagesByIds(array $ids) + { + $ids = array_values(array_filter(array_map('intval', $ids))); + + if (empty($ids)) { + return []; + } + + $pages = $this->createQueryBuilder('node') + ->distinct() + ->innerJoin('node.travelProgram', 'tp') + ->addSelect('tp') + ->leftJoin('tp.countries', 'c') + ->addSelect('c') + ->where('node.id IN (:ids)') + ->andWhere('node.status = 1') + ->andWhere('tp.status = 1') + ->setParameter('ids', $ids) + ->getQuery() + ->execute(); + + $pagesById = []; + foreach ($pages as $page) { + $pagesById[$page->getId()] = $page; + } + + $ret = []; + foreach ($ids as $id) { + if (isset($pagesById[$id])) { + $ret[] = $pagesById[$id]; + } + } + + return $ret; + } + /** * @return Page[] */ @@ -155,6 +191,28 @@ class PageRepository extends NestedTreeRepository return $pages; } + /** + * @return Page[] + */ + public function findHomepageNews($limit = 3) + { + $rootPage = $this->find(3153); + if (!$rootPage) { + return []; + } + + return $this->createQueryBuilder('node') + ->where('node.parent = :rootPage') + ->andWhere('node.showInNavi = 1') + ->andWhere('node.status = 1') + ->orderBy('node.date', 'DESC') + ->addOrderBy('node.order', 'ASC') + ->setParameter('rootPage', $rootPage) + ->setMaxResults($limit) + ->getQuery() + ->execute(); + } + private function getHomepagePriority(Page $page) { $haystack = $this->buildHomepageSortHaystack($page); @@ -220,7 +278,7 @@ class PageRepository extends NestedTreeRepository public function findTopCountryNavPages() { - return $this->createQueryBuilder('node') + $pages = $this->createQueryBuilder('node') ->innerJoin('node.country', 'country') ->leftJoin('node.children', 'childPage', Expr\Join::WITH, 'childPage.status > 0') ->addSelect('childPage') @@ -232,6 +290,25 @@ class PageRepository extends NestedTreeRepository ->getQuery() ->execute() ; + + usort($pages, function (Page $a, Page $b) { + $priorityA = $this->getHomepagePriority($a); + $priorityB = $this->getHomepagePriority($b); + + if ($priorityA !== $priorityB) { + return $priorityA - $priorityB; + } + + $orderA = $a->getOrder() ?: 9999; + $orderB = $b->getOrder() ?: 9999; + if ($orderA !== $orderB) { + return $orderA - $orderB; + } + + return strcasecmp($a->getTitle(), $b->getTitle()); + }); + + return $pages; } public function findFeedbacks($rootPageId) diff --git a/src/AppBundle/Entity/SidebarWidget.php b/src/AppBundle/Entity/SidebarWidget.php index b7f587ad..48e57d78 100644 --- a/src/AppBundle/Entity/SidebarWidget.php +++ b/src/AppBundle/Entity/SidebarWidget.php @@ -146,6 +146,57 @@ class SidebarWidget return $this->html; } + public function getConfig() + { + $config = json_decode($this->html, true); + + if (!is_array($config)) { + return []; + } + + return $config; + } + + public function getConfigPageIds() + { + $config = $this->getConfig(); + + if (!isset($config['page_ids']) || !is_array($config['page_ids'])) { + return []; + } + + return array_values(array_filter($config['page_ids'])); + } + + public function getConfigNewBadgeActive() + { + $config = $this->getConfig(); + + return !empty($config['new_badge_active']); + } + + public function getConfigNewPageIds() + { + $config = $this->getConfig(); + + if (!isset($config['new_page_ids']) || !is_array($config['new_page_ids'])) { + return []; + } + + return array_values(array_filter(array_map('intval', $config['new_page_ids']))); + } + + public function getConfigNewsLimit() + { + $config = $this->getConfig(); + + if (!isset($config['news_limit'])) { + return 3; + } + + return max(1, min(12, (int) $config['news_limit'])); + } + /** * Set showAt * diff --git a/src/AppBundle/Entity/SidebarWidgetRepository.php b/src/AppBundle/Entity/SidebarWidgetRepository.php index edfd4828..01a3ce99 100644 --- a/src/AppBundle/Entity/SidebarWidgetRepository.php +++ b/src/AppBundle/Entity/SidebarWidgetRepository.php @@ -15,6 +15,8 @@ class SidebarWidgetRepository extends \Doctrine\ORM\EntityRepository { $qb = $this->createQueryBuilder('sidebar_widget'); $qb->where('sidebar_widget.active = 1') + ->andWhere('sidebar_widget.component NOT IN (:configComponents)') + ->setParameter('configComponents', ['homepagePlannableTrips', 'homepagePopularTrips']) ->addOrderBy('sidebar_widget.pos', 'ASC'); $results = $qb->getQuery()->getResult(); @@ -27,4 +29,23 @@ class SidebarWidgetRepository extends \Doctrine\ORM\EntityRepository } return $ret; } + + public function findActiveWidgetByComponent($component, $site = null) + { + $qb = $this->createQueryBuilder('sidebar_widget'); + $results = $qb->where('sidebar_widget.active = 1') + ->andWhere('sidebar_widget.component = :component') + ->setParameter('component', $component) + ->addOrderBy('sidebar_widget.pos', 'ASC') + ->getQuery() + ->getResult(); + + foreach ($results as $result) { + if ($site === null || $result->getIsShowAt($site)) { + return $result; + } + } + + return null; + } } diff --git a/src/AppBundle/Resources/public/js/custom.js b/src/AppBundle/Resources/public/js/custom.js index 44411f25..a89b40ca 100644 --- a/src/AppBundle/Resources/public/js/custom.js +++ b/src/AppBundle/Resources/public/js/custom.js @@ -379,7 +379,23 @@ jQuery(document).ready(function($) { /* ============================================== OWL CAROUSEL --> =============================================== */ - var owl = $('.owl-fullwidth').owlCarousel({ + function loadOwlCarouselBackgrounds(ctx$) { + $('.lozad[data-background-image]', ctx$).each(function () { + var image$ = $(this); + var backgroundImage = image$.attr('data-background-image'); + + if (backgroundImage) { + image$.css('background-image', 'url("' + backgroundImage + '")'); + } + }); + } + + var owlFullwidth$ = $('.owl-fullwidth'); + owlFullwidth$.on('initialized.owl.carousel translated.owl.carousel refreshed.owl.carousel', function () { + loadOwlCarouselBackgrounds($(this)); + }); + + var owl = owlFullwidth$.owlCarousel({ loop:true, margin:0, nav:true, @@ -399,6 +415,7 @@ jQuery(document).ready(function($) { } }, }); + loadOwlCarouselBackgrounds(owlFullwidth$); /* ============================================== BOX LINK --> @@ -613,14 +630,31 @@ initGoTo(); $(document).ready(function() { $('.st-booking-form').validator().on('submit', function (e) { if (e.isDefaultPrevented()) { - // handle the invalid form... - } else { - $(".btn-booking-form").attr("disabled", true); + $(".btn-booking-form .alert-danger").removeClass("hide"); + $(".btn-booking-form .alert-danger").addClass("show"); + } else { + $(".btn-booking-form .alert-danger").removeClass("hide"); + $(".btn-booking-form .alert-danger").addClass("show"); + + $(".btn-booking-form").attr("disabled", true); $(".btn-booking-form .btn-booking-submit").addClass("hide"); $(".btn-booking-form .btn-booking-loading").removeClass("hide"); } }); + + $(".st-booking-form") + .validator() + .on("submit", function (t) { + (t.isDefaultPrevented(), + $(".btn-booking-form .alert-danger").removeClass("hide"), + $(".btn-booking-form .alert-danger").addClass("show")) || + ($(".btn-booking-form .alert-danger").removeClass("show"), + $(".btn-booking-form .alert-danger").addClass(""), + $(".btn-booking-form").attr("disabled", !0), + $(".btn-booking-form .btn-booking-submit").addClass("hide"), + $(".btn-booking-form .btn-booking-loading").removeClass("hide")); + }); var $topNavAccordion = $('#topNavAccordion'); $topNavAccordion.on('show.bs.collapse','.collapse', function() { $topNavAccordion.find('.collapse.in').collapse('hide'); diff --git a/web/js/custom-min.js b/web/js/custom-min.js index ff497a5a..acfe9686 100644 --- a/web/js/custom-min.js +++ b/web/js/custom-min.js @@ -1,16 +1,25176 @@ -if(function(t,e){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=t.document?e(t,!0):function(t){if(!t.document)throw new Error("jQuery requires a window with a document");return e(t)}:e(t)}("undefined"!=typeof window?window:this,(function(t,e){"use strict";var i=[],s=t.document,n=Object.getPrototypeOf,o=i.slice,r=i.concat,a=i.push,l=i.indexOf,h={},c=h.toString,u=h.hasOwnProperty,d=u.toString,p=d.call(Object),f={};function g(t,e){var i=(e=e||s).createElement("script");i.text=t,e.head.appendChild(i).parentNode.removeChild(i)}var m=function(t,e){return new m.fn.init(t,e)},v=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,b=/^-ms-/,_=/-([a-z])/g,y=function(t,e){return e.toUpperCase()};function w(t){var e=!!t&&"length"in t&&t.length,i=m.type(t);return"function"!==i&&!m.isWindow(t)&&("array"===i||0===e||"number"==typeof e&&e>0&&e-1 in t)}m.fn=m.prototype={jquery:"3.1.1",constructor:m,length:0,toArray:function(){return o.call(this)},get:function(t){return null==t?o.call(this):t<0?this[t+this.length]:this[t]},pushStack:function(t){var e=m.merge(this.constructor(),t);return e.prevObject=this,e},each:function(t){return m.each(this,t)},map:function(t){return this.pushStack(m.map(this,(function(e,i){return t.call(e,i,e)})))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(t){var e=this.length,i=+t+(t<0?e:0);return this.pushStack(i>=0&&i+~]|"+H+")"+H+"*"),q=new RegExp("="+H+"*([^\\]'\"]*?)"+H+"*\\]","g"),U=new RegExp(R),V=new RegExp("^"+L+"$"),Y={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+R),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+H+"*(even|odd|(([+-]|)(\\d*)n|)"+H+"*(?:([+-]|)"+H+"*(\\d+)|))"+H+"*\\)|)","i"),bool:new RegExp("^(?:"+z+")$","i"),needsContext:new RegExp("^"+H+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+H+"*((?:-\\d)?\\d*)"+H+"*\\)|)(?=[^-]|$)","i")},K=/^(?:input|select|textarea|button)$/i,Q=/^h\d$/i,X=/^[^{]+\{\s*\[native \w/,G=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,J=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+H+"?|("+H+")|.)","ig"),tt=function(t,e,i){var s="0x"+e-65536;return s!=s||i?e:s<0?String.fromCharCode(s+65536):String.fromCharCode(s>>10|55296,1023&s|56320)},et=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,it=function(t,e){return e?"\0"===t?"�":t.slice(0,-1)+"\\"+t.charCodeAt(t.length-1).toString(16)+" ":"\\"+t},st=function(){d()},nt=bt((function(t){return!0===t.disabled&&("form"in t||"label"in t)}),{dir:"parentNode",next:"legend"});try{O.apply(E=N.call(w.childNodes),w.childNodes),E[w.childNodes.length].nodeType}catch(t){O={apply:E.length?function(t,e){A.apply(t,N.call(e))}:function(t,e){for(var i=t.length,s=0;t[i++]=e[s++];);t.length=i-1}}}function ot(t,e,s,n){var o,a,h,c,u,f,v,b=e&&e.ownerDocument,x=e?e.nodeType:9;if(s=s||[],"string"!=typeof t||!t||1!==x&&9!==x&&11!==x)return s;if(!n&&((e?e.ownerDocument||e:w)!==p&&d(e),e=e||p,g)){if(11!==x&&(u=G.exec(t)))if(o=u[1]){if(9===x){if(!(h=e.getElementById(o)))return s;if(h.id===o)return s.push(h),s}else if(b&&(h=b.getElementById(o))&&_(e,h)&&h.id===o)return s.push(h),s}else{if(u[2])return O.apply(s,e.getElementsByTagName(t)),s;if((o=u[3])&&i.getElementsByClassName&&e.getElementsByClassName)return O.apply(s,e.getElementsByClassName(o)),s}if(i.qsa&&!D[t+" "]&&(!m||!m.test(t))){if(1!==x)b=e,v=t;else if("object"!==e.nodeName.toLowerCase()){for((c=e.getAttribute("id"))?c=c.replace(et,it):e.setAttribute("id",c=y),a=(f=r(t)).length;a--;)f[a]="#"+c+" "+vt(f[a]);v=f.join(","),b=J.test(t)&>(e.parentNode)||e}if(v)try{return O.apply(s,b.querySelectorAll(v)),s}catch(t){}finally{c===y&&e.removeAttribute("id")}}}return l(t.replace($,"$1"),e,s,n)}function rt(){var t=[];return function e(i,n){return t.push(i+" ")>s.cacheLength&&delete e[t.shift()],e[i+" "]=n}}function at(t){return t[y]=!0,t}function lt(t){var e=p.createElement("fieldset");try{return!!t(e)}catch(t){return!1}finally{e.parentNode&&e.parentNode.removeChild(e),e=null}}function ht(t,e){for(var i=t.split("|"),n=i.length;n--;)s.attrHandle[i[n]]=e}function ct(t,e){var i=e&&t,s=i&&1===t.nodeType&&1===e.nodeType&&t.sourceIndex-e.sourceIndex;if(s)return s;if(i)for(;i=i.nextSibling;)if(i===e)return-1;return t?1:-1}function ut(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function dt(t){return function(e){var i=e.nodeName.toLowerCase();return("input"===i||"button"===i)&&e.type===t}}function pt(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&nt(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ft(t){return at((function(e){return e=+e,at((function(i,s){for(var n,o=t([],i.length,e),r=o.length;r--;)i[n=o[r]]&&(i[n]=!(s[n]=i[n]))}))}))}function gt(t){return t&&void 0!==t.getElementsByTagName&&t}for(e in i=ot.support={},o=ot.isXML=function(t){var e=t&&(t.ownerDocument||t).documentElement;return!!e&&"HTML"!==e.nodeName},d=ot.setDocument=function(t){var e,n,r=t?t.ownerDocument||t:w;return r!==p&&9===r.nodeType&&r.documentElement?(f=(p=r).documentElement,g=!o(p),w!==p&&(n=p.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",st,!1):n.attachEvent&&n.attachEvent("onunload",st)),i.attributes=lt((function(t){return t.className="i",!t.getAttribute("className")})),i.getElementsByTagName=lt((function(t){return t.appendChild(p.createComment("")),!t.getElementsByTagName("*").length})),i.getElementsByClassName=X.test(p.getElementsByClassName),i.getById=lt((function(t){return f.appendChild(t).id=y,!p.getElementsByName||!p.getElementsByName(y).length})),i.getById?(s.filter.ID=function(t){var e=t.replace(Z,tt);return function(t){return t.getAttribute("id")===e}},s.find.ID=function(t,e){if(void 0!==e.getElementById&&g){var i=e.getElementById(t);return i?[i]:[]}}):(s.filter.ID=function(t){var e=t.replace(Z,tt);return function(t){var i=void 0!==t.getAttributeNode&&t.getAttributeNode("id");return i&&i.value===e}},s.find.ID=function(t,e){if(void 0!==e.getElementById&&g){var i,s,n,o=e.getElementById(t);if(o){if((i=o.getAttributeNode("id"))&&i.value===t)return[o];for(n=e.getElementsByName(t),s=0;o=n[s++];)if((i=o.getAttributeNode("id"))&&i.value===t)return[o]}return[]}}),s.find.TAG=i.getElementsByTagName?function(t,e){return void 0!==e.getElementsByTagName?e.getElementsByTagName(t):i.qsa?e.querySelectorAll(t):void 0}:function(t,e){var i,s=[],n=0,o=e.getElementsByTagName(t);if("*"===t){for(;i=o[n++];)1===i.nodeType&&s.push(i);return s}return o},s.find.CLASS=i.getElementsByClassName&&function(t,e){if(void 0!==e.getElementsByClassName&&g)return e.getElementsByClassName(t)},v=[],m=[],(i.qsa=X.test(p.querySelectorAll))&&(lt((function(t){f.appendChild(t).innerHTML="",t.querySelectorAll("[msallowcapture^='']").length&&m.push("[*^$]="+H+"*(?:''|\"\")"),t.querySelectorAll("[selected]").length||m.push("\\["+H+"*(?:value|"+z+")"),t.querySelectorAll("[id~="+y+"-]").length||m.push("~="),t.querySelectorAll(":checked").length||m.push(":checked"),t.querySelectorAll("a#"+y+"+*").length||m.push(".#.+[+~]")})),lt((function(t){t.innerHTML="";var e=p.createElement("input");e.setAttribute("type","hidden"),t.appendChild(e).setAttribute("name","D"),t.querySelectorAll("[name=d]").length&&m.push("name"+H+"*[*^$|!~]?="),2!==t.querySelectorAll(":enabled").length&&m.push(":enabled",":disabled"),f.appendChild(t).disabled=!0,2!==t.querySelectorAll(":disabled").length&&m.push(":enabled",":disabled"),t.querySelectorAll("*,:x"),m.push(",.*:")}))),(i.matchesSelector=X.test(b=f.matches||f.webkitMatchesSelector||f.mozMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&<((function(t){i.disconnectedMatch=b.call(t,"*"),b.call(t,"[s!='']:x"),v.push("!=",R)})),m=m.length&&new RegExp(m.join("|")),v=v.length&&new RegExp(v.join("|")),e=X.test(f.compareDocumentPosition),_=e||X.test(f.contains)?function(t,e){var i=9===t.nodeType?t.documentElement:t,s=e&&e.parentNode;return t===s||!(!s||1!==s.nodeType||!(i.contains?i.contains(s):t.compareDocumentPosition&&16&t.compareDocumentPosition(s)))}:function(t,e){if(e)for(;e=e.parentNode;)if(e===t)return!0;return!1},I=e?function(t,e){if(t===e)return u=!0,0;var s=!t.compareDocumentPosition-!e.compareDocumentPosition;return s||(1&(s=(t.ownerDocument||t)===(e.ownerDocument||e)?t.compareDocumentPosition(e):1)||!i.sortDetached&&e.compareDocumentPosition(t)===s?t===p||t.ownerDocument===w&&_(w,t)?-1:e===p||e.ownerDocument===w&&_(w,e)?1:c?M(c,t)-M(c,e):0:4&s?-1:1)}:function(t,e){if(t===e)return u=!0,0;var i,s=0,n=t.parentNode,o=e.parentNode,r=[t],a=[e];if(!n||!o)return t===p?-1:e===p?1:n?-1:o?1:c?M(c,t)-M(c,e):0;if(n===o)return ct(t,e);for(i=t;i=i.parentNode;)r.unshift(i);for(i=e;i=i.parentNode;)a.unshift(i);for(;r[s]===a[s];)s++;return s?ct(r[s],a[s]):r[s]===w?-1:a[s]===w?1:0},p):p},ot.matches=function(t,e){return ot(t,null,null,e)},ot.matchesSelector=function(t,e){if((t.ownerDocument||t)!==p&&d(t),e=e.replace(q,"='$1']"),i.matchesSelector&&g&&!D[e+" "]&&(!v||!v.test(e))&&(!m||!m.test(e)))try{var s=b.call(t,e);if(s||i.disconnectedMatch||t.document&&11!==t.document.nodeType)return s}catch(t){}return ot(e,p,null,[t]).length>0},ot.contains=function(t,e){return(t.ownerDocument||t)!==p&&d(t),_(t,e)},ot.attr=function(t,e){(t.ownerDocument||t)!==p&&d(t);var n=s.attrHandle[e.toLowerCase()],o=n&&S.call(s.attrHandle,e.toLowerCase())?n(t,e,!g):void 0;return void 0!==o?o:i.attributes||!g?t.getAttribute(e):(o=t.getAttributeNode(e))&&o.specified?o.value:null},ot.escape=function(t){return(t+"").replace(et,it)},ot.error=function(t){throw new Error("Syntax error, unrecognized expression: "+t)},ot.uniqueSort=function(t){var e,s=[],n=0,o=0;if(u=!i.detectDuplicates,c=!i.sortStable&&t.slice(0),t.sort(I),u){for(;e=t[o++];)e===t[o]&&(n=s.push(o));for(;n--;)t.splice(s[n],1)}return c=null,t},n=ot.getText=function(t){var e,i="",s=0,o=t.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof t.textContent)return t.textContent;for(t=t.firstChild;t;t=t.nextSibling)i+=n(t)}else if(3===o||4===o)return t.nodeValue}else for(;e=t[s++];)i+=n(e);return i},(s=ot.selectors={cacheLength:50,createPseudo:at,match:Y,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(t){return t[1]=t[1].replace(Z,tt),t[3]=(t[3]||t[4]||t[5]||"").replace(Z,tt),"~="===t[2]&&(t[3]=" "+t[3]+" "),t.slice(0,4)},CHILD:function(t){return t[1]=t[1].toLowerCase(),"nth"===t[1].slice(0,3)?(t[3]||ot.error(t[0]),t[4]=+(t[4]?t[5]+(t[6]||1):2*("even"===t[3]||"odd"===t[3])),t[5]=+(t[7]+t[8]||"odd"===t[3])):t[3]&&ot.error(t[0]),t},PSEUDO:function(t){var e,i=!t[6]&&t[2];return Y.CHILD.test(t[0])?null:(t[3]?t[2]=t[4]||t[5]||"":i&&U.test(i)&&(e=r(i,!0))&&(e=i.indexOf(")",i.length-e)-i.length)&&(t[0]=t[0].slice(0,e),t[2]=i.slice(0,e)),t.slice(0,3))}},filter:{TAG:function(t){var e=t.replace(Z,tt).toLowerCase();return"*"===t?function(){return!0}:function(t){return t.nodeName&&t.nodeName.toLowerCase()===e}},CLASS:function(t){var e=k[t+" "];return e||(e=new RegExp("(^|"+H+")"+t+"("+H+"|$)"))&&k(t,(function(t){return e.test("string"==typeof t.className&&t.className||void 0!==t.getAttribute&&t.getAttribute("class")||"")}))},ATTR:function(t,e,i){return function(s){var n=ot.attr(s,t);return null==n?"!="===e:!e||(n+="","="===e?n===i:"!="===e?n!==i:"^="===e?i&&0===n.indexOf(i):"*="===e?i&&n.indexOf(i)>-1:"$="===e?i&&n.slice(-i.length)===i:"~="===e?(" "+n.replace(F," ")+" ").indexOf(i)>-1:"|="===e&&(n===i||n.slice(0,i.length+1)===i+"-"))}},CHILD:function(t,e,i,s,n){var o="nth"!==t.slice(0,3),r="last"!==t.slice(-4),a="of-type"===e;return 1===s&&0===n?function(t){return!!t.parentNode}:function(e,i,l){var h,c,u,d,p,f,g=o!==r?"nextSibling":"previousSibling",m=e.parentNode,v=a&&e.nodeName.toLowerCase(),b=!l&&!a,_=!1;if(m){if(o){for(;g;){for(d=e;d=d[g];)if(a?d.nodeName.toLowerCase()===v:1===d.nodeType)return!1;f=g="only"===t&&!f&&"nextSibling"}return!0}if(f=[r?m.firstChild:m.lastChild],r&&b){for(_=(p=(h=(c=(u=(d=m)[y]||(d[y]={}))[d.uniqueID]||(u[d.uniqueID]={}))[t]||[])[0]===x&&h[1])&&h[2],d=p&&m.childNodes[p];d=++p&&d&&d[g]||(_=p=0)||f.pop();)if(1===d.nodeType&&++_&&d===e){c[t]=[x,p,_];break}}else if(b&&(_=p=(h=(c=(u=(d=e)[y]||(d[y]={}))[d.uniqueID]||(u[d.uniqueID]={}))[t]||[])[0]===x&&h[1]),!1===_)for(;(d=++p&&d&&d[g]||(_=p=0)||f.pop())&&((a?d.nodeName.toLowerCase()!==v:1!==d.nodeType)||!++_||(b&&((c=(u=d[y]||(d[y]={}))[d.uniqueID]||(u[d.uniqueID]={}))[t]=[x,_]),d!==e)););return(_-=n)===s||_%s==0&&_/s>=0}}},PSEUDO:function(t,e){var i,n=s.pseudos[t]||s.setFilters[t.toLowerCase()]||ot.error("unsupported pseudo: "+t);return n[y]?n(e):n.length>1?(i=[t,t,"",e],s.setFilters.hasOwnProperty(t.toLowerCase())?at((function(t,i){for(var s,o=n(t,e),r=o.length;r--;)t[s=M(t,o[r])]=!(i[s]=o[r])})):function(t){return n(t,0,i)}):n}},pseudos:{not:at((function(t){var e=[],i=[],s=a(t.replace($,"$1"));return s[y]?at((function(t,e,i,n){for(var o,r=s(t,null,n,[]),a=t.length;a--;)(o=r[a])&&(t[a]=!(e[a]=o))})):function(t,n,o){return e[0]=t,s(e,null,o,i),e[0]=null,!i.pop()}})),has:at((function(t){return function(e){return ot(t,e).length>0}})),contains:at((function(t){return t=t.replace(Z,tt),function(e){return(e.textContent||e.innerText||n(e)).indexOf(t)>-1}})),lang:at((function(t){return V.test(t||"")||ot.error("unsupported lang: "+t),t=t.replace(Z,tt).toLowerCase(),function(e){var i;do{if(i=g?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(i=i.toLowerCase())===t||0===i.indexOf(t+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}})),target:function(e){var i=t.location&&t.location.hash;return i&&i.slice(1)===e.id},root:function(t){return t===f},focus:function(t){return t===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(t.type||t.href||~t.tabIndex)},enabled:pt(!1),disabled:pt(!0),checked:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&!!t.checked||"option"===e&&!!t.selected},selected:function(t){return t.parentNode&&t.parentNode.selectedIndex,!0===t.selected},empty:function(t){for(t=t.firstChild;t;t=t.nextSibling)if(t.nodeType<6)return!1;return!0},parent:function(t){return!s.pseudos.empty(t)},header:function(t){return Q.test(t.nodeName)},input:function(t){return K.test(t.nodeName)},button:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&"button"===t.type||"button"===e},text:function(t){var e;return"input"===t.nodeName.toLowerCase()&&"text"===t.type&&(null==(e=t.getAttribute("type"))||"text"===e.toLowerCase())},first:ft((function(){return[0]})),last:ft((function(t,e){return[e-1]})),eq:ft((function(t,e,i){return[i<0?i+e:i]})),even:ft((function(t,e){for(var i=0;i=0;)t.push(s);return t})),gt:ft((function(t,e,i){for(var s=i<0?i+e:i;++s1?function(e,i,s){for(var n=t.length;n--;)if(!t[n](e,i,s))return!1;return!0}:t[0]}function yt(t,e,i,s,n){for(var o,r=[],a=0,l=t.length,h=null!=e;a-1&&(o[h]=!(r[h]=u))}}else v=yt(v===r?v.splice(f,v.length):v),n?n(null,r,v,l):O.apply(r,v)}))}function xt(t){for(var e,i,n,o=t.length,r=s.relative[t[0].type],a=r||s.relative[" "],l=r?1:0,c=bt((function(t){return t===e}),a,!0),u=bt((function(t){return M(e,t)>-1}),a,!0),d=[function(t,i,s){var n=!r&&(s||i!==h)||((e=i).nodeType?c(t,i,s):u(t,i,s));return e=null,n}];l1&&_t(d),l>1&&vt(t.slice(0,l-1).concat({value:" "===t[l-2].type?"*":""})).replace($,"$1"),i,l0,n=t.length>0,o=function(o,r,a,l,c){var u,f,m,v=0,b="0",_=o&&[],y=[],w=h,C=o||n&&s.find.TAG("*",c),k=x+=null==w?1:Math.random()||.1,T=C.length;for(c&&(h=r===p||r||c);b!==T&&null!=(u=C[b]);b++){if(n&&u){for(f=0,r||u.ownerDocument===p||(d(u),a=!g);m=t[f++];)if(m(u,r||p,a)){l.push(u);break}c&&(x=k)}i&&((u=!m&&u)&&v--,o&&_.push(u))}if(v+=b,i&&b!==v){for(f=0;m=e[f++];)m(_,y,r,a);if(o){if(v>0)for(;b--;)_[b]||y[b]||(y[b]=P.call(l));y=yt(y)}O.apply(l,y),c&&!o&&y.length>0&&v+e.length>1&&ot.uniqueSort(l)}return c&&(x=k,h=w),_};return i?at(o):o}(o,n))).selector=t}return a},l=ot.select=function(t,e,i,n){var o,l,h,c,u,d="function"==typeof t&&t,p=!n&&r(t=d.selector||t);if(i=i||[],1===p.length){if((l=p[0]=p[0].slice(0)).length>2&&"ID"===(h=l[0]).type&&9===e.nodeType&&g&&s.relative[l[1].type]){if(!(e=(s.find.ID(h.matches[0].replace(Z,tt),e)||[])[0]))return i;d&&(e=e.parentNode),t=t.slice(l.shift().value.length)}for(o=Y.needsContext.test(t)?0:l.length;o--&&(h=l[o],!s.relative[c=h.type]);)if((u=s.find[c])&&(n=u(h.matches[0].replace(Z,tt),J.test(l[0].type)&>(e.parentNode)||e))){if(l.splice(o,1),!(t=n.length&&vt(l)))return O.apply(i,n),i;break}}return(d||a(t,p))(n,e,!g,i,!e||J.test(t)&>(e.parentNode)||e),i},i.sortStable=y.split("").sort(I).join("")===y,i.detectDuplicates=!!u,d(),i.sortDetached=lt((function(t){return 1&t.compareDocumentPosition(p.createElement("fieldset"))})),lt((function(t){return t.innerHTML="","#"===t.firstChild.getAttribute("href")}))||ht("type|href|height|width",(function(t,e,i){if(!i)return t.getAttribute(e,"type"===e.toLowerCase()?1:2)})),i.attributes&<((function(t){return t.innerHTML="",t.firstChild.setAttribute("value",""),""===t.firstChild.getAttribute("value")}))||ht("value",(function(t,e,i){if(!i&&"input"===t.nodeName.toLowerCase())return t.defaultValue})),lt((function(t){return null==t.getAttribute("disabled")}))||ht(z,(function(t,e,i){var s;if(!i)return!0===t[e]?e.toLowerCase():(s=t.getAttributeNode(e))&&s.specified?s.value:null})),ot}(t);m.find=x,m.expr=x.selectors,m.expr[":"]=m.expr.pseudos,m.uniqueSort=m.unique=x.uniqueSort,m.text=x.getText,m.isXMLDoc=x.isXML,m.contains=x.contains,m.escapeSelector=x.escape;var C=function(t,e,i){for(var s=[],n=void 0!==i;(t=t[e])&&9!==t.nodeType;)if(1===t.nodeType){if(n&&m(t).is(i))break;s.push(t)}return s},k=function(t,e){for(var i=[];t;t=t.nextSibling)1===t.nodeType&&t!==e&&i.push(t);return i},T=m.expr.match.needsContext,D=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,I=/^.[^:#\[\.,]*$/;function S(t,e,i){return m.isFunction(e)?m.grep(t,(function(t,s){return!!e.call(t,s,t)!==i})):e.nodeType?m.grep(t,(function(t){return t===e!==i})):"string"!=typeof e?m.grep(t,(function(t){return l.call(e,t)>-1!==i})):I.test(e)?m.filter(e,t,i):(e=m.filter(e,t),m.grep(t,(function(t){return l.call(e,t)>-1!==i&&1===t.nodeType})))}m.filter=function(t,e,i){var s=e[0];return i&&(t=":not("+t+")"),1===e.length&&1===s.nodeType?m.find.matchesSelector(s,t)?[s]:[]:m.find.matches(t,m.grep(e,(function(t){return 1===t.nodeType})))},m.fn.extend({find:function(t){var e,i,s=this.length,n=this;if("string"!=typeof t)return this.pushStack(m(t).filter((function(){for(e=0;e1?m.uniqueSort(i):i},filter:function(t){return this.pushStack(S(this,t||[],!1))},not:function(t){return this.pushStack(S(this,t||[],!0))},is:function(t){return!!S(this,"string"==typeof t&&T.test(t)?m(t):t||[],!1).length}});var E,P=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(m.fn.init=function(t,e,i){var n,o;if(!t)return this;if(i=i||E,"string"==typeof t){if(!(n="<"===t[0]&&">"===t[t.length-1]&&t.length>=3?[null,t,null]:P.exec(t))||!n[1]&&e)return!e||e.jquery?(e||i).find(t):this.constructor(e).find(t);if(n[1]){if(e=e instanceof m?e[0]:e,m.merge(this,m.parseHTML(n[1],e&&e.nodeType?e.ownerDocument||e:s,!0)),D.test(n[1])&&m.isPlainObject(e))for(n in e)m.isFunction(this[n])?this[n](e[n]):this.attr(n,e[n]);return this}return(o=s.getElementById(n[2]))&&(this[0]=o,this.length=1),this}return t.nodeType?(this[0]=t,this.length=1,this):m.isFunction(t)?void 0!==i.ready?i.ready(t):t(m):m.makeArray(t,this)}).prototype=m.fn,E=m(s);var A=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function N(t,e){for(;(t=t[e])&&1!==t.nodeType;);return t}m.fn.extend({has:function(t){var e=m(t,this),i=e.length;return this.filter((function(){for(var t=0;t-1:1===i.nodeType&&m.find.matchesSelector(i,t))){o.push(i);break}return this.pushStack(o.length>1?m.uniqueSort(o):o)},index:function(t){return t?"string"==typeof t?l.call(m(t),this[0]):l.call(this,t.jquery?t[0]:t):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(t,e){return this.pushStack(m.uniqueSort(m.merge(this.get(),m(t,e))))},addBack:function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}}),m.each({parent:function(t){var e=t.parentNode;return e&&11!==e.nodeType?e:null},parents:function(t){return C(t,"parentNode")},parentsUntil:function(t,e,i){return C(t,"parentNode",i)},next:function(t){return N(t,"nextSibling")},prev:function(t){return N(t,"previousSibling")},nextAll:function(t){return C(t,"nextSibling")},prevAll:function(t){return C(t,"previousSibling")},nextUntil:function(t,e,i){return C(t,"nextSibling",i)},prevUntil:function(t,e,i){return C(t,"previousSibling",i)},siblings:function(t){return k((t.parentNode||{}).firstChild,t)},children:function(t){return k(t.firstChild)},contents:function(t){return t.contentDocument||m.merge([],t.childNodes)}},(function(t,e){m.fn[t]=function(i,s){var n=m.map(this,e,i);return"Until"!==t.slice(-5)&&(s=i),s&&"string"==typeof s&&(n=m.filter(s,n)),this.length>1&&(O[t]||m.uniqueSort(n),A.test(t)&&n.reverse()),this.pushStack(n)}}));var M=/[^\x20\t\r\n\f]+/g;function z(t){return t}function H(t){throw t}function L(t,e,i){var s;try{t&&m.isFunction(s=t.promise)?s.call(t).done(e).fail(i):t&&m.isFunction(s=t.then)?s.call(t,e,i):e.call(void 0,t)}catch(t){i.call(void 0,t)}}m.Callbacks=function(t){t="string"==typeof t?function(t){var e={};return m.each(t.match(M)||[],(function(t,i){e[i]=!0})),e}(t):m.extend({},t);var e,i,s,n,o=[],r=[],a=-1,l=function(){for(n=t.once,s=e=!0;r.length;a=-1)for(i=r.shift();++a-1;)o.splice(i,1),i<=a&&a--})),this},has:function(t){return t?m.inArray(t,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return n=r=[],o=i="",this},disabled:function(){return!o},lock:function(){return n=r=[],i||e||(o=i=""),this},locked:function(){return!!n},fireWith:function(t,i){return n||(i=[t,(i=i||[]).slice?i.slice():i],r.push(i),e||l()),this},fire:function(){return h.fireWith(this,arguments),this},fired:function(){return!!s}};return h},m.extend({Deferred:function(e){var i=[["notify","progress",m.Callbacks("memory"),m.Callbacks("memory"),2],["resolve","done",m.Callbacks("once memory"),m.Callbacks("once memory"),0,"resolved"],["reject","fail",m.Callbacks("once memory"),m.Callbacks("once memory"),1,"rejected"]],s="pending",n={state:function(){return s},always:function(){return o.done(arguments).fail(arguments),this},catch:function(t){return n.then(null,t)},pipe:function(){var t=arguments;return m.Deferred((function(e){m.each(i,(function(i,s){var n=m.isFunction(t[s[4]])&&t[s[4]];o[s[1]]((function(){var t=n&&n.apply(this,arguments);t&&m.isFunction(t.promise)?t.promise().progress(e.notify).done(e.resolve).fail(e.reject):e[s[0]+"With"](this,n?[t]:arguments)}))})),t=null})).promise()},then:function(e,s,n){var o=0;function r(e,i,s,n){return function(){var a=this,l=arguments,h=function(){var t,h;if(!(e=o&&(s!==H&&(a=void 0,l=[t]),i.rejectWith(a,l))}};e?c():(m.Deferred.getStackHook&&(c.stackTrace=m.Deferred.getStackHook()),t.setTimeout(c))}}return m.Deferred((function(t){i[0][3].add(r(0,t,m.isFunction(n)?n:z,t.notifyWith)),i[1][3].add(r(0,t,m.isFunction(e)?e:z)),i[2][3].add(r(0,t,m.isFunction(s)?s:H))})).promise()},promise:function(t){return null!=t?m.extend(t,n):n}},o={};return m.each(i,(function(t,e){var r=e[2],a=e[5];n[e[1]]=r.add,a&&r.add((function(){s=a}),i[3-t][2].disable,i[0][2].lock),r.add(e[3].fire),o[e[0]]=function(){return o[e[0]+"With"](this===o?void 0:this,arguments),this},o[e[0]+"With"]=r.fireWith})),n.promise(o),e&&e.call(o,o),o},when:function(t){var e=arguments.length,i=e,s=Array(i),n=o.call(arguments),r=m.Deferred(),a=function(t){return function(i){s[t]=this,n[t]=arguments.length>1?o.call(arguments):i,--e||r.resolveWith(s,n)}};if(e<=1&&(L(t,r.done(a(i)).resolve,r.reject),"pending"===r.state()||m.isFunction(n[i]&&n[i].then)))return r.then();for(;i--;)L(n[i],a(i),r.reject);return r.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;m.Deferred.exceptionHook=function(e,i){t.console&&t.console.warn&&e&&W.test(e.name)&&t.console.warn("jQuery.Deferred exception: "+e.message,e.stack,i)},m.readyException=function(e){t.setTimeout((function(){throw e}))};var R=m.Deferred();function F(){s.removeEventListener("DOMContentLoaded",F),t.removeEventListener("load",F),m.ready()}m.fn.ready=function(t){return R.then(t).catch((function(t){m.readyException(t)})),this},m.extend({isReady:!1,readyWait:1,holdReady:function(t){t?m.readyWait++:m.ready(!0)},ready:function(t){(!0===t?--m.readyWait:m.isReady)||(m.isReady=!0,!0!==t&&--m.readyWait>0||R.resolveWith(s,[m]))}}), -m.ready.then=R.then,"complete"===s.readyState||"loading"!==s.readyState&&!s.documentElement.doScroll?t.setTimeout(m.ready):(s.addEventListener("DOMContentLoaded",F),t.addEventListener("load",F));var $=function(t,e,i,s,n,o,r){var a=0,l=t.length,h=null==i;if("object"===m.type(i))for(a in n=!0,i)$(t,e,a,i[a],!0,o,r);else if(void 0!==s&&(n=!0,m.isFunction(s)||(r=!0),h&&(r?(e.call(t,s),e=null):(h=e,e=function(t,e,i){return h.call(m(t),i)})),e))for(;a1,null,!0)},removeData:function(t){return this.each((function(){U.remove(this,t)}))}}),m.extend({queue:function(t,e,i){var s;if(t)return e=(e||"fx")+"queue",s=q.get(t,e),i&&(!s||m.isArray(i)?s=q.access(t,e,m.makeArray(i)):s.push(i)),s||[]},dequeue:function(t,e){e=e||"fx";var i=m.queue(t,e),s=i.length,n=i.shift(),o=m._queueHooks(t,e);"inprogress"===n&&(n=i.shift(),s--),n&&("fx"===e&&i.unshift("inprogress"),delete o.stop,n.call(t,(function(){m.dequeue(t,e)}),o)),!s&&o&&o.empty.fire()},_queueHooks:function(t,e){var i=e+"queueHooks";return q.get(t,i)||q.access(t,i,{empty:m.Callbacks("once memory").add((function(){q.remove(t,[e+"queue",i])}))})}}),m.fn.extend({queue:function(t,e){var i=2;return"string"!=typeof t&&(e=t,t="fx",i--),arguments.length\x20\t\r\n\f]+)/i,rt=/^$|\/(?:java|ecma)script/i,at={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function lt(t,e){var i;return i=void 0!==t.getElementsByTagName?t.getElementsByTagName(e||"*"):void 0!==t.querySelectorAll?t.querySelectorAll(e||"*"):[],void 0===e||e&&m.nodeName(t,e)?m.merge([t],i):i}function ht(t,e){for(var i=0,s=t.length;i-1)n&&n.push(o);else if(h=m.contains(o.ownerDocument,o),r=lt(u.appendChild(o),"script"),h&&ht(r),i)for(c=0;o=r[c++];)rt.test(o.type||"")&&i.push(o);return u}ct=s.createDocumentFragment().appendChild(s.createElement("div")),(ut=s.createElement("input")).setAttribute("type","radio"),ut.setAttribute("checked","checked"),ut.setAttribute("name","t"),ct.appendChild(ut),f.checkClone=ct.cloneNode(!0).cloneNode(!0).lastChild.checked,ct.innerHTML="",f.noCloneChecked=!!ct.cloneNode(!0).lastChild.defaultValue;var ft=s.documentElement,gt=/^key/,mt=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,vt=/^([^.]*)(?:\.(.+)|)/;function bt(){return!0}function _t(){return!1}function yt(){try{return s.activeElement}catch(t){}}function wt(t,e,i,s,n,o){var r,a;if("object"==typeof e){for(a in"string"!=typeof i&&(s=s||i,i=void 0),e)wt(t,a,i,s,e[a],o);return t}if(null==s&&null==n?(n=i,s=i=void 0):null==n&&("string"==typeof i?(n=s,s=void 0):(n=s,s=i,i=void 0)),!1===n)n=_t;else if(!n)return t;return 1===o&&(r=n,(n=function(t){return m().off(t),r.apply(this,arguments)}).guid=r.guid||(r.guid=m.guid++)),t.each((function(){m.event.add(this,e,n,s,i)}))}m.event={global:{},add:function(t,e,i,s,n){var o,r,a,l,h,c,u,d,p,f,g,v=q.get(t);if(v)for(i.handler&&(i=(o=i).handler,n=o.selector),n&&m.find.matchesSelector(ft,n),i.guid||(i.guid=m.guid++),(l=v.events)||(l=v.events={}),(r=v.handle)||(r=v.handle=function(e){return void 0!==m&&m.event.triggered!==e.type?m.event.dispatch.apply(t,arguments):void 0}),h=(e=(e||"").match(M)||[""]).length;h--;)p=g=(a=vt.exec(e[h])||[])[1],f=(a[2]||"").split(".").sort(),p&&(u=m.event.special[p]||{},p=(n?u.delegateType:u.bindType)||p,u=m.event.special[p]||{},c=m.extend({type:p,origType:g,data:s,handler:i,guid:i.guid,selector:n,needsContext:n&&m.expr.match.needsContext.test(n),namespace:f.join(".")},o),(d=l[p])||((d=l[p]=[]).delegateCount=0,u.setup&&!1!==u.setup.call(t,s,f,r)||t.addEventListener&&t.addEventListener(p,r)),u.add&&(u.add.call(t,c),c.handler.guid||(c.handler.guid=i.guid)),n?d.splice(d.delegateCount++,0,c):d.push(c),m.event.global[p]=!0)},remove:function(t,e,i,s,n){var o,r,a,l,h,c,u,d,p,f,g,v=q.hasData(t)&&q.get(t);if(v&&(l=v.events)){for(h=(e=(e||"").match(M)||[""]).length;h--;)if(p=g=(a=vt.exec(e[h])||[])[1],f=(a[2]||"").split(".").sort(),p){for(u=m.event.special[p]||{},d=l[p=(s?u.delegateType:u.bindType)||p]||[],a=a[2]&&new RegExp("(^|\\.)"+f.join("\\.(?:.*\\.|)")+"(\\.|$)"),r=o=d.length;o--;)c=d[o],!n&&g!==c.origType||i&&i.guid!==c.guid||a&&!a.test(c.namespace)||s&&s!==c.selector&&("**"!==s||!c.selector)||(d.splice(o,1),c.selector&&d.delegateCount--,u.remove&&u.remove.call(t,c));r&&!d.length&&(u.teardown&&!1!==u.teardown.call(t,f,v.handle)||m.removeEvent(t,p,v.handle),delete l[p])}else for(p in l)m.event.remove(t,p+e[h],i,s,!0);m.isEmptyObject(l)&&q.remove(t,"handle events")}},dispatch:function(t){var e,i,s,n,o,r,a=m.event.fix(t),l=new Array(arguments.length),h=(q.get(this,"events")||{})[a.type]||[],c=m.event.special[a.type]||{};for(l[0]=a,e=1;e=1))for(;h!==this;h=h.parentNode||this)if(1===h.nodeType&&("click"!==t.type||!0!==h.disabled)){for(o=[],r={},i=0;i-1:m.find(n,this,null,[h]).length),r[n]&&o.push(s);o.length&&a.push({elem:h,handlers:o})}return h=this,l\x20\t\r\n\f]*)[^>]*)\/>/gi,Ct=/\s*$/g;function It(t,e){return m.nodeName(t,"table")&&m.nodeName(11!==e.nodeType?e:e.firstChild,"tr")&&t.getElementsByTagName("tbody")[0]||t}function St(t){return t.type=(null!==t.getAttribute("type"))+"/"+t.type,t}function $t(t){var e=Tt.exec(t.type);return e?t.type=e[1]:t.removeAttribute("type"),t}function Et(t,e){var i,s,n,o,r,a,l,h;if(1===e.nodeType){if(q.hasData(t)&&(o=q.access(t),r=q.set(e,o),h=o.events))for(n in delete r.handle,r.events={},h)for(i=0,s=h[n].length;i1&&"string"==typeof v&&!f.checkClone&&kt.test(v))return t.each((function(n){var o=t.eq(n);b&&(e[0]=v.call(this,n,o.html())),Pt(o,e,i,s)}));if(d&&(o=(n=pt(e,t[0].ownerDocument,!1,t,s)).firstChild,1===n.childNodes.length&&(n=o),o||s)){for(l=(a=m.map(lt(n,"script"),St)).length;u")},clone:function(t,e,i){var s,n,o,r,a,l,h,c=t.cloneNode(!0),u=m.contains(t.ownerDocument,t);if(!(f.noCloneChecked||1!==t.nodeType&&11!==t.nodeType||m.isXMLDoc(t)))for(r=lt(c),s=0,n=(o=lt(t)).length;s0&&ht(r,!u&<(t,"script")),c},cleanData:function(t){for(var e,i,s,n=m.event.special,o=0;void 0!==(i=t[o]);o++)if(j(i)){if(e=i[q.expando]){if(e.events)for(s in e.events)n[s]?m.event.remove(i,s):m.removeEvent(i,s,e.handle);i[q.expando]=void 0}i[U.expando]&&(i[U.expando]=void 0)}}}),m.fn.extend({detach:function(t){return At(this,t,!0)},remove:function(t){return At(this,t)},text:function(t){return $(this,(function(t){return void 0===t?m.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=t)}))}),null,t,arguments.length)},append:function(){return Pt(this,arguments,(function(t){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||It(this,t).appendChild(t)}))},prepend:function(){return Pt(this,arguments,(function(t){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var e=It(this,t);e.insertBefore(t,e.firstChild)}}))},before:function(){return Pt(this,arguments,(function(t){this.parentNode&&this.parentNode.insertBefore(t,this)}))},after:function(){return Pt(this,arguments,(function(t){this.parentNode&&this.parentNode.insertBefore(t,this.nextSibling)}))},empty:function(){for(var t,e=0;null!=(t=this[e]);e++)1===t.nodeType&&(m.cleanData(lt(t,!1)),t.textContent="");return this},clone:function(t,e){return t=null!=t&&t,e=null==e?t:e,this.map((function(){return m.clone(this,t,e)}))},html:function(t){return $(this,(function(t){var e=this[0]||{},i=0,s=this.length;if(void 0===t&&1===e.nodeType)return e.innerHTML;if("string"==typeof t&&!Ct.test(t)&&!at[(ot.exec(t)||["",""])[1].toLowerCase()]){t=m.htmlPrefilter(t);try{for(;i1)}}),m.Tween=Yt,Yt.prototype={constructor:Yt,init:function(t,e,i,s,n,o){this.elem=t,this.prop=i,this.easing=n||m.easing._default,this.options=e,this.start=this.now=this.cur(),this.end=s,this.unit=o||(m.cssNumber[i]?"":"px")},cur:function(){var t=Yt.propHooks[this.prop];return t&&t.get?t.get(this):Yt.propHooks._default.get(this)},run:function(t){var e,i=Yt.propHooks[this.prop];return this.options.duration?this.pos=e=m.easing[this.easing](t,this.options.duration*t,0,1,this.options.duration):this.pos=e=t,this.now=(this.end-this.start)*e+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),i&&i.set?i.set(this):Yt.propHooks._default.set(this),this}},Yt.prototype.init.prototype=Yt.prototype,Yt.propHooks={_default:{get:function(t){var e;return 1!==t.elem.nodeType||null!=t.elem[t.prop]&&null==t.elem.style[t.prop]?t.elem[t.prop]:(e=m.css(t.elem,t.prop,""))&&"auto"!==e?e:0},set:function(t){m.fx.step[t.prop]?m.fx.step[t.prop](t):1!==t.elem.nodeType||null==t.elem.style[m.cssProps[t.prop]]&&!m.cssHooks[t.prop]?t.elem[t.prop]=t.now:m.style(t.elem,t.prop,t.now+t.unit)}}},Yt.propHooks.scrollTop=Yt.propHooks.scrollLeft={set:function(t){t.elem.nodeType&&t.elem.parentNode&&(t.elem[t.prop]=t.now)}},m.easing={linear:function(t){return t},swing:function(t){return.5-Math.cos(t*Math.PI)/2},_default:"swing"},m.fx=Yt.prototype.init,m.fx.step={};var Kt,Qt,Xt=/^(?:toggle|show|hide)$/,Gt=/queueHooks$/;function Jt(){Qt&&(t.requestAnimationFrame(Jt),m.fx.tick())}function Zt(){return t.setTimeout((function(){Kt=void 0})),Kt=m.now()}function te(t,e){var i,s=0,n={height:t};for(e=e?1:0;s<4;s+=2-e)n["margin"+(i=G[s])]=n["padding"+i]=t;return e&&(n.opacity=n.width=t),n}function ee(t,e,i){for(var s,n=(ie.tweeners[e]||[]).concat(ie.tweeners["*"]),o=0,r=n.length;o1)},removeAttr:function(t){return this.each((function(){m.removeAttr(this,t)}))}}),m.extend({attr:function(t,e,i){var s,n,o=t.nodeType;if(3!==o&&8!==o&&2!==o)return void 0===t.getAttribute?m.prop(t,e,i):(1===o&&m.isXMLDoc(t)||(n=m.attrHooks[e.toLowerCase()]||(m.expr.match.bool.test(e)?se:void 0)),void 0!==i?null===i?void m.removeAttr(t,e):n&&"set"in n&&void 0!==(s=n.set(t,i,e))?s:(t.setAttribute(e,i+""), -i):n&&"get"in n&&null!==(s=n.get(t,e))?s:null==(s=m.find.attr(t,e))?void 0:s)},attrHooks:{type:{set:function(t,e){if(!f.radioValue&&"radio"===e&&m.nodeName(t,"input")){var i=t.value;return t.setAttribute("type",e),i&&(t.value=i),e}}}},removeAttr:function(t,e){var i,s=0,n=e&&e.match(M);if(n&&1===t.nodeType)for(;i=n[s++];)t.removeAttribute(i)}}),se={set:function(t,e,i){return!1===e?m.removeAttr(t,i):t.setAttribute(i,i),i}},m.each(m.expr.match.bool.source.match(/\w+/g),(function(t,e){var i=ne[e]||m.find.attr;ne[e]=function(t,e,s){var n,o,r=e.toLowerCase();return s||(o=ne[r],ne[r]=n,n=null!=i(t,e,s)?r:null,ne[r]=o),n}}));var oe=/^(?:input|select|textarea|button)$/i,re=/^(?:a|area)$/i;function ae(t){return(t.match(M)||[]).join(" ")}function le(t){return t.getAttribute&&t.getAttribute("class")||""}m.fn.extend({prop:function(t,e){return $(this,m.prop,t,e,arguments.length>1)},removeProp:function(t){return this.each((function(){delete this[m.propFix[t]||t]}))}}),m.extend({prop:function(t,e,i){var s,n,o=t.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&m.isXMLDoc(t)||(e=m.propFix[e]||e,n=m.propHooks[e]),void 0!==i?n&&"set"in n&&void 0!==(s=n.set(t,i,e))?s:t[e]=i:n&&"get"in n&&null!==(s=n.get(t,e))?s:t[e]},propHooks:{tabIndex:{get:function(t){var e=m.find.attr(t,"tabindex");return e?parseInt(e,10):oe.test(t.nodeName)||re.test(t.nodeName)&&t.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),f.optSelected||(m.propHooks.selected={get:function(t){var e=t.parentNode;return e&&e.parentNode&&e.parentNode.selectedIndex,null},set:function(t){var e=t.parentNode;e&&(e.selectedIndex,e.parentNode&&e.parentNode.selectedIndex)}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],(function(){m.propFix[this.toLowerCase()]=this})),m.fn.extend({addClass:function(t){var e,i,s,n,o,r,a,l=0;if(m.isFunction(t))return this.each((function(e){m(this).addClass(t.call(this,e,le(this)))}));if("string"==typeof t&&t)for(e=t.match(M)||[];i=this[l++];)if(n=le(i),s=1===i.nodeType&&" "+ae(n)+" "){for(r=0;o=e[r++];)s.indexOf(" "+o+" ")<0&&(s+=o+" ");n!==(a=ae(s))&&i.setAttribute("class",a)}return this},removeClass:function(t){var e,i,s,n,o,r,a,l=0;if(m.isFunction(t))return this.each((function(e){m(this).removeClass(t.call(this,e,le(this)))}));if(!arguments.length)return this.attr("class","");if("string"==typeof t&&t)for(e=t.match(M)||[];i=this[l++];)if(n=le(i),s=1===i.nodeType&&" "+ae(n)+" "){for(r=0;o=e[r++];)for(;s.indexOf(" "+o+" ")>-1;)s=s.replace(" "+o+" "," ");n!==(a=ae(s))&&i.setAttribute("class",a)}return this},toggleClass:function(t,e){var i=typeof t;return"boolean"==typeof e&&"string"===i?e?this.addClass(t):this.removeClass(t):m.isFunction(t)?this.each((function(i){m(this).toggleClass(t.call(this,i,le(this),e),e)})):this.each((function(){var e,s,n,o;if("string"===i)for(s=0,n=m(this),o=t.match(M)||[];e=o[s++];)n.hasClass(e)?n.removeClass(e):n.addClass(e);else void 0!==t&&"boolean"!==i||((e=le(this))&&q.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===t?"":q.get(this,"__className__")||""))}))},hasClass:function(t){var e,i,s=0;for(e=" "+t+" ";i=this[s++];)if(1===i.nodeType&&(" "+ae(le(i))+" ").indexOf(e)>-1)return!0;return!1}});var he=/\r/g;m.fn.extend({val:function(t){var e,i,s,n=this[0];return arguments.length?(s=m.isFunction(t),this.each((function(i){var n;1===this.nodeType&&(null==(n=s?t.call(this,i,m(this).val()):t)?n="":"number"==typeof n?n+="":m.isArray(n)&&(n=m.map(n,(function(t){return null==t?"":t+""}))),(e=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()])&&"set"in e&&void 0!==e.set(this,n,"value")||(this.value=n))}))):n?(e=m.valHooks[n.type]||m.valHooks[n.nodeName.toLowerCase()])&&"get"in e&&void 0!==(i=e.get(n,"value"))?i:"string"==typeof(i=n.value)?i.replace(he,""):null==i?"":i:void 0}}),m.extend({valHooks:{option:{get:function(t){var e=m.find.attr(t,"value");return null!=e?e:ae(m.text(t))}},select:{get:function(t){var e,i,s,n=t.options,o=t.selectedIndex,r="select-one"===t.type,a=r?null:[],l=r?o+1:n.length;for(s=o<0?l:r?o:0;s-1)&&(i=!0);return i||(t.selectedIndex=-1),o}}}}),m.each(["radio","checkbox"],(function(){m.valHooks[this]={set:function(t,e){if(m.isArray(e))return t.checked=m.inArray(m(t).val(),e)>-1}},f.checkOn||(m.valHooks[this].get=function(t){return null===t.getAttribute("value")?"on":t.value})}));var ce=/^(?:focusinfocus|focusoutblur)$/;m.extend(m.event,{trigger:function(e,i,n,o){var r,a,l,h,c,d,p,f=[n||s],g=u.call(e,"type")?e.type:e,v=u.call(e,"namespace")?e.namespace.split("."):[];if(a=l=n=n||s,3!==n.nodeType&&8!==n.nodeType&&!ce.test(g+m.event.triggered)&&(g.indexOf(".")>-1&&(v=g.split("."),g=v.shift(),v.sort()),c=g.indexOf(":")<0&&"on"+g,(e=e[m.expando]?e:new m.Event(g,"object"==typeof e&&e)).isTrigger=o?2:3,e.namespace=v.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+v.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),i=null==i?[e]:m.makeArray(i,[e]),p=m.event.special[g]||{},o||!p.trigger||!1!==p.trigger.apply(n,i))){if(!o&&!p.noBubble&&!m.isWindow(n)){for(h=p.delegateType||g,ce.test(h+g)||(a=a.parentNode);a;a=a.parentNode)f.push(a),l=a;l===(n.ownerDocument||s)&&f.push(l.defaultView||l.parentWindow||t)}for(r=0;(a=f[r++])&&!e.isPropagationStopped();)e.type=r>1?h:p.bindType||g,(d=(q.get(a,"events")||{})[e.type]&&q.get(a,"handle"))&&d.apply(a,i),(d=c&&a[c])&&d.apply&&j(a)&&(e.result=d.apply(a,i),!1===e.result&&e.preventDefault());return e.type=g,o||e.isDefaultPrevented()||p._default&&!1!==p._default.apply(f.pop(),i)||!j(n)||c&&m.isFunction(n[g])&&!m.isWindow(n)&&((l=n[c])&&(n[c]=null),m.event.triggered=g,n[g](),m.event.triggered=void 0,l&&(n[c]=l)),e.result}},simulate:function(t,e,i){var s=m.extend(new m.Event,i,{type:t,isSimulated:!0});m.event.trigger(s,null,e)}}),m.fn.extend({trigger:function(t,e){return this.each((function(){m.event.trigger(t,e,this)}))},triggerHandler:function(t,e){var i=this[0];if(i)return m.event.trigger(t,e,i,!0)}}),m.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),(function(t,e){m.fn[e]=function(t,i){return arguments.length>0?this.on(e,null,t,i):this.trigger(e)}})),m.fn.extend({hover:function(t,e){return this.mouseenter(t).mouseleave(e||t)}}),f.focusin="onfocusin"in t,f.focusin||m.each({focus:"focusin",blur:"focusout"},(function(t,e){var i=function(t){m.event.simulate(e,t.target,m.event.fix(t))};m.event.special[e]={setup:function(){var s=this.ownerDocument||this,n=q.access(s,e);n||s.addEventListener(t,i,!0),q.access(s,e,(n||0)+1)},teardown:function(){var s=this.ownerDocument||this,n=q.access(s,e)-1;n?q.access(s,e,n):(s.removeEventListener(t,i,!0),q.remove(s,e))}}}));var ue=t.location,de=m.now(),pe=/\?/;m.parseXML=function(e){var i;if(!e||"string"!=typeof e)return null;try{i=(new t.DOMParser).parseFromString(e,"text/xml")}catch(t){i=void 0}return i&&!i.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+e),i};var fe=/\[\]$/,ge=/\r?\n/g,me=/^(?:submit|button|image|reset|file)$/i,ve=/^(?:input|select|textarea|keygen)/i;function be(t,e,i,s){var n;if(m.isArray(e))m.each(e,(function(e,n){i||fe.test(t)?s(t,n):be(t+"["+("object"==typeof n&&null!=n?e:"")+"]",n,i,s)}));else if(i||"object"!==m.type(e))s(t,e);else for(n in e)be(t+"["+n+"]",e[n],i,s)}m.param=function(t,e){var i,s=[],n=function(t,e){var i=m.isFunction(e)?e():e;s[s.length]=encodeURIComponent(t)+"="+encodeURIComponent(null==i?"":i)};if(m.isArray(t)||t.jquery&&!m.isPlainObject(t))m.each(t,(function(){n(this.name,this.value)}));else for(i in t)be(i,t[i],e,n);return s.join("&")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map((function(){var t=m.prop(this,"elements");return t?m.makeArray(t):this})).filter((function(){var t=this.type;return this.name&&!m(this).is(":disabled")&&ve.test(this.nodeName)&&!me.test(t)&&(this.checked||!nt.test(t))})).map((function(t,e){var i=m(this).val();return null==i?null:m.isArray(i)?m.map(i,(function(t){return{name:e.name,value:t.replace(ge,"\r\n")}})):{name:e.name,value:i.replace(ge,"\r\n")}})).get()}});var _e=/%20/g,ye=/#.*$/,we=/([?&])_=[^&]*/,xe=/^(.*?):[ \t]*([^\r\n]*)$/gm,Ce=/^(?:GET|HEAD)$/,ke=/^\/\//,Te={},De={},Ie="*/".concat("*"),Se=s.createElement("a");function $e(t){return function(e,i){"string"!=typeof e&&(i=e,e="*");var s,n=0,o=e.toLowerCase().match(M)||[];if(m.isFunction(i))for(;s=o[n++];)"+"===s[0]?(s=s.slice(1)||"*",(t[s]=t[s]||[]).unshift(i)):(t[s]=t[s]||[]).push(i)}}function Ee(t,e,i,s){var n={},o=t===De;function r(a){var l;return n[a]=!0,m.each(t[a]||[],(function(t,a){var h=a(e,i,s);return"string"!=typeof h||o||n[h]?o?!(l=h):void 0:(e.dataTypes.unshift(h),r(h),!1)})),l}return r(e.dataTypes[0])||!n["*"]&&r("*")}function Pe(t,e){var i,s,n=m.ajaxSettings.flatOptions||{};for(i in e)void 0!==e[i]&&((n[i]?t:s||(s={}))[i]=e[i]);return s&&m.extend(!0,t,s),t}Se.href=ue.href,m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:ue.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(ue.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Ie,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(t,e){return e?Pe(Pe(t,m.ajaxSettings),e):Pe(m.ajaxSettings,t)},ajaxPrefilter:$e(Te),ajaxTransport:$e(De),ajax:function(e,i){"object"==typeof e&&(i=e,e=void 0),i=i||{};var n,o,r,a,l,h,c,u,d,p,f=m.ajaxSetup({},i),g=f.context||f,v=f.context&&(g.nodeType||g.jquery)?m(g):m.event,b=m.Deferred(),_=m.Callbacks("once memory"),y=f.statusCode||{},w={},x={},C="canceled",k={readyState:0,getResponseHeader:function(t){var e;if(c){if(!a)for(a={};e=xe.exec(r);)a[e[1].toLowerCase()]=e[2];e=a[t.toLowerCase()]}return null==e?null:e},getAllResponseHeaders:function(){return c?r:null},setRequestHeader:function(t,e){return null==c&&(t=x[t.toLowerCase()]=x[t.toLowerCase()]||t,w[t]=e),this},overrideMimeType:function(t){return null==c&&(f.mimeType=t),this},statusCode:function(t){var e;if(t)if(c)k.always(t[k.status]);else for(e in t)y[e]=[y[e],t[e]];return this},abort:function(t){var e=t||C;return n&&n.abort(e),T(0,e),this}};if(b.promise(k),f.url=((e||f.url||ue.href)+"").replace(ke,ue.protocol+"//"),f.type=i.method||i.type||f.method||f.type,f.dataTypes=(f.dataType||"*").toLowerCase().match(M)||[""],null==f.crossDomain){h=s.createElement("a");try{h.href=f.url,h.href=h.href,f.crossDomain=Se.protocol+"//"+Se.host!=h.protocol+"//"+h.host}catch(t){f.crossDomain=!0}}if(f.data&&f.processData&&"string"!=typeof f.data&&(f.data=m.param(f.data,f.traditional)),Ee(Te,f,i,k),c)return k;for(d in(u=m.event&&f.global)&&0==m.active++&&m.event.trigger("ajaxStart"),f.type=f.type.toUpperCase(),f.hasContent=!Ce.test(f.type),o=f.url.replace(ye,""),f.hasContent?f.data&&f.processData&&0===(f.contentType||"").indexOf("application/x-www-form-urlencoded")&&(f.data=f.data.replace(_e,"+")):(p=f.url.slice(o.length),f.data&&(o+=(pe.test(o)?"&":"?")+f.data,delete f.data),!1===f.cache&&(o=o.replace(we,"$1"),p=(pe.test(o)?"&":"?")+"_="+de+++p),f.url=o+p),f.ifModified&&(m.lastModified[o]&&k.setRequestHeader("If-Modified-Since",m.lastModified[o]),m.etag[o]&&k.setRequestHeader("If-None-Match",m.etag[o])),(f.data&&f.hasContent&&!1!==f.contentType||i.contentType)&&k.setRequestHeader("Content-Type",f.contentType),k.setRequestHeader("Accept",f.dataTypes[0]&&f.accepts[f.dataTypes[0]]?f.accepts[f.dataTypes[0]]+("*"!==f.dataTypes[0]?", "+Ie+"; q=0.01":""):f.accepts["*"]),f.headers)k.setRequestHeader(d,f.headers[d]);if(f.beforeSend&&(!1===f.beforeSend.call(g,k,f)||c))return k.abort();if(C="abort",_.add(f.complete),k.done(f.success),k.fail(f.error),n=Ee(De,f,i,k)){if(k.readyState=1,u&&v.trigger("ajaxSend",[k,f]),c)return k;f.async&&f.timeout>0&&(l=t.setTimeout((function(){k.abort("timeout")}),f.timeout));try{c=!1,n.send(w,T)}catch(t){if(c)throw t;T(-1,t)}}else T(-1,"No Transport");function T(e,i,s,a){var h,d,p,w,x,C=i;c||(c=!0,l&&t.clearTimeout(l),n=void 0,r=a||"",k.readyState=e>0?4:0,h=e>=200&&e<300||304===e,s&&(w=function(t,e,i){for(var s,n,o,r,a=t.contents,l=t.dataTypes;"*"===l[0];)l.shift(),void 0===s&&(s=t.mimeType||e.getResponseHeader("Content-Type"));if(s)for(n in a)if(a[n]&&a[n].test(s)){l.unshift(n);break}if(l[0]in i)o=l[0];else{for(n in i){if(!l[0]||t.converters[n+" "+l[0]]){o=n;break}r||(r=n)}o=o||r}if(o)return o!==l[0]&&l.unshift(o),i[o]}(f,k,s)),w=function(t,e,i,s){var n,o,r,a,l,h={},c=t.dataTypes.slice();if(c[1])for(r in t.converters)h[r.toLowerCase()]=t.converters[r];for(o=c.shift();o;)if(t.responseFields[o]&&(i[t.responseFields[o]]=e),!l&&s&&t.dataFilter&&(e=t.dataFilter(e,t.dataType)),l=o,o=c.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(!(r=h[l+" "+o]||h["* "+o]))for(n in h)if((a=n.split(" "))[1]===o&&(r=h[l+" "+a[0]]||h["* "+a[0]])){!0===r?r=h[n]:!0!==h[n]&&(o=a[0],c.unshift(a[1]));break}if(!0!==r)if(r&&t.throws)e=r(e);else try{e=r(e)}catch(t){return{state:"parsererror",error:r?t:"No conversion from "+l+" to "+o}}}return{state:"success",data:e}}(f,w,k,h),h?(f.ifModified&&((x=k.getResponseHeader("Last-Modified"))&&(m.lastModified[o]=x),(x=k.getResponseHeader("etag"))&&(m.etag[o]=x)),204===e||"HEAD"===f.type?C="nocontent":304===e?C="notmodified":(C=w.state,d=w.data,h=!(p=w.error))):(p=C,!e&&C||(C="error",e<0&&(e=0))),k.status=e,k.statusText=(i||C)+"",h?b.resolveWith(g,[d,C,k]):b.rejectWith(g,[k,C,p]),k.statusCode(y),y=void 0,u&&v.trigger(h?"ajaxSuccess":"ajaxError",[k,f,h?d:p]),_.fireWith(g,[k,C]),u&&(v.trigger("ajaxComplete",[k,f]),--m.active||m.event.trigger("ajaxStop")))}return k},getJSON:function(t,e,i){return m.get(t,e,i,"json")},getScript:function(t,e){return m.get(t,void 0,e,"script")}}),m.each(["get","post"],(function(t,e){m[e]=function(t,i,s,n){return m.isFunction(i)&&(n=n||s,s=i,i=void 0),m.ajax(m.extend({url:t,type:e,dataType:n,data:i,success:s},m.isPlainObject(t)&&t))}})),m._evalUrl=function(t){return m.ajax({url:t,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,throws:!0})},m.fn.extend({wrapAll:function(t){var e;return this[0]&&(m.isFunction(t)&&(t=t.call(this[0])),e=m(t,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&e.insertBefore(this[0]),e.map((function(){for(var t=this;t.firstElementChild;)t=t.firstElementChild;return t})).append(this)),this},wrapInner:function(t){return m.isFunction(t)?this.each((function(e){m(this).wrapInner(t.call(this,e))})):this.each((function(){var e=m(this),i=e.contents();i.length?i.wrapAll(t):e.append(t)}))},wrap:function(t){var e=m.isFunction(t);return this.each((function(i){m(this).wrapAll(e?t.call(this,i):t)}))},unwrap:function(t){return this.parent(t).not("body").each((function(){m(this).replaceWith(this.childNodes)})),this}}),m.expr.pseudos.hidden=function(t){return!m.expr.pseudos.visible(t)},m.expr.pseudos.visible=function(t){return!!(t.offsetWidth||t.offsetHeight||t.getClientRects().length)},m.ajaxSettings.xhr=function(){try{return new t.XMLHttpRequest}catch(t){}};var Ae={0:200,1223:204},Oe=m.ajaxSettings.xhr();f.cors=!!Oe&&"withCredentials"in Oe,f.ajax=Oe=!!Oe,m.ajaxTransport((function(e){var i,s;if(f.cors||Oe&&!e.crossDomain)return{send:function(n,o){var r,a=e.xhr();if(a.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(r in e.xhrFields)a[r]=e.xhrFields[r];for(r in e.mimeType&&a.overrideMimeType&&a.overrideMimeType(e.mimeType),e.crossDomain||n["X-Requested-With"]||(n["X-Requested-With"]="XMLHttpRequest"),n)a.setRequestHeader(r,n[r]);i=function(t){return function(){i&&(i=s=a.onload=a.onerror=a.onabort=a.onreadystatechange=null,"abort"===t?a.abort():"error"===t?"number"!=typeof a.status?o(0,"error"):o(a.status,a.statusText):o(Ae[a.status]||a.status,a.statusText,"text"!==(a.responseType||"text")||"string"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=i(),s=a.onerror=i("error"),void 0!==a.onabort?a.onabort=s:a.onreadystatechange=function(){4===a.readyState&&t.setTimeout((function(){i&&s()}))},i=i("abort");try{a.send(e.hasContent&&e.data||null)}catch(t){if(i)throw t}},abort:function(){i&&i()}}})),m.ajaxPrefilter((function(t){t.crossDomain&&(t.contents.script=!1)})),m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(t){return m.globalEval(t),t}}}),m.ajaxPrefilter("script",(function(t){void 0===t.cache&&(t.cache=!1),t.crossDomain&&(t.type="GET")})),m.ajaxTransport("script",(function(t){var e,i;if(t.crossDomain)return{send:function(n,o){e=m("