DB-Skript:

CREATE TABLE fewo_lodging (id INT AUTO_INCREMENT NOT NULL, type_id INT DEFAULT NULL, name VARCHAR(255) NOT NULL, description LONGTEXT NOT NULL, equipment LONGTEXT NOT NULL, adress1 VARCHAR(255) NOT NULL, adress2 VARCHAR(255) DEFAULT NULL, zip_code VARCHAR(255) NOT NULL, city VARCHAR(255) NOT NULL, maximum_persons INT NOT NULL, deposit DOUBLE PRECISION NOT NULL, only_weekday INT NOT NULL, calendar_visible TINYINT(1) NOT NULL, INDEX IDX_9629C357C54C8C93 (type_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE fewo_lodging_image (id INT AUTO_INCREMENT NOT NULL, lodging_id INT DEFAULT NULL, full_file_name VARCHAR(255) NOT NULL, file_name VARCHAR(255) NOT NULL, description VARCHAR(255) DEFAULT NULL, INDEX IDX_D49F667187335AF1 (lodging_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE fewo_lodging_type (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE fewo_price (id INT AUTO_INCREMENT NOT NULL, lodging_id INT DEFAULT NULL, season_id INT DEFAULT NULL, per_night DOUBLE PRECISION NOT NULL, flat_price DOUBLE PRECISION NOT NULL, INDEX IDX_3DE13C987335AF1 (lodging_id), INDEX IDX_3DE13C94EC001D1 (season_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE fewo_reservation (id INT AUTO_INCREMENT NOT NULL, lodging_id INT DEFAULT NULL, from_date DATE NOT NULL, to_date DATE NOT NULL, status INT NOT NULL, type INT NOT NULL, INDEX IDX_36537F7487335AF1 (lodging_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE fewo_season (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, from_date DATE NOT NULL, to_date DATE NOT NULL, minimum_stay INT NOT NULL, description LONGTEXT DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
ALTER TABLE fewo_lodging ADD CONSTRAINT FK_9629C357C54C8C93 FOREIGN KEY (type_id) REFERENCES fewo_lodging_type (id);
ALTER TABLE fewo_lodging_image ADD CONSTRAINT FK_D49F667187335AF1 FOREIGN KEY (lodging_id) REFERENCES fewo_lodging (id) ON DELETE SET NULL;
ALTER TABLE fewo_price ADD CONSTRAINT FK_3DE13C987335AF1 FOREIGN KEY (lodging_id) REFERENCES fewo_lodging (id);
ALTER TABLE fewo_price ADD CONSTRAINT FK_3DE13C94EC001D1 FOREIGN KEY (season_id) REFERENCES fewo_season (id) ON DELETE SET NULL;
ALTER TABLE fewo_reservation ADD CONSTRAINT FK_36537F7487335AF1 FOREIGN KEY (lodging_id) REFERENCES fewo_lodging (id) ON DELETE SET NULL;
ALTER TABLE page ADD fewo_lodging INT DEFAULT NULL;
ALTER TABLE page ADD CONSTRAINT FK_140AB6209629C357 FOREIGN KEY (fewo_lodging) REFERENCES fewo_lodging (id) ON DELETE SET NULL;
CREATE UNIQUE INDEX UNIQ_140AB6209629C357 ON page (fewo_lodging);

INSERT INTO `fewo_lodging_type` (`name`) VALUES ('Apartment');
INSERT INTO `fewo_lodging_type` (`name`) VALUES ('Bauernhof');
INSERT INTO `fewo_lodging_type` (`name`) VALUES ('Bungalow');
INSERT INTO `fewo_lodging_type` (`name`) VALUES ('Campingplatz');
INSERT INTO `fewo_lodging_type` (`name`) VALUES ('Chalet');
INSERT INTO `fewo_lodging_type` (`name`) VALUES ('Ferienanlage');
INSERT INTO `fewo_lodging_type` (`name`) VALUES ('Ferienhaus');
INSERT INTO `fewo_lodging_type` (`name`) VALUES ('Ferienwohnung');
INSERT INTO `fewo_lodging_type` (`name`) VALUES ('Finca');
INSERT INTO `fewo_lodging_type` (`name`) VALUES ('Hotel');
INSERT INTO `fewo_lodging_type` (`name`) VALUES ('Hütte');
INSERT INTO `fewo_lodging_type` (`name`) VALUES ('Pension');
INSERT INTO `fewo_lodging_type` (`name`) VALUES ('Schloss');
INSERT INTO `fewo_lodging_type` (`name`) VALUES ('Villa');

git-svn-id: http://78.47.251.156/svn/dev/sterntours-3@3348 f459cee4-fb09-11de-96c3-f9c5f16c3c76
This commit is contained in:
valentin.wacker 2017-10-25 12:25:37 +00:00
parent 2ebd38d3d7
commit ab026b752f
57 changed files with 6507 additions and 25 deletions

View file

@ -0,0 +1,128 @@
<!DOCTYPE html>
{% if app.debug -%}
<!-- {% if page is defined %}page-Eintrag mit ID {{ page.id }}{% else %}Für diese Seite existiert kein page-Eintrag, sondern ein Twig-Seitetemplate in app/Resources/views/default/pages{% endif %} -->
{%- endif %}
<!--[if lt IE 7 ]><html class="ie ie6" lang="de"> <![endif]-->
<!--[if IE 7 ]><html class="ie ie7" lang="de"> <![endif]-->
<!--[if IE 8 ]><html class="ie ie8" lang="de"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--><html lang="de"><!--<![endif]-->
<head>
<title>
{% block page_title %}
FeWo-Adminbereich
{% endblock page_title %}
</title>
<!-- Favicons -->
<link rel="shortcut icon" href="/bundles/app/images/favicon.ico" type="image/x-icon" />
<link rel="apple-touch-icon" href="/bundles/app/images/apple-icon.png" />
<link rel="apple-touch-icon" sizes="72x72" href="/bundles/app/images/apple-icon-72x72.png" />
<link rel="apple-touch-icon" sizes="114x114" href="/bundles/app/images/apple-icon-114x114.png" />
{% block stylesheets %}
{% stylesheets
'bundles/app/css/bootstrap-3.3.7.css'
filter='cssrewrite'
%}
<link rel="stylesheet" href="{{ asset_url }}"/>
{% endstylesheets %}
{% stylesheets
'bundles/app/css/custom.css'
filter='cssrewrite'
%}
<link rel="stylesheet" href="{{ asset_url }}"/>
{% endstylesheets %}
<style>.box-slider .slide:not(.active) {display: none;}</style>{# TODO Move to custom.css #}
{% endblock stylesheets %}
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div id="wrapper">
<header class="header fixedheader setbg">
<div class="menu-container">
<div class="container">
<div class="menu-wrapper">
<nav id="navigation" class="navbar" role="navigation" itemscope itemtype="https://schema.org/SiteNavigationElement">
<div class="navbar-inner">
<div id="navbar-collapse" class="navbar-left navbar-collapse collapse clearfix">
<ul class="nav navbar-nav">
<li itemprop="name">
<a href="/admin/fewo/lodgings" title="Wohnungen/Objekte" itemprop="">Objekte</a>
</li>
<li itemprop="name">
<a href="/admin/fewo/seasons" title="Saisons" itemprop="">Saisons</a>
</li>
<li itemprop="name">
<a href="/logout" title="Logout" itemprop="">Logout</a>
</li>
</ul><!-- end navbar-right -->
</div><!-- end navbar-callopse -->
</div>
</nav><!-- end navigation -->
</div><!-- menu wrapper -->
</div><!-- end container -->
</div><!-- end menu-container -->
</header>
<section class="section clearfix" style="padding-top: 100px;">
<div class="container">
<div class="row">
<div id="fullwidth" class="col-sm-12">
<!-- START CONTENT -->
<div class="row">
<div id="content" class="col-md-9 col-sm-8 col-xs-12">
{% block body %}
<section class="clearfix">
<div class="content-copy">
<h1>Sterntours - Adminbereich</h1>
</div>
</section><!-- end section -->
{% endblock %}
</div><!-- end col -->
</div><!-- end row -->
<!-- END CONTENT -->
</div><!-- end fullwidth -->
</div><!-- end row -->
</div><!-- end container -->
</section><!-- end section -->
{#{% include 'default/components/footer.html.twig' %}#}
</div><!-- end wrapper -->
<!-- default modal -->
{#{% embed 'default/components/embed/modal.html.twig' with {id: 'default'} %}{% endembed %}#}
{#TODO ausmisten und im gleichen zuge das CSS für den Datepicker einfügen#}
{% block javascripts %}
<script src="https://maps.google.com/maps/api/js?sensor=false"></script>
{% javascripts
'@AppBundle/Resources/public/js/jquery-3.1.1.js'
'@AppBundle/Resources/public/js/jquery-ui-1.12.1.js'
'@AppBundle/Resources/public/js/bootstrap-3.3.7.js'
'@AppBundle/Resources/public/js/jquery.prettyPhoto-3.1.6.js'
'@AppBundle/Resources/public/js/parallax.js'
'@AppBundle/Resources/public/js/owl.carousel-2.2.0.js'
'@AppBundle/Resources/public/js/bootstrap-select-1.12.0.js'
'@AppBundle/Resources/public/js/custom.js'
%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock javascripts %}
</body>
</html>

View file

@ -0,0 +1,38 @@
{% extends 'admin.html.twig' %}
{% form_theme form 'default/form/theme.html.twig' %}
{% block body %}
<section class="clearfix">
<div class="content-copy">
<h1>Neues Bild für "{{ lodging.name }}" anlegen</h1>
<form class="st-booking-form" method="post" enctype="multipart/form-data">
{{ form_errors(form) }}
<div id="message"></div>
<div class="form-box">
{{ form_row(form.file, {label: 'Bild'}) }}
{{ form_row(form.fileName, {label: 'Name'}) }}
{{ form_row(form.description, {label: 'Beschreibung'}) }}
<div class="col-md-12 col-sm-12 col-xs-12">
<button type="submit" value="SEND" id="submit"
class="btn btn-primary btn-lg border-radius"
>
Speichern
</button>
</div>
</div><!-- end form-box -->
{{ form_rest(form) }}
</form>
<a href="{{ '/admin/fewo/lodgings/' ~ lodging.id }}"
class="btn btn-primary"
rel="nofollow"
>
Zurück
</a>
</div>
</section><!-- end section -->
{% endblock body %}

View file

@ -0,0 +1,63 @@
{% extends 'admin.html.twig' %}
{% block body %}
<section class="clearfix">
<div class="content-copy">
<h1>Objekte</h1>
<div class="table-responsive" id="no-more-tables">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Typ</th>
<th>Objekt</th>
</tr>
</thead>
<tbody>
{% if lodgings is not empty %}
{% for lodging in lodgings %}
<tr>
<td>{{ lodging.id }}</td>
<td>{{ lodging.name }}</td>
<td>{{ lodging.type }}</td>
<td>
<a href="{{ '/admin/fewo/lodgings/' ~ lodging.id }}"
class="btn btn-primary"
rel="nofollow"
>
Bearbeiten
</a>
<a href="{{ '/admin/fewo/lodgings/' ~ lodging.id ~ '/delete' }}"
class="btn btn-primary"
rel="nofollow"
>
Löschen
</a>
</td>
</tr>
{% endfor %}
{% else %}
<h2>Keine Objekte verfügbar</h2>
{% endif %}
<tr>
<td>
<a href="/admin/fewo/lodgings/new"
class="btn btn-primary"
rel="nofollow"
>
Hinzufügen
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</section><!-- end section -->
{% endblock body %}

View file

@ -0,0 +1,231 @@
{% extends 'admin.html.twig' %}
{% form_theme form 'default/form/theme.html.twig' %}
{% block body %}
<section class="clearfix">
<div class="content-copy">
<h1>{{ lodging.name }} bearbeiten</h1>
<form class="st-booking-form" method="post">
{{ form_errors(form) }}
<div id="message"></div>
<div class="form-box">
{{ form_row(form.name, {'label': 'Name'}) }}
{{ form_row(form.type, {'label': 'Typ'}) }}
{{ form_row(form.description, {'label': 'Beschreibung'}) }}
{{ form_row(form.equipment, {'label': 'Ausstattung'}) }}
{{ form_row(form.adress1, {'label': 'Adresse 1'}) }}
{{ form_row(form.adress2, {'label': 'Adresse 2'}) }}
{{ form_row(form.zipCode, {'label': 'PLZ'}) }}
{{ form_row(form.city, {'label': 'Ort'}) }}
{{ form_row(form.maximumPersons, {'label': 'Maximale Personenanzahl'}) }}
{{ form_row(form.deposit, {'label': 'Kaution'}) }}
{{ form_row(form.onlyWeekday, {'label': 'Exklusiver Wochentag'}) }}
<div class="checkbox">
{{ form_widget(form.calendarVisible) }}
<label for="{{ form.calendarVisible.vars.id }}">
Kalender sichtbar
</label>
{{ form_errors(form.calendarVisible) }}
</div>
<br><br>
<h3>Bilder</h3>
{% if lodging.images is not empty %}
<table class="table">
<thead>
<tr>
<th>Bild</th>
<th>Name</th>
<th>Beschreibung</th>
<th></th>
</tr>
</thead>
<tbody>
{% for image in lodging.images %}
<tr>
<td><img src="{{ asset('uploads/images/' ~ image.file) }}" alt="{{ image.description }}" style="width:228px;height:128px;" ></td>
<td>{{ image.fileName }}</td>
<td>{{ image.description }}</td>
<td>
<a href="{{ '/admin/fewo/lodgings/' ~ lodging.id ~ '/images/' ~ image.id ~ '/delete' }}"
class="btn btn-primary"
rel="nofollow"
>
Löschen
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<h4>Keine Bilder vorhanden</h4>
{% endif %}
<a href="{{ '/admin/fewo/lodgings/' ~ lodging.id ~ '/images/new' }}"
class="btn btn-primary"
rel="nofollow"
>
Hinzufügen
</a>
<br><br>
<h3>Saisons (Preise)</h3>
{% if lodging.prices is not empty %}
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Von</th>
<th>Bis</th>
<th>Mindestbelegung</th>
<th>Preis pro Nacht</th>
<th>Pauschalpreis</th>
<th></th>
</tr>
</thead>
<tbody>
{% for lodgingPrice in lodging.prices %}
<tr>
<td>{{ lodgingPrice.season.name }}</td>
<td>{{ lodgingPrice.season.fromDate|date('d-m-y') }}</td>
<td>{{ lodgingPrice.season.toDate|date('d-m-y') }}</td>
<td>{{ lodgingPrice.season.minimumStay }}</td>
<td>{{ lodgingPrice.perNight }}</td>
<td>{{ lodgingPrice.flatPrice }}</td>
<td>
<a href="{{ '/admin/fewo/lodgings/' ~ lodging.id ~ '/prices/' ~ lodgingPrice.id }}"
class="btn btn-primary"
rel="nofollow"
>
Bearbeiten
</a>
<a href="{{ '/admin/fewo/lodgings/' ~ lodging.id ~ '/prices/' ~ lodgingPrice.id ~ '/delete' }}"
class="btn btn-primary"
rel="nofollow"
>
Löschen
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<h4>Keine Saisons vorhanden</h4>
{% endif %}
<a href="/admin/fewo/lodgings/{{ lodging.id }}/prices/new"
class="btn btn-primary"
rel="nofollow"
>
Hinzufügen
</a>
<br><br>
<h3>Reservierungen</h3>
{% if lodging.reservations is not empty %}
<table class="table">
<thead>
<tr>
<th>Von</th>
<th>Bis</th>
<th>Status</th>
<th>Typ</th>
<th></th>
</tr>
</thead>
<tbody>
{% for lodgingReservation in lodging.reservations %}
<tr>
<td>{{ lodgingReservation.fromDate|date('d-m-y') }}</td>
<td>{{ lodgingReservation.toDate|date('d-m-y') }}</td>
<td>
{% if lodgingReservation.status == 0 %}
belegt
{% elseif lodgingReservation.status == 1 %}
nicht verfügbar
{% endif %}
</td>
<td>
{% if lodgingReservation.type == 0 %}
Buchung
{% elseif lodgingReservation.type == 1 %}
händisch
{% endif %}
</td>
<td>
<a href="{{ '/admin/fewo/lodgings/' ~ lodging.id ~ '/reservations/' ~ lodgingReservation.id }}"
class="btn btn-primary"
rel="nofollow"
>
Bearbeiten
</a>
<a href="{{ '/admin/fewo/lodgings/' ~ lodging.id ~ '/reservations/' ~ lodgingReservation.id ~ '/delete' }}"
class="btn btn-primary"
rel="nofollow"
>
Löschen
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<h4>Keine Reservierungen vorhanden</h4>
{% endif %}
{% if lodging.prices is not empty %}
<a href="/admin/fewo/lodgings/{{ lodging.id }}/reservations/new"
class="btn btn-primary"
rel="nofollow"
>
Hinzufügen
</a>
{% else %}
<h4>Mindestens eine Saison pflegen.</h4>
{% endif %}
<br><br>
<h1>Verfügbarkeit</h1>
{% include 'default/admin/lodgingsEditCalendar.html.twig' %}
<br>
<div class="col-md-12 col-sm-12 col-xs-12">
<button type="submit" value="SEND" id="submit"
class="btn btn-primary btn-lg border-radius"
>
Speichern
</button>
</div>
</div><!-- end form-box -->
{{ form_rest(form) }}
</form>
<a href="/admin/fewo/lodgings"
class="btn btn-primary"
rel="nofollow"
>
Zurück
</a>
</div>
</section><!-- end section -->
{% endblock body %}

View file

@ -0,0 +1,100 @@
<table class="table">
{% for month in calendar %}
<thead>
<tr>
<th colspan="7">
{{ month['monthName'] }} {{ month['year'] }}
</th>
</tr>
<tr>
<th>Mo</th>
<th>Di</th>
<th>Mi</th>
<th>Do</th>
<th>Fr</th>
<th>Sa</th>
<th>So</th>
</tr>
</thead>
<tbody>
{% for weekIndex in 0..5 %}
<tr>
{% for dayIndex in 0..6 %}
{% set day = month['data'][(weekIndex * 7) + dayIndex]|split(',') %}
{% if day|length > 1 %}
{% if day[1] == 'reservable' %}
<td style="background-color: green!important;">
<a href="/admin/fewo/lodgings/{{ lodging.id }}/reservations/new/{{ day[0] < 10 ? '0':'' }}{{day[0]}}{{ month['monthNumber'] < 10 ? '0':'' }}{{month['monthNumber']}}{{month['year']}}"
style="color: #5a5a5a;"
{#class="btn btn-primary"#}
rel="nofollow"
>
{{ day[0] }}
</a>
</td>
{% else %}
{% if day|length > 3%}
<td style="background-color: red!important;">
<a href="{{ '/admin/fewo/lodgings/' ~ lodging.id ~ '/reservations/' ~ day[1] }}"
style="color: #5a5a5a;"
{#class="btn btn-primary"#}
rel="nofollow"
>
{{ day[0] }}
</a>
</td>
{% elseif day|length > 2 and day[2] == 'from' %}
<td style="
background: -webkit-gradient(linear, left top, right bottom, color-stop(1%, #f2f2f2), color-stop(52%, #f2f2f2), color-stop(52%, red), color-stop(52%, red), color-stop(100%, red));
background: -moz-gradient(linear, left top, right bottom, color-stop(1%, #f2f2f2), color-stop(52%, #f2f2f2), color-stop(52%, red), color-stop(52%, red), color-stop(100%, red));
background: -o-gradient(linear, left top, right bottom, color-stop(1%, #f2f2f2), color-stop(52%, #f2f2f2), color-stop(52%, red), color-stop(52%, red), color-stop(100%, red));
background: gradient(linear, left top, right bottom, color-stop(1%, #f2f2f2), color-stop(52%, #f2f2f2), color-stop(52%, red), color-stop(52%, red), color-stop(100%, red));
">
<a href="{{ '/admin/fewo/lodgings/' ~ lodging.id ~ '/reservations/' ~ day[1] }}"
style="color: #5a5a5a;"
rel="nofollow"
>
{{ day[0] }}
</a>
</td>
{% elseif day|length > 2 and day[2] == 'to' %}
<td style="
background: -webkit-gradient(linear, left top, right bottom, color-stop(1%, red), color-stop(52%, red), color-stop(52%, green), color-stop(52%, green), color-stop(100%, green));
background: -moz-gradient(linear, left top, right bottom, color-stop(1%, red), color-stop(52%, red), color-stop(52%, green), color-stop(52%, green), color-stop(100%, green));
background: -o-gradient(linear, left top, right bottom, color-stop(1%, red), color-stop(52%, red), color-stop(52%, green), color-stop(52%, green), color-stop(100%, green));
background: gradient(linear, left top, right bottom, color-stop(1%, red), color-stop(52%, red), color-stop(52%, green), color-stop(52%, green), color-stop(100%, green));
">
<a href="/admin/fewo/lodgings/{{ lodging.id }}/reservations/new/{{ day[0] < 10 ? '0':'' }}{{day[0]}}{{ month['monthNumber'] < 10 ? '0':'' }}{{month['monthNumber']}}{{month['year']}}"
style="color: #5a5a5a;"
rel="nofollow"
>
{{ day[0] }}
</a>
</td>
{% else %}
<td style="background-color: red!important;">
<a href="{{ '/admin/fewo/lodgings/' ~ lodging.id ~ '/reservations/' ~ day[1] }}"
style="color: #5a5a5a;"
rel="nofollow"
>
{{ day[0] }}
</a>
</td>
{% endif %}
{% endif %}
{% else %}
<td>
{% if day[0] == 0 %}
-
{% else %}
{{ day[0] }}
{% endif %}
</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>

View file

@ -0,0 +1,56 @@
{% extends 'admin.html.twig' %}
{% form_theme form 'default/form/theme.html.twig' %}
{% block body %}
<section class="clearfix">
<div class="content-copy">
<h1>Neues Objekt anlegen</h1>
<form class="st-booking-form" method="post">
{{ form_errors(form) }}
<div id="message"></div>
<div class="form-box">
{{ form_row(form.name, {label: 'Name'}) }}
{{ form_row(form.type, {label: 'Typ'}) }}
{{ form_row(form.description, {label: 'Beschreibung'}) }}
{{ form_row(form.equipment, {label: 'Ausstattung'}) }}
{{ form_row(form.adress1, {label: 'Adresse 1'}) }}
{{ form_row(form.adress2, {label: 'Adresse 2'}) }}
{{ form_row(form.zipCode, {label: 'PLZ'}) }}
{{ form_row(form.city, {label: 'Ort'}) }}
{{ form_row(form.maximumPersons, {label: 'Maximale Personenanzahl'}) }}
{{ form_row(form.deposit, {label: 'Kaution'}) }}
{{ form_row(form.onlyWeekday, {label: 'Exklusiver Wochentag'}) }}
<div class="checkbox">
{{ form_widget(form.calendarVisible) }}
<label for="{{ form.calendarVisible.vars.id }}">
Kalender sichtbar
</label>
{{ form_errors(form.calendarVisible) }}
</div>
<div class="col-md-12 col-sm-12 col-xs-12">
<button type="submit" value="SEND" id="submit"
class="btn btn-primary btn-lg border-radius"
>
Speichern
</button>
</div>
</div><!-- end form-box -->
{{ form_rest(form) }}
</form>
<a href="/admin/fewo/lodgings"
class="btn btn-primary"
rel="nofollow"
>
Zurück
</a>
</div>
</section><!-- end section -->
{% endblock body %}

View file

@ -0,0 +1,37 @@
{% extends 'admin.html.twig' %}
{% block body %}
<section class="clearfix">
<div class="content-copy">
<h1>Login Adminbereich</h1>
{% if error %}
<div id="message">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
<form action="{{ path('login') }}" class="st-booking-form" method="post">
{#{{ form_errors(form) }}#}
<div class="form-box">
<label for="username">Benutzername:</label>
<input type="text" id="username" name="_username" value="{{ last_username }}" />
<label for="password">Passwort:</label>
<input type="password" id="password" name="_password" />
{#TODO hier evtl hidden input#}
<br><br>
<div class="col-md-12 col-sm-12 col-xs-12">
<button type="submit" id="submit"
class="btn btn-primary btn-lg border-radius"
>
Login
</button>
</div>
</div><!-- end form-box -->
</form>
</div>
</section><!-- end section -->
{% endblock body %}

View file

@ -0,0 +1,37 @@
{% extends 'admin.html.twig' %}
{% form_theme form 'default/form/theme.html.twig' %}
{% block body %}
<section class="clearfix">
<div class="content-copy">
<h1>Saison von {{ lodging.name }} bearbeiten</h1>
<form class="st-booking-form" method="post">
{{ form_errors(form) }}
<div id="message"></div>
<div class="form-box">
{{ form_row(form.season, {label: 'Saison'}) }}
{{ form_row(form.perNight, {label: 'Preis pro Nacht'}) }}
{{ form_row(form.flatPrice, {label: 'Pauschalpreis'}) }}
<div class="col-md-12 col-sm-12 col-xs-12">
<button type="submit" value="SEND" id="submit"
class="btn btn-primary btn-lg border-radius"
>
Speichern
</button>
</div>
</div><!-- end form-box -->
{{ form_rest(form) }}
</form>
<a href="/admin/fewo/lodgings/{{ lodging.id }}"
class="btn btn-primary"
rel="nofollow"
>
Zurück
</a>
</div>
</section><!-- end section -->
{% endblock body %}

View file

@ -0,0 +1,37 @@
{% extends 'admin.html.twig' %}
{% form_theme form 'default/form/theme.html.twig' %}
{% block body %}
<section class="clearfix">
<div class="content-copy">
<h1>Saison zu {{ lodging.name }} hinzufügen</h1>
<form class="st-booking-form" method="post">
{{ form_errors(form) }}
<div id="message"></div>
<div class="form-box">
{{ form_row(form.season, {label: 'Saison'}) }}
{{ form_row(form.perNight, {label: 'Preis pro Nacht'}) }}
{{ form_row(form.flatPrice, {label: 'Pauschalpreis'}) }}
<div class="col-md-12 col-sm-12 col-xs-12">
<button type="submit" value="SEND" id="submit"
class="btn btn-primary btn-lg border-radius"
>
Speichern
</button>
</div>
</div><!-- end form-box -->
{{ form_rest(form) }}
</form>
<a href="/admin/fewo/lodgings/{{ lodging.id }}"
class="btn btn-primary"
rel="nofollow"
>
Zurück
</a>
</div>
</section><!-- end section -->
{% endblock body %}

View file

@ -0,0 +1,73 @@
{% extends 'admin.html.twig' %}
{% form_theme form 'default/form/theme.html.twig' %}
{% block body %}
<section class="clearfix">
<div class="content-copy">
<h1>Reservierung bearbeiten für {{ lodging.name }}</h1>
<h3>Mögliche Saisons</h3>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Von</th>
<th>Bis</th>
<th>Preis pro Nacht</th>
<th>Pauschalpreis</th>
</tr>
</thead>
<tbody>
{% for lodgingPrice in lodging.prices %}
<tr>
<td>{{ lodgingPrice.season.name }}</td>
<td>{{ lodgingPrice.season.fromDate|date('d-m-y') }}</td>
<td>{{ lodgingPrice.season.toDate|date('d-m-y') }}</td>
<td>{{ lodgingPrice.perNight }}</td>
<td>{{ lodgingPrice.flatPrice }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<h3>Reservierung</h3>
<form class="st-booking-form" method="post">
{{ form_errors(form) }}
<div id="message"></div>
<div class="form-box">
{{ form_row(form.lodging, {label: 'Objekt'}) }}
{{ form_row(form.fromDate , {label: 'Von'}) }}
{{ form_row(form.toDate, {label: 'Bis'}) }}
{{ form_row(form.status, {label: 'Status'}) }}
{{ form_row(form.type, {label: 'Typ'}) }}
<div class="col-md-12 col-sm-12 col-xs-12">
<button type="submit" value="SEND" id="submit"
class="btn btn-primary btn-lg border-radius"
>
Speichern
</button>
</div>
</div><!-- end form-box -->
{{ form_rest(form) }}
</form>
<a href="/admin/fewo/lodgings/{{ lodging.id }}"
class="btn btn-primary"
rel="nofollow"
>
Zurück
</a>
<a href="/admin/fewo/lodgings/{{ lodging.id }}/reservations/{{ reservationId }}/delete"
class="btn btn-primary"
rel="nofollow"
>
Löschen
</a>
</div>
</section><!-- end section -->
{% endblock body %}

View file

@ -0,0 +1,67 @@
{% extends 'admin.html.twig' %}
{% form_theme form 'default/form/theme.html.twig' %}
{% block body %}
<section class="clearfix">
<div class="content-copy">
<h1>Neue Reservierung anlegen für {{ lodging.name }}</h1>
<h3>Mögliche Saisons</h3>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Von</th>
<th>Bis</th>
<th>Preis pro Nacht</th>
<th>Pauschalpreis</th>
</tr>
</thead>
<tbody>
{% for lodgingPrice in lodging.prices %}
<tr>
<td>{{ lodgingPrice.season.name }}</td>
<td>{{ lodgingPrice.season.fromDate|date('d-m-y') }}</td>
<td>{{ lodgingPrice.season.toDate|date('d-m-y') }}</td>
<td>{{ lodgingPrice.perNight }}</td>
<td>{{ lodgingPrice.flatPrice }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<h3>Reservierung</h3>
<form class="st-booking-form" method="post">
{{ form_errors(form) }}
<div id="message"></div>
<div class="form-box">
{{ form_row(form.lodging, {label: 'Objekt'}) }}
{{ form_row(form.fromDate , {label: 'Von'}) }}
{{ form_row(form.toDate, {label: 'Bis'}) }}
{{ form_row(form.status, {label: 'Status'}) }}
{{ form_row(form.type, {label: 'Typ'}) }}
<div class="col-md-12 col-sm-12 col-xs-12">
<button type="submit" value="SEND" id="submit"
class="btn btn-primary btn-lg border-radius"
>
Speichern
</button>
</div>
</div><!-- end form-box -->
{{ form_rest(form) }}
</form>
<a href="/admin/fewo/lodgings/{{ lodging.id }}"
class="btn btn-primary"
rel="nofollow"
>
Zurück
</a>
</div>
</section><!-- end section -->
{% endblock body %}

View file

@ -0,0 +1,64 @@
{% extends 'admin.html.twig' %}
{% block body %}
<section class="clearfix">
<div class="content-copy">
<h1>Saisons</h1>
<div class="table-responsive" id="no-more-tables">
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Von</th>
<th>Bis</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{% if seasons is not empty %}
{% for season in seasons %}
<tr>
<td>{{ season.name }}</td>
<td>{{ season.fromDate|date('d-m-y') }}</td>
<td>{{ season.toDate|date('d-m-y') }}</td>
<td>
<a href="{{ '/admin/fewo/seasons/' ~ season.id }}"
class="btn btn-primary"
rel="nofollow"
>
Bearbeiten
</a>
</td>
<td>
<a href="{{ '/admin/fewo/seasons/' ~ season.id ~ '/delete' }}"
class="btn btn-primary"
rel="nofollow"
>
Löschen
</a>
</td>
</tr>
{% endfor %}
{% else %}
<h2>Keine Saisons verfügbar</h2>
{% endif %}
<tr>
<td>
<a href="/admin/fewo/seasons/new"
class="btn btn-primary"
rel="nofollow"
>
Hinzufügen
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</section><!-- end section -->
{% endblock body %}

View file

@ -0,0 +1,42 @@
{% extends 'admin.html.twig' %}
{% form_theme form 'default/form/theme.html.twig' %}
{% block body %}
<section class="clearfix">
<div class="content-copy">
<h1>Saison {{ season.name }} bearbeiten</h1>
<form class="st-booking-form" method="post">
{{ form_errors(form) }}
<div id="message"></div>
<div class="form-box">
{{ form_row(form.name, {label: 'Name'}) }}
{{ form_row(form.fromDate, {label: 'Von'}) }}
{{ form_row(form.toDate, {label: 'Bis'}) }}
{{ form_row(form.minimumStay, {label: 'Mindestbelegung in Tagen'}) }}
{{ form_row(form.description, {label: 'Beschreibung'}) }}
<div class="col-md-12 col-sm-12 col-xs-12">
<button type="submit" value="SEND" id="submit"
class="btn btn-primary btn-lg border-radius"
>
Speichern
</button>
</div>
</div><!-- end form-box -->
{{ form_rest(form) }}
</form>
<a href="/admin/fewo/seasons"
class="btn btn-primary"
rel="nofollow"
>
Zurück
</a>
</div>
</section><!-- end section -->
{% endblock body %}

View file

@ -0,0 +1,42 @@
{% extends 'admin.html.twig' %}
{% form_theme form 'default/form/theme.html.twig' %}
{% block body %}
<section class="clearfix">
<div class="content-copy">
<h1>Neue Saison anlegen</h1>
<form class="st-booking-form" method="post">
{{ form_errors(form) }}
<div id="message"></div>
<div class="form-box">
{{ form_row(form.name, {label: 'Name'}) }}
{{ form_row(form.fromDate, {label: 'Von'}) }}
{{ form_row(form.toDate, {label: 'Bis'}) }}
{{ form_row(form.minimumStay, {label: 'Mindestbelegung in Tagen'}) }}
{{ form_row(form.description, {label: 'Beschreibung'}) }}
<div class="col-md-12 col-sm-12 col-xs-12">
<button type="submit" value="SEND" id="submit"
class="btn btn-primary btn-lg border-radius"
>
Speichern
</button>
</div>
</div><!-- end form-box -->
{{ form_rest(form) }}
</form>
<a href="/admin/fewo/seasons"
class="btn btn-primary"
rel="nofollow"
>
Zurück
</a>
</div>
</section><!-- end section -->
{% endblock body %}

View file

@ -0,0 +1,34 @@
<table class="st-booking-table">
<tbody>
<tr>
<td class="st-position-price-col">
+ {{ fewo_lodging.deposit|number_format(2) }}
</td>
<td class="st-position-name-col">
Kaution
</td>
</tr>
<tr>
<td class="st-position-price-col">
+ {{ fewo_price.flatPrice|number_format(2) }}
</td>
<td class="st-position-name-col">
Pauschalpreis
</td>
</tr>
<tr>
<td class="st-position-price-col">
+ {{ total_price_per_night|number_format(2) }}
</td>
<td class="st-position-name-col">
({{ fewo_booking_request.numberDays }} x {{ fewo_price.perNight|number_format(2) }} €)
</td>
</tr>
<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

@ -4,6 +4,9 @@
{% elseif page.travelProgram is not empty and page.travelProgram.previewImage is not empty %}
{% set image_url = '/uploads/travel_program/' ~ page.travelProgram.previewImage.fileNameWithExtension %}
{% set image_alt = page.title %}
{% elseif page.fewoLodging is not empty and page.fewoLodging.images[0] is not empty %}
{% set image_url = asset('uploads/images/' ~ page.fewoLodging.images[0].file) %}
{% set image_alt = page.title %}
{% else %}
{% set image_url = '/bundles/app/images/no-picture.png' %}
{% set image_alt = 'Kein Vorschaubild vorhanden' %}

View file

@ -0,0 +1,34 @@
{# @var fewo_booking_request \AppBundle\Entity\FewoBookingRequest #}
{# @var fewo_lodging \AppBundle\Entity\FewoLodging #}
{# @var fewo_price \AppBundle\Entity\FewoPrice #}
=====================================================================================
Reisedaten:
=====================================================================================
Ferienwohnung: {{ fewo_lodging.name }}
Saison: {{ fewo_price.season.name }}
Reisezeitraum: {{ fewo_booking_request.fromDate|date }} - {{ fewo_booking_request.toDate|date }}
Gesamtpreis: {{ fewo_booking_request.totalPrice|number_format(2) }}
=====================================================================================
Reiseanmelder{% if fewo_booking_request.salutation == 2 %}in{% endif %}
=====================================================================================
Vorname: {{ fewo_booking_request.firstName }}
Nachname: {{ fewo_booking_request.lastName }}
Adresse: {{ fewo_booking_request.streetAddress }}
PLZ: {{ fewo_booking_request.zipCode }}
Ort: {{ fewo_booking_request.city }}
Telefonnummer: {{ fewo_booking_request.phone }}
Fax: {{ fewo_booking_request.fax ?? 'keine Angabe' }}
E-Mail: {{ fewo_booking_request.email ?? 'keine Angabe' }}
=====================================================================================
Reiseteilnehmer: {{ fewo_booking_request.travelerCount }}
=====================================================================================
=====================================================================================
Mitteilungen / Sonstiges:
=====================================================================================
{{ fewo_booking_request.notes ?? '-' }}

View file

@ -0,0 +1,11 @@
{# @var fewo_booking_request \AppBundle\Entity\FewoBookingRequest #}
Sehr geehrte{{ fewo_booking_request.salutation == 1 ? 'r Herr' : ' Frau' }} {{ fewo_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/fewoBookingSummary.txt.twig' %}
{% include 'default/email/components/signature.txt.twig' %}

View file

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

View file

@ -0,0 +1,84 @@
{% for monthIndex in 0..11 %}
{% if monthIndex is even %}
<table class="table calendarEven">
{% else %}
<table class="table calendarOdd">
{% endif %}
<thead>
<tr>
<th colspan="7">
{{ calendar[monthIndex]['monthName'] }} {{ calendar[monthIndex]['year'] }}
</th>
</tr>
<tr>
<th>Mo</th>
<th>Di</th>
<th>Mi</th>
<th>Do</th>
<th>Fr</th>
<th>Sa</th>
<th>So</th>
</tr>
</thead>
<tbody>
{% for weekIndex in 0..5 %}
<tr>
{% for dayIndex in 0..6 %}
{% set day = calendar[monthIndex]['data'][(weekIndex * 7) + dayIndex]|split(',') %}
{% if day|length > 1 %}
{% if day[1] == 'reservable' %}
<td>
<a href="/fewo/{{ page.slug }}/fewo-buchen?pnr={{ day[2] }}&fd={{ day[0] < 10 ? '0':'' }}{{day[0]}}{{ calendar[monthIndex]['monthNumber'] < 10 ? '0':'' }}{{calendar[monthIndex]['monthNumber']}}{{calendar[monthIndex]['year']}}"
style="color: #5a5a5a;"
rel="nofollow"
>
{{ day[0] }}
</a>
</td>
{% else %}
{% if day|length > 3%}
<td style="background-color: darkgray!important;">
<del>{{ day[0] }}</del>
</td>
{% elseif day|length > 2 and day[2] == 'from' %}
<td style="
background: darkgray!important;
">
<del>{{ day[0] }}</del>
</td>
{% elseif day|length > 2 and day[2] == 'to' %}
{% set nextDay = calendar[monthIndex]['data'][(weekIndex * 7) + (dayIndex + 1)]|split(',') %}
<td class="calendarGradient">
<a href="/fewo/{{ page.slug }}/fewo-buchen?pnr={{ nextDay[2] }}&fd={{ day[0] < 10 ? '0':'' }}{{day[0]}}{{ calendar[monthIndex]['monthNumber'] < 10 ? '0':'' }}{{calendar[monthIndex]['monthNumber']}}{{calendar[monthIndex]['year']}}"
style="color: white;"
rel="nofollow"
>
<del>{{ day[0] }}</del>
</a>
</td>
{% else %}
<td style="background-color: darkgray!important;">
<del>{{ day[0] }}</del>
</td>
{% endif %}
{% endif %}
{% else %}
{% if day[0] == 0 %}
<td>
-
</td>
{% else %}
<td style="background-color: darkgray!important">
<del>{{ day[0] }}</del>
</td>
{% endif %}
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% endfor %}

View file

@ -0,0 +1,221 @@
{#{% extends 'admin.html.twig' %}#}
{# @var fewo_lodging \AppBundle\Entity\FewoLodging #}
{% extends get_base_template() %}
{% block javascripts %}
{{ parent() }}
{% javascripts '@AppBundle/Resources/public/js/travelProgram.js' %}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
{% block body %}
<section class="clearfix">
<div class="content-copy">
<h1>{{ fewo_lodging.name }}</h1>
{#
********* SLIDER *********
#}
<section class="section fullscreen background padding-0 margin-bottom-20">
<div id="myCarousel" class="carousel slide">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li>
<li data-target="#myCarousel" data-slide-to="2"></li>
</ol>
<!-- Wrapper for Slides -->
<div class="carousel-inner">
{% for lodging_image in fewo_lodging.images %}
{# @var image \AppBundle\Entity\FewoLodgingImage #}
<div class="item{% if loop.first %} active{% endif %}">
<!-- Set the first background image using inline CSS below. -->
{# TODO #}
<div class="fill" style="background-image:url({{ asset('uploads/images/' ~ lodging_image.file) }});"></div>
</div>
{% endfor %}
</div>
<!-- Controls -->
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</section><!-- end section -->
{#
********* TAB BAR *********
#}
{% block travel_lodging_program_tab_bar %}
<div class="scroller-nav-tabs scroller-left-nav-tabs"><i class="glyphicon glyphicon-chevron-left"></i></div>
<div class="scroller-nav-tabs scroller-right-nav-tabs"><i class="glyphicon glyphicon-chevron-right"></i></div>
<div class="wrapper-nav-tabs">
<ul class="nav nav-tabs nav-justified list-nav-tabs">
<li class="active">
<a href="#travel-description-content-tab" aria-controls="travel-description-content-tab" role="tab" data-toggle="tab">
Beschreibung
</a>
</li>
<li>
<a href="#travel-equipment-content-tab" aria-controls="travel-equipment-content-tab" role="tab" data-toggle="tab">
Ausstattung
</a>
</li>
<li>
<a href="#travel-dates-content-tab" aria-controls="travel-dates-content-tab" role="tab" data-toggle="tab">
Termine <i class="fa fa-star"></i> Preise
</a>
</li>
</ul>
</div>
{% endblock travel_lodging_program_tab_bar %}
<div class="tab-content">
{#
********* BESCHREIBUNG *********
#}
<div role="tabpanel" class="tab-pane active" id="travel-description-content-tab">
{#TODO alles wirklich hier? wo bilder?#}
<h3>Allgemeines</h3>
<div class="table-responsive" id="no-more-tables">
<table class="table">
<thead>
<tr>
<th>Typ</th>
<th>Adresse</th>
<th>PLZ</th>
<th>Ort</th>
<th>Max. Personenanzahl</th>
<th>Kaution</th>
</tr>
</thead>
<tbody>
<tr>
<td data-title="Typ">
{{ fewo_lodging.type }}
</td>
<td data-title="Adresse">
{{ fewo_lodging.adress1 }}
{% if fewo_lodging.adress2 is not empty %}
{{ fewo_lodging.adress2 }}
{% endif %}
</td>
<td data-title="PLZ">
{{ fewo_lodging.zipCode }}
</td>
<td data-title="Ort">
{% if fewo_lodging.city is not empty %}
{{ fewo_lodging.city }}
{% endif %}
</td>
<td data-title="Max. Personenanzahl">
{% if fewo_lodging.maximumPersons is not empty %}
{{ fewo_lodging.maximumPersons }}
{% endif %}
</td>
<td data-title="Kaution">
{% if fewo_lodging.deposit is not empty %}
{{ fewo_lodging.deposit|number_format(2, ',', '.') }}
{% endif %}
</td>
</tr>
</tbody>
</table>
</div>
{% if fewo_lodging.description is not empty %}
<hr>
<div>
{{ fewo_lodging.description|raw }}
</div>
{% endif %}
</div> <!-- END tabpanel -->
{#
********* AUSSTATTUNG *********
#}
<div role="tabpanel" class="tab-pane" id="travel-equipment-content-tab">
<div>
{{ fewo_lodging.equipment|raw }}
</div>
</div> <!-- END tabpanel -->
{#
********* TERMINE UND PREISE *********
#}
<div role="tabpanel" class="tab-pane" id="travel-dates-content-tab">
<h3>Saisons</h3>
<div class="table-responsive" id="no-more-tables">
{% if fewo_lodging.prices is not empty %}
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Beginn</th>
<th>Ende</th>
<th>Preis p.P. pro Nacht</th>
<th>Pauschalpreis</th>
<th>Kaution</th>
</tr>
</thead>
<tbody>
{% for price in fewo_lodging.prices %}
<tr>
<td data-title="Name">
<strong class="small">
{{ price.season.name }}
</strong>
</td>
<td data-title="Beginn">
{{ price.season.fromDate|date }}
</td>
<td data-title="Ende">
{{ price.season.toDate|date }}
</td>
<td data-title="Preis p.P pro Nacht">
{{ price.perNight|number_format(2, ',', '.') }}
</td>
<td data-title="Pauschalpreis">
{{ price.flatPrice|number_format(2, ',', '.') }}
</td>
<td data-title="Kaution">
{% if fewo_lodging.deposit is not empty %}
{{ fewo_lodging.deposit|number_format(2, ',', '.') }}
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<h3>Buchung</h3>
{% include 'default/pages/cms/calendarLodgingProgram.html.twig' %}
{% else %}
Momentan sind für dieses Programm keine Termine verfügbar.
{% endif %}
</div>
</div> <!-- END tabpanel -->
</div>
{{ block('travel_lodging_program_tab_bar') }}
</div>
</section><!-- end section -->
{% endblock body %}

View file

@ -0,0 +1,192 @@
{% 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/fewoBooking.js' %}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
{% block body %}
<section class="clearfix">
<div class="content-copy">
<h1>Buchungsformular FeWo</h1>
{#
<div class="pull-right">
<a href="{{ page.urlPath }}" class="btn btn-primary btn-sm"><< zurück zu Termine und Preise</a>
</div>
<div class="clearfix"></div>
#}
<h2 style="margin-top:10px">{{ lodging.name }}</h2>
<div id="booking_form" class="booking_form">
<form class="st-booking-form" method="post">
{{ form_errors(form) }}
<div id="message"></div>
<div class="form-box">
<div class="table-responsive" id="no-more-tables_first">
<table class="table first-table">
<tbody>
<tr>
<td>Ferienwohnung</td>
<td>
{{ lodging.name }}
</td>
</tr>
<tr>
<td>Saison</td>
<td>
{{ fewo_price.season.name }}
</td>
</tr>
<tr>
<td>Reisebeginn</td>
<td>{{ fromDate|date }}</td>
</tr>
<tr>
<td>{{ form_label(form.toDate, 'Reiseende') }}</td>
<td>
{{ form_widget(form.toDate) }}
{{ form_errors(form.toDate) }}
</td>
</tr>
<tr>
<td>{{ form_label(form.travelerCount, 'Reiseteilnehmer') }}</td>
<td>
{{ form_widget(form.travelerCount) }}
{{ form_errors(form.travelerCount) }}
</td>
</tr>
</tbody>
</table>
</div>
<div class="col-xs-12">
<div class="panel">
<div class="panel-body">
<h3>Ihr gewähltes Angebot</h3>
<div class="st-booking-summary">
{% include 'default/components/booking/fewoSummary.html.twig' with {
'fewo_booking_request' : fewo_booking_request,
'fewo_lodging' : fewo_lodging,
'fewo_price' : fewo_price,
'total_price' : total_price,
'total_price_per_night' : total_price_per_night,
} %}
</div>
</div>
</div>
</div>
</div>
<div class="form-box">
<div class="">
<div class="col-md-12 col-sm-12 col-xs-12">
<h5>Reiseanmelder</h5>
</div>
<div class="form-group col-md-12 col-sm-12 col-xs-12">
{{ form_field_pho(form.salutation, 'Anrede', {'label_attr': {class: 'sr-only'}}) }}
</div>
<div class="col-md-6 col-sm-6 col-xs-12">
{{ form_field_pho(form.firstName, 'Vorname') }}
</div>
<div class="col-md-6 col-sm-6 col-xs-12">
{{ form_field_pho(form.lastName, 'Nachname') }}
</div>
<div class="col-md-12 col-sm-12 col-xs-12">
{{ form_field_pho(form.streetAddress, 'Straße, Hausnummer') }}
</div>
<div class="col-md-6 col-sm-6 col-xs-12">
{{ 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="col-md-6 col-sm-6 col-xs-12">
{{ form_field_pho(form.phone, 'Telefon tagsüber') }}
</div>
<div class="col-md-6 col-sm-6 col-xs-12">
{{ form_field_pho(form.fax, 'Fax (optional)') }}
</div>
<div class="col-md-12 col-sm-12 col-xs-12">
{{ form_field_pho(form.email, 'E-Mail-Adresse') }}
</div>
</div>
</div><!-- end form-box -->
<div class="form-box">
<div class="">
<div class="col-md-12 col-sm-12 col-xs-12">
<h5>Mitteilungen / Sonstiges (optional)</h5>
</div>
<div class="col-md-12 col-sm-12 col-xs-12">
{{ form_field(form.notes, 'Mitteilungen / Sonstiges (optional)', {
'label_attr': {'class': 'sr-only'},
'attr': {'rows': '6'}
}) }}
</div>
</div>
</div><!-- end form-box -->
<div class="form-box">
<div class="">
{#
<div class="col-md-12 col-sm-12 col-xs-12">
<h5>Allgemeine Geschäftsbedingungen</h5>
<div class="checkbox">
{{ form_widget(form.acceptTerms) }}
<label for="{{ form.acceptTerms.vars.id }}">
Ich habe alles gelesen usw...
</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>
</div>
</div>
</div><!-- end form-box -->
{{ form_rest(form) }}
</form>
</div><!-- end contact-form -->
</div>
</section>
{% endblock body %}

View file

@ -0,0 +1,150 @@
{% extends 'base.html.twig' %}
{% block canonical_tag %}{% endblock %}
{% block body %}
<section class="clearfix">
<div class="content-copy">
<h1>Vielen Dank für Ihren Buchungsauftrag!</h1>
<div class="pull-right">
<a href="/" class="btn btn-primary btn-sm"><< Zurück zur Startseite</a>
</div>
<div class="clearfix"></div>
<h2 style="margin-top:10px">{{ page.fewoLodging.name }} {{ fewo_price.season.name }}</h2>
<div id="booking_form" class="booking_form">
<form class="st-booking-form" method="post">
<div id="message"></div>
<div class="form-box">
<div class="table-responsive" id="no-more-tables_first">
<table class="table first-table">
<tbody>
<tr>
<td>Ferienwohnung</td>
<td>
{{ page.fewoLodging.name }}
</td>
</tr>
<tr>
<td>Reisezeitraum</td>
<td>{{ fewo_booking_request.fromDate|date }} - {{ fewo_booking_request.toDate|date }}</td>
</tr>
</tbody>
</table>
</div>
{#TODO#}
<div class="col-xs-12">
<div class="panel">
<div class="panel-body">
<h3>Ihr gewähltes Angebot</h3>
<div class="st-booking-summary">
{% include 'default/components/booking/fewoSummary.html.twig' with {
'fewo_booking_request' : fewo_booking_request,
'fewo_lodging' : fewo_lodging,
'fewo_price' : fewo_price,
'total_price' : total_price,
'total_price_per_night' : total_price_per_night,
} %}
</div>
</div>
</div>
</div>
</div>
<div class="form-box">
<div class="">
<div class="col-md-12 col-sm-12 col-xs-12">
<h5>Reiseanmelder</h5>
</div>
<div class="table-responsive" id="no-more-tables_first">
<table class="table first-table">
<tbody>
<tr>
<td>Anrede</td>
<td>
{% if fewo_booking_request.salutation == 1 %}
Herr
{% elseif fewo_booking_request.salutation == 2 %}
Frau
{% endif %}
</td>
</tr>
<tr>
<td>Vorname</td>
<td>{{ fewo_booking_request.firstName }}</td>
</tr>
<tr>
<td>Nachname</td>
<td>{{ fewo_booking_request.lastName }}</td>
</tr>
<tr>
<td>Straße, Hausnummer</td>
<td>{{ fewo_booking_request.streetAddress }}</td>
</tr>
<tr>
<td>PLZ</td>
<td>{{ fewo_booking_request.zipCode }}</td>
</tr>
<tr>
<td>Ort</td>
<td>{{ fewo_booking_request.city }}</td>
</tr>
<tr>
<td>Telefon tagsüber</td>
<td>{{ fewo_booking_request.phone }}</td>
</tr>
<tr>
<td>Fax (optional)</td>
<td>{{ fewo_booking_request.fax }}</td>
</tr>
<tr>
<td>E-Mail-Adresse</td>
<td>{{ fewo_booking_request.email }}</td>
</tr>
<tr>
<td>
Anzahl Reiseteilnehmer
</td>
<td>{{ fewo_booking_request.travelerCount }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div><!-- end form-box -->
<div class="form-box">
<div class="">
<div class="col-md-12 col-sm-12 col-xs-12">
<h5>Mitteilungen / Sonstiges (optional)</h5>
</div>
<div class="col-md-12 col-sm-12 col-xs-12">
<p>{{ fewo_booking_request.notes }}</p>
</div>
</div>
</div><!-- end form-box -->
</div><!-- end contact-form -->
<div class="pull-right">
<a href="/" class="btn btn-primary btn-sm"><< Zurück zur Startseite</a>
</div>
</div>
</section>
{% endblock %}

View file

@ -6,3 +6,6 @@ route1:
defaults: { _controller: 'AppBundle:Default:default' }
requirements:
req: ".+"
logout:
path: /logout

View file

@ -1,24 +1,32 @@
# To get started with security, check out the documentation:
# http://symfony.com/doc/current/book/security.html
security:
# http://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
providers:
in_memory:
memory: ~
memory:
users:
bstar:
password: $2y$13$./cas5fxa2yto6Q2or0TZ.zwwisoFWWP6MgrCQbO7ljUtynaCalAi
roles: 'ROLE_ADMIN'
encoders:
Symfony\Component\Security\Core\User\User: #plaintext
algorithm: bcrypt
cost: 13
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
# activate different ways to authenticate
# http_basic: ~
# http://symfony.com/doc/current/book/security.html#a-configuring-how-your-users-will-authenticate
# form_login: ~
# http://symfony.com/doc/current/cookbook/security/form_login_setup.html
form_login:
login_path: login
check_path: login
default_target_path: after_login
always_use_default_target_path: true
logout:
path: /logout
target: /
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }

View file

@ -36,6 +36,11 @@ services:
arguments:
- '@monolog.logger'
app.fewo_booking_exporter:
class: AppBundle\Export\FewoBookingSternToursCrmExporter
arguments:
- '@monolog.logger'
app.contact_exporter:
class: AppBundle\Export\ContactSternToursCrmExporter
arguments:
@ -51,3 +56,21 @@ services:
arguments:
- '%kernel.root_dir%'
- '@assetic.asset_manager'
app.image_uploader:
class: AppBundle\Service\FileManager
arguments:
- '%image_upload_directory%'
app.image_upload_listener:
class: AppBundle\Listener\DoctrineFileListener
autowire: true
tags:
- { name: doctrine.event_listener, event: prePersist }
- { name: doctrine.event_listener, event: preUpdate }
- { name: doctrine.event_listener, event: preRemove }
app.lodging_calendar_util:
class: AppBundle\Util\LodgingCalendarUtil
arguments:
- '@doctrine.orm.entity_manager'

View file

@ -0,0 +1,830 @@
<?php
/**
* Created by PhpStorm.
* User: Valentin Wacker
* Date: 18.08.2017
* Time: 15:03
*/
namespace AppBundle\Controller;
use AppBundle\AppBundle;
use AppBundle\Entity\FewoBookingRequest;
use AppBundle\Entity\FewoLodging;
use AppBundle\Entity\FewoPrice;
use AppBundle\Entity\FewoReservation;
use AppBundle\Entity\FewoSeason;
use AppBundle\Entity\FewoLodgingImage;
use AppBundle\Form\FewoBookingRequestType;
use AppBundle\Form\FewoLodgingType;
use AppBundle\Form\FewoPriceType;
use AppBundle\Form\FewoReservationType;
use AppBundle\Form\FewoSeasonType;
use AppBundle\Form\FewoLodgingImageType;
use AppBundle\Service\FileManager;
use AppBundle\Util;
use Doctrine\Bundle\DoctrineCacheBundle\Tests\Functional\FileSystemCacheTest;
use Doctrine\ORM\EntityManager;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\File;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class AdminController extends Controller
{
public function getEntityManager()
{
return $this->getDoctrine()->getManager();
}
/**
* @Route("/login", name="login")
*/
public function adminAction(Request $request)
{
$authUtils = $this->get('security.authentication_utils');
$error = $authUtils->getLastAuthenticationError();
$lastUsername = $authUtils->getLastUsername();
return $this->render('default/admin/loginAdmin.html.twig', [
'last_username' => $lastUsername,
'error' => $error,
]);
}
/**
* @Route("/admin/fewo")
*/
public function adminFewoAction()
{
return $this->render('admin.html.twig', [
]);
}
/**
* @Route("/admin/fewo/lodgings", name="after_login")
*/
public function adminFewoLodgingsAction(Request $request)
{
$fewoLodgingRepo = $this->getEntityManager()->getRepository('AppBundle:FewoLodging');
$lodgings = $fewoLodgingRepo->findAll();
return $this->render('default/admin/lodgings.html.twig', [
'lodgings' => $lodgings,
]);
}
/**
* @Route("/admin/fewo/lodgings/new")
*/
public function adminFewoNewLodgingAction(Request $request)
{
$lodging = null;
if ($request->getMethod() != 'POST')
{
$lodging = new FewoLodging();
}
$form = $this->createForm(FewoLodgingType::class, $lodging, [
]);
// todo if(form == null)...
if ($request->getMethod() == 'POST')
{
$form->handleRequest($request);
$lodging = $form->getData();
}
if ($request->getMethod() == 'POST' && $form->isValid())
{
$em = $this->getEntityManager();
$em->persist($lodging);
$em->flush();
return $this->redirect('/admin/fewo/lodgings');
}
return $this->render('default/admin/lodgingsNew.html.twig', [
'form' => $form->createView(),
]);
}
private function getSeasons(FewoLodging $lodging)
{
$seasons = [];
$lodgingPrices = $lodging->getPrices();
foreach($lodgingPrices as $price)
{
$seasons[] = $price->getSeason();
}
return $seasons;
}
private function setChoosableSeasons(FewoLodging $lodging)
{
$em = $this->getEntityManager();
$fewoSeasonRepo = $em->getRepository('AppBundle:FewoSeason');
$allSeasons = $fewoSeasonRepo->findAll();
$lodgingSeasons = [];
$lodgingSeasons = $this->getSeasons($lodging);
$seasons = null;
for($i = 0; $i < count($allSeasons); $i++)
{
if(!in_array($allSeasons[$i], $lodgingSeasons))
{
$seasons[] = $allSeasons[$i];
}
}
$lodging->setChoosableSeasons($seasons);
}
/**
* @Route("/admin/fewo/lodgings/{lodgingId}", requirements={"lodgingId": "\d+"})
*/
public function adminFewoEditLodgingAction(Request $request, $lodgingId)
{
$em = $this->getEntityManager();
$fewoLodgingRepo = $em->getRepository('AppBundle:FewoLodging');
$lodging = null;
$calendarUtil = $this->container->get('app.lodging_calendar_util');
$lodging = $fewoLodgingRepo->find($lodgingId);
$reservations = $calendarUtil->getReservations($lodging);
$paddedCalendar = $calendarUtil->getCalendarWithPadding();
$calendar = $calendarUtil->getCalendar();
$calendar = $calendarUtil->markCalendarDaysWithReservations($lodging, $calendar);
$calendar = $calendarUtil->mergeWithPaddedCalendar($calendar, $paddedCalendar);
$form = $this->createForm(FewoLodgingType::class, $lodging, [
//options
]);
if($request->getMethod() == 'POST')
{
$form->handleRequest($request);
}
if ($request->getMethod() == 'POST' && $form->isValid())
{
$em->flush();
return $this->redirect('/admin/fewo/lodgings');
}
return $this->render('default/admin/lodgingsEdit.html.twig', [
'form' => $form->createView(),
'lodging' => $lodging,
'calendar'=> $calendar,
'reservations' => $reservations
]);
}
/**
* @Route("/admin/fewo/lodgings/{lodgingId}/delete", requirements={"lodgingId": "\d+"})
*/
public function adminFewoDeleteLodgingAction(Request $request, $lodgingId)
{
$em = $this->getEntityManager();
$fewoLodgingRepo = $em->getRepository('AppBundle:FewoLodging');
$lodging = $fewoLodgingRepo->find($lodgingId);
if($lodging != null)
{
$em->remove($lodging);
$em->flush();
}
return $this->redirect('/admin/fewo/lodgings');
}
/**
* @Route("/admin/fewo/lodgings/{lodgingId}/program", requirements={"lodgingId": "\d+"})
*/
public function adminFewoLodgingProgramAction(Request $request, $lodgingId)
{
$fewoLodgingRepo = $this->getEntityManager()->getRepository('AppBundle:FewoLodging');
$lodging = $fewoLodgingRepo->find($lodgingId);
$calendarUtil = $this->container->get('app.lodging_calendar_util');
$reservations = $calendarUtil->getReservations($lodging);
$paddedCalendar = $calendarUtil->getCalendarWithPadding();
$calendar = $calendarUtil->getCalendar();
$calendar = $calendarUtil->markCalendarDaysWithReservations($lodging, $calendar);
$calendar = $calendarUtil->mergeWithPaddedCalendar($calendar, $paddedCalendar);
return $this->render('default/pages/cms/fewoTravelProgram.html.twig', [
'fewo_lodging' => $lodging,
'calendar' => $calendar
]);
}
/**
* @ Route("/admin/fewo/lodgings/{lodgingId}/prices/{priceId}/reservations/new/{fromDate}/booking", requirements={"lodgingId": "\d+", "priceId": "\d+", "fromDate": "\w+"})
*/
public function adminFewoBookingAction(Request $request, $lodgingId, $priceId, $fromDate)
{
$em = $this->getEntityManager();
$fewoLodgingRepo = $em->getRepository('AppBundle:FewoLodging');
$fewoPriceRepo = $em->getRepository('AppBundle:FewoPrice');
$lodging = $fewoLodgingRepo->find($lodgingId);
$price = $fewoPriceRepo->find($priceId);
/** @var FewoSeason $season */
$season = $price->getSeason();
$minimumStay = $season->getMinimumStay();
$fromDate = $this->convertDate($fromDate);
$toDate = '';
$maxPersons = $lodging->getMaximumPersons();
$fewoBookingRequest = new FewoBookingRequest();
$reservation = new FewoReservation();
if ($request->getMethod() != 'POST')
{
$dateAppendix = " + ".($minimumStay - 1)." day";
if($minimumStay > 1)
{
$dateAppendix= $dateAppendix."s";
}
$toDate = date('d.m.Y', strtotime($fromDate.$dateAppendix));
$fewoBookingRequest->setFromDate($fromDate);
$fewoBookingRequest->setToDate($toDate);
}
$form = $this->createForm(FewoBookingRequestType::class, $fewoBookingRequest, [
'lodging' => $lodging,
'maxPersons' => $maxPersons,
'toDate' => $toDate
]);
if ($request->getMethod() == 'POST')
{
$form->handleRequest($request);
$fewoBookingRequest = $form->getData();
$fromDateTime = new \DateTime($fromDate);
$fewoBookingRequest->setFromDate($fromDateTime);
$fewoBookingRequest->setLodging($lodging);
}
if ($request->getMethod() == 'POST' && $form->isValid())
{
$reservation->setFromDate($fewoBookingRequest->getFromDate());
$reservation->setToDate($fewoBookingRequest->getToDate());
$reservation->setStatus(0); // 0 = belegt; 1 = nicht verfügbar
$reservation->setType(0); // 0 = Buchung; 1 = Händisch
$reservation->setLodging($lodging);
$em->persist($reservation);
$em->flush();
$crmBookingUrl = $this->get('app.fewo_booking_exporter')->process($fewoBookingRequest, $lodging, $price);//, $travelDate, $bookingPriceInfo);
$crmBookingUrl = preg_replace('/\\/api/', '', $crmBookingUrl) .'/edit';
$this->get('mailer')->send(\Swift_Message::newInstance()
->setSubject('Ihr FeWo-Buchungsauftrag bei STERN TOURS')
->setFrom('stern@stern-tours.de', 'STERN TOURS')
->setTo($fewoBookingRequest->getEmail())
->setBody(
$this->renderView('default/email/fewoBookingConfirmationEmail.txt.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
'fewo_booking_request' => $fewoBookingRequest,
//'booking_price_info' => $bookingPriceInfo,
//'travel_date' => $travelDate,
//'breadcrumb_entries' => $breadcrumbEntries,
]),
'text/plain', 'utf-8'
)
);
$this->get('mailer')->send(\Swift_Message::newInstance()
->setSubject('FEWO-BUCHUNG: '. $lodging->getName())//$travelProgram->getTitle() .'('. $travelDate->getName() .')') //TODO !!! allein hierfür braucht man mehr infos in $fewoBookingRequest
->setFrom('stern@stern-tours.de', 'STERN TOURS')
->setTo('stern@stern-tours.de')
->setBody(
$this->renderView('default/email/fewoBookingServiceEmail.txt.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
'crm_url' => $crmBookingUrl,
//'travel_program_url' => Util::getBaseUrl() . $travelProgramPage->getUrlPath(),
'fewo_booking_request' => $fewoBookingRequest,
//'booking_price_info' => $bookingPriceInfo,
//'travel_date' => $travelDate,
//'breadcrumb_entries' => $breadcrumbEntries,
]),
'text/plain', 'utf-8'
)
);
return $this->redirect('/admin/fewo/lodgings/'.$lodgingId.'/program');
}
// -------------------------------------------------------------------------------------------
return $this->render('default/admin/fewoBooking.html.twig', [
'form' => $form->createView(),
'lodging' => $lodging,
'fromDate' => $fromDate,
'toDate' => $toDate
]);
}
/**
* @Route("/admin/fewo/lodgings/{lodgingId}/prices/new", requirements={"lodgingId": "\d+"})
*/
public function adminFewoNewPriceAction(Request $request, $lodgingId)
{
$em = $this->getEntityManager();
$fewoLodgingRepo = $em->getRepository('AppBundle:FewoLodging');
$lodging = $fewoLodgingRepo->find($lodgingId);
$price = null;
if ($request->getMethod() != 'POST')
{
$price = new FewoPrice();
}
$this->setChoosableSeasons($lodging);
$form = $this->createForm(FewoPriceType::class, $price, [
'lodging' => $lodging
]);
if ($request->getMethod() == 'POST')
{
$form->handleRequest($request);
$price = $form->getData();
}
if ($request->getMethod() == 'POST' && $form->isValid())
{
if($price == null)
{
return $this->redirect('/admin/fewo/lodgings/'.$lodgingId);
}
$price->setLodging($lodging);
$em->persist($price);
$em->flush();
return $this->redirect('/admin/fewo/lodgings/'.$lodgingId);
}
return $this->render('default/admin/pricesNew.html.twig', [
'form' => $form->createView(),
'lodging' => $lodging,
]);
}
/**
* @Route("/admin/fewo/lodgings/{lodgingId}/prices/{priceId}", requirements={"lodgingId": "\d+", "priceId": "\d+"})
*/
public function adminFewoEditPriceAction(Request $request, $lodgingId, $priceId)
{
$em = $this->getEntityManager();
$fewoLodgingRepo = $em->getRepository('AppBundle:FewoLodging');
$fewoPriceRepo = $em->getRepository('AppBundle:FewoPrice');
$lodging = $fewoLodgingRepo->find($lodgingId);
$price = $fewoPriceRepo->find($priceId);
$choosableSeason[] = $price->getSeason();
$lodging->setChoosableSeasons($choosableSeason);
$form = $this->createForm(FewoPriceType::class, $price, [
'lodging' => $lodging
]);
if ($request->getMethod() == 'POST')
{
$form->handleRequest($request);
}
if ($request->getMethod() == 'POST' && $form->isValid())
{
if($price == null)
{
return $this->redirect('/admin/fewo/lodgings/'.$lodgingId);
}
$em->flush();
return $this->redirect('/admin/fewo/lodgings/'.$lodgingId);
}
return $this->render('default/admin/pricesEdit.html.twig', [
'form' => $form->createView(),
'lodging' => $lodging,
]);
}
/**
* @Route("/admin/fewo/lodgings/{lodgingId}/prices/{priceId}/delete", requirements={"lodgingId": "\d+", "priceId": "\d+"})
*/
public function adminFewoDeletePriceAction(Request $request, $lodgingId, $priceId)
{
$em = $this->getEntityManager();
$fewoPriceRepo = $em->getRepository('AppBundle:FewoPrice');
$fewoLodgingRepo = $em->getRepository('AppBundle:FewoLodging');
$lodging = $fewoLodgingRepo->find($lodgingId);
$price = $fewoPriceRepo->find($priceId);
if($price != null)
{
$em->remove($price);
$em->flush();
}
return $this->redirect('/admin/fewo/lodgings/'.$lodgingId);
}
/**
* @Route("/admin/fewo/lodgings/{lodgingId}/reservations/new", requirements={"lodgingId": "\d+"})
*/
public function adminFewoNewReservationAction(Request $request, $lodgingId)
{
$em = $this->getEntityManager();
$fewoLodgingRepo = $em->getRepository('AppBundle:FewoLodging');
$lodging = $fewoLodgingRepo->find($lodgingId);
$reservation = null;
if ($request->getMethod() != 'POST')
{
$reservation = new FewoReservation();
}
$form = $this->createForm(FewoReservationType::class, $reservation, [
'lodging' => $lodging
]);
if ($request->getMethod() == 'POST')
{
$form->handleRequest($request);
$reservation = $form->getData();
}
if ($request->getMethod() == 'POST' && $form->isValid())
{
if($reservation == null)
{
return $this->redirect('/admin/fewo/lodgings/'.$lodgingId);
}
$reservation->setLodging($lodging);
$em->persist($reservation);
$em->flush();
return $this->redirect('/admin/fewo/lodgings/'.$lodgingId);
}
return $this->render('default/admin/reservationsNew.html.twig', [
'form' => $form->createView(),
'lodging' => $lodging,
]);
}
private function addDaysToDate($date, $days)
{
$result = date('dd-mm-yyyy', strtotime($date." + ".$days." days"));
return $result;
}
private function convertDate($date)
{
$result = substr($date, 0, 2).'.'.substr($date, 2, 2).'.'.substr($date, 4, 4);
return $result;
}
/**
* @Route("/admin/fewo/lodgings/{lodgingId}/reservations/new/{fromDate}", requirements={"lodgingId": "\d+", "fromDate": "\w+"})
*/
public function adminFewoNewReservationWithStartingDayAction(Request $request, $lodgingId, $fromDate)
{
//todo price -> season
//todo season.minimumStay
$em = $this->getEntityManager();
$fewoLodgingRepo = $em->getRepository('AppBundle:FewoLodging');
$lodging = $fewoLodgingRepo->find($lodgingId);
$fromDate = $this->convertDate($fromDate);
$reservation = null;
if ($request->getMethod() != 'POST')
{
$reservation = new FewoReservation();
}
$form = $this->createForm(FewoReservationType::class, $reservation, [
'lodging' => $lodging,
'fromDate' => $fromDate
]);
if ($request->getMethod() == 'POST')
{
$form->handleRequest($request);
$reservation = $form->getData();
}
if ($request->getMethod() == 'POST' && $form->isValid())
{
if($reservation == null)
{
return $this->redirect('/admin/fewo/lodgings/'.$lodgingId);
}
$reservation->setLodging($lodging);
$em->persist($reservation);
$em->flush();
return $this->redirect('/admin/fewo/lodgings/'.$lodgingId);
}
return $this->render('default/admin/reservationsNew.html.twig', [
'form' => $form->createView(),
'lodging' => $lodging,
]);
}
/**
* @Route("/admin/fewo/lodgings/{lodgingId}/reservations/{reservationId}", requirements={"lodgingId": "\d+", "reservationId": "\d+"})
*/
public function adminFewoEditReservationAction(Request $request, $lodgingId, $reservationId)
{
$em = $this->getEntityManager();
$fewoLodgingRepo = $em->getRepository('AppBundle:FewoLodging');
$fewoReservationRepo = $em->getRepository('AppBundle:FewoReservation');
$lodging = $fewoLodgingRepo->find($lodgingId);
$reservation = $fewoReservationRepo->find($reservationId);
$fromDate = $reservation->getFromDate()->format('d.m.Y');
$form = $this->createForm(FewoReservationType::class, $reservation, [
'lodging' => $lodging,
'fromDate' => $fromDate,
]);
if ($request->getMethod() == 'POST')
{
$form->handleRequest($request);
}
if ($request->getMethod() == 'POST' && $form->isValid())
{
$em->flush();
return $this->redirect('/admin/fewo/lodgings/'.$lodgingId);
}
return $this->render('default/admin/reservationsEdit.html.twig', [
'form' => $form->createView(),
'lodging' => $lodging,
'reservationId' => $reservationId
]);
}
/**
* @Route("/admin/fewo/lodgings/{lodgingId}/reservations/{reservationId}/delete", requirements={"lodgingId": "\d+", "reservationId": "\d+"})
*/
public function adminFewoDeleteReservationAction(Request $request, $lodgingId, $reservationId)
{
$em = $this->getEntityManager();
$fewoLodgingRepo = $em->getRepository('AppBundle:FewoLodging');
$fewoReservationRepo = $em->getRepository('AppBundle:FewoReservation');
$lodging = $fewoLodgingRepo->find($lodgingId);
$reservation = $fewoReservationRepo->find($reservationId);
if($reservation != null)
{
$em->remove($reservation);
$em->flush();
}
return $this->redirect('/admin/fewo/lodgings/'.$lodgingId);
}
/**
* @Route("/admin/fewo/seasons")
*/
public function adminFewoSeasonsAction(Request $request)
{
$fewoSeasonRepo = $this->getEntityManager()->getRepository('AppBundle:FewoSeason');
$seasons = $fewoSeasonRepo->findAll();
return $this->render('default/admin/seasons.html.twig', [
'seasons' => $seasons,
]);
}
/**
* @Route("/admin/fewo/seasons/new")
*/
public function adminFewoNewSeasonAction(Request $request)
{
$em = $this->getEntityManager();
$season = null;
if ($request->getMethod() != 'POST')
{
$season = new FewoSeason();
}
$form = $this->createForm(FewoSeasonType::class, $season, [
]);
if ($request->getMethod() == 'POST')
{
$form->handleRequest($request);
$season = $form->getData();
}
if ($request->getMethod() == 'POST' && $form->isValid())
{
if($season == null)
{
return $this->redirect('/admin/fewo/seasons');
}
$em->persist($season);
$em->flush();
return $this->redirect('/admin/fewo/seasons');
}
return $this->render('default/admin/seasonsNew.html.twig', [
'form' => $form->createView(),
'season' => $season,
]);
}
/**
* @Route("/admin/fewo/seasons/{seasonId}", requirements={"seasonId": "\d+"})
*/
public function adminFewoEditSeasonAction(Request $request, $seasonId)
{
$em = $this->getEntityManager();
$fewoSeasonsRepo = $em->getRepository('AppBundle:FewoSeason');
$season = null;
$season = $fewoSeasonsRepo->find($seasonId);
$form = $this->createForm(FewoSeasonType::class, $season, [
//options
]);
if($request->getMethod() == 'POST')
{
$form->handleRequest($request);
}
if ($request->getMethod() == 'POST' && $form->isValid())
{
$em->flush();
return $this->redirect('/admin/fewo/seasons');
}
return $this->render('default/admin/seasonsEdit.html.twig', [
'form' => $form->createView(),
'season' => $season,
]);
}
/**
* @Route("/admin/fewo/seasons/{seasonId}/delete", requirements={"seasonId": "\d+"})
*/
public function adminFewoDeleteSeasonAction(Request $request, $seasonId)
{
$em = $this->getEntityManager();
$fewoSeasonRepo = $em->getRepository('AppBundle:FewoSeason');
$season = $fewoSeasonRepo->find($seasonId);
if($season != null)
{
$em->remove($season);
$em->flush();
}
return $this->redirect('/admin/fewo/seasons');
}
/**
* @Route("/admin/fewo/lodgings/{lodgingId}/images/new", requirements={"lodgingId": "\d+"})
*/
public function adminFewoNewImageAction(Request $request, $lodgingId)
{
$em = $this->getEntityManager();
$fewoLodgingRepo = $em->getRepository('AppBundle:FewoLodging');
$lodging = $fewoLodgingRepo->find($lodgingId);
$image = null;
if ($request->getMethod() != 'POST')
{
$image = new FewoLodgingImage();
}
$form = $this->createForm(FewoLodgingImageType::class, $image, [
]);
if ($request->getMethod() == 'POST')
{
$form->handleRequest($request);
$image = $form->getData();
}
if ($request->getMethod() == 'POST' && $form->isValid())
{
if($lodging == null)
{
return $this->redirect('/admin/fewo/lodgings');
}
$image->setLodging($lodging);
$em->persist($image);
$em->flush();
return $this->redirect('/admin/fewo/lodgings/'.$lodgingId);
}
return $this->render('default/admin/imagesNew.html.twig', [
'form' => $form->createView(),
'lodging' => $lodging,
]);
}
/**
* @Route("/admin/fewo/lodgings/{lodgingId}/images/{imageId}/delete", requirements={"lodgingId": "\d+", "imageId": "\d+"})
*/
public function adminFewoDeleteImageAction(Request $request, $lodgingId, $imageId)
{
$em = $this->getEntityManager();
$fewoLodgingImageRepo = $em->getRepository('AppBundle:FewoLodgingImage');
$image = $fewoLodgingImageRepo->find($imageId);
if($image != null)
{
$em->remove($image);
$em->flush();
}
return $this->redirect('/admin/fewo/lodgings/'.$lodgingId);
}
}

View file

@ -123,6 +123,29 @@ class CmsController extends Controller
]);
}
public function fewoLodgingAction(Page $page)
{
//$calendarUtil = new Util\LodgingCalendarUtil();
$calendarUtil = $this->container->get('app.lodging_calendar_util');
//$fewoLodgingRepo = $this->getEntityManager()->getRepository('AppBundle:FewoLodging');
$lodging = $page->getFewoLodging();
$paddedCalendar = $calendarUtil->getCalendarWithPadding();
$calendar = $calendarUtil->getCalendar();
$calendar = $calendarUtil->markCalendarDaysWithReservations($lodging, $calendar);
$calendar = $calendarUtil->mergeWithPaddedCalendar($calendar, $paddedCalendar);
return $this->render('default/pages/cms/fewoTravelProgram.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
'page' => $page,
'fewo_lodging' => $lodging,
//'lodging' => $lodging, //so wurde es im AdminController aufgerufen
'calendar' => $calendar
]);
}
public function pdfAction(Page $page)
{
$travelProgram = $page->getTravelProgram();

View file

@ -0,0 +1,251 @@
<?php
namespace AppBundle\Controller;
//TODO bereinigen
use AppBundle\Entity\BookingRequest;
use AppBundle\Entity\BreadcrumbEntry;
use AppBundle\Entity\FewoLodging;
use AppBundle\Entity\FewoPrice;
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 AppBundle\Entity\FewoSeason;
use AppBundle\Entity\FewoBookingRequest;
use AppBundle\Form\FewoBookingRequestType;
use AppBundle\Entity\FewoReservation;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class FewoBookingController extends Controller
{
public function getEntityManager()
{
return $this->getDoctrine()->getManager();
}
/**
* The routing for this action is entirely controlled by KernelControllerListener!
*
* @param Page $fewoTravelProgramPage
* @param Request $request
* @param $action
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
* @throws \Exception
*/
public function indexAction(Page $fewoTravelProgramPage, $action, Request $request)
{
//$calendarUtils = new Util\LodgingCalendarUtil();
$calendarUtil = $this->container->get('app.lodging_calendar_util');
$em = $this->getEntityManager();
//$fewoLodgingRepo = $em->getRepository('AppBundle:FewoLodging');
$fewoPriceRepo = $em->getRepository('AppBundle:FewoPrice');
if (!$request->query->has('pnr') || !$request->query->has('fd'))
{
return $this->redirect($fewoTravelProgramPage->getUrlPath());
}
$priceId = $request->query->get('pnr');
$fromDate = $request->query->get('fd');
$lodging = $fewoTravelProgramPage->getFewoLodging();
/** @var FewoPrice $price */
$price = $fewoPriceRepo->find($priceId);
/** @var FewoSeason $season */
$season = $price->getSeason();
$minimumStay = $season->getMinimumStay();
$fromDate = $calendarUtil->convertDate($fromDate);
$fromDateTime = new \DateTime($fromDate);
$toDate = '';
$maxPersons = $lodging->getMaximumPersons();
$fewoBookingRequest = new FewoBookingRequest();
$reservation = new FewoReservation();
$fewoBookingRequest->setFromDate($fromDateTime);
//$fewoBookingRequest->setToDate($toDate);
$fewoBookingRequest->setNumberDays($minimumStay);
$fewoBookingRequest->setLodging($lodging);
$fewoBookingRequest->setPrice($price);
if ($request->getMethod() != 'POST')
{
$dateAppendix = " + ".($minimumStay - 1)." day";
if($minimumStay > 1)
{
$dateAppendix= $dateAppendix."s";
}
$toDate = date('d.m.Y', strtotime($fromDate.$dateAppendix));
$fewoBookingRequest->setFromDate($fromDate);
$fewoBookingRequest->setToDate($toDate);
$fewoBookingRequest->setNumberDays($minimumStay);
$fewoBookingRequest->setLodging($lodging);
$fewoBookingRequest->setPrice($price);
}
$form = $this->createForm(FewoBookingRequestType::class, $fewoBookingRequest, [
'lodging' => $lodging,
'maxPersons' => $maxPersons,
'toDate' => $toDate
]);
if ($request->getMethod() == 'POST')
{
$form->handleRequest($request);
/** @var FewoBookingRequest $fewoBookingRequest */
$fewoBookingRequest = $form->getData();
$fewoBookingRequest->setFromDate($fromDateTime);
$finalFromDate = $fewoBookingRequest->getFromDate();
$finalToDate = $fewoBookingRequest->getToDate();
$timeDiff = date_diff($finalFromDate, $finalToDate);
$numberDays = $timeDiff->days + 1;
$fewoBookingRequest->setNumberDays($numberDays);
$fewoBookingRequest->setLodging($lodging);
$fewoBookingRequest->setPrice($price);
}
$totalPrice = $this->calculatePrice($fewoBookingRequest, $lodging, $price);
$perDayTotalPrice = $this->calculatePerDayTotalPrice($fewoBookingRequest, $price);
$fewoBookingRequest->setTotalPrice($totalPrice);
if($action == '/fewo-buchen')
{
if ($request->getMethod() == 'POST' && $form->isValid())
{
$reservation->setFromDate($fewoBookingRequest->getFromDate());
$reservation->setToDate($fewoBookingRequest->getToDate());
$reservation->setStatus(0); // 0 = belegt; 1 = nicht verfügbar
$reservation->setType(0); // 0 = Buchung; 1 = Händisch
$reservation->setLodging($lodging);
$em->persist($reservation);
$em->flush();
$crmBookingUrl = $this->get('app.fewo_booking_exporter')->process($fewoBookingRequest, $lodging, $price);//, $travelDate, $bookingPriceInfo);
$crmBookingUrl = preg_replace('/\\/api/', '', $crmBookingUrl) . '/edit';
$this->get('mailer')->send(\Swift_Message::newInstance()
->setSubject('Ihr FeWo-Buchungsauftrag bei STERN TOURS')
->setFrom('stern@stern-tours.de', 'STERN TOURS')
->setTo($fewoBookingRequest->getEmail())
->setBody(
$this->renderView('default/email/fewoBookingConfirmationEmail.txt.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir') . '/..') . DIRECTORY_SEPARATOR,
'fewo_booking_request' => $fewoBookingRequest,
'fewo_lodging' => $lodging,
'fewo_price' => $price,
//'booking_price_info' => $bookingPriceInfo,
//'travel_date' => $travelDate,
//'breadcrumb_entries' => $breadcrumbEntries,
]),
'text/plain', 'utf-8'
)
);
$this->get('mailer')->send(\Swift_Message::newInstance()
->setSubject('FEWO-BUCHUNG: ' . $lodging->getName())
->setFrom('stern@stern-tours.de', 'STERN TOURS')
->setTo('stern@stern-tours.de')
->setBody(
$this->renderView('default/email/fewoBookingServiceEmail.txt.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir') . '/..') . DIRECTORY_SEPARATOR,
'crm_url' => $crmBookingUrl,
'lodging_url' => Util::getBaseUrl() . $fewoTravelProgramPage->getUrlPath(),
'fewo_booking_request' => $fewoBookingRequest,
'fewo_lodging' => $lodging,
'fewo_price' => $price,
//'booking_price_info' => $bookingPriceInfo,
//'travel_date' => $travelDate,
//'breadcrumb_entries' => $breadcrumbEntries,
]),
'text/plain', 'utf-8'
)
);
return $this->render('default/pages/fewoBookingConfirmation.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
'page' => $fewoTravelProgramPage,
'fewo_booking_request' => $fewoBookingRequest,
'fewo_lodging' => $lodging,
'fewo_price' => $price,
'total_price' => $totalPrice,
'total_price_per_night' => $perDayTotalPrice,
]);
}
return $this->render('default/pages/fewoBooking.html.twig', [
'form' => $form->createView(),
'fewo_booking_request' => $fewoBookingRequest,
'lodging' => $lodging,
'fromDate' => $fromDate,
'toDate' => $toDate,
'fewo_lodging' => $lodging,
'fewo_price' => $price,
'total_price' => $totalPrice,
'total_price_per_night' => $perDayTotalPrice,
]);
}
elseif($action == '/fewo-berechne-gesamtpreis')
{
return $this->render('default/components/booking/fewoSummary.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
'fewo_booking_request' => $fewoBookingRequest,
'fewo_lodging' => $lodging,
'fewo_price' => $price,
'total_price' => $totalPrice,
'total_price_per_night' => $perDayTotalPrice,
]);
}
throw new \Exception('Unknow FewoBookingController action: '. $action);
}
public function calculatePrice(FewoBookingRequest $fewoBookingRequest, FewoLodging $fewoLodging, FewoPrice $fewoPrice)
{
$result = $fewoLodging->getDeposit();
$result = $result + $fewoPrice->getFlatPrice();
for($i = 0; $i < $fewoBookingRequest->getNumberDays(); $i++)
{
$result = $result + $fewoPrice->getPerNight();
}
return $result;
}
public function calculatePerDayTotalPrice(FewoBookingRequest $fewoBookingRequest, FewoPrice $fewoPrice)
{
$result = 0;
for($i = 0; $i < $fewoBookingRequest->getNumberDays(); $i++)
{
$result = $result + $fewoPrice->getPerNight();
}
return $result;
}
}

View file

@ -0,0 +1,428 @@
<?php
/**
* @author Ulrich Hecht <ulrich.hecht@hecht-software.de>
* @date 12/16/2016
*/
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
use AppBundle\Validator\Constraints as AppBundleAssert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
//TODO im folgenden fehlt noch die Validierung
/**
* Class BookingRequest
* @package AppBundle\Entity
* @AppBundleAssert\FewoBookingRequest
*/
class FewoBookingRequest
{
// Used in SternToursCrmBookingExports, expected to be equivalent to sex (as defined in Traveler)
const MR = 1;
const MRS = 2;
/**
* @Assert\DateTime()
*/
private $fromDate;
/**
* @Assert\DateTime()
*/
private $toDate;
private $numberDays;
private $totalPrice;
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;
private $notes;
private $travelerCount;
private $acceptTerms = false;
private $lodging;
private $season;
private $price;
/**
* BookingRequest constructor.
*/
public function __construct()
{
}
/**
* @return mixed
*/
public function getFromDate()
{
return $this->fromDate;
}
/**
* @param mixed $fromDate
*/
public function setFromDate($fromDate)
{
$this->fromDate = $fromDate;
}
/**
* @return mixed
*/
public function getToDate()
{
return $this->toDate;
}
/**
* @param mixed $toDate
*/
public function setToDate($toDate)
{
$this->toDate = $toDate;
}
/**
* @return mixed
*/
public function getSalutation()
{
return $this->salutation;
}
/**
* @param mixed $salutation
*/
public function setSalutation($salutation)
{
$this->salutation = $salutation;
}
/**
* @return mixed
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* @param mixed $firstName
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
}
/**
* @return mixed
*/
public function getLastName()
{
return $this->lastName;
}
/**
* @param mixed $lastName
*/
public function setLastName($lastName)
{
$this->lastName = $lastName;
}
/**
* @return mixed
*/
public function getStreetAddress()
{
return $this->streetAddress;
}
/**
* @param mixed $streetAddress
*/
public function setStreetAddress($streetAddress)
{
$this->streetAddress = $streetAddress;
}
/**
* @return mixed
*/
public function getZipCode()
{
return $this->zipCode;
}
/**
* @param mixed $zipCode
*/
public function setZipCode($zipCode)
{
$this->zipCode = $zipCode;
}
/**
* @return mixed
*/
public function getCity()
{
return $this->city;
}
/**
* @param mixed $city
*/
public function setCity($city)
{
$this->city = $city;
}
/**
* @return mixed
*/
public function getNation()
{
return $this->nation;
}
/**
* @param mixed $nation
*/
public function setNation($nation)
{
$this->nation = $nation;
}
/**
* @return mixed
*/
public function getPhone()
{
return $this->phone;
}
/**
* @param mixed $phone
*/
public function setPhone($phone)
{
$this->phone = $phone;
}
/**
* @return mixed
*/
public function getFax()
{
return $this->fax;
}
/**
* @param mixed $fax
*/
public function setFax($fax)
{
$this->fax = $fax;
}
/**
* @return mixed
*/
public function getEmail()
{
return $this->email;
}
/**
* @param mixed $email
*/
public function setEmail($email)
{
$this->email = $email;
}
/**
* @return mixed
*/
public function getNotes()
{
return $this->notes;
}
/**
* @param mixed $notes
*/
public function setNotes($notes)
{
$this->notes = $notes;
}
/**
* @return mixed
*/
public function getTravelerCount()
{
return $this->travelerCount;
}
/**
* @param mixed $travelerCount
*/
public function setTravelerCount($travelerCount)
{
$this->travelerCount = $travelerCount;
}
/**
* @return mixed
*/
public function getAcceptTerms()
{
return $this->acceptTerms;
}
/**
* @param mixed $acceptTerms
*/
public function setAcceptTerms($acceptTerms)
{
$this->acceptTerms = $acceptTerms;
}
/**
* @return mixed
*/
public function getNumberDays()
{
return $this->numberDays;
}
/**
* @param mixed $numberDays
*/
public function setNumberDays($numberDays)
{
$this->numberDays = $numberDays;
}
/**
* @return mixed
*/
public function getTotalPrice()
{
return $this->totalPrice;
}
/**
* @param mixed $totalPrice
*/
public function setTotalPrice($totalPrice)
{
$this->totalPrice = $totalPrice;
}
/**
* @return FewoLodging
*/
public function getLodging()
{
return $this->lodging;
}
/**
* @param FewoLodging $lodging
*/
public function setLodging($lodging)
{
$this->lodging = $lodging;
}
/**
* @return FewoSeason
*/
public function getSeason()
{
return $this->season;
}
/**
* @param FewoSeason $season
*/
public function setSeason($season)
{
$this->season = $season;
}
/**
* @return FewoPrice
*/
public function getPrice()
{
return $this->price;
}
/**
* @param FewoPrice $price
*/
public function setPrice($price)
{
$this->price = $price;
}
/**
* @Assert\Callback
*/
public function validate(ExecutionContextInterface $context, $payload)
{
//$context->
}
}

View file

@ -0,0 +1,619 @@
<?php
namespace AppBundle\Entity;
use AppBundle\AppBundle;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table
* @ORM\Entity(repositoryClass="AppBundle\Entity\FewoLodgingRepository")
*/
class FewoLodging
{
//------------------------------------------------------------------------------------------------------------------
// Allgemein
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* @var \AppBundle\Entity\FewoLodgingType
*
* @ORM\ManyToOne(targetEntity="FewoLodgingType")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="type_id", referencedColumnName="id")
* })
*/
private $type;
/**
* @var text
*
* @ORM\Column(name="description", type="text", nullable=false)
*/
private $description;
/**
* @var text
*
* @ORM\Column(name="equipment", type="text", nullable=false)
*/
private $equipment;
//------------------------------------------------------------------------------------------------------------------
// Adresse
/**
* @var string
*
* @ORM\Column(name="adress1", type="string", length=255, nullable=false)
*/
private $adress1;
/**
* @var string
*
* @ORM\Column(name="adress2", type="string", length=255, nullable=true)
*/
private $adress2;
/**
* @var string
*
* @ORM\Column(name="zip_code", type="string", length=255, nullable=false)
*/
private $zipCode;
/**
* @var string
*
* @ORM\Column(name="city", type="string", length=255, nullable=false)
*/
private $city;
//------------------------------------------------------------------------------------------------------------------
// Preise
/**
* @var integer
*
* @ORM\Column(name="maximum_persons", type="integer", nullable=false)
*/
private $maximumPersons;
/**
* @var float
*
* @ORM\Column(name="deposit", type="float", scale=2, nullable=false)
*/
private $deposit;
/**
* @var \AppBundle\Entity\FewoPrice
*
* @ORM\OneToMany(targetEntity="FewoPrice", mappedBy="lodging", cascade={"persist", "remove"})
*/
private $prices;
//------------------------------------------------------------------------------------------------------------------
// Bilder
/**
* @ORM\OneToMany(targetEntity="FewoLodgingImage", mappedBy="lodging", cascade={"persist", "remove"})
*/
private $images;
//------------------------------------------------------------------------------------------------------------------
// Kalender
/**
* @var integer
*
* @ORM\Column(name="only_weekday", type="integer", nullable=false)
*/
private $onlyWeekday;
/**
* @var \AppBundle\Entity\FewoReservation
*
* @ORM\OneToMany(targetEntity="FewoReservation", mappedBy="lodging", cascade={"persist", "remove"})
*/
private $reservations;
/**
* @var boolean
*
* @ORM\Column(name="calendar_visible", type="boolean", nullable=false)
*/
private $calendarVisible;
private $choosableSeasons;
/**
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Page", mappedBy="fewoLodging")
*/
private $page;
public function getChoosableSeasons()
{
return $this->choosableSeasons;
}
public function setChoosableSeasons($choosableSeasons)
{
$this->choosableSeasons = $choosableSeasons;
}
public function getSeasons()
{
$prices = $this->getPrices();
$seasons = null;
for($i = 0; $i < count($prices); $i++)
{
$seasons[] = $prices->get($i)->getSeason();
}
return $seasons;
}
/**
* Constructor
*/
public function __construct()
{
$this->prices = new \Doctrine\Common\Collections\ArrayCollection();
$this->images = new \Doctrine\Common\Collections\ArrayCollection();
$this->reservations = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return FewoLodging
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set description
*
* @param string $description
*
* @return FewoLodging
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set equipment
*
* @param string $equipment
*
* @return FewoLodging
*/
public function setEquipment($equipment)
{
$this->equipment = $equipment;
return $this;
}
/**
* Get equipment
*
* @return string
*/
public function getEquipment()
{
return $this->equipment;
}
/**
* Set adress1
*
* @param string $adress1
*
* @return FewoLodging
*/
public function setAdress1($adress1)
{
$this->adress1 = $adress1;
return $this;
}
/**
* Get adress1
*
* @return string
*/
public function getAdress1()
{
return $this->adress1;
}
/**
* Set adress2
*
* @param string $adress2
*
* @return FewoLodging
*/
public function setAdress2($adress2)
{
$this->adress2 = $adress2;
return $this;
}
/**
* Get adress2
*
* @return string
*/
public function getAdress2()
{
return $this->adress2;
}
/**
* Set zipCode
*
* @param string $zipCode
*
* @return FewoLodging
*/
public function setZipCode($zipCode)
{
$this->zipCode = $zipCode;
return $this;
}
/**
* Get zipCode
*
* @return string
*/
public function getZipCode()
{
return $this->zipCode;
}
/**
* Set city
*
* @param string $city
*
* @return FewoLodging
*/
public function setCity($city)
{
$this->city = $city;
return $this;
}
/**
* Get city
*
* @return string
*/
public function getCity()
{
return $this->city;
}
/**
* Set maximumPersons
*
* @param integer $maximumPersons
*
* @return FewoLodging
*/
public function setMaximumPersons($maximumPersons)
{
$this->maximumPersons = $maximumPersons;
return $this;
}
/**
* Get maximumPersons
*
* @return integer
*/
public function getMaximumPersons()
{
return $this->maximumPersons;
}
/**
* Set deposit
*
* @param float $deposit
*
* @return FewoLodging
*/
public function setDeposit($deposit)
{
$this->deposit = $deposit;
return $this;
}
/**
* Get deposit
*
* @return float
*/
public function getDeposit()
{
return $this->deposit;
}
/**
* Set onlyWeekday
*
* @param integer $onlyWeekday
*
* @return FewoLodging
*/
public function setOnlyWeekday($onlyWeekday)
{
$this->onlyWeekday = $onlyWeekday;
return $this;
}
/**
* Get onlyWeekday
*
* @return integer
*/
public function getOnlyWeekday()
{
return $this->onlyWeekday;
}
/**
* Set calendarVisible
*
* @param boolean $calendarVisible
*
* @return FewoLodging
*/
public function setCalendarVisible($calendarVisible)
{
$this->calendarVisible = $calendarVisible;
return $this;
}
/**
* Get calendarVisible
*
* @return boolean
*/
public function getCalendarVisible()
{
return $this->calendarVisible;
}
/**
* Set type
*
* @param \AppBundle\Entity\FewoLodgingType $type
*
* @return FewoLodging
*/
public function setType(\AppBundle\Entity\FewoLodgingType $type = null)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* @return \AppBundle\Entity\FewoLodgingType
*/
public function getType()
{
return $this->type;
}
/**
* Add price
*
* @param \AppBundle\Entity\FewoPrice $price
*
* @return FewoLodging
*/
public function addPrice(\AppBundle\Entity\FewoPrice $price)
{
$this->prices[] = $price;
return $this;
}
/**
* Remove price
*
* @param \AppBundle\Entity\FewoPrice $price
*/
public function removePrice(\AppBundle\Entity\FewoPrice $price)
{
$this->prices->removeElement($price);
}
/**
* Get prices
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getPrices()
{
return $this->prices;
}
/**
* Add image
*
* @param \AppBundle\Entity\FewoLodgingImage $image
*
* @return FewoLodging
*/
public function addImage(\AppBundle\Entity\FewoLodgingImage $image)
{
$this->images[] = $image;
return $this;
}
/**
* Remove image
*
* @param \AppBundle\Entity\FewoLodgingImage $image
*/
public function removeImage(\AppBundle\Entity\FewoLodgingImage $image)
{
$this->images->removeElement($image);
}
/**
* Get images
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getImages()
{
return $this->images;
}
/**
* Add reservation
*
* @param \AppBundle\Entity\FewoReservation $reservation
*
* @return FewoLodging
*/
public function addReservation(\AppBundle\Entity\FewoReservation $reservation)
{
$this->reservations[] = $reservation;
return $this;
}
/**
* Remove reservation
*
* @param \AppBundle\Entity\FewoReservation $reservation
*/
public function removeReservation(\AppBundle\Entity\FewoReservation $reservation)
{
$this->reservations->removeElement($reservation);
}
/**
* Get reservations
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getReservations()
{
return $this->reservations;
}
/**
* Set page
*
* @param \AppBundle\Entity\Page $page
*
* @return FewoLodging
*/
public function setPage(\AppBundle\Entity\Page $page = null)
{
$this->page = $page;
return $this;
}
/**
* Get page
*
* @return \AppBundle\Entity\Page
*/
public function getPage()
{
return $this->page;
}
function __toString()
{
return $this->name;
}
}

View file

@ -0,0 +1,167 @@
<?php
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table
* @ORM\Entity
*/
class FewoLodgingImage
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="full_file_name", type="string", length=255, nullable=false)
* @Assert\Image(maxSize="6000000", mimeTypes={"image/jpeg", "image/png"})
*/
private $file;
/**
* @var string
*
* @ORM\Column(name="file_name", type="string", length=255, nullable=false)
* @Assert\NotBlank
*/
private $fileName;
/**
* @var string
*
* @ORM\Column(name="description", type="string", length=255, nullable=true)
*/
private $description;
/**
* @var \AppBundle\Entity\FewoLodging
*
* @ORM\ManyToOne(targetEntity="FewoLodging", inversedBy="images")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="lodging_id", referencedColumnName="id", onDelete="SET NULL")
* })
*/
private $lodging;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set file
*
* @param string $file
*
* @return FewoLodgingImage
*/
public function setFile($file)
{
$this->file = $file;
return $this;
}
/**
* Get file
*
* @return string
*/
public function getFile()
{
return $this->file;
}
/**
* Set description
*
* @param string $description
*
* @return FewoLodgingImage
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set lodging
*
* @param \AppBundle\Entity\FewoLodging $lodging
*
* @return FewoLodgingImage
*/
public function setLodging(\AppBundle\Entity\FewoLodging $lodging = null)
{
$this->lodging = $lodging;
return $this;
}
/**
* Get lodging
*
* @return \AppBundle\Entity\FewoLodging
*/
public function getLodging()
{
return $this->lodging;
}
function __toString()
{
return $this->file;
}
/**
* Set fileName
*
* @param string $fileName
*
* @return FewoLodgingImage
*/
public function setFileName($fileName)
{
$this->fileName = $fileName;
return $this;
}
/**
* Get fileName
*
* @return string
*/
public function getFileName()
{
return $this->fileName;
}
}

View file

@ -0,0 +1,17 @@
<?php
namespace AppBundle\Entity;
/**
* FewoLodgingRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class FewoLodgingRepository extends \Doctrine\ORM\EntityRepository
{
public function findWithChoosableSeasons($lodgingId)
{
}
}

View file

@ -0,0 +1,70 @@
<?php
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table
* @ORM\Entity
*/
class FewoLodgingType
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255, nullable=true)
*/
private $name;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return FewoLodgingType
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
function __toString()
{
return $this->name;
}
}

View file

@ -0,0 +1,163 @@
<?php
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table
* @ORM\Entity
*/
class FewoPrice
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var \AppBundle\Entity\FewoLodging
*
* @ORM\ManyToOne(targetEntity="FewoLodging", inversedBy="prices")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="lodging_id", referencedColumnName="id")
* })
*/
private $lodging;
/**
* @var \AppBundle\Entity\FewoSeason
*
* @ORM\ManyToOne(targetEntity="FewoSeason", inversedBy="prices")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="season_id", referencedColumnName="id", onDelete="SET NULL")
* })
*/
private $season;
/**
* @var float
*
* @ORM\Column(name="per_night", type="float", scale=2, nullable=false)
*/
private $perNight;
/**
* @var float
*
* @ORM\Column(name="flat_price", type="float", scale=2, nullable=false)
*/
private $flatPrice;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set perNight
*
* @param float $perNight
*
* @return FewoPrice
*/
public function setPerNight($perNight)
{
$this->perNight = $perNight;
return $this;
}
/**
* Get perNight
*
* @return float
*/
public function getPerNight()
{
return $this->perNight;
}
/**
* Set flatPrice
*
* @param float $flatPrice
*
* @return FewoPrice
*/
public function setFlatPrice($flatPrice)
{
$this->flatPrice = $flatPrice;
return $this;
}
/**
* Get flatPrice
*
* @return float
*/
public function getFlatPrice()
{
return $this->flatPrice;
}
/**
* Set lodging
*
* @param \AppBundle\Entity\FewoLodging $lodging
*
* @return FewoPrice
*/
public function setLodging(\AppBundle\Entity\FewoLodging $lodging = null)
{
$this->lodging = $lodging;
return $this;
}
/**
* Get lodging
*
* @return \AppBundle\Entity\FewoLodging
*/
public function getLodging()
{
return $this->lodging;
}
/**
* Set season
*
* @param \AppBundle\Entity\FewoSeason $season
*
* @return FewoPrice
*/
public function setSeason(\AppBundle\Entity\FewoSeason $season = null)
{
$this->season = $season;
return $this;
}
/**
* Get season
*
* @return \AppBundle\Entity\FewoSeason
*/
public function getSeason()
{
return $this->season;
}
}

View file

@ -0,0 +1,204 @@
<?php
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
use AppBundle\Validator\Constraints as AppBundleAssert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table
* @ORM\Entity
* @AppBundleAssert\FewoReservation
*/
class FewoReservation
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var \AppBundle\Entity\FewoLodging
*
* @ORM\ManyToOne(targetEntity="FewoLodging", inversedBy="reservations")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="lodging_id", referencedColumnName="id", onDelete="SET NULL")
* })
*/
private $lodging;
/**
* @var \DateTime
*
* @ORM\Column(name="from_date", type="date", nullable=false)
*/
private $fromDate;
/**
* @var \DateTime
*
* @ORM\Column(name="to_date", type="date", nullable=false)
*/
private $toDate;
// belegt, nicht verfügbar
/**
* @var integer
*
* @ORM\Column(name="status", type="integer", nullable=false)
*/
private $status;
/**
* @var integer
*
* @ORM\Column(name="type", type="integer", nullable=false)
*/
private $type;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set fromDate
*
* @param \DateTime $fromDate
*
* @return FewoReservation
*/
public function setFromDate($fromDate)
{
$this->fromDate = $fromDate;
return $this;
}
/**
* Get fromDate
*
* @return \DateTime
*/
public function getFromDate()
{
return $this->fromDate;
}
/**
* Set toDate
*
* @param \DateTime $toDate
*
* @return FewoReservation
*/
public function setToDate($toDate)
{
$this->toDate = $toDate;
return $this;
}
/**
* Get toDate
*
* @return \DateTime
*/
public function getToDate()
{
return $this->toDate;
}
/**
* Set status
*
* @param integer $status
*
* @return FewoReservation
*/
public function setStatus($status)
{
$this->status = $status;
return $this;
}
/**
* Get status
*
* @return integer
*/
public function getStatus()
{
return $this->status;
}
/**
* Set lodging
*
* @param \AppBundle\Entity\FewoLodging $lodging
*
* @return FewoReservation
*/
public function setLodging(\AppBundle\Entity\FewoLodging $lodging = null)
{
$this->lodging = $lodging;
return $this;
}
/**
* Get lodging
*
* @return \AppBundle\Entity\FewoLodging
*/
public function getLodging()
{
return $this->lodging;
}
/**
* Set type
*
* @param integer $type
*
* @return FewoReservation
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* @return integer
*/
public function getType()
{
return $this->type;
}
/**
* @Assert\Callback
*/
public function validate(ExecutionContextInterface $context, $payload)
{
//$context->
}
}

View file

@ -0,0 +1,245 @@
<?php
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints\Date;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table
* @ORM\Entity
*/
class FewoSeason
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
// es gab hier lodgings, wird aber über prices geholt
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* @var \AppBundle\Entity\FewoPrice
*
* @ORM\OneToMany(targetEntity="FewoPrice", mappedBy="season", cascade={"persist", "remove"})
*/
private $prices;
/**
* @var \DateTime
*
* @ORM\Column(name="from_date", type="date", nullable=false)
*/
private $fromDate;
/**
* @var \DateTime
*
* @ORM\Column(name="to_date", type="date", nullable=false)
*/
private $toDate;
/**
* @var integer
*
* @ORM\Column(name="minimum_stay", type="integer", nullable=false)
*/
private $minimumStay;
/**
* @var string
*
* @ORM\Column(name="description", type="text", nullable=true)
*/
private $description;
/**
* Constructor
*/
public function __construct()
{
$this->prices = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set fromDate
*
* @param \DateTime $fromDate
*
* @return FewoSeason
*/
public function setFromDate($fromDate)
{
$this->fromDate = $fromDate;
return $this;
}
/**
* Get fromDate
*
* @return \DateTime
*/
public function getFromDate()
{
return $this->fromDate;
}
/**
* Set toDate
*
* @param \DateTime $toDate
*
* @return FewoSeason
*/
public function setToDate($toDate)
{
$this->toDate = $toDate;
return $this;
}
/**
* Get toDate
*
* @return \DateTime
*/
public function getToDate()
{
return $this->toDate;
}
/**
* Set minimumStay
*
* @param integer $minimumStay
*
* @return FewoSeason
*/
public function setMinimumStay($minimumStay)
{
$this->minimumStay = $minimumStay;
return $this;
}
/**
* Get minimumStay
*
* @return integer
*/
public function getMinimumStay()
{
return $this->minimumStay;
}
/**
* Set description
*
* @param string $description
*
* @return FewoSeason
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Add price
*
* @param \AppBundle\Entity\FewoPrice $price
*
* @return FewoSeason
*/
public function addPrice(\AppBundle\Entity\FewoPrice $price)
{
$this->prices[] = $price;
return $this;
}
/**
* Remove price
*
* @param \AppBundle\Entity\FewoPrice $price
*/
public function removePrice(\AppBundle\Entity\FewoPrice $price)
{
$this->prices->removeElement($price);
}
/**
* Get prices
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getPrices()
{
return $this->prices;
}
/**
* Set name
*
* @param string $name
*
* @return FewoSeason
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
function __toString()
{
return $this->name;
}
}

View file

@ -100,10 +100,18 @@ class Page
* @var TravelProgram
*
* @ORM\OneToOne(targetEntity="AppBundle\Entity\TravelProgram", inversedBy="page")
* @ORM\JoinColumn(name="travel_program", referencedColumnName="id")
* @ORM\JoinColumn(name="travel_program", referencedColumnName="id", onDelete="SET NULL")
*/
private $travelProgram;
/**
* @var FewoLodging
*
* @ORM\OneToOne(targetEntity="AppBundle\Entity\FewoLodging", inversedBy="page")
* @ORM\JoinColumn(name="fewo_lodging", referencedColumnName="id", onDelete="SET NULL")
*/
private $fewoLodging;
/**
* @var integer
*
@ -1070,6 +1078,30 @@ class Page
return $this->travelProgram;
}
/**
* Set fewoLodging
*
* @param \AppBundle\Entity\FewoLodging $fewoLodging
*
* @return Page
*/
public function setFewoLodging(\AppBundle\Entity\FewoLodging $fewoLodging = null)
{
$this->fewoLodging = $fewoLodging;
return $this;
}
/**
* Get fewoLodging
*
* @return \AppBundle\Entity\FewoLodging
*/
public function getFewoLodging()
{
return $this->fewoLodging;
}
/**
* @param string|null $realUrlPath
*

View file

@ -16,7 +16,7 @@ class Traveler
/**
* @Assert\NotNull
* @ Assert\Choice(choices={1,2})
* @Assert\Choice(choices={1,2})
*/
private $sex;

View file

@ -0,0 +1,144 @@
<?php
namespace AppBundle\Export;
use AppBundle\Entity\BookingRequest;
use AppBundle\Entity\FewoBookingRequest;
use AppBundle\Entity\FewoLodging;
use AppBundle\Entity\FewoPrice;
use AppBundle\Entity\TravelDate;
use AppBundle\Entity\Traveler;
use AppBundle\Util;
use Monolog\Logger;
class FewoBookingSternToursCrmExporter extends SternToursCrmExporter
{
public function __construct(Logger $logger)
{
parent::__construct($logger);
}
public function process(FewoBookingRequest $fewoBookingRequest, FewoLodging $fewoLodging, FewoPrice $fewoPrice)
{
$lead = $this->createLead($fewoBookingRequest);
if ($lead === null)
{
$this->warn('Failed creating lead in CRM', $fewoBookingRequest, Logger::ERROR);
return false;
}
$bookingUrl = $this->createBooking($fewoBookingRequest, $fewoLodging, $fewoPrice, $lead['customer_id'], $lead['id']);
if ($bookingUrl === false)
{
$this->warn('Failed creating booking in CRM', $fewoBookingRequest, Logger::ERROR);
return false;
}
/*
if(!$this->createTraveler($bookingUrl, $fewoBookingRequest))
{
$this->warn('Failed creating traveler in CRM.', $fewoBookingRequest);
}
*/
return $bookingUrl;
}
private function createLead(FewoBookingRequest $fewoBookingRequest)
{
$resp = $this->httpPost('lead', ['lead' => [
'customerForm' => [
'salutation_id' => $fewoBookingRequest->getSalutation(),
'name' => $fewoBookingRequest->getLastName(),
'firstname' => $fewoBookingRequest->getFirstName(),
'street' => $fewoBookingRequest->getStreetAddress(),
'zip' => $fewoBookingRequest->getZipCode(),
'city' => $fewoBookingRequest->getCity(),
'country_id' => $fewoBookingRequest->getNation(),
'phone' => $fewoBookingRequest->getPhone(),
'fax' => $fewoBookingRequest->getFax(),
'email' => $fewoBookingRequest->getEmail()
],
'request_date' => (new \DateTime())->format('Y-m-d'),
'sf_guard_user_id' => self::API_USER_ID,
'status_id' => 7, // 'gebucht'
'travelperiod_start' => $fewoBookingRequest->getFromDate()->format('Y-m-d'),
'travelperiod_end' => $fewoBookingRequest->getToDate()->format('Y-m-d'),
//'travelcategory_id'
'is_closed' => 1,
'website_id' => self::WEBSITE_ID,
'initialcontacttype_id' => 14,
// 'travelperiod_length
'remarks' => $fewoBookingRequest->getNotes()
]]);
if ($resp['success'])
{
$ret = $this->httpGet($resp['location']);
if ($ret == null)
{
$this->warn('Failed retrieving newly created lead object', $fewoBookingRequest);
}
return $ret;
}
return null;
}
private function createBooking(FewoBookingRequest $fewoBookingRequest, FewoLodging $lodging, FewoPrice $price, $customerId, $leadId)
{
$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' => $lodging->getName(),
'start_date' => $fewoBookingRequest->getFromDate()->format('Y-m-d'),
'end_date' => $fewoBookingRequest->getToDate()->format('Y-m-d'),
'pax' => $fewoBookingRequest->getTravelerCount(),
'travel_number' => $lodging->getName()." - ".$price->getSeason()->getName(),
'price' => $fewoBookingRequest->getTotalPrice(),
'participant_salutation_id' => $fewoBookingRequest->getSalutation(),
'participant_name' => $fewoBookingRequest->getLastName(),
'participant_firstname' => $fewoBookingRequest->getFirstName(),
//'participant_birthdate' => $bookingRequest->getTravelers()[0]->getBirthDate(),
]]);
if (!$resp['success'])
{
return false;
}
return $resp['location'];
}
private function createTraveler($bookingUrl, FewoBookingRequest $fewoBookingRequest)
{
$resp = $this->httpPost($bookingUrl .'/participant.json', ['participant' => [
'participant_salutation_id' => $fewoBookingRequest->getSalutation(),
'participant_name' => $fewoBookingRequest->getLastName(),
'participant_firstname' => $fewoBookingRequest->getFirstName(),
//'participant_birthdate' => $traveler->getBirthDate(),
]], true);
return $resp['success'];
}
private function warn($msg, FewoBookingRequest $fewoBookingRequest = null, $level = Logger::WARNING)
{
$this->logger->log($level, 'SternToursCrmBookingExporter: '. $msg);
$this->logger->log($level, '*** Date: '. (new \DateTime())->format('d.m.Y'));
if ($fewoBookingRequest !== null)
{
$this->logger->log($level, '*** Booking date: '. $fewoBookingRequest->getFromDate()->format('d.m.Y') .
' - '. $fewoBookingRequest->getToDate()->format('d.m.Y') .')');
$this->logger->log($level, '*** User name: '. $fewoBookingRequest->getFirstName() .' '. $fewoBookingRequest->getLastName());
}
}
}

View file

@ -0,0 +1,118 @@
<?php
namespace AppBundle\Form;
//TODO bereinigen
use AppBundle\Entity\BookingRequest;
use AppBundle\Entity\TravelDate;
use AppBundle\Entity\Traveler;
use AppBundle\Entity\TravelProgram;
use AppBundle\Util;
use Doctrine\Common\Collections\Collection;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use AppBundle\Form\StPlainDateType;
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\RangeType;
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;
class FewoBookingRequestType extends AbstractType
{
public static $SALUTATION_CHOICES = [
'Herr' => 1,
'Frau' => 2
];
public static $NATION_CHOICES = [
'Deutschland' => 27,
'Österreich' => 34,
'Schweiz' => 181,
'Niederlande' => 196,
'Sonstiges' => 197,
];
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'lodging' => null,
'maxPersons' => null,
'toDate' => null,
'data_class' => 'AppBundle\Entity\FewoBookingRequest',
]);
$resolver->setAllowedTypes('lodging', ['AppBundle\Entity\FewoLodging']);
$resolver->setAllowedTypes('toDate', ['string', 'NULL']);
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$maxPersons = $options['maxPersons'];
$toDate = $options['toDate'];
$toDateDateTime = new \DateTime($toDate);
$TRAVELERS_CHOICES = [
'1' => 1,
];
if($maxPersons > 1)
{
for($i = 2; $i <= $maxPersons; $i++)
{
$TRAVELERS_CHOICES[] = $i;
}
}
$builder
->add('toDate', StDateType::class, [
//options
//'widget' => 'single_text',
'data' => $toDateDateTime,
'format' => 'd.M.y'
])
->add('travelerCount', ChoiceType::class, [
'choices' => $TRAVELERS_CHOICES,
'constraints' => [
new NotNull(),
new Choice(['choices' => $TRAVELERS_CHOICES])
]
])
->add('salutation', ChoiceType::class,[
'choices' => self::$SALUTATION_CHOICES,
'constraints' => [
new NotNull(),
new Choice(['choices' => self::$SALUTATION_CHOICES])
]
])
->add('firstName')
->add('lastName')
->add('streetAddress')
->add('zipCode')
->add('city')
->add('phone')
->add('fax')
->add('email')
->add('notes', TextareaType::class, ['required' => false])
;
}
}

View file

@ -0,0 +1,46 @@
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class FewoLodgingImageType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('file', FileType::class, [
])
->add('fileName')
->add('description')
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\FewoLodgingImage'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_fewolodgingimage';
}
}

View file

@ -0,0 +1,92 @@
<?php
namespace AppBundle\Form;
use Doctrine\Common\Collections\Collection;
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;
use AppBundle\Entity\FewoSeason;
class FewoLodgingType extends AbstractType
{
public static $WEEKDAY_CHOICES = [
'keiner' => 0,
'Montag' => 1,
'Dienstag' => 2,
'Mittwoch' => 3,
'Donnerstag' => 4,
'Freitag' => 5,
'Samstag' => 6,
'Sonntag' => 7
];
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('description')
->add('equipment')
->add('adress1')
->add('adress2')
->add('zipCode')
->add('city')
->add('maximumPersons', TextType::class, [
])
->add('deposit')
->add('onlyWeekday', ChoiceType::class, [
'choices' => self::$WEEKDAY_CHOICES,
'constraints' => [
new Choice(['choices' => self::$WEEKDAY_CHOICES])
]
])
->add('calendarVisible')
->add('type', EntityType::class, [
'placeholder' => '(Bitte wählen) *',
'class' => 'AppBundle\Entity\FewoLodgingType',
'constraints' => [
new NotNull()
]
])
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\FewoLodging'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_fewolodging';
}
}

View file

@ -0,0 +1,60 @@
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Validator\Constraints\Choice;
use Symfony\Component\Validator\Constraints\NotNull;
class FewoPriceType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$lodging = $options['lodging'];
$builder
->add('perNight')
->add('flatPrice')
->add('season', EntityType::class, [
'placeholder' => 'Bitte wählen',
'class' => 'AppBundle\Entity\FewoSeason',
'choices' => $lodging->getChoosableSeasons(),
'constraints' => [
new NotNull(),
new Choice([
'choices' => $lodging->getChoosableSeasons()
]
)]
])
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'lodging' => null,
'data_class' => 'AppBundle\Entity\FewoPrice'
));
$resolver->setAllowedTypes('lodging', ['AppBundle\Entity\FewoLodging']);
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_fewoprice';
}
}

View file

@ -0,0 +1,95 @@
<?php
namespace AppBundle\Form;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Choice;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use AppBundle\Form\StDateType;
class FewoReservationType extends AbstractType
{
public static $STATUS_CHOICES = [
'Belegt' => 0,
'Nicht verfügbar' => 1,
];
public static $TYPE_CHOICES = [
'Buchung' => 0,
'Händisch' => 1
];
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$lodging = $options['lodging'];
$fromDate = $options['fromDate'];
$fromDateDateTime = new \DateTime($fromDate);
$lodgingArr[] = $lodging;
$builder
->add('lodging', EntityType::class, [
'class' => 'AppBundle\Entity\FewoLodging',
'choices' => $lodgingArr,
'constraints' => [
new Choice(['choices' => $lodgingArr])
],
'required'=> true
])
->add('fromDate', StDateType::class, [
//options
'data' => $fromDateDateTime
])
->add('toDate', StDateType::class, [
])
->add('status', ChoiceType::class, [
'placeholder' => 'Status (Bitte wählen) *',
'choices' => self::$STATUS_CHOICES,
'constraints' => [
new Choice(['choices' => self::$STATUS_CHOICES])
],
'required' => true,
])
->add('type', ChoiceType::class, [
'placeholder' => 'Buchungstyp (Bitte wählen) *',
'choices' => self::$TYPE_CHOICES,
'constraints' => [
new Choice(['choices' => self::$TYPE_CHOICES])
],
'required' => true,
])
//->add('lodging') // wird händisch gesetzt
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'lodging' => null,
'fromDate' => null,
'data_class' => 'AppBundle\Entity\FewoReservation'
));
$resolver->setAllowedTypes('lodging', ['AppBundle\Entity\FewoLodging']);
$resolver->setAllowedTypes('fromDate', ['string', 'NULL']);
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_feworeservation';
}
}

View file

@ -0,0 +1,63 @@
<?php
namespace AppBundle\Form;
use Doctrine\Common\Collections\Collection;
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\Extension\Core\Type\DateType;
use AppBundle\Form\StDateType;
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;
class FewoSeasonType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('fromDate', StDateType::class, [
//options
])
->add('toDate', StDateType::class, [
//options
])
->add('minimumStay', TextType::class, [
])
->add('description')
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\FewoSeason'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_fewoseason';
}
}

View file

@ -0,0 +1,76 @@
<?php
namespace AppBundle\Listener;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use AppBundle\Entity\FewoLodgingImage;
use AppBundle\Service\FileManager;
class DoctrineFileListener
{
private $uploader;
public function __construct(FileManager $uploader)
{
$this->uploader = $uploader;
}
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$this->uploadFile($entity);
}
public function preUpdate(PreUpdateEventArgs $args)
{
$entity = $args->getEntity();
$this->uploadFile($entity);
}
public function preRemove(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$this->deleteFile($entity);
}
private function uploadFile($entity)
{
if (!$entity instanceof FewoLodgingImage)
{
return;
}
$file = $entity->getFile();
// man könnte hier noch anpassungen tätigen, wie zb. dass man den dateinamen selbst über fileName angeben kann
// oder man nutzt (so wie es jetzt ist) fileName dafür, es als alt-Name usw. zu benutzen und der dateiname bleibt kryptisch
// only upload new files
if (!$file instanceof UploadedFile)
{
return;
}
$fileName = $this->uploader->upload($file);
$entity->setFile($fileName);
}
private function deleteFile($entity)
{
if(!$entity instanceof FewoLodgingImage)
{
return;
}
$this->uploader->delete($entity);
}
}

View file

@ -145,6 +145,18 @@ class KernelControllerListener
}
$request->attributes->set('_controller', 'AppBundle:Cms:travelProgram');
}
elseif ($node->getFewoLodging() != null && ($restOfPath == '/fewo-buchen' || $restOfPath == '/fewo-berechne-gesamtpreis'))
{
$request->attributes->set('fewoTravelProgramPage', $node);
$request->attributes->set('action', $restOfPath);
$request->attributes->set('_controller', 'AppBundle:FewoBooking:index');
}
elseif ($node->getFewoLodging() != null)
{
$request->attributes->set('fewoLodgingPage', $node);
$request->attributes->set('action', $restOfPath);
$request->attributes->set('_controller', 'AppBundle:Cms:fewoLodging');
}
else
{
$handler = $node->getTemplate() ? ucfirst($node->getTemplate()) : 'Default';

View file

@ -507,3 +507,20 @@
.widget .sidebar-price .btn {
color:#ffffff !important;
}
.calendarEven{
float: left;
width: 50%;
}
.calendarOdd{
float: left;
width: 50%;
}
.calendarGradient{
background: -webkit-gradient(linear, left top, right bottom, color-stop(1%, darkgray), color-stop(52%, darkgray), color-stop(52%, #f2f2f2), color-stop(52%, #f2f2f2), color-stop(100%, #f2f2f2));
background: -moz-gradient(linear, left top, right bottom, color-stop(1%, darkgray), color-stop(52%, darkgray), color-stop(52%, #f2f2f2), color-stop(52%, #f2f2f2), color-stop(100%, #f2f2f2));
background: -o-gradient(linear, left top, right bottom, color-stop(1%, darkgray), color-stop(52%, darkgray), color-stop(52%, #f2f2f2), color-stop(52%, #f2f2f2), color-stop(100%, #f2f2f2));
background: gradient(linear, left top, right bottom, color-stop(1%, darkgray), color-stop(52%, darkgray), color-stop(52%, #f2f2f2), color-stop(52%, #f2f2f2), color-stop(100%, #f2f2f2));
}

View file

@ -1057,6 +1057,20 @@ a[id^="video_"]:before,
.widget .sidebar-price .btn {
color: #ffffff !important;
}
.calendarEven {
float: left;
width: 50%;
}
.calendarOdd {
float: left;
width: 50%;
}
.calendarGradient {
background: -webkit-gradient(linear, left top, right bottom, color-stop(1%, #a9a9a9), color-stop(52%, #a9a9a9), color-stop(52%, #f2f2f2), color-stop(52%, #f2f2f2), color-stop(100%, #f2f2f2));
background: -moz-gradient(linear, left top, right bottom, color-stop(1%, #a9a9a9), color-stop(52%, #a9a9a9), color-stop(52%, #f2f2f2), color-stop(52%, #f2f2f2), color-stop(100%, #f2f2f2));
background: -o-gradient(linear, left top, right bottom, color-stop(1%, #a9a9a9), color-stop(52%, #a9a9a9), color-stop(52%, #f2f2f2), color-stop(52%, #f2f2f2), color-stop(100%, #f2f2f2));
background: gradient(linear, left top, right bottom, color-stop(1%, #a9a9a9), color-stop(52%, #a9a9a9), color-stop(52%, #f2f2f2), color-stop(52%, #f2f2f2), color-stop(100%, #f2f2f2));
}
/*
7) SHORTCODES
===============================================================

View file

@ -0,0 +1,32 @@
$(document).ready(function() {
var frm$ = $('.st-booking-form');
var summary$ = $('.st-booking-summary');
var toDateDay$ = $('#fewo_booking_request_toDate_day');
var toDateMonth$ = $('#fewo_booking_request_toDate_month');
var toDateYear$ = $('#fewo_booking_request_toDate_year');
frm$.find('input, select').change(function() {
var tmp = location.href.split('?');
var tmp2 = tmp[0].split('/');
tmp2.pop();
var url = tmp2.join('/') + '/fewo-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.');
})
});
});

View file

@ -0,0 +1,37 @@
<?php
namespace AppBundle\Service;
use AppBundle\Entity\FewoLodgingImage;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Filesystem\Filesystem;
class FileManager
{
private $targetDir;
public function __construct($targetDir)
{
$this->targetDir = $targetDir;
}
public function upload(UploadedFile $file)
{
$fileName = md5(uniqid()).'.'.$file->guessExtension();
$file->move($this->getTargetDir(), $fileName);
return $fileName;
}
public function delete(FewoLodgingImage $image)
{
$filesystem = new Filesystem();
$filesystem->remove($this->getTargetDir().'/'.$image->getFile());
}
public function getTargetDir()
{
return $this->targetDir;
}
}

View file

@ -0,0 +1,620 @@
<?php
namespace AppBundle\Util;
use AppBundle\Entity\FewoLodging;
use AppBundle\Entity\FewoPrice;
use AppBundle\Entity\FewoReservation;
use AppBundle\Entity\FewoSeason;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\EntityManager;
class LodgingCalendarUtil
{
private $em;
public function __construct(EntityManager $entityManager)
{
$this->em = $entityManager;
}
private function daysInMonth($month, $year)
{
return $month == 2 ? ($year % 4 ? 28 : ($year % 100 ? 29 : ($year % 400 ? 28 : 29))) : (($month - 1) % 7 % 2 ? 30 : 31);
}
public function getCalendarWithPadding()
{
$calendar = null;
$currentMonth = date('n');
$currentYear = date('Y');
$weekDays = ['So','Mo','Di','Mi','Do','Fr','Sa'];
setlocale(LC_TIME, "german");
for($m = $currentMonth; $m < ($currentMonth + 12); $m++)
{
if($m < 13)
{
$actualMonth = $m;
$actualCurrentYear = $currentYear;
}
else
{
$actualMonth = $m % 12;
$actualCurrentYear = $currentYear + 1;
}
$date = getdate(mktime(0,0,0, $actualMonth, 1, $actualCurrentYear));
$weekDay = $weekDays[$date['wday']];
$numberDays = $this->daysInMonth($actualMonth, $actualCurrentYear);
$data = null;
$actualStartingWeekDay = $date['wday'];
if($actualStartingWeekDay == 0)
{
$actualStartingWeekDay = 7;
}
for($fwd = 0; $fwd < $actualStartingWeekDay - 1; $fwd++)
{
$data[] = 0;
}
for($d = 1; $d <= $numberDays; $d++)
{
$data[] = $d;
}
$startIndex = count($data);
for($lwd = $startIndex; $lwd < 42; $lwd++)
{
$data[] = 0;
}
$calendar[] = [
'numberDays' => $numberDays,
'monthNumber' => $actualMonth,
'monthName' => utf8_encode(strftime("%B", mktime(0, 0, 0, $actualMonth, 1, $actualCurrentYear))),
'year' => $actualCurrentYear,
'startWeekDay' => $weekDay,
'data' => $data,
'marked' => 0
];
}
return $calendar;
}
public function getCalendar()
{
$calendar = null;
$currentMonth = date('n');
$currentYear = date('Y');
$weekDays = ['So','Mo','Di','Mi','Do','Fr','Sa'];
setlocale(LC_TIME, "german");
for($m = $currentMonth; $m < ($currentMonth + 12); $m++)
{
if($m < 13)
{
$actualMonth = $m;
$actualCurrentYear = $currentYear;
}
else
{
$actualMonth = $m % 12;
$actualCurrentYear = $currentYear + 1;
}
$date = getdate(mktime(0,0,0, $actualMonth, 1, $actualCurrentYear));
$weekDay = $weekDays[$date['wday']];
$numberDays = $this->daysInMonth($actualMonth, $actualCurrentYear);
$data = null;
// alle Wochentage
for($d = 1; $d <= $numberDays; $d++)
{
$data[] = $d;
}
$calendar[] = [
'numberDays' => $numberDays,
'monthNumber' => $actualMonth,
'monthName' => utf8_encode(strftime("%B", mktime(0, 0, 0, $actualMonth, 1, $actualCurrentYear))),
'year' => $actualCurrentYear,
'startWeekDay' => $weekDay,
'data' => $data,
'marked' => 0
];
}
return $calendar;
}
/**
* @param FewoLodging $lodging
* @return array|null
*/
public function getReservations(FewoLodging $lodging)
{
$reservations = $lodging->getReservations();
$ret = null;
for($i = 0; $i < count($reservations); $i++)
{
$fromDate = $reservations[$i]->getFromDate();
$toDate = $reservations[$i]->getToDate();
$ret[] = [
'startDay' => $fromDate->format('j'),
'startMonth' => $fromDate->format('n'),
'startYear' => $fromDate->format('Y'),
'endDay' => $toDate->format('j'),
'endMonth' => $toDate->format('n'),
'endYear' => $toDate->format('Y')
];
}
return $ret;
}
private function getMonthIndex($calendar, $month)
{
$result = 0;
for($i = 0; $i < count($calendar); $i++)
{
if($calendar[$i]['monthNumber'] == $month)
{
$result = $i;
break;
}
}
return $result;
}
/**
* @param $calendar
* @param \DateTime $fromDate
* @param \DateTime $toDate
* @param $appendix
* @return mixed
*/
private function markCalendarDays($calendar, \DateTime $fromDate, \DateTime $toDate, $appendix, $reservationMode = false)
{
$startDay = $fromDate->format('j');
$startMonth = $fromDate->format('n');
$startYear = $fromDate->format('Y');
$endDay = $toDate->format('j');
$endMonth = $toDate->format('n');
$endYear = $toDate->format('Y');
$today = new \DateTime();
$todayDay = $today->format('j');
$todayMonth = $today->format('n');
$todayYear = $today->format('Y');
if($startMonth < $todayMonth && $startYear == $todayYear)
{
$startDay = 1;
$startMonth = $today->format('n');
$startYear = $today->format('Y');
}
$startCalendarIndex = $this->getMonthIndex($calendar, $startMonth);
$endCalendarIndex = $this->getMonthIndex($calendar, $endMonth);
if($startCalendarIndex == $endCalendarIndex)
{
$data = $calendar[$startCalendarIndex]['data'];
$calendar[$startCalendarIndex]['marked'] = 1;
$startIndex = $startDay - 1;
$endIndex = $endDay - 1;
$firstDay = explode(',', $data[$startIndex]);
if(count($firstDay) > 1 && $reservationMode == false)
$startIndex = $startIndex + 1;
for($i = $startIndex; $i <= $endIndex; $i++)
{
if($i == $startIndex && $reservationMode)
{
$data[$i] = $data[$i].$appendix.",from";
} elseif($i == $endIndex && $reservationMode) {
$data[$i] = $data[$i].$appendix.",to";
} else {
$data[$i] = $data[$i].$appendix;
}
}
$calendar[$startCalendarIndex]['data'] = $data;
}
else
{
$data = $calendar[$startCalendarIndex]['data'];
$calendar[$startCalendarIndex]['marked'] = 1;
$startIndex = $startDay - 1;
$firstDay = explode(',', $data[$startIndex]);
if(count($firstDay) > 1 && $reservationMode == false)
$startIndex = $startIndex + 1;
$endIndex = count($data) - 1;
for($i = $startIndex; $i <= $endIndex; $i++)
{
if($i == $startIndex && $reservationMode)
{
$data[$i] = $data[$i].$appendix.",from";
} else {
$data[$i] = $data[$i].$appendix;
}
}
$calendar[$startCalendarIndex]['data'] = $data;
$data = $calendar[$endCalendarIndex]['data'];
$calendar[$endCalendarIndex]['marked'] = 1;
$startIndex = 0;
$endIndex = $endDay - 1;
for($i = $startIndex; $i <= $endIndex; $i++)
{
if($i == $endIndex && $reservationMode)
{
$data[$i] = $data[$i].$appendix.",to";
} else {
$data[$i] = $data[$i].$appendix;
}
}
$calendar[$endCalendarIndex]['data'] = $data;
for($i = $startCalendarIndex + 1; $i < $endCalendarIndex; $i++)
{
$data = $calendar[$i]['data'];
$calendar[$i]['marked'] = 1;
$startIndex = 0;
$endIndex = count($data) - 1;
for($j = $startIndex; $j <= $endIndex; $j++)
{
$data[$j] = $data[$j].$appendix;
}
$calendar[$i]['data'] = $data;
}
}
return $calendar;
}
private function mergeCalendars($calendar, $extensionCalendar, $withFromTo = false)
{
for($i = 0; $i < 12; $i++)
{
if($calendar[$i]['marked'] == 1 && $extensionCalendar[$i]['marked'] == 1)
{
$calendarData = $calendar[$i]['data'];
$extensionCalendarData = $extensionCalendar[$i]['data'];
$endIndex = count($calendarData);
for($j = 0; $j < $endIndex; $j++)
{
if(strlen($extensionCalendarData[$j]) > 2)
{
if($withFromTo)
{
$calDay = explode(',', $calendarData[$j]);
$extCalDay = explode(',', $extensionCalendarData[$j]);
if(count ($calDay) > 1 && $calDay[1] == "reservable" && count($extCalDay) > 2 && $extCalDay[2] == 'to')
{
$calendarData[$j] = $extensionCalendarData[$j].",reservable".','.$calDay[2];
}
else
$calendarData[$j] = $extensionCalendarData[$j];
}
else
{
$calendarData[$j] = $extensionCalendarData[$j];
}
}
}
$calendar[$i]['data'] = $calendarData;
}
}
return $calendar;
}
public function mergeWithPaddedCalendar($calendar, $paddedCalendar)
{
for($i = 0; $i < count($paddedCalendar); $i++)
{
$calendarDataCurrMonth = $calendar[$i]['data'];
$paddedCalendarDataCurrMonth = $paddedCalendar[$i]['data'];
$startIndex = array_search(1, $paddedCalendarDataCurrMonth);
for($j = 0; $j < count($calendarDataCurrMonth); $j++, $startIndex++)
{
$paddedCalendarDataCurrMonth[$startIndex] = $calendarDataCurrMonth[$j];
}
$paddedCalendar[$i]['data'] = $paddedCalendarDataCurrMonth;
}
return $paddedCalendar;
}
private function isNextDay($current, $next)
{
$result = false;
$calculatedNextDate = date('d.m.Y', strtotime($current." + 1 day"));
if($calculatedNextDate == $next)
{
$result = true;
}
return $result;
}
private function getMonthFromCalendar($calendar, $monthNumber)
{
$result = [];
for($i = 0; $i < count($calendar); $i++)
{
if($calendar[$i]['monthNumber'] == $monthNumber)
{
$result = $calendar[$i];
}
}
return $result;
}
/**
* @param FewoLodging $lodging
* @param $calendar
* @return array|null
*/
private function filterReservableDays(FewoLodging $lodging, $calendar)
{
$priceRepo = $this->em->getRepository('AppBundle:FewoPrice');
$today = new \DateTime();
$seasons = $lodging->getSeasons();
$prices = $lodging->getPrices();
$cleanCalendar = $this->getCalendar();
$potentiallyReservableDays = [];
$actuallyReservableDays = [];
$lastReservablePriceId = 0;
$priceId = 0;
for($currMonthIndex = 0; $currMonthIndex < count($calendar); $currMonthIndex++)
{
$currMonth = $calendar[$currMonthIndex];
$data = $currMonth['data'];
for($currDayIndex = 0; $currDayIndex < count($data); $currDayIndex++)
{
$currDay = explode(',', $data[$currDayIndex]);
if(count($currDay) > 1)
{
if($currDay[1] == "reservable")
{
$priceId = $currDay[2];
if($lastReservablePriceId == 0)
$lastReservablePriceId = $priceId;
if($lastReservablePriceId != $priceId)
{
$price = $priceRepo->find($lastReservablePriceId);
/** @var FewoSeason $season */
$season = $price->getSeason();
$actuallyReservableDays = $this->processPotentiallyReservableDays($potentiallyReservableDays, $season->getMinimumStay());
$this->processRest($actuallyReservableDays, $lastReservablePriceId, $cleanCalendar);
$lastReservablePriceId = $priceId;
$potentiallyReservableDays = [];
$actuallyReservableDays = [];
}
$currentDayDate = date("d.m.Y", strtotime($currMonth['year']."-".$currMonth['monthNumber']."-".$currDay[0]));
$potentiallyReservableDays[] = $currentDayDate;
}
elseif(count($currDay) > 2 && $currDay[2] == "from")
{
$currentDayDate = date("d.m.Y", strtotime($currMonth['year']."-".$currMonth['monthNumber']."-".$currDay[0]));
$potentiallyReservableDays[] = $currentDayDate;
}
}
else
{
if($lastReservablePriceId == $priceId)
{
$price = $priceRepo->find($lastReservablePriceId);
/** @var FewoSeason $season */
$season = $price->getSeason();
$actuallyReservableDays = $this->processPotentiallyReservableDays($potentiallyReservableDays, $season->getMinimumStay());
$this->processRest($actuallyReservableDays, $lastReservablePriceId, $cleanCalendar);
$lastReservablePriceId = $priceId;
$potentiallyReservableDays = [];
$actuallyReservableDays = [];
}
}
}
}
return $cleanCalendar;
}
private function processPotentiallyReservableDays($potentiallyReservableDays, $minimumStay)
{
$coherentDays = [];
$actuallyReservableDays = [];
//$coherentDays[] = $potentiallyReservableDays[0];
for($i = 1; $i < count($potentiallyReservableDays); $i++)
{
if($this->isNextDay($potentiallyReservableDays[$i - 1], $potentiallyReservableDays[$i]))
{
if(count($coherentDays) == 0)
{
$coherentDays[] = $potentiallyReservableDays[$i - 1];
}
$coherentDays[] = $potentiallyReservableDays[$i];
}
else
{
if(count($coherentDays) < $minimumStay)
{
$coherentDays = [];
$coherentDays[] = $potentiallyReservableDays[$i];
}
else
{
$coherentDaysCount = count($coherentDays);
$offset = $coherentDaysCount - ($minimumStay - 1);
$coherentDays = array_splice($coherentDays, 0, $offset);
for($j = 0; $j < count($coherentDays); $j++)
{
$actuallyReservableDays[] = $coherentDays[$j];
}
$coherentDays = [];
}
}
}
if(count($coherentDays) > 0)
{
$coherentDaysCount = count($coherentDays);
$offset = $coherentDaysCount - ($minimumStay - 1);
$coherentDays = array_splice($coherentDays, 0, $offset);
for($j = 0; $j < count($coherentDays); $j++)
{
$actuallyReservableDays[] = $coherentDays[$j];
}
}
return $actuallyReservableDays;
}
private function processRest($actuallyReservableDays, $priceId, &$cleanCalendar)
{
for($currMonthIndex = 0; $currMonthIndex < count($cleanCalendar); $currMonthIndex++)
{
$currMonth = $cleanCalendar[$currMonthIndex];
$data = $currMonth['data'];
$startIndex = array_search(1, $data);
$endIndex = $startIndex + ($currMonth['numberDays']);
for($currDayIndex = $startIndex; $currDayIndex < $endIndex; $currDayIndex++)
{
$currDay = explode(',', $data[$currDayIndex]);
$currentDate = date("d.m.Y", strtotime($currMonth['year']."-".$currMonth['monthNumber']."-".$currDay[0]));
if(in_array($currentDate, $actuallyReservableDays))
{
$data[$currDayIndex] = $data[$currDayIndex].",reservable,".$priceId;
$currMonth['marked'] = 1;
}
}
$currMonth['data'] = $data;
$cleanCalendar[$currMonthIndex] = $currMonth;
}
}
/**
* @param FewoLodging $lodging
* @param $calendar
* @return mixed
*/
public function markCalendarDaysWithReservations(FewoLodging $lodging, $calendar)
{
$today = new \DateTime();
$pricesCalendar = $calendar;
$reservationsCalendar = $calendar;
$reservations = $lodging->getReservations();
$prices = $lodging->getPrices();
$lodgingId = $lodging->getId();
foreach($prices as $price)
{
/** @var FewoSeason $season */
$season = $price->getSeason();
$appendix = ',reservable,'.$price->getId();
$fromDate = $season->getFromDate();
$toDate = $season->getToDate();
if($toDate < $today)
{
}
else
{
$pricesCalendar = $this->markCalendarDays($pricesCalendar, $fromDate, $toDate, $appendix, false);
}
}
foreach($reservations as $reservation)
{
$reservationId = $reservation->getId();
$appendix = ','.$reservationId;
$fromDate = $reservation->getFromDate();
$toDate = $reservation->getToDate();
$reservationsCalendar = $this->markCalendarDays($reservationsCalendar, $fromDate, $toDate, $appendix, true);
}
$mergedPricesAndReservationsCalendar = $this->mergeCalendars($pricesCalendar, $reservationsCalendar, false);
$actuallyReservableDaysCalendar = $this->filterReservableDays($lodging, $mergedPricesAndReservationsCalendar);
$resultCalendar = $this->mergeCalendars($actuallyReservableDaysCalendar, $reservationsCalendar, true);
return $resultCalendar;
}
public function convertDate($date)
{
$result = substr($date, 0, 2).'.'.substr($date, 2, 2).'.'.substr($date, 4, 4);
return $result;
}
}

View file

@ -0,0 +1,18 @@
<?php
namespace AppBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class FewoBookingRequest extends Constraint
{
public $message = 'Ungültige Eingabe!';
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}
}

View file

@ -0,0 +1,107 @@
<?php
namespace AppBundle\Validator\Constraints;
use AppBundle\Entity\FewoBookingRequest;
use AppBundle\Entity\FewoReservation;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use AppBundle\Validator\Constraints;
/**
* Class FewoReservationValidator
* @package AppBundle\Validator
*/
class FewoBookingRequestValidator extends ConstraintValidator
{
private function withinDates($date, $fromDate, $toDate)
{
$result = false;
if($date >= $fromDate && $date <= $toDate)
{
$result = true;
}
return $result;
}
private function alreadyReserved($fromDate, $toDate, $reservationFromDate, $reservationToDate)
{
$result = true;
if($fromDate >= $reservationToDate || $toDate <= $reservationFromDate)
{
$result = false;
}
return $result;
}
/**
* Checks if the passed value is valid.
*
* @param FewoBookingRequest $bookingRequest The value that should be validated
* @param Constraint $constraint The constraint for the validation
*/
public function validate($bookingRequest, Constraint $constraint)
{
$fromDate = $bookingRequest->getFromDate();
$toDate = $bookingRequest->getToDate();
$lodging = $bookingRequest->getLodging();
$price = $bookingRequest->getPrice();
$season = $price->getSeason();
$reservations = $lodging->getReservations();
$timeDiff = date_diff($fromDate, $toDate);
$numberDays = $timeDiff->days + 1;
$withinSeason = false;
$alreadyReserved = false;
if($fromDate >= $season->getFromDate()
&& $toDate <= $season->getToDate())
{
$withinSeason = true;
}
/** @var FewoReservation $reservation */
foreach($reservations as $reservation)
{
$reservationFromDate = $reservation->getFromDate();
$reservationToDate = $reservation->getToDate();
if($this->alreadyReserved($fromDate, $toDate, $reservationFromDate, $reservationToDate))
{
$alreadyReserved = true;
}
}
if(!$withinSeason)
{
$this->context->buildViolation("Zeitraum außerhalb der Saison!")
->addViolation();
}
if($alreadyReserved)
{
$this->context->buildViolation("Es gibt bereits Reservierungen innerhalb des gewünschten Zeitraums!")
->addViolation();
}
if($numberDays < $season->getMinimumStay())
{
$this->context->buildViolation("Mindestanzahl an Tagen nicht erreicht!")
->addViolation();
}
if($bookingRequest->getTravelerCount() > $lodging->getMaximumPersons())
{
$this->context->buildViolation("Anzahl der Reisenden übersteigt die maximale Personenanzahl!")
->addViolation();
}
}
}

View file

@ -0,0 +1,18 @@
<?php
namespace AppBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class FewoReservation extends Constraint
{
public $message = 'Die Daten müssen innerhalb einer Saison liegen!';
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}
}

View file

@ -0,0 +1,79 @@
<?php
namespace AppBundle\Validator\Constraints;
use AppBundle\Entity\FewoReservation;
use AppBundle\Form\FewoReservationType;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
/**
* Class FewoReservationValidator
* @package AppBundle\Validator
*/
class FewoReservationValidator extends ConstraintValidator
{
private function alreadyReserved($fromDate, $toDate, $reservationFromDate, $reservationToDate)
{
$result = true;
if($fromDate >= $reservationToDate || $toDate <= $reservationFromDate)
{
$result = false;
}
return $result;
}
/**
* Checks if the passed value is valid.
*
* @param FewoReservation $reservation The value that should be validated
* @param Constraint $constraint The constraint for the validation
*/
public function validate($reservation, Constraint $constraint)
{
$lodging = $reservation->getLodging();
$reservations = $lodging->getReservations();
$seasons = $lodging->getSeasons();
$withinAnySeason = false;
$alreadyReserved = false;
for($i = 0; $i < count($seasons); $i++)
{
if($reservation->getFromDate() >= $seasons[$i]->getFromDate()
&& $reservation->getToDate() <= $seasons[$i]->getToDate())
{
$withinAnySeason = true;
}
}
foreach($reservations as $reservation)
{
$reservationFromDate = $reservation->getFromDate();
$reservationToDate = $reservation->getToDate();
if($this->alreadyReserved($reservation->getFromDate(), $reservation->getToDate(), $reservationFromDate, $reservationToDate))
{
$alreadyReserved = true;
}
}
if(!$withinAnySeason)
{
$this->context->buildViolation($constraint->message)
->addViolation();
}
if($alreadyReserved)
{
$this->context->buildViolation("Es gibt bereits Reservierungen innerhalb des gewünschten Zeitraums!")
->addViolation();
}
}
}