Browse code

Complete Check-In notifications

Benjamin Roth authored on08/08/2025 16:02:36
Showing7 changed files
... ...
@@ -170,3 +170,90 @@ $GLOBALS['NOTIFICATION_CENTER']['NOTIFICATION_TYPE']['weinanlieferung']['wa_slot
170 170
         'slot_ncsent',
171 171
     )
172 172
 );
173
+
174
+$GLOBALS['NOTIFICATION_CENTER']['NOTIFICATION_TYPE']['weinanlieferung']['wa_booking_checkin'] = array
175
+(
176
+    'recipients'    => array
177
+    (
178
+        'member_email', // The email address of the recipient
179
+        'admin_email' // The email address of the recipient
180
+    ),
181
+    'email_sender_address'    => array
182
+    (
183
+        'member_email', // The email address of the recipient
184
+        'admin_email' // The email address of the recipient
185
+    ),
186
+    'email_sender_name'    => array
187
+    (
188
+        'member_email', // The email address of the recipient
189
+        'admin_email' // The email address of the recipient
190
+    ),
191
+    'email_subject'        => array
192
+    (
193
+        'domain',
194
+        'member_email',
195
+        'admin_email',
196
+        'slot_date',
197
+        'slot_time',
198
+        'slot_standort',
199
+        'booking_ncsent',
200
+        'booking_approved',
201
+        'booking_approved_on',
202
+        'booking_checked_in',
203
+        'booking_checked_in_on',
204
+        'booking_checked_in_ncsent',
205
+        'booking_checkin_incomplete',
206
+    ),
207
+    'email_text'    => array
208
+    (
209
+        'member_firstname', // The firstname of the recipient
210
+        'member_lastname', // The lastname of the recipient
211
+        'member_memberno', // The member account number of the recipient
212
+        'slot_date',
213
+        'slot_time',
214
+        'slot_standort',
215
+        'slot_behaelter',
216
+        'slot_sorten',
217
+        'slot_ernteart',
218
+        'slot_lage',
219
+        'slot_anmerkungen',
220
+        'booking_ncsent',
221
+        'booking_behaelter',
222
+        'booking_sorten',
223
+        'booking_ernteart',
224
+        'booking_lage',
225
+        'booking_approved',
226
+        'booking_approved_on',
227
+        'booking_checked_in',
228
+        'booking_checked_in_on',
229
+        'booking_checked_in_ncsent',
230
+        'booking_checkin_incomplete',
231
+        'booking_behaelter_numbers',
232
+    ),
233
+    'email_html'    => array
234
+    (
235
+        'member_firstname', // The firstname of the recipient
236
+        'member_lastname', // The lastname of the recipient
237
+        'member_memberno', // The member account number of the recipient
238
+        'slot_date',
239
+        'slot_time',
240
+        'slot_standort',
241
+        'slot_behaelter',
242
+        'slot_sorten',
243
+        'slot_ernteart',
244
+        'slot_lage',
245
+        'slot_anmerkungen',
246
+        'booking_ncsent',
247
+        'booking_behaelter',
248
+        'booking_sorten',
249
+        'booking_ernteart',
250
+        'booking_lage',
251
+        'booking_approved',
252
+        'booking_approved_on',
253
+        'booking_checked_in',
254
+        'booking_checked_in_on',
255
+        'booking_checked_in_ncsent',
256
+        'booking_checkin_incomplete',
257
+        'booking_behaelter_numbers',
258
+    )
259
+);
... ...
@@ -96,13 +96,14 @@ $GLOBALS['TL_DCA']['tl_vr_wa_reservation'] = array
96 96
     // Palettes
97 97
     'palettes' => array
98 98
     (
99
-        '__selector__' => array(),
100
-        'default' => 'pid,uid,behaelter,sorten,lage,ernteart,upload;{approval_legend},approved;{checkin_legend},checked_in,behaelter_numbers'
99
+        '__selector__' => array('checked_in'),
100
+        'default' => 'pid,uid,behaelter,sorten,lage,ernteart,upload;{approval_legend},approved;{checkin_legend},checked_in'
101 101
     ),
102 102
 
103 103
     // Subpalettes
104 104
     'subpalettes' => array
105 105
     (
106
+        'checked_in' => 'behaelter_numbers'
106 107
     ),
107 108
 
108 109
     // Fields
... ...
@@ -205,7 +206,7 @@ $GLOBALS['TL_DCA']['tl_vr_wa_reservation'] = array
205 206
         (
206 207
             'exclude'                 => true,
207 208
             'inputType'               => 'checkbox',
208
-            'eval'                    => array('tl_class'=>'w50 m12'),
209
+            'eval'                    => array('tl_class'=>'w50 m12', 'submitOnChange'=>true),
209 210
             'sql'                     => "char(1) NOT NULL default ''"
210 211
         ),
211 212
         'checked_in_on' => array
... ...
@@ -111,7 +111,7 @@ $GLOBALS['TL_DCA']['tl_vr_wa_standort'] = array
111 111
     // Subpalettes
112 112
     'subpalettes' => array
113 113
     (
114
-        'nc_enable' => 'nc_notification,nc_notification_slots,nc_notification_groups'
114
+        'nc_enable' => 'nc_notification,nc_notification_checkin,nc_notification_slots,nc_notification_groups'
115 115
     ),
116 116
 
117 117
     // Fields
... ...
@@ -159,6 +159,13 @@ $GLOBALS['TL_DCA']['tl_vr_wa_standort'] = array
159 159
             'eval'                      => array('mandatory'=>false,'includeBlankOption'=>true, 'chosen'=>true, 'tl_class'=>'w50'),
160 160
             'sql'                       => "int(10) unsigned NOT NULL default '0'"
161 161
         ),
162
+        'nc_notification_checkin' => array
163
+        (
164
+            'exclude'                   => true,
165
+            'inputType'                 => 'select',
166
+            'eval'                      => array('mandatory'=>false,'includeBlankOption'=>true, 'chosen'=>true, 'tl_class'=>'w50'),
167
+            'sql'                       => "int(10) unsigned NOT NULL default '0'"
168
+        ),
162 169
         'nc_notification_groups' => array
163 170
         (
164 171
             'exclude'                 => true,
... ...
@@ -13,3 +13,5 @@ $GLOBALS['TL_LANG']['tl_nc_notification']['type']['wa_booking_change'][0] = 'Neu
13 13
 $GLOBALS['TL_LANG']['tl_nc_notification']['type']['wa_booking_change'][1] = 'Wenn eine neue Buchung eingeht, oder eine vorhandene Buchung geändert wird.';
14 14
 $GLOBALS['TL_LANG']['tl_nc_notification']['type']['wa_slot_change'][0] = 'Neuer buchbarer Slot / Slot-Aktualisierung';
15 15
 $GLOBALS['TL_LANG']['tl_nc_notification']['type']['wa_slot_change'][1] = 'Wenn eine neuer buchbarer Slot zur Verfügung steht, oder ein vorhandener Slot geändert wird.';
16
+$GLOBALS['TL_LANG']['tl_nc_notification']['type']['wa_booking_checkin'][0] = 'Check-In erfolgt';
17
+$GLOBALS['TL_LANG']['tl_nc_notification']['type']['wa_booking_checkin'][1] = 'Wenn der Check-In einer Buchung erfolgreich durchgeführt wurde.';
... ...
@@ -16,6 +16,8 @@ $GLOBALS['TL_LANG']['tl_vr_wa_standort']['nc_notification'][0] = 'Benachrichtigu
16 16
 $GLOBALS['TL_LANG']['tl_vr_wa_standort']['nc_notification'][1] = 'Die zu versendende Benachrichtigung.';
17 17
 $GLOBALS['TL_LANG']['tl_vr_wa_standort']['nc_notification_slots'][0] = 'Benachrichtigung für Slots';
18 18
 $GLOBALS['TL_LANG']['tl_vr_wa_standort']['nc_notification_slots'][1] = 'Die zu versendende Benachrichtigung für Slot-Änderungen.';
19
+$GLOBALS['TL_LANG']['tl_vr_wa_standort']['nc_notification_checkin'][0] = 'Benachrichtigung nach Check-In';
20
+$GLOBALS['TL_LANG']['tl_vr_wa_standort']['nc_notification_checkin'][1] = 'Die zu versendende Benachrichtigung nach Check-In.';
19 21
 $GLOBALS['TL_LANG']['tl_vr_wa_standort']['nc_notification_groups'][0] = 'Mitgliedergruppen';
20 22
 $GLOBALS['TL_LANG']['tl_vr_wa_standort']['nc_notification_groups'][1] = 'Die Mitgliedergruppen, die benachrichtigt werden sollen.';
21 23
 $GLOBALS['TL_LANG']['tl_vr_wa_standort']['number_ranges'][0] = 'Büttennummern';
... ...
@@ -63,7 +63,7 @@ class SendCheckInNotificationJob
63 63
                 // The key difference from SendBookingChangeNotificationJob is the WHERE clause:
64 64
                 // We look for r.checked_in = '1' AND r.checked_in_on > r.checked_in_nc_sent
65 65
                 $Bookings = $this->db->executeQuery(
66
-                    "SELECT r.id, r.pid, r.uid, r.behaelter, r.sorten, r.lage, r.ernteart, r.upload, r.checked_in_nc_sent,
66
+                    "SELECT r.id, r.pid, r.uid, r.behaelter, r.sorten, r.lage, r.ernteart, r.upload, r.nc_sent, r.checked_in_nc_sent,
67 67
                     s.date as slot_date, s.time as slot_time, s.behaelter as slot_behaelter,
68 68
                     s.sorten as slot_sorten, s.ernteart as slot_ernteart, s.lage as slot_lage,
69 69
                     s.anmerkungen as slot_anmerkungen, r.approved, r.approved_on, r.checked_in,
... ...
@@ -75,7 +75,7 @@ class SendCheckInNotificationJob
75 75
                 );
76 76
 
77 77
                 // Load notification model if we have check-ins to notify
78
-                if ($Bookings->rowCount() && ($Notification = Notification::findByPk($Location->nc_notification)) !== null) {
78
+                if ($Bookings->rowCount() && ($Notification = Notification::findByPk($Location->nc_notification_checkin)) !== null) {
79 79
                     foreach ($Bookings->iterateAssociative() as $Booking) {
80 80
                         // Get member
81 81
                         $Member = MemberModel::findOneBy(
... ...
@@ -162,6 +162,33 @@ class SendCheckInNotificationJob
162 162
                                 }
163 163
                             }
164 164
 
165
+                            // Behaelter numbers handling
166
+                            $blnIsIncomplete = false;
167
+                            $arrBehaelterNumbers = [];
168
+
169
+                            $behaelterNumbers = json_decode($Booking['behaelter_numbers'] ?? '[]', true);
170
+                            $isNewFormat = isset($behaelterNumbers[0]) && is_array($behaelterNumbers[0]) && isset($behaelterNumbers[0]['behaelter']);
171
+
172
+                            // If it's the old format, convert it to the new format for compatibility
173
+                            if (!$isNewFormat) {
174
+                                $oldFormat = $behaelterNumbers;
175
+                                $memberModel = MemberModel::findById($Booking['uid']);
176
+
177
+                                $behaelterNumbers = [];
178
+                                foreach ($oldFormat as $number) {
179
+                                    $behaelterNumbers[] = [
180
+                                        'behaelter' => $number,
181
+                                        'member' => $memberModel->memberno
182
+                                    ];
183
+                                }
184
+                            }
185
+                            foreach ($behaelterNumbers as $behaelterNumber) {
186
+                                if ($behaelterNumber['behaelter'] === '9999') {
187
+                                    $blnIsIncomplete = true;
188
+                                }
189
+                                $arrBehaelterNumbers[] = $behaelterNumber['behaelter'] . ' [Mitglied: ' . $behaelterNumber['member'] . ']';
190
+                            }
191
+
165 192
                             // Send notification with all booking data
166 193
                             // We include the check-in specific fields: checked_in, checked_in_on, behaelter_numbers
167 194
                             $Notification->send(
... ...
@@ -178,7 +205,7 @@ class SendCheckInNotificationJob
178 205
                                     'slot_ernteart'      => implode(', ', $arrErnteartAvailable),
179 206
                                     'slot_lage'          => implode(', ', $arrLageAvailable),
180 207
                                     'slot_anmerkungen'   => $Booking['slot_anmerkungen'],
181
-                                    'booking_checked_in_ncsent'     => $Booking['checked_in_nc_sent'],
208
+                                    'booking_ncsent'     => $Booking['nc_sent'],
182 209
                                     'booking_behaelter'  => $Booking['behaelter'],
183 210
                                     'booking_sorten'     => implode(', ', $arrSortenBooked),
184 211
                                     'booking_ernteart'   => implode(', ', $arrErnteartBooked),
... ...
@@ -187,7 +214,9 @@ class SendCheckInNotificationJob
187 214
                                     'booking_approved_on'=> $Booking['approved_on'],
188 215
                                     'booking_checked_in' => $Booking['checked_in'],
189 216
                                     'booking_checked_in_on' => $Booking['checked_in_on'],
190
-                                    'booking_behaelter_numbers' => $Booking['behaelter_numbers'],
217
+                                    'booking_checked_in_ncsent'     => $Booking['checked_in_nc_sent'],
218
+                                    'booking_checkin_incomplete'     => $blnIsIncomplete,
219
+                                    'booking_behaelter_numbers' => \implode(', ', $arrBehaelterNumbers),
191 220
                                     'admin_email'        => $admin_email,
192 221
                                 ],
193 222
                                 $GLOBALS['TL_LANGUAGE']
... ...
@@ -70,6 +70,27 @@ class WeinanlieferungStandortContainerListener
70 70
     }
71 71
 
72 72
     /**
73
+     * @Callback(table="tl_vr_wa_standort", target="fields.nc_notification_checkin.options")
74
+     */
75
+    public function onNcNotificationCheckinOptionsCallback(DataContainer $dc)
76
+    {
77
+        $arrOptions = [];
78
+        $objNotifications = $this->db->executeQuery("SELECT id,title FROM tl_nc_notification WHERE type='wa_booking_checkin' ORDER BY title");
79
+
80
+        if (!$objNotifications->rowCount())
81
+        {
82
+            return $arrOptions;
83
+        }
84
+
85
+        foreach ($objNotifications->fetchAllAssociative() as $notification)
86
+        {
87
+            $arrOptions[$notification['id']] = $notification['title'];
88
+        }
89
+
90
+        return $arrOptions;
91
+    }
92
+
93
+    /**
73 94
      * @Callback(table="tl_vr_wa_standort", target="fields.number_ranges.save")
74 95
      */
75 96
     public function onNumberRangesSaveCallback($varValue, DataContainer $dc)