# Behaelter and Member Number Widget This document describes the implementation of a widget for editing both behaelter (container) numbers and their corresponding member numbers in the backend. ## Overview The implementation allows backend users to: - Edit both behaelter numbers and their corresponding member numbers in a paired interface - See which member number is associated with each behaelter - Change the member number for individual behaelters - Leave the member number field empty to use the booking member's number as a fallback ## Implementation Details ### 1. Widget Configuration The behaelter_numbers field in `tl_vr_wa_reservation.php` has been updated to use the multiColumnWizard input type with two columns: - **Behälternummer**: A text input for the behaelter number with validation for natural numbers - **Mitgliedsnummer**: A text input for the member number with validation for natural numbers ```php 'behaelter_numbers' => array ( 'exclude' => true, 'inputType' => 'multiColumnWizard', 'eval' => array( 'tl_class' => 'clr', 'columnFields' => array ( 'behaelter' => array ( 'label' => $GLOBALS['TL_LANG']['MSC']['wa_behaelter_number'], 'inputType' => 'text', 'eval' => array('style' => 'width:200px', 'mandatory' => true, 'rgxp' => 'natural') ), 'member' => array ( 'label' => $GLOBALS['TL_LANG']['MSC']['wa_member_number'], 'inputType' => 'text', 'eval' => array('style' => 'width:200px', 'rgxp' => 'natural') ) ) ), 'sql' => "text NULL" ), ``` ### 2. Callback Modifications #### Load Callback The `onBehaelterNumbersLoadCallback` method has been updated to: - Handle the new data format (array of objects with behaelter and member) - Convert old format data (simple array of behaelter numbers) to the new format - Return the data in the format expected by the multiColumnWizard ```php public function onBehaelterNumbersLoadCallback($varValue, DataContainer $dc) { if (!empty($varValue)) { $decodedValue = \json_decode($varValue, true); // Check if we have the new format (array of objects with behaelter and member) // or the old format (simple array of behaelter numbers) $isNewFormat = isset($decodedValue[0]) && is_array($decodedValue[0]) && isset($decodedValue[0]['behaelter']); if ($isNewFormat) { // The data is already in the correct format for the multiColumnWizard return $decodedValue; } else { // Convert old format to new format $result = []; // Get the member associated with this reservation as fallback $reservation = \vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungReservationModel::findByPk($dc->id); $memberId = $reservation ? $reservation->uid : 0; $memberModel = \Contao\MemberModel::findById($memberId); $defaultMemberNo = $memberModel ? $memberModel->memberno : ''; foreach ($decodedValue as $behaelterNumber) { $result[] = [ 'behaelter' => $behaelterNumber, 'member' => $defaultMemberNo ]; } return $result; } } return $varValue; } ``` #### Save Callback The `onBehaelterNumbersSaveCallback` method has been updated to: - Handle the data format from the multiColumnWizard (array of rows with behaelter and member) - Validate the behaelter numbers - Process the member numbers, using the default member number as a fallback if a member number is empty - Return the processed data as JSON ```php public function onBehaelterNumbersSaveCallback($varValue, DataContainer $dc) { if (!empty($varValue) && is_array($varValue)) { // ... validation code ... // Get the member associated with this reservation as fallback $memberId = $reservation->uid; $memberModel = \Contao\MemberModel::findById($memberId); $defaultMemberNo = $memberModel ? $memberModel->memberno : ''; // Process the data from the multiColumnWizard $processedData = []; foreach ($varValue as $item) { $behaelterNumber = $item['behaelter']; // If member number is empty, use the default member number $memberNumber = !empty($item['member']) ? $item['member'] : $defaultMemberNo; $processedData[] = [ 'behaelter' => $behaelterNumber, 'member' => $memberNumber ]; } // Return the processed data as JSON return json_encode($processedData); } return $varValue; } ``` ### 3. Language Labels Language labels have been added to the default.php language file for the column headers: ```php $GLOBALS['TL_LANG']['MSC']['wa_behaelter_number'] = 'Behälternummer'; $GLOBALS['TL_LANG']['MSC']['wa_member_number'] = 'Mitgliedsnummer'; ``` ## Data Structure The behaelter_numbers field stores a JSON-encoded array of objects, each with: - `behaelter`: The behaelter number - `member`: The associated member number Example: ```json [ { "behaelter": "123", "member": "456" }, { "behaelter": "789", "member": "456" } ] ``` ## Backward Compatibility The implementation maintains backward compatibility with existing data: - If the behaelter_numbers field contains the old format (simple array of behaelter numbers), it's automatically converted to the new format - For old data, all behaelters are associated with the booking member's number - The existing CSV export functionality continues to work with both old and new data formats ## Usage To use the widget: 1. Edit a reservation in the backend 2. Scroll to the "Check-in" section 3. Enter behaelter numbers and optionally member numbers for each behaelter 4. If a member number is left empty, the booking member's number will be used as a fallback 5. Save the reservation ## Integration with Existing Features This widget integrates with the existing features: - The CSV export functionality uses the member numbers associated with each behaelter - The backend booking list displays the behaelter numbers with their associated member numbers - The check-in process in the frontend continues to work with the new data structure