Browse code

Allow overcapacity booking

Benjamin Roth authored on20/08/2024 16:36:00
Showing11 changed files
... ...
@@ -93,7 +93,7 @@ $GLOBALS['TL_DCA']['tl_vr_wa_slot'] = array
93 93
     (
94 94
         '__selector__' => array('addEnclosure'),
95 95
 //        'default' => '{time_legend},date,time,duration;{type_legend},behaelter,sorten,lage,ernteart;{info_legend},anmerkungen,addEnclosure;{booking_legend},published,buchbar_ab,buchbar_bis'
96
-        'default' => '{time_legend},date,time,duration;{type_legend},behaelter;{info_legend},anmerkungen,addEnclosure;{booking_legend},published,buchbar_ab,buchbar_bis'
96
+        'default' => '{time_legend},date,time,duration;{type_legend},behaelter,overcapacity;{info_legend},anmerkungen,addEnclosure;{booking_legend},published,buchbar_ab,buchbar_bis'
97 97
     ),
98 98
 
99 99
     // Subpalettes
... ...
@@ -177,6 +177,19 @@ $GLOBALS['TL_DCA']['tl_vr_wa_slot'] = array
177 177
             ),
178 178
             'sql'                     => "int(4) NOT NULL default 0"
179 179
         ),
180
+        'overcapacity' => array
181
+        (
182
+            'exclude'                 => true,
183
+            'inputType'               => 'text',
184
+            'eval'                    => array
185
+            (
186
+                'mandatory' => true,
187
+                'rgxp'      => 'prcnt',
188
+                'nospace'   => true,
189
+                'tl_class' => 'w50'
190
+            ),
191
+            'sql'                     => "int(10) NULL"
192
+        ),
180 193
         'sorten'       => array
181 194
         (
182 195
             'exclude'   => true,
... ...
@@ -88,7 +88,7 @@ $GLOBALS['TL_DCA']['tl_vr_wa_slottypes'] = array
88 88
     // Palettes
89 89
     'palettes' => array
90 90
     (
91
-        'default' => '{title_legend},title;{config_legend},duration,containers;{expert_legend},default'
91
+        'default' => '{title_legend},title;{config_legend},duration,containers,overcapacity;{expert_legend},default'
92 92
     ),
93 93
 
94 94
     // Subpalettes
... ...
@@ -157,6 +157,19 @@ $GLOBALS['TL_DCA']['tl_vr_wa_slottypes'] = array
157 157
             ),
158 158
             'sql'                     => "int(4) NOT NULL default 0"
159 159
         ),
160
+        'overcapacity' => array
161
+        (
162
+            'exclude'                 => true,
163
+            'inputType'               => 'text',
164
+            'eval'                    => array
165
+            (
166
+                'mandatory' => true,
167
+                'rgxp'      => 'prcnt',
168
+                'nospace'   => true,
169
+                'tl_class' => 'w50'
170
+            ),
171
+            'sql'                     => "int(10) NULL"
172
+        ),
160 173
         'default' => array
161 174
         (
162 175
             'exclude'                 => true,
... ...
@@ -16,6 +16,7 @@ $GLOBALS['TL_LANG']['MSC']['wa_duration_minute'] = 'Minute';
16 16
 $GLOBALS['TL_LANG']['MSC']['wa_duration_minutes'] = 'Minuten';
17 17
 $GLOBALS['TL_LANG']['MSC']['wa_duration_hour'] = 'Stunde';
18 18
 $GLOBALS['TL_LANG']['MSC']['wa_duration_hours'] = 'Stunden';
19
+$GLOBALS['TL_LANG']['MSC']['wa_overbooking'] = 'erlaubte Überbuchung';
19 20
 
20 21
 $GLOBALS['TL_LANG']['REF']['wa_ernteart'] = [
21 22
     'handlese' => 'Handlese',
... ...
@@ -16,6 +16,8 @@ $GLOBALS['TL_LANG']['tl_vr_wa_slot']['duration'][0] = 'Dauer in min.';
16 16
 $GLOBALS['TL_LANG']['tl_vr_wa_slot']['duration'][1] = 'Die Dauer des Slots.';
17 17
 $GLOBALS['TL_LANG']['tl_vr_wa_slot']['behaelter'][0] = 'Bottiche';
18 18
 $GLOBALS['TL_LANG']['tl_vr_wa_slot']['behaelter'][1] = 'Anzahl der Bottiche, die verarbeitet werden können.';
19
+$GLOBALS['TL_LANG']['tl_vr_wa_slot']['overcapacity'][0] = 'Überkapazität';
20
+$GLOBALS['TL_LANG']['tl_vr_wa_slot']['overcapacity'][1] = 'Die mögliche Überkapazität in Prozent auf die verarbeitbare Menge gesehen.';
19 21
 $GLOBALS['TL_LANG']['tl_vr_wa_slot']['lage'][0] = 'Lage';
20 22
 $GLOBALS['TL_LANG']['tl_vr_wa_slot']['lage'][1] = 'Lage der angelieferten Reben.';
21 23
 $GLOBALS['TL_LANG']['tl_vr_wa_slot']['units'][0] = 'Zusätzliche Bottich-Einheiten';
... ...
@@ -26,6 +26,14 @@
26 26
                 <source>The amount of processable containers within the slot duration.</source>
27 27
                 <target>Die Anzahl der verarbeitbaren Bottiche innerhalb der Slotdauer.</target>
28 28
             </trans-unit>
29
+            <trans-unit id="tl_vr_wa_slottypes.overcapacity.0">
30
+                <source>Overcapacity</source>
31
+                <target>Überkapazität</target>
32
+            </trans-unit>
33
+            <trans-unit id="tl_vr_wa_slottypes.overcapacity.1">
34
+                <source>The possible overcapacity as a percentage of the quantity that can be processed.</source>
35
+                <target>Die mögliche Überkapazität in Prozent auf die verarbeitbare Menge gesehen.</target>
36
+            </trans-unit>
29 37
             <trans-unit id="tl_vr_wa_slottypes.units.0">
30 38
                 <source>Additional container units</source>
31 39
                 <target>Zusätzliche Bottich-Einheiten</target>
... ...
@@ -67,7 +67,11 @@
67 67
                             <select id="res-behaelter" name="behaelter" required>
68 68
                                 <option value="">-</option>
69 69
                                 {% for option in buchen.behaelter %}
70
-                                    <option value="{{ option }}"{{ buchung.amount == option ? ' selected' : '' }}>{{ option }}</option>
70
+                                    {% if option > slot.behaelter %}
71
+                                        <option value="{{ option }}"{{ buchung.amount == option ? ' selected' : '' }}>{{ option }} ({{ 'MSC.wa_overbooking'|trans([], 'contao_default') }})</option>
72
+                                    {% else %}
73
+                                        <option value="{{ option }}"{{ buchung.amount == option ? ' selected' : '' }}>{{ option }}</option>
74
+                                    {% endif %}
71 75
                                 {% endfor %}
72 76
                             </select>
73 77
                         </fieldset>
... ...
@@ -101,7 +101,11 @@
101 101
                                     <select id="res-behaelter" name="behaelter" required>
102 102
                                         <option value="">-</option>
103 103
                                         {% for option in buchen.behaelter %}
104
-                                            <option value="{{ option }}">{{ option }}</option>
104
+                                            {% if option > slot.behaelterAvailable %}
105
+                                                <option value="{{ option }}">{{ option }} ({{ 'MSC.wa_overbooking'|trans([], 'contao_default') }})</option>
106
+                                            {% else %}
107
+                                                <option value="{{ option }}">{{ option }}</option>
108
+                                            {% endif %}
105 109
                                         {% endfor %}
106 110
                                     </select>
107 111
                                 </fieldset>
... ...
@@ -502,6 +502,7 @@ class WeinanlieferungSlotAssistantController extends AbstractController
502 502
                     'time' => $intTime,
503 503
                     'duration' => $intDuration/60,
504 504
                     'behaelter' => $SlotType->containers,
505
+                    'overcapacity' => $SlotType->overcapacity,
505 506
                     'anmerkungen' => Input::post('annotation'),
506 507
                     'buchbar_ab' => (int) $intTime-intval(Input::post('bookableFrom'))*3600,
507 508
                     'buchbar_bis' => (int) $intTime-intval(Input::post('bookableTill'))*3600,
... ...
@@ -135,6 +135,7 @@ class SlotAjaxController extends AbstractController
135 135
 
136 136
         // Build data
137 137
         $intAvailableBehaelter = max(0,$Slot->getAvailableBehaelter());
138
+        $intBookableBehaelter = $Slot->getAvailableBehaelter() + $Slot->getOvercapacityBehaelter();
138 139
         $arrUnits = [];
139 140
 
140 141
         if (($Site = $Slot->getRelated('pid')) !== null)
... ...
@@ -159,7 +160,7 @@ class SlotAjaxController extends AbstractController
159 160
             'standort' => $Slot->getRelated('pid'),
160 161
             'buchen' => [
161 162
                 'buchbar' => (boolean) $intAvailableBehaelter,
162
-                'behaelter' => range(min($intAvailableBehaelter,1),$intAvailableBehaelter),
163
+                'behaelter' => range(min($intBookableBehaelter,1),$intBookableBehaelter),
163 164
                 'units' => $arrUnits,
164 165
             ],
165 166
             'reservations' => $arrReservations
... ...
@@ -296,6 +297,7 @@ class SlotAjaxController extends AbstractController
296 297
         }
297 298
 
298 299
         $intAvailableBehaelter = max(0,$Slot->getAvailableBehaelter());
300
+        $intBookableBehaelter = $Slot->getAvailableBehaelter() + $Slot->getOvercapacityBehaelter();
299 301
         $arrUnits = [];
300 302
 
301 303
         if (($Site = $Slot->getRelated('pid')) !== null)
... ...
@@ -320,8 +322,8 @@ class SlotAjaxController extends AbstractController
320 322
             'buchung' => $Booking->row(),
321 323
             'standort' => $Slot->getRelated('pid'),
322 324
             'buchen' => [
323
-                'buchbar' => (boolean) $intAvailableBehaelter,
324
-                'behaelter' => range(min($intAvailableBehaelter,1),$intAvailableBehaelter+$Booking->behaelter),
325
+                'buchbar' => (boolean) $intBookableBehaelter,
326
+                'behaelter' => range(min($intBookableBehaelter,1),$intBookableBehaelter+$Booking->behaelter),
325 327
                 'units' => $arrUnits,
326 328
             ]
327 329
         ]);
... ...
@@ -373,9 +375,9 @@ class SlotAjaxController extends AbstractController
373 375
         // Form validation
374 376
         $intBehaelter = Input::post('behaelter');
375 377
 
376
-        if (Input::post('behaelter') > $Slot->getAvailableBehaelter())
378
+        if (Input::post('behaelter') > $Slot->getAvailableBehaelter(true))
377 379
         {
378
-            return $this->renderDetails(false,sprintf('<div class="toast toast--danger mx-0">Fehler: Es sind mittlerweile nur noch %s Bottiche verfügbar.</div>',$Slot->getAvailableBehaelter()));
380
+            return $this->renderDetails(false,sprintf('<div class="toast toast--danger mx-0">Fehler: Es sind mittlerweile nur noch %s Bottiche verfügbar.</div>',$Slot->getAvailableBehaelter(true)));
379 381
         }
380 382
 
381 383
         $arrError = [];
... ...
@@ -473,9 +475,9 @@ class SlotAjaxController extends AbstractController
473 475
         // Form validation
474 476
         $intBehaelter = Input::post('behaelter');
475 477
 
476
-        if (Input::post('behaelter') > $Slot->getAvailableBehaelter()+$Reservation->behaelter)
478
+        if (Input::post('behaelter') > $Slot->getAvailableBehaelter(true)+$Reservation->behaelter)
477 479
         {
478
-            return $this->renderBooking(false,sprintf('<div class="toast toast--danger mx-0">Fehler: Es sind mittlerweile nur noch %s Bottiche verfügbar.</div>',$Slot->getAvailableBehaelter()+$Reservation->behaelter));
480
+            return $this->renderBooking(false,sprintf('<div class="toast toast--danger mx-0">Fehler: Es sind mittlerweile nur noch %s Bottiche verfügbar.</div>',$Slot->getAvailableBehaelter(true)+$Reservation->behaelter));
479 481
         }
480 482
 
481 483
         $arrError = [];
... ...
@@ -68,11 +68,12 @@ class WeinanlieferungSlotContainerListener
68 68
             </div>
69 69
             <div class="col-3">
70 70
               <div class="t-label">Bottichkapazität</div>%s
71
+              <div class="t-label">Überkapazität</div>%s%% (%s Behälter)
71 72
             </div>
72 73
             <div class="col-3">
73 74
               <div class="t-label">Dauer</div>%s %s
74 75
             </div>
75
-        </div></div>', Date::parse(Date::getNumericDateFormat(), $row['date']), Date::parse(Date::getNumericTimeFormat(), $row['time']), Date::parse(Date::getNumericDatimFormat(), $row['buchbar_ab']), Date::parse(Date::getNumericDatimFormat(), $row['buchbar_bis']), $Slot->behaelter, $row['duration'], ($row['duration'] == 1 ? $this->translator->trans('MSC.wa_duration_minute', [], 'contao_tl_vr_wa_units') : $this->translator->trans('MSC.wa_duration_minutes', [], 'contao_tl_vr_wa_units')));
76
+        </div></div>', Date::parse(Date::getNumericDateFormat(), $row['date']), Date::parse(Date::getNumericTimeFormat(), $row['time']), Date::parse(Date::getNumericDatimFormat(), $row['buchbar_ab']), Date::parse(Date::getNumericDatimFormat(), $row['buchbar_bis']), $Slot->behaelter, $Slot->overcapacity, round($Slot->behaelter/100*$Slot->overcapacity), $row['duration'], ($row['duration'] == 1 ? $this->translator->trans('MSC.wa_duration_minute', [], 'contao_tl_vr_wa_units') : $this->translator->trans('MSC.wa_duration_minutes', [], 'contao_tl_vr_wa_units')));
76 77
     }
77 78
 
78 79
     /**
... ...
@@ -120,7 +120,7 @@ class WeinanlieferungSlotsModel extends Model
120 120
         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);
121 121
     }
122 122
 
123
-    public function getAvailableBehaelter(?int $intOffset=null)
123
+    public function getAvailableBehaelter(bool $inclOvercapacity = false, ?int $intOffset=null)
124 124
     {
125 125
         /** @var Connection $db */
126 126
         $db = Controller::getContainer()->get('database_connection');
... ...
@@ -129,6 +129,12 @@ class WeinanlieferungSlotsModel extends Model
129 129
             ->executeQuery([$this->id]);
130 130
 
131 131
         $intReserved = $ReservedBehaelter->fetchOne();
132
+        $intOvercapacity = 0;
133
+
134
+        if ($inclOvercapacity)
135
+        {
136
+            $intOvercapacity = $this->getOvercapacityBehaelter();
137
+        }
132 138
 
133 139
         if ($intReserved === null)
134 140
         {
... ...
@@ -140,6 +146,11 @@ class WeinanlieferungSlotsModel extends Model
140 146
             $intReserved += $intOffset;
141 147
         }
142 148
 
143
-        return (int) $this->behaelter - $intReserved;
149
+        return (int) $this->behaelter + $intOvercapacity - $intReserved;
150
+    }
151
+
152
+    public function getOvercapacityBehaelter()
153
+    {
154
+        return round($this->behaelter/100*$this->overcapacity);
144 155
     }
145 156
 }