* Fertigstellung Buchungsformular (#1321) (SternTours-CRM-API-Anbindung, Mailversand, Validierung, Dynamische Preisberechnung, Persistierung von Buchungsinformationen)

* Fehler bei der Preisberechnung behoben
* Farbschema geändert (Kevin Adametz)

git-svn-id: http://78.47.251.156/svn/dev/sterntours-3@3289 f459cee4-fb09-11de-96c3-f9c5f16c3c76
This commit is contained in:
uli 2017-02-14 11:26:49 +00:00
parent dde3b91724
commit 3a28866cd2
36 changed files with 2200 additions and 268 deletions

View file

@ -0,0 +1,20 @@
<table class="st-booking-table">
<tbody>
{% for summary_entry in summary %}
<tr>
<td class="st-position-price-col">
{{ summary_entry.value|number_format(2) }}
</td>
<td class="st-position-name-col">
{{ summary_entry.label|raw }}
</td>
</tr>
{% endfor %}
<tr class="st-total-tr">
<td class="st-position-price-col">
<span class="st-total-price">= {{ total_price|number_format(2) }} €</span>
</td>
<td class="st-position-name-col">Gesamtpreis der Reise</td>
</tr>
</tbody>
</table>

View file

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

View file

@ -0,0 +1,7 @@
FOLGENDE REISE WURDE GEBUCHT:
URL: {{ travel_program_url }}
CRM: {{ crm_url }}
{% include 'default/email/components/bookingSummary.txt.twig' %}

View file

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

View file

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

View file

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

View file

@ -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')
}) %}
<div class="dropdown">
{{- block('base_choice_widget_collapsed') -}}
</div>
{%- 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 %}

View file

@ -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' %}
<link rel="stylesheet" href="{{ asset_url }}"/>
{% endstylesheets %}
{% endblock %}
{% block javascripts %}
{{ parent() }}
{% javascripts '@AppBundle/Resources/public/js/booking.js' %}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
{% block breadcrumb %}
{{ include('default/components/breadcrumb.html.twig') }}
@ -21,7 +36,10 @@
<div id="booking_form" class="booking_form">
<form id="contactform" class="" action="#" name="contactform" method="post">
<form class="st-booking-form" method="post">
{{ form_errors(form) }}
<div id="message"></div>
<div class="form-box">
@ -46,30 +64,27 @@
<tr>
<td>{{ form_label(form.departure, 'Abflugort') }}</td>
<td>
<div class="dropdown">
{{ form_widget(form.departure, {'attr': {
'class': 'selectpicker',
'data-style': 'btn-white'
}}) }}
</div>
{{ form_widget(form.departure) }}
{{ form_errors(form.departure) }}
</td>
</tr>
<tr>
<td>{{ form_label(form.travelerCount, 'Reiseteilnehmer') }}</td>
<td><div class="dropdown">
Erwachsene<br>
{{ form_widget(form.travelerCount) }}
</div>
<td>
Erwachsene<br>
{{ form_widget(form.travelerCount) }}
{{ form_errors(form.travelerCount) }}
</td>
</tr>
<tr>
<td>Reiseversicherung</td>
<td>
<div class="radio">
<input id="radio1" type="radio" name="radio">
<label for="radio1">
keine Reiseversicherung
</label>
<input id="st-no-insurance-opt" type="radio" value=""
name="{{ form.insurance.vars.full_name }}"
{% if form.insurance.vars.value == '' %}checked{% endif %}
>
<label for="st-no-insurance-opt">keine Reiseversicherung</label>
</div>
{% for insuranceForm in form.insurance %}
@ -78,6 +93,8 @@
'insurance': form.insurance.vars.choices[insuranceForm.vars.value].data
} %}
{% endfor %}
{{ form_errors(form.insurance) }}
</td>
</tr>
<tr>
@ -100,7 +117,7 @@
{% for price in travel_date.prices %}
{# @var price \AppBundle\Entity\TravelPeriodPrice #}
<li>
p.P. {{ price.priceComfort|number_format(2) }}
p.P. {{ price.effectiveComfortPrice|number_format(2) }}
{{ price_type_by_id[price.priceType.id].name }}
</li>
{% endfor %}
@ -128,23 +145,12 @@
<div class="panel">
<div class="panel-body">
<h3>Ihr gewähltes Angebot</h3>
<table class="st-booking-table">
<tbody>
<tr>
<td class="st-position-price-col">-700,00 €</td>
<td class="st-position-name-col">
Abzug für Abfahrts-/Abflugort "Eigenanreise" (2 x -350,00 €):
<strong>-700,00 €</strong>
</td>
</tr>
<tr class="st-total-tr">
<td class="st-position-price-col">
<span class="st-total-price">= 3.921,68 €</span>
</td>
<td class="st-position-name-col">Gesamtpreis der Reise</td>
</tr>
</tbody>
</table>
<div class="st-booking-summary">
{% include 'default/components/booking/summary.html.twig' with {
'summary': summary,
'total_price': total_price
} %}
</div>
</div>
</div>
</div>
@ -197,59 +203,44 @@
</div>
<div class="form-group col-md-12 col-sm-12 col-xs-12">
<div class="dropdown">
<select name="salutation" id="salutation" class="selectpicker" data-style="btn-white" data-dropup-auto="false">
<option value="" selected="selected">Anrede (Bitte wählen)</option>
<option value="1">Herr</option>
<option value="2">Frau</option>
</select>
</div>
{{ form_field_pho(form.salutation, 'Anrede', {'label_attr': {class: 'sr-only'}}) }}
</div>
<div class="col-md-6 col-sm-6 col-xs-12">
<input type="text" name="firstname" id="firstname" class="form-control" placeholder="Vorname *">
{#<input type="text" name="firstname" id="firstname" class="form-control" placeholder="Vorname *">#}
{{ form_field_pho(form.firstName, 'Vorname') }}
</div>
<div class="col-md-6 col-sm-6 col-xs-12">
<input type="text" name="lastname" id="lastname" class="form-control" placeholder="Nachname *">
{{ form_field_pho(form.lastName, 'Nachname') }}
</div>
<div class="col-md-12 col-sm-12 col-xs-12">
<input type="text" name="street" id="street" class="form-control" placeholder="Straße, Hausnummer">
</div>
<div class="col-md-6 col-sm-6 col-xs-12">
<input type="text" name="plz" id="plz" class="form-control" placeholder="PLZ">
{{ form_field_pho(form.streetAddress, 'Straße, Hausnummer') }}
</div>
<div class="col-md-6 col-sm-6 col-xs-12">
<input type="text" name="ort" id="ort" class="form-control" placeholder="Ort">
{{ form_field_pho(form.zipCode, 'PLZ') }}
</div>
<div class="col-md-6 col-sm-6 col-xs-12">
{{ form_field_pho(form.city, 'Ort') }}
</div>
<div class="form-group col-md-12 col-sm-12 col-xs-12">
<div class="dropdown">
<select name="country" class="selectpicker" data-style="btn-white" data-dropup-auto="false">
<option value="" selected="selected">Land (Bitte wählen)</option>
<option value="27">Deutschland</option>
<option value="34">Österreich</option>
<option value="181">Schweiz</option>
<option value="196">Niederlande</option>
<option value="197">Sonstiges</option>
</select>
</div>
{{ form_field_pho(form.nation, 'Land') }}
</div>
<div class="col-md-6 col-sm-6 col-xs-12">
<input type="text" name="firstname" id="firstname" class="form-control" placeholder="Telefon tagsüber *">
{{ form_field_pho(form.phone, 'Telefon tagsüber') }}
</div>
<div class="col-md-6 col-sm-6 col-xs-12">
<input type="text" name="lastname" id="lastname" class="form-control" placeholder="Fax (optional)">
{{ form_field_pho(form.fax, 'Fax (optional)') }}
</div>
<div class="col-md-12 col-sm-12 col-xs-12">
<input type="text" name="email" id="email" class="form-control" placeholder="E-Mail-Adresse *">
{{ form_field_pho(form.email, 'E-Mail-Adresse') }}
</div>
</div>
@ -274,53 +265,36 @@
<th>Geburtsdatum (TT.MM.JJJJ)</th>
</tr>
</thead>
<tbody>
<tr>
<td data-title="Nr.">
<button class="btn btn-primary btn-sm border-radius">1</button>
</td>
<td data-title="Geschlecht">
<div class="dropdown">
<select name="salutation" id="salutation1" class="selectpicker" data-style="btn-white" data-dropup-auto="false">
<option value="" selected="selected">Anrede (Bitte wählen)</option>
<option value="1">Herr</option>
<option value="2">Frau</option>
</select>
</div>
</td>
<td data-title="Vorname">
<input type="text" name="firstname" id="firstname1" class="form-control" placeholder="Vorname">
</td>
<td data-title="Nachname">
<input type="text" name="firstname" id="firstname1" class="form-control" placeholder="Nachname">
</td>
<td data-title="Geburtsdatum">
<input type="text" name="firstname" id="firstname1" class="form-control" placeholder="Geburtsdatum">
</td>
</tr>
<tr>
<td data-title="Nr.">
<button class="btn btn-primary btn-sm border-radius">2</button>
</td>
<td data-title="Geschlecht">
<div class="dropdown">
<select name="salutation" id="salutation2" class="selectpicker" data-style="btn-white" data-dropup-auto="false">
<option value="" selected="selected">Anrede (Bitte wählen)</option>
<option value="2">Herr</option>
<option value="2">Frau</option>
</select>
</div>
</td>
<td data-title="Vorname">
<input type="text" name="firstname" id="firstname2" class="form-control" placeholder="Vorname">
</td>
<td data-title="Nachname">
<input type="text" name="firstname" id="firstname2" class="form-control" placeholder="Nachname">
</td>
<td data-title="Geburtsdatum">
<input type="text" name="firstname" id="firstname2" class="form-control" placeholder="Geburtsdatum">
</td>
</tr>
<tbody class="st-travelers">
{% for traveler_form in form.travelers %}
<tr class="st-traveler st-traveler-{{ loop.index }}"
data-st-traveler-index="{{ loop.index }}"
style="display: none;"
>
<td>
<button class="btn btn-primary btn-sm border-radius st-traveller-index"
type="button"
>
{{ loop.index ?? '' }}
</button>
</td>
<td>
{{ form_field_pho(traveler_form.sex, 'Geschlecht', {
required: false
}) }}
</td>
<td>
{{ form_field_pho(traveler_form.firstName, 'Vorname') }}
</td>
<td>
{{ form_field_pho(traveler_form.lastName, 'Nachname') }}
</td>
<td>
{{ form_field_pho(traveler_form.birthDate, 'Geburtsdatum') }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
@ -335,7 +309,10 @@
<h5>Mitteilungen / Sonstiges (optional)</h5>
</div>
<div class="col-md-12 col-sm-12 col-xs-12">
<textarea class="form-control" name="comments" id="comments" rows="6" placeholder=""></textarea>
{{ form_field(form.notes, 'Mitteilungen / Sonstiges (optional)', {
'label_attr': {'class': 'sr-only'},
'attr': {'rows': '6'}
}) }}
</div>
</div>
</div><!-- end form-box -->
@ -345,7 +322,9 @@
<div class="col-md-12 col-sm-12 col-xs-12">
<h5>Zahlung</h5>
<p>Die gewünschte Zahlungsart (Rechnung, Überweisung, Sofortüberweisung, Kreditkarten, Barzahlung) stimmen wir mit Ihnen im Anschluss an Ihre Buchung ab.</p>
<p>Die gewünschte Zahlungsart (Rechnung, Überweisung, Sofortüberweisung, Kreditkarten,
Barzahlung) stimmen wir mit Ihnen im Anschluss an Ihre Buchung ab.
</p>
</div>
@ -357,18 +336,28 @@
<div class="col-md-12 col-sm-12 col-xs-12">
<h5>Allgemeine Geschäftsbedingungen</h5>
<div class="checkbox">
<input id="checkbox4" type="checkbox">
<label for="checkbox4">
Ich habe alle Daten und Angaben auf Richtigkeit überprüft. Ich habe die <a href="#">Allgemeinen Geschäftsbedingungen des Reiseveranstalters</a> SKR sowie die <a href="#">Allgemeinen Geschäftsbedingungen des Reisevermittlers</a> gelesen und akzeptiert. Zugleich erkenne ich diese für alle Reiseteilnehmer an.
{{ form_widget(form.acceptTerms) }}
<label for="{{ form.acceptTerms.vars.id }}">
Ich habe alle Daten und Angaben auf Richtigkeit überprüft. Ich habe die
<a href="#">Allgemeinen Geschäftsbedingungen des Reiseveranstalters</a> SKR
sowie die <a href="#">Allgemeinen Geschäftsbedingungen des Reisevermittlers</a>
gelesen und akzeptiert. Zugleich erkenne ich diese für alle Reiseteilnehmer an.
</label>
{{ form_errors(form.acceptTerms) }}
</div>
</div>
<div class="col-md-12 col-sm-12 col-xs-12">
<button type="submit" value="SEND" id="submit" class="aligncenter btn btn-primary btn-lg border-radius">kostenpflichtig<br class="visible-xs"> buchen</button>
<button type="submit" value="SEND" id="submit"
class="aligncenter btn btn-primary btn-lg border-radius"
>
kostenpflichtig<br class="visible-xs"> buchen
</button>
</div>
</div>
</div><!-- end form-box -->
{{ form_rest(form) }}
</form>
</div><!-- end contact-form -->

View file

@ -0,0 +1,5 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Vielen Dank für Ihren Buchungsauftrag!</h1>
{% endblock %}