'datetime', 'details' => 'array' ]; public function restaurant() { return $this->belongsTo(Restaurant::class); } public function booking() { return $this->belongsTo(Booking::class); } /** * Generate an idempotency key for an automation action * * @param string $automationType * @param int $bookingId * @return string SHA-256 hash */ public static function generateIdempotencyKey($automationType, $bookingId) { return hash('sha256', "{$automationType}|{$bookingId}"); } /** * Registrar una acción de automatización * * @param int $restaurant_id * @param int $booking_id * @param string $automation_type * @param string $action * @param string|null $old_status * @param string|null $new_status * @param array|null $details * @param string|null $idempotencyKey * @return AutomationLog */ public static function logAutomation( $restaurant_id, $booking_id, $automation_type, $action, $old_status = null, $new_status = null, $details = null, $idempotencyKey = null ) { return AutomationLog::create([ 'restaurant_id' => $restaurant_id, 'booking_id' => $booking_id, 'automation_type' => $automation_type, 'action' => $action, 'old_status' => $old_status, 'new_status' => $new_status, 'executed_at' => evavel_now(), 'details' => $details, 'idempotency_key' => $idempotencyKey ]); } /** * Registrar cambio de status automatizado * * @param Booking $booking * @param string $automation_type * @param string $old_status * @param string $new_status * @param array|null $details * @param string|null $idempotencyKey * @return AutomationLog */ public static function logStatusChange( Booking $booking, $automation_type, $old_status, $new_status, $details = null, $idempotencyKey = null ) { return self::logAutomation( $booking->restaurant_id, $booking->id, $automation_type, 'status_change', $old_status, $new_status, $details, $idempotencyKey ); } /** * Registrar envío de email automatizado * * @param Booking $booking * @param string $automation_type * @param string $email_type * @param array|null $details * @param string|null $idempotencyKey * @return AutomationLog */ public static function logEmailSent( Booking $booking, $automation_type, $email_type, $details = null, $idempotencyKey = null ) { return self::logAutomation( $booking->restaurant_id, $booking->id, $automation_type, $email_type, null, null, array_merge(['email_type' => $email_type], $details ?: []), $idempotencyKey ); } /** * Obtener logs por tipo de automatización * * @param int $restaurant_id * @param string|null $automation_type * @param int $limit * @return \Illuminate\Database\Eloquent\Collection */ public static function getRecentLogs($restaurant_id, $automation_type = null, $limit = 100) { $query = self::where('restaurant_id', $restaurant_id) ->with(['booking']) ->orderBy('executed_at', 'desc') ->limit($limit); if ($automation_type) { $query->where('automation_type', $automation_type); } return $query->get(); } public function updateDetails($args) { $details = $this->details; if (is_array($details)) { $details = array_merge($details, $args); $this->details = $details; $this->save(); } } }