first(); if (! $user) { // Create a new user only if not exists $user = User::create([ 'first_name' => $ownerData['name'], 'email' => $ownerData['email'], 'phone' => $ownerData['phone'], 'password' => Hash::make($ownerData['password']), 'avatar' => $ownerData['avatar'] ?? null, 'role_id' => 2, 'user_type' => 'System Admin', ]); // Assign role $role = \Spatie\Permission\Models\Role::find(2); $user->assignRole($role); } // Step 2: Assign this user as restaurant owner $restaurant->owner_id = $user->id; $restaurant->save(); // Step 3: Insert default settings self::insertDefaultSettings($restaurant); // Step 4: Create Subscription & SubscriptionItem if package_id is provided $package = Package::first(); $startDate = Carbon::now()->startOfDay(); $endDate = Carbon::now()->addDays($package->duration - 1)->endOfDay(); // Create subscription $subscription = Subscription::updateOrCreate([ 'user_id' => $user->id, 'restaurant_id' => $restaurant->id, 'package_id' => $package->id, ], [ 'start_date' => $startDate, 'end_date' => $endDate, 'status' => 1, ]); // Create subscription item SubscriptionItem::updateOrCreate([ 'user_id' => $user->id, 'restaurant_id' => $restaurant->id, 'subscription_id' => $subscription->id, 'package_id' => $package->id, ], [ 'amount' => (float) $package->price, 'start_date' => $startDate, 'end_date' => $endDate, ]); // Step 5: Add domain to Vercel if restaurant domain exists if (! empty($restaurant->domain)) { try { $vercelDomainResponse = self::addDomainToVercel($restaurant->domain); if (! $vercelDomainResponse['success']) { Log::warning('Vercel domain add failed', [ 'domain' => $restaurant->domain, 'response' => $vercelDomainResponse, ]); } } catch (Exception $e) { Log::error('Vercel domain add exception: '.$e->getMessage()); } } // Step 6: Send onboarding mail only if user is new if ($sendMail && $user->wasRecentlyCreated) { Mail::to($ownerData['email'])->send(new RestaurantOnboardingMail([ 'restaurant_name' => $restaurant->name, 'restaurant_id' => $restaurant->id, 'email' => $ownerData['email'], 'password' => $ownerData['password'], 'package_name' => $package->name ?? 'Trial Package', 'trial_days' => $package->duration ?? 14, 'trial_end_date' => now()->addDays($package->duration ?? 14)->format('Y-m-d'), 'login_url' => url('/login'), ])); } return $user; } /** * Example placeholder for adding domain to Vercel * * @param string $domain * @return array */ public static function addDomainToVercel($fullDomain) { $client = new Client; $projectId = get_saas_option('vercel_project_id'); $token = get_saas_option('vercel_token'); $url = "https://api.vercel.com/v9/projects/{$projectId}/domains"; try { $response = $client->post($url, [ 'headers' => [ 'Authorization' => 'Bearer '.$token, 'Content-Type' => 'application/json', ], 'json' => [ 'name' => $fullDomain, ], ]); return [ 'success' => true, 'data' => json_decode($response->getBody(), true), ]; } catch (\GuzzleHttp\Exception\ClientException $e) { return [ 'success' => false, 'error_type' => 'client', 'message' => $e->getMessage(), ]; } catch (Exception $e) { return [ 'success' => false, 'error_type' => 'general', 'message' => $e->getMessage(), ]; } } private static function insertDefaultSettings(Restaurant $restaurant) { DB::table('settings')->insert([ ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'restaurant_name', 'option_value' => 'Restaurant'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'site_title', 'option_value' => 'restaurant'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'phone', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'email', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'language', 'option_value' => 'en'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'google_map', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'address', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'on_google_map', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'restaurant_code', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'timezone', 'option_value' => 'Asia/Dhaka'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'currency_symbol', 'option_value' => '$'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'mail_type', 'option_value' => 'mail'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'logo', 'option_value' => 'logo.png'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'disabled_website', 'option_value' => 'no'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'copyright_text', 'option_value' => '© Copyright 2025. All Rights Reserved by FueDevs LTD'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'facebook_link', 'option_value' => 'https://www.facebook.com/'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'google_plus_link', 'option_value' => 'https://www.google.com/'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'youtube_link', 'option_value' => 'https://www.youtube.com/'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'whats_app_link', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'twitter_link', 'option_value' => 'https://www.twitter.com'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'eiin_code', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'sms_gateway', 'option_value' => 'twilio'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'bulk_sms_api_key', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'bulk_sms_sender_id', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'twilio_sid', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'twilio_token', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'twilio_from_number', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'header_notice', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'app_version', 'option_value' => '1.0.0'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'app_url', 'option_value' => 'drive-link'], // ๐ŸŽจ Restaurant Identity & Display ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'tagline', 'option_value' => 'Delicious Food, Fresh Taste'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'favicon', 'option_value' => 'favicon.png'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'theme_color', 'option_value' => '#ff6b00'], ['restaurant_id' => $restaurant->id, 'type' => 'general', 'option_key' => 'background_image', 'option_value' => 'bg.jpg'], // ๐Ÿ’ฐ Finance / POS / Invoice ['restaurant_id' => $restaurant->id, 'type' => 'pos', 'option_key' => 'tax_type', 'option_value' => 'exclusive'], ['restaurant_id' => $restaurant->id, 'type' => 'pos', 'option_key' => 'tax_percentage', 'option_value' => '10'], ['restaurant_id' => $restaurant->id, 'type' => 'pos', 'option_key' => 'service_charge', 'option_value' => '5'], ['restaurant_id' => $restaurant->id, 'type' => 'pos', 'option_key' => 'default_currency', 'option_value' => 'USD'], ['restaurant_id' => $restaurant->id, 'type' => 'pos', 'option_key' => 'billing_prefix', 'option_value' => 'INV-'], ['restaurant_id' => $restaurant->id, 'type' => 'pos', 'option_key' => 'invoice_footer', 'option_value' => 'Thank you! Visit again.'], ['restaurant_id' => $restaurant->id, 'type' => 'pos', 'option_key' => 'enable_kitchen_print', 'option_value' => 'yes'], ['restaurant_id' => $restaurant->id, 'type' => 'pos', 'option_key' => 'enable_customer_copy', 'option_value' => 'yes'], // ๐Ÿšš Online Ordering & Delivery ['restaurant_id' => $restaurant->id, 'type' => 'order', 'option_key' => 'enable_online_order', 'option_value' => 'yes'], ['restaurant_id' => $restaurant->id, 'type' => 'order', 'option_key' => 'delivery_charge', 'option_value' => '50'], ['restaurant_id' => $restaurant->id, 'type' => 'order', 'option_key' => 'minimum_order_amount', 'option_value' => '100'], ['restaurant_id' => $restaurant->id, 'type' => 'order', 'option_key' => 'auto_accept_order', 'option_value' => 'no'], ['restaurant_id' => $restaurant->id, 'type' => 'order', 'option_key' => 'estimated_preparation_time', 'option_value' => '30'], // ๐Ÿ”” Notifications / Integrations ['restaurant_id' => $restaurant->id, 'type' => 'integration', 'option_key' => 'slack_webhook_url', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'integration', 'option_key' => 'telegram_bot_token', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'integration', 'option_key' => 'telegram_chat_id', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'integration', 'option_key' => 'twilio_sms_enabled', 'option_value' => 'yes'], ['restaurant_id' => $restaurant->id, 'type' => 'integration', 'option_key' => 'email_notifications', 'option_value' => 'yes'], ['restaurant_id' => $restaurant->id, 'type' => 'integration', 'option_key' => 'whatsapp_notifications', 'option_value' => 'no'], // ๐Ÿงพ Reports & Logs ['restaurant_id' => $restaurant->id, 'type' => 'system', 'option_key' => 'auto_backup', 'option_value' => 'daily'], ['restaurant_id' => $restaurant->id, 'type' => 'system', 'option_key' => 'report_timezone', 'option_value' => 'Asia/Dhaka'], ['restaurant_id' => $restaurant->id, 'type' => 'system', 'option_key' => 'data_retention_days', 'option_value' => '365'], // ๐Ÿ’ป UI/UX Preferences ['restaurant_id' => $restaurant->id, 'type' => 'ui', 'option_key' => 'sidebar_collapsed', 'option_value' => 'no'], ['restaurant_id' => $restaurant->id, 'type' => 'ui', 'option_key' => 'dark_mode', 'option_value' => 'no'], ['restaurant_id' => $restaurant->id, 'type' => 'ui', 'option_key' => 'default_dashboard', 'option_value' => 'sales'], // ๐Ÿ’ณ Payment Gateways ['restaurant_id' => $restaurant->id, 'type' => 'payment', 'option_key' => 'razorpay_key', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'payment', 'option_key' => 'razorpay_secret', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'payment', 'option_key' => 'stripe_key', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'payment', 'option_key' => 'stripe_secret', 'option_value' => ''], ['restaurant_id' => $restaurant->id, 'type' => 'payment', 'option_key' => 'cash_on_delivery', 'option_value' => 'yes'], // ๐Ÿ‘จโ€๐Ÿณ Kitchen & Staff ['restaurant_id' => $restaurant->id, 'type' => 'staff', 'option_key' => 'max_table_capacity', 'option_value' => '10'], ['restaurant_id' => $restaurant->id, 'type' => 'staff', 'option_key' => 'default_shift_start', 'option_value' => '09:00'], ['restaurant_id' => $restaurant->id, 'type' => 'staff', 'option_key' => 'default_shift_end', 'option_value' => '23:00'], ['restaurant_id' => $restaurant->id, 'type' => 'staff', 'option_key' => 'auto_logout_idle_minutes', 'option_value' => '60'], // ๐ŸŽจ Color Combination ['restaurant_id' => $restaurant->id, 'type' => 'system_color', 'option_key' => 'primary_color', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'system_color', 'option_key' => 'secondary_color', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'system_color', 'option_key' => 'primary_container_color', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'system_color', 'option_key' => 'dark_primary_color', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'system_color', 'option_key' => 'dark_secondary_color', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'system_color', 'option_key' => 'dark_container_color', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'system_color', 'option_key' => 'text_color', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'system_color', 'option_key' => 'dark_text_color', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'system_color', 'option_key' => 'sidebar_selected_bg_color', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'system_color', 'option_key' => 'sidebar_selected_text_color', 'option_value' => null], // ๐Ÿšš Delivery / Online features ['restaurant_id' => $restaurant->id, 'type' => 'delivery', 'option_key' => 'is_online', 'option_value' => false], ['restaurant_id' => $restaurant->id, 'type' => 'delivery', 'option_key' => 'latitude', 'option_value' => '23.8103'], ['restaurant_id' => $restaurant->id, 'type' => 'delivery', 'option_key' => 'longitude', 'option_value' => '90.4125'], ['restaurant_id' => $restaurant->id, 'type' => 'delivery', 'option_key' => 'delivery_radius_km', 'option_value' => 5.00], ['restaurant_id' => $restaurant->id, 'type' => 'delivery', 'option_key' => 'delivery_fee', 'option_value' => 0], ['restaurant_id' => $restaurant->id, 'type' => 'delivery', 'option_key' => 'delivery_partner_count', 'option_value' => 0], ['restaurant_id' => $restaurant->id, 'type' => 'delivery', 'option_key' => 'delivery_time_avg', 'option_value' => 30], ['restaurant_id' => $restaurant->id, 'type' => 'delivery', 'option_key' => 'pickup_enabled', 'option_value' => true], // ๐Ÿ•’ Operational hours & capacity ['restaurant_id' => $restaurant->id, 'type' => 'operational', 'option_key' => 'opening_time', 'option_value' => '09:00:00'], ['restaurant_id' => $restaurant->id, 'type' => 'operational', 'option_key' => 'closing_time', 'option_value' => '22:00:00'], ['restaurant_id' => $restaurant->id, 'type' => 'operational', 'option_key' => 'auto_accept_orders', 'option_value' => false], ['restaurant_id' => $restaurant->id, 'type' => 'operational', 'option_key' => 'pre_order_enabled', 'option_value' => false], ['restaurant_id' => $restaurant->id, 'type' => 'operational', 'option_key' => 'max_order_capacity', 'option_value' => 50], // ๐Ÿ“Š Analytics / reviews ['restaurant_id' => $restaurant->id, 'type' => 'analytics', 'option_key' => 'avg_rating', 'option_value' => 0.00], ['restaurant_id' => $restaurant->id, 'type' => 'analytics', 'option_key' => 'review_count', 'option_value' => 0], ['restaurant_id' => $restaurant->id, 'type' => 'analytics', 'option_key' => 'total_orders', 'option_value' => 0], ['restaurant_id' => $restaurant->id, 'type' => 'analytics', 'option_key' => 'last_order_time', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'analytics', 'option_key' => 'last_active_time', 'option_value' => null], // ๐ŸŽฏ Marketing & social ['restaurant_id' => $restaurant->id, 'type' => 'marketing', 'option_key' => 'loyalty_points_enabled', 'option_value' => false], ['restaurant_id' => $restaurant->id, 'type' => 'marketing', 'option_key' => 'offers_enabled', 'option_value' => false], ['restaurant_id' => $restaurant->id, 'type' => 'marketing', 'option_key' => 'social_media_links', 'option_value' => json_encode([ 'facebook' => '', 'instagram' => '', 'twitter' => '', 'linkedin' => '', ])], // ๐Ÿ’ป Future-proof / extra ['restaurant_id' => $restaurant->id, 'type' => 'system', 'option_key' => 'settings', 'option_value' => json_encode([])], ['restaurant_id' => $restaurant->id, 'type' => 'system', 'option_key' => 'uuid', 'option_value' => uniqid('rest_')], ['restaurant_id' => $restaurant->id, 'type' => 'email_config', 'option_key' => 'email_smtp_host', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'email_config', 'option_key' => 'email_smtp_port', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'email_config', 'option_key' => 'email_smtp_username', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'email_config', 'option_key' => 'email_smtp_password', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'email_config', 'option_key' => 'email_smtp_encryption', 'option_value' => null], // SMS Config ['restaurant_id' => $restaurant->id, 'type' => 'sms_config', 'option_key' => 'twilio_api_key', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'sms_config', 'option_key' => 'twilio_api_secret', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'sms_config', 'option_key' => 'twilio_sender_id', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'sms_config', 'option_key' => 'twilio_api_url', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'sms_config', 'option_key' => 'twilio_is_default', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'sms_config', 'option_key' => 'nexmo_api_key', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'sms_config', 'option_key' => 'nexmo_api_secret', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'sms_config', 'option_key' => 'nexmo_sender_id', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'sms_config', 'option_key' => 'nexmo_api_url', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'sms_config', 'option_key' => 'nexmo_is_default', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'sms_config', 'option_key' => 'muthofun_api_key', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'sms_config', 'option_key' => 'smsglobal_api_key', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'sms_config', 'option_key' => 'smsglobal_api_secret', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'sms_config', 'option_key' => 'smsglobal_sender_id', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'sms_config', 'option_key' => 'smsglobal_api_url', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'sms_config', 'option_key' => 'smsglobal_extra_key', 'option_value' => null], ['restaurant_id' => $restaurant->id, 'type' => 'sms_config', 'option_key' => 'smsglobal_is_default', 'option_value' => null], ]); } }