Issues fixed: - #161: Quote submission - add tax_rate migration (already existed) - #162: Contact edit 404 - change contact->id to contact->hashid in routes - #163: Batch creation - expand batch_type constraint to include component/homogenized - #164: Stock search - convert client-side to server-side search - #165: Product edit save button - make always visible with different states - #166: Product creation validation - make price_unit nullable with default - #167: Invoice products - change stockFilter default from true to false Additional fixes: - Fix layouts.seller (non-existent) to layouts.app-with-sidebar in 14 views - Fix CRM route names from seller.crm.* to seller.business.crm.*
157 lines
5.7 KiB
PHP
157 lines
5.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Seller;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Business;
|
|
use App\Models\BusinessMailSettings;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Validation\Rule;
|
|
|
|
class EmailSettingsController extends Controller
|
|
{
|
|
/**
|
|
* Show the email settings form.
|
|
*/
|
|
public function edit(Business $business)
|
|
{
|
|
$settings = BusinessMailSettings::getOrCreate($business);
|
|
|
|
return view('seller.settings.email', [
|
|
'business' => $business,
|
|
'settings' => $settings,
|
|
'drivers' => BusinessMailSettings::DRIVERS,
|
|
'providers' => BusinessMailSettings::PROVIDERS,
|
|
'encryptions' => BusinessMailSettings::ENCRYPTIONS,
|
|
'commonPorts' => BusinessMailSettings::COMMON_PORTS,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Update email settings.
|
|
*/
|
|
public function update(Request $request, Business $business)
|
|
{
|
|
$validated = $request->validate([
|
|
'driver' => ['required', 'string', Rule::in(array_keys(BusinessMailSettings::DRIVERS))],
|
|
'provider' => ['required', 'string', Rule::in(array_keys(BusinessMailSettings::PROVIDERS))],
|
|
'host' => ['nullable', 'string', 'max:255'],
|
|
'port' => ['nullable', 'integer', 'min:1', 'max:65535'],
|
|
'encryption' => ['nullable', 'string', Rule::in(['tls', 'ssl', ''])],
|
|
'username' => ['nullable', 'string', 'max:255'],
|
|
'password' => ['nullable', 'string', 'max:255'],
|
|
'from_name' => ['nullable', 'string', 'max:255'],
|
|
'from_email' => ['nullable', 'email', 'max:255'],
|
|
'reply_to_email' => ['nullable', 'email', 'max:255'],
|
|
'is_active' => ['boolean'],
|
|
// Postal-specific config fields
|
|
'postal_server_url' => ['nullable', 'url', 'max:255'],
|
|
'postal_webhook_secret' => ['nullable', 'string', 'max:255'],
|
|
]);
|
|
|
|
// Handle empty encryption value
|
|
if (isset($validated['encryption']) && $validated['encryption'] === '') {
|
|
$validated['encryption'] = null;
|
|
}
|
|
|
|
// Don't update password if not provided (keep existing)
|
|
if (empty($validated['password'])) {
|
|
unset($validated['password']);
|
|
}
|
|
|
|
// Build provider_config from provider-specific fields
|
|
$providerConfig = [];
|
|
if ($validated['provider'] === BusinessMailSettings::PROVIDER_POSTAL) {
|
|
if (! empty($validated['postal_server_url'])) {
|
|
$providerConfig['server_url'] = $validated['postal_server_url'];
|
|
}
|
|
if (! empty($validated['postal_webhook_secret'])) {
|
|
$providerConfig['webhook_secret'] = $validated['postal_webhook_secret'];
|
|
}
|
|
}
|
|
$validated['provider_config'] = ! empty($providerConfig) ? $providerConfig : null;
|
|
|
|
// Remove provider-specific fields from main validated array
|
|
unset($validated['postal_server_url'], $validated['postal_webhook_secret']);
|
|
|
|
$settings = BusinessMailSettings::getOrCreate($business);
|
|
$settings->update($validated);
|
|
|
|
return redirect()
|
|
->route('seller.business.settings.email', $business->slug)
|
|
->with('success', 'Email settings updated successfully.');
|
|
}
|
|
|
|
/**
|
|
* Test the email connection.
|
|
*/
|
|
public function test(Request $request, Business $business)
|
|
{
|
|
$settings = BusinessMailSettings::forBusiness($business);
|
|
|
|
if (! $settings || ! $settings->isConfigured()) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Email settings are not fully configured.',
|
|
], 400);
|
|
}
|
|
|
|
try {
|
|
// For now, just validate the configuration and log
|
|
// In the future, we'll actually test the SMTP connection
|
|
$this->validateMailConfig($settings);
|
|
|
|
// Log the test attempt
|
|
Log::info('Email settings test initiated', [
|
|
'business_id' => $business->id,
|
|
'driver' => $settings->driver,
|
|
'host' => $settings->host,
|
|
'port' => $settings->port,
|
|
]);
|
|
|
|
// Record successful test (stub - no actual connection yet)
|
|
$settings->recordTestResult(true, 'Configuration validated successfully');
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Configuration appears valid. Connection test will be available soon.',
|
|
]);
|
|
|
|
} catch (\Exception $e) {
|
|
$settings->recordTestResult(false, $e->getMessage());
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => $e->getMessage(),
|
|
], 400);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Validate mail configuration without actually connecting.
|
|
*/
|
|
private function validateMailConfig(BusinessMailSettings $settings): void
|
|
{
|
|
if ($settings->driver === BusinessMailSettings::DRIVER_SMTP) {
|
|
if (empty($settings->host)) {
|
|
throw new \InvalidArgumentException('SMTP host is required.');
|
|
}
|
|
|
|
if (empty($settings->port)) {
|
|
throw new \InvalidArgumentException('SMTP port is required.');
|
|
}
|
|
|
|
// Validate port is in reasonable range
|
|
if ($settings->port < 1 || $settings->port > 65535) {
|
|
throw new \InvalidArgumentException('Invalid port number.');
|
|
}
|
|
}
|
|
|
|
// Validate from email format
|
|
if (! empty($settings->from_email) && ! filter_var($settings->from_email, FILTER_VALIDATE_EMAIL)) {
|
|
throw new \InvalidArgumentException('Invalid from email address.');
|
|
}
|
|
}
|
|
}
|