Financial Settings Configuration Guide

📄 General
← Back to Documentation
# Financial Settings Configuration Guide ## Overview The Financial Settings system uses a **config-first approach** with database overrides. This ensures that: 1. New companies get sensible defaults immediately 2. Settings can be customized per company 3. System remains functional even without database configuration 4. Easy to maintain and update default values ## Architecture ### Config File **Location:** `config/financial-settings.php` Contains all default values organized by category: - Deposits & Partial Payments - Tax Rates & VAT - Payment Gateway - Refund Rules - Dynamic Pricing - Multi-Currency - Security Deposit - Invoicing - Pricing Rules - Payment Methods - Fiscal & Compliance - Notifications ### Helper Class **Location:** `app/Helpers/FinancialSettingsHelper.php` Provides methods to: - Get settings with config fallback - Initialize settings for new companies - Calculate deposit amounts - Get tax rates by category - Check if features are enabled ### Helper Functions **Location:** `app/Helpers/helpers.php` Global helper functions: - `setting($name, $group, $default)` - Get any setting - `financial_setting($name, $default)` - Get financial setting (shorthand) ## Usage ### 1. Getting Settings ```php // Using the setting() helper $depositEnabled = setting('enable_deposit_payments', 'financial', false); $taxRate = setting('default_tax_rate', 'financial', 20); // Using the financial_setting() shorthand $depositEnabled = financial_setting('enable_deposit_payments', false); $taxRate = financial_setting('default_tax_rate', 20); // Using the helper class directly use App\Helpers\FinancialSettingsHelper; $depositEnabled = FinancialSettingsHelper::get('enable_deposit_payments'); $taxRate = FinancialSettingsHelper::get('default_tax_rate'); ``` ### 2. Checking if Features are Enabled ```php use App\Helpers\FinancialSettingsHelper; if (FinancialSettingsHelper::isEnabled('deposits')) { // Deposit payments are enabled } if (FinancialSettingsHelper::isEnabled('partial_payments')) { // Partial payments are enabled } if (FinancialSettingsHelper::isEnabled('dynamic_pricing')) { // Dynamic pricing is enabled } ``` ### 3. Calculating Deposit Amounts ```php use App\Helpers\FinancialSettingsHelper; $bookingTotal = 500.00; $depositAmount = FinancialSettingsHelper::calculateDepositAmount($bookingTotal); // If deposit type is 'percentage' with 30%: returns 150.00 // If deposit type is 'fixed' with 100: returns 100.00 // If deposits disabled: returns 0.00 ``` ### 4. Getting Tax Rates ```php use App\Helpers\FinancialSettingsHelper; // Get global tax rate $taxRate = FinancialSettingsHelper::getTaxRate(); // Get tax rate for specific category $accommodationTax = FinancialSettingsHelper::getTaxRate('accommodation'); $serviceTax = FinancialSettingsHelper::getTaxRate('service'); ``` ### 5. Initializing Settings for New Company ```php use App\Helpers\FinancialSettingsHelper; // When creating a new company $company = Company::create([...]); // Initialize all financial settings with defaults FinancialSettingsHelper::initializeForCompany($company->id, $workspace->id); ``` ### 6. Getting All Settings ```php use App\Helpers\FinancialSettingsHelper; // Get all settings for current company $allSettings = FinancialSettingsHelper::getAll(); // Get all settings for specific company $allSettings = FinancialSettingsHelper::getAll($companyId); ``` ## Configuration Examples ### Example 1: Beach Resort Configuration ```php // config/financial-settings.php return [ 'deposits' => [ 'enable_deposit_payments' => true, 'require_deposit_for_booking' => true, 'deposit_type' => 'percentage', 'deposit_percentage' => 50, // 50% deposit for beach spots 'deposit_due_timing' => 'immediately', ], 'tax' => [ 'default_tax_rate_type' => 'per_category', 'tax_rates_by_category' => [ ['category' => 'spot', 'tax_rate' => 20, 'description' => 'Beach spots VAT'], ['category' => 'service', 'tax_rate' => 10, 'description' => 'Services reduced rate'], ], ], 'dynamic_pricing' => [ 'enabled' => true, 'peak_hours_factor' => 1.5, // 50% increase during peak hours 'weekend_factor' => 1.3, // 30% increase on weekends ], ]; ``` ### Example 2: Hotel Configuration ```php return [ 'deposits' => [ 'enable_deposit_payments' => true, 'deposit_type' => 'fixed', 'deposit_fixed_amount' => 100.00, 'deposit_due_timing' => 'days_before', 'deposit_due_days' => 14, ], 'partial_payments' => [ 'enable_partial_payments' => true, 'partial_payment_min_installments' => 3, 'partial_payment_max_installments' => 12, 'partial_payment_schedule_type' => 'equal', ], 'security_deposit' => [ 'required' => true, 'amount' => 200.00, 'refund_processing_days' => 7, 'auto_refund' => true, ], ]; ``` ### Example 3: Service Provider Configuration ```php return [ 'deposits' => [ 'enable_deposit_payments' => false, // No deposits for services ], 'tax' => [ 'default_tax_rate_type' => 'global', 'default_tax_rate' => 0, // Tax-exempt services 'enable_tax_exemptions' => true, ], 'payment_gateway' => [ 'provider' => 'stripe', 'auto_capture_payments' => true, ], 'refunds' => [ 'refund_policy' => 'flexible', 'allow_partial_refunds' => true, ], ]; ``` ## Integration with Booking System ### In BookingController ```php use App\Helpers\FinancialSettingsHelper; public function store(Request $request) { $booking = Booking::create($request->validated()); // Check if deposit is required if (FinancialSettingsHelper::isEnabled('deposits')) { $depositAmount = FinancialSettingsHelper::calculateDepositAmount($booking->total); if (FinancialSettingsHelper::get('require_deposit_for_booking')) { $booking->status = 'pending_deposit'; $booking->deposit_required = $depositAmount; $booking->save(); } } return redirect()->route('bookings.show', $booking); } ``` ### In InvoiceService ```php use App\Helpers\FinancialSettingsHelper; public function generateInvoice(Booking $booking): Invoice { $invoice = Invoice::create([ 'booking_id' => $booking->id, 'subtotal' => $booking->subtotal, ]); // Apply tax $taxRate = FinancialSettingsHelper::getTaxRate('accommodation'); $invoice->tax_rate = $taxRate; $invoice->tax_amount = $booking->subtotal * ($taxRate / 100); // Check if tax is inclusive if (FinancialSettingsHelper::get('tax_inclusive_pricing')) { // Extract tax from total $invoice->total = $booking->subtotal; $invoice->tax_amount = $booking->subtotal - ($booking->subtotal / (1 + ($taxRate / 100))); } else { // Add tax to total $invoice->total = $booking->subtotal + $invoice->tax_amount; } $invoice->save(); return $invoice; } ``` ### In PricingService ```php use App\Helpers\FinancialSettingsHelper; public function calculatePrice(VenueSpot $spot, Carbon $date, Carbon $time): float { $basePrice = $spot->price; if (!FinancialSettingsHelper::isEnabled('dynamic_pricing')) { return $basePrice; } $price = $basePrice; // Apply weekend pricing if ($date->isWeekend()) { $factor = FinancialSettingsHelper::get('weekend_pricing_factor', 1.0); $price *= $factor; } // Apply peak hours pricing $peakStart = config('financial-settings.dynamic_pricing.peak_hours.start'); $peakEnd = config('financial-settings.dynamic_pricing.peak_hours.end'); if ($time->between($peakStart, $peakEnd)) { $factor = FinancialSettingsHelper::get('peak_hours_pricing_factor', 1.0); $price *= $factor; } return $price; } ``` ## Company Creation Hook ### In CompanyObserver or CompanySeeder ```php use App\Helpers\FinancialSettingsHelper; class CompanyObserver { public function created(Company $company) { // Initialize financial settings with defaults FinancialSettingsHelper::initializeForCompany($company->id); // Or with workspace if ($company->defaultWorkspace) { FinancialSettingsHelper::initializeForCompany( $company->id, $company->defaultWorkspace->id ); } } } ``` ## Environment Variables Some settings can be overridden via environment variables: ```env # Payment Gateway PAYMENT_GATEWAY_API_KEY=sk_test_... PAYMENT_GATEWAY_SECRET_KEY=sk_secret_... PAYMENT_GATEWAY_MODE=test PAYMENT_GATEWAY_WEBHOOK_SECRET=whsec_... # Currency Conversion CURRENCY_API_KEY=your_api_key_here ``` ## Updating Config Defaults When you need to change default values: 1. **Update config file:** ```php // config/financial-settings.php 'deposits' => [ 'deposit_percentage' => 40, // Changed from 30 ], ``` 2. **Existing companies keep their settings** (database values) 3. **New companies get new defaults** automatically 4. **To apply to existing companies:** ```php // Run in tinker or migration Company::each(function ($company) { // Only update if not customized $setting = Setting::where('company_id', $company->id) ->where('name', 'deposit_percentage') ->first(); if (!$setting) { FinancialSettingsHelper::initializeForCompany($company->id); } }); ``` ## Best Practices 1. **Always use helper functions** instead of direct database queries 2. **Provide sensible defaults** in config file 3. **Document custom settings** in company notes 4. **Test with config values** before saving to database 5. **Use feature flags** (`isEnabled()`) before applying logic 6. **Cache frequently accessed settings** if needed 7. **Validate settings** before saving to database 8. **Log setting changes** for audit trail ## Troubleshooting ### Settings not loading ```php // Clear config cache php artisan config:clear // Dump autoload composer dump-autoload ``` ### Wrong values returned ```php // Check if database has override $setting = Setting::where('name', 'deposit_percentage') ->where('company_id', session('selected_company')) ->first(); dd($setting->payload); // Database value dd(config('financial-settings.deposits.deposit_percentage')); // Config value ``` ### Initialize missing settings ```php use App\Helpers\FinancialSettingsHelper; // In tinker FinancialSettingsHelper::initializeForCompany(1); // Company ID 1 ``` ## Summary ✅ **Config file** provides defaults for all settings ✅ **Database** stores company-specific overrides ✅ **Helper class** manages fallback logic ✅ **Helper functions** provide easy access ✅ **Automatic initialization** for new companies ✅ **Feature flags** for conditional logic ✅ **Calculation helpers** for common operations ✅ **Environment variables** for sensitive data This system ensures your application always has valid financial settings, whether from database or config defaults!