migrate to gtea from bistbucket

This commit is contained in:
2026-03-15 17:08:23 +07:00
commit 129ca2260c
3716 changed files with 566316 additions and 0 deletions

View File

@@ -0,0 +1,323 @@
<?php
namespace Modules\Authentication\Services;
use App\Mail\RestaurantOnboardingMail;
use Carbon\Carbon;
use Exception;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Modules\Authentication\Models\Package;
use Modules\Authentication\Models\Restaurant;
use Modules\Authentication\Models\Subscription;
use Modules\Authentication\Models\SubscriptionItem;
use Modules\Authentication\Models\User;
class RestaurantSetupService
{
/**
* Initialize restaurant related setup including default settings, subscriptions, and domain.
*
* @param array $ownerData
* Expected keys: name, email, phone, password, avatar (optional), package_id, price
*/
public static function setup(Restaurant $restaurant, array $ownerData, bool $sendMail = true): User
{
// Step 1: Check if user already exists
$user = User::where('email', $ownerData['email'])->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' => '&copy; 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],
]);
}
}