| ... | ... |
@@ -97,7 +97,7 @@ $GLOBALS['TL_DCA']['tl_vr_wa_reservation'] = array |
| 97 | 97 |
'palettes' => array |
| 98 | 98 |
( |
| 99 | 99 |
'__selector__' => array(), |
| 100 |
- 'default' => 'pid,uid,lage,behaelter,sorten,ernteart,upload' |
|
| 100 |
+ 'default' => 'pid,uid,behaelter,sorten,lage,ernteart,upload' |
|
| 101 | 101 |
), |
| 102 | 102 |
|
| 103 | 103 |
// Subpalettes |
| ... | ... |
@@ -140,6 +140,7 @@ $GLOBALS['TL_DCA']['tl_vr_wa_reservation'] = array |
| 140 | 140 |
'inputType' => 'checkbox', |
| 141 | 141 |
'eval' => array('multiple'=>true, 'csv'=>',','tl_class'=>'w50'),
|
| 142 | 142 |
'sql' => "blob NULL", |
| 143 |
+ 'relation' => array('type' => 'hasMany', 'load' => 'lazy', 'table'=>'tl_vr_wa_lage')
|
|
| 143 | 144 |
), |
| 144 | 145 |
'behaelter' => array |
| 145 | 146 |
( |
| ... | ... |
@@ -76,7 +76,7 @@ $GLOBALS['TL_DCA']['tl_vr_wa_slot'] = array |
| 76 | 76 |
), |
| 77 | 77 |
'toggle' => array |
| 78 | 78 |
( |
| 79 |
- 'href' => 'act=toggle&field=buchbar', |
|
| 79 |
+ 'href' => 'act=toggle&field=published', |
|
| 80 | 80 |
'icon' => 'visible.svg', |
| 81 | 81 |
'showInHeader' => true |
| 82 | 82 |
), |
| ... | ... |
@@ -91,7 +91,7 @@ $GLOBALS['TL_DCA']['tl_vr_wa_slot'] = array |
| 91 | 91 |
'palettes' => array |
| 92 | 92 |
( |
| 93 | 93 |
'__selector__' => array('addEnclosure'),
|
| 94 |
- 'default' => '{time_legend},date,time;{type_legend},lage,behaelter,sorten,ernteart;{info_legend},anmerkungen,addEnclosure;{booking_legend},buchbar,buchbar_bis'
|
|
| 94 |
+ 'default' => '{time_legend},date,time;{type_legend},behaelter,sorten,lage,ernteart;{info_legend},anmerkungen,addEnclosure;{booking_legend},published,buchbar_ab,buchbar_bis'
|
|
| 95 | 95 |
), |
| 96 | 96 |
|
| 97 | 97 |
// Subpalettes |
| ... | ... |
@@ -140,11 +140,11 @@ $GLOBALS['TL_DCA']['tl_vr_wa_slot'] = array |
| 140 | 140 |
'lage' => array |
| 141 | 141 |
( |
| 142 | 142 |
'exclude' => true, |
| 143 |
- 'inputType' => 'select', |
|
| 143 |
+ 'inputType' => 'checkbox', |
|
| 144 | 144 |
'foreignKey' => 'tl_vr_wa_lage.title', |
| 145 |
- 'eval' => array('mandatory' => false, 'includeBlankOption' => true, 'chosen'=>true,'tl_class' => 'w50'),
|
|
| 146 |
- 'sql' => "smallint(3) unsigned NOT NULL default 0", |
|
| 147 |
- 'relation' => array('type' => 'hasOne', 'load' => 'lazy')
|
|
| 145 |
+ 'eval' => array('mandatory' => false, 'multiple' => true, 'csv'=>',','tl_class' => 'w50'),
|
|
| 146 |
+ 'sql' => "blob NULL", |
|
| 147 |
+ 'relation' => array('type' => 'hasMany', 'load' => 'lazy')
|
|
| 148 | 148 |
), |
| 149 | 149 |
'behaelter' => array |
| 150 | 150 |
( |
| ... | ... |
@@ -193,7 +193,7 @@ $GLOBALS['TL_DCA']['tl_vr_wa_slot'] = array |
| 193 | 193 |
'exclude' => true, |
| 194 | 194 |
'inputType' => 'checkbox', |
| 195 | 195 |
'options' => array('handlese','vollernter'),
|
| 196 |
- 'eval' => array('mandatory'=>true,'multiple'=>true,'csv'=>','),
|
|
| 196 |
+ 'eval' => array('mandatory'=>true,'multiple'=>true,'csv'=>',', 'tl_class'=>'w50'),
|
|
| 197 | 197 |
'reference' => $GLOBALS['TL_LANG']['REF']['wa_ernteart'], |
| 198 | 198 |
'sql' => "blob NULL" |
| 199 | 199 |
), |
| ... | ... |
@@ -219,7 +219,7 @@ $GLOBALS['TL_DCA']['tl_vr_wa_slot'] = array |
| 219 | 219 |
'eval' => array('multiple'=>true, 'fieldType'=>'checkbox', 'filesOnly'=>true, 'isDownloads'=>true, 'extensions'=>Config::get('allowedDownload'), 'mandatory'=>true, 'isSortable'=>true),
|
| 220 | 220 |
'sql' => "blob NULL" |
| 221 | 221 |
), |
| 222 |
- 'buchbar' => array |
|
| 222 |
+ 'published' => array |
|
| 223 | 223 |
( |
| 224 | 224 |
'exclude' => true, |
| 225 | 225 |
'toggle' => true, |
| ... | ... |
@@ -230,11 +230,18 @@ $GLOBALS['TL_DCA']['tl_vr_wa_slot'] = array |
| 230 | 230 |
'eval' => array('doNotCopy' => true),
|
| 231 | 231 |
'sql' => "char(1) NOT NULL default ''" |
| 232 | 232 |
), |
| 233 |
+ 'buchbar_ab' => array |
|
| 234 |
+ ( |
|
| 235 |
+ 'exclude' => true, |
|
| 236 |
+ 'inputType' => 'text', |
|
| 237 |
+ 'eval' => array('rgxp' => 'datim', 'datepicker' => true, 'tl_class' => 'clr w50 wizard'),
|
|
| 238 |
+ 'sql' => "int(10) unsigned NULL" |
|
| 239 |
+ ), |
|
| 233 | 240 |
'buchbar_bis' => array |
| 234 | 241 |
( |
| 235 | 242 |
'exclude' => true, |
| 236 | 243 |
'inputType' => 'text', |
| 237 |
- 'eval' => array('rgxp' => 'datim', 'mandatory' => true, 'datepicker' => true, 'tl_class' => 'clr w50 wizard'),
|
|
| 244 |
+ 'eval' => array('rgxp' => 'datim', 'mandatory' => true, 'datepicker' => true, 'tl_class' => 'w50 wizard'),
|
|
| 238 | 245 |
'sql' => "int(10) unsigned NULL" |
| 239 | 246 |
), |
| 240 | 247 |
) |
| ... | ... |
@@ -14,6 +14,8 @@ $GLOBALS['TL_LANG']['tl_vr_wa_reservation']['behaelter'][0] = 'Behälteranzahl'; |
| 14 | 14 |
$GLOBALS['TL_LANG']['tl_vr_wa_reservation']['behaelter'][1] = 'Die Anzahl an Behälter, die der Winzer anliefert.'; |
| 15 | 15 |
$GLOBALS['TL_LANG']['tl_vr_wa_reservation']['sorten'][0] = 'Sorten'; |
| 16 | 16 |
$GLOBALS['TL_LANG']['tl_vr_wa_reservation']['sorten'][1] = 'Die Sorten, die der Winzer anliefert.'; |
| 17 |
+$GLOBALS['TL_LANG']['tl_vr_wa_reservation']['lage'][0] = 'Lage'; |
|
| 18 |
+$GLOBALS['TL_LANG']['tl_vr_wa_reservation']['lage'][1] = 'Lage der angelieferten Reben.'; |
|
| 17 | 19 |
$GLOBALS['TL_LANG']['tl_vr_wa_reservation']['ernteart'][0] = 'Ernteart'; |
| 18 | 20 |
$GLOBALS['TL_LANG']['tl_vr_wa_reservation']['ernteart'][1] = 'Die Ernteart, der angelieferten Reben.'; |
| 19 | 21 |
$GLOBALS['TL_LANG']['tl_vr_wa_reservation']['uid'][0] = 'Winzer'; |
| ... | ... |
@@ -28,8 +28,10 @@ $GLOBALS['TL_LANG']['tl_vr_wa_slot']['addEnclosure'][0] = 'Anhänge'; |
| 28 | 28 |
$GLOBALS['TL_LANG']['tl_vr_wa_slot']['addEnclosure'][1] = 'Dateianhänge zum Download.'; |
| 29 | 29 |
$GLOBALS['TL_LANG']['tl_vr_wa_slot']['enclosure'][0] = 'Dateien'; |
| 30 | 30 |
$GLOBALS['TL_LANG']['tl_vr_wa_slot']['enclosure'][1] = 'Bitte die downloadbaren Dateien auswählen.'; |
| 31 |
-$GLOBALS['TL_LANG']['tl_vr_wa_slot']['buchbar'][0] = 'Buchbar'; |
|
| 32 |
-$GLOBALS['TL_LANG']['tl_vr_wa_slot']['buchbar'][1] = 'Steuert die Buchbarkeit dieses Zeitslots.'; |
|
| 31 |
+$GLOBALS['TL_LANG']['tl_vr_wa_slot']['published'][0] = 'Veröffentlicht'; |
|
| 32 |
+$GLOBALS['TL_LANG']['tl_vr_wa_slot']['published'][1] = 'Legt fest ob der Slot im Frontend angezeigt wird oder nicht.'; |
|
| 33 |
+$GLOBALS['TL_LANG']['tl_vr_wa_slot']['buchbar_ab'][0] = 'Buchbar ab'; |
|
| 34 |
+$GLOBALS['TL_LANG']['tl_vr_wa_slot']['buchbar_ab'][1] = 'Zeitpunkt, ab wann der Slot gebucht werden kann.'; |
|
| 33 | 35 |
$GLOBALS['TL_LANG']['tl_vr_wa_slot']['buchbar_bis'][0] = 'Buchbar bis'; |
| 34 | 36 |
$GLOBALS['TL_LANG']['tl_vr_wa_slot']['buchbar_bis'][1] = 'Zeitpunkt, bis wann der Slot spätestens gebucht werden kann.'; |
| 35 | 37 |
|
| ... | ... |
@@ -1,10 +1,10 @@ |
| 1 | 1 |
{% block content %}
|
| 2 | 2 |
{% if modal %}<div class="modal-content">{% endif %}
|
| 3 |
- <div id="wa-booking-{{ id }}" class="frame">
|
|
| 3 |
+ <div id="wa-booking-{{ id }}" hx-target="this" hx-swap="outerHTML" class="frame">
|
|
| 4 | 4 |
<div class="frame__header"> |
| 5 | 5 |
<h3>Reservierung</h3> |
| 6 |
- <div class="row"> |
|
| 7 |
- <div class="col-md-6"> |
|
| 6 |
+ <div class="grid-md u-gap-2"> |
|
| 7 |
+ <div class="grid-c-6 mb-2 mb-0-md"> |
|
| 8 | 8 |
<div class="u-flex u-items-center u-gap-1"> |
| 9 | 9 |
<i class="icon-uhr-outline"></i> |
| 10 | 10 |
<div class="t-label">Tag/Urzeit</div> |
| ... | ... |
@@ -12,52 +12,37 @@ |
| 12 | 12 |
<div class="">{{ slot.time|date('d.m.Y H:i') }}</div>
|
| 13 | 13 |
</div> |
| 14 | 14 |
|
| 15 |
- <div class="col-md-6"> |
|
| 15 |
+ <div class="grid-c-6 mb-2 mb-0-md"> |
|
| 16 | 16 |
<div class="u-flex u-items-center u-gap-1"> |
| 17 | 17 |
<i class="icon-standort-outline"></i> |
| 18 | 18 |
<div class="t-label">Standort</div> |
| 19 | 19 |
</div> |
| 20 | 20 |
<div class="">{{ standort.title }}</div>
|
| 21 | 21 |
</div> |
| 22 |
- </div> |
|
| 23 |
- |
|
| 24 |
- <div class="row"> |
|
| 25 |
- <div class="col-md-6"> |
|
| 26 |
- <div class="u-flex u-items-center u-gap-1"> |
|
| 27 |
- <i class="icon-behaelter-outline"></i> |
|
| 28 |
- <div class="t-label">Verfügbare Behälterkapazität</div> |
|
| 29 |
- </div> |
|
| 30 |
- <div class="">{{ slot.behaelterAvailable }}</div>
|
|
| 31 |
- </div> |
|
| 32 | 22 |
|
| 33 |
- <div class="col-md-6"> |
|
| 34 |
- <div class="u-flex u-items-center u-gap-1"> |
|
| 35 |
- <i class="icon-reben-outline"></i> |
|
| 36 |
- <div class="t-label">Verarbeitete Sorten</div> |
|
| 23 |
+ {% if slot.anmerkungen %}
|
|
| 24 |
+ <div class="grid-c-12 mb-2 mb-0-md"> |
|
| 25 |
+ <div class="u-flex u-items-center u-gap-1"> |
|
| 26 |
+ <i class="icon-info-outline"></i> |
|
| 27 |
+ <div class="t-label">Anmerkungen</div> |
|
| 28 |
+ </div> |
|
| 29 |
+ {{ slot.anmerkungen|raw }}
|
|
| 37 | 30 |
</div> |
| 38 |
- <div class="">{{ slot.sorte|join(', ') }}</div>
|
|
| 39 |
- </div> |
|
| 31 |
+ {% endif %}
|
|
| 40 | 32 |
</div> |
| 41 |
- |
|
| 42 |
- {% if slot.anmerkungen %}
|
|
| 43 |
- <div> |
|
| 44 |
- <div class="u-flex u-items-center u-gap-1"> |
|
| 45 |
- <i class="icon-info-outline"></i> |
|
| 46 |
- <div class="t-label">Anmerkungen</div> |
|
| 47 |
- </div> |
|
| 48 |
- {{ slot.anmerkungen|raw }}
|
|
| 49 |
- </div> |
|
| 50 |
- {% endif %}
|
|
| 51 | 33 |
</div> |
| 52 | 34 |
|
| 53 | 35 |
<div class="divider m-0 mb-2"></div> |
| 54 | 36 |
|
| 55 | 37 |
<div class="frame__body"> |
| 56 | 38 |
<h3>Reservierung ändern</h3> |
| 39 |
+ {% if toast is defined %}
|
|
| 40 |
+ {{ toast|raw }}
|
|
| 41 |
+ {% endif %}
|
|
| 57 | 42 |
<form hx-post="/_ajax/vr_wa/v1/slot?do=updateReservation" enctype="multipart/form-data"> |
| 58 | 43 |
<input type="hidden" name="id" value="{{ id }}">
|
| 59 | 44 |
<fieldset> |
| 60 |
- <label for="res-behaelter">Liefernde Behältermenge</label> |
|
| 45 |
+ <label for="res-behaelter"><strong>Liefernde Behältermenge</strong><sup class="text-danger">*</sup></label> |
|
| 61 | 46 |
<select id="res-behaelter" name="behaelter" required> |
| 62 | 47 |
<option value="">-</option> |
| 63 | 48 |
{% for option in buchen.behaelter %}
|
| ... | ... |
@@ -66,21 +51,33 @@ |
| 66 | 51 |
</select> |
| 67 | 52 |
</fieldset> |
| 68 | 53 |
<fieldset> |
| 69 |
- <legend>Anliefernde Rebsorte(n)</legend> |
|
| 54 |
+ <legend>Anliefernde Rebsorte(n)<sup class="text-danger">*</sup></legend> |
|
| 70 | 55 |
{% for value,label in buchen.sorten %}
|
| 71 | 56 |
<label><input type="checkbox" name="sorten[]" value="{{ value }}"{{ value in buchung.sorten|keys ? ' checked' : '' }}> <span class="checkable">{{ label }}</span></label><br>
|
| 72 | 57 |
{% endfor %}
|
| 73 | 58 |
</fieldset> |
| 59 |
+ <fieldset> |
|
| 60 |
+ <legend>Ernteart(en)<sup class="text-danger">*</sup></legend> |
|
| 61 |
+ {% for value,label in buchen.ernteart %}
|
|
| 62 |
+ <label><input type="checkbox" name="ernteart[]" value="{{ value }}"{{ value in buchung.ernteart ? ' checked' : '' }}> <span class="checkable">{{ label }}</span></label><br>
|
|
| 63 |
+ {% endfor %}
|
|
| 64 |
+ </fieldset> |
|
| 65 |
+ <fieldset> |
|
| 66 |
+ <legend>Lage(n)</legend> |
|
| 67 |
+ {% for value,label in buchen.lage %}
|
|
| 68 |
+ <label><input type="checkbox" name="lage[]" value="{{ value }}"{{ value in buchung.lage ? ' checked' : '' }}> <span class="checkable">{{ label }}</span></label><br>
|
|
| 69 |
+ {% endfor %}
|
|
| 70 |
+ </fieldset> |
|
| 74 | 71 |
{% if file is defined %}
|
| 75 | 72 |
<fieldset> |
| 76 | 73 |
<div class="t-label">Aktuelle Datei</div> |
| 77 | 74 |
<div class="u-flex u-items-center u-gap-1"><a href="{{ file.link }}">{{ file.name }}</a> <a href="javascript:;" hx-get="/_ajax/vr_wa/v1/slot?do=booking&id={{ id }}&modal=false&deleteFile=true" hx-target="closest .frame" hx-swap="outerHTML" class="tag tag__close-btn tag--danger tag--xs"></a></div>
|
| 78 | 75 |
</fieldset> |
| 79 | 76 |
<fieldset> |
| 80 |
- <label for="res-upload">Datei überschreiben</label> |
|
| 77 |
+ <label for="res-upload"><strong>Datei überschreiben</strong></label> |
|
| 81 | 78 |
{% else %}
|
| 82 | 79 |
<fieldset> |
| 83 |
- <label for="res-upload">Datei hochladen</label> |
|
| 80 |
+ <label for="res-upload"><strong>Datei hochladen</strong></label> |
|
| 84 | 81 |
{% endif %}
|
| 85 | 82 |
<input type="file" id="res-upload" name="upload"> |
| 86 | 83 |
</fieldset> |
| ... | ... |
@@ -31,7 +31,7 @@ |
| 31 | 31 |
<div class="grid-c-6 mb-2 mb-0-md"> |
| 32 | 32 |
<div class="u-flex u-items-center u-gap-1"> |
| 33 | 33 |
<i class="icon-schere-outline"></i> |
| 34 |
- <div class="t-label">Ernteart</div> |
|
| 34 |
+ <div class="t-label">Erntearten</div> |
|
| 35 | 35 |
</div> |
| 36 | 36 |
<div class="">{{ ernteart|join(', ') }}</div>
|
| 37 | 37 |
</div> |
| ... | ... |
@@ -47,9 +47,9 @@ |
| 47 | 47 |
<div class="grid-c-6 mb-2 mb-0-md"> |
| 48 | 48 |
<div class="u-flex u-items-center u-gap-1"> |
| 49 | 49 |
<i class="icon-lage-outline"></i> |
| 50 |
- <div class="t-label">Lage</div> |
|
| 50 |
+ <div class="t-label">Lagen</div> |
|
| 51 | 51 |
</div> |
| 52 |
- <div class="">{{ lage.title }}</div>
|
|
| 52 |
+ <div class="">{{ lage|join(', ') }}</div>
|
|
| 53 | 53 |
</div> |
| 54 | 54 |
|
| 55 | 55 |
{% if slot.anmerkungen %}
|
| ... | ... |
@@ -31,7 +31,7 @@ |
| 31 | 31 |
<div class="grid-c-6 mb-2 mb-0-md"> |
| 32 | 32 |
<div class="u-flex u-items-center u-gap-1"> |
| 33 | 33 |
<i class="icon-schere-outline"></i> |
| 34 |
- <div class="t-label">Ernteart</div> |
|
| 34 |
+ <div class="t-label">Erntearten</div> |
|
| 35 | 35 |
</div> |
| 36 | 36 |
<div class="">{{ ernteart|join(', ') }}</div>
|
| 37 | 37 |
</div> |
| ... | ... |
@@ -47,9 +47,9 @@ |
| 47 | 47 |
<div class="grid-c-6 mb-2 mb-0-md"> |
| 48 | 48 |
<div class="u-flex u-items-center u-gap-1"> |
| 49 | 49 |
<i class="icon-lage-outline"></i> |
| 50 |
- <div class="t-label">Lage</div> |
|
| 50 |
+ <div class="t-label">Lagen</div> |
|
| 51 | 51 |
</div> |
| 52 |
- <div class="">{{ lage.title }}</div>
|
|
| 52 |
+ <div class="">{{ lage|join(', ') }}</div>
|
|
| 53 | 53 |
</div> |
| 54 | 54 |
|
| 55 | 55 |
{% if slot.anmerkungen %}
|
| ... | ... |
@@ -105,7 +105,7 @@ |
| 105 | 105 |
<form hx-post="/_ajax/vr_wa/v1/slot?do=reservate" enctype="multipart/form-data"> |
| 106 | 106 |
<input type="hidden" name="id" value="{{ id }}">
|
| 107 | 107 |
<fieldset> |
| 108 |
- <label for="res-behaelter">Liefernde Behältermenge</label> |
|
| 108 |
+ <label for="res-behaelter"><strong>Liefernde Behältermenge<sup class="text-danger">*</sup></strong></label> |
|
| 109 | 109 |
<select id="res-behaelter" name="behaelter" required> |
| 110 | 110 |
<option value="">-</option> |
| 111 | 111 |
{% for option in buchen.behaelter %}
|
| ... | ... |
@@ -114,13 +114,25 @@ |
| 114 | 114 |
</select> |
| 115 | 115 |
</fieldset> |
| 116 | 116 |
<fieldset> |
| 117 |
- <legend>Anliefernde Rebsorte(n)</legend> |
|
| 117 |
+ <legend>Anliefernde Rebsorte(n)<sup class="text-danger">*</sup></legend> |
|
| 118 | 118 |
{% for value,label in buchen.sorten %}
|
| 119 | 119 |
<label><input type="checkbox" name="sorten[]" value="{{ value }}"> <span class="checkable">{{ label }}</span></label><br>
|
| 120 | 120 |
{% endfor %}
|
| 121 | 121 |
</fieldset> |
| 122 | 122 |
<fieldset> |
| 123 |
- <label for="res-upload">Dateianhang</label> |
|
| 123 |
+ <legend>Ernteart(en)<sup class="text-danger">*</sup></legend> |
|
| 124 |
+ {% for value,label in buchen.ernteart %}
|
|
| 125 |
+ <label><input type="checkbox" name="ernteart[]" value="{{ value }}"> <span class="checkable">{{ label }}</span></label><br>
|
|
| 126 |
+ {% endfor %}
|
|
| 127 |
+ </fieldset> |
|
| 128 |
+ <fieldset> |
|
| 129 |
+ <legend>Lage(n)</legend> |
|
| 130 |
+ {% for value,label in buchen.lage %}
|
|
| 131 |
+ <label><input type="checkbox" name="lage[]" value="{{ value }}"> <span class="checkable">{{ label }}</span></label><br>
|
|
| 132 |
+ {% endfor %}
|
|
| 133 |
+ </fieldset> |
|
| 134 |
+ <fieldset> |
|
| 135 |
+ <label for="res-upload"><strong>Dateianhang</strong></label> |
|
| 124 | 136 |
<input type="file" id="res-upload" name="upload"> |
| 125 | 137 |
</fieldset> |
| 126 | 138 |
<fieldset> |
| ... | ... |
@@ -32,18 +32,24 @@ |
| 32 | 32 |
</h3> |
| 33 | 33 |
<div class="bookings u-row-striped"> |
| 34 | 34 |
{% for booking in bookings.items %}
|
| 35 |
- <div class="row u-items-center ml-2"> |
|
| 36 |
- <div class="col-2 time icon-uhr-outline"> |
|
| 35 |
+ <div class="row u-items-center"> |
|
| 36 |
+ <div class="col-1 time icon-uhr-outline"> |
|
| 37 | 37 |
<div class="t-label">Uhrzeit</div> |
| 38 | 38 |
{{ booking.slot.time|date('H:i') }}
|
| 39 | 39 |
</div> |
| 40 | 40 |
<div class="col-3 behaelter icon-behaelter-outline"> |
| 41 | 41 |
<div class="t-label">Gebuchte Behälterkapazität</div> |
| 42 | 42 |
{{ booking.behaelter }}
|
| 43 |
- <div class="t-label">Anliefernde Sorten</div> |
|
| 44 |
- {{ booking.sorte|join(', ') }}
|
|
| 43 |
+ <div class="t-label">Ernteart</div> |
|
| 44 |
+ {{ booking.ernteart|join(', ') }}
|
|
| 45 | 45 |
</div> |
| 46 |
- <div class="col-5 rebsorten icon-reben-outline"> |
|
| 46 |
+ <div class="col-3 behaelter icon-behaelter-outline"> |
|
| 47 |
+ <div class="t-label">Anliefernde Sorten</div> |
|
| 48 |
+ {{ booking.sorte|join(', ') }}
|
|
| 49 |
+ <div class="t-label">Lage</div> |
|
| 50 |
+ {{ booking.lage|join(', ') }}
|
|
| 51 |
+ </div> |
|
| 52 |
+ <div class="col-3 rebsorten icon-reben-outline"> |
|
| 47 | 53 |
<div class="t-label">Mitglied</div> |
| 48 | 54 |
{% if booking.member is not null %}
|
| 49 | 55 |
{% if booking.member.memberno is defined %}<div>{{booking.member.memberno }}</div>{% endif %}
|
| ... | ... |
@@ -52,7 +58,7 @@ |
| 52 | 58 |
{% if booking.member.email is defined %}<div><a href="mailto:{{ booking.member.email }}">{{ booking.member.email }}</a></div>{% endif %}
|
| 53 | 59 |
{% endif %}
|
| 54 | 60 |
</div> |
| 55 |
- <div class="col u-text-right action"> |
|
| 61 |
+ <div class="col-1 u-text-right action"> |
|
| 56 | 62 |
<a |
| 57 | 63 |
href="/contao?do=weinanlieferung&table=tl_vr_wa_reservation&act=edit&id={{ booking.id }}&rt={{ request_token }}&ref={{ ref }}"
|
| 58 | 64 |
{# onclick="Backend.openModalIframe({'title':'Quellelement ID {{ booking.id }} bearbeiten','url':this.href});return false"#}
|
| ... | ... |
@@ -8,39 +8,60 @@ |
| 8 | 8 |
<div class="accordion-dis"> |
| 9 | 9 |
<div class="bookings"> |
| 10 | 10 |
{% for booking in bookings %}
|
| 11 |
- <div class="row u-flex-nowrap-md u-items-center"> |
|
| 11 |
+ <div class="row py-2 u-flex-nowrap-md u-items-center"> |
|
| 12 | 12 |
<div class="col-12"> |
| 13 |
- <div class="row"> |
|
| 14 |
- <div class="col-3 time pl-0"> |
|
| 15 |
- <div class="icon-uhr-outline u-flex u-items-center u-gap-1"> |
|
| 13 |
+ <div class="grid-md u-gap-1"> |
|
| 14 |
+ <div class="grid-c-3 time bg-white p-1"> |
|
| 15 |
+ <div class="u-flex u-items-center u-gap-1"> |
|
| 16 |
+ <i class="icon-uhr-outline"></i> |
|
| 16 | 17 |
<span class="t-label">Uhrzeit</span> |
| 17 | 18 |
{{ booking.slot.time|date('H:i') }}
|
| 18 | 19 |
</div> |
| 19 |
- <div class="icon-standort-outline u-flex u-items-center u-gap-1"> |
|
| 20 |
- <span class="t-label">Standort</span> |
|
| 21 |
- {{ booking.standort }}
|
|
| 22 |
- </div> |
|
| 23 | 20 |
</div> |
| 24 |
- <div class="col-3 behaelter"> |
|
| 25 |
- <div class="icon-behaelter-outline u-flex u-items-center u-gap-1"> |
|
| 21 |
+ <div class="grid-c-3 behaelter bg-white p-1"> |
|
| 22 |
+ <div class="u-flex u-flex-wrap u-gap-1"> |
|
| 23 |
+ <i class="icon-behaelter-outline"></i> |
|
| 26 | 24 |
<span class="t-label">Gebuchte Behälterkapazität</span> |
| 27 | 25 |
{{ booking.behaelter }}
|
| 28 | 26 |
</div> |
| 29 | 27 |
</div> |
| 30 |
- <div class="col-6 rebsorten pr-0"> |
|
| 31 |
- <div class="icon-reben-outline u-flex u-items-center u-gap-1"> |
|
| 28 |
+ <div class="grid-c-6 rebsorten bg-white p-1"> |
|
| 29 |
+ <div class="u-flex u-flex-wrap u-gap-1"> |
|
| 30 |
+ <i class="icon-reben-outline"></i> |
|
| 32 | 31 |
<div class="t-label">Anliefernde Sorten</div> |
| 33 | 32 |
|
| 34 | 33 |
</div> |
| 35 | 34 |
{{ booking.sorte|join(', ') }}
|
| 36 | 35 |
</div> |
| 36 |
+ <div class="grid-c-3 standort bg-white p-1"> |
|
| 37 |
+ <div class="u-flex u-flex-wrap u-gap-1"> |
|
| 38 |
+ <i class="icon-standort-outline"></i> |
|
| 39 |
+ <span class="t-label">Standort</span> |
|
| 40 |
+ {{ booking.standort }}
|
|
| 41 |
+ </div> |
|
| 42 |
+ </div> |
|
| 43 |
+ <div class="grid-c-3 ernteart bg-white p-1"> |
|
| 44 |
+ <div class="u-flex u-flex-wrap u-gap-1"> |
|
| 45 |
+ <i class="icon-schere-outline"></i> |
|
| 46 |
+ <div class="t-label">Erntearten</div> |
|
| 47 |
+ {{ booking.ernteart|join(', ') }}
|
|
| 48 |
+ </div> |
|
| 49 |
+ </div> |
|
| 50 |
+ <div class="grid-c-6 lage bg-white p-1"> |
|
| 51 |
+ <div class="u-flex u-flex-wrap u-gap-1"> |
|
| 52 |
+ <i class="icon-lage-outline"></i> |
|
| 53 |
+ <span class="t-label">Lagen</span> |
|
| 54 |
+ {{ booking.lage|join(', ') }}
|
|
| 55 |
+ </div> |
|
| 56 |
+ </div> |
|
| 37 | 57 |
{% if booking.slot.anmerkungen is defined and booking.slot.anmerkungen %}
|
| 38 |
- <div class="col-12 px-0"> |
|
| 39 |
- <div class="icon-info-outline u-flex u-items-center u-gap-1"> |
|
| 58 |
+ <div class="grid-c-12 bg-white p-1"> |
|
| 59 |
+ <div class="u-flex u-flex-wrap u-gap-1"> |
|
| 60 |
+ <i class="icon-info-outline"></i> |
|
| 40 | 61 |
<span class="t-label">Anmerkungen</span> |
| 62 |
+ {{ booking.slot.anmerkungen|raw }}
|
|
| 63 |
+ <a hx-get="/_ajax/vr_wa/v1/slot?do=annotation&id={{ booking.slot.id }}" hx-target="body" hx-swap="beforeend" href="javascript:;">mehr lesen</a>
|
|
| 41 | 64 |
</div> |
| 42 |
- {{ booking.slot.anmerkungen|raw }}
|
|
| 43 |
- <a hx-get="/_ajax/vr_wa/v1/slot?do=annotation&id={{ booking.slot.id }}" hx-target="body" hx-swap="beforeend" href="javascript:;">mehr lesen</a>
|
|
| 44 | 65 |
</div> |
| 45 | 66 |
{% endif %}
|
| 46 | 67 |
</div> |
| ... | ... |
@@ -83,15 +83,15 @@ |
| 83 | 83 |
<div class="grid-c-3 ernteart bg-white p-1"> |
| 84 | 84 |
<div class="u-flex u-flex-wrap u-gap-1"> |
| 85 | 85 |
<i class="icon-schere-outline"></i> |
| 86 |
- <div class="t-label">Ernteart</div> |
|
| 86 |
+ <div class="t-label">Erntearten</div> |
|
| 87 | 87 |
{{ slot.ernteart|join(', ') }}
|
| 88 | 88 |
</div> |
| 89 | 89 |
</div> |
| 90 | 90 |
<div class="grid-c-6 lage bg-white p-1"> |
| 91 | 91 |
<div class="u-flex u-flex-wrap u-gap-1"> |
| 92 | 92 |
<i class="icon-lage-outline"></i> |
| 93 |
- <span class="t-label">Lage</span> |
|
| 94 |
- {{ slot.lage }}
|
|
| 93 |
+ <span class="t-label">Lagen</span> |
|
| 94 |
+ {{ slot.lage|join(', ') }}
|
|
| 95 | 95 |
</div> |
| 96 | 96 |
</div> |
| 97 | 97 |
{% if slot.anmerkungen is defined and slot.anmerkungen %}
|
| ... | ... |
@@ -62,6 +62,7 @@ class WeinanlieferungBookingsController extends AbstractController |
| 62 | 62 |
'request_token' => $this->tokenManager->getDefaultTokenValue(), |
| 63 | 63 |
'ref' => $this->request->attributes->get('_contao_referer_id')
|
| 64 | 64 |
]; |
| 65 |
+ System::loadLanguageFile('default');
|
|
| 65 | 66 |
|
| 66 | 67 |
// Get bookings |
| 67 | 68 |
if (($bookings = WeinanlieferungReservationModel::findAllFuture(['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) |
| ... | ... |
@@ -74,6 +75,8 @@ class WeinanlieferungBookingsController extends AbstractController |
| 74 | 75 |
{
|
| 75 | 76 |
$day = new Date($Slot->date); |
| 76 | 77 |
$arrSorten = []; |
| 78 |
+ $arrErnteart = []; |
|
| 79 |
+ $arrLagen = []; |
|
| 77 | 80 |
|
| 78 | 81 |
if (!isset($arrData['days'][$day->dayBegin][$Slot->time])) |
| 79 | 82 |
{
|
| ... | ... |
@@ -103,8 +106,26 @@ class WeinanlieferungBookingsController extends AbstractController |
| 103 | 106 |
} |
| 104 | 107 |
} |
| 105 | 108 |
|
| 109 |
+ if ($booking->ernteart !== null) |
|
| 110 |
+ {
|
|
| 111 |
+ foreach (explode(',', $booking->ernteart) as $ernteart)
|
|
| 112 |
+ {
|
|
| 113 |
+ $arrErnteart[$ernteart] = $GLOBALS['TL_LANG']['REF']['wa_ernteart'][$ernteart] ?? $ernteart; |
|
| 114 |
+ } |
|
| 115 |
+ } |
|
| 116 |
+ |
|
| 117 |
+ if (($Lagen = $booking->getRelated('lage')) !== null)
|
|
| 118 |
+ {
|
|
| 119 |
+ foreach ($Lagen as $lage) |
|
| 120 |
+ {
|
|
| 121 |
+ $arrLagen[$lage->id] = $lage->title; |
|
| 122 |
+ } |
|
| 123 |
+ } |
|
| 124 |
+ |
|
| 106 | 125 |
$arrData['days'][$day->dayBegin][$Slot->time]['items'][] = array_merge($booking->row(), [ |
| 107 | 126 |
'sorte' => $arrSorten, |
| 127 |
+ 'ernteart' => $arrErnteart, |
|
| 128 |
+ 'lage' => $arrLagen, |
|
| 108 | 129 |
'slot' => $Slot->row(), |
| 109 | 130 |
'member' => $booking->getRelated('uid') !== null ? $booking->getRelated('uid')->row() : null
|
| 110 | 131 |
]); |
| ... | ... |
@@ -31,6 +31,7 @@ use Symfony\Component\HttpFoundation\Request; |
| 31 | 31 |
use Symfony\Component\HttpFoundation\Response; |
| 32 | 32 |
use Symfony\Component\Routing\Annotation\Route; |
| 33 | 33 |
use Symfony\Contracts\Translation\TranslatorInterface; |
| 34 |
+use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungLageModel; |
|
| 34 | 35 |
use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungLeseartModel; |
| 35 | 36 |
use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungRebsorteModel; |
| 36 | 37 |
use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungReservationModel; |
| ... | ... |
@@ -154,10 +155,16 @@ class SlotAjaxController extends AbstractController |
| 154 | 155 |
{
|
| 155 | 156 |
foreach (explode(',', $Slot->ernteart) as $ernteart)
|
| 156 | 157 |
{
|
| 157 |
- $arrErnteart[] = $GLOBALS['TL_LANG']['REF']['wa_ernteart'][$ernteart] ?? $ernteart; |
|
| 158 |
+ $arrErnteart[$ernteart] = $GLOBALS['TL_LANG']['REF']['wa_ernteart'][$ernteart] ?? $ernteart; |
|
| 158 | 159 |
} |
| 159 | 160 |
} |
| 160 | 161 |
|
| 162 |
+ $arrLage = []; |
|
| 163 |
+ if (($Lage = $Slot->getRelated('lage')) !== null)
|
|
| 164 |
+ {
|
|
| 165 |
+ $arrLage = array_combine($Lage->fetchEach('id'),$Lage->fetchEach('title'));
|
|
| 166 |
+ } |
|
| 167 |
+ |
|
| 161 | 168 |
$intAvailableBehaelter = $Slot->getAvailableBehaelter(); |
| 162 | 169 |
|
| 163 | 170 |
$arrData = [ |
| ... | ... |
@@ -168,12 +175,14 @@ class SlotAjaxController extends AbstractController |
| 168 | 175 |
'behaelterAvailable' => $intAvailableBehaelter |
| 169 | 176 |
]), |
| 170 | 177 |
'standort' => $Slot->getRelated('pid'),
|
| 171 |
- 'lage' => $Slot->getRelated('lage'),
|
|
| 178 |
+ 'lage' => $arrLage, |
|
| 172 | 179 |
'ernteart' => $arrErnteart, |
| 173 | 180 |
'buchen' => [ |
| 174 | 181 |
'buchbar' => (boolean) $intAvailableBehaelter, |
| 175 | 182 |
'behaelter' => range(min($intAvailableBehaelter,1),$intAvailableBehaelter), |
| 176 |
- 'sorten' => $arrSorten |
|
| 183 |
+ 'sorten' => $arrSorten, |
|
| 184 |
+ 'lage' => $arrLage, |
|
| 185 |
+ 'ernteart' => $arrErnteart, |
|
| 177 | 186 |
], |
| 178 | 187 |
'reservations' => $arrReservations |
| 179 | 188 |
]; |
| ... | ... |
@@ -217,6 +226,12 @@ class SlotAjaxController extends AbstractController |
| 217 | 226 |
} |
| 218 | 227 |
} |
| 219 | 228 |
|
| 229 |
+ $arrLage = []; |
|
| 230 |
+ if (($Lage = $Slot->getRelated('lage')) !== null)
|
|
| 231 |
+ {
|
|
| 232 |
+ $arrLage = $Lage->fetchEach('title');
|
|
| 233 |
+ } |
|
| 234 |
+ |
|
| 220 | 235 |
$intAvailableBehaelter = $Slot->getAvailableBehaelter(); |
| 221 | 236 |
|
| 222 | 237 |
$arrData = [ |
| ... | ... |
@@ -227,7 +242,7 @@ class SlotAjaxController extends AbstractController |
| 227 | 242 |
'behaelterAvailable' => $intAvailableBehaelter |
| 228 | 243 |
]), |
| 229 | 244 |
'standort' => $Slot->getRelated('pid'),
|
| 230 |
- 'lage' => $Slot->getRelated('lage'),
|
|
| 245 |
+ 'lage' => $arrLage, |
|
| 231 | 246 |
'ernteart' => $arrErnteart, |
| 232 | 247 |
'buchen' => [ |
| 233 | 248 |
'buchbar' => (boolean) $intAvailableBehaelter, |
| ... | ... |
@@ -239,7 +254,7 @@ class SlotAjaxController extends AbstractController |
| 239 | 254 |
return $this->render('@Contao/modal_slot_annotation.html.twig',$arrData);
|
| 240 | 255 |
} |
| 241 | 256 |
|
| 242 |
- protected function renderBooking(bool $blnModal=true) |
|
| 257 |
+ protected function renderBooking(bool $blnModal=true,string $error=null) |
|
| 243 | 258 |
{
|
| 244 | 259 |
$arrData = []; |
| 245 | 260 |
|
| ... | ... |
@@ -315,6 +330,34 @@ class SlotAjaxController extends AbstractController |
| 315 | 330 |
$arrSortenBooked[$objSorte->id.','.$objLeseart->id] = ($objSorte !== null ? $objSorte->title : '') . ' ' . ($objLeseart !== null ? $objLeseart->title : ''); |
| 316 | 331 |
} |
| 317 | 332 |
|
| 333 |
+ $arrErnteartAvailable = []; |
|
| 334 |
+ if ($Slot->ernteart !== null) |
|
| 335 |
+ {
|
|
| 336 |
+ foreach (explode(',', $Slot->ernteart) as $ernteart)
|
|
| 337 |
+ {
|
|
| 338 |
+ $arrErnteartAvailable[$ernteart] = $GLOBALS['TL_LANG']['REF']['wa_ernteart'][$ernteart] ?? $ernteart; |
|
| 339 |
+ } |
|
| 340 |
+ } |
|
| 341 |
+ $arrErnteartBooked = []; |
|
| 342 |
+ if ($Booking->ernteart !== null) |
|
| 343 |
+ {
|
|
| 344 |
+ $arrErnteartBooked = explode(',', $Booking->ernteart);
|
|
| 345 |
+ } |
|
| 346 |
+ |
|
| 347 |
+ $arrLagenAvailable = []; |
|
| 348 |
+ if (($Lagen = $Slot->getRelated('lage')) !== null)
|
|
| 349 |
+ {
|
|
| 350 |
+ foreach ($Lagen as $lage) |
|
| 351 |
+ {
|
|
| 352 |
+ $arrLagenAvailable[$lage->id] = $lage->title; |
|
| 353 |
+ } |
|
| 354 |
+ } |
|
| 355 |
+ $arrLagenBooked = []; |
|
| 356 |
+ if ($Booking->lage !== null) |
|
| 357 |
+ {
|
|
| 358 |
+ $arrLagenBooked = explode(',', $Booking->lage);
|
|
| 359 |
+ } |
|
| 360 |
+ |
|
| 318 | 361 |
$intAvailableBehaelter = $Slot->getAvailableBehaelter(); |
| 319 | 362 |
|
| 320 | 363 |
$arrData = array_merge($arrData,[ |
| ... | ... |
@@ -322,19 +365,28 @@ class SlotAjaxController extends AbstractController |
| 322 | 365 |
'id' => $Booking->id, |
| 323 | 366 |
'slot' => array_merge($Slot->row(),[ |
| 324 | 367 |
'sorte' => $arrSortenAvailable, |
| 325 |
- 'behaelterAvailable' => $intAvailableBehaelter |
|
| 368 |
+ 'behaelterAvailable' => $intAvailableBehaelter, |
|
| 326 | 369 |
]), |
| 327 | 370 |
'buchung' => array_merge($Booking->row(),[ |
| 328 |
- 'sorten' => $arrSortenBooked |
|
| 371 |
+ 'sorten' => $arrSortenBooked, |
|
| 372 |
+ 'ernteart' => $arrErnteartBooked, |
|
| 373 |
+ 'lage' => $arrLagenBooked, |
|
| 329 | 374 |
]), |
| 330 | 375 |
'standort' => $Slot->getRelated('pid'),
|
| 331 | 376 |
'buchen' => [ |
| 332 | 377 |
'buchbar' => (boolean) $intAvailableBehaelter, |
| 333 | 378 |
'behaelter' => range(min($intAvailableBehaelter,1),$intAvailableBehaelter+$Booking->behaelter), |
| 334 |
- 'sorten' => $arrSortenAvailable |
|
| 379 |
+ 'sorten' => $arrSortenAvailable, |
|
| 380 |
+ 'ernteart' => $arrErnteartAvailable, |
|
| 381 |
+ 'lage' => $arrLagenAvailable, |
|
| 335 | 382 |
] |
| 336 | 383 |
]); |
| 337 | 384 |
|
| 385 |
+ if (!empty($error)) |
|
| 386 |
+ {
|
|
| 387 |
+ $arrData['toast'] = $error; |
|
| 388 |
+ } |
|
| 389 |
+ |
|
| 338 | 390 |
return $this->render('@Contao/modal_booking_details.html.twig',$arrData);
|
| 339 | 391 |
} |
| 340 | 392 |
|
| ... | ... |
@@ -364,11 +416,33 @@ class SlotAjaxController extends AbstractController |
| 364 | 416 |
} |
| 365 | 417 |
} |
| 366 | 418 |
|
| 367 |
- if (empty($_REQUEST['id']) || empty(Input::post('behaelter')) || empty(Input::post('sorten')))
|
|
| 419 |
+ if (empty($_REQUEST['id'])) |
|
| 368 | 420 |
{
|
| 369 | 421 |
return new Response('Missing parameter',412);
|
| 370 | 422 |
} |
| 371 | 423 |
|
| 424 |
+ // Form validation |
|
| 425 |
+ if (($Slot = WeinanlieferungSlotsModel::findByPk($_REQUEST['id'])) !== null) |
|
| 426 |
+ {
|
|
| 427 |
+ if (Input::post('behaelter') > $Slot->getAvailableBehaelter())
|
|
| 428 |
+ {
|
|
| 429 |
+ return $this->renderDetails(false,sprintf('<div class="toast toast--danger mx-0">Fehler: Es sind mittlerweile nur noch %s Behälter verfügbar.</div>',$Slot->getAvailableBehaelter()));
|
|
| 430 |
+ } |
|
| 431 |
+ } |
|
| 432 |
+ $arrError = []; |
|
| 433 |
+ foreach (['behaelter','sorten','ernteart'] as $field) |
|
| 434 |
+ {
|
|
| 435 |
+ if (empty(Input::post($field))) |
|
| 436 |
+ {
|
|
| 437 |
+ $arrError = [$field]; |
|
| 438 |
+ } |
|
| 439 |
+ } |
|
| 440 |
+ |
|
| 441 |
+ if (count($arrError)) |
|
| 442 |
+ {
|
|
| 443 |
+ return $this->renderDetails(false,'<div class="toast toast--danger mx-0">Bitte geben Sie alle Pflichtangaben (mit * marierte Felder) an</div>'); |
|
| 444 |
+ } |
|
| 445 |
+ |
|
| 372 | 446 |
$arrSorten = []; |
| 373 | 447 |
if (!is_array(Input::post('sorten')))
|
| 374 | 448 |
{
|
| ... | ... |
@@ -377,13 +451,31 @@ class SlotAjaxController extends AbstractController |
| 377 | 451 |
$arrSorten = implode(';', Input::post('sorten'));
|
| 378 | 452 |
} |
| 379 | 453 |
|
| 454 |
+ $arrErnteart = []; |
|
| 455 |
+ if (!is_array(Input::post('ernteart')))
|
|
| 456 |
+ {
|
|
| 457 |
+ $arrErnteart[] = Input::post('ernteart');
|
|
| 458 |
+ } else {
|
|
| 459 |
+ $arrErnteart = implode(',', Input::post('ernteart'));
|
|
| 460 |
+ } |
|
| 461 |
+ |
|
| 462 |
+ $arrLage = []; |
|
| 463 |
+ if (!is_array(Input::post('lage')))
|
|
| 464 |
+ {
|
|
| 465 |
+ $arrLage[] = Input::post('lage');
|
|
| 466 |
+ } else {
|
|
| 467 |
+ $arrLage = implode(',', Input::post('lage'));
|
|
| 468 |
+ } |
|
| 469 |
+ |
|
| 380 | 470 |
$Reservation = new WeinanlieferungReservationModel(); |
| 381 | 471 |
$arrData = array_merge($arrData,[ |
| 382 | 472 |
'pid' => $_REQUEST['id'], |
| 383 | 473 |
'tstamp' => time(), |
| 384 | 474 |
'uid' => FrontendUser::getInstance()->id, |
| 385 | 475 |
'behaelter' => Input::post('behaelter'),
|
| 386 |
- 'sorten' => $arrSorten |
|
| 476 |
+ 'sorten' => $arrSorten, |
|
| 477 |
+ 'ernteart' => $arrErnteart, |
|
| 478 |
+ 'lage' => $arrLage |
|
| 387 | 479 |
]); |
| 388 | 480 |
$Reservation->setRow($arrData); |
| 389 | 481 |
|
| ... | ... |
@@ -397,7 +489,7 @@ class SlotAjaxController extends AbstractController |
| 397 | 489 |
{
|
| 398 | 490 |
Controller::loadDataContainer('tl_vr_wa_reservation');
|
| 399 | 491 |
|
| 400 |
- if (empty($_REQUEST['id']) || empty(Input::post('behaelter')) || empty(Input::post('sorten')))
|
|
| 492 |
+ if (empty($_REQUEST['id'])) |
|
| 401 | 493 |
{
|
| 402 | 494 |
return new Response('Missing parameter',412);
|
| 403 | 495 |
} |
| ... | ... |
@@ -418,7 +510,7 @@ class SlotAjaxController extends AbstractController |
| 418 | 510 |
|
| 419 | 511 |
if ($File->hasErrors()) |
| 420 | 512 |
{
|
| 421 |
- return $this->renderDetails(false,'<div class="toast toast--danger mx-0">' . $File->getErrorAsHTML() . '</div>'); |
|
| 513 |
+ return $this->renderBooking(false,'<div class="toast toast--danger mx-0">' . $File->getErrorAsHTML() . '</div>'); |
|
| 422 | 514 |
} |
| 423 | 515 |
|
| 424 | 516 |
if (!empty($_SESSION['FILES'][$File->name])) |
| ... | ... |
@@ -428,6 +520,28 @@ class SlotAjaxController extends AbstractController |
| 428 | 520 |
} |
| 429 | 521 |
} |
| 430 | 522 |
|
| 523 |
+ // Form validation |
|
| 524 |
+ if (($Slot = $Reservation->getRelated('pid')) !== null)
|
|
| 525 |
+ {
|
|
| 526 |
+ if (Input::post('behaelter') > $Slot->getAvailableBehaelter()+$Reservation->behaelter)
|
|
| 527 |
+ {
|
|
| 528 |
+ return $this->renderBooking(false,sprintf('<div class="toast toast--danger mx-0">Fehler: Es sind mittlerweile nur noch %s Behälter verfügbar.</div>',$Slot->getAvailableBehaelter()+$Reservation->behaelter));
|
|
| 529 |
+ } |
|
| 530 |
+ } |
|
| 531 |
+ $arrError = []; |
|
| 532 |
+ foreach (['behaelter','sorten','ernteart'] as $field) |
|
| 533 |
+ {
|
|
| 534 |
+ if (empty(Input::post($field))) |
|
| 535 |
+ {
|
|
| 536 |
+ $arrError = [$field]; |
|
| 537 |
+ } |
|
| 538 |
+ } |
|
| 539 |
+ |
|
| 540 |
+ if (count($arrError)) |
|
| 541 |
+ {
|
|
| 542 |
+ return $this->renderBooking(false,'<div class="toast toast--danger mx-0">Bitte geben Sie alle Pflichtangaben (mit * marierte Felder) an</div>'); |
|
| 543 |
+ } |
|
| 544 |
+ |
|
| 431 | 545 |
$arrSorten = []; |
| 432 | 546 |
if (!is_array(Input::post('sorten')))
|
| 433 | 547 |
{
|
| ... | ... |
@@ -436,9 +550,27 @@ class SlotAjaxController extends AbstractController |
| 436 | 550 |
$arrSorten = implode(';', Input::post('sorten'));
|
| 437 | 551 |
} |
| 438 | 552 |
|
| 553 |
+ $arrErnteart = []; |
|
| 554 |
+ if (!is_array(Input::post('ernteart')))
|
|
| 555 |
+ {
|
|
| 556 |
+ $arrErnteart[] = Input::post('ernteart');
|
|
| 557 |
+ } else {
|
|
| 558 |
+ $arrErnteart = implode(',', Input::post('ernteart'));
|
|
| 559 |
+ } |
|
| 560 |
+ |
|
| 561 |
+ $arrLage = []; |
|
| 562 |
+ if (!is_array(Input::post('lage')))
|
|
| 563 |
+ {
|
|
| 564 |
+ $arrLage[] = Input::post('lage');
|
|
| 565 |
+ } else {
|
|
| 566 |
+ $arrLage = implode(',', Input::post('lage'));
|
|
| 567 |
+ } |
|
| 568 |
+ |
|
| 439 | 569 |
$Reservation->tstamp = time(); |
| 440 | 570 |
$Reservation->behaelter = Input::post('behaelter');
|
| 441 | 571 |
$Reservation->sorten = $arrSorten; |
| 572 |
+ $Reservation->ernteart = $arrErnteart; |
|
| 573 |
+ $Reservation->lage = $arrLage; |
|
| 442 | 574 |
|
| 443 | 575 |
$Reservation->save(); |
| 444 | 576 |
|
| ... | ... |
@@ -76,12 +76,28 @@ class WeinanlieferungBookedListModuleController extends AbstractFrontendModuleCo |
| 76 | 76 |
$strStandort = $Standort->title; |
| 77 | 77 |
} |
| 78 | 78 |
|
| 79 |
+ if ($booking->ernteart !== null) |
|
| 80 |
+ {
|
|
| 81 |
+ foreach (explode(',', $booking->ernteart) as $ernteart)
|
|
| 82 |
+ {
|
|
| 83 |
+ $arrErnteart[] = $GLOBALS['TL_LANG']['REF']['wa_ernteart'][$ernteart] ?? $ernteart; |
|
| 84 |
+ } |
|
| 85 |
+ } |
|
| 86 |
+ |
|
| 87 |
+ $arrLage = []; |
|
| 88 |
+ if (($Lage = $booking->getRelated('lage')) !== null)
|
|
| 89 |
+ {
|
|
| 90 |
+ $arrLage = $Lage->fetchEach('title');
|
|
| 91 |
+ } |
|
| 92 |
+ |
|
| 79 | 93 |
$arrData['days'][$day->dayBegin][] = array_merge($booking->row(), [ |
| 80 | 94 |
'sorte' => $arrSorten, |
| 81 | 95 |
'slot' => array_merge($Slot->row(),[ |
| 82 | 96 |
'anmerkungen' => $Slot->anmerkungen ? StringUtil::substr(strip_tags($Slot->anmerkungen),110) : '', |
| 83 | 97 |
]), |
| 84 | 98 |
'standort' => $strStandort, |
| 99 |
+ 'ernteart' => $arrErnteart, |
|
| 100 |
+ 'lage' => $arrLage, |
|
| 85 | 101 |
]); |
| 86 | 102 |
} |
| 87 | 103 |
} |
| ... | ... |
@@ -135,16 +135,16 @@ class WeinanlieferungSlotsListModuleController extends AbstractFrontendModuleCon |
| 135 | 135 |
$strStandort = $Standort->title; |
| 136 | 136 |
} |
| 137 | 137 |
|
| 138 |
- $strLage = ''; |
|
| 138 |
+ $arrLage = []; |
|
| 139 | 139 |
if (($Lage = $slot->getRelated('lage')) !== null)
|
| 140 | 140 |
{
|
| 141 |
- $strLage = $Lage->title; |
|
| 141 |
+ $arrLage = $Lage->fetchEach('title');
|
|
| 142 | 142 |
} |
| 143 | 143 |
|
| 144 | 144 |
$arrData['days'][$day->dayBegin][] = array_merge($slot->row(),[ |
| 145 | 145 |
'anmerkungen' => $slot->anmerkungen ? StringUtil::substr(strip_tags($slot->anmerkungen),110) : '', |
| 146 | 146 |
'standort' => $strStandort, |
| 147 |
- 'lage' => $strLage, |
|
| 147 |
+ 'lage' => $arrLage, |
|
| 148 | 148 |
'sorte' => $arrSorten, |
| 149 | 149 |
'ernteart' => $arrErnteart, |
| 150 | 150 |
'behaelterAvailable' => $intAvailableBehaelter, |
| ... | ... |
@@ -56,6 +56,26 @@ class WeinanlieferungReservationContainerListener |
| 56 | 56 |
} |
| 57 | 57 |
|
| 58 | 58 |
/** |
| 59 |
+ * @Callback(table="tl_vr_wa_reservation", target="fields.lage.options") |
|
| 60 |
+ */ |
|
| 61 |
+ public function onLageOptionsCallback(DataContainer $dc) |
|
| 62 |
+ {
|
|
| 63 |
+ $arrLagen = []; |
|
| 64 |
+ |
|
| 65 |
+ if (($Slot = WeinanlieferungSlotsModel::findByPk($dc->activeRecord->pid)) === null || $Slot->lage === null) |
|
| 66 |
+ {
|
|
| 67 |
+ return $arrLagen; |
|
| 68 |
+ } |
|
| 69 |
+ |
|
| 70 |
+ if (($Lagen = $Slot->getRelated('lage')) !== null)
|
|
| 71 |
+ {
|
|
| 72 |
+ $arrLagen = array_combine($Lagen->fetchEach('id'),$Lagen->fetchEach('title'));
|
|
| 73 |
+ } |
|
| 74 |
+ |
|
| 75 |
+ return $arrLagen; |
|
| 76 |
+ } |
|
| 77 |
+ |
|
| 78 |
+ /** |
|
| 59 | 79 |
* @Callback(table="tl_vr_wa_reservation", target="fields.ernteart.options") |
| 60 | 80 |
*/ |
| 61 | 81 |
public function onErnteartOptionsCallback(DataContainer $dc) |
| ... | ... |
@@ -70,7 +90,7 @@ class WeinanlieferungReservationContainerListener |
| 70 | 90 |
$Ernteart = explode(',',$Slot->ernteart);
|
| 71 | 91 |
foreach($Ernteart as $art) |
| 72 | 92 |
{
|
| 73 |
- $arrErnteart[] = $GLOBALS['TL_LANG']['REF']['wa_ernteart'][$art] ?? $art; |
|
| 93 |
+ $arrErnteart[$art] = $GLOBALS['TL_LANG']['REF']['wa_ernteart'][$art] ?? $art; |
|
| 74 | 94 |
} |
| 75 | 95 |
|
| 76 | 96 |
return $arrErnteart; |
| ... | ... |
@@ -35,8 +35,9 @@ class WeinanlieferungSlotsModel extends Model |
| 35 | 35 |
|
| 36 | 36 |
// Skip unsaved elements (see #2708) |
| 37 | 37 |
$arrColumns[] = "$t.tstamp!=0"; |
| 38 |
+ $arrColumns[] = "$t.published='1'"; |
|
| 38 | 39 |
|
| 39 |
- $arrColumns[] = "$t.buchbar='1' AND $t.buchbar_bis>$time"; |
|
| 40 |
+ $arrColumns[] = "($t.buchbar_ab<=$time OR $t.buchbar_ab = 0 OR $t.buchbar_ab IS NULL) AND $t.buchbar_bis>$time"; |
|
| 40 | 41 |
|
| 41 | 42 |
if (!isset($arrOptions['order'])) |
| 42 | 43 |
{
|
| ... | ... |
@@ -54,8 +55,9 @@ class WeinanlieferungSlotsModel extends Model |
| 54 | 55 |
|
| 55 | 56 |
// Skip unsaved elements (see #2708) |
| 56 | 57 |
$arrColumns[] = "$t.tstamp!=0"; |
| 58 |
+ $arrColumns[] = "$t.published='1'"; |
|
| 57 | 59 |
|
| 58 |
- $arrColumns[] = "$t.buchbar='1' AND $t.buchbar_bis>$time"; |
|
| 60 |
+ $arrColumns[] = "($t.buchbar_ab<=$time OR $t.buchbar_ab = 0 OR $t.buchbar_ab IS NULL) AND $t.buchbar_bis>$time"; |
|
| 59 | 61 |
|
| 60 | 62 |
if (!isset($arrOptions['order'])) |
| 61 | 63 |
{
|
| ... | ... |
@@ -87,8 +89,9 @@ class WeinanlieferungSlotsModel extends Model |
| 87 | 89 |
|
| 88 | 90 |
// Skip unsaved elements (see #2708) |
| 89 | 91 |
$arrColumns[] = "$t.tstamp!=0"; |
| 92 |
+ $arrColumns[] = "$t.published='1'"; |
|
| 90 | 93 |
|
| 91 |
- $arrColumns[] = "$t.buchbar='1' AND $t.buchbar_bis>$time"; |
|
| 94 |
+ $arrColumns[] = "($t.buchbar_ab<=$time OR $t.buchbar_ab = 0 OR $t.buchbar_ab IS NULL) AND $t.buchbar_bis>$time"; |
|
| 92 | 95 |
|
| 93 | 96 |
if (!isset($arrOptions['order'])) |
| 94 | 97 |
{
|
| ... | ... |
@@ -108,7 +111,7 @@ class WeinanlieferungSlotsModel extends Model |
| 108 | 111 |
$arrOptions['order'] = "$t.time ASC"; |
| 109 | 112 |
} |
| 110 | 113 |
|
| 111 |
- return static::findBy(array("$t.time >= ?","$t.tstamp!=0","$t.buchbar='1' AND $t.buchbar_bis > ?"), [$time,$time], $arrOptions);
|
|
| 114 |
+ return static::findBy(array("$t.time >= ?","$t.tstamp!=0","$t.published='1' AND ($t.buchbar_ab<=$time OR $t.buchbar_ab = 0 OR $t.buchbar_ab IS NULL) AND $t.buchbar_bis > ?"), [$time,$time,$time], $arrOptions);
|
|
| 112 | 115 |
} |
| 113 | 116 |
|
| 114 | 117 |
public function getAvailableBehaelter(?int $intOffset=null) |