This commit is contained in:
Kevin Adametz 2020-02-14 10:19:06 +01:00
parent ee89626864
commit a37785b391
23 changed files with 1398 additions and 254 deletions

View file

@ -8,7 +8,9 @@
<!--[if IE 8 ]><html class="ie ie8" lang="de"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--><html lang="de"><!--<![endif]-->
<head>
<title>{% block page_title %}{{ page is defined ? page.pagetitle : 'Kulturreisen vom Reiseveranstalter STERN TOURS aus Berlin' }}{% endblock page_title %}</title>
<title>{% block page_title %}
{{ page is defined ? page.pagetitle : iq_page_title is defined ? iq_page_title : 'Kulturreisen vom Reiseveranstalter STERN TOURS aus Berlin' }}
{% endblock page_title %}</title>
{% block metatags %}
<meta charset="utf-8">
@ -17,20 +19,18 @@
{% block meta_description -%}
{%- if page is defined and page.description is not empty -%}
<meta name="description" content="{{ page.description }}" >
{%- elseif app.debug -%}
<!-- <meta name="description" > {% if page is not defined %} muss im Twig-Seitentemplate im Block meta_description festgelegt werden.{% else %} fehlt, da das Feld "description" im page Eintrag mit der ID {{ page.id }} leer ist.{% endif %} -->
{%- endif -%}
{%- if iq_page_description is defined and iq_page_description is not empty -%}
<meta name="description" content="{{ iq_page_description }}" >
{%- endif -%}
{%- endblock %}
{% block meta_keywords -%}
{%- if page is defined and page.keywords is not empty -%}
<meta name="keywords" content="{{ page.keywords }}" >
{%- elseif app.debug -%}
<!-- <meta name="keywords" > {% if page is not defined %} muss im Twig-Seitentemplate im Block meta_keywords festgelegt werden.{% else %} fehlt, da das Feld "keywords" im page Eintrag mit der ID {{ page.id }} leer ist.{% endif %} -->
{%- endif -%}
{%- endblock %}
{% block meta_robots %}
<meta name="robots" content="follow,index" />
{% if app.debug %}<!-- Falls der meta-robots-Tag für diese Seite falsch ist, kann der Block "meta_robots" im Twig-Template überschrieben werden -->{% endif %}
{% endblock %}
{% endblock %}

View file

@ -66,7 +66,7 @@
<table class="table table-condensed table-vertical-middle">
{% for key, val in local %}
<tr>
<td class="text-left" style="width: 50%">{{ val.day }} <span class="text-muted pull-right"> {{ key }}</span></td>
<td class="text-left" style="width: 50%">{{ val.day }} <span class="text-muted pull-right"> {{ val.date }}</span></td>
{% if val.active == 0 %}
<td colspan="3">geschlossen</td>
{% else %}
@ -107,7 +107,7 @@
<table class="table table-condensed table-vertical-middle">
{% for key, val in phone %}
<tr>
<td class="text-left" style="width: 50%">{{ val.day }} <span class="text-muted pull-right"> {{ key }}</span></td>
<td class="text-left" style="width: 50%">{{ val.day }} <span class="text-muted pull-right"> {{ val.date }}</span></td>
{% if val.active == 0 %}
<td colspan="3">geschlossen</td>
{% else %}

View file

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

View file

@ -1,7 +1,9 @@
Folgende Wohnung wurde gemietet
URL: {{ lodging_url }}
URL:
{{ lodging_url }}
CRM: {{ crm_url }}
CRM:
{{ crm_url }}
{% include 'default/email/components/fewoBookingSummary.txt.twig' %}

View file

@ -142,9 +142,9 @@
<tr>
<td>Anrede</td>
<td>
{% if booking.salutation == 1 %}
{% if booking.salutationId == 1 %}
Herr
{% elseif booking.salutation == 2 %}
{% elseif booking.salutationId == 2 %}
Frau
{% endif %}
</td>
@ -163,7 +163,7 @@
</tr>
<tr>
<td>Straße, Hausnummer</td>
<td>{{ booking.street }} {{ booking.houseNr }}</td>
<td>{{ booking.street }}</td>
</tr>
<tr>
<td>PLZ</td>
@ -175,7 +175,7 @@
</tr>
<tr>
<td>Land</td>
<td>{{ booking.country }}</td>
<td>{{ booking.countryId }}</td>
</tr>
<tr>
<td>Telefon tagsüber</td>
@ -187,7 +187,7 @@
</tr>
<tr>
<td>E-Mail-Adresse</td>
<td>{{ booking.mail }}</td>
<td>{{ booking.email }}</td>
</tr>
</tbody>
</table>

View file

@ -29,7 +29,7 @@
<div class="carousel-inner">
{% for lodging_image in slider_imgs %}
<div class="item{% if loop.first %} active{% endif %}">
<div class="fill" style="background-image:url({{ asset('_uploads/images/' ~ lodging_image.file) }});">
<div class="fill" style="background-image:url({{ asset('_uploads/images/' ~ lodging_image.file) }});background-position: center {{ travel_program_image.position }}">
<span class="image-title">{{ lodging_image.fileName }}</span>
</div>
</div>

View file

@ -2,8 +2,8 @@
{% block body %}
<section class="clearfix">
{% set site_has_h1 = false %}
{% if(api is defined) %}
{% if api.sites|length > 1 %}
<div class="wrapper-nav-tabs">
<ul class="nav nav-tabs nav-justified list-nav-tabs">
@ -20,11 +20,15 @@
{% endfor %}
</ul>
</div>
<div class="tab-content">
{% for site in api.sites %}
<div role="tabpanel" class="tab-pane {% if loop.index==1 %} active {% endif %}" id="travel_guide_content_{{ site.id }}">
<h1>{{ site.name }}</h1>
{% if(site_has_h1) %}
<h2 class="h1l">{{ site.name }}</h2>
{% else %}
<h1>{{ site.name }}</h1>
{% set site_has_h1 = true %}
{% endif %}
{{ site.full_text|raw|keywords|lozad }}
</div>
{% endfor %}
@ -47,7 +51,12 @@
</div>
{% else %}
{% for site in api.sites %}
<h1>{{ site.name }}</h1>
{% if(site_has_h1) %}
<h2 class="h1l">{{ site.name }}</h2>
{% else %}
<h1>{{ site.name }}</h1>
{% set site_has_h1 = true %}
{% endif %}
{{ site.full_text|raw|keywords|lozad }}
{% endfor %}
{% endif %}
@ -56,7 +65,6 @@
<hr>
{% if(api is defined and api.children is defined and api.children is not empty) %}
<section class="clearfix">
<h2></h2>
<div class="row">
{% for child_page in api.children %}
{% if(child_page.active) %}

View file

@ -6,13 +6,13 @@
<div class="wrapper-nav-tabs">
<ul class="nav nav-tabs nav-justified list-nav-tabs">
<li class="active">
<a href="#travel_guide_short_content" aria-controls="travel_guide_short_content" role="tab" data-toggle="tab">
Kurzer Inhalt
<a href="#travel_guide_long_content" aria-controls="travel_guide_long_content" role="tab" data-toggle="tab">
Ausführliche Darstellung <i class="hidden-xs">für Interessierte</i>
</a>
</li>
<li>
<a href="#travel_guide_long_content" aria-controls="travel_guide_long_content" role="tab" data-toggle="tab">
Langer Inhalt
<a href="#travel_guide_short_content" aria-controls="travel_guide_short_content" role="tab" data-toggle="tab">
Zusammenfassung <i class="hidden-xs">für eilige Leser</i>
</a>
</li>
</ul>
@ -30,13 +30,13 @@
<div class="wrapper-nav-tabs">
<ul class="nav nav-tabs nav-justified list-nav-tabs">
<li class="active">
<a href="#travel_guide_short_content" aria-controls="travel_guide_short_content" role="tab" data-toggle="tab">
Kurzer Inhalt
<a href="#travel_guide_long_content" aria-controls="travel_guide_long_content" role="tab" data-toggle="tab">
Ausführliche Darstellung <i class="hidden-xs">für Interessierte</i>
</a>
</li>
<li>
<a href="#travel_guide_long_content" aria-controls="travel_guide_long_content" role="tab" data-toggle="tab">
Langer Inhalt
<a href="#travel_guide_short_content" aria-controls="travel_guide_short_content" role="tab" data-toggle="tab">
Zusammenfassung <i class="hidden-xs">für eilige Leser</i>
</a>
</li>
</ul>

View file

@ -49,9 +49,9 @@
<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>
{% for travel_program_image in travel_program.images %}
<li data-target="#myCarousel" data-slide-to="{{ loop.index-1 }}" {% if loop.first %}class="active"{% endif %}></li>
{% endfor %}
</ol>
<!-- Wrapper for Slides -->
<div class="carousel-inner">
@ -62,10 +62,10 @@
{% set image_url = asset('uploads/travel_program/' ~ travel_program_image.fileNameWithExtension) %}
<div class="fill lozad"
data-background-image="{{ image(image_url|trim('/')).cropResize(848).guess(75) }}"
style="background-image:url({{ asset('images/placeholder-image.png') }})"></div>
style="background-image:url({{ asset('images/placeholder-image.png') }});background-position: center {{ travel_program_image.position }}"></div>
<noscript>
<div class="fill"
style="background-image:url({{ image(image_url|trim('/')).cropResize(848).guess(75) }})"></div>
style="background-image:url({{ image(image_url|trim('/')).cropResize(848).guess(75) }}); background-position: center {{ travel_program_image.position }};"></div>
</noscript>
</div>

View file

@ -2,28 +2,33 @@
{% block body %}
<section class="clearfix">
{% set site_has_h1 = false %}
{% if(api is defined) %}
{% if api.sites|length > 1 %}
<div class="wrapper-nav-tabs">
<ul class="nav nav-tabs nav-justified list-nav-tabs">
{% for site in api.sites %}
<li class="">
<li class="{% if loop.index==1 %} active {% endif %}">
<a href="#travel_guide_content_{{ site.id }}" aria-controls="travel_guide_content_{{ site.id }}" role="tab" data-toggle="tab">
{% if(site.scope == 0) %}
Kurzer Inhalt
Zusammenfassung <i class="hidden-xs">für eilige Leser</i>
{% else %}
Langer Inhalt
Ausführliche Darstellung <i class="hidden-xs">für Interessierte</i>
{% endif %}
</a>
</li>
{% endfor %}
</ul>
</div>
<div class="tab-content">
{% for site in api.sites %}
<div role="tabpanel" class="tab-pane active" id="travel_guide_content_{{ site.id }}">
<div role="tabpanel" class="tab-pane {% if loop.index==1 %} active {% endif %}" id="travel_guide_content_{{ site.id }}">
{% if(site_has_h1) %}
<h2 class="h1l">{{ site.name }}</h2>
{% else %}
<h1>{{ site.name }}</h1>
{% set site_has_h1 = true %}
{% endif %}
{{ site.full_text|raw|keywords|lozad }}
</div>
{% endfor %}
@ -32,12 +37,12 @@
<div class="wrapper-nav-tabs">
<ul class="nav nav-tabs nav-justified list-nav-tabs">
{% for site in api.sites %}
<li class="">
<li class="{% if loop.index==1 %} active {% endif %}">
<a href="#travel_guide_content_{{ site.id }}" aria-controls="travel_guide_content_{{ site.id }}" role="tab" data-toggle="tab">
{% if(site.scope == 0) %}
Kurzer Inhalt
Zusammenfassung <i class="hidden-xs">für eilige Leser</i>
{% else %}
Langer Inhalt
Ausführliche Darstellung <i class="hidden-xs">für Interessierte</i>
{% endif %}
</a>
</li>
@ -46,6 +51,12 @@
</div>
{% else %}
{% for site in api.sites %}
{% if(site_has_h1) %}
<h2 class="h1l">{{ site.name }}</h2>
{% else %}
<h1>{{ site.name }}</h1>
{% set site_has_h1 = true %}
{% endif %}
{{ site.full_text|raw|keywords|lozad }}
{% endfor %}
{% endif %}
@ -53,42 +64,41 @@
</section>
<hr>
{% if(api is defined and api.children is defined and api.children is not empty) %}
<section class="clearfix">
<h2></h2>
<div class="row">
{% for child_page in api.children %}
{% if(child_page.active) %}
<div class="col-md-4 col-sm-6">
<div class="travel-wrapper get-box-link">
<div class="item text-left">
{% if(false and child_page.box_image_url is defined and child_page.box_image_url is not empty) %}
<div class="item-img" style="height: 220px;">
{% if child_page.box_image_url is defined and child_page.box_image_url is not empty %}
{% set image_url = child_page.box_image_url %}
{% set image_alt = child_page.name %}
{% else %}
{% set image_url = asset('/bundles/app/images/no-picture.png')%}
{% set image_alt = 'Kein Vorschaubild vorhanden' %}
{% endif %}
<div class="img-background lozad" data-background-image="{{ image(image_url|trim('/')).cropResize(960).guess(90) }}" style="background-image:url({{ asset('images/placeholder-image.png') }}); height: 220px;"></div>
<noscript>
<img width="234" height="180" src="{{ image(image_url|trim('/')).cropResize(960).guess(90) }}" class="img-responsiv img-responsiv-item" style="">
</noscript>
<section class="clearfix">
<div class="row">
{% for child_page in api.children %}
{% if(child_page.active) %}
<div class="col-md-4 col-sm-6">
<div class="travel-wrapper get-box-link">
<div class="item text-left">
{% if(false and child_page.box_image_url is defined and child_page.box_image_url is not empty) %}
<div class="item-img" style="height: 220px;">
{% if child_page.box_image_url is defined and child_page.box_image_url is not empty %}
{% set image_url = child_page.box_image_url %}
{% set image_alt = child_page.name %}
{% else %}
{% set image_url = asset('/bundles/app/images/no-picture.png')%}
{% set image_alt = 'Kein Vorschaubild vorhanden' %}
{% endif %}
<div class="img-background lozad" data-background-image="{{ image(image_url|trim('/')).cropResize(960).guess(90) }}" style="background-image:url({{ asset('images/placeholder-image.png') }}); height: 220px;"></div>
<noscript>
<img width="234" height="180" src="{{ image(image_url|trim('/')).cropResize(960).guess(90) }}" class="img-responsiv img-responsiv-item" style="">
</noscript>
</div>
{% endif %}
<div class="box_mid">
<div class="hl5">{{ child_page.name }}</div>
<p>{{ child_page.description }}</p>
</div>
<a class="item-button is-box-link dobble_line" href="{{ child_page.url }}" title="{{ child_page.name }}">
<span>{{ child_page.name }}</span>
</a>
</div>
</div>
{% endif %}
<div class="box_mid">
<div class="hl5">{{ child_page.name }}</div>
<p>{{ child_page.description }}</p>
</div>
<a class="item-button is-box-link dobble_line" href="{{ child_page.url }}" title="{{ child_page.name }}">
<span>{{ child_page.name }}</span>
</a>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</section>
{% endif %}
{% endfor %}
</div>
</section>
{% endif %}
{% endblock %}

View file

@ -155,7 +155,7 @@ class BookingController extends Controller
$breadcrumbEntries = Util::createBreadcrumb($travelProgramPage);
$breadcrumbEntries[] = new BreadcrumbEntry('Buchen');
if ($request->getMethod() == 'POST' && $form->isValid())
if ($request->getMethod() === 'POST' && $form->isValid())
{
$errors = array();
foreach ($form as $fieldName => $formField) {
@ -171,15 +171,9 @@ class BookingController extends Controller
$em->persist($booking);
$em->flush();
$crmBookingUrl = $this->get('app.booking_exporter')->process($bookingRequest, $travelDate, $bookingPriceInfo);
if (!$crmBookingUrl)
{
$crmBookingUrl = '[CRM-EXPORT FEHLGESCHLAGEN]';
}
else
{
$crmBookingUrl = preg_replace('/\\/api/', '', $crmBookingUrl).'/edit';
}
$ret = Util::loadFromApi('booking/import', ['travel_booking_id' => $booking->getId()]);
$error_crm = 'CRM Fehler: | interne travel_booking ID: '.$booking->getId();
$this->get('mailer')->send(\Swift_Message::newInstance()
->setSubject('Ihr Buchungsauftrag bei STERN TOURS')
->setFrom('stern@stern-tours.de', 'STERN TOURS')
@ -206,7 +200,9 @@ class BookingController extends Controller
->setBody(
$this->renderView('default/email/bookingServiceEmail.txt.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
'crm_url' => $crmBookingUrl,
'crm_v1_url' => isset($ret->url_v1) ? $ret->url_v1 : $error_crm,
'crm_v3_url' => isset($ret->url_v3) ? $ret->url_v3 : $error_crm,
'lead_id' => isset($ret->lead_id) ? $ret->lead_id : '',
'travel_program_url' => Util::getBaseUrl() . $travelProgramPage->getUrlPath(),
'booking_request' => $bookingRequest,
'booking_price_info' => $bookingPriceInfo,

View file

@ -61,16 +61,15 @@ class CmsController extends Controller
$travel_guide_content = $repo->findByID($page->getTravelGuideContentId());
}
*/
return $this->render('default/pages/cms/iq'. $template .'.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
'site_loading' => 'default',
'api' => $api,
'breadcrumb_entries' => $api->bread_crumb,
// 'search_form' => $this->createForm(SearchRequestType::class)->createView(),
'iq_page_title' => $api->title,
'iq_page_description' => $api->description,
// 'search_form' => $this->createForm(SearchRequestType::class)->createView(),
]);
}

View file

@ -57,9 +57,9 @@ class TravelBooking
/**
* @var integer
*
* @ORM\Column(name="salutation", type="integer", nullable=true)
* @ORM\Column(name="salutation_id", type="integer", nullable=true)
*/
private $salutation;
private $salutationId;
/**
* @var string
@ -82,13 +82,6 @@ class TravelBooking
*/
private $street;
/**
* @var string
*
* @ORM\Column(name="house_nr", type="string", length=255, nullable=true)
*/
private $houseNr;
/**
* @var string
*
@ -106,16 +99,16 @@ class TravelBooking
/**
* @var integer
*
* @ORM\Column(name="country", type="integer", nullable=true)
* @ORM\Column(name="country_id", type="integer", nullable=true)
*/
private $country;
private $countryId;
/**
* @var string
*
* @ORM\Column(name="mail", type="string", length=255, nullable=true)
* @ORM\Column(name="email", type="string", length=255, nullable=true)
*/
private $mail;
private $email;
/**
* @var string
@ -162,23 +155,31 @@ class TravelBooking
/**
* @var integer
*
* @ORM\Column(name="selected_child1", type="integer", nullable=true)
* @ORM\Column(name="selected_childs", type="integer", nullable=true)
*/
private $selectedChild1;
private $selectedChilds;
/**
* @var integer
* @var string
*
* @ORM\Column(name="selected_child2", type="integer", nullable=true)
* @ORM\Column(name="drafts", type="text", length=65535, nullable=true)
*/
private $selectedChild2;
private $drafts;
/**
* @var integer
* @var string
*
* @ORM\Column(name="selected_child3", type="integer", nullable=true)
* @ORM\Column(name="service_items", type="text", length=65535, nullable=true)
*/
private $selectedChild3;
private $serviceItems;
/**
* @var string
*
* @ORM\Column(name="arrangements", type="text", length=65535, nullable=true)
*/
private $arrangements;
/**
* @var string
@ -201,6 +202,21 @@ class TravelBooking
*/
private $participantsTotal;
/**
* @var string
*
* @ORM\Column(name="selected_travel", type="text", length=65535, nullable=true)
*/
private $selectedTravel;
/**
* @var float
*
* @ORM\Column(name="price", type="float", precision=10, scale=2, nullable=true)
*/
private $price;
/**
* @var float
*
@ -441,27 +457,27 @@ class TravelBooking
}
/**
* Set salutation
* Set salutationId
*
* @param integer $salutation
* @param integer $salutationId
*
* @return TravelBooking
*/
public function setSalutation($salutation)
public function setSalutationId($salutationId)
{
$this->salutation = $salutation;
$this->salutationId = $salutationId;
return $this;
}
/**
* Get salutation
* Get salutationId
*
* @return integer
*/
public function getSalutation()
public function getSalutationId()
{
return $this->salutation;
return $this->salutationId;
}
/**
@ -536,30 +552,6 @@ class TravelBooking
return $this->street;
}
/**
* Set houseNr
*
* @param string $houseNr
*
* @return TravelBooking
*/
public function setHouseNr($houseNr)
{
$this->houseNr = $houseNr;
return $this;
}
/**
* Get houseNr
*
* @return string
*/
public function getHouseNr()
{
return $this->houseNr;
}
/**
* Set zipcode
*
@ -609,51 +601,51 @@ class TravelBooking
}
/**
* Set country
* Set countryId
*
* @param integer $country
* @param integer $countryId
*
* @return TravelBooking
*/
public function setCountry($country)
public function setCountryId($countryId)
{
$this->country = $country;
$this->countryId = $countryId;
return $this;
}
/**
* Get country
* Get countryId
*
* @return integer
*/
public function getCountry()
public function getCountryId()
{
return $this->country;
return $this->countryId;
}
/**
* Set mail
* Set email
*
* @param string $mail
* @param string $email
*
* @return TravelBooking
*/
public function setMail($mail)
public function setEmail($email)
{
$this->mail = $mail;
$this->email = $email;
return $this;
}
/**
* Get mail
* Get email
*
* @return string
*/
public function getMail()
public function getEmail()
{
return $this->mail;
return $this->email;
}
/**
@ -704,6 +696,35 @@ class TravelBooking
return $this->mobile;
}
/**
* Set selectedTravel
*
* @param string $selectedTravel
*
* @return TravelBooking
*/
public function setSelectedTravel($selectedTravel)
{
$this->selectedTravel = is_array($selectedTravel) ? json_encode($selectedTravel) : $selectedTravel;
return $this;
}
/**
* Get selectedTravel
*
* @return string
*/
public function getSelectedTravel()
{
$ret = json_decode($this->selectedTravel, true);
if (empty($ret) || !is_array($ret))
{
return $this->selectedTravel;
}
return $ret;
}
/**
* Set selectedDeparture
*
@ -806,52 +827,30 @@ class TravelBooking
}
/**
* Set selectedChild1
* Set selectedChilds
*
* @param integer $selectedChild1
* @param integer $selectedChilds
*
* @return TravelBooking
*/
public function setSelectedChild1($selectedChild1)
public function setSelectedChilds($selectedChilds)
{
$this->selectedChild1 = $selectedChild1;
$this->selectedChilds = $selectedChilds;
return $this;
}
/**
* Get selectedChild1
* Get selectedChilds
*
* @return integer
*/
public function getSelectedChild1()
public function getSelectedChilds()
{
return $this->selectedChild1;
return $this->selectedChilds;
}
/**
* Set selectedChild2
*
* @param integer $selectedChild2
*
* @return TravelBooking
*/
public function setSelectedChild2($selectedChild2)
{
$this->selectedChild2 = $selectedChild2;
return $this;
}
/**
* Get selectedChild2
*
* @return integer
*/
public function getSelectedChild2()
{
return $this->selectedChild2;
}
/**
* Set selectedChild3
@ -877,6 +876,37 @@ class TravelBooking
return $this->selectedChild3;
}
/**
* Set drafts
*
* @param string $drafts
*
* @return TravelBooking
*/
public function setDrafts($drafts)
{
$this->drafts = is_array($drafts) ? json_encode($drafts) : $drafts;
return $this;
}
/**
* Get drafts
*
* @return string
*/
public function getDrafts()
{
$ret = json_decode($this->drafts, true);
if (empty($ret) || !is_array($ret))
{
return $this->drafts;
}
return $ret;
}
/**
* Set rooms
*
@ -886,7 +916,7 @@ class TravelBooking
*/
public function setRooms($rooms)
{
$this->options = is_array($rooms) ? json_encode($rooms) : $rooms;
$this->rooms = is_array($rooms) ? json_encode($rooms) : $rooms;
return $this;
}
@ -906,6 +936,64 @@ class TravelBooking
return $ret;
}
/**
* Set rooms
*
* @param string $serviceItems
*
* @return TravelBooking
*/
public function setServiceItems($serviceItems)
{
$this->serviceItems = is_array($serviceItems) ? json_encode($serviceItems) : $serviceItems;
return $this;
}
/**
* Get serviceItems
*
* @return string
*/
public function getServiceItems()
{
$ret = json_decode($this->serviceItems, true);
if (empty($ret) || !is_array($ret))
{
return $this->serviceItems;
}
return $ret;
}
/**
* Set rooms
*
* @param string $arrangements
*
* @return TravelBooking
*/
public function setArrangements($arrangements)
{
$this->arrangements = is_array($arrangements) ? json_encode($arrangements) : $arrangements;
return $this;
}
/**
* Get arrangements
*
* @return string
*/
public function getArrangements()
{
$ret = json_decode($this->arrangements, true);
if (empty($ret) || !is_array($ret))
{
return $this->arrangements;
}
return $ret;
}
/**
* Set participants
*
@ -922,21 +1010,20 @@ class TravelBooking
}
$participants = [];
for ($i = 0; $i < count($travelers); ++$i)
foreach($travelers as $traveler)
{
$traveler = $travelers[$i];
$birthdate = $traveler->getBirthDate();
if(!strtotime($birthdate)){
$birthdate = '01.01.1900';
}
$participants[''. ($i+1)] = [
$participants[] = [
'gender' => $traveler->getSex(),
'first_name' => $traveler->getFirstName(),
'last_name' => $traveler->getLastName(),
'birthday' => $birthdate,
'nationality' => $traveler->getNationality(),
'child' => $traveler->isChild(),
'acceptEntryRequirements' => $traveler->isAcceptEntryRequirements(),
];
}
@ -966,6 +1053,7 @@ class TravelBooking
$traveler->setFirstName($participant['first_name']);
$traveler->setLastName($participant['last_name']);
$traveler->setNationality($participant['nationality']);
$traveler->setChild($participant['child']);
if(!strtotime($participant['birthday'])){
$participant['birthday'] = '01.01.1900';
}
@ -999,6 +1087,30 @@ class TravelBooking
return $this->participantsTotal;
}
/**
* Set price
*
* @param float $price
*
* @return TravelBooking
*/
public function setPrice($price)
{
$this->price = $price;
return $this;
}
/**
* Get price
*
* @return float
*/
public function getPrice()
{
return $this->price;
}
/**
* Set priceTotal
*

View file

@ -2,6 +2,9 @@
namespace AppBundle\Entity;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\ClassMetadata;
/**
* TravelBookingRepository
*
@ -10,37 +13,149 @@ namespace AppBundle\Entity;
*/
class TravelBookingRepository extends \Doctrine\ORM\EntityRepository
{
private $serviceItems = [];
private $arrangements = [];
private function createServiceItem($serviceItemData){
$this->serviceItems[] = $serviceItemData;
}
private function createArrangement($arrangementData)
{
if (isset($arrangementData['data_s']) && is_array($arrangementData['data_s']))
{
$tmp = [];
foreach ($arrangementData['data_s'] as $k => $v)
{
$tmp[] .= $k .': '. $v;
}
$arrangementData['data_s'] = implode("\n", $tmp);
}
$this->arrangements[] = $arrangementData;
}
public function createFromBookingRequest(BookingRequest $bookingRequest, TravelDate $travelDate, $bookingPriceInfo)
{
$tp = $travelDate->getTravelProgram();
$ret = new TravelBooking();
$startDateStr = $travelDate->getStart()->format('Y-m-d');
$ret->setIp($_SERVER['REMOTE_ADDR']);
$ret->setCreated(new \DateTime());
$ret->setProgramName($tp->getTitle() . ' ('. $travelDate->getName() .')');
//$ret->setClass()
$ret->setSalutation($bookingRequest->getSalutation());
if(count($tp->getDrafts()) > 0){
$newDrafts = true;
}else{
$newDrafts = false;
}
//##lead createLead
$ret->setSalutationId($bookingRequest->getSalutation());
$ret->setFirstName($bookingRequest->getFirstName());
$ret->setLastName($bookingRequest->getLastName());
$ret->setStreet($bookingRequest->getStreetAddress());
//$ret->setHouseNr()
$ret->setZipcode($bookingRequest->getZipCode());
$ret->setCity($bookingRequest->getCity());
$ret->setCountry($bookingRequest->getNation());
$ret->setMail($bookingRequest->getEmail());
$ret->setCountryId($bookingRequest->getNation());
$ret->setPhone($bookingRequest->getPhone());
//phonemobile
$ret->setMobile($bookingRequest->getMobile());
$ret->setEmail($bookingRequest->getEmail());
//remarks
$ret->setComments($bookingRequest->getNotes());
//##booking createBooking
//booking_date
$ret->setCreated(new \DateTime());
//travelperiod_start //start_date
$ret->setSelectedStartDate($travelDate->getStart());
//travelperiod_end //start_date
$ret->setSelectedEndDate($travelDate->getEnd());
$ret->setProgramName($tp->getTitle() . ' ('. $travelDate->getName() .')');
$ret->setProgramId($tp->getId());
$ret->setPeriodId($travelDate->__getTravelPeriod()->getId());
$countries = [];
foreach ($tp->getCountries() as $country){
$countries[] = $country->getCrmId();
}
$ret->setSelectedTravel([
'travel_country_id' => $countries,
'travel_category_id' => $tp->getTravelCategory(),
'travelagenda_id' => $tp->getTravelAgenda(),
'travel_title' => $tp->getTitle(),
'travel_number' => $travelDate->getName()
]);
$ret->setSelectedDeparture([
'name' => $bookingRequest->getDeparture()->getName(),
'extra_charge' => $bookingRequest->getDeparture()->getExtraCharge(),
'extra_charge_total' => $bookingRequest->getTravelerCount()
]);
$ret->setSelectedStartDate($travelDate->getStart());
$ret->setSelectedEndDate($travelDate->getEnd());
$ret->setSelectedAdults($bookingRequest->getTravelerCount());
$ret->setSelectedChild1(0);
$ret->setSelectedChild2(0);
$ret->setSelectedChild3(0);
$ret->setPrice($bookingPriceInfo['totalWithoutInsurance']);
$ret->setPriceTotal($bookingPriceInfo['total']);
$ret->setDepositTotal($bookingPriceInfo['deposit_total']);
$ret->setFinalPayment($bookingPriceInfo['final_payment']);
$ret->setFinalPaymentDate(new \DateTime($bookingPriceInfo['final_payment_date']));
//## traveler createTraveler
$ret->setSelectedAdults($bookingRequest->getTravelerCount());
$ret->setSelectedChilds($bookingRequest->getChildrenCount());
$ret->setParticipantsTotal($bookingRequest->getTravelerCount() + $bookingRequest->getChildrenCount());
$ret->setParticipants($bookingRequest->getTravelers());
if ($tp->getIsMediated()) {
$serviceItemDefaults = [
'travel_company_id' => $tp->getOrganizer()->getCmsId(),
'travel_date' => $startDateStr,
'commission' => 0,
];
foreach ($bookingPriceInfo['rooms'] as $room) {
$this->createServiceItem($serviceItemDefaults + [
'service_price' => $room['price_total'],
'name' => $room['name'],
]);
}
$this->createServiceItem($serviceItemDefaults + [
'service_price' => $bookingRequest->getTravelerCount() * $bookingPriceInfo['departure']->getExtraCharge(),
'name' => $bookingRequest->getTravelerCount() .' x '. $bookingPriceInfo['departure']->getName()
]);
foreach ($bookingRequest->getTravelOptions() as $option) {
$this->createServiceItem($serviceItemDefaults + [
'service_price' => $option->getPrice() * $bookingRequest->getTravelerCount(),
'name' => $bookingRequest->getTravelerCount() .' x '. $option->getName()
]);
}
foreach ($bookingPriceInfo['classOptions'] as $classOption){
$this->createServiceItem($serviceItemDefaults + [
'service_price' => $classOption['count'] * $classOption['price'],
'name' => $classOption['count'] .' x '. $classOption['name']
]);
}
} else {
if($newDrafts){
$ret->setDrafts($this->createNewDrafts($bookingRequest, $tp, $travelDate, $bookingPriceInfo, $startDateStr));
}else{
//no new Drafts - create the old Arrangements
$this->createOldArrangement($bookingRequest, $tp, $travelDate, $bookingPriceInfo, $startDateStr);
}
}
$ret->setServiceItems($this->serviceItems);
$ret->setArrangements($this->arrangements);
$insurance = $bookingRequest->getInsurance();
$ret->setInsuranceName($insurance ? $insurance->getName() : '0'); // #TODO Adapted from v2
@ -54,25 +169,37 @@ class TravelBookingRepository extends \Doctrine\ORM\EntityRepository
foreach ($bookingPriceInfo['insurances'] as $insuranceInfo)
{
$insurances[] = [
'travel_company_id' => 30,
'service_price' => $insuranceInfo['count'] * $insuranceInfo['insurancePriceValue'],
'name' => $insuranceInfo['count'] . 'x ' . $insuranceInfo['insurance']->getName() . ' (' .
$insuranceInfo['insurancePrice']->getCode() . ')',
'commission' => round(($insuranceInfo['count'] * $insuranceInfo['insurancePriceValue']) * 20 / 100, 2),
'count' => $insuranceInfo['count'],
'price' => $insuranceInfo['insurancePriceValue'],
'code' => $insuranceInfo['insurancePrice']->getCode()
'code' => $insuranceInfo['insurancePrice']->getCode(),
'travel_date' => $startDateStr,
];
if ($insuranceInfo['countChild'] > 0) {
$insurances[] = [
'travel_company_id' => 30,
'service_price' => $insuranceInfo['countChild'] * $insuranceInfo['insuranceChildPriceValue'],
'name' => $insuranceInfo['countChild'] . 'x ' . $insuranceInfo['insurance']->getName() . ' (' .
$insuranceInfo['insuranceChildPrice']->getCode() . ')',
'commission' => round(($insuranceInfo['countChild'] * $insuranceInfo['insuranceChildPriceValue']) * 20 / 100, 2),
'count' => $insuranceInfo['countChild'],
'price' => $insuranceInfo['insuranceChildPriceValue'],
'code' => $insuranceInfo['insuranceChildPrice']->getCode(),
'travel_date' => $startDateStr,
];
}
}
$ret->setInsurances($insurances);
}
//$ret->setTravelCancellation($bookingRequest->getTravelCancellation());
$ret->setParticipants($bookingRequest->getTravelers());
$ret->setParticipantsTotal($bookingRequest->getTravelerCount());
$ret->setRooms($bookingPriceInfo['rooms']);
$ret->setPriceTotal($bookingPriceInfo['total']);
$ret->setDepositTotal($bookingPriceInfo['deposit_total']);
$ret->setFinalPayment($bookingPriceInfo['final_payment']);
$ret->setFinalPaymentDate(new \DateTime($bookingPriceInfo['final_payment_date']));
$ret->setComments($bookingRequest->getNotes());
if (empty($bookingPriceInfo['options']))
{
$ret->setOptions(false);
@ -95,4 +222,209 @@ class TravelBookingRepository extends \Doctrine\ORM\EntityRepository
return $ret;
}
private function createNewDrafts(BookingRequest $bookingRequest, TravelProgram $tp, TravelDate $travelDate, $bookingPriceInfo, $startDateStr){
//make an request omn the new API
$endDateStr = $travelDate->getEnd()->format('Y-m-d');
$rooms = [];
$i = 0;
foreach ($bookingPriceInfo['rooms'] as $room)
{
$rooms[$i] = [
'name' => $room['name'],
'price_adult' => $room['price'],
'adult' => $room['adults'],
'children' => 0,
'price_children' => 0,
'price_children_full' => 0,
'price_adult_full' => $room['price_full'],
];
if($room['children'] > 0){
$rooms[$i]['children'] = $room['children'];
$rooms[$i]['price_children'] = $room['price_children'];
$rooms[$i]['price_children_full'] = $room['price_children_full'];
}
$i++;
}
$class_options = [];
// Actually: extra_category
foreach ($bookingPriceInfo['classOptions'] as $classOption)
{
$class_options[] = [
'name' => $classOption['name'],
'price' => $classOption['price'],
'count' => $classOption['count'],
];
}
$travel_options = [];
$i = 0;
foreach ($bookingRequest->getTravelOptions() as $option)
{
$travel_options[$i] = [
'name' => $option->getName(),
'price_adult' => $option->getPrice(),
'adult' => $bookingRequest->getTravelerCount(),
'children' => 0,
'price_children' => 0,
];
if($bookingRequest->getChildrenCount() > 0){
$travel_options[$i]['children'] = $bookingRequest->getChildrenCount();
$travel_options[$i]['price_children'] = $option->getPriceChildren();
}
$i++;
}
$dis = [];
$i = 0;
foreach ($bookingPriceInfo['discount'] as $discount)
{
$dis[$i] = [
'count' => $discount['count'],
'value' => $discount['value'],
'price' => round($discount['price_discount'], 2)
];
$i++;
}
return [
'travel_program_id' => $tp->getId(),
'comfort' => $bookingRequest->getComfort(),
'booking_before' => $bookingPriceInfo['booking_before'],
'booking_after' => $bookingPriceInfo['booking_after'],
'request_date' => (new \DateTime())->format('Y-m-d'),
'startDateStr' => $startDateStr,
'endDateStr' => $endDateStr,
'departure' => $bookingPriceInfo['departure']->getName(),
'departure_extra_charge' => $bookingPriceInfo['departure']->getExtraCharge(),
'traveler' => ($bookingRequest->getTravelerCount() + $bookingRequest->getChildrenCount()),
'title' => $tp->getTitle(),
'number' => $travelDate->getName(),
'rooms' => $rooms,
'class_options' => $class_options,
'travel_options' => $travel_options,
'discount' => $dis,
];
}
private function createOldArrangement(BookingRequest $bookingRequest, TravelProgram $tp, TravelDate $travelDate, $bookingPriceInfo, $startDateStr){
$viewPosition = 100;
$viewPositionPrice = 50;
$endDateStr = $travelDate->getEnd()->format('Y-m-d');
$arrangementDefaults = [
'state' => (new \DateTime())->format('Y-m-d'),
'in_pdf' => 1
];
$this->createArrangement( $arrangementDefaults + [
'type_id' => 4, // Flug
'type_s' => 'Flug',
'begin' => $startDateStr,
'view_position' => --$viewPosition,
'data_s' => ['Hinflug' => 'von '. $bookingPriceInfo['departure']->getName()],
]);
$this->createArrangement( $arrangementDefaults + [
'type_id' => 26, // Preisinformation
'type_s' => 'Preisinformation',
'view_position' => --$viewPositionPrice,
'data_s' => [
'Name' => 'Abfahrts-/Abflugort '. $bookingPriceInfo['departure']->getName(),
'Preis' => $bookingPriceInfo['departure']->getExtraCharge(),
'Teilnehmer' => ($bookingRequest->getTravelerCount() + $bookingRequest->getChildrenCount()),
],
]);
$this->createArrangement( $arrangementDefaults + [
'type_id' => 24, // Rundreise
'type_s' => 'Rundreise', // Rundreise
'begin' => $startDateStr,
'end' => $endDateStr,
'view_position' => --$viewPosition,
'data_s' => ['Name' => $tp->getTitle() .' ('. $travelDate->getName() .')'],
]);
$roomStrs = [];
foreach ($bookingPriceInfo['rooms'] as $room)
{
$roomStrs[] = '1x '. $room['name'];
$child = array();
if($room['children'] > 0){
$child = [
'Kind' => $room['children'],
'KindPreis' => $room['price_children'],
];
}
$data = [
'Name' => 'pro Person im \''. $room['name'] .'\'',
'Preis' => $room['price'],
'Teilnehmer' => $room['adults'],
];
$this->createArrangement( $arrangementDefaults + [
'type_id' => 26, // Preisinformation
'type_s' => 'Preisinformation',
'view_position' => --$viewPositionPrice,
'data_s' => array_merge($data, $child),
]);
}
$this->createArrangement( $arrangementDefaults + [
'type_id' => 5, // Hotel
'type_s' => 'Hotel',
'begin' => $startDateStr,
'end' => $endDateStr,
'view_position' => --$viewPosition,
'data_s' => ['Zimmer' => implode(', ', $roomStrs)],
]);
// Actually: extra_category
foreach ($bookingPriceInfo['classOptions'] as $classOption)
{
$this->createArrangement( $arrangementDefaults + [
'type_id' => 26, // Preisinformation
'type_s' => 'Preisinformation',
'view_position' => --$viewPositionPrice,
'data_s' => [
'Name' => $classOption['name'],
'Preis' => $classOption['price'],
'Teilnehmer' => $classOption['count'],
],
]);
}
$this->createArrangement( $arrangementDefaults + [
'type_id' => 4, // Flug
'type_s' => 'Flug',
'begin' => $endDateStr,
'view_position' => --$viewPosition,
'data_s' => ['Rückflug' => $bookingRequest->getDeparture()->getName()],
]);
foreach ($bookingRequest->getTravelOptions() as $option)
{
$child = array();
if($option->getPriceChildren() > 0){
$child = [
'Kind' => $bookingRequest->getChildrenCount(),
'KindPreis' => $option->getPriceChildren(),
];
}
$data = [
'Name' => $option->getName(),
'Preis' => $option->getPrice(),
'Teilnehmer' => $bookingRequest->getTravelerCount(),
];
$this->createArrangement($arrangementDefaults + [
'type_id' => 26, // Preisinformation
'type_s' => 'Preisinformation',
'view_position' => --$viewPositionPrice,
'data_s' => array_merge($data, $child)
]);
}
}
}

View file

@ -64,6 +64,13 @@ class TravelCountry
*/
private $id;
/**
* @var integer
*
* @ORM\Column(name="crm_id", type="integer")
*/
private $crmId;
/**
* @var boolean
*
@ -95,6 +102,29 @@ class TravelCountry
/**
* Set name
*
* @param string $crmId
*
* @return TravelCountry
*/
public function setCrmId($crmId)
{
$this->crmId = $crmId;
return $this;
}
/**
* Get crmId
*
* @return string
*/
public function getCrmId()
{
return $this->crmId;
}
/**
* Set name

View file

@ -40,6 +40,14 @@ class TravelProgramImage
*/
private $type;
/**
* @var string
*
* @ORM\Column(name="position", type="string", length=10, nullable=true)
*/
private $position;
/**
* @var integer
*
@ -157,6 +165,35 @@ class TravelProgramImage
return $this->type;
}
/**
* Set type
*
* @param string $position
*
* @return TravelProgramImage
*/
public function setPosition($position)
{
$this->position = $position;
return $this;
}
/**
* Get position
*
* @return string
*/
public function getPosition()
{
if(!$this->position){
return 'bottom';
}
return $this->position;
}
/**
* Get id
*

View file

@ -65,31 +65,31 @@ class BookingSternToursCrmExporter extends SternToursCrmExporter
foreach ($bookingPriceInfo['rooms'] as $room)
{
$this->createServiceItem($bookingUrl, $serviceItemDefaults + [
'service_price' => $room['price_total'],
'name' => $room['name'],
]);
'service_price' => $room['price_total'],
'name' => $room['name'],
]);
}
$this->createServiceItem($bookingUrl, $serviceItemDefaults + [
'service_price' => $bookingRequest->getTravelerCount() * $bookingPriceInfo['departure']->getExtraCharge(),
'name' => $bookingRequest->getTravelerCount() .' x '. $bookingPriceInfo['departure']->getName()
]);
'service_price' => $bookingRequest->getTravelerCount() * $bookingPriceInfo['departure']->getExtraCharge(),
'name' => $bookingRequest->getTravelerCount() .' x '. $bookingPriceInfo['departure']->getName()
]);
foreach ($bookingRequest->getTravelOptions() as $option)
{
$this->createServiceItem($bookingUrl, $serviceItemDefaults + [
'service_price' => $option->getPrice() * $bookingRequest->getTravelerCount(),
'name' => $bookingRequest->getTravelerCount() .' x '. $option->getName()
]);
'service_price' => $option->getPrice() * $bookingRequest->getTravelerCount(),
'name' => $bookingRequest->getTravelerCount() .' x '. $option->getName()
]);
}
// Actually: extra_category
foreach ($bookingPriceInfo['classOptions'] as $classOption)
{
$this->createServiceItem($bookingUrl, $serviceItemDefaults + [
'service_price' => $classOption['count'] * $classOption['price'],
'name' => $classOption['count'] .' x '. $classOption['name']
]);
'service_price' => $classOption['count'] * $classOption['price'],
'name' => $classOption['count'] .' x '. $classOption['name']
]);
}
}
else {
@ -380,7 +380,7 @@ class BookingSternToursCrmExporter extends SternToursCrmExporter
}
private function createBooking(BookingRequest $bookingRequest, TravelDate $travelDate, $bookingPriceInfo,
$customerId, $leadId, $newDrafts = false)
$customerId, $leadId, $newDrafts = false)
{
$tp = $travelDate->getTravelProgram();
$resp = $this->httpPost('booking', ['booking' => [
@ -458,7 +458,7 @@ class BookingSternToursCrmExporter extends SternToursCrmExporter
}
private function warn($msg, BookingRequest $bookingRequest = null, TravelDate $travelDate = null,
$level = Logger::WARNING)
$level = Logger::WARNING)
{
$this->logger->log($level, 'SternToursCrmBookingExporter: '. $msg);
$this->logger->log($level, '*** Date: '. (new \DateTime())->format('d.m.Y'));

View file

@ -98,24 +98,24 @@ abstract class SternToursCrmExporter
$result = curl_exec($ch);
$r = json_decode($result);
if($r->success) {
//api URL
$data = json_encode($postData);
//var_dump($data);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $r->success->token, 'Accept:application/json', 'Content-Type:application/json']);
curl_setopt($ch, CURLOPT_URL, $baseUrl.$action);
$result = curl_exec($ch);
$r = json_decode($result);
//var_dump($r);
curl_close($ch);
if(isset($r->success)) {
return $r->success;
}
if(isset($r->error)) {
$this->logger->warn('*** v3 Error: '.$r->error);
return $r->error;
}
//api URL
$data = json_encode($postData);
//var_dump($data);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $r->success->token, 'Accept:application/json', 'Content-Type:application/json']);
curl_setopt($ch, CURLOPT_URL, $baseUrl.$action);
$result = curl_exec($ch);
$r = json_decode($result);
//var_dump($r);
curl_close($ch);
if(isset($r->success)) {
return $r->success;
}
if(isset($r->error)) {
$this->logger->warn('*** v3 Error: '.$r->error);
return $r->error;
}
}
return $ret;
}

View file

@ -0,0 +1,476 @@
<?php
/**
* @author Ulrich Hecht <ulrich.hecht@hecht-software.de>
* @date 02/13/2017
*/
namespace AppBundle\Export;
use AppBundle\Entity\BookingRequest;
use AppBundle\Entity\TravelDate;
use AppBundle\Entity\Traveler;
use AppBundle\Util;
use Monolog\Logger;
class BookingSternToursCrmExporter extends SternToursCrmExporter
{
public function __construct(Logger $logger)
{
parent::__construct($logger);
}
public function process(BookingRequest $bookingRequest, TravelDate $travelDate, $bookingPriceInfo)
{
$tp = $travelDate->getTravelProgram();
$startDateStr = $travelDate->getStart()->format('Y-m-d');
if(count($tp->getDrafts()) > 0){
$newDrafts = true;
}else{
$newDrafts = false;
}
$lead = $this->createLead($bookingRequest, $travelDate);
if ($lead === null)
{
$this->warn('Failed creating lead in CRM Lead', $bookingRequest, $travelDate, Logger::ERROR);
return false;
}
$bookingUrl = $this->createBooking($bookingRequest, $travelDate, $bookingPriceInfo, $lead['customer_id'], $lead['id'], $newDrafts);
if ($bookingUrl === false)
{
$this->warn('Failed creating booking in CRM Booking', $bookingRequest, $travelDate, Logger::ERROR);
return false;
}
for ($i = 1; $i < ($bookingRequest->getTravelerCount() + $bookingRequest->getChildrenCount()); ++$i)
{
if (!$this->createTraveler($bookingUrl, $bookingRequest->getTravelers()[$i]))
{
$this->warn('Failed creating traveler with index '. $i .' in CRM.', $bookingRequest, $travelDate);
}
}
if ($tp->getIsMediated())
{
$serviceItemDefaults = [
'travel_company_id' => $tp->getOrganizer()->getCmsId(),
'travel_date' => $startDateStr,
'commission' => 0,
];
foreach ($bookingPriceInfo['rooms'] as $room)
{
$this->createServiceItem($bookingUrl, $serviceItemDefaults + [
'service_price' => $room['price_total'],
'name' => $room['name'],
]);
}
$this->createServiceItem($bookingUrl, $serviceItemDefaults + [
'service_price' => $bookingRequest->getTravelerCount() * $bookingPriceInfo['departure']->getExtraCharge(),
'name' => $bookingRequest->getTravelerCount() .' x '. $bookingPriceInfo['departure']->getName()
]);
foreach ($bookingRequest->getTravelOptions() as $option)
{
$this->createServiceItem($bookingUrl, $serviceItemDefaults + [
'service_price' => $option->getPrice() * $bookingRequest->getTravelerCount(),
'name' => $bookingRequest->getTravelerCount() .' x '. $option->getName()
]);
}
// Actually: extra_category
foreach ($bookingPriceInfo['classOptions'] as $classOption)
{
$this->createServiceItem($bookingUrl, $serviceItemDefaults + [
'service_price' => $classOption['count'] * $classOption['price'],
'name' => $classOption['count'] .' x '. $classOption['name']
]);
}
}
else {
//has drafts - get the new Drafts from the CRM v3
if($newDrafts){
$this->createNewDrafts($bookingUrl, $bookingRequest, $tp, $travelDate, $bookingPriceInfo, $startDateStr);
}else{
//no new Drafts - create the old Arrangements
$this->createOldArrangement($bookingUrl, $bookingRequest, $tp, $travelDate, $bookingPriceInfo, $startDateStr);
}
foreach ($bookingPriceInfo['insurances'] as $insuranceInfo) {
$this->createServiceItem($bookingUrl, [
'travel_company_id' => 30,
'service_price' => $insuranceInfo['count'] * $insuranceInfo['insurancePriceValue'],
'name' => $insuranceInfo['count'] . 'x ' . $insuranceInfo['insurance']->getName() . ' (' .
$insuranceInfo['insurancePrice']->getCode() . ')',
'commission' => round(($insuranceInfo['count'] * $insuranceInfo['insurancePriceValue']) * 20 / 100, 2),
'travel_date' => $startDateStr,
]);
//child
if ($insuranceInfo['countChild'] > 0) {
$this->createServiceItem($bookingUrl, [
'travel_company_id' => 30,
'service_price' => $insuranceInfo['countChild'] * $insuranceInfo['insuranceChildPriceValue'],
'name' => $insuranceInfo['countChild'] . 'x ' . $insuranceInfo['insurance']->getName() . ' (' .
$insuranceInfo['insuranceChildPrice']->getCode() . ')',
'commission' => round(($insuranceInfo['countChild'] * $insuranceInfo['insuranceChildPriceValue']) * 20 / 100, 2),
'travel_date' => $startDateStr,
]);
}
}
}
return $bookingUrl;
}
private function createNewDrafts($bookingUrl, $bookingRequest, $tp, $travelDate, $bookingPriceInfo, $startDateStr){
//make an request omn the new API
$endDateStr = $travelDate->getEnd()->format('Y-m-d');
$rooms = [];
$i = 0;
foreach ($bookingPriceInfo['rooms'] as $room)
{
$rooms[$i] = [
'name' => $room['name'],
'price_adult' => $room['price'],
'adult' => $room['adults'],
'children' => 0,
'price_children' => 0,
'price_children_full' => 0,
'price_adult_full' => $room['price_full'],
];
if($room['children'] > 0){
$rooms[$i]['children'] = $room['children'];
$rooms[$i]['price_children'] = $room['price_children'];
$rooms[$i]['price_children_full'] = $room['price_children_full'];
}
$i++;
}
$class_options = [];
// Actually: extra_category
foreach ($bookingPriceInfo['classOptions'] as $classOption)
{
$class_options[] = [
'name' => $classOption['name'],
'price' => $classOption['price'],
'count' => $classOption['count'],
];
}
$travel_options = [];
$i = 0;
foreach ($bookingRequest->getTravelOptions() as $option)
{
$travel_options[$i] = [
'name' => $option->getName(),
'price_adult' => $option->getPrice(),
'adult' => $bookingRequest->getTravelerCount(),
'children' => 0,
'price_children' => 0,
];
if($bookingRequest->getChildrenCount() > 0){
$travel_options[$i]['children'] = $bookingRequest->getChildrenCount();
$travel_options[$i]['price_children'] = $option->getPriceChildren();
}
$i++;
}
$dis = [];
$i = 0;
foreach ($bookingPriceInfo['discount'] as $discount)
{
$dis[$i] = [
'count' => $discount['count'],
'value' => $discount['value'],
'price' => $discount['price_discount']
];
$i++;
}
$resp = $this->httpPostAPIv3('draft/create_drafts_from_booking', [
'travel_program_id' => $tp->getId(),
'comfort' => $bookingRequest->getComfort(),
'booking_before' => $bookingPriceInfo['booking_before'],
'booking_after' => $bookingPriceInfo['booking_after'],
'booking_id' => array_values(array_slice(explode("/", $bookingUrl), -1))[0],
'request_date' => (new \DateTime())->format('Y-m-d'),
'startDateStr' => $startDateStr,
'endDateStr' => $endDateStr,
'departure' => $bookingPriceInfo['departure']->getName(),
'departure_extra_charge' => $bookingPriceInfo['departure']->getExtraCharge(),
'traveler' => ($bookingRequest->getTravelerCount() + $bookingRequest->getChildrenCount()),
'title' => $tp->getTitle(),
'number' => $travelDate->getName(),
'rooms' => $rooms,
'class_options' => $class_options,
'travel_options' => $travel_options,
'discount' => $dis,
]);
if (count($resp) == 0)
{
$this->warn('Failed retrieving newly created lead object', $bookingRequest, $travelDate);
}
return $resp;
}
private function createOldArrangement($bookingUrl, $bookingRequest, $tp, $travelDate, $bookingPriceInfo, $startDateStr){
$viewPosition = 100;
$viewPositionPrice = 50;
$endDateStr = $travelDate->getEnd()->format('Y-m-d');
$arrangementDefaults = [
'state' => (new \DateTime())->format('Y-m-d'),
'in_pdf' => 1
];
$this->createArrangement($bookingUrl, $arrangementDefaults + [
'type_id' => 4, // Flug
'type_s' => 'Flug',
'begin' => $startDateStr,
'view_position' => --$viewPosition,
'data_s' => ['Hinflug' => 'von '. $bookingPriceInfo['departure']->getName()],
]);
$this->createArrangement($bookingUrl, $arrangementDefaults + [
'type_id' => 26, // Preisinformation
'type_s' => 'Preisinformation',
'view_position' => --$viewPositionPrice,
'data_s' => [
'Name' => 'Abfahrts-/Abflugort '. $bookingPriceInfo['departure']->getName(),
'Preis' => $bookingPriceInfo['departure']->getExtraCharge(),
'Teilnehmer' => ($bookingRequest->getTravelerCount() + $bookingRequest->getChildrenCount()),
],
]);
$this->createArrangement($bookingUrl, $arrangementDefaults + [
'type_id' => 24, // Rundreise
'type_s' => 'Rundreise', // Rundreise
'begin' => $startDateStr,
'end' => $endDateStr,
'view_position' => --$viewPosition,
'data_s' => ['Name' => $tp->getTitle() .' ('. $travelDate->getName() .')'],
]);
$roomStrs = [];
foreach ($bookingPriceInfo['rooms'] as $room)
{
$roomStrs[] = '1x '. $room['name'];
$child = array();
if($room['children'] > 0){
$child = [
'Kind' => $room['children'],
'KindPreis' => $room['price_children'],
];
}
$data = [
'Name' => 'pro Person im \''. $room['name'] .'\'',
'Preis' => $room['price'],
'Teilnehmer' => $room['adults'],
];
$data = array_merge($data, $child);
$this->createArrangement($bookingUrl, $arrangementDefaults + [
'type_id' => 26, // Preisinformation
'type_s' => 'Preisinformation',
'view_position' => --$viewPositionPrice,
'data_s' => $data,
]);
}
$this->createArrangement($bookingUrl, $arrangementDefaults + [
'type_id' => 5, // Hotel
'type_s' => 'Hotel',
'begin' => $startDateStr,
'end' => $endDateStr,
'view_position' => --$viewPosition,
'data_s' => ['Zimmer' => implode(', ', $roomStrs)],
]);
// Actually: extra_category
foreach ($bookingPriceInfo['classOptions'] as $classOption)
{
$this->createArrangement($bookingUrl, $arrangementDefaults + [
'type_id' => 26, // Preisinformation
'type_s' => 'Preisinformation',
'view_position' => --$viewPositionPrice,
'data_s' => [
'Name' => $classOption['name'],
'Preis' => $classOption['price'],
'Teilnehmer' => $classOption['count'],
],
]);
}
$this->createArrangement($bookingUrl, $arrangementDefaults + [
'type_id' => 4, // Flug
'type_s' => 'Flug',
'begin' => $endDateStr,
'view_position' => --$viewPosition,
'data_s' => ['Rückflug' => $bookingRequest->getDeparture()->getName()],
]);
foreach ($bookingRequest->getTravelOptions() as $option)
{
$child = array();
if($option->getPriceChildren() > 0){
$child = [
'Kind' => $bookingRequest->getChildrenCount(),
'KindPreis' => $option->getPriceChildren(),
];
}
$data = [
'Name' => $option->getName(),
'Preis' => $option->getPrice(),
'Teilnehmer' => $bookingRequest->getTravelerCount(),
];
$data = array_merge($data, $child);
$this->createArrangement($bookingUrl, $arrangementDefaults + [
'type_id' => 26, // Preisinformation
'type_s' => 'Preisinformation',
'view_position' => --$viewPositionPrice,
'data_s' => $data
]);
}
}
private function createLead(BookingRequest $bookingRequest, TravelDate $travelDate)
{
$resp = $this->httpPost('lead', ['lead' => [
'customerForm' => [
'salutation_id' => $bookingRequest->getSalutation(),
'name' => $bookingRequest->getLastName(),
'firstname' => $bookingRequest->getFirstName(),
'street' => $bookingRequest->getStreetAddress(),
'zip' => $bookingRequest->getZipCode(),
'city' => $bookingRequest->getCity(),
'country_id' => $bookingRequest->getNation(),
'phone' => $bookingRequest->getPhone(),
'phonemobile' => $bookingRequest->getMobile(),
'email' => $bookingRequest->getEmail()
],
'request_date' => (new \DateTime())->format('Y-m-d'),
'sf_guard_user_id' => self::API_USER_ID,
'status_id' => 7, // 'gebucht'
'travelperiod_start' => $travelDate->getStart()->format('Y-m-d'),
'travelperiod_end' => $travelDate->getEnd()->format('Y-m-d'),
//'travelcategory_id'
'is_closed' => 1,
'website_id' => self::WEBSITE_ID,
'initialcontacttype_id' => 14,
// 'travelperiod_length
'remarks' => $bookingRequest->getNotes()
]]);
if ($resp['success'])
{
$ret = $this->httpGet($resp['location']);
if ($ret == null)
{
$this->warn('Failed retrieving newly created lead object', $bookingRequest, $travelDate);
}
return $ret;
}
return null;
}
private function createBooking(BookingRequest $bookingRequest, TravelDate $travelDate, $bookingPriceInfo,
$customerId, $leadId, $newDrafts = false)
{
$tp = $travelDate->getTravelProgram();
$resp = $this->httpPost('booking', ['booking' => [
'booking_date' => (new \DateTime())->format('Y-m-d'),
'customer_id' => $customerId,
'lead_id' => $leadId,
'travel_country_id' => $tp->getTravelCountry(),
'travel_category_id' => $tp->getTravelCategory(),
'travelagenda_id' => $tp->getTravelAgenda(),
'sf_guard_user_id' => self::API_USER_ID,
'branch_id' => 4,
'website_id' => self::WEBSITE_ID,
'title' => $tp->getTitle(),
'start_date' => $travelDate->getStart()->format('Y-m-d'),
'end_date' => $travelDate->getEnd()->format('Y-m-d'),
'pax' => $bookingRequest->getTravelerCount(),
'travel_number' => $travelDate->getName(),
'price' => $bookingPriceInfo['totalWithoutInsurance'],
'price_total' => $bookingPriceInfo['total'],
'deposit_total' => $bookingPriceInfo['deposit_total'],
'final_payment' => $bookingPriceInfo['final_payment'],
'final_payment_date' => date("Y-m-d",strtotime($bookingPriceInfo['final_payment_date'])),
'participant_salutation_id' => $bookingRequest->getTravelers()[0]->getSex(),
'participant_name' => $bookingRequest->getTravelers()[0]->getLastName(),
'participant_firstname' => $bookingRequest->getTravelers()[0]->getFirstName(),
'participant_birthdate' => $bookingRequest->getTravelers()[0]->getBirthDate(),
'new_drafts' => $newDrafts,
]]);
if (!$resp['success'])
{
return false;
}
return $resp['location'];
}
private function createTraveler($bookingUrl, Traveler $traveler)
{
$resp = $this->httpPost($bookingUrl .'/participant.json', ['participant' => [
'participant_salutation_id' => $traveler->getSex(),
'participant_name' => $traveler->getLastName(),
'participant_firstname' => $traveler->getFirstName(),
'participant_birthdate' => $traveler->getBirthDate(),
'participant_child' => $traveler->isChild(),
]], true);
return $resp['success'];
}
private function createServiceItem($bookingUrl, $serviceItemData)
{
$resp = $this->httpPost($bookingUrl .'/serviceitem.json', ['booking_service_item' => $serviceItemData], true);
if (!$resp['success'])
{
$this->warn('Failed creating service item '. $serviceItemData['name'] .' for booking '. $bookingUrl);
}
return $resp['success'];
}
private function createArrangement($bookingUrl, $arrangementData)
{
if (isset($arrangementData['data_s']) && is_array($arrangementData['data_s']))
{
$tmp = [];
foreach ($arrangementData['data_s'] as $k => $v)
{
$tmp[] .= $k .': '. $v;
}
$arrangementData['data_s'] = implode("\n", $tmp);
}
$resp = $this->httpPost($bookingUrl .'/arrangement.json', ['arrangement' => $arrangementData], true);
if (!$resp['success'])
{
$this->warn('Failed creating arrangement item '. $arrangementData['type_s'] .' for booking '. $bookingUrl);
}
return $resp['success'];
}
private function warn($msg, BookingRequest $bookingRequest = null, TravelDate $travelDate = null,
$level = Logger::WARNING)
{
$this->logger->log($level, 'SternToursCrmBookingExporter: '. $msg);
$this->logger->log($level, '*** Date: '. (new \DateTime())->format('d.m.Y'));
if ($travelDate !== null)
{
$this->logger->log($level, '*** Travel date: '. $travelDate->getName() .'('. $travelDate->getStart()->format('d.m.Y') .
' - '. $travelDate->getEnd()->format('d.m.Y') .')');
//$this->logger->warn('*** Travel program ID: '. $travelDate->)
}
if ($bookingRequest !== null)
{
$this->logger->log($level, '*** User name: '. $bookingRequest->getFirstName() .' '. $bookingRequest->getLastName());
}
}
}

View file

@ -0,0 +1,123 @@
<?php
/**
* @author Ulrich Hecht <ulrich.hecht@hecht-software.de>
* @date 02/21/2017
*/
namespace AppBundle\Export;
use AppBundle\Util;
use Monolog\Logger;
abstract class SternToursCrmExporter
{
//auto
const API_URL_LOCAL = 'http://cms-stern-tours.local/api';
const API_v3_URL_LOCAL = 'http://mein.sterntours.local/';
const API_URL = 'https://cms.stern-tours.net/api';
const API_v3_URL = 'https://mein.sterntours.de/';
const API_KEY = 'f6077389c9ce710e554763a5de02c8ec';
const API_USER_ID = 15; // 'apiuser'
const WEBSITE_ID = 1; // 'sterntours.de'
const API_v3_MAIL = 'info@mein.sterntours.de';
const API_v3_PASS = '6m9j,v2GE8px<bt75w';
protected $logger;
public function __construct(Logger $logger)
{
$this->logger = $logger;
}
protected final function httpGet($url)
{
$auth = base64_encode("star:4w28baV8xEZa0SR4");
$resp = Util::httpGet($url, ['X-ApiKey: '. self::API_KEY, 'Authorization: Basic '.$auth]);
$ret = json_decode($resp['content'], true);
if ($ret === null)
{
$this->logger->warn(get_class($this) .': Invalid server response: '. $resp['content']);
$this->logger->warn('*** Date: '. (new \DateTime())->format('d.m.Y'));
}
return $ret;
}
protected final function httpPost($context, $postData = [], $isContextFullUrl = false)
{
$baseUrl = self::API_URL;
if($_SERVER['HTTP_HOST'] == 'sterntours.local') {
$baseUrl = self::API_URL_LOCAL;
}
$url = $isContextFullUrl ? $context : $baseUrl.'/'. $context .'.json';
$auth = base64_encode("star:4w28baV8xEZa0SR4");
$resp = Util::httpPost($url, $postData, ['X-ApiKey: '. self::API_KEY, 'Authorization: Basic '.$auth], true);
return [
'content' => json_decode($resp['content']),
'location' => isset($resp['response_headers']['location'])
? $resp['response_headers']['location']
: null,
'success' => $resp['success'] && ($resp['status_code'] == 201)
];
}
protected final function httpPostAPIv3($action, $postData = [])
{
return self::loadFromApi($action, $postData);
}
protected final function loadFromApi($action, $postData){
//first - login and get token
$baseUrl = self::API_v3_URL.'api/';
if($_SERVER['HTTP_HOST'] == 'sterntours.local') {
$baseUrl = self::API_v3_URL_LOCAL.'api/';
}
$data = array(
'email' => self::API_v3_MAIL,
'password' => self::API_v3_PASS,
);
$ret = [];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $baseUrl.'login');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_POST, count($data));
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$result = curl_exec($ch);
$r = json_decode($result);
if($r->success) {
//api URL
$data = json_encode($postData);
//var_dump($data);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $r->success->token, 'Accept:application/json', 'Content-Type:application/json']);
curl_setopt($ch, CURLOPT_URL, $baseUrl.$action);
$result = curl_exec($ch);
$r = json_decode($result);
//var_dump($r);
curl_close($ch);
if(isset($r->success)) {
return $r->success;
}
if(isset($r->error)) {
$this->logger->warn('*** v3 Error: '.$r->error);
return $r->error;
}
}
return $ret;
}
}

View file

@ -6184,6 +6184,17 @@ hr.primary {
}
.tab-pane .h1l {
font-size: 25px;
position: relative;
padding-bottom: 8px;
border-bottom: 1px solid #ffc926;
font-weight: 400;
margin-bottom: 20px;
color: #777;
line-height: 1.2em;
}
.youtube {
margin-bottom: 25px;
position: relative;

View file

@ -173,7 +173,7 @@ class Util
public static function loadFromApi($action, $postData){
$baseUrl = 'https://mein.sterntours.de/api/';
if($_SERVER['HTTP_HOST'] == 'sterntours.local') {
if($_SERVER['HTTP_HOST'] === 'sterntours.local') {
$baseUrl = 'http://mein.sterntours.local/api/';
}
$postData['key'] = 'f6077389c9ce710e554763a5de02c8ec';

File diff suppressed because one or more lines are too long