'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;
}
}