... | ... |
@@ -56,6 +56,7 @@ $GLOBALS['TL_DCA']['tl_vr_wa_reservation'] = array |
56 | 56 |
'sorten' => array |
57 | 57 |
( |
58 | 58 |
'foreignKey' => 'tl_vr_wa_rebsorte.title', |
59 |
+ 'eval' => array('multiple'=>true, 'csv'=>','), |
|
59 | 60 |
'sql' => "blob NULL", |
60 | 61 |
'relation' => array('type' => 'hasMany', 'load' => 'lazy') |
61 | 62 |
), |
62 | 63 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,72 @@ |
1 |
+{% block content %} |
|
2 |
+ {% if modal %}<div class="modal-content">{% endif %} |
|
3 |
+ <div id="wa-slot-{{ id }}"> |
|
4 |
+ <dl> |
|
5 |
+ <dt>Tag/Uhrzeit</dt> |
|
6 |
+ <dd>{{ slot.time|date('d.m.Y H:i') }}</dd> |
|
7 |
+ |
|
8 |
+ <dt>Gebuchte Behälterkapazität</dt> |
|
9 |
+ <dd>{{ buchung.behaelter }}</dd> |
|
10 |
+ |
|
11 |
+ <dt>Anliefernde Sorten</dt> |
|
12 |
+ <dd>{{ buchung.sorten|join(', ') }}</dd> |
|
13 |
+ </dl> |
|
14 |
+ <h3>Reservierung ändern</h3> |
|
15 |
+ <form hx-post="/_ajax/vr_wa/v1/slot?do=updateReservation"> |
|
16 |
+ <input type="hidden" name="id" value="{{ id }}"> |
|
17 |
+ <div class="dflex"> |
|
18 |
+ <div> |
|
19 |
+ <label for="res-behaelter">Liefernde Behältermenge</label> |
|
20 |
+ <select id="res-behaelter" name="behaelter" required> |
|
21 |
+ <option value="">-</option> |
|
22 |
+ {% for option in buchen.behaelter %} |
|
23 |
+ <option value="{{ option }}"{{ buchung.behaelter == option ? ' selected' : '' }}>{{ option }}</option> |
|
24 |
+ {% endfor %} |
|
25 |
+ </select> |
|
26 |
+ </div> |
|
27 |
+ <fieldset> |
|
28 |
+ <legend>Anliefernde Rebsorte(n)</legend> |
|
29 |
+ {% for value,label in buchen.sorten %} |
|
30 |
+ <label><input type="checkbox" name="sorten[]" value="{{ value }}"{{ value in buchung.sorten|keys ? ' checked' : '' }}> <span class="checkable">{{ label }}</span></label><br> |
|
31 |
+ {% endfor %} |
|
32 |
+ </fieldset> |
|
33 |
+ <div> |
|
34 |
+ <button type="submit">Speichern</button> |
|
35 |
+ </div> |
|
36 |
+ </div> |
|
37 |
+ </form> |
|
38 |
+ </div> |
|
39 |
+ {% if modal %}</div>{% endif %} |
|
40 |
+{% endblock %} |
|
41 |
+ |
|
42 |
+{% block modal %} |
|
43 |
+ {% if modal %} |
|
44 |
+ <script> |
|
45 |
+ (function ($) { |
|
46 |
+ |
|
47 |
+ window.modals = window.modals || [] |
|
48 |
+ window.modals.wa_slots = window.modals.wa_slots || [] |
|
49 |
+ |
|
50 |
+ if (window.modals.wa_slots.details{{ id }} === undefined) |
|
51 |
+ { |
|
52 |
+ window.modals.wa_slots.details{{ id }} = new jBox('Modal', { |
|
53 |
+ closeButton: 'box', |
|
54 |
+ content: $('#wa-slot-{{ id }}'), |
|
55 |
+ maxWidth: 650, |
|
56 |
+ minWidth: 100, |
|
57 |
+ minHeight: 100, |
|
58 |
+ width: 650, |
|
59 |
+ overlay: true, |
|
60 |
+ closeOnClick: false, |
|
61 |
+ zIndex: 'auto', |
|
62 |
+ addClass: '' |
|
63 |
+ }).open(); |
|
64 |
+ } else { |
|
65 |
+ window.modals.wa_slots.details{{ id }}.content.empty(); |
|
66 |
+ window.modals.wa_slots.details{{ id }}.setContent($('#wa-slot-{{ id }}')).open(); |
|
67 |
+ } |
|
68 |
+ |
|
69 |
+ })(jQuery); |
|
70 |
+ </script> |
|
71 |
+ {% endif %} |
|
72 |
+{% endblock %} |
... | ... |
@@ -1,66 +1,96 @@ |
1 |
-<div class="modal-content"> |
|
2 |
- <div id="wa-slot-{{ id }}"> |
|
3 |
- <dl> |
|
4 |
- <dt>Tag/Uhrzeit</dt> |
|
5 |
- <dd>{{ slot.time|date('d.m.Y H:i') }}</dd> |
|
1 |
+{% block content %} |
|
2 |
+ {% if modal %}<div class="modal-content">{% endif %} |
|
3 |
+ <div id="wa-slot-{{ id }}" hx-get="/_ajax/vr_wa/v1/slot?do=details&id={{ id }}&modal=false" hx-target="this" hx-swap="outerHTML" hx-trigger="updateWaBooking from:body"> |
|
4 |
+ <dl> |
|
5 |
+ <dt>Tag/Uhrzeit</dt> |
|
6 |
+ <dd>{{ slot.time|date('d.m.Y H:i') }}</dd> |
|
6 | 7 |
|
7 |
- <dt>Verfügbare Behälterkapazität</dt> |
|
8 |
- <dd>{{ slot.behaelterAvailable }}</dd> |
|
8 |
+ <dt>Verfügbare Behälterkapazität</dt> |
|
9 |
+ <dd>{{ slot.behaelterAvailable }}</dd> |
|
9 | 10 |
|
10 |
- <dt>Verarbeitete Sorten</dt> |
|
11 |
- <dd>{{ slot.sorte|join(', ') }}</dd> |
|
12 |
- </dl> |
|
13 |
- <h3>Reservieren</h3> |
|
14 |
- {% if buchen.buchbar %} |
|
15 |
- <form hx-post="/_ajax/vr_wa/v1/slot?do=reservate"> |
|
16 |
- <input type="hidden" name="id" value="{{ id }}"> |
|
17 |
- <div class="dflex"> |
|
18 |
- <div> |
|
19 |
- <label for="res-behaelter">Liefernde Behältermenge</label> |
|
20 |
- <select id="res-behaelter" name="behaelter" required> |
|
21 |
- <option value="">-</option> |
|
22 |
- {% for option in buchen.behaelter %} |
|
23 |
- <option value="{{ option }}">{{ option }}</option> |
|
11 |
+ <dt>Verarbeitete Sorten</dt> |
|
12 |
+ <dd>{{ slot.sorte|join(', ') }}</dd> |
|
13 |
+ </dl> |
|
14 |
+ |
|
15 |
+ {% if reservations|length %} |
|
16 |
+ <h4>Ihre Reservierungen</h4> |
|
17 |
+ <ul class="reservations"> |
|
18 |
+ {% for reservation in reservations %} |
|
19 |
+ <li class="flex align-items-center"> |
|
20 |
+ <div class="full fifth-500"> |
|
21 |
+ <div class="icon-behaelter-outline">{{ reservation.behaelter }}</div> |
|
22 |
+ </div> |
|
23 |
+ <div class="full three-fifth-500"> |
|
24 |
+ <div class="icon-reben-outline">{{ reservation.sorten|join(', ') }}</div> |
|
25 |
+ </div> |
|
26 |
+ <div class="full fifth-500"> |
|
27 |
+ <div><a hx-get="/_ajax/vr_wa/v1/slot?do=booking&id={{ reservation.id }}" hx-target="body" hx-swap="beforeend" href="javascript:;">Bearbeiten</a></div> |
|
28 |
+ </div> |
|
29 |
+ </li> |
|
30 |
+ {% endfor %} |
|
31 |
+ </ul> |
|
32 |
+ {% endif %} |
|
33 |
+ |
|
34 |
+ <h3>Reservieren</h3> |
|
35 |
+ {% if buchen.buchbar %} |
|
36 |
+ <form hx-post="/_ajax/vr_wa/v1/slot?do=reservate"> |
|
37 |
+ <input type="hidden" name="id" value="{{ id }}"> |
|
38 |
+ <div class="dflex"> |
|
39 |
+ <div> |
|
40 |
+ <label for="res-behaelter">Liefernde Behältermenge</label> |
|
41 |
+ <select id="res-behaelter" name="behaelter" required> |
|
42 |
+ <option value="">-</option> |
|
43 |
+ {% for option in buchen.behaelter %} |
|
44 |
+ <option value="{{ option }}">{{ option }}</option> |
|
45 |
+ {% endfor %} |
|
46 |
+ </select> |
|
47 |
+ </div> |
|
48 |
+ <fieldset> |
|
49 |
+ <legend>Anliefernde Rebsorte(n)</legend> |
|
50 |
+ {% for value,label in buchen.sorten %} |
|
51 |
+ <label><input type="checkbox" name="sorten[]" value="{{ value }}"> <span class="checkable">{{ label }}</span></label><br> |
|
24 | 52 |
{% endfor %} |
25 |
- </select> |
|
53 |
+ </fieldset> |
|
54 |
+ <div> |
|
55 |
+ <button type="submit">Reservieren</button> |
|
56 |
+ </div> |
|
26 | 57 |
</div> |
27 |
- <fieldset> |
|
28 |
- <legend>Anliefernde Rebsorte(n)</legend> |
|
29 |
- {% for value,label in buchen.sorten %} |
|
30 |
- <label><input type="checkbox" name="sorten[]" value="{{ value }}"> <span class="checkable">{{ label }}</span></label><br> |
|
31 |
- {% endfor %} |
|
32 |
- </fieldset> |
|
33 |
- <div> |
|
34 |
- <button type="submit">Reservieren</button> |
|
35 |
- </div> |
|
36 |
- </div> |
|
37 |
- </form> |
|
38 |
- {% else %} |
|
39 |
- <p class="warning">Dieser Zeit-Slot ist bereits ausgebucht</p> |
|
40 |
- {% endif %} |
|
41 |
- </div> |
|
42 |
-</div> |
|
43 |
-<script> |
|
44 |
- (function ($) { |
|
58 |
+ </form> |
|
59 |
+ {% else %} |
|
60 |
+ <p class="warning">Dieser Zeit-Slot ist bereits ausgebucht</p> |
|
61 |
+ {% endif %} |
|
62 |
+ </div> |
|
63 |
+ {% if modal %}</div>{% endif %} |
|
64 |
+{% endblock %} |
|
65 |
+ |
|
66 |
+{% block modal %} |
|
67 |
+ {% if modal %} |
|
68 |
+ <script> |
|
69 |
+ (function ($) { |
|
45 | 70 |
|
46 |
- window.modals = window.modals || [] |
|
47 |
- window.modals.wa_slots = window.modals.wa_slots || [] |
|
71 |
+ window.modals = window.modals || [] |
|
72 |
+ window.modals.wa_slots = window.modals.wa_slots || [] |
|
48 | 73 |
|
49 |
- if (window.modals.wa_slots.details{{ id }} === undefined) |
|
50 |
- { |
|
51 |
- window.modals.wa_slots.details{{ id }} = new jBox('Modal', { |
|
52 |
- closeButton: 'box', |
|
53 |
- content: $('#wa-slot-{{ id }}'), |
|
54 |
- maxWidth: 650, |
|
55 |
- minWidth: 100, |
|
56 |
- minHeight: 100, |
|
57 |
- width: 650, |
|
58 |
- addClass: '' |
|
59 |
- }).open(); |
|
60 |
- } else { |
|
61 |
- window.modals.wa_slots.details{{ id }}.content.empty(); |
|
62 |
- window.modals.wa_slots.details{{ id }}.setContent($('#wa-slot-{{ id }}')).open(); |
|
63 |
- } |
|
74 |
+ if (window.modals.wa_slots.details{{ id }} === undefined) |
|
75 |
+ { |
|
76 |
+ window.modals.wa_slots.details{{ id }} = new jBox('Modal', { |
|
77 |
+ closeButton: 'box', |
|
78 |
+ content: $('#wa-slot-{{ id }}'), |
|
79 |
+ maxWidth: 650, |
|
80 |
+ minWidth: 100, |
|
81 |
+ minHeight: 100, |
|
82 |
+ width: 650, |
|
83 |
+ overlay: true, |
|
84 |
+ closeOnClick: false, |
|
85 |
+ zIndex: 'auto', |
|
86 |
+ addClass: '' |
|
87 |
+ }).open(); |
|
88 |
+ } else { |
|
89 |
+ window.modals.wa_slots.details{{ id }}.content.empty(); |
|
90 |
+ window.modals.wa_slots.details{{ id }}.setContent($('#wa-slot-{{ id }}')).open(); |
|
91 |
+ } |
|
64 | 92 |
|
65 |
- })(jQuery); |
|
66 |
-</script> |
|
93 |
+ })(jQuery); |
|
94 |
+ </script> |
|
95 |
+ {% endif %} |
|
96 |
+{% endblock %} |
... | ... |
@@ -1,4 +1,4 @@ |
1 |
-<div hx-get="{{ insert_tag('env::request') }}" hx-headers='{"VR-Ajax": "WabookingsModule"}' hx-trigger="updateWaList from:body" class="{{ class }} content-wrapper block"{{ cssID }}{% if style is defined and style is not empty %} style="{{ style }}"{% endif %}> |
|
1 |
+<div hx-get="{{ insert_tag('env::request') }}" hx-headers='{"VR-Ajax": "WaBookedModule"}' hx-trigger="updateWaBooking from:body" class="{{ class }} content-wrapper block"{{ cssID }}{% if style is defined and style is not empty %} style="{{ style }}"{% endif %}> |
|
2 | 2 |
|
3 | 3 |
{% block content %} |
4 | 4 |
{% if days is defined and days|length %} |
... | ... |
@@ -24,6 +24,7 @@ |
24 | 24 |
</div> |
25 | 25 |
<div class="full third-500 sixth-900 align-right action"> |
26 | 26 |
<a hx-get="/_ajax/vr_wa/v1/slot?do=delete&id={{ booking.id }}" hx-target="body" hx-swap="beforeend" href="javascript:;" class="button error">Löschen</a> |
27 |
+ <a hx-get="/_ajax/vr_wa/v1/slot?do=booking&id={{ booking.id }}" hx-target="body" hx-swap="beforeend" href="javascript:;" class="button">Anzeigen</a> |
|
27 | 28 |
</div> |
28 | 29 |
</div> |
29 | 30 |
</div> |
... | ... |
@@ -1,4 +1,4 @@ |
1 |
-<div hx-get="{{ insert_tag('env::request') }}" hx-headers='{"VR-Ajax": "WaSlotsModule"}' hx-trigger="updateWaList from:body" class="{{ class }} content-wrapper block"{{ cssID }}{% if style is defined and style is not empty %} style="{{ style }}"{% endif %}> |
|
1 |
+<div hx-get="{{ insert_tag('env::request') }}" hx-headers='{"VR-Ajax": "WaSlotsModule"}' hx-trigger="updateWaList from:body, updateWaBooking from:body" class="{{ class }} content-wrapper block"{{ cssID }}{% if style is defined and style is not empty %} style="{{ style }}"{% endif %}> |
|
2 | 2 |
|
3 | 3 |
{% block filter %} |
4 | 4 |
<form hx-get="{{ insert_tag('env::request') }}" hx-headers='{"VR-Ajax": "WaSlotsModule"}' hx-trigger="change, submit" hx-target="closest .content-wrapper" class="filter"> |
5 | 5 |
new file mode 100644 |
... | ... |
@@ -0,0 +1 @@ |
1 |
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 413 413" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><rect id="Artboard1" x="0" y="0" width="412.5" height="412.5" style="fill:none;"/><g id="Artboard11" serif:id="Artboard1"><g id="Behaelter"><path d="M412.5,119.063c-0,12.418 -10.082,22.5 -22.5,22.5l-367.5,-0c-12.418,-0 -22.5,-10.082 -22.5,-22.5c0,-12.419 10.082,-22.5 22.5,-22.5l367.5,-0c12.418,-0 22.5,10.081 22.5,22.5Zm-15,-0c-0,-4.14 -3.361,-7.5 -7.5,-7.5l-367.5,-0c-4.139,-0 -7.5,3.36 -7.5,7.5c0,4.139 3.361,7.5 7.5,7.5l367.5,-0c4.139,-0 7.5,-3.361 7.5,-7.5Z"/><path d="M379.41,141.563l-32.166,168.283c-0.676,3.535 -3.768,6.091 -7.367,6.091l-267.254,0c-3.599,0 -6.691,-2.556 -7.367,-6.091l-32.166,-168.283l15.271,-0c6.778,35.459 30.464,159.374 30.464,159.374l254.85,0.001l30.464,-159.375l15.271,-0Z"/></g></g></svg> |
|
0 | 2 |
\ No newline at end of file |
1 | 3 |
new file mode 100644 |
... | ... |
@@ -0,0 +1 @@ |
1 |
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 413 413" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><rect id="Artboard1" x="0" y="0" width="412.5" height="412.5" style="fill:none;"/><g id="Artboard11" serif:id="Artboard1"><g><g><path d="M74.684,98.842c18.526,2.813 31.283,20.137 28.47,38.662c-2.812,18.526 -20.136,31.284 -38.662,28.471c-18.526,-2.812 -31.283,-20.136 -28.471,-38.662c2.813,-18.526 20.137,-31.283 38.663,-28.471Zm-2.252,14.83c-10.341,-1.57 -20.011,5.551 -21.581,15.892c-1.569,10.341 5.552,20.011 15.892,21.581c10.341,1.57 20.011,-5.551 21.581,-15.892c1.57,-10.341 -5.551,-20.011 -15.892,-21.581Z"/><path d="M109.897,166.703c25.725,3.905 43.44,27.961 39.534,53.686c-3.905,25.725 -27.961,43.44 -53.686,39.535c-25.725,-3.906 -43.44,-27.962 -39.534,-53.687c3.905,-25.725 27.961,-43.44 53.686,-39.534Zm-2.251,14.83c-17.54,-2.663 -33.942,9.415 -36.605,26.955c-2.663,17.541 9.415,33.943 26.955,36.605c17.54,2.663 33.943,-9.415 36.605,-26.955c2.663,-17.54 -9.415,-33.942 -26.955,-36.605Z"/><path d="M148.372,262.486c17.513,2.659 29.573,19.036 26.914,36.549c-2.659,17.513 -19.036,29.573 -36.549,26.915c-17.513,-2.659 -29.573,-19.036 -26.915,-36.55c2.659,-17.513 19.036,-29.573 36.55,-26.914Zm-2.252,14.83c-9.328,-1.416 -18.051,5.008 -19.468,14.336c-1.416,9.328 5.008,18.051 14.336,19.468c9.329,1.416 18.052,-5.008 19.468,-14.336c1.416,-9.329 -5.007,-18.052 -14.336,-19.468Z"/><path d="M236.218,298.467c13.389,2.032 22.609,14.553 20.576,27.942c-2.032,13.39 -14.553,22.61 -27.942,20.577c-13.39,-2.033 -22.61,-14.553 -20.577,-27.943c2.033,-13.389 14.553,-22.609 27.943,-20.576Zm-2.252,14.83c-5.204,-0.791 -10.071,2.793 -10.861,7.998c-0.79,5.204 2.794,10.071 7.998,10.861c5.205,0.79 10.071,-2.794 10.861,-7.998c0.79,-5.205 -2.793,-10.071 -7.998,-10.861Z"/><path d="M174.691,339.53c19.644,2.982 33.171,21.352 30.189,40.996c-2.983,19.644 -21.352,33.171 -40.996,30.189c-19.644,-2.983 -33.171,-21.352 -30.189,-40.996c2.982,-19.644 21.352,-33.171 40.996,-30.189Zm-2.252,14.83c-11.459,-1.739 -22.174,6.152 -23.914,17.61c-1.739,11.459 6.151,22.175 17.61,23.915c11.459,1.739 22.175,-6.152 23.914,-17.611c1.74,-11.459 -6.151,-22.174 -17.61,-23.914Z"/><path d="M163.421,106.453c17.641,2.678 29.789,19.175 27.111,36.817c-2.678,17.641 -19.175,29.789 -36.816,27.111c-17.642,-2.678 -29.79,-19.175 -27.111,-36.817c2.678,-17.641 19.175,-29.789 36.816,-27.111Zm-2.251,14.83c-9.457,-1.435 -18.3,5.077 -19.735,14.533c-1.436,9.456 5.076,18.299 14.532,19.735c9.457,1.435 18.3,-5.076 19.735,-14.533c1.436,-9.456 -5.076,-18.299 -14.532,-19.735Z"/><path d="M204.597,191.939c19.252,2.923 32.51,20.926 29.587,40.178c-2.923,19.252 -20.926,32.51 -40.178,29.587c-19.252,-2.923 -32.51,-20.926 -29.587,-40.178c2.923,-19.252 20.926,-32.509 40.178,-29.587Zm-2.251,14.83c-11.067,-1.68 -21.417,5.941 -23.097,17.008c-1.68,11.068 5.941,21.417 17.008,23.097c11.067,1.68 21.417,-5.941 23.097,-17.008c1.68,-11.067 -5.941,-21.416 -17.008,-23.097Z"/><path d="M277.889,217.486c16.747,2.542 28.28,18.203 25.738,34.951c-2.543,16.748 -18.204,28.28 -34.952,25.738c-16.747,-2.543 -28.28,-18.204 -25.738,-34.952c2.543,-16.747 18.204,-28.28 34.952,-25.737Zm-2.252,14.83c-8.562,-1.3 -16.57,4.596 -17.87,13.159c-1.3,8.563 4.597,16.57 13.16,17.87c8.562,1.3 16.57,-4.597 17.87,-13.16c1.299,-8.562 -4.597,-16.569 -13.16,-17.869Z"/><path d="M251.327,134.541c13.734,2.085 23.191,14.928 21.106,28.662c-2.085,13.734 -14.928,23.192 -28.662,21.107c-13.734,-2.085 -23.191,-14.928 -21.106,-28.662c2.085,-13.734 14.928,-23.192 28.662,-21.107Zm-2.252,14.83c-5.549,-0.842 -10.738,2.979 -11.58,8.528c-0.843,5.549 2.978,10.738 8.527,11.581c5.55,0.842 10.739,-2.979 11.581,-8.528c0.842,-5.549 -2.979,-10.738 -8.528,-11.581Z"/><path d="M342.583,133.058c22.008,3.341 37.164,23.921 33.823,45.93c-3.342,22.008 -23.922,37.164 -45.931,33.822c-22.008,-3.341 -37.163,-23.921 -33.822,-45.93c3.341,-22.008 23.922,-37.163 45.93,-33.822Zm-2.251,14.83c-13.824,-2.099 -26.75,7.42 -28.849,21.244c-2.099,13.823 7.421,26.75 21.244,28.848c13.823,2.099 26.75,-7.42 28.849,-21.244c2.098,-13.823 -7.421,-26.75 -21.244,-28.848Z"/></g><path d="M196.6,105.642c0,0 9.626,-42.688 26.774,-73.146c8.068,-14.329 17.988,-25.882 28.928,-30.526c1.279,-0.543 2.683,-0.72 4.057,-0.512l29.66,4.503c3.243,0.493 5.79,3.036 6.287,6.278c0.498,3.243 -1.17,6.432 -4.117,7.874c0,0 -27.67,14.345 -63.035,92.453c-1.386,3.06 -4.637,4.826 -7.958,4.322l-14.404,-2.187c-2.057,-0.312 -3.892,-1.465 -5.066,-3.183c-1.174,-1.717 -1.582,-3.845 -1.126,-5.876Zm16.584,-4.535l0.677,0.103c21.549,-46.341 40.728,-70.665 53.129,-82.966c0,0 -10.619,-1.612 -10.619,-1.612c-10.723,5.681 -19.275,20.43 -26.324,35.912c-8.315,18.265 -14.065,37.964 -16.863,48.563Z"/></g></g></svg> |
|
0 | 2 |
\ No newline at end of file |
... | ... |
@@ -57,24 +57,36 @@ class SlotAjaxController extends AbstractController |
57 | 57 |
return new Response('Required parameter missing',412); |
58 | 58 |
} |
59 | 59 |
|
60 |
+ $blnModal = true; |
|
61 |
+ |
|
62 |
+ if (!empty($_REQUEST['modal'])) |
|
63 |
+ { |
|
64 |
+ $blnModal = !(strtolower($_REQUEST['modal']) == 'false'); |
|
65 |
+ } |
|
66 |
+ |
|
60 | 67 |
switch ($_REQUEST['do']) |
61 | 68 |
{ |
62 | 69 |
case 'details': |
63 |
- return $this->renderDetails(); |
|
64 |
- break; |
|
70 |
+ return $this->renderDetails($blnModal); |
|
71 |
+ |
|
72 |
+ case 'booking': |
|
73 |
+ return $this->renderBooking($blnModal); |
|
65 | 74 |
|
66 | 75 |
case 'reservate': |
67 | 76 |
return $this->reservate(); |
68 | 77 |
|
78 |
+ case 'updateReservation': |
|
79 |
+ return $this->updateReservation(); |
|
80 |
+ |
|
69 | 81 |
case 'delete': |
70 |
- return $this->deleteBooking(); |
|
82 |
+ return $this->deleteReservation(); |
|
71 | 83 |
} |
72 | 84 |
|
73 | 85 |
return new Response('',500); |
74 | 86 |
return new Response(null,203); |
75 | 87 |
} |
76 | 88 |
|
77 |
- protected function renderDetails() |
|
89 |
+ protected function renderDetails(bool $blnModal=true) |
|
78 | 90 |
{ |
79 | 91 |
if (empty($_REQUEST['id'])) |
80 | 92 |
{ |
... | ... |
@@ -86,6 +98,25 @@ class SlotAjaxController extends AbstractController |
86 | 98 |
return new Response('Could not load slot data',500); |
87 | 99 |
} |
88 | 100 |
|
101 |
+ // Get slot reservations from user |
|
102 |
+ $arrReservations = []; |
|
103 |
+ |
|
104 |
+ if (($Reservations = WeinanlieferungReservationModel::findBy(["uid = ?","pid = ?"],[FrontendUser::getInstance()->id,$Slot->id])) !== null) |
|
105 |
+ { |
|
106 |
+ foreach ($Reservations as $reservation) |
|
107 |
+ { |
|
108 |
+ $arrSortenBooked = []; |
|
109 |
+ if (($Sorten = $reservation->getRelated('sorten')) !== null) |
|
110 |
+ { |
|
111 |
+ $arrSortenBooked = $Sorten->fetchEach('title'); |
|
112 |
+ } |
|
113 |
+ $arrReservations[] = array_merge($reservation->row(),[ |
|
114 |
+ 'sorten' => $arrSortenBooked |
|
115 |
+ ]); |
|
116 |
+ } |
|
117 |
+ } |
|
118 |
+ |
|
119 |
+ // Build data |
|
89 | 120 |
$arrSorten = []; |
90 | 121 |
if (($Sorten = $Slot->getRelated('sorte')) !== null) |
91 | 122 |
{ |
... | ... |
@@ -95,6 +126,7 @@ class SlotAjaxController extends AbstractController |
95 | 126 |
$intAvailableBehaelter = $Slot->getAvailableBehaelter(); |
96 | 127 |
|
97 | 128 |
$arrData = [ |
129 |
+ 'modal' => $blnModal, |
|
98 | 130 |
'id' => $Slot->id, |
99 | 131 |
'slot' => array_merge($Slot->row(),[ |
100 | 132 |
'sorte' => $arrSorten, |
... | ... |
@@ -105,17 +137,65 @@ class SlotAjaxController extends AbstractController |
105 | 137 |
'buchbar' => (boolean) $intAvailableBehaelter, |
106 | 138 |
'behaelter' => range(min($intAvailableBehaelter,1),$intAvailableBehaelter), |
107 | 139 |
'sorten' => $arrSorten |
108 |
- ] |
|
140 |
+ ], |
|
141 |
+ 'reservations' => $arrReservations |
|
109 | 142 |
]; |
110 | 143 |
|
111 | 144 |
return $this->render('@Contao/modal_slot_details.html.twig',$arrData); |
112 | 145 |
} |
113 | 146 |
|
147 |
+ protected function renderBooking(bool $blnModal=true) |
|
148 |
+ { |
|
149 |
+ if (empty($_REQUEST['id'])) |
|
150 |
+ { |
|
151 |
+ return new Response('Required parameter missing',412); |
|
152 |
+ } |
|
153 |
+ |
|
154 |
+ /** @var WeinanlieferungSlotsModel $Slot */ |
|
155 |
+ if (($Booking = WeinanlieferungReservationModel::findById($_REQUEST['id'])) === null || ($Slot = $Booking->getRelated('pid')) === null) |
|
156 |
+ { |
|
157 |
+ return new Response('Could not load booking data',500); |
|
158 |
+ } |
|
159 |
+ |
|
160 |
+ $arrSortenAvailable = []; |
|
161 |
+ if (($Sorten = $Slot->getRelated('sorte')) !== null) |
|
162 |
+ { |
|
163 |
+ $arrSortenAvailable = array_combine($Sorten->fetchEach('id'),$Sorten->fetchEach('title')); |
|
164 |
+ } |
|
165 |
+ $arrSortenBooked = []; |
|
166 |
+ if (($Sorten = $Booking->getRelated('sorten')) !== null) |
|
167 |
+ { |
|
168 |
+ $arrSortenBooked = array_combine($Sorten->fetchEach('id'),$Sorten->fetchEach('title')); |
|
169 |
+ } |
|
170 |
+ |
|
171 |
+ $intAvailableBehaelter = $Slot->getAvailableBehaelter(); |
|
172 |
+ |
|
173 |
+ $arrData = [ |
|
174 |
+ 'modal' => $blnModal, |
|
175 |
+ 'id' => $Booking->id, |
|
176 |
+ 'slot' => array_merge($Slot->row(),[ |
|
177 |
+ 'sorte' => $arrSortenAvailable, |
|
178 |
+ 'behaelterAvailable' => $intAvailableBehaelter |
|
179 |
+ ]), |
|
180 |
+ 'buchung' => array_merge($Booking->row(),[ |
|
181 |
+ 'sorten' => $arrSortenBooked |
|
182 |
+ ]), |
|
183 |
+ 'standort' => $Slot->getRelated('pid'), |
|
184 |
+ 'buchen' => [ |
|
185 |
+ 'buchbar' => (boolean) $intAvailableBehaelter, |
|
186 |
+ 'behaelter' => range(min($intAvailableBehaelter,1),$intAvailableBehaelter+$Booking->behaelter), |
|
187 |
+ 'sorten' => $arrSortenAvailable |
|
188 |
+ ] |
|
189 |
+ ]; |
|
190 |
+ |
|
191 |
+ return $this->render('@Contao/modal_booking_details.html.twig',$arrData); |
|
192 |
+ } |
|
193 |
+ |
|
114 | 194 |
protected function reservate() |
115 | 195 |
{ |
116 | 196 |
if (empty($_REQUEST['id']) || empty(Input::post('behaelter')) || empty(Input::post('sorten'))) |
117 | 197 |
{ |
118 |
- return new Response('Missing parameter',500); |
|
198 |
+ return new Response('Missing parameter',412); |
|
119 | 199 |
} |
120 | 200 |
|
121 | 201 |
$arrSorten = []; |
... | ... |
@@ -139,14 +219,43 @@ class SlotAjaxController extends AbstractController |
139 | 219 |
|
140 | 220 |
$Reservation->save(); |
141 | 221 |
|
142 |
- return new Response('<p>Reservierung erfolgreich</p>'); |
|
222 |
+ return new Response('<p>Reservierung erfolgreich</p>',200,['HX-Trigger'=> 'updateWaList']); |
|
223 |
+ } |
|
224 |
+ |
|
225 |
+ protected function updateReservation() |
|
226 |
+ { |
|
227 |
+ if (empty($_REQUEST['id']) || empty(Input::post('behaelter')) || empty(Input::post('sorten'))) |
|
228 |
+ { |
|
229 |
+ return new Response('Missing parameter',412); |
|
230 |
+ } |
|
231 |
+ |
|
232 |
+ if (($Reservation = WeinanlieferungReservationModel::findById($_REQUEST['id'])) === null) |
|
233 |
+ { |
|
234 |
+ return new Response('Could not load booking data',500); |
|
235 |
+ } |
|
236 |
+ |
|
237 |
+ $arrSorten = []; |
|
238 |
+ if (!is_array(Input::post('sorten'))) |
|
239 |
+ { |
|
240 |
+ $arrSorten[] = Input::post('sorten'); |
|
241 |
+ } else { |
|
242 |
+ $arrSorten = implode(',', Input::post('sorten')); |
|
243 |
+ } |
|
244 |
+ |
|
245 |
+ $Reservation->tstamp = time(); |
|
246 |
+ $Reservation->behaelter = Input::post('behaelter'); |
|
247 |
+ $Reservation->sorten = $arrSorten; |
|
248 |
+ |
|
249 |
+ $Reservation->save(); |
|
250 |
+ |
|
251 |
+ return new Response('<p>Reservierung erfolgreich geändert</p>',200,['HX-Trigger'=> 'updateWaBooking']); |
|
143 | 252 |
} |
144 | 253 |
|
145 |
- protected function deleteBooking() |
|
254 |
+ protected function deleteReservation() |
|
146 | 255 |
{ |
147 | 256 |
if (empty($_REQUEST['id'])) |
148 | 257 |
{ |
149 |
- return new Response('Missing parameter',500); |
|
258 |
+ return new Response('Missing parameter',412); |
|
150 | 259 |
} |
151 | 260 |
|
152 | 261 |
/** @var Connection $db */ |
... | ... |
@@ -159,7 +268,7 @@ class SlotAjaxController extends AbstractController |
159 | 268 |
|
160 | 269 |
if ($db->delete('tl_vr_wa_reservation',$arrCriteria)) |
161 | 270 |
{ |
162 |
- return new Response(null,203); |
|
271 |
+ return new Response(null,203,['HX-Trigger'=> 'updateWaBooking']); |
|
163 | 272 |
} |
164 | 273 |
|
165 | 274 |
return new Response('Could not delete',500); |
... | ... |
@@ -48,14 +48,14 @@ class WeinanlieferungBookedListModuleController extends AbstractFrontendModuleCo |
48 | 48 |
$arrData = $template->getData(); |
49 | 49 |
|
50 | 50 |
// Get bookings |
51 |
- if (($bookings = WeinanlieferungReservationModel::findBy("uid",FrontendUser::getInstance()->id)) !== null) |
|
51 |
+ if (($bookings = WeinanlieferungReservationModel::findBy("uid",FrontendUser::getInstance()->id,['order' => "(SELECT tl_vr_wa_slot.time FROM tl_vr_wa_slot WHERE tl_vr_wa_slot.id=tl_vr_wa_reservation.pid) ASC"])) !== null) |
|
52 | 52 |
{ |
53 | 53 |
/** @var WeinanlieferungReservationModel $booking */ |
54 | 54 |
foreach ($bookings as $booking) |
55 | 55 |
{ |
56 | 56 |
if (($Slot = $booking->getRelated('pid')) !== null) |
57 | 57 |
{ |
58 |
- $day = new Date($booking->date); |
|
58 |
+ $day = new Date($Slot->date); |
|
59 | 59 |
$arrSorten = []; |
60 | 60 |
|
61 | 61 |
if (($Sorten = $booking->getRelated('sorten')) !== null) |
... | ... |
@@ -97,7 +97,7 @@ class WeinanlieferungSlotsModel extends Model |
97 | 97 |
return static::findBy($arrColumns,null,$arrOptions); |
98 | 98 |
} |
99 | 99 |
|
100 |
- public function getAvailableBehaelter() |
|
100 |
+ public function getAvailableBehaelter(?int $intOffset=null) |
|
101 | 101 |
{ |
102 | 102 |
/** @var Connection $db */ |
103 | 103 |
$db = Controller::getContainer()->get('database_connection'); |
... | ... |
@@ -112,6 +112,11 @@ class WeinanlieferungSlotsModel extends Model |
112 | 112 |
$intReserved = 0; |
113 | 113 |
} |
114 | 114 |
|
115 |
+ if ($intOffset > 0) |
|
116 |
+ { |
|
117 |
+ $intReserved += $intOffset; |
|
118 |
+ } |
|
119 |
+ |
|
115 | 120 |
return (int) $this->behaelter - $intReserved; |
116 | 121 |
} |
117 | 122 |
} |