# Complete Settings System Guide
## Overview
A comprehensive, config-first settings system with database overrides for all application settings groups.
## Architecture
### Config Files (Defaults)
All settings have config files with sensible defaults:
1. **`config/financial-settings.php`** - Deposits, taxes, payments, refunds, pricing
2. **`config/booking-settings.php`** - Booking rules, duration, working hours
3. **`config/notification-settings.php`** - Email, SMS, push notifications
4. **`config/discount-promotion-settings.php`** - Discounts, loyalty, promotions
5. **`config/pos-settings.php`** - Point of sale, cash drawer, fiscal printer
6. **`config/policy-document-settings.php`** - Terms, privacy, GDPR
7. **`config/pwa-settings.php`** - Progressive web app configuration
8. **`config/tremol-settings.php`** - Tremol fiscal printer settings
### Helper Classes
#### Universal Settings Helper
**`App\Helpers\SettingsHelper`** - Handles all setting groups
```php
// Get setting with config fallback
SettingsHelper::get($name, $group, $default);
// Get all settings for a group
SettingsHelper::getAll($group, $companyId);
// Initialize settings for new company
SettingsHelper::initializeForCompany($companyId, $group, $workspaceId);
// Initialize all groups
SettingsHelper::initializeAllForCompany($companyId, $workspaceId);
// Set a setting
SettingsHelper::set($name, $group, $value, $companyId, $workspaceId);
// Check if feature is enabled
SettingsHelper::isEnabled($feature, $group);
// Reset to defaults
SettingsHelper::reset($name, $group);
SettingsHelper::resetGroup($group);
// Export/Import
SettingsHelper::export($companyId);
SettingsHelper::import($settings, $companyId);
```
#### Financial Settings Helper
**`App\Helpers\FinancialSettingsHelper`** - Specialized for financial settings
```php
// Calculate deposit amount
FinancialSettingsHelper::calculateDepositAmount($bookingTotal);
// Get tax rate by category
FinancialSettingsHelper::getTaxRate($category);
```
### Global Helper Functions
```php
// Universal setting getter
setting($name, $group, $default);
// Shorthand functions
financial_setting($name, $default);
booking_setting($name, $default);
notification_setting($name, $default);
pos_setting($name, $default);
```
## Usage Examples
### 1. Getting Settings
```php
// Using setting() helper
$depositEnabled = setting('enable_deposit_payments', 'financial');
$maxBookings = setting('max_bookings_per_user', 'booking', 5);
$emailEnabled = setting('enable_email_notifications', 'notifications');
// Using shorthand functions
$depositEnabled = financial_setting('enable_deposit_payments');
$maxBookings = booking_setting('max_bookings_per_user');
$emailEnabled = notification_setting('enable_email_notifications');
// Using SettingsHelper directly
use App\Helpers\SettingsHelper;
$depositEnabled = SettingsHelper::get('enable_deposit_payments', 'financial');
$maxBookings = SettingsHelper::get('max_bookings_per_user', 'booking');
```
### 2. Setting Values
```php
use App\Helpers\SettingsHelper;
// Set a single setting
SettingsHelper::set('max_bookings_per_user', 'booking', 10);
// Set for specific company
SettingsHelper::set('enable_pos', 'pos', true, $companyId);
```
### 3. Checking Features
```php
use App\Helpers\SettingsHelper;
if (SettingsHelper::isEnabled('enable_deposit_payments', 'financial')) {
// Deposits are enabled
}
if (SettingsHelper::isEnabled('enable_sms_notifications', 'notifications')) {
// SMS notifications are enabled
}
if (SettingsHelper::isEnabled('enable_fiscal_printer', 'pos')) {
// Fiscal printer is enabled
}
```
### 4. Initializing New Company
```php
use App\Helpers\SettingsHelper;
// When creating a new company
$company = Company::create([...]);
$workspace = Workspace::create([...]);
// Initialize all settings with defaults
SettingsHelper::initializeAllForCompany($company->id, $workspace->id);
// Or initialize specific groups
SettingsHelper::initializeForCompany($company->id, 'financial', $workspace->id);
SettingsHelper::initializeForCompany($company->id, 'booking', $workspace->id);
```
### 5. Exporting/Importing Settings
```php
use App\Helpers\SettingsHelper;
// Export all settings for a company
$settings = SettingsHelper::export($companyId);
// Save to file
file_put_contents('company-settings.json', json_encode($settings));
// Import settings
$settings = json_decode(file_get_contents('company-settings.json'), true);
SettingsHelper::import($settings, $newCompanyId);
```
### 6. Resetting to Defaults
```php
use App\Helpers\SettingsHelper;
// Reset single setting
SettingsHelper::reset('max_bookings_per_user', 'booking');
// Reset entire group
SettingsHelper::resetGroup('financial');
```
## Integration Examples
### In Controllers
```php
use App\Helpers\SettingsHelper;
class BookingController extends Controller
{
public function store(Request $request)
{
// Check max bookings limit
$maxBookings = booking_setting('max_bookings_per_user', 5);
$userBookings = $request->user()->bookings()->count();
if ($userBookings >= $maxBookings) {
return back()->withErrors(['error' => 'Maximum bookings reached']);
}
// Check if approval required
$approvalWorkflow = booking_setting('booking_approval_workflow', 'automatic');
$status = $approvalWorkflow === 'automatic' ? 'confirmed' : 'pending';
$booking = Booking::create([
...$request->validated(),
'status' => $status,
]);
// Send notification if enabled
if (notification_setting('enable_email_notifications')) {
Mail::to($request->user())->send(new BookingConfirmation($booking));
}
return redirect()->route('bookings.show', $booking);
}
}
```
### In Services
```php
use App\Helpers\FinancialSettingsHelper;
use App\Helpers\SettingsHelper;
class PricingService
{
public function calculateTotal(Booking $booking): float
{
$subtotal = $booking->calculateSubtotal();
// Apply discounts if enabled
if (SettingsHelper::isEnabled('enable_discounts', 'discounts')) {
$subtotal = $this->applyDiscounts($subtotal, $booking);
}
// Calculate tax
$taxRate = FinancialSettingsHelper::getTaxRate('accommodation');
$taxAmount = $subtotal * ($taxRate / 100);
// Check if tax is inclusive
if (financial_setting('tax_inclusive_pricing')) {
$total = $subtotal;
$taxAmount = $subtotal - ($subtotal / (1 + ($taxRate / 100)));
} else {
$total = $subtotal + $taxAmount;
}
return $total;
}
protected function applyDiscounts(float $amount, Booking $booking): float
{
// Early bird discount
if (SettingsHelper::isEnabled('enable_early_bird_discount', 'discounts')) {
$daysInAdvance = now()->diffInDays($booking->check_in);
$minDays = setting('early_bird_days_before', 'discounts', 30);
if ($daysInAdvance >= $minDays) {
$discount = setting('early_bird_discount_percentage', 'discounts', 10);
$amount *= (1 - ($discount / 100));
}
}
// Long stay discount
if (SettingsHelper::isEnabled('enable_long_stay_discount', 'discounts')) {
$nights = $booking->getTotalNights();
$minNights = setting('long_stay_min_nights', 'discounts', 7);
if ($nights >= $minNights) {
$discount = setting('long_stay_discount_percentage', 'discounts', 15);
$amount *= (1 - ($discount / 100));
}
}
return $amount;
}
}
```
### In Observers
```php
use App\Helpers\SettingsHelper;
class CompanyObserver
{
public function created(Company $company)
{
// Initialize all settings with defaults
SettingsHelper::initializeAllForCompany($company->id);
// Log the initialization
activity()
->performedOn($company)
->log('Settings initialized with default values');
}
}
```
### In Commands
```php
use App\Helpers\SettingsHelper;
class SyncSettingsCommand extends Command
{
protected $signature = 'settings:sync {company?}';
public function handle()
{
$companyId = $this->argument('company');
if ($companyId) {
$company = Company::findOrFail($companyId);
SettingsHelper::initializeAllForCompany($company->id);
$this->info("Settings synced for company: {$company->name}");
} else {
Company::each(function ($company) {
SettingsHelper::initializeAllForCompany($company->id);
$this->info("Settings synced for company: {$company->name}");
});
}
}
}
```
## Configuration Reference
### Financial Settings
```php
financial_setting('enable_deposit_payments')
financial_setting('deposit_type') // 'percentage' or 'fixed'
financial_setting('deposit_percentage')
financial_setting('default_tax_rate')
financial_setting('tax_inclusive_pricing')
financial_setting('enable_multi_currency')
```
### Booking Settings
```php
booking_setting('max_bookings_per_user')
booking_setting('booking_approval_workflow')
booking_setting('working_hours_start')
booking_setting('working_hours_end')
booking_setting('overbooking_prevention')
```
### Notification Settings
```php
notification_setting('enable_email_notifications')
notification_setting('enable_sms_notifications')
notification_setting('enable_push_notifications')
notification_setting('reminder_hours_before')
```
### Discount Settings
```php
setting('enable_early_bird_discount', 'discounts')
setting('early_bird_discount_percentage', 'discounts')
setting('enable_loyalty_program', 'discounts')
setting('loyalty_points_per_euro', 'discounts')
```
### POS Settings
```php
pos_setting('enable_pos')
pos_setting('auto_print_receipt')
pos_setting('enable_fiscal_printer')
pos_setting('fiscal_printer_type')
pos_setting('require_cashier_login')
```
## Environment Variables
Some settings can use environment variables:
```env
# Financial
PAYMENT_GATEWAY_API_KEY=
PAYMENT_GATEWAY_SECRET_KEY=
CURRENCY_API_KEY=
# Notifications
MAIL_FROM_ADDRESS=
SMS_API_KEY=
PUSH_NOTIFICATION_KEY=
# POS
POS_REPORT_EMAIL=
# Tremol
TREMOL_IP=192.168.1.100
TREMOL_PORT=4444
TREMOL_OPERATOR_PASSWORD=
# PWA
VAPID_PUBLIC_KEY=
VAPID_PRIVATE_KEY=
```
## Best Practices
1. **Always use helper functions** instead of direct database queries
2. **Provide sensible defaults** in config files
3. **Initialize settings** when creating new companies
4. **Use feature flags** before applying conditional logic
5. **Cache frequently accessed settings** if needed
6. **Validate settings** before saving to database
7. **Log setting changes** for audit trail
8. **Export settings** before major changes
9. **Test with config values** before database override
10. **Document custom settings** in company notes
## Troubleshooting
### Settings not loading
```bash
# Clear config cache
php artisan config:clear
# Dump autoload
composer dump-autoload
# Clear application cache
php artisan cache:clear
```
### Wrong values returned
```php
// Check database value
$setting = Setting::where('name', 'max_bookings_per_user')
->where('group', 'booking')
->where('company_id', session('selected_company'))
->first();
dd($setting?->payload);
// Check config value
dd(config('booking-settings.max_bookings_per_user'));
// Check helper value
dd(booking_setting('max_bookings_per_user'));
```
### Initialize missing settings
```php
// In tinker
use App\Helpers\SettingsHelper;
// Initialize all groups
SettingsHelper::initializeAllForCompany(1);
// Initialize specific group
SettingsHelper::initializeForCompany(1, 'booking');
```
## Summary
✅ **8 Config files** with comprehensive defaults
✅ **Universal SettingsHelper** for all groups
✅ **Specialized helpers** for complex calculations
✅ **Global helper functions** for easy access
✅ **Automatic initialization** for new companies
✅ **Export/Import** functionality
✅ **Reset to defaults** capability
✅ **Feature flags** for conditional logic
✅ **Environment variable** support
✅ **Multi-tenant** support
Your application now has a complete, robust settings system with config fallbacks for all setting groups!