... |
... |
@@ -69,9 +69,11 @@ class WeinanlieferungSlotsListModuleController extends AbstractFrontendModuleCon
|
69 |
69 |
|
70 |
70 |
// Support unit-prefixed values like "u1-16" (unit-specific) and legacy "u-16". Both resolve to numeric capacity 16 for SQL.
|
71 |
71 |
$filterNumeric = null;
|
72 |
|
- if (preg_match('/^u\d+-(\d+)$/', $filterRaw, $m)) {
|
|
72 |
+ $filterUnitId = null;
|
|
73 |
+ if (preg_match('/^u(\d+)-(\d+)$/', $filterRaw, $m)) {
|
73 |
74 |
// New format: u<unitId>-<capacity>
|
74 |
|
- $filterNumeric = (int) $m[1];
|
|
75 |
+ $filterUnitId = (int) $m[1];
|
|
76 |
+ $filterNumeric = (int) $m[2];
|
75 |
77 |
} elseif (preg_match('/^u-(\d+)$/', $filterRaw, $m)) {
|
76 |
78 |
// Legacy format kept for backward compatibility: u-<capacity>
|
77 |
79 |
$filterNumeric = (int) $m[1];
|
... |
... |
@@ -79,8 +81,16 @@ class WeinanlieferungSlotsListModuleController extends AbstractFrontendModuleCon
|
79 |
81 |
$filterNumeric = (int) $filterRaw;
|
80 |
82 |
}
|
81 |
83 |
|
|
84 |
+ // Capacity availability condition
|
82 |
85 |
$arrOptions['column'][] = '(SELECT tl_vr_wa_slot.behaelter - IFNULL(SUM(tl_vr_wa_reservation.behaelter),0) FROM tl_vr_wa_reservation WHERE tl_vr_wa_reservation.pid = tl_vr_wa_slot.id) >= ?';
|
83 |
86 |
$arrOptions['value'][] = $filterNumeric;
|
|
87 |
+
|
|
88 |
+ // If a specific unit was selected (new format), restrict slots to Standorte that have this unit enabled
|
|
89 |
+ if ($filterUnitId !== null) {
|
|
90 |
+ // units is a serialized array, match serialized occurrence of the unit id
|
|
91 |
+ $arrOptions['column'][] = 'pid IN (SELECT id FROM tl_vr_wa_standort WHERE units REGEXP ?)';
|
|
92 |
+ $arrOptions['value'][] = 's:[0-9]+:"' . $filterUnitId . '"';
|
|
93 |
+ }
|
84 |
94 |
}
|
85 |
95 |
if (!empty($_GET['filter_standort']))
|
86 |
96 |
{
|
... |
... |
@@ -209,10 +219,49 @@ class WeinanlieferungSlotsListModuleController extends AbstractFrontendModuleCon
|
209 |
219 |
}
|
210 |
220 |
}
|
211 |
221 |
|
212 |
|
- // Append unit options at the bottom, without exceeding max capacity and only for allowed units
|
|
222 |
+ // Build a map of units enabled per shown Standort and compute per-unit max available capacity across shown slots
|
|
223 |
+ $unitsPerStandort = [];
|
|
224 |
+ $unitMaxAvailable = [];
|
|
225 |
+ if (!empty($shownStandortIds)) {
|
|
226 |
+ if (($ShownStandorte = WeinanlieferungStandortModel::findBy(["id IN (" . implode(',', $shownStandortIds) . ")"], null)) !== null) {
|
|
227 |
+ foreach ($ShownStandorte as $ShownStandort) {
|
|
228 |
+ $sid = (int) $ShownStandort->id;
|
|
229 |
+ $ids = \Contao\StringUtil::deserialize($ShownStandort->units, true);
|
|
230 |
+ if (!empty($ids)) {
|
|
231 |
+ foreach ($ids as $uid) {
|
|
232 |
+ $uid = (int) $uid;
|
|
233 |
+ $unitsPerStandort[$sid][$uid] = true;
|
|
234 |
+ // initialize unit max availability bucket
|
|
235 |
+ if (!isset($unitMaxAvailable[$uid])) {
|
|
236 |
+ $unitMaxAvailable[$uid] = 0;
|
|
237 |
+ }
|
|
238 |
+ }
|
|
239 |
+ }
|
|
240 |
+ }
|
|
241 |
+ }
|
|
242 |
+ }
|
|
243 |
+
|
|
244 |
+ // Iterate the shown slots and, for each, update max available for the units enabled at that slot's Standort
|
|
245 |
+ if (!empty($unitsPerStandort) && !empty($slotIds)) {
|
|
246 |
+ foreach ($slots as $slot) {
|
|
247 |
+ $sid = (int) $slot->pid;
|
|
248 |
+ if (empty($unitsPerStandort[$sid])) {
|
|
249 |
+ continue;
|
|
250 |
+ }
|
|
251 |
+ $available = max(0, (int) $slot->getAvailableBehaelter());
|
|
252 |
+ foreach ($unitsPerStandort[$sid] as $uid => $_true) {
|
|
253 |
+ if ($available > ($unitMaxAvailable[$uid] ?? 0)) {
|
|
254 |
+ $unitMaxAvailable[$uid] = $available;
|
|
255 |
+ }
|
|
256 |
+ }
|
|
257 |
+ }
|
|
258 |
+ }
|
|
259 |
+
|
|
260 |
+ // Append unit options at the bottom, without exceeding per-unit max availability and only for allowed units
|
213 |
261 |
if (!empty($allowedUnitIds) && ($Units = WeinanlieferungUnitsModel::findAll()) !== null) {
|
214 |
262 |
foreach ($Units as $unit) {
|
215 |
|
- if (empty($allowedUnitIds[(int)$unit->id])) {
|
|
263 |
+ $unitId = (int) $unit->id;
|
|
264 |
+ if (empty($allowedUnitIds[$unitId])) {
|
216 |
265 |
continue; // this unit is not enabled on any shown standort
|
217 |
266 |
}
|
218 |
267 |
|
... |
... |
@@ -222,14 +271,18 @@ class WeinanlieferungSlotsListModuleController extends AbstractFrontendModuleCon
|
222 |
271 |
}
|
223 |
272 |
|
224 |
273 |
$unitName = $unit->description ?: $unit->title; // visible unit name
|
225 |
|
- $multiplierMax = intdiv($max, $unitContainers);
|
|
274 |
+ $unitCap = (int) ($unitMaxAvailable[$unitId] ?? 0);
|
|
275 |
+ $multiplierMax = intdiv($unitCap, $unitContainers);
|
|
276 |
+ if ($multiplierMax <= 0) {
|
|
277 |
+ continue; // nothing available for this unit across shown slots
|
|
278 |
+ }
|
226 |
279 |
|
227 |
280 |
for ($m = 1; $m <= $multiplierMax; $m++) {
|
228 |
281 |
$value = (string) ($m * $unitContainers);
|
229 |
282 |
$label = $m . ' ' . $unitName;
|
230 |
283 |
|
231 |
284 |
$options[] = [
|
232 |
|
- 'value' => 'u' . $unit->id . '-' . $value,
|
|
285 |
+ 'value' => 'u' . $unitId . '-' . $value,
|
233 |
286 |
'label' => $label,
|
234 |
287 |
];
|
235 |
288 |
}
|