validate([ 'shop_name' => 'required|string|max:255', 'shop_address' => 'required|string|max:255', 'shop_city' => 'required|string|max:100', 'shop_state' => 'required|string|max:100', 'shop_zip_code' => 'required|string|max:20', 'shop_phone' => 'required|string|max:20', 'shop_email' => 'required|email|max:255', 'shop_website' => 'nullable|url|max:255', 'default_tax_rate' => 'required|numeric|min:0|max:100', 'currency' => 'required|string|max:10', 'currency_symbol' => 'required|string|max:5', 'timezone' => 'required|string', 'date_format' => 'required|string', 'time_format' => 'required|string', 'enable_notifications' => 'nullable|boolean', 'enable_sms_notifications' => 'nullable|boolean', 'enable_email_notifications' => 'nullable|boolean', 'is_open_weekends' => 'nullable|boolean', 'business_hours' => 'nullable|array', 'holiday_hours' => 'nullable|array', ]); // Handle boolean fields that might not be present in request $validated['enable_notifications'] = $request->has('enable_notifications'); $validated['enable_sms_notifications'] = $request->has('enable_sms_notifications'); $validated['enable_email_notifications'] = $request->has('enable_email_notifications'); $validated['is_open_weekends'] = $request->has('is_open_weekends'); // Ensure arrays have default values if not provided $validated['business_hours'] = $validated['business_hours'] ?? $settings->business_hours ?? []; $validated['holiday_hours'] = $validated['holiday_hours'] ?? $settings->holiday_hours ?? []; foreach ($validated as $key => $value) { $settings->$key = $value; } $settings->save(); return redirect()->back()->with('success', 'General settings updated successfully!'); } public function service(ServiceSettings $settings) { return view('settings.service', compact('settings')); } public function updateService(Request $request, ServiceSettings $settings) { $validated = $request->validate([ 'standard_labor_rate' => 'required|numeric|min:0', 'overtime_labor_rate' => 'required|numeric|min:0', 'weekend_labor_rate' => 'required|numeric|min:0', 'holiday_labor_rate' => 'required|numeric|min:0', 'oil_change_interval' => 'required|integer|min:1000', 'tire_rotation_interval' => 'required|integer|min:1000', 'brake_inspection_interval' => 'required|integer|min:1000', 'general_inspection_interval' => 'required|integer|min:1000', 'enable_service_reminders' => 'nullable|boolean', 'reminder_advance_days' => 'required|integer|min:1|max:90', 'default_parts_warranty_days' => 'required|integer|min:1', 'default_labor_warranty_days' => 'required|integer|min:1', 'enable_extended_warranty' => 'nullable|boolean', 'require_quality_inspection' => 'nullable|boolean', 'require_technician_signature' => 'nullable|boolean', 'require_customer_signature' => 'nullable|boolean', 'enable_photo_documentation' => 'nullable|boolean', 'service_categories' => 'nullable|array', 'priority_levels' => 'nullable|array', ]); // Handle boolean fields that might not be present in request $validated['enable_service_reminders'] = $request->has('enable_service_reminders'); $validated['enable_extended_warranty'] = $request->has('enable_extended_warranty'); $validated['require_quality_inspection'] = $request->has('require_quality_inspection'); $validated['require_technician_signature'] = $request->has('require_technician_signature'); $validated['require_customer_signature'] = $request->has('require_customer_signature'); $validated['enable_photo_documentation'] = $request->has('enable_photo_documentation'); // Ensure arrays have default values if not provided $validated['service_categories'] = $validated['service_categories'] ?? $settings->service_categories ?? []; $validated['priority_levels'] = $validated['priority_levels'] ?? $settings->priority_levels ?? []; foreach ($validated as $key => $value) { $settings->$key = $value; } $settings->save(); return redirect()->back()->with('success', 'Service settings updated successfully!'); } public function inventory(InventorySettings $settings) { return view('settings.inventory', compact('settings')); } public function updateInventory(Request $request, InventorySettings $settings) { $validated = $request->validate([ 'low_stock_threshold' => 'required|integer|min:1', 'critical_stock_threshold' => 'required|integer|min:1', 'default_reorder_quantity' => 'required|integer|min:1', 'default_lead_time_days' => 'required|integer|min:1', 'default_markup_percentage' => 'required|numeric|min:0', 'preferred_supplier_count' => 'required|integer|min:1', 'minimum_order_amount' => 'required|numeric|min:0', 'default_part_markup' => 'required|numeric|min:0', 'core_charge_percentage' => 'required|numeric|min:0', 'shop_supply_fee' => 'required|numeric|min:0', 'environmental_fee' => 'required|numeric|min:0', 'waste_oil_fee' => 'required|numeric|min:0', 'tire_disposal_fee' => 'required|numeric|min:0', 'default_payment_terms' => 'required|string', 'preferred_ordering_method' => 'required|string', 'free_shipping_threshold' => 'nullable|numeric|min:0', 'enable_low_stock_alerts' => 'nullable|boolean', 'enable_automatic_reorder' => 'nullable|boolean', 'track_serial_numbers' => 'nullable|boolean', 'enable_barcode_scanning' => 'nullable|boolean', 'enable_volume_discounts' => 'nullable|boolean', 'enable_seasonal_pricing' => 'nullable|boolean', 'enable_customer_specific_pricing' => 'nullable|boolean', 'require_po_approval' => 'nullable|boolean', 'enable_dropship' => 'nullable|boolean', 'enable_backorders' => 'nullable|boolean', ]); // Handle boolean fields that might not be present in request $validated['enable_low_stock_alerts'] = $request->has('enable_low_stock_alerts'); $validated['enable_auto_reorder'] = $request->has('enable_automatic_reorder'); // Map form field to DB field $validated['track_serial_numbers'] = $request->has('track_serial_numbers'); $validated['enable_barcode_scanning'] = $request->has('enable_barcode_scanning'); $validated['enable_volume_discounts'] = $request->has('enable_volume_discounts'); $validated['enable_seasonal_pricing'] = $request->has('enable_seasonal_pricing'); $validated['enable_customer_specific_pricing'] = $request->has('enable_customer_specific_pricing'); $validated['require_po_approval'] = $request->has('require_po_approval'); $validated['enable_dropship'] = $request->has('enable_dropship'); $validated['enable_backorders'] = $request->has('enable_backorders'); foreach ($validated as $key => $value) { $settings->$key = $value; } $settings->save(); return redirect()->back()->with('success', 'Inventory settings updated successfully!'); } public function notifications(NotificationSettings $settings) { return view('settings.notifications', compact('settings')); } public function updateNotifications(Request $request, NotificationSettings $settings) { $validated = $request->validate([ 'from_email' => 'required|email', 'from_name' => 'required|string|max:255', 'manager_email' => 'required|email', 'enable_customer_notifications' => 'nullable|boolean', 'enable_technician_notifications' => 'nullable|boolean', 'enable_manager_notifications' => 'nullable|boolean', 'enable_sms' => 'nullable|boolean', 'sms_provider' => 'nullable|string', 'sms_api_key' => 'nullable|string', 'sms_from_number' => 'nullable|string', 'customer_notification_types' => 'nullable|array', 'notification_timing' => 'nullable|array', 'notify_on_new_job' => 'nullable|boolean', 'notify_on_job_completion' => 'nullable|boolean', 'notify_on_low_stock' => 'nullable|boolean', 'notify_on_overdue_inspection' => 'nullable|boolean', 'notify_on_warranty_expiry' => 'nullable|boolean', 'enable_escalation' => 'nullable|boolean', 'escalation_hours' => 'required|integer|min:1', 'escalation_contacts' => 'nullable|array', ]); // Handle boolean fields that might not be present in request $validated['enable_customer_notifications'] = $request->has('enable_customer_notifications'); $validated['enable_technician_notifications'] = $request->has('enable_technician_notifications'); $validated['enable_manager_notifications'] = $request->has('enable_manager_notifications'); $validated['enable_sms'] = $request->has('enable_sms'); $validated['notify_on_new_job'] = $request->has('notify_on_new_job'); $validated['notify_on_job_completion'] = $request->has('notify_on_job_completion'); $validated['notify_on_low_stock'] = $request->has('notify_on_low_stock'); $validated['notify_on_overdue_inspection'] = $request->has('notify_on_overdue_inspection'); $validated['notify_on_warranty_expiry'] = $request->has('notify_on_warranty_expiry'); $validated['enable_escalation'] = $request->has('enable_escalation'); // Ensure arrays have default values if not provided $validated['customer_notification_types'] = $validated['customer_notification_types'] ?? $settings->customer_notification_types ?? []; $validated['notification_timing'] = $validated['notification_timing'] ?? $settings->notification_timing ?? []; $validated['escalation_contacts'] = $validated['escalation_contacts'] ?? $settings->escalation_contacts ?? []; foreach ($validated as $key => $value) { $settings->$key = $value; } $settings->save(); return redirect()->back()->with('success', 'Notification settings updated successfully!'); } public function security(SecuritySettings $settings) { return view('settings.security', compact('settings')); } public function updateSecurity(Request $request, SecuritySettings $settings) { $validated = $request->validate([ 'enable_two_factor_auth' => 'nullable|boolean', 'session_timeout_minutes' => 'required|integer|min:5', 'password_expiry_days' => 'required|integer|min:1', 'max_login_attempts' => 'required|integer|min:1', 'lockout_duration_minutes' => 'required|integer|min:1', 'min_password_length' => 'required|integer|min:6', 'require_uppercase' => 'nullable|boolean', 'require_lowercase' => 'nullable|boolean', 'require_numbers' => 'nullable|boolean', 'require_special_characters' => 'nullable|boolean', 'enable_data_encryption' => 'nullable|boolean', 'enable_audit_logging' => 'nullable|boolean', 'audit_log_retention_days' => 'required|integer|min:1', 'enable_backup_alerts' => 'nullable|boolean', 'enable_api_rate_limiting' => 'nullable|boolean', 'api_requests_per_minute' => 'required|integer|min:1', 'allowed_ip_addresses' => 'nullable|string', 'allow_customer_portal' => 'nullable|boolean', 'allow_customer_data_download' => 'nullable|boolean', 'customer_session_timeout_minutes' => 'required|integer|min:5', ]); // Handle boolean fields that might not be present in request $validated['enable_two_factor_auth'] = $request->has('enable_two_factor_auth'); $validated['require_uppercase'] = $request->has('require_uppercase'); $validated['require_lowercase'] = $request->has('require_lowercase'); $validated['require_numbers'] = $request->has('require_numbers'); $validated['require_special_characters'] = $request->has('require_special_characters'); $validated['enable_data_encryption'] = $request->has('enable_data_encryption'); $validated['enable_audit_logging'] = $request->has('enable_audit_logging'); $validated['enable_backup_alerts'] = $request->has('enable_backup_alerts'); $validated['enable_api_rate_limiting'] = $request->has('enable_api_rate_limiting'); $validated['allow_customer_portal'] = $request->has('allow_customer_portal'); $validated['allow_customer_data_download'] = $request->has('allow_customer_data_download'); // Convert IP addresses from textarea to array if (!empty($validated['allowed_ip_addresses'])) { $validated['allowed_ip_addresses'] = array_filter( array_map('trim', explode("\n", $validated['allowed_ip_addresses'])), function($ip) { return !empty($ip); } ); } else { $validated['allowed_ip_addresses'] = []; } foreach ($validated as $key => $value) { $settings->$key = $value; } $settings->save(); return redirect()->back()->with('success', 'Security settings updated successfully!'); } }