| ... | ... |
@@ -218,8 +218,25 @@ $GLOBALS['TL_DCA']['tl_vr_wa_reservation'] = array |
| 218 | 218 |
'behaelter_numbers' => array |
| 219 | 219 |
( |
| 220 | 220 |
'exclude' => true, |
| 221 |
- 'inputType' => 'text', |
|
| 222 |
- 'eval' => array('tl_class'=>'clr', 'preserveTags'=>true),
|
|
| 221 |
+ 'inputType' => 'multiColumnWizard', |
|
| 222 |
+ 'eval' => array( |
|
| 223 |
+ 'tl_class' => 'clr', |
|
| 224 |
+ 'columnFields' => array |
|
| 225 |
+ ( |
|
| 226 |
+ 'behaelter' => array |
|
| 227 |
+ ( |
|
| 228 |
+ 'label' => &$GLOBALS['TL_LANG']['MSC']['wa_behaelter_number'], |
|
| 229 |
+ 'inputType' => 'text', |
|
| 230 |
+ 'eval' => array('style' => 'width:200px', 'mandatory' => true, 'rgxp' => 'natural')
|
|
| 231 |
+ ), |
|
| 232 |
+ 'member' => array |
|
| 233 |
+ ( |
|
| 234 |
+ 'label' => &$GLOBALS['TL_LANG']['MSC']['wa_member_number'], |
|
| 235 |
+ 'inputType' => 'text', |
|
| 236 |
+ 'eval' => array('style' => 'width:200px', 'rgxp' => 'natural')
|
|
| 237 |
+ ) |
|
| 238 |
+ ) |
|
| 239 |
+ ), |
|
| 223 | 240 |
'sql' => "text NULL" |
| 224 | 241 |
), |
| 225 | 242 |
) |
| ... | ... |
@@ -10,6 +10,8 @@ |
| 10 | 10 |
|
| 11 | 11 |
$GLOBALS['TL_LANG']['MSC']['wa_sorte'] = 'Rebsorte'; |
| 12 | 12 |
$GLOBALS['TL_LANG']['MSC']['wa_leseart'] = 'Leseart'; |
| 13 |
+$GLOBALS['TL_LANG']['MSC']['wa_behaelter_number'] = 'Behälternummer'; |
|
| 14 |
+$GLOBALS['TL_LANG']['MSC']['wa_member_number'] = 'Mitgliedsnummer'; |
|
| 13 | 15 |
$GLOBALS['TL_LANG']['MSC']['wa_approval_needed'] = 'erfordert Freigabe'; |
| 14 | 16 |
$GLOBALS['TL_LANG']['MSC']['wa_approval_pending'] = 'Freigabe ausstehend'; |
| 15 | 17 |
|
| ... | ... |
@@ -62,14 +62,25 @@ |
| 62 | 62 |
|
| 63 | 63 |
<div class="grid-md u-gap-2"> |
| 64 | 64 |
{% for i in 1..checkin.behaelter %}
|
| 65 |
- <div class="grid-c-6"> |
|
| 66 |
- <fieldset> |
|
| 67 |
- <label for="behaelter-number-{{ i }}"><strong>Behälter {{ i }}</strong><sup class="text-danger">*</sup></label>
|
|
| 68 |
- <select id="behaelter-number-{{ i }}" name="behaelter_numbers[]" required data-loaded="false">
|
|
| 69 |
- <option value="">-</option> |
|
| 70 |
- <!-- Options will be loaded via Ajax when the select is focused --> |
|
| 71 |
- </select> |
|
| 72 |
- </fieldset> |
|
| 65 |
+ <div class="grid-c-12"> |
|
| 66 |
+ <div class="grid-md u-gap-2"> |
|
| 67 |
+ <div class="grid-c-6"> |
|
| 68 |
+ <fieldset> |
|
| 69 |
+ <label for="behaelter-number-{{ i }}"><strong>Behälter {{ i }}</strong><sup class="text-danger">*</sup></label>
|
|
| 70 |
+ <select id="behaelter-number-{{ i }}" name="behaelter_numbers[]" required data-loaded="false">
|
|
| 71 |
+ <option value="">-</option> |
|
| 72 |
+ <!-- Options will be loaded via Ajax when the select is focused --> |
|
| 73 |
+ </select> |
|
| 74 |
+ </fieldset> |
|
| 75 |
+ </div> |
|
| 76 |
+ <div class="grid-c-6"> |
|
| 77 |
+ <fieldset> |
|
| 78 |
+ <label for="member-number-{{ i }}"><strong>Mitgliedsnummer</strong></label>
|
|
| 79 |
+ <input type="text" id="member-number-{{ i }}" name="member_numbers[]" value="{{ current_member.memberno|default('') }}" placeholder="Mitgliedsnummer">
|
|
| 80 |
+ <p class="text-sm text-muted">Leer lassen für aktuelle Mitgliedsnummer: {{ current_member.memberno|default('Keine') }}</p>
|
|
| 81 |
+ </fieldset> |
|
| 82 |
+ </div> |
|
| 83 |
+ </div> |
|
| 73 | 84 |
</div> |
| 74 | 85 |
{% endfor %}
|
| 75 | 86 |
</div> |
| ... | ... |
@@ -142,7 +142,9 @@ |
| 142 | 142 |
</div> |
| 143 | 143 |
<div class="col-10 behaelter_nummern"> |
| 144 | 144 |
<div class="t-label">Eingecheckte Behälternummern</div> |
| 145 |
- {{ booking.behaelter_numbers|join(', ') }}
|
|
| 145 |
+ {% for behaelter in booking.behaelter_numbers %}
|
|
| 146 |
+ {% if loop.index != 1 %}, {% endif %}{{ behaelter.behaelter }} [M:{{ behaelter.member }}]
|
|
| 147 |
+ {% endfor %}
|
|
| 146 | 148 |
</div> |
| 147 | 149 |
{% endif %}
|
| 148 | 150 |
<div class="col px-1 u-text-right action"> |
| ... | ... |
@@ -19,6 +19,7 @@ use Contao\Date; |
| 19 | 19 |
use Contao\Environment; |
| 20 | 20 |
use Contao\FrontendUser; |
| 21 | 21 |
use Contao\Input; |
| 22 |
+use Contao\MemberModel; |
|
| 22 | 23 |
use Contao\StringUtil; |
| 23 | 24 |
use Contao\System; |
| 24 | 25 |
use Doctrine\DBAL\Connection; |
| ... | ... |
@@ -273,6 +274,23 @@ class WeinanlieferungBookingsController extends AbstractController |
| 273 | 274 |
$strStandort = $Standort->title; |
| 274 | 275 |
} |
| 275 | 276 |
|
| 277 |
+ $behaelterNumbers = json_decode($booking->behaelter_numbers, true); |
|
| 278 |
+ $isNewFormat = isset($behaelterNumbers[0]) && is_array($behaelterNumbers[0]) && isset($behaelterNumbers[0]['behaelter']); |
|
| 279 |
+ |
|
| 280 |
+ // If it's the old format, convert it to the new format for compatibility |
|
| 281 |
+ if (!$isNewFormat) {
|
|
| 282 |
+ $oldFormat = $behaelterNumbers; |
|
| 283 |
+ $memberModel = MemberModel::findById($booking->uid); |
|
| 284 |
+ |
|
| 285 |
+ $behaelterNumbers = []; |
|
| 286 |
+ foreach ($oldFormat as $number) {
|
|
| 287 |
+ $behaelterNumbers[] = [ |
|
| 288 |
+ 'behaelter' => $number, |
|
| 289 |
+ 'member' => $memberModel->memberno |
|
| 290 |
+ ]; |
|
| 291 |
+ } |
|
| 292 |
+ } |
|
| 293 |
+ |
|
| 276 | 294 |
$arrData['days'][$day->dayBegin][$Slot->pid]['times'][$Slot->time]['items'][] = array_merge($booking->row(), [ |
| 277 | 295 |
'sorte' => $arrSorten, |
| 278 | 296 |
'ernteart' => $arrErnteart, |
| ... | ... |
@@ -280,7 +298,7 @@ class WeinanlieferungBookingsController extends AbstractController |
| 280 | 298 |
'slot' => $Slot->row(), |
| 281 | 299 |
'standort' => $strStandort, |
| 282 | 300 |
'member' => $booking->getRelated('uid') !== null ? $booking->getRelated('uid')->row() : null,
|
| 283 |
- 'behaelter_numbers' => \json_decode($booking->behaelter_numbers) |
|
| 301 |
+ 'behaelter_numbers' => $behaelterNumbers |
|
| 284 | 302 |
]); |
| 285 | 303 |
} |
| 286 | 304 |
} |
| ... | ... |
@@ -24,6 +24,7 @@ use Contao\FormFileUpload; |
| 24 | 24 |
use Contao\Frontend; |
| 25 | 25 |
use Contao\FrontendUser; |
| 26 | 26 |
use Contao\Input; |
| 27 |
+use Contao\MemberModel; |
|
| 27 | 28 |
use Contao\StringUtil; |
| 28 | 29 |
use Contao\System; |
| 29 | 30 |
use Doctrine\DBAL\Connection; |
| ... | ... |
@@ -746,6 +747,10 @@ class SlotAjaxController extends AbstractController |
| 746 | 747 |
} |
| 747 | 748 |
} |
| 748 | 749 |
|
| 750 |
+ // Load the member model for the booking's user |
|
| 751 |
+ $memberModel = MemberModel::findById($Booking->uid); |
|
| 752 |
+ $currentMemberModel = MemberModel::findById(FrontendUser::getInstance()->id); |
|
| 753 |
+ |
|
| 749 | 754 |
$arrData = array_merge($arrData, [ |
| 750 | 755 |
'modal' => $blnModal, |
| 751 | 756 |
'id' => $Booking->id, |
| ... | ... |
@@ -760,7 +765,9 @@ class SlotAjaxController extends AbstractController |
| 760 | 765 |
'standort' => $Standort, |
| 761 | 766 |
'checkin' => [ |
| 762 | 767 |
'behaelter' => $Booking->behaelter, |
| 763 |
- ] |
|
| 768 |
+ ], |
|
| 769 |
+ 'member' => $memberModel ? $memberModel->row() : null, |
|
| 770 |
+ 'current_member' => $currentMemberModel ? $currentMemberModel->row() : null |
|
| 764 | 771 |
]); |
| 765 | 772 |
|
| 766 | 773 |
if (!empty($error)) |
| ... | ... |
@@ -791,6 +798,19 @@ class SlotAjaxController extends AbstractController |
| 791 | 798 |
return $this->renderCheckin(false, '<div class="toast toast--danger mx-0">Bitte wählen Sie für jeden Behälter eine Nummer aus.</div>'); |
| 792 | 799 |
} |
| 793 | 800 |
|
| 801 |
+ // Get member numbers from the form |
|
| 802 |
+ $memberNumbers = Input::post('member_numbers');
|
|
| 803 |
+ |
|
| 804 |
+ // If member numbers are not provided or not an array, initialize an empty array |
|
| 805 |
+ if (!is_array($memberNumbers) || count($memberNumbers) != $Booking->behaelter) |
|
| 806 |
+ {
|
|
| 807 |
+ $memberNumbers = array_fill(0, count($behaelterNumbers), ''); |
|
| 808 |
+ } |
|
| 809 |
+ |
|
| 810 |
+ // Get the current member's number to use as fallback |
|
| 811 |
+ $currentMember = MemberModel::findById(FrontendUser::getInstance()->id); |
|
| 812 |
+ $currentMemberNo = $currentMember ? $currentMember->memberno : ''; |
|
| 813 |
+ |
|
| 794 | 814 |
// Filter out the special value 9999 ("Nummer nicht bekannt") for duplicate check
|
| 795 | 815 |
$numbersForDuplicateCheck = array_filter($behaelterNumbers, function($number) {
|
| 796 | 816 |
return $number !== '9999'; |
| ... | ... |
@@ -802,11 +822,21 @@ class SlotAjaxController extends AbstractController |
| 802 | 822 |
return $this->renderCheckin(false, '<div class="toast toast--danger mx-0">Jede Nummer kann nur einmal verwendet werden.</div>'); |
| 803 | 823 |
} |
| 804 | 824 |
|
| 825 |
+ // Create combined array with behaelter numbers and member numbers |
|
| 826 |
+ $combinedData = []; |
|
| 827 |
+ foreach ($behaelterNumbers as $index => $behaelterNumber) {
|
|
| 828 |
+ $memberNumber = !empty($memberNumbers[$index]) ? $memberNumbers[$index] : $currentMemberNo; |
|
| 829 |
+ $combinedData[] = [ |
|
| 830 |
+ 'behaelter' => $behaelterNumber, |
|
| 831 |
+ 'member' => $memberNumber |
|
| 832 |
+ ]; |
|
| 833 |
+ } |
|
| 834 |
+ |
|
| 805 | 835 |
// Save the check-in data |
| 806 | 836 |
$time = time(); |
| 807 | 837 |
$Booking->checked_in = '1'; |
| 808 | 838 |
$Booking->checked_in_on = $time; |
| 809 |
- $Booking->behaelter_numbers = json_encode($behaelterNumbers); |
|
| 839 |
+ $Booking->behaelter_numbers = json_encode($combinedData); |
|
| 810 | 840 |
$Booking->tstamp = $time; |
| 811 | 841 |
$Booking->save(); |
| 812 | 842 |
|
| ... | ... |
@@ -115,6 +115,22 @@ class CheckInCompletedListener implements EventSubscriberInterface |
| 115 | 115 |
return; |
| 116 | 116 |
} |
| 117 | 117 |
|
| 118 |
+ // Check if we have the new format (array of objects with behaelter and member) |
|
| 119 |
+ // or the old format (simple array of behaelter numbers) |
|
| 120 |
+ $isNewFormat = isset($behaelterNumbers[0]) && is_array($behaelterNumbers[0]) && isset($behaelterNumbers[0]['behaelter']); |
|
| 121 |
+ |
|
| 122 |
+ // If it's the old format, convert it to the new format for compatibility |
|
| 123 |
+ if (!$isNewFormat) {
|
|
| 124 |
+ $oldFormat = $behaelterNumbers; |
|
| 125 |
+ $behaelterNumbers = []; |
|
| 126 |
+ foreach ($oldFormat as $number) {
|
|
| 127 |
+ $behaelterNumbers[] = [ |
|
| 128 |
+ 'behaelter' => $number, |
|
| 129 |
+ 'member' => $memberModel->memberno |
|
| 130 |
+ ]; |
|
| 131 |
+ } |
|
| 132 |
+ } |
|
| 133 |
+ |
|
| 118 | 134 |
// Format check-in date |
| 119 | 135 |
$checkInDate = date('d.m.Y', $reservationData['checked_in_on']);
|
| 120 | 136 |
|
| ... | ... |
@@ -166,16 +182,41 @@ class CheckInCompletedListener implements EventSubscriberInterface |
| 166 | 182 |
'vollernter' => 'V' |
| 167 | 183 |
]; |
| 168 | 184 |
|
| 169 |
- // Prepare CSV data |
|
| 170 |
- $csvData = []; |
|
| 185 |
+ // Group CSV data by member number |
|
| 186 |
+ $csvDataByMember = []; |
|
| 187 |
+ $memberNames = []; // Store member names for logging |
|
| 188 |
+ |
|
| 189 |
+ // For each behaelter, create a line in the CSV and group by member number |
|
| 190 |
+ foreach ($behaelterNumbers as $behaelterData) {
|
|
| 191 |
+ // Get behaelter number and member number from the data |
|
| 192 |
+ $behaelterNumber = $isNewFormat ? $behaelterData['behaelter'] : $behaelterData; |
|
| 193 |
+ $memberNo = $isNewFormat && isset($behaelterData['member']) ? $behaelterData['member'] : $memberModel->memberno; |
|
| 171 | 194 |
|
| 172 |
- // For each behaelter, create a line in the CSV |
|
| 173 |
- foreach ($behaelterNumbers as $behaelterNumber) {
|
|
| 174 | 195 |
// Skip special value 9999 if needed |
| 175 | 196 |
if ($behaelterNumber === '9999') {
|
| 176 | 197 |
continue; |
| 177 | 198 |
} |
| 178 | 199 |
|
| 200 |
+ // If member number is empty, use the booking member's number |
|
| 201 |
+ if (empty($memberNo)) {
|
|
| 202 |
+ $memberNo = $memberModel->memberno; |
|
| 203 |
+ } |
|
| 204 |
+ |
|
| 205 |
+ // Get member name - use the booking member's name as default |
|
| 206 |
+ $memberName = $memberModel->firstname . ' ' . $memberModel->lastname; |
|
| 207 |
+ |
|
| 208 |
+ // If the member number is different from the booking member's number, |
|
| 209 |
+ // try to find the corresponding member to get their name |
|
| 210 |
+ if ($memberNo !== $memberModel->memberno) {
|
|
| 211 |
+ $otherMember = MemberModel::findByMemberno($memberNo); |
|
| 212 |
+ if ($otherMember) {
|
|
| 213 |
+ $memberName = $otherMember->firstname . ' ' . $otherMember->lastname; |
|
| 214 |
+ } |
|
| 215 |
+ } |
|
| 216 |
+ |
|
| 217 |
+ // Store member name for logging |
|
| 218 |
+ $memberNames[$memberNo] = $memberName; |
|
| 219 |
+ |
|
| 179 | 220 |
// Use the first sorte, leseart, and lage if available |
| 180 | 221 |
$rebsorteId = !empty($sortenData) ? $sortenData[0]['rebsorte_id'] : ''; |
| 181 | 222 |
$rebsorteTitle = !empty($sortenData) ? $sortenData[0]['rebsorte_title'] : ''; |
| ... | ... |
@@ -193,10 +234,14 @@ class CheckInCompletedListener implements EventSubscriberInterface |
| 193 | 234 |
} |
| 194 | 235 |
} |
| 195 | 236 |
|
| 196 |
- // Create CSV line |
|
| 197 |
- $csvData[] = [ |
|
| 198 |
- $memberModel->memberno, // member id |
|
| 199 |
- $memberModel->firstname . ' ' . $memberModel->lastname, // member first and lastname |
|
| 237 |
+ // Create CSV line and add to the appropriate member group |
|
| 238 |
+ if (!isset($csvDataByMember[$memberNo])) {
|
|
| 239 |
+ $csvDataByMember[$memberNo] = []; |
|
| 240 |
+ } |
|
| 241 |
+ |
|
| 242 |
+ $csvDataByMember[$memberNo][] = [ |
|
| 243 |
+ $memberNo, // member id (now using the member number associated with this behaelter) |
|
| 244 |
+ $memberName, // member first and lastname |
|
| 200 | 245 |
$rebsorteId, // rebsorte identifikator |
| 201 | 246 |
$rebsorteTitle, // rebsorte title |
| 202 | 247 |
$lageId, // lage identifikator |
| ... | ... |
@@ -206,25 +251,47 @@ class CheckInCompletedListener implements EventSubscriberInterface |
| 206 | 251 |
$ernteart, // ernteart (H for handlese, V for vollernter) |
| 207 | 252 |
$behaelterNumber, // behaelter number |
| 208 | 253 |
$checkInDate, // check-in date |
| 209 |
- $reservationData['behaelter'] // behaelter amount for the whole checked-in booking |
|
| 254 |
+// $reservationData['behaelter'] // behaelter amount for the whole checked-in booking |
|
| 210 | 255 |
]; |
| 211 | 256 |
} |
| 212 | 257 |
|
| 213 |
- // Generate CSV file |
|
| 214 |
- $filename = $reservationData['id'] . '_' . $memberModel->memberno . '.csv'; |
|
| 215 |
- $filepath = $exportDir . '/' . $filename; |
|
| 258 |
+ // Generate a separate CSV file for each member |
|
| 259 |
+ $generatedFiles = []; |
|
| 260 |
+ foreach ($csvDataByMember as $memberNo => $csvData) {
|
|
| 261 |
+ // Generate CSV file with the naming scheme "bookingId_memberno.csv" |
|
| 262 |
+ $filename = $reservationData['id'] . '_' . $memberNo . '.csv'; |
|
| 263 |
+ $filepath = $exportDir . '/' . $filename; |
|
| 264 |
+ $generatedFiles[] = $filepath; |
|
| 216 | 265 |
|
| 217 |
- $file = fopen($filepath, 'w'); |
|
| 266 |
+ $file = fopen($filepath, 'w'); |
|
| 218 | 267 |
|
| 219 |
- foreach ($csvData as $line) {
|
|
| 220 |
- fputcsv($file, $line, ';'); |
|
| 221 |
- } |
|
| 268 |
+ foreach ($csvData as $line) {
|
|
| 269 |
+ $line[] = count($csvData); |
|
| 270 |
+ fputcsv($file, $line, ';'); |
|
| 271 |
+ } |
|
| 222 | 272 |
|
| 223 |
- fclose($file); |
|
| 273 |
+ fclose($file); |
|
| 274 |
+ |
|
| 275 |
+ $this->logger->log( |
|
| 276 |
+ LogLevel::INFO, |
|
| 277 |
+ sprintf('CSV export created for reservation ID: %s, member: %s (%s) at %s',
|
|
| 278 |
+ $reservationData['id'], |
|
| 279 |
+ $memberNo, |
|
| 280 |
+ $memberNames[$memberNo], |
|
| 281 |
+ $filepath |
|
| 282 |
+ ), |
|
| 283 |
+ ['contao' => new ContaoContext(__METHOD__, 'CHECK_IN_CSV_EXPORT')] |
|
| 284 |
+ ); |
|
| 285 |
+ } |
|
| 224 | 286 |
|
| 287 |
+ // Log summary of all generated files |
|
| 225 | 288 |
$this->logger->log( |
| 226 | 289 |
LogLevel::INFO, |
| 227 |
- sprintf('CSV export created for reservation ID: %s at %s', $reservationData['id'], $filepath),
|
|
| 290 |
+ sprintf('CSV export completed for reservation ID: %s. Generated %d file(s) for %d member(s).',
|
|
| 291 |
+ $reservationData['id'], |
|
| 292 |
+ count($generatedFiles), |
|
| 293 |
+ count($csvDataByMember) |
|
| 294 |
+ ), |
|
| 228 | 295 |
['contao' => new ContaoContext(__METHOD__, 'CHECK_IN_CSV_EXPORT')] |
| 229 | 296 |
); |
| 230 | 297 |
} |
| ... | ... |
@@ -175,7 +175,34 @@ class WeinanlieferungReservationContainerListener |
| 175 | 175 |
{
|
| 176 | 176 |
if (!empty($varValue)) |
| 177 | 177 |
{
|
| 178 |
- $varValue = implode(', ',\json_decode($varValue));
|
|
| 178 |
+ $decodedValue = \json_decode($varValue, true); |
|
| 179 |
+ |
|
| 180 |
+ // Check if we have the new format (array of objects with behaelter and member) |
|
| 181 |
+ // or the old format (simple array of behaelter numbers) |
|
| 182 |
+ $isNewFormat = isset($decodedValue[0]) && is_array($decodedValue[0]) && isset($decodedValue[0]['behaelter']); |
|
| 183 |
+ |
|
| 184 |
+ if ($isNewFormat) {
|
|
| 185 |
+ // The data is already in the correct format for the multiColumnWizard |
|
| 186 |
+ return $decodedValue; |
|
| 187 |
+ } else {
|
|
| 188 |
+ // Convert old format to new format |
|
| 189 |
+ $result = []; |
|
| 190 |
+ |
|
| 191 |
+ // Get the member associated with this reservation as fallback |
|
| 192 |
+ $reservation = \vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungReservationModel::findByPk($dc->id); |
|
| 193 |
+ $memberId = $reservation ? $reservation->uid : 0; |
|
| 194 |
+ $memberModel = \Contao\MemberModel::findById($memberId); |
|
| 195 |
+ $defaultMemberNo = $memberModel ? $memberModel->memberno : ''; |
|
| 196 |
+ |
|
| 197 |
+ foreach ($decodedValue as $behaelterNumber) {
|
|
| 198 |
+ $result[] = [ |
|
| 199 |
+ 'behaelter' => $behaelterNumber, |
|
| 200 |
+ 'member' => $defaultMemberNo |
|
| 201 |
+ ]; |
|
| 202 |
+ } |
|
| 203 |
+ |
|
| 204 |
+ return $result; |
|
| 205 |
+ } |
|
| 179 | 206 |
} |
| 180 | 207 |
return $varValue; |
| 181 | 208 |
} |
| ... | ... |
@@ -185,10 +212,9 @@ class WeinanlieferungReservationContainerListener |
| 185 | 212 |
*/ |
| 186 | 213 |
public function onBehaelterNumbersSaveCallback($varValue, DataContainer $dc) |
| 187 | 214 |
{
|
| 188 |
- if (!empty($varValue)) |
|
| 215 |
+ $varValue = StringUtil::deserialize($varValue, true); |
|
| 216 |
+ if (!empty($varValue) && is_array($varValue)) |
|
| 189 | 217 |
{
|
| 190 |
- $values = array_map('trim', explode(',', $varValue));
|
|
| 191 |
- |
|
| 192 | 218 |
// Get the reservation model |
| 193 | 219 |
$reservation = \vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungReservationModel::findByPk($dc->id); |
| 194 | 220 |
if ($reservation === null) {
|
| ... | ... |
@@ -204,15 +230,20 @@ class WeinanlieferungReservationContainerListener |
| 204 | 230 |
// Check if the booking is in the past |
| 205 | 231 |
$isInPast = $slot->time < time(); |
| 206 | 232 |
|
| 233 |
+ // Extract behaelter numbers from the multiColumnWizard data |
|
| 234 |
+ $behaelterNumbers = array_map(function($item) {
|
|
| 235 |
+ return $item['behaelter']; |
|
| 236 |
+ }, $varValue); |
|
| 237 |
+ |
|
| 207 | 238 |
// Only perform validation if the booking is not in the past |
| 208 | 239 |
if (!$isInPast) {
|
| 209 | 240 |
// Check if the number of container numbers matches the number of booked containers |
| 210 |
- if (count($values) != $reservation->behaelter) {
|
|
| 241 |
+ if (count($behaelterNumbers) != $reservation->behaelter) {
|
|
| 211 | 242 |
throw new \Exception('Die Anzahl der Behälternummern muss mit der Anzahl der gebuchten Behälter übereinstimmen.');
|
| 212 | 243 |
} |
| 213 | 244 |
|
| 214 | 245 |
// Filter out the special value 9999 ("Nummer nicht bekannt") for duplicate check
|
| 215 |
- $numbersForDuplicateCheck = array_filter($values, function($number) {
|
|
| 246 |
+ $numbersForDuplicateCheck = array_filter($behaelterNumbers, function($number) {
|
|
| 216 | 247 |
return $number !== '9999'; |
| 217 | 248 |
}); |
| 218 | 249 |
|
| ... | ... |
@@ -247,8 +278,20 @@ class WeinanlieferungReservationContainerListener |
| 247 | 278 |
while ($row = $result->fetchAssociative()) {
|
| 248 | 279 |
$numbers = json_decode($row['behaelter_numbers'], true); |
| 249 | 280 |
if (is_array($numbers)) {
|
| 250 |
- foreach ($numbers as $number) {
|
|
| 251 |
- $usedNumbers[] = $number; |
|
| 281 |
+ // Check if we have the new format (array of objects with behaelter and member) |
|
| 282 |
+ // or the old format (simple array of behaelter numbers) |
|
| 283 |
+ $isNewFormat = isset($numbers[0]) && is_array($numbers[0]) && isset($numbers[0]['behaelter']); |
|
| 284 |
+ |
|
| 285 |
+ if ($isNewFormat) {
|
|
| 286 |
+ // Extract just the behaelter numbers from the new format |
|
| 287 |
+ foreach ($numbers as $item) {
|
|
| 288 |
+ $usedNumbers[] = $item['behaelter']; |
|
| 289 |
+ } |
|
| 290 |
+ } else {
|
|
| 291 |
+ // Old format - simple array of behaelter numbers |
|
| 292 |
+ foreach ($numbers as $number) {
|
|
| 293 |
+ $usedNumbers[] = $number; |
|
| 294 |
+ } |
|
| 252 | 295 |
} |
| 253 | 296 |
} |
| 254 | 297 |
} |
| ... | ... |
@@ -267,7 +310,27 @@ class WeinanlieferungReservationContainerListener |
| 267 | 310 |
} |
| 268 | 311 |
} |
| 269 | 312 |
|
| 270 |
- $varValue = json_encode($values); |
|
| 313 |
+ // Get the member associated with this reservation as fallback |
|
| 314 |
+ $memberId = $reservation->uid; |
|
| 315 |
+ $memberModel = \Contao\MemberModel::findById($memberId); |
|
| 316 |
+ $defaultMemberNo = $memberModel ? $memberModel->memberno : ''; |
|
| 317 |
+ |
|
| 318 |
+ // Process the data from the multiColumnWizard |
|
| 319 |
+ $processedData = []; |
|
| 320 |
+ foreach ($varValue as $item) {
|
|
| 321 |
+ $behaelterNumber = $item['behaelter']; |
|
| 322 |
+ |
|
| 323 |
+ // If member number is empty, use the default member number |
|
| 324 |
+ $memberNumber = !empty($item['member']) ? $item['member'] : $defaultMemberNo; |
|
| 325 |
+ |
|
| 326 |
+ $processedData[] = [ |
|
| 327 |
+ 'behaelter' => $behaelterNumber, |
|
| 328 |
+ 'member' => $memberNumber |
|
| 329 |
+ ]; |
|
| 330 |
+ } |
|
| 331 |
+ |
|
| 332 |
+ // Return the processed data as JSON |
|
| 333 |
+ return json_encode($processedData); |
|
| 271 | 334 |
} |
| 272 | 335 |
return $varValue; |
| 273 | 336 |
} |