'boolean', 'for_shifts' => 'boolean', 'for_events' => 'boolean', ]; public static function description() { return __eva('Send WhatsApp reconfirmation messages to your clients before their reservation and handle their responses.'); } public function restaurant() { return $this->belongsTo(Restaurant::class); } public function fields() { return [ [ 'attribute' => 'for_shifts', 'stacked' => true, 'style' => 'display: inline-block; width: 10%; vertical-align: top;', 'name' => __eva('Use For Shifts'), 'component' => 'boolean-field', 'type' => 'switch', 'value' => $this->for_shifts ], [ 'attribute' => 'for_events', 'stacked' => true, 'style' => 'display: inline-block; width: 10%; vertical-align: top;', 'name' => __eva('Use For Events'), 'component' => 'boolean-field', 'type' => 'switch', 'value' => $this->for_events ], [ 'attribute' => 'name', 'stacked' => true, 'inputClass' => 'form-input-bordered-highlight', 'name' => __eva('Name'), 'helpText' => __eva('Use this field to identify your reconfirmation'), 'component' => 'text-field', 'value' => $this->name ], [ 'attribute' => 'whatsapp_active', 'stacked' => true, 'style' => 'display: inline-block; width: 20%; vertical-align: top;', 'name' => __eva('Send this WhatsApp'), 'component' => 'boolean-field', 'type' => 'switch', 'value' => $this->whatsapp_active ], [ 'attribute' => 'whatsapp_time', 'stacked' => true, 'style' => 'display: inline-block; width: 50%; vertical-align: top;', 'name' => __eva('When should be sent'), 'component' => 'select-field', 'options' => $this->getListOfTimes(), 'value' => $this->whatsapp_time ], [ 'attribute' => 'whatsapp_reconfirmation', 'stacked' => true, 'name' => __eva('WhatsApp reconfirmation template'), 'component' => 'group-whatsapp-template-field', 'helpText' => __eva('Select the WhatsApp template to use for the reconfirmation in each language.'), 'value' => $this->valueWithLanguagesFor('whatsapp_reconfirmation'), 'bookingFields' => self::getBookingFields(), 'isAdmin' => false, ], // Explanation of how button responses work [ 'attribute' => 'button_actions_explanation', 'component' => 'group-info-field', 'name' => __eva('Button Response Actions'), 'value' => $this->getButtonActionsExplanation(), ], // NO LOS USO PORQUE YA ESTAN LOS MENSAJES POR DEFECTO // Custom reply messages for button responses /*[ 'attribute' => 'reply_messages', 'stacked' => true, 'name' => __eva('Auto-reply messages'), 'component' => 'group-whatsapp-reply-field', 'helpText' => __eva('Optional custom messages sent automatically when the customer clicks a button. Leave empty to not send any reply.'), 'value' => $this->getReplyMessagesValue(), ],*/ ]; } /** * Get the explanation text for button actions * * @return string */ protected function getButtonActionsExplanation() { return '
' . '

' . __eva('When the customer clicks on the WhatsApp template buttons, the booking status will be automatically updated:') . '

' . '
' . 'confirm_booking' . '→' . '' . __eva('User Confirmed') . ' (confirmed)' . '
' . '
' . 'cancel_booking' . '→' . '' . __eva('Cancelled') . ' (cancelled)' . '
' . '

' . __eva('Make sure your WhatsApp template buttons use these exact payload values.') . '

' . '
'; } protected function getListOfTimes() { $options = [ ['label' => __eva('1 hour before'), 'value' => 3600], ]; for ($i = 2; $i <= 48; $i++) { $label = $i . ' ' .__eva('hours before'); if ($i == 24) { $label .= ' ' . __eva('(1 day before)'); } else if ($i == 36) { $label .= ' ' . __eva('(1.5 days before)'); } else if ($i == 48) { $label .= ' ' . __eva('(2 days before)'); } $options[] = ['label' => $label, 'value' => 3600 * $i]; } for($i = 3; $i <= 30; $i++) { $value = $i * 24 * 3600; $label = str_replace('{x}', $i, __eva('{x} days before')); $options[] = ['label' => $label, 'value' => $value]; } return $options; } public function defaultValue() { return [ 'name' => __eva('WhatsApp Reconfirmation'), 'for_shifts' => true, 'for_events' => true, 'whatsapp_active' => true, 'whatsapp_time' => 86400, // 24 hours before 'whatsapp_reconfirmation' => $this->getDefaultTemplateValue(), 'reply_messages' => $this->getDefaultReplyMessages(), ]; } /** * Get default template value structure for all languages * * @return array */ protected function getDefaultTemplateValue() { $languages = evavel_languages_allowed(); $value = []; foreach ($languages as $lang => $label) { $value[$lang] = [ 'template_sid' => '', 'template_name' => '', 'field_mapping' => [], ]; } return $value; } /** * Get value with languages for a specific field * * @param string $key * @return array */ public function valueWithLanguagesFor($key) { $languages = evavel_languages_allowed(); $value = $this->{$key}; if (!is_array($value)) { $value = []; } // Ensure all languages have a configuration foreach ($languages as $lang => $label) { if (!isset($value[$lang])) { $value[$lang] = [ 'template_sid' => '', 'template_name' => '', 'field_mapping' => [], ]; } } return $value; } /** * Get configured template for a specific language * * @param string $language * @return array|null */ public function getTemplateConfig($language) { $config = $this->whatsapp_reconfirmation; if (!is_array($config) || !isset($config[$language])) { return null; } return $config[$language]; } /** * Check if the reconfirmation is enabled * * @return bool */ public function isEnabled() { return (bool) $this->whatsapp_active; } /** * Get the time before the booking when the reconfirmation should be sent * * @return int Time in seconds */ public function getTimeBefore() { return (int) $this->whatsapp_time; } /** * Check if this reconfirmation should be used for shifts * * @return bool */ public function isForShifts() { return (bool) $this->for_shifts; } /** * Check if this reconfirmation should be used for events * * @return bool */ public function isForEvents() { return (bool) $this->for_events; } /** * Check if a button payload matches the confirm action * * @param string $payload * @return bool */ public function isConfirmPayload($payload) { return strtolower(trim($payload)) === self::BUTTON_PAYLOAD_CONFIRM; } /** * Check if a button payload matches the cancel action * * @param string $payload * @return bool */ public function isCancelPayload($payload) { return strtolower(trim($payload)) === self::BUTTON_PAYLOAD_CANCEL; } /** * Get the status to set when customer confirms * * @return string */ public function getConfirmStatus() { return self::STATUS_ON_CONFIRM; } /** * Get the status to set when customer cancels * * @return string */ public function getCancelStatus() { return self::STATUS_ON_CANCEL; } /** * Process a button payload and return the new status if applicable * * @param string $payload * @return string|null Returns the new status or null if payload not recognized */ public function processButtonPayload($payload) { if ($this->isConfirmPayload($payload)) { return self::STATUS_ON_CONFIRM; } if ($this->isCancelPayload($payload)) { return self::STATUS_ON_CANCEL; } return null; } /** * Get default reply messages structure for all languages * * @return array */ protected function getDefaultReplyMessages() { $languages = evavel_languages_allowed(); $value = []; foreach ($languages as $lang => $label) { $value[$lang] = [ 'reply_on_confirm' => '', 'reply_on_cancel' => '', ]; } return $value; } /** * Get the reply_messages value with all languages filled * * @return array */ public function getReplyMessagesValue() { $languages = evavel_languages_allowed(); $value = $this->reply_messages; if (!is_array($value)) { $value = []; } foreach ($languages as $lang => $label) { if (!isset($value[$lang])) { $value[$lang] = [ 'reply_on_confirm' => '', 'reply_on_cancel' => '', ]; } } return $value; } /** * Get the custom reply message for confirm action in a given language * * @param string $language * @return string|null */ public function getReplyOnConfirm($language) { $messages = $this->reply_messages; if (!is_array($messages) || !isset($messages[$language])) { return null; } $text = trim($messages[$language]['reply_on_confirm'] ?? ''); return !empty($text) ? $text : null; } /** * Get the custom reply message for cancel action in a given language * * @param string $language * @return string|null */ public function getReplyOnCancel($language) { $messages = $this->reply_messages; if (!is_array($messages) || !isset($messages[$language])) { return null; } $text = trim($messages[$language]['reply_on_cancel'] ?? ''); return !empty($text) ? $text : null; } }