diff --git a/trunk/app/Resources/views/base.html.twig b/trunk/app/Resources/views/base.html.twig index 68a662e8..1821083b 100644 --- a/trunk/app/Resources/views/base.html.twig +++ b/trunk/app/Resources/views/base.html.twig @@ -21,7 +21,6 @@ {% stylesheets 'bundles/app/css/bootstrap-3.3.7.css' 'bundles/app/css/custom.css' - 'bundles/app/css/booking.css' filter='cssrewrite' %} diff --git a/trunk/app/Resources/views/default/components/booking/summary.html.twig b/trunk/app/Resources/views/default/components/booking/summary.html.twig new file mode 100644 index 00000000..d8af11be --- /dev/null +++ b/trunk/app/Resources/views/default/components/booking/summary.html.twig @@ -0,0 +1,20 @@ + + + {% for summary_entry in summary %} + + + + + {% endfor %} + + + + + +
+ {{ summary_entry.value|number_format(2) }} € + + {{ summary_entry.label|raw }} +
+ = {{ total_price|number_format(2) }} € + Gesamtpreis der Reise
diff --git a/trunk/app/Resources/views/default/email/bookingConfirmationEmail.txt.twig b/trunk/app/Resources/views/default/email/bookingConfirmationEmail.txt.twig new file mode 100644 index 00000000..b15e9b6b --- /dev/null +++ b/trunk/app/Resources/views/default/email/bookingConfirmationEmail.txt.twig @@ -0,0 +1,11 @@ +{# @var booking_request \AppBundle\Entity\BookingRequest #} +Sehr geehrte{{ booking_request.salutation == 1 ? 'r Herr' : ' Frau' }} {{ booking_request.lastName }}, + +vielen Dank für Ihren Buchungsauftrag. Dieser wird schnellstmöglich bearbeitet und stellt noch keine{# +#} Buchungsbestätigung dar. Bitte prüfen Sie noch einmal Ihre Angaben und kontaktieren Sie uns bitte, wenn ein Fehler{# +#} enthalten ist. + +{% include 'default/email/components/bookingSummary.txt.twig' %} + +{% include 'default/email/components/signature.txt.twig' %} + diff --git a/trunk/app/Resources/views/default/email/bookingServiceEmail.txt.twig b/trunk/app/Resources/views/default/email/bookingServiceEmail.txt.twig new file mode 100644 index 00000000..0a063408 --- /dev/null +++ b/trunk/app/Resources/views/default/email/bookingServiceEmail.txt.twig @@ -0,0 +1,7 @@ +FOLGENDE REISE WURDE GEBUCHT: + +URL: {{ travel_program_url }} + +CRM: {{ crm_url }} + +{% include 'default/email/components/bookingSummary.txt.twig' %} \ No newline at end of file diff --git a/trunk/app/Resources/views/default/email/components/bookingSummary.txt.twig b/trunk/app/Resources/views/default/email/components/bookingSummary.txt.twig new file mode 100644 index 00000000..64bc411d --- /dev/null +++ b/trunk/app/Resources/views/default/email/components/bookingSummary.txt.twig @@ -0,0 +1,71 @@ +{# @var booking_request \AppBundle\Entity\BookingRequest #} +===================================================================================== +Reisedaten: +===================================================================================== +Reiseprogramm: {{ travel_date.travelProgram.title }} ({{ travel_date.name }}) +Kategorie: Standard +Reisezeitraum: {{ travel_date.start|date }} - {{ travel_date.end|date }} +Abfahrts-/Abflugort: {{ booking_request.departure.name }} {{ booking_request.departure.extraCharge|number_format(2) }} € p.P. + +{% for room in booking_price_info['rooms'] %} +1x {{ room['name'] }} [Personen: {{ room.adults }} x {{ room['price']|number_format(2) }} €] +{% endfor %} +{{ booking_request.departure.extraCharge < 0 ? 'Aufschlag' : 'Abzug' }} Abfahrts-/Abflugort {{ booking_request.departure.name }}{# +#} {{ booking_request.travelerCount }} x {{ booking_request.departure.extraCharge|number_format(2) }} €: {{ + (booking_request.travelerCount * booking_request.departure.extraCharge)|number_format(2) }} € +{% for insuranceInfo in booking_price_info['insurances'] %} +{{ insuranceInfo['count'] }}x RV {{ insuranceInfo['insurance'].name }} ({{ insuranceInfo['insurancePrice'].code -}} +) {{ insuranceInfo['insurancePriceValue']|number_format(2) }} €: {{ (insuranceInfo['count'] * + insuranceInfo['insurancePriceValue'])|number_format(2) }} € +{% endfor %} +{% for option in booking_request.travelOptions %} +{{ booking_request.travelerCount }}x zugebuchte Leistung (Erwachsener): {{ option.name }} {{ option.price|number_format(2) -}} +€: {{ (booking_request.travelerCount * option.price|number_format(2)) }} € +{% endfor %} +{% for classOption in booking_price_info['classOptions'] %} +{{ classOption['count'] }}x {{ classOption['name'] }} {{ classOption['price']|number_format(2) }} €: {{ +(classOption['count'] * classOption['price'])|number_format(2) }} € +{% endfor %} + +Gesamtpreis: {{ booking_price_info['total']|number_format(2) }} € + +===================================================================================== +Reiseleistungen: +===================================================================================== +Eingeschlossene Leistungen: +{% for travel_program_service in travel_date.travelProgram.included|split('\n') %} + [x] {{ travel_program_service|raw }} +{% endfor %} + +Nicht eingeschlossene, zubuchbare Leistungen: +{% for travel_program_service in travel_date.travelProgram.excluded|split('\n') %} + [o] {{ travel_program_service|raw }} +{% endfor %} + +===================================================================================== +Reiseanmelder{% if booking_request.salutation == 2 %}in{% endif %} + +===================================================================================== +Vorname: {{ booking_request.firstName }} +Nachname: {{ booking_request.lastName }} +Adresse: {{ booking_request.streetAddress }} +PLZ: {{ booking_request.zipCode }} +Ort: {{ booking_request.city }} +Telefonnummer: {{ booking_request.phone }} +Fax: {{ booking_request.fax ?? 'keine Angabe' }} + +===================================================================================== +Reiseteilnehmer: +#) Geschlecht, Vorname, Nachname, Geburtsdatum +===================================================================================== +{% for traveler in booking_request.travelers|slice(0, booking_request.travelerCount) %} +{{ loop.index }}) {{ traveler.sex == 1 ? 'männlich' : 'weiblich' }}, {{ traveler.firstName }}, {{ traveler.lastName -}} +, {{ traveler.birthDate|date }} +{% endfor %} + +===================================================================================== +Mitteilungen / Sonstiges: +===================================================================================== +{{ booking_request.notes ?? '-' }} + + diff --git a/trunk/app/Resources/views/default/email/components/signature.txt.twig b/trunk/app/Resources/views/default/email/components/signature.txt.twig new file mode 100644 index 00000000..2323278e --- /dev/null +++ b/trunk/app/Resources/views/default/email/components/signature.txt.twig @@ -0,0 +1,19 @@ +Mit freundlichen Grüßen +Ihr Team von STERN TOURS + +-- + +STERN TOURS Travelservice GmbH +Uhlandstr. 137 +10717 Berlin + +Geschäftsführer: Thomas Stern +E-Mail: stern@stern-tours.de +Tel.: 030 / 700 94 100 +Fax: 030 / 700 94 1044 + +Registergericht: Amtsgericht Charlottenburg +Registernummer: HRB 67111 +Steuernummer: 27/016/10728 +UST-Ident.-Nr.: DE192609253 +Finanzamt: Wilmersdorf \ No newline at end of file diff --git a/trunk/app/Resources/views/default/form/helpers.html.twig b/trunk/app/Resources/views/default/form/helpers.html.twig new file mode 100644 index 00000000..03bef70b --- /dev/null +++ b/trunk/app/Resources/views/default/form/helpers.html.twig @@ -0,0 +1,19 @@ +{%- block form_field -%} + {{- form_label(form, label, opt ?? {}) -}} + {{- form_widget(form, opt ?? {}) -}} + {{- form_errors(form) -}} +{%- endblock form_field -%} + +{%- block form_field_pho -%} + {%- set opt = opt|merge({ + label_attr: (opt.label_attr ?? {})|merge({class: (opt.label_attr.class|default('') ~ ' sr-only')|trim}), + attr: (opt.attr ?? {})|merge({placeholder: opt.attr.placeholder|default( + (form.vars.translation_domain is same as(false) ? label : label|trans({}, form.vars.translation_domain)) ~ + ((opt.required ?? form.vars.required) ? ' *' : '') + )}) + }) -%} + {#{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' sr-only')|trim}) -%}#} + {{- form_label(form, label, opt) -}} + {{- form_widget(form, opt) -}} + {{- form_errors(form, opt) -}} +{%- endblock form_field_pho -%} \ No newline at end of file diff --git a/trunk/app/Resources/views/default/form/theme.html.twig b/trunk/app/Resources/views/default/form/theme.html.twig new file mode 100644 index 00000000..dd4e0102 --- /dev/null +++ b/trunk/app/Resources/views/default/form/theme.html.twig @@ -0,0 +1,32 @@ +{% use 'form_div_layout.html.twig' with + choice_widget_collapsed as base_choice_widget_collapsed, + checkbox_widget as base_checkbox_widget, + radio_widget as base_radio_widget +%} +{% use 'bootstrap_3_layout.html.twig' %} + +{% block choice_widget_collapsed -%} + {% set attr = attr|merge({ + class: (attr.class|default('') ~ ' selectpicker')|trim, + 'data-style': attr['data-style']|default('btn-white'), + 'data-dropout': attr['data-dropout']|default('false') + }) %} + +{%- endblock %} + +{% block checkbox_widget -%} + {{- block('base_checkbox_widget') -}} +{%- endblock checkbox_widget %} + +{% block radio_widget -%} + {{- block('base_radio_widget') -}} +{%- endblock radio_widget %} + +{% block form_label -%} + {%- if required -%} + {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' st-required')|trim}) -%} + {%- endif -%} + {{- parent() -}} +{%- endblock form_label %} \ No newline at end of file diff --git a/trunk/app/Resources/views/default/pages/booking.html.twig b/trunk/app/Resources/views/default/pages/booking.html.twig index aebc2776..a6a4a078 100644 --- a/trunk/app/Resources/views/default/pages/booking.html.twig +++ b/trunk/app/Resources/views/default/pages/booking.html.twig @@ -1,4 +1,19 @@ {% extends 'base.html.twig' %} +{% form_theme form 'default/form/theme.html.twig' %} + +{% block stylesheets %} + {{ parent() }} + {% stylesheets 'bundles/app/css/booking.css' filter='cssrewrite' %} + + {% endstylesheets %} +{% endblock %} + +{% block javascripts %} + {{ parent() }} + {% javascripts '@AppBundle/Resources/public/js/booking.js' %} + + {% endjavascripts %} +{% endblock %} {% block breadcrumb %} {{ include('default/components/breadcrumb.html.twig') }} @@ -21,7 +36,10 @@
-
+ + + {{ form_errors(form) }} +
@@ -46,30 +64,27 @@ {{ form_label(form.departure, 'Abflugort') }} - + {{ form_widget(form.departure) }} + {{ form_errors(form.departure) }} {{ form_label(form.travelerCount, 'Reiseteilnehmer') }} - + + Erwachsene
+ {{ form_widget(form.travelerCount) }} + {{ form_errors(form.travelerCount) }} Reiseversicherung
- - + +
{% for insuranceForm in form.insurance %} @@ -78,6 +93,8 @@ 'insurance': form.insurance.vars.choices[insuranceForm.vars.value].data } %} {% endfor %} + + {{ form_errors(form.insurance) }} @@ -100,7 +117,7 @@ {% for price in travel_date.prices %} {# @var price \AppBundle\Entity\TravelPeriodPrice #}
  • - p.P. {{ price.priceComfort|number_format(2) }} € + p.P. {{ price.effectiveComfortPrice|number_format(2) }} € {{ price_type_by_id[price.priceType.id].name }}
  • {% endfor %} @@ -128,23 +145,12 @@

    Ihr gewähltes Angebot

    - - - - - - - - - - - -
    -700,00 € - Abzug für Abfahrts-/Abflugort "Eigenanreise" (2 x -350,00 €): - -700,00 € -
    - = 3.921,68 € - Gesamtpreis der Reise
    +
    + {% include 'default/components/booking/summary.html.twig' with { + 'summary': summary, + 'total_price': total_price + } %} +
    @@ -197,59 +203,44 @@
    - + {{ form_field_pho(form.salutation, 'Anrede', {'label_attr': {class: 'sr-only'}}) }}
    - + {##} + {{ form_field_pho(form.firstName, 'Vorname') }}
    - + {{ form_field_pho(form.lastName, 'Nachname') }}
    - -
    - - -
    - + {{ form_field_pho(form.streetAddress, 'Straße, Hausnummer') }}
    - + {{ form_field_pho(form.zipCode, 'PLZ') }} +
    + +
    + {{ form_field_pho(form.city, 'Ort') }}
    - + {{ form_field_pho(form.nation, 'Land') }}
    - + {{ form_field_pho(form.phone, 'Telefon tagsüber') }}
    - + {{ form_field_pho(form.fax, 'Fax (optional)') }}
    - + {{ form_field_pho(form.email, 'E-Mail-Adresse') }}
    @@ -274,53 +265,36 @@ Geburtsdatum (TT.MM.JJJJ) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + {% for traveler_form in form.travelers %} + + + + + + {{ form_field_pho(traveler_form.sex, 'Geschlecht', { + required: false + }) }} + + + {{ form_field_pho(traveler_form.firstName, 'Vorname') }} + + + {{ form_field_pho(traveler_form.lastName, 'Nachname') }} + + + {{ form_field_pho(traveler_form.birthDate, 'Geburtsdatum') }} + + + {% endfor %} @@ -335,7 +309,10 @@
    Mitteilungen / Sonstiges (optional)
    - + {{ form_field(form.notes, 'Mitteilungen / Sonstiges (optional)', { + 'label_attr': {'class': 'sr-only'}, + 'attr': {'rows': '6'} + }) }}
    @@ -345,7 +322,9 @@
    Zahlung
    -

    Die gewünschte Zahlungsart (Rechnung, Überweisung, Sofortüberweisung, Kreditkarten, Barzahlung) stimmen wir mit Ihnen im Anschluss an Ihre Buchung ab.

    +

    Die gewünschte Zahlungsart (Rechnung, Überweisung, Sofortüberweisung, Kreditkarten, + Barzahlung) stimmen wir mit Ihnen im Anschluss an Ihre Buchung ab. +

    @@ -357,18 +336,28 @@
    Allgemeine Geschäftsbedingungen
    - -
    - +
    + + {{ form_rest(form) }} diff --git a/trunk/app/Resources/views/default/pages/bookingConfirmation.html.twig b/trunk/app/Resources/views/default/pages/bookingConfirmation.html.twig new file mode 100644 index 00000000..db6caca2 --- /dev/null +++ b/trunk/app/Resources/views/default/pages/bookingConfirmation.html.twig @@ -0,0 +1,5 @@ +{% extends 'base.html.twig' %} + +{% block body %} +

    Vielen Dank für Ihren Buchungsauftrag!

    +{% endblock %} \ No newline at end of file diff --git a/trunk/app/config/config.yml b/trunk/app/config/config.yml index 3bd7d58a..22400760 100644 --- a/trunk/app/config/config.yml +++ b/trunk/app/config/config.yml @@ -5,12 +5,12 @@ imports: # Put parameters here that don't need to change on each machine where the app is deployed # http://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration -parameters: - locale: en +#parameters: +# locale: en framework: #esi: ~ - #translator: { fallbacks: ["%locale%"] } + translator: { fallbacks: ["%locale%", "en"] } secret: "%secret%" router: resource: "%kernel.root_dir%/config/routing.yml" @@ -31,8 +31,8 @@ framework: fragments: ~ http_method_override: true assets: ~ - profiler: - collect: false + #profiler: + # collect: false # Twig Configuration twig: @@ -88,7 +88,7 @@ assetic: cssrewrite: ~ stof_doctrine_extensions: - default_locale: en_US + default_locale: de_DE orm: default: tree: true \ No newline at end of file diff --git a/trunk/app/config/config_dev.yml b/trunk/app/config/config_dev.yml index 3d115031..0709acc5 100644 --- a/trunk/app/config/config_dev.yml +++ b/trunk/app/config/config_dev.yml @@ -21,6 +21,9 @@ monolog: console: type: console channels: [!event, !doctrine] + browser_console: + type: browser_console + level: debug # uncomment to get logging in your browser # you may have to allow bigger header sizes in your Web server configuration #firephp: diff --git a/trunk/app/config/parameters.yml.dist b/trunk/app/config/parameters.yml.dist index 1c6d8ce7..71cc63d5 100644 --- a/trunk/app/config/parameters.yml.dist +++ b/trunk/app/config/parameters.yml.dist @@ -19,3 +19,4 @@ parameters: secret: ThisTokenIsNotSoSecretChangeIt st_cache_driver: array + locale: de_DE diff --git a/trunk/app/config/services.yml b/trunk/app/config/services.yml index 0058edd8..25117a51 100644 --- a/trunk/app/config/services.yml +++ b/trunk/app/config/services.yml @@ -14,4 +14,22 @@ services: - "@doctrine.orm.entity_manager" - "@controller_resolver" tags: - - { name: kernel.event_listener, event: kernel.controller, method: onKernelController } \ No newline at end of file + - { name: kernel.event_listener, event: kernel.controller, method: onKernelController } + + app.twig_extension: + class: AppBundle\Twig\AppExtension + #public: false + arguments: + - '@twig' + tags: + - { name: twig.extension } + + app.booking_exporter: + class: AppBundle\Export\SternToursCrmBookingExporter + arguments: + - '@monolog.logger' + + app.booking_request_validator: + class: AppBundle\Validator\BookingRequestValidator + tags: + - {name: validator.constraint_validator } \ No newline at end of file diff --git a/trunk/src/AppBundle/Controller/BookingController.php b/trunk/src/AppBundle/Controller/BookingController.php index b53b77f6..1595ee2d 100644 --- a/trunk/src/AppBundle/Controller/BookingController.php +++ b/trunk/src/AppBundle/Controller/BookingController.php @@ -10,14 +10,32 @@ 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 Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; class BookingController extends Controller { - public function indexAction(Page $travelProgramPage, Request $request) + /** @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 + */ + public function indexAction(Page $travelProgramPage, $action, Request $request) { $travelProgram = $travelProgramPage->getTravelProgram(); if (!$request->query->has('nr')) @@ -26,6 +44,8 @@ class BookingController extends Controller } $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) { @@ -40,31 +60,355 @@ class BookingController extends Controller throw $this->createNotFoundException(); } - $form = $this->createForm(BookingRequestType::class, null, [ + /** @var BookingRequest $bookingRequest */ + $bookingRequest = new BookingRequest(); + if ($request->getMethod() != 'POST') + { + $bookingRequest->setTravelerCount(2); + $bookingRequest->setDeparture($travelDate->getDepartures()[0]); + } + $form = $this->createForm(BookingRequestType::class, $bookingRequest, [ 'travel_date' => $travelDate, 'travel_program' => $travelProgram ]); - //$form->submit([]); + if ($request->getMethod() == 'POST') + { + $form->handleRequest($request); + $bookingRequest = $form->getData(); + } + $htmlSummary = []; + $bookingPriceInfo = []; + $totalPrice = $this->calculatePrice($travelDate, $bookingRequest, $htmlSummary, $bookingPriceInfo); - $priceTypeById = $this->getDoctrine()->getRepository('AppBundle:TravelPeriodPriceType')->findAllIndexedById(); + if ($action == 'buchen') + { + $breadcrumbEntries = Util::createBreadcrumb($travelProgramPage); + $breadcrumbEntries[] = new BreadcrumbEntry('Buchen', $travelProgramPage->getUrlPath() .'/buchen'); - $breadcrumbEntries = Util::createBreadcrumb($travelProgramPage); - $breadcrumbEntries[] = new BreadcrumbEntry('Buchen', $travelProgramPage->getUrlPath() .'/buchen'); + if ($request->getMethod() == 'POST' && $form->isValid()) + { + $booking = $this->getDoctrine()->getRepository('AppBundle:TravelBooking')->createFromBookingRequest( + $bookingRequest, $travelDate, $bookingPriceInfo); + $em = $this->getDoctrine()->getManager(); + $em->persist($booking); + $em->flush(); - return $this->render('default/pages/booking.html.twig', [ - 'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR, - 'page' => $travelProgramPage, - 'travel_program' => $travelProgram, - 'travel_date' => $travelDate, - 'form' => $form->createView(), - 'price_type_by_id' => $priceTypeById, - 'breadcrumb_entries' => $breadcrumbEntries, - ]); + $crmBookingUrl = $this->get('app.booking_exporter')->process($bookingRequest, $travelDate, $bookingPriceInfo); + + $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, + ]), + '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('sternt@stern-tours.de') + ->setBody( + $this->renderView('default/email/bookingServiceEmail.txt.twig', [ + 'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR, + 'crm_url' => $crmBookingUrl .'/edit', + 'travel_program_url' => 'http' . (($_SERVER['SERVER_PORT'] == 443) ? 's://' : '://') . + $_SERVER['HTTP_HOST'] . $travelProgramPage->getUrlPath(), + 'booking_request' => $bookingRequest, + 'booking_price_info' => $bookingPriceInfo, + 'travel_date' => $travelDate, + 'breadcrumb_entries' => $breadcrumbEntries, + ]), + '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, + 'page' => $travelProgramPage, + 'breadcrumb_entries' => $breadcrumbEntries, + ]); + } + + return $this->render('default/pages/booking.html.twig', [ + 'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR, + 'page' => $travelProgramPage, + 'travel_program' => $travelProgram, + 'travel_date' => $travelDate, + 'form' => $form->createView(), + 'price_type_by_id' => $this->priceTypeById, + 'breadcrumb_entries' => $breadcrumbEntries, + 'summary' => $htmlSummary, + 'total_price' => $totalPrice + ]); + } + 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 + ]); + } + throw new \Exception('Unknow BookingController action: '. $action); } - public function calculatePrice() + public function calculatePrice(TravelDate $travelDate, BookingRequest $bookingRequest, &$outHtmlSummary = null, + &$outPriceInfo = null) { + $ret = 0; + $insuranceAssessmentBasis = 0; + $travelerCount = $bookingRequest->getTravelerCount(); + if (isset($outHtmlSummary)) + { + $insuranceHtmlSummary = []; + } + if (isset($outPriceInfo)) + { + $outPriceInfo['rooms'] = []; + $outPriceInfo['insurances'] = []; + $outPriceInfo['options'] = []; + $outPriceInfo['classOptions'] = []; + } + $departure = Util\DepartureUtil::limitIndividualArrivalPrice($bookingRequest->getDeparture(), + $travelDate->getFlightPrice()); + if (isset($outPriceInfo)) + { + $outPriceInfo['departure'] = $departure; + } + + if ($departure->getExtraCharge() != 0) + { + $insuranceAssessmentBasis += $departure->getExtraCharge(); + $a = $travelerCount * $departure->getExtraCharge(); + $ret += $a; + if (isset($outHtmlSummary)) + { + $outHtmlSummary[] = [ + 'value' => $a, + 'label' => $travelerCount .'x '. ($departure->getExtraCharge() > 0 ? 'Aufschlag' : 'Abzug') . + ' für Abfahrts-/Abflugort "'. $departure->getName() .'" '. + Util::formatPrice($departure->getExtraCharge()) .'' + ]; + } + } + + foreach ($bookingRequest->getTravelOptions() as $travelOption) + { + $insuranceAssessmentBasis += $travelOption->getPrice(); + $a = $travelerCount * $travelOption->getPrice(); + $ret += $a; + if (isset($outHtmlSummary)) + { + $outHtmlSummary[] = [ + 'value' => $a, + 'label' => $travelerCount .'x zugebuchte Leistung: '. $travelOption->getName() .' '. + Util::formatPrice($travelOption->getPrice()) .'' + ]; + } + if (isset($outPriceInfo)) + { + $outPriceInfo['options'][] = $travelOption; + } + } + + $persons = [ + 'total' => $travelerCount, + 'adults' => $travelerCount, + 'children' => 0 + ]; + $possibleRooms = $this->searchRooms($travelDate->getPrices(), $persons); + + if (empty($possibleRooms)) + { + if ($travelerCount % 2 == 0) + { + $possibleRooms = $this->splitIntoTwoGroups($travelDate->getPrices(), $persons, 'equal'); + } + elseif ($travelerCount >= 3) + { + $possibleRooms = $this->splitIntoTwoGroups($travelDate->getPrices(), $persons, 'move_without_children'); + } + } + + if ($bookingRequest->getComfort()) + { + foreach ($possibleRooms as $room) + { + $insuranceAssessmentBasis += $room['price']->getEffectiveComfortPrice(); + $a = $room['persons']['total'] * $room['price']->getEffectiveComfortPrice(); + $ret += $a; + if (isset($outHtmlSummary)) + { + $outHtmlSummary[] = [ + 'value' => $a, + 'label' => $room['persons']['total'] .'x zugebuchte Leistung: Komfort-Kategorie '. + Util::formatPrice($room['price']->getEffectiveComfortPrice()) .'' + ]; + } + if (isset($outPriceInfo)) + { + $outPriceInfo['classOptions'][] = [ + 'count' => $room['persons']['total'], + 'name' => 'zugebuchte Leistung: Komfort (4 Sterne)', + 'price' => $room['price']->getEffectiveComfortPrice() + ]; + } + } + } + + $insuranceTotal = 0; + + foreach ($possibleRooms as $room) + { + $adultCount = $room['persons']['adults']; + $singleFullPrice = $room['price']->getEffectivePrice(); + $roomPrice = $singleFullPrice * $adultCount + $singleFullPrice * $room['persons']['children']; + $singleDiscountPrice = $room['price']->getEffectiveDiscountPrice(); + $discount = ($singleDiscountPrice === null) ? 0 + : ($adultCount * ($singleDiscountPrice - $singleFullPrice)); + $ret += $roomPrice + $discount; + + if (isset($outPriceInfo)) + { + $outPriceInfo['rooms'][] = [ + 'name' => $room['priceType']->getName(), + 'adults' => $room['persons']['adults'], + 'children' => $room['persons']['children'], + 'price' => $singleDiscountPrice ?? $singleFullPrice, + 'price_children' => $room['price']->getEffectiveChildPrice(), + 'price_total' => $roomPrice + $discount, + ]; + } + + if (isset($outHtmlSummary)) + { + $label = '1x '. $room['priceType']->getName() .' [Personen: '. $adultCount .' x '. + Util::formatPrice($singleFullPrice) .''; + if ($room['persons']['children'] != 0) + { + $label .= ', Kinder: '. $room['persons']['children'] .' x '. + Util::formatPrice($room['price']->getEffectiveChildPrice()) .''; + } + $label .= ']'; + $outHtmlSummary[] = [ + 'value' => $roomPrice, + 'label' => $label + ]; + if ($singleDiscountPrice !== null) + { + $outHtmlSummary[] = [ + 'value' => $discount, + 'label' => $adultCount .'x '. + Util::formatPrice($singleFullPrice - $singleDiscountPrice) .' Rabatt' + ]; + } + if ($bookingRequest->getInsurance() && $adultCount > 0) + { + $curAssessmentBasis = $insuranceAssessmentBasis + ($singleDiscountPrice ?? $singleFullPrice); + $insurancePrice = $this->getDoctrine()->getRepository('AppBundle:TravelInsurancePrice') + ->findOneByInsuranceIdAndAssessmentBasis($bookingRequest->getInsurance()->getId(), + $curAssessmentBasis); + $insurancePriceValue = $insurancePrice->getPrice() > 0 ? $insurancePrice->getPrice() + : round($insurancePrice->getPercent() * $curAssessmentBasis / 100, 2); + $a = $adultCount * $insurancePriceValue; + $insuranceTotal += $a; + $ret += $a; + if (isset($insuranceHtmlSummary)) + { + $insuranceHtmlSummary[] = [ + 'value' => $a, + 'label' => $adultCount .'x RV '. $bookingRequest->getInsurance()->getName() .' ('. + $insurancePrice->getCode() .') '. Util::formatPrice($insurancePriceValue) . + '' + ]; + } + if (isset($outPriceInfo)) + { + $outPriceInfo['insurances'][] = [ + 'insurance' => $bookingRequest->getInsurance(), + 'insurancePriceValue' => $insurancePriceValue, + 'insurancePrice' => $insurancePrice, + 'count' => $adultCount, + ]; + } + } + } + } + + if (isset($insuranceHtmlSummary)) + { + $outHtmlSummary = array_merge($outHtmlSummary, $insuranceHtmlSummary); + } + if (isset($outPriceInfo)) + { + $outPriceInfo['total'] = $ret; + $outPriceInfo['totalWithoutInsurance'] = $ret - $insuranceTotal; + } + + return $ret; + } + + /** + * @param TravelPeriodPrice[] $prices + * @param $persons + * + * @return array + */ + private function searchRooms($prices, $persons) + { + $ret = []; + foreach ($prices as $price) + { + $priceType = $this->priceTypeById[$price->getPriceTypeId()]; + if ($priceType->getMax() == $persons['total'] && + $priceType->getMaxAdults() >= $persons['adults'] && + $priceType->getMinAdults() <= $persons['adults'] && + $priceType->getMaxChildren() >= $persons['children']) + { + $ret[] = [ + 'priceType' => $priceType, + 'persons' => $persons, + 'price' => $price + ]; + } + } + return $ret; + } + + private function splitIntoTwoGroups($prices, $persons, $mode) + { + $group1 = []; + $group2 = []; + if($mode == 'equal') + { + $group1['adults'] = $group2['adults'] = $persons['adults'] / 2; + $group1['children'] = $group2['children'] = $persons['children'] / 2; + $group1['total'] = $group2['total'] = $group1['adults'] + $group2['children']; + } + elseif($mode = 'move_without_children') + { + $group1['adults'] = $persons['adults'] - 1; + $group1['children'] = 0; + $group1['total'] = $group1['adults'] + $group1['children']; + + $group2['adults'] = 1; + $group2['children'] = 0; + $group2['total'] = $group2['adults'] + $group2['children']; + } + $possibleRoomsGroup1 = $this->searchRooms($prices, $group1); + $possibleRoomsGroup2 = $this->searchRooms($prices, $group2); + + return array_merge($possibleRoomsGroup1, $possibleRoomsGroup2); } diff --git a/trunk/src/AppBundle/Entity/BookingRequest.php b/trunk/src/AppBundle/Entity/BookingRequest.php index a3603a33..bee26b49 100644 --- a/trunk/src/AppBundle/Entity/BookingRequest.php +++ b/trunk/src/AppBundle/Entity/BookingRequest.php @@ -7,10 +7,20 @@ 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; + /** * @var TravelDeparturePoint $departure */ @@ -23,14 +33,78 @@ class BookingRequest */ private $insurance; - private $comfort; + private $comfort = false; - private $travelOptions; + private $travelOptions = []; + + private $salutation; + + /** + * @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 $fax; + + /** + * @Assert\NotBlank() + */ + private $email; + + /* + * @ Assert\Valid() + */ + private $travelers = []; + + private $notes; + + /** + * @Assert\IsTrue() + */ + private $acceptTerms = false; + + /** + * BookingRequest constructor. + */ + public function __construct() + { + for ($i = 0; $i < 4; ++$i) + { + $this->travelers[] = new Traveler(); + } + } /** * @return TravelDeparturePoint */ - public function getDeparture(): TravelDeparturePoint + public function getDeparture() { return $this->departure; } @@ -62,7 +136,7 @@ class BookingRequest /** * @return TravelInsurance */ - public function getInsurance(): TravelInsurance + public function getInsurance() { return $this->insurance; } @@ -92,7 +166,7 @@ class BookingRequest } /** - * @return mixed + * @return TravelOption[] */ public function getTravelOptions() { @@ -107,6 +181,221 @@ class BookingRequest $this->travelOptions = $travelOptions; } + /** + * @return int + */ + public function getSalutation() + { + return $this->salutation; + } + + /** + * @param int $salutation + */ + public function setSalutation($salutation) + { + $this->salutation = $salutation; + } + + /** + * @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 string + */ + public function getPhone() + { + return $this->phone; + } + + /** + * @param string $phone + */ + public function setPhone($phone) + { + $this->phone = $phone; + } + + /** + * @return string + */ + public function getFax() + { + return $this->fax; + } + + /** + * @param string $fax + */ + public function setFax($fax) + { + $this->fax = $fax; + } + + /** + * @return string + */ + public function getEmail() + { + return $this->email; + } + + /** + * @param string $email + */ + public function setEmail($email) + { + $this->email = $email; + } + + /** + * @return Traveler[] + */ + public function getTravelers() + { + return $this->travelers; + } + + /** + * @param Traveler[] $travelers + */ + public function setTravelers($travelers) + { + $this->travelers = $travelers; + } + + /* + 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; + } + /** * @Assert\Callback */ diff --git a/trunk/src/AppBundle/Entity/FlightPeriodRepository.php b/trunk/src/AppBundle/Entity/FlightPeriodRepository.php index 64367a2f..fa81dba0 100644 --- a/trunk/src/AppBundle/Entity/FlightPeriodRepository.php +++ b/trunk/src/AppBundle/Entity/FlightPeriodRepository.php @@ -10,4 +10,50 @@ namespace AppBundle\Entity; */ class FlightPeriodRepository extends \Doctrine\ORM\EntityRepository { + public function getIndexedFlightPeriodsForTimePeriod($startDate, $endDate, $arrivalPointIds = null) + { + $qb = $this->getEntityManager()->createQueryBuilder(); + $qb + ->from('AppBundle:FlightPeriod', 'fp') + ->addSelect('fp') + ->leftJoin('fp.departures', 'fp_dep') + ->addSelect('fp_dep') + ; + + if ($startDate !== null) + { + $qb->where('fp.startDate >= :startDate'); + $qb->setParameter('startDate', $startDate); + } + if ($endDate !== null) + { + $qb->andWhere('fp.endDate <= :endDate'); + $qb->setParameter('endDate', $endDate); + } + if (!empty($arrivalPointIds)) + { + if (is_array($arrivalPointIds)) + { + $qb->andWhere($qb->expr()->in('IDENTITY(fp.travelArrivalPoint)', $arrivalPointIds)); + } + else + { + $qb->andWhere($qb->expr()->eq('IDENTITY(fp.travelArrivalPoint)', $arrivalPointIds)); + } + } + + $unindexedFlightPeriods = $qb->getQuery()->getResult(); + $ret = []; + + // Index by CONCAT(start date, end date, arrival point id): + /** @var FlightPeriod $flightPeriod */ + foreach ($unindexedFlightPeriods as $flightPeriod) + { + $ret[$flightPeriod->getStartDate()->format('Y-m-d') . + $flightPeriod->getEndDate()->format('Y-m-d') . + $flightPeriod->getTravelArrivalPoint()->getId()] = $flightPeriod; + } + + return $ret; + } } diff --git a/trunk/src/AppBundle/Entity/TravelBooking.php b/trunk/src/AppBundle/Entity/TravelBooking.php index 1a9fa4be..50b989d4 100644 --- a/trunk/src/AppBundle/Entity/TravelBooking.php +++ b/trunk/src/AppBundle/Entity/TravelBooking.php @@ -8,7 +8,7 @@ use Doctrine\ORM\Mapping as ORM; * TravelBooking * * @ORM\Table(name="travel_booking", indexes={@ORM\Index(name="FK_travel_booking_travel_period", columns={"period_id"}), @ORM\Index(name="FK_travel_booking_travel_program", columns={"program_id"})}) - * @ORM\Entity + * @ORM\Entity(repositoryClass="AppBundle\Entity\TravelBookingRepository") */ class TravelBooking { @@ -678,7 +678,7 @@ class TravelBooking */ public function setSelectedDeparture($selectedDeparture) { - $this->selectedDeparture = $selectedDeparture; + $this->selectedDeparture = is_array($selectedDeparture) ? json_encode($selectedDeparture) : $selectedDeparture; return $this; } @@ -690,7 +690,12 @@ class TravelBooking */ public function getSelectedDeparture() { - return $this->selectedDeparture; + $ret = json_decode($this->selectedDeparture, true); + if (empty($ret) || !is_array($ret)) + { + return $this->selectedDeparture; + } + return $ret; } /** @@ -846,7 +851,7 @@ class TravelBooking */ public function setRooms($rooms) { - $this->rooms = $rooms; + $this->options = is_array($rooms) ? json_encode($rooms) : $rooms; return $this; } @@ -858,19 +863,43 @@ class TravelBooking */ public function getRooms() { - return $this->rooms; + $ret = json_decode($this->rooms, true); + if (empty($ret) || !is_array($ret)) + { + return $this->rooms; + } + return $ret; } /** * Set participants * - * @param string $participants + * @param Traveler[] $travelers * * @return TravelBooking */ - public function setParticipants($participants) + public function setParticipants($travelers) { - $this->participants = $participants; + if (!is_array($travelers)) + { + $this->participants = $travelers; + return $this; + } + + $participants = []; + + for ($i = 0; $i < count($travelers); ++$i) + { + $traveler = $travelers[$i]; + $participants[''. ($i+1)] = [ + 'gender' => $traveler->getSex(), + 'first_name' => $traveler->getFirstName(), + 'last_name' => $traveler->getLastName(), + 'birthday' => $traveler->getBirthDate()->format('d.m.Y') + ]; + } + + $this->participants = json_encode($participants); return $this; } @@ -882,7 +911,22 @@ class TravelBooking */ public function getParticipants() { - return $this->participants; + $participants = json_decode($this->participants, true); + if (empty($participants) || !is_array($participants)) + { + return $this->participants; + } + $ret = []; + foreach ($participants as $participant) + { + $traveler = new Traveler(); + $traveler->setSex(intval($participant['gender'])); + $traveler->setFirstName($participant['first_name']); + $traveler->setLastName($participant['last_name']); + $traveler->setBirthDate(\DateTime::createFromFormat('d.m.Y', $participant['birthday'])); + $ret[] = $traveler; + } + return $ret; } /** @@ -990,7 +1034,7 @@ class TravelBooking */ public function setInsurances($insurances) { - $this->insurances = $insurances; + $this->insurances = is_array($insurances) ? json_encode($insurances) : $insurances; return $this; } @@ -1002,7 +1046,12 @@ class TravelBooking */ public function getInsurances() { - return $this->insurances; + $ret = json_decode($this->insurances, true); + if (empty($ret) || !is_array($ret)) + { + return $this->insurances; + } + return $ret; } /** @@ -1014,7 +1063,7 @@ class TravelBooking */ public function setOptions($options) { - $this->options = $options; + $this->options = is_array($options) ? json_encode($options) : $options; return $this; } @@ -1026,7 +1075,12 @@ class TravelBooking */ public function getOptions() { - return $this->options; + $ret = json_decode($this->options, true); + if (empty($ret) || !is_array($ret)) + { + return $this->options; + } + return $ret; } /** @@ -1038,7 +1092,7 @@ class TravelBooking */ public function setClassOptions($classOptions) { - $this->classOptions = $classOptions; + $this->classOptions = is_array($classOptions) ? json_encode($classOptions) : $classOptions; return $this; } @@ -1050,7 +1104,12 @@ class TravelBooking */ public function getClassOptions() { - return $this->classOptions; + $ret = json_decode($this->classOptions, true); + if (empty($ret) || !is_array($ret)) + { + return $this->classOptions; + } + return $ret; } /** @@ -1062,7 +1121,7 @@ class TravelBooking */ public function setExtraCategory($extraCategory) { - $this->extraCategory = $extraCategory; + $this->extraCategory = is_array($extraCategory) ? json_encode($extraCategory) : $extraCategory; return $this; } @@ -1074,7 +1133,12 @@ class TravelBooking */ public function getExtraCategory() { - return $this->extraCategory; + $ret = json_decode($this->extraCategory, true); + if (empty($ret) || !is_array($ret)) + { + return $this->extraCategory; + } + return $ret; } /** diff --git a/trunk/src/AppBundle/Entity/TravelBookingRepository.php b/trunk/src/AppBundle/Entity/TravelBookingRepository.php new file mode 100644 index 00000000..2aade6d8 --- /dev/null +++ b/trunk/src/AppBundle/Entity/TravelBookingRepository.php @@ -0,0 +1,88 @@ +getTravelProgram(); + $ret = new TravelBooking(); + $ret->setIp($_SERVER['REMOTE_ADDR']); + $ret->setCreated(new \DateTime()); + $ret->setProgramName($tp->getTitle() . ' ('. $travelDate->getName() .')'); + //$ret->setClass() + $ret->setSalutation($bookingRequest->getSalutation()); + $ret->setFirstName($bookingRequest->getFirstName()); + $ret->setLastName($bookingRequest->getLastName()); + $ret->setStreet($bookingRequest->getStreetAddress()); + //$ret->setHouseNr() + $ret->setZipcode($bookingRequest->getZipCode()); + $ret->setCity($bookingRequest->getCity()); + $ret->setCountry($bookingRequest->getNation()); + $ret->setMail($bookingRequest->getEmail()); + $ret->setPhone($bookingRequest->getPhone()); + $ret->setFax($bookingRequest->getFax()); + $ret->setSelectedDeparture([ + 'name' => $bookingRequest->getDeparture()->getName(), + 'extra_charge' => $bookingRequest->getDeparture()->getExtraCharge(), + 'extra_charge_total' => $bookingRequest->getTravelerCount() + ]); + $ret->setSelectedStartDate($travelDate->getStart()); + $ret->setSelectedEndDate($travelDate->getEnd()); + $ret->setSelectedAdults($bookingRequest->getTravelerCount()); + $ret->setSelectedChild1(0); + $ret->setSelectedChild2(0); + $ret->setSelectedChild3(0); + $insurance = $bookingRequest->getInsurance(); + $ret->setInsuranceName($insurance ? $insurance->getName() : '0'); // #TODO Adapted from v2 + if (empty($bookingPriceInfo['insurances'])) + { + $ret->setInsurances(false); + } + else + { + $insurances = []; + foreach ($bookingPriceInfo['insurances'] as $insuranceInfo) + { + $insurances[] = [ + 'count' => $insuranceInfo['count'], + 'price' => $insuranceInfo['insurancePriceValue'], + 'code' => $insuranceInfo['insurancePrice']->getCode() + ]; + } + $ret->setInsurances($insurances); + } + $ret->setParticipants(array_slice($bookingRequest->getTravelers(), 0, $bookingRequest->getTravelerCount())); + $ret->setParticipantsTotal($bookingRequest->getTravelerCount()); + $ret->setRooms($bookingPriceInfo['rooms']); + $ret->setPriceTotal($bookingPriceInfo['total']); + $ret->setComments($bookingRequest->getNotes()); + if (empty($bookingPriceInfo['options'])) + { + $ret->setOptions(false); + } + else + { + $options = []; + foreach ($bookingPriceInfo['options'] as $option) + { + $options[] = [ + 'name' => $option->getName(), + 'price' => $option->getPrice() + ]; + } + $ret->setOptions($options); + } + $ret->setClassOptions(false); + $ret->setExtraCategory(empty($bookingPriceInfo['classOptions']) ? false : $bookingPriceInfo['classOptions']); + + return $ret; + } +} diff --git a/trunk/src/AppBundle/Entity/TravelDate.php b/trunk/src/AppBundle/Entity/TravelDate.php index a4818de1..f460253c 100644 --- a/trunk/src/AppBundle/Entity/TravelDate.php +++ b/trunk/src/AppBundle/Entity/TravelDate.php @@ -89,12 +89,12 @@ final class TravelDate } $this->start = $start; $this->index = $index; - $this->flightPeriod = $flightPeriod; } else { $this->start = $travelPeriod->getStartDate(); } + $this->flightPeriod = $flightPeriod; $this->travelProgram = $travelPeriod->getProgram(); $this->key = $key; $this->travelPeriod = $travelPeriod; @@ -187,6 +187,24 @@ final class TravelDate return $this->departures; } + public function getFlightPrice() + { + if ($this->travelProgram->getIsMediated()) + { + return 0; + } + $flightPrice = null; + if ($this->flightPeriod !== null) + { + $flightPrice = $this->flightPeriod->getPrice(); + } + if ($flightPrice === null) + { + $flightPrice = $this->travelProgram->getDefaultFlightPrice(); + } + return $flightPrice; + } + /** * @return TravelPeriodPrice[]|\Doctrine\Common\Collections\Collection */ @@ -195,31 +213,21 @@ final class TravelDate if (!$this->calculatedEffectivePrices) { $this->calculatedEffectivePrices = true; + $flightPrice = $this->getFlightPrice(); if ($this->travelProgram->getIsMediated()) { $profitMargin = 1; - $flightPrice = 0; } else { $profitMargin = $this->travelProgram->getProfitMargin() / 100 + 1; - $flightPrice = null; - if ($this->flightPeriod !== null) - { - $flightPrice = $this->flightPeriod->getPrice(); - } - if ($flightPrice === null) - { - $flightPrice = $this->travelProgram->getDefaultFlightPrice(); - } } $currencyFactor = $this->travelProgram->getNettoPricesInEuro() ? 1 : $this->currencyFactor; foreach ($this->travelPeriod->getPrices() as $price) { $price->setEffectivePrice(round(($flightPrice + $price->getPrice() * $currencyFactor) * $profitMargin)); - $price->setEffectiveDiscountPrice( - round(($flightPrice + $price->getDiscountPrice() * $currencyFactor) * $profitMargin)); - //$price->setEffectiveDiscountPrice($pr) + $price->setEffectiveComfortPrice(round($price->getPriceComfort() * $currencyFactor * $profitMargin)); + $price->setEffectiveChildPrice(round($price->getPriceChildren() * $currencyFactor * $profitMargin)); } } return $this->travelPeriod->getPrices(); @@ -255,6 +263,14 @@ final class TravelDate return false; } + /** + * @return TravelProgram + */ + public function getTravelProgram(): TravelProgram + { + return $this->travelProgram; + } + /** * @return TravelPeriod * @internal diff --git a/trunk/src/AppBundle/Entity/TravelDeparturePoint.php b/trunk/src/AppBundle/Entity/TravelDeparturePoint.php index a89171cc..66d07818 100644 --- a/trunk/src/AppBundle/Entity/TravelDeparturePoint.php +++ b/trunk/src/AppBundle/Entity/TravelDeparturePoint.php @@ -139,11 +139,11 @@ class TravelDeparturePoint /** * Get extraCharge * - * @return string + * @return float */ public function getExtraCharge() { - return $this->extraCharge; + return ($this->extraCharge === null || $this->extraCharge === '') ? null : floatval($this->extraCharge); } /** diff --git a/trunk/src/AppBundle/Entity/TravelInsurancePrice.php b/trunk/src/AppBundle/Entity/TravelInsurancePrice.php index d0a593bb..757a77b5 100644 --- a/trunk/src/AppBundle/Entity/TravelInsurancePrice.php +++ b/trunk/src/AppBundle/Entity/TravelInsurancePrice.php @@ -8,7 +8,7 @@ use Doctrine\ORM\Mapping as ORM; * TravelInsurancePrice * * @ORM\Table(name="travel_insurance_price", indexes={@ORM\Index(name="FK_travel_insurance_price_travel_insurance", columns={"insurance_id"})}) - * @ORM\Entity + * @ORM\Entity(repositoryClass="AppBundle\Entity\TravelInsurancePriceRepository") */ class TravelInsurancePrice { diff --git a/trunk/src/AppBundle/Entity/TravelInsurancePriceRepository.php b/trunk/src/AppBundle/Entity/TravelInsurancePriceRepository.php new file mode 100644 index 00000000..da4b11a6 --- /dev/null +++ b/trunk/src/AppBundle/Entity/TravelInsurancePriceRepository.php @@ -0,0 +1,32 @@ +createQueryBuilder('i'); + return $qb + ->where($qb->expr()->eq('IDENTITY(i.insurance)', $insuranceId)) + //->where('IDENTITY(i.insurance) = '. $insuranceId) + ->andWhere($qb->expr()->gte('i.border', $assessmentBasis)) + ->orderBy('i.border') + ->setMaxResults(1) + ->getQuery() + ->getOneOrNullResult(); + } +} diff --git a/trunk/src/AppBundle/Entity/TravelPeriodPrice.php b/trunk/src/AppBundle/Entity/TravelPeriodPrice.php index 45ef9377..6b50e72d 100644 --- a/trunk/src/AppBundle/Entity/TravelPeriodPrice.php +++ b/trunk/src/AppBundle/Entity/TravelPeriodPrice.php @@ -67,7 +67,8 @@ class TravelPeriodPrice private $priceTypeId; private $effectivePrice = null; - private $effectiveDiscountPrice = null; + private $effectiveChildPrice = null; + private $effectiveComfortPrice = null; /** * Set priceType @@ -199,29 +200,28 @@ class TravelPeriodPrice return $this->period; } - public function getDiscountPrice() + /** + * Set priceTypeId + * + * @param integer $priceTypeId + * + * @return TravelPeriodPrice + */ + public function setPriceTypeId($priceTypeId) { - if ($this->getPeriod() == null) - { - return null; - } - // #TODO FIX! Discount calculation differs for period and program - $price = $this->price; // #TODO Is the discount calculated for the effective price or for the original price? - $newPrice = $price; - foreach ($this->getPeriod()->getDiscounts() as $discount) - { - $newPrice -= $discount->getPercent() - ? round($newPrice * $discount->getValue() / 100, 2) // FIXME - : $discount->getValue(); - } - $program = $this->getPeriod()->getProgram(); - if ($program != null && $program->getDiscount() != null) - { - $newPrice -= $program->getDiscountIsPercentValue() - ? round($price * $program->getDiscount() / 100, 2) // FIXME - : $program->getDiscount(); - } - return $price == $newPrice ? null : $newPrice; + $this->priceTypeId = $priceTypeId; + + return $this; + } + + /** + * Get priceTypeId + * + * @return integer + */ + public function getPriceTypeId() + { + return $this->priceTypeId; } /** @@ -245,48 +245,92 @@ class TravelPeriodPrice $this->effectivePrice = $effectivePrice; } + /** + * Probably getEffectiveDiscountPrice() is the method you are actually looking for. + * @return float|null + */ + public function getDiscountPrice() + { + return $this->calculateDiscountPrice($this->price); + } + /** * @return float * @throws \Exception */ public function getEffectiveDiscountPrice() { - if ($this->effectiveDiscountPrice === null) + if ($this->effectivePrice === null) { - throw new \Exception('Effective discount price must be set from outside before reading it.'); + throw new \Exception('Effective price must be set from outside before reading effective discount price.'); } - return $this->effectiveDiscountPrice; + return $this->calculateDiscountPrice($this->effectivePrice); } /** - * @param float $effectiveDiscountPrice + * @return float + * @throws \Exception + * + * @todo The child price will not be set yet. This is just a preparation for later */ - public function setEffectiveDiscountPrice($effectiveDiscountPrice) + public function getEffectiveChildPrice() { - $this->effectiveDiscountPrice = $effectiveDiscountPrice; + if ($this->effectiveChildPrice === null) + { + throw new \Exception('Effective child price must be set from outside before reading it.'); + } + return $this->effectiveChildPrice; } /** - * Set priceTypeId - * - * @param integer $priceTypeId - * - * @return TravelPeriodPrice + * @param null $effectiveChildPrice */ - public function setPriceTypeId($priceTypeId) + public function setEffectiveChildPrice($effectiveChildPrice) { - $this->priceTypeId = $priceTypeId; - - return $this; + $this->effectiveChildPrice = $effectiveChildPrice; } /** - * Get priceTypeId - * - * @return integer + * @return float|null + * @throws \Exception */ - public function getPriceTypeId() + public function getEffectiveComfortPrice() { - return $this->priceTypeId; + if ($this->effectiveComfortPrice === null) + { + throw new \Exception('Effective comfort price must be set from outside before reading it.'); + } + return $this->effectiveComfortPrice; + } + + /** + * @param float|null $effectiveComfortPrice + */ + public function setEffectiveComfortPrice($effectiveComfortPrice) + { + $this->effectiveComfortPrice = $effectiveComfortPrice; + } + + private function calculateDiscountPrice($price) + { + if ($this->getPeriod() == null) + { + return null; + } + $newPrice = $price; + foreach ($this->getPeriod()->getDiscounts() as $discount) + { + $newPrice -= $discount->getPercent() + ? round($newPrice * $discount->getValue() / 100, 2) // #TODO FIXME + : $discount->getValue(); + } + $program = $this->getPeriod()->getProgram(); + if ($program != null && $program->getDiscount() != null) + { + $newPrice -= $program->getDiscountIsPercentValue() + ? round($price * $program->getDiscount() / 100, 2) // #TODO FIXME + : $program->getDiscount(); + } + return $price == $newPrice ? null : $newPrice; } } diff --git a/trunk/src/AppBundle/Entity/TravelPeriodRepository.php b/trunk/src/AppBundle/Entity/TravelPeriodRepository.php index b3179efc..e4e6176a 100644 --- a/trunk/src/AppBundle/Entity/TravelPeriodRepository.php +++ b/trunk/src/AppBundle/Entity/TravelPeriodRepository.php @@ -129,32 +129,9 @@ class TravelPeriodRepository extends \Doctrine\ORM\EntityRepository $usedArrivalPointIds = array_keys($isUsedArrivalPointById); // Find flight periods and related departures - $flightPeriods = []; - if (!empty($isUsedArrivalPointById)) - { - $qb = $this->getEntityManager()->createQueryBuilder(); - $unindexedFlightPeriods = $qb - ->from('AppBundle:FlightPeriod', 'fp') - ->addSelect('fp') - ->leftJoin('fp.departures', 'fp_dep') - ->addSelect('fp_dep') - ->where('fp.startDate >= :startDate') - ->andWhere('fp.endDate <= :endDate') - ->andWhere($qb->expr()->in('IDENTITY(fp.travelArrivalPoint)', $usedArrivalPointIds)) - ->setParameter('startDate', $startDate) - ->setParameter('endDate', $endDate) - ->getQuery()->getResult(); - - // Index by CONCAT(start date, end date, arrival point id): - /** @var FlightPeriod $flightPeriod */ - foreach ($unindexedFlightPeriods as $flightPeriod) - { - $flightPeriods[$flightPeriod->getStartDate()->format('Y-m-d') . - $flightPeriod->getEndDate()->format('Y-m-d') . - $flightPeriod->getTravelArrivalPoint()->getId()] = $flightPeriod; - } - - } + $flightPeriods = empty($isUsedArrivalPointById) ? [] + : $this->getEntityManager()->getRepository('AppBundle:FlightPeriod') + ->getIndexedFlightPeriodsForTimePeriod($startDate, $endDate, $usedArrivalPointIds); // Find default departures and classify by-program or by-arrival-point // We could've simply left joined them to get an equal result. But we're reducing the number of rows returned @@ -253,8 +230,9 @@ class TravelPeriodRepository extends \Doctrine\ORM\EntityRepository // Only mediated travel programs define departures in travelPeriods $qb->leftJoin('p.departures', 'p_dep')->addSelect('p_dep'); } - else + elseif (!($flags & self::TD_QUERY_VIRTUAL)) { + // Retrieving all flight periods by join is only possible, if virtual entries are excluded $qb->leftJoin('AppBundle:FlightPeriod', 'fp', Expr\Join::WITH, 'IDENTITY(fp.travelArrivalPoint) = '. ':travelArrivalPointId AND d.startDate = fp.startDate AND d.endDate = fp.endDate'); $qb->setParameter('travelArrivalPointId', $program->getTravelArrivalPoint()->getId()); @@ -299,11 +277,19 @@ class TravelPeriodRepository extends \Doctrine\ORM\EntityRepository ->addOrderBy('p.name', 'ASC') ; - // #TODO Try to optimize this later $entities = $qb->getQuery()->execute(); - $flightPeriodByKey = []; + + $flightPeriodByKey = null; if (!$program->getIsMediated()) { + if ($flags & self::TD_QUERY_VIRTUAL) + { + // If virtual entries are included, we have to fetch all flight periods, because we don't know + // the actual dates yet + $flightPeriodByKey = $this->getEntityManager()->getRepository('AppBundle:FlightPeriod') + ->getIndexedFlightPeriodsForTimePeriod($startDate, null, $program->getTravelArrivalPoint()->getId()); + } + foreach ($entities as $key => $entity) { if ($entity == null) @@ -334,6 +320,8 @@ class TravelPeriodRepository extends \Doctrine\ORM\EntityRepository } } } + //$x = array_keys($flightPeriodByKey); + //var_dump($x); die(); $this->addTravelDatesToProgram($program, $entities, $flightPeriodByKey, $startDate, null); return $program->getTravelDates(); @@ -415,6 +403,15 @@ class TravelPeriodRepository extends \Doctrine\ORM\EntityRepository { $flightPeriodKey = $travelDateKey . $travelProgram->getTravelArrivalPoint()->getId(); + // #DEBUG + /* + if ($travelPeriodDate->getId() . $travelPeriod->getName() . $i == '18888D8') + { + $x = array_keys($flightPeriods); + var_dump($x); + die (isset($flightPeriods[$flightPeriodKey]) ? 'ok' : 'nok'); + } + */ $flightPeriod = $flightPeriods[$flightPeriodKey] ?? null; } $travelProgram->addTravelDateFromSeasonTravelPeriod( @@ -443,8 +440,13 @@ class TravelPeriodRepository extends \Doctrine\ORM\EntityRepository $flightPeriod = null; if (!$travelProgram->getIsMediated()) { + //$x = array_keys($flightPeriods); + //var_dump($x); + //die($travelDateKey . $travelProgram->getTravelArrivalPoint()->getId()); $flightPeriod = $flightPeriods[$travelDateKey . $travelProgram->getTravelArrivalPoint()->getId()] ?? null; + //if ($travelPeriod->getName() == 'ISRA-HOE18888D8'); + //die($travelPeriod->getName() .';'. $flightPeriod->getPrice()); } // #TODO There is an error in the old backend which causes duplicates diff --git a/trunk/src/AppBundle/Entity/Traveler.php b/trunk/src/AppBundle/Entity/Traveler.php new file mode 100644 index 00000000..e9b74d02 --- /dev/null +++ b/trunk/src/AppBundle/Entity/Traveler.php @@ -0,0 +1,104 @@ + + * @date 02/10/2017 + */ + +namespace AppBundle\Entity; + +use Symfony\Component\Validator\Constraints as Assert; + +class Traveler +{ + // Used in SternToursCrmBookingExports, expected to be equivalent to salutation (as defined in BookingRequest) + const MALE = 1; + const FEMALE = 2; + + /** + * @Assert\NotNull + * @ Assert\Choice(choices={1,2}) + */ + private $sex; + + /** + * @Assert\NotBlank() + */ + private $firstName; + + /** + * @Assert\NotBlank() + */ + private $lastName; + + /** + * @var \DateTime $birthDate + * @Assert\NotBlank() + */ + private $birthDate; + + /** + * @return int + */ + public function getSex() + { + return $this->sex; + } + + /** + * @param int $sex + */ + public function setSex($sex) + { + $this->sex = $sex; + } + + /** + * @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 \DateTime + */ + public function getBirthDate() + { + return $this->birthDate; + } + + /** + * @param \DateTime $birthDate + */ + public function setBirthDate($birthDate) + { + $this->birthDate = $birthDate; + } + + +} \ No newline at end of file diff --git a/trunk/src/AppBundle/Export/SternToursCrmBookingExporter.php b/trunk/src/AppBundle/Export/SternToursCrmBookingExporter.php new file mode 100644 index 00000000..3a63d3f4 --- /dev/null +++ b/trunk/src/AppBundle/Export/SternToursCrmBookingExporter.php @@ -0,0 +1,365 @@ + + * @date 02/13/2017 + */ + +namespace AppBundle\Export; + + +use AppBundle\Entity\BookingRequest; +use AppBundle\Entity\TravelDate; +use AppBundle\Entity\Traveler; +use AppBundle\Util; +use Monolog\Logger; + +class SternToursCrmBookingExporter +{ + const API_URL = 'http://www.cms.stern-tours.net/api'; + const API_KEY = 'f6077389c9ce710e554763a5de02c8ec'; + const API_USER_ID = 15; // 'apiuser' + const WEBSITE_ID = 1; // 'sterntours.de' + + private $logger; + + public function __construct(Logger $logger) + { + $this->logger = $logger; + } + + public function process(BookingRequest $bookingRequest, TravelDate $travelDate, $bookingPriceInfo) + { + $tp = $travelDate->getTravelProgram(); + $startDateStr = $travelDate->getStart()->format('Y-m-d'); + $lead = $this->createLead($bookingRequest, $travelDate); + if ($lead === null) + { + $this->warn('Failed creating lead in CRM', $bookingRequest, $travelDate, Logger::ERROR); + return false; + } + $bookingUrl = $this->createBooking($bookingRequest, $travelDate, $bookingPriceInfo, $lead['customer_id'], + $lead['id']); + if ($bookingUrl === false) + { + $this->warn('Failed creating booking in CRM', $bookingRequest, $travelDate, Logger::ERROR); + return false; + } + + for ($i = 1; $i < $bookingRequest->getTravelerCount(); ++$i) + { + if (!$this->createTraveler($bookingUrl, $bookingRequest->getTravelers()[$i])) + { + $this->warn('Failed creating traveler with index '. $i .' in CRM.', $bookingRequest, $travelDate); + } + } + + if ($tp->getIsMediated()) + { + $serviceItemDefaults = [ + 'travel_company_id' => $tp->getOrganizer()->getCmsId(), + 'travel_date' => $startDateStr, + 'commission' => 0, + ]; + + foreach ($bookingPriceInfo['rooms'] as $room) + { + $this->createServiceItem($bookingUrl, $serviceItemDefaults + [ + 'service_price' => $room['price_total'], + 'name' => $room['name'], + ]); + } + + $this->createServiceItem($bookingUrl, $serviceItemDefaults + [ + 'service_price' => $bookingRequest->getTravelerCount() * $bookingPriceInfo['departure']->getExtraCharge(), + 'name' => $bookingRequest->getTravelerCount() .' x '. $bookingPriceInfo['departure']->getName() + ]); + + foreach ($bookingRequest->getTravelOptions() as $option) + { + $this->createServiceItem($bookingUrl, $serviceItemDefaults + [ + 'service_price' => $option->getPrice() * $bookingRequest->getTravelerCount(), + 'name' => $bookingRequest->getTravelerCount() .' x '. $option->getName() + ]); + } + + // Actually: extra_category + foreach ($bookingPriceInfo['classOptions'] as $classOption) + { + $this->createServiceItem($bookingUrl, $serviceItemDefaults + [ + 'service_price' => $classOption['count'] * $classOption['price'], + 'name' => $classOption['count'] .' x '. $classOption['name'] + ]); + } + } + else + { + $viewPosition = 100; + $viewPositionPrice = 50; + $endDateStr = $travelDate->getEnd()->format('Y-m-d'); + + $arrangementDefaults = [ + 'state' => (new \DateTime())->format('Y-m-d'), + 'in_pdf' => 1 + ]; + + $this->createArrangement($bookingUrl, $arrangementDefaults + [ + 'type_id' => 4, // Flug + 'type_s' => 'Flug', + 'begin' => $startDateStr, + 'view_position' => --$viewPosition, + 'data_s' => ['Hinflug' => 'von '. $bookingPriceInfo['departure']->getName()], + ]); + + $this->createArrangement($bookingUrl, $arrangementDefaults + [ + 'type_id' => 26, // Preisinformation + 'type_s' => 'Preisinformation', + 'view_position' => --$viewPositionPrice, + 'data_s' => [ + 'Name' => 'Abfahrts-/Abflugort '. $bookingPriceInfo['departure']->getName(), + 'Preis' => $bookingPriceInfo['departure']->getExtraCharge(), + 'Teilnehmer' => $bookingRequest->getTravelerCount(), + ], + ]); + + $this->createArrangement($bookingUrl, $arrangementDefaults + [ + 'type_id' => 24, // Rundreise + 'type_s' => 'Rundreise', // Rundreise + 'begin' => $startDateStr, + 'end' => $endDateStr, + 'view_position' => --$viewPosition, + 'data_s' => ['Name' => $tp->getTitle() .' ('. $travelDate->getName() .')'], + ]); + + $roomStrs = []; + foreach ($bookingPriceInfo['rooms'] as $room) + { + $roomStrs[] = '1x '. $room['name']; + + $this->createArrangement($bookingUrl, $arrangementDefaults + [ + 'type_id' => 26, // Preisinformation + 'type_s' => 'Preisinformation', + 'view_position' => --$viewPositionPrice, + 'data_s' => [ + 'Name' => 'pro Person im \''. $room['name'] .'\'', + 'Preis' => $room['price'], + 'Teilnehmer' => $room['adults'], + ], + ]); + } + $this->createArrangement($bookingUrl, $arrangementDefaults + [ + 'type_id' => 5, // Hotel + 'type_s' => 'Hotel', + 'begin' => $startDateStr, + 'end' => $endDateStr, + 'view_position' => --$viewPosition, + 'data_s' => ['Zimmer' => implode(', ', $roomStrs)], + ]); + + // Actually: extra_category + foreach ($bookingPriceInfo['classOptions'] as $classOption) + { + $this->createArrangement($bookingUrl, $arrangementDefaults + [ + 'type_id' => 26, // Preisinformation + 'type_s' => 'Preisinformation', + 'view_position' => --$viewPositionPrice, + 'data_s' => [ + 'Name' => $classOption['name'], + 'Preis' => $classOption['price'], + 'Teilnehmer' => $classOption['count'], + ], + ]); + } + + $this->createArrangement($bookingUrl, $arrangementDefaults + [ + 'type_id' => 4, // Flug + 'type_s' => 'Flug', + 'begin' => $endDateStr, + 'view_position' => --$viewPosition, + 'data_s' => ['Rückflug' => $bookingRequest->getDeparture()->getName()], + ]); + + foreach ($bookingRequest->getTravelOptions() as $option) + { + $this->createArrangement($bookingUrl, $arrangementDefaults + [ + 'type_id' => 26, // Preisinformation + 'type_s' => 'Preisinformation', + 'view_position' => --$viewPositionPrice, + 'data_s' => [ + 'Name' => $option->getName(), + 'Preis' => $option->getPrice(), + 'Teilnehmer' => $bookingRequest->getTravelerCount(), + ], + ]); + } + } + + foreach ($bookingPriceInfo['insurances'] as $insuranceInfo) + { + $this->createServiceItem($bookingUrl, [ + 'travel_company_id' => 30, + 'service_price' => $insuranceInfo['count'] * $insuranceInfo['insurancePriceValue'], + 'name' => $insuranceInfo['count'] . 'x ' . $insuranceInfo['insurance']->getName() . ' ('. + $insuranceInfo['insurancePrice']->getCode() . ')', + 'commission' => round(($insuranceInfo['count'] * $insuranceInfo['insurancePriceValue']) * 20 / 100, 2), + 'travel_date' => $startDateStr, + ]); + } + + return $bookingUrl; + } + + private function createLead(BookingRequest $bookingRequest, TravelDate $travelDate) + { + $resp = $this->httpPost('lead', ['lead' => [ + 'customerForm' => [ + 'salutation_id' => $bookingRequest->getSalutation(), + 'name' => $bookingRequest->getLastName(), + 'firstname' => $bookingRequest->getFirstName(), + 'street' => $bookingRequest->getStreetAddress(), + 'zip' => $bookingRequest->getZipCode(), + 'city' => $bookingRequest->getCity(), + 'country_id' => $bookingRequest->getNation(), + 'phone' => $bookingRequest->getPhone(), + 'fax' => $bookingRequest->getFax(), + 'email' => $bookingRequest->getEmail() + ], + 'request_date' => (new \DateTime())->format('Y-m-d'), + 'sf_guard_user_id' => self::API_USER_ID, + 'status_id' => 7, // 'gebucht' + 'travelperiod_start' => $travelDate->getStart()->format('Y-m-d'), + 'travelperiod_end' => $travelDate->getEnd()->format('Y-m-d'), + //'travelcategory_id' + 'is_closed' => 1, + 'website_id' => self::WEBSITE_ID, + 'initialcontacttype_id' => 14, + // 'travelperiod_length + 'remarks' => $bookingRequest->getNotes() + ]]); + + if ($resp['success']) + { + $ret = $this->httpGet($resp['location']); + if ($ret == null) + { + $this->warn('Failed retrieving newly created lead object', $bookingRequest, $travelDate); + } + return $ret; + } + return null; + } + + private function createBooking(BookingRequest $bookingRequest, TravelDate $travelDate, $bookingPriceInfo, + $customerId, $leadId) + { + $tp = $travelDate->getTravelProgram(); + $resp = $this->httpPost('booking', ['booking' => [ + 'booking_date' => (new \DateTime())->format('Y-m-d'), + 'customer_id' => $customerId, + 'lead_id' => $leadId, + 'travel_country_id' => $tp->getTravelCountry(), + 'travel_category_id' => $tp->getTravelCategory(), + 'travelagenda_id' => $tp->getTravelAgenda(), + 'sf_guard_user_id' => self::API_USER_ID, + 'branch_id' => 4, + 'website_id' => self::WEBSITE_ID, + 'title' => $tp->getTitle(), + 'start_date' => $travelDate->getStart()->format('Y-m-d'), + 'end_date' => $travelDate->getEnd()->format('Y-m-d'), + 'pax' => $bookingRequest->getTravelerCount(), + 'travel_number' => $travelDate->getName(), + 'price' => $bookingPriceInfo['totalWithoutInsurance'], + + 'participant_salutation_id' => $bookingRequest->getTravelers()[0]->getSex(), + 'participant_name' => $bookingRequest->getTravelers()[0]->getLastName(), + 'participant_firstname' => $bookingRequest->getTravelers()[0]->getFirstName(), + 'participant_birthdate' => $bookingRequest->getTravelers()[0]->getBirthDate()->format('Y-m-d'), + ]]); + + if (!$resp['success']) + { + return false; + } + return $resp['location']; + } + + private function createTraveler($bookingUrl, Traveler $traveler) + { + $resp = $this->httpPost($bookingUrl .'/participant.json', ['participant' => [ + 'participant_salutation_id' => $traveler->getSex(), + 'participant_name' => $traveler->getLastName(), + 'participant_firstname' => $traveler->getFirstName(), + 'participant_birthdate' => $traveler->getBirthDate()->format('Y-m-d'), + ]], true); + return $resp['success']; + } + + private function createServiceItem($bookingUrl, $serviceItemData) + { + $resp = $this->httpPost($bookingUrl .'/serviceitem.json', ['booking_service_item' => $serviceItemData], true); + if (!$resp['success']) + { + $this->warn('Failed creating service item '. $serviceItemData['name'] .' for booking '. $bookingUrl); + } + return $resp['success']; + } + + private function createArrangement($bookingUrl, $arrangementData) + { + if (isset($arrangementData['data_s']) && is_array($arrangementData['data_s'])) + { + $tmp = []; + foreach ($arrangementData['data_s'] as $k => $v) + { + $tmp[] .= $k .': '. $v; + } + $arrangementData['data_s'] = implode("\n", $tmp); + } + $resp = $this->httpPost($bookingUrl .'/arrangement.json', ['arrangement' => $arrangementData], true); + if (!$resp['success']) + { + $this->warn('Failed creating arrangement item '. $arrangementData['type_s'] .' for booking '. $bookingUrl); + } + return $resp['success']; + } + + private function httpGet($url) + { + $resp = Util::httpGet($url, ['X-ApiKey: '. self::API_KEY]); + $ret = json_decode($resp['content'], true); + if ($ret === null) + { + $this->warn('Invalid server response: '. $resp['content']); + } + return $ret; + } + + private function httpPost($context, $postData = [], $isContextFullUrl = false) + { + $url = $isContextFullUrl ? $context : self::API_URL.'/'. $context .'.json'; + $resp = Util::httpPost($url, $postData, ['X-ApiKey: '. self::API_KEY], true); + return [ + 'content' => json_decode($resp['content']), + 'location' => isset($resp['response_headers']['location']) + ? $resp['response_headers']['location'] + : null, + 'success' => $resp['success'] && ($resp['status_code'] == 201) + ]; + } + + private function warn($msg, BookingRequest $bookingRequest = null, TravelDate $travelDate = null, + $level = Logger::WARNING) + { + $this->logger->log($level, 'SternToursCrmBookingExporter: '. $msg); + $this->logger->log($level, '*** Date: '. (new \DateTime())->format('d.m.Y')); + if ($travelDate !== null) + { + $this->logger->log($level, '*** Travel date: '. $travelDate->getName() .'('. $travelDate->getStart()->format('d.m.Y') . + ' - '. $travelDate->getEnd()->format('d.m.Y') .')'); + //$this->logger->warn('*** Travel program ID: '. $travelDate->) + } + if ($bookingRequest !== null) + { + $this->logger->log($level, '*** User name: '. $bookingRequest->getFirstName() .' '. $bookingRequest->getLastName()); + } + } +} \ No newline at end of file diff --git a/trunk/src/AppBundle/Form/BookingRequestType.php b/trunk/src/AppBundle/Form/BookingRequestType.php index e9c5a9e9..b07d6a02 100644 --- a/trunk/src/AppBundle/Form/BookingRequestType.php +++ b/trunk/src/AppBundle/Form/BookingRequestType.php @@ -7,7 +7,9 @@ namespace AppBundle\Form; +use AppBundle\Entity\BookingRequest; use AppBundle\Entity\TravelDate; +use AppBundle\Entity\Traveler; use AppBundle\Entity\TravelProgram; use AppBundle\Util; use Doctrine\Common\Collections\Collection; @@ -15,7 +17,12 @@ use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; +use Symfony\Component\Form\Extension\Core\Type\CollectionType; +use Symfony\Component\Form\Extension\Core\Type\TextareaType; +use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\FormEvents; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Validator\Constraints\Choice; use Symfony\Component\Validator\Constraints\NotNull; @@ -26,7 +33,20 @@ class BookingRequestType extends AbstractType '1 Person' => 1, '2 Personen' => 2, '3 Personen' => 3, - '4 Personen' => 4 + '4 Personen' => 4, + ]; + + public static $NATION_CHOICES = [ + 'Deutschland' => 27, + 'Österreich' => 34, + 'Schweiz' => 181, + 'Niederlande' => 196, + 'Sonstiges' => 197, + ]; + + public static $SALUTATION_CHOICES = [ + 'Herr' => BookingRequest::MR, + 'Frau' => BookingRequest::MRS ]; /* @@ -47,7 +67,8 @@ class BookingRequestType extends AbstractType { $resolver->setDefaults([ 'travel_date' => null, - 'travel_program' => null + 'travel_program' => null, + 'data_class' => 'AppBundle\Entity\BookingRequest', ]); $resolver->setAllowedTypes('travel_date', ['AppBundle\Entity\TravelDate']); @@ -65,14 +86,46 @@ class BookingRequestType extends AbstractType /* @var TravelProgram $travelProgram */ $travelProgram = $options['travel_program']; + $builder + ->add('salutation', ChoiceType::class, [ + 'placeholder' => 'Anrede (Bitte wählen) *', + 'choices' => self::$SALUTATION_CHOICES, + 'constraints' => [ + new NotNull(), + new Choice(['choices' => self::$SALUTATION_CHOICES]) + ] + ]) + ->add('firstName') + ->add('lastName') + ->add('streetAddress') + ->add('zipCode') + ->add('city') + ->add('nation', ChoiceType::class, [ + 'choices' => self::$NATION_CHOICES, + 'constraints' => [ + new NotNull(), + new Choice(['choices' => self::$NATION_CHOICES]) + ] + ]) + ->add('phone') + ->add('fax') + ->add('email') + ->add('travelers', CollectionType::class, [ + 'entry_type' => TravelerType::class, + 'by_reference' => false, + ]) + ->add('notes', TextareaType::class, ['required' => false]) + ->add('acceptTerms', CheckboxType::class, ['required' => true]) + ; + $builder->add('departure', EntityType::class, [ + 'placeholder' => 'Abflugort (Bitte wählen) *', 'class' => 'AppBundle\Entity\TravelDeparturePoint', 'choices' => $travelDate->getDepartures(), 'constraints' => [ new NotNull(), new Choice([ - 'choices' => $travelDate->getDepartures(), - 'multiple' => true + 'choices' => $travelDate->getDepartures() ] )] ]); @@ -84,7 +137,6 @@ class BookingRequestType extends AbstractType )] ]); - $insuranceChoices = []; if ($travelProgram->getInsurance1()) { diff --git a/trunk/src/AppBundle/Form/TravelerType.php b/trunk/src/AppBundle/Form/TravelerType.php new file mode 100644 index 00000000..1d4768a3 --- /dev/null +++ b/trunk/src/AppBundle/Form/TravelerType.php @@ -0,0 +1,60 @@ + + * @date 02/10/2017 + */ + +namespace AppBundle\Form; + +use AppBundle\Entity\Traveler; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; +use Symfony\Component\Form\Extension\Core\Type\DateType; +use Symfony\Component\Form\Extension\Core\Type\TextType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Validator\Constraints\Choice; +use Symfony\Component\Validator\Constraints\NotNull; + +class TravelerType extends AbstractType +{ + public static $SEX_CHOICES = [ + 'männlich' => Traveler::MALE, + 'weiblich' => Traveler::FEMALE + ]; + + /** + * @param OptionsResolver $resolver + */ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'AppBundle\Entity\Traveler' + )); + } + + /** + * @param FormBuilderInterface $builder + * @param array $options + */ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder + ->add('sex', ChoiceType::class, [ + 'placeholder' => 'Geschlecht (Bitte wählen) *', + 'choices' => self::$SEX_CHOICES, + 'constraints' => [ + new Choice(['choices' => self::$SEX_CHOICES]) + ], + 'required' => true, + ]) + ->add('firstName') + ->add('lastName') + ->add('birthDate', DateType::class, [ + 'widget' => 'single_text', + 'format' => 'dd.MM.yyyy', + 'required' => true, + ]) + ; + } +} \ No newline at end of file diff --git a/trunk/src/AppBundle/Listener/KernelControllerListener.php b/trunk/src/AppBundle/Listener/KernelControllerListener.php index 23b57731..1006e0a0 100644 --- a/trunk/src/AppBundle/Listener/KernelControllerListener.php +++ b/trunk/src/AppBundle/Listener/KernelControllerListener.php @@ -71,9 +71,11 @@ class KernelControllerListener $request->attributes->set('_controller', 'AppBundle:Default:'. $handler); } } - elseif (isset($parentNode) && $parentNode->getTravelProgram() != null && $pathArray[$i] == 'buchen') + elseif (isset($parentNode) && $parentNode->getTravelProgram() != null && ( + $pathArray[$i] == 'buchen' || $pathArray[$i] == 'berechne-gesamtpreis')) { $request->attributes->set('travelProgramPage', $parentNode); + $request->attributes->set('action', $pathArray[$i]); $request->attributes->set('_controller', 'AppBundle:Booking:index'); } else diff --git a/trunk/src/AppBundle/Resources/public/css/booking.css b/trunk/src/AppBundle/Resources/public/css/booking.css index 4fb15f0c..bed0bdd5 100644 --- a/trunk/src/AppBundle/Resources/public/css/booking.css +++ b/trunk/src/AppBundle/Resources/public/css/booking.css @@ -13,4 +13,9 @@ .st-booking-table .st-total-price { border-bottom: 1px solid; font-weight: bold; +} + +/* #TODO Move */ +.st-required:after { + content: " *"; } \ No newline at end of file diff --git a/trunk/src/AppBundle/Resources/public/css/custom.css b/trunk/src/AppBundle/Resources/public/css/custom.css index ec25d5af..da0db99f 100644 --- a/trunk/src/AppBundle/Resources/public/css/custom.css +++ b/trunk/src/AppBundle/Resources/public/css/custom.css @@ -733,7 +733,7 @@ a, text-transform: uppercase; display: block; position: relative; - background-color: #ffc926; + background-color: #777777; color: #fff; padding: 8px 58px 8px 20px; font-size: 14px; @@ -790,7 +790,7 @@ a, z-index: 10; left: 0; top: 140px; - background-color: #648859; + background-color: #1a457c; color: #fff; padding: 4px 6px 4px 12px; font-weight: bold; @@ -835,7 +835,7 @@ a, text-transform: uppercase; display: block; position: relative; - background-color: #ffc926; + background-color: #777777; color: #fff; padding: 4px 12px 3px 12px; font-size: 14px; @@ -852,18 +852,18 @@ a, } .item-switch > a.item-button-prev:hover { color: #fff; - background-color: #777777; + background-color: #ffc926; } .item-switch > a.item-button-next:hover { color: #fff; - background-color: #777777; + background-color: #ffc926; } .travel-wrapper .item > a.item-button:hover { color: #fff; - background-color: #777777; + background-color: #ffc926; } .travel-wrapper .item > a.item-button:hover:after { - background-color: #5e5e5e; + background-color: #f2b600; } .travel-wrapper .item > a.item-button:after { transition: 0.5s ease; @@ -873,7 +873,7 @@ a, bottom: 0; width: 46px; right: 0px; - background-color: #f2b600; + background-color: #5e5e5e; content: ''; position: absolute; text-align: center; @@ -883,7 +883,7 @@ a, font-size: 26px; } .item-switch > a.item-button-prev:hover:before { - background-color: #5e5e5e; + background-color: #f2b600; } .item-switch > a.item-button-prev:before { transition: 0.5s ease; @@ -893,7 +893,7 @@ a, bottom: 0; width: 30px; left: 0px; - background-color: #f2b600; + background-color: #5e5e5e; content: '\f104'; position: absolute; text-align: center; @@ -903,7 +903,7 @@ a, font-size: 26px; } .item-switch > a.item-button-next:hover:after { - background-color: #5e5e5e; + background-color: #f2b600; } .item-switch > a.item-button-next:after { transition: 0.5s ease; @@ -913,7 +913,7 @@ a, bottom: 0; width: 30px; right: 0px; - background-color: #f2b600; + background-color: #5e5e5e; content: ''; position: absolute; text-align: center; @@ -3296,6 +3296,11 @@ h5:hover a, .c2 li span, .btn-primary { color: #fff; + background-color: #777777; + border-color: #777777; +} +.btn-primary:hover, +.btn-primary:active:hover { background-color: #ffc926; border-color: #ffc926; } diff --git a/trunk/src/AppBundle/Resources/public/css/custom.css.map b/trunk/src/AppBundle/Resources/public/css/custom.css.map new file mode 100644 index 00000000..3ad781f0 --- /dev/null +++ b/trunk/src/AppBundle/Resources/public/css/custom.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../less/includes/tripsfont.less","../less/includes/reset.less","../less/includes/skeleton.less","../less/includes/deals.less","../less/includes/travel.less","../less/includes/shortcodes.less","../less/includes/sections_pages.less","../less/includes/header.less","../less/includes/sidebar_nav.less","../less/includes/slider.less","../less/includes/footer.less","../less/includes/sidebar_widgets.less","../less/includes/color_schemes.less","../less/includes/extras.less","../less/includes/responsive.less","../less/includes/checkbox.less","../less//Users/kevinadametz/Library/Mobile Documents/com~apple~CloudDocs/Webseiten/sterntours.de/assets/bower_components/bootstrap/less/mixins/vendor-prefixes.less","../less//Users/kevinadametz/Library/Mobile Documents/com~apple~CloudDocs/Webseiten/sterntours.de/assets/bower_components/bootstrap/less/mixins/tab-focus.less"],"names":[],"mappings":"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","file":"custom.css"} \ No newline at end of file diff --git a/trunk/src/AppBundle/Resources/public/js/booking.js b/trunk/src/AppBundle/Resources/public/js/booking.js new file mode 100644 index 00000000..ababa6ed --- /dev/null +++ b/trunk/src/AppBundle/Resources/public/js/booking.js @@ -0,0 +1,45 @@ +$(document).ready(function() { + + var frm$ = $('.st-booking-form'); + var summary$ = $('.st-booking-summary'); + var travelerCountDd$ = $('#booking_request_travelerCount'); + var travelers$ = $('.st-traveler'); + var travelerFields$ = travelers$.find('input,select'); + + frm$.find('input, select').change(function() { + var tmp = location.href.split('?'); + var tmp2 = tmp[0].split('/'); + tmp2.pop(); + var url = tmp2.join('/') + '/berechne-gesamtpreis'; + if (tmp[1]) + { + url += '?'+ tmp[1]; + } + + $.ajax({ + url: url, + type: 'post', + data: frm$.serialize() + + }).then(function(r) { + summary$.html(r); + + }, function() { + summary$.html('Aufgrund eines Fehlers konnte kein Angebot ermittelt werden.'); + }) + }); + + function updateTravelers() + { + var travelerCount = parseInt(travelerCountDd$.val()); + travelers$.hide(); + travelerFields$.prop('required', false); + for (var i = 1; i <= travelerCount; ++i) + { + $('.st-traveler-'+ i).show().find('input,select').prop('required', true); + } + } + travelerCountDd$.change(updateTravelers); + updateTravelers(); + +}); \ No newline at end of file diff --git a/trunk/src/AppBundle/Twig/AppExtension.php b/trunk/src/AppBundle/Twig/AppExtension.php new file mode 100644 index 00000000..0bc3d426 --- /dev/null +++ b/trunk/src/AppBundle/Twig/AppExtension.php @@ -0,0 +1,72 @@ + + * @date 02/10/2017 + */ + +namespace AppBundle\Twig; + + +class AppExtension extends \Twig_Extension +{ + protected $environment; + private $template; + + public function __construct(\Twig_Environment $env) + { + $this->environment = $env; + } + + + public function getFunctions() + { + return array( + 'form_field' => new \Twig_SimpleFunction('form_field', array($this, 'formField'), array( + 'is_safe' => array('html') + )), + 'form_field_pho' => new \Twig_SimpleFunction('form_field_pho', array($this, 'formFieldPho'), array( + 'is_safe' => array('html') + )), + ); + } + + public function formField($form, $label = null, $opt = null) + { + $this->template = $this->environment->loadTemplate( '::default/form/helpers.html.twig' ); + return $this->template->renderBlock('form_field', array( + 'form' => $form, + 'label' => $label, + 'opt' => $opt + )); + } + + /** + * Form field with placeholder only + * + * @param $form + * @param null $label + * @param null $opt + * + * @return mixed + */ + public function formFieldPho($form, $label = null, $opt = []) + { + $this->template = $this->environment->loadTemplate( '::default/form/helpers.html.twig' ); + + return $this->template->renderBlock('form_field_pho', array( + 'form' => $form, + 'label' => $label, + 'opt' => $opt + )); + } + + /** + * Returns the name of the extension. + * + * @return string The extension name + */ + public function getName() + { + return 'app_extension'; + } +} \ No newline at end of file diff --git a/trunk/src/AppBundle/Util.php b/trunk/src/AppBundle/Util.php index 1ecd4830..2bf09dd5 100644 --- a/trunk/src/AppBundle/Util.php +++ b/trunk/src/AppBundle/Util.php @@ -35,6 +35,108 @@ class Util $prop->setValue($entity, $collection); } + public static function formatPrice($value) + { + return number_format($value, 2, ',', '.') .' €'; + } + + static function httpRequest($url, $method = "GET", $data = "", $headers = array(), $withRespHeaders = false, + $cookieJar = null) + { + global $kernel; + + $ch = curl_init(); + $headerList = array(); + //self::buildHttpQueryForCurl($headers, $headerList); //? + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_HEADER, $withRespHeaders); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + if (isset($cookieJar)) + { + curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieJar); + curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieJar); + } + if (strtoupper($method) == 'POST') + { + $dataStr = is_array($data) ? http_build_query($data) : $data; + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $dataStr); + } + $response = curl_exec($ch); + + $ret = [ + 'info' => curl_getinfo($ch), + 'success' => true, + 'status_code' => curl_getinfo($ch, CURLINFO_HTTP_CODE) + ]; + + if ($withRespHeaders) + { + $respArray = explode("\r\n\r\n", $response); + $ret['response_headers'] = []; + // count() - 2 due to HTTP status 100 (continue) with multiple responses + $headers = is_array($respArray) && isset($respArray[count($respArray) - 2]) + ? explode("\r\n", $respArray[count($respArray) - 2]) + : []; + + // HTTP/1.1 200 OK + array_shift($headers); + + foreach ($headers as $header) + { + $headerKV = explode(': ', $header); + $key = strtolower($headerKV[0]); + if (isset($ret['response_headers'][$key])) + { + if (is_array($ret['response_headers'][$key])) + { + $ret['response_headers'][$key][] = $headerKV[1]; + } + else + { + $ret['response_headers'][$key] = array($ret['response_headers'][$key], $headerKV[1]); + } + } + else + { + $ret['response_headers'][$key] = $headerKV[1]; + } + } + $ret['content'] = $respArray[count($respArray) - 1]; + } + else + { + $ret['content'] = $response; + } + + if (curl_errno($ch) > 0) + { + $ret['info']['curl_errno'] = curl_errno($ch); + $ret['success'] = false; + } + + if (isset($kernel)) + { + $logger = $kernel->getContainer()->get('logger'); + $logger->warn('HTTP request to \''. $url .'\' with server response code '. $ret['status_code']); + } + + curl_close($ch); + return $ret; + } + + static function httpPost($url, $postData = '', $headers = array(), $withRespHeaders = true, $cookieJarPath = null) + { + return self::httpRequest($url, 'POST', $postData, $headers, $withRespHeaders, $cookieJarPath); + } + + static function httpGet($url, $headers = array(), $withRespHeaders = false, $cookieJarPath = null) + { + return self::httpRequest($url, 'GET', '', $headers, $withRespHeaders, $cookieJarPath); + } + /** * Prints formatted back-trace. CLI-output is colorized as well. *