add sms sending feat
This commit is contained in:
@@ -4,6 +4,7 @@ namespace Modules\Identity\Filament\Pages;
|
||||
|
||||
use BackedEnum;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\TagsInput;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Filament\Notifications\Notification;
|
||||
@@ -12,6 +13,7 @@ use Filament\Schemas\Components\Actions;
|
||||
use Filament\Schemas\Components\Form;
|
||||
use Filament\Schemas\Components\Tabs;
|
||||
use Filament\Schemas\Components\Tabs\Tab;
|
||||
use Filament\Schemas\Components\Utilities\Get;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
@@ -61,6 +63,11 @@ class ManageAppSettings extends Page
|
||||
'back_seat_enabled' => (bool) config('booking.back_seat_enabled'),
|
||||
'whole_vehicle_enabled' => (bool) config('booking.whole_vehicle_enabled'),
|
||||
'front_seat_max_per_booking' => config('booking.front_seat_max_per_booking'),
|
||||
'booking_admin_emails' => config('booking.admin_emails'),
|
||||
'sms_enabled' => (bool) config('services.sms.enabled'),
|
||||
'sms_server' => config('services.sms.sms_poh.server'),
|
||||
'sms_token' => config('services.sms.sms_poh.token'),
|
||||
'sms_sender' => config('services.sms.sms_poh.sender'),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -111,7 +118,34 @@ class ManageAppSettings extends Page
|
||||
->minValue(1)
|
||||
->required()
|
||||
->helperText('Max Front Seats a single booking may request.'),
|
||||
TagsInput::make('booking_admin_emails')
|
||||
->label('Admin Emails')
|
||||
->required()
|
||||
->helperText('Notified on booking events. Press enter after each address.'),
|
||||
]),
|
||||
Tab::make('SMS')
|
||||
->schema([
|
||||
Toggle::make('sms_enabled')
|
||||
->label('SMS Enabled')
|
||||
->live()
|
||||
->helperText('Whether driver/car SMS notifications are sent at all.'),
|
||||
TextInput::make('sms_server')
|
||||
->label('SMS Server URL')
|
||||
->url()
|
||||
->maxLength(255)
|
||||
->required(fn (Get $get): bool => (bool) $get('sms_enabled')),
|
||||
TextInput::make('sms_token')
|
||||
->label('SMS Token')
|
||||
->password()
|
||||
->revealable()
|
||||
->maxLength(255)
|
||||
->required(fn (Get $get): bool => (bool) $get('sms_enabled')),
|
||||
TextInput::make('sms_sender')
|
||||
->label('SMS Sender')
|
||||
->maxLength(255)
|
||||
->helperText('Default sender name/number for outgoing SMS.'),
|
||||
])
|
||||
->columns(2),
|
||||
]),
|
||||
])
|
||||
->livewireSubmitHandler('save')
|
||||
@@ -139,6 +173,11 @@ class ManageAppSettings extends Page
|
||||
'BOOKING_BACK_SEAT_ENABLED' => (bool) $state['back_seat_enabled'],
|
||||
'BOOKING_WHOLE_VEHICLE_ENABLED' => (bool) $state['whole_vehicle_enabled'],
|
||||
'BOOKING_FRONT_SEAT_MAX_PER_BOOKING' => (int) $state['front_seat_max_per_booking'],
|
||||
'BOOKING_ADMIN_EMAILS' => implode(',', $state['booking_admin_emails'] ?? []),
|
||||
'SMS_ENABLED' => (bool) $state['sms_enabled'],
|
||||
'SMS_SERVER' => $state['sms_server'],
|
||||
'SMS_TOKEN' => $state['sms_token'],
|
||||
'SMS_SENDER' => $state['sms_sender'],
|
||||
]);
|
||||
|
||||
Artisan::call('config:clear');
|
||||
|
||||
@@ -28,6 +28,37 @@ test('a booking status transition is recorded in the audit log', function () {
|
||||
expect($activity->attribute_changes->get('attributes'))->toMatchArray(['status' => BookingStatus::Confirmed->value]);
|
||||
});
|
||||
|
||||
test('assigning a driver is recorded in the audit log with who and when', function () {
|
||||
$dispatcher = User::factory()->create();
|
||||
$booking = Booking::factory()->create(['status' => BookingStatus::Confirmed]);
|
||||
|
||||
$this->actingAs($dispatcher);
|
||||
|
||||
$booking->update([
|
||||
'driver_name' => 'U Aung',
|
||||
'driver_phone' => '+959111222333',
|
||||
'car_plate_number' => 'YGN-1234',
|
||||
'car_model' => 'Tesla Model Y',
|
||||
]);
|
||||
|
||||
$activity = Activity::where('subject_type', Booking::class)
|
||||
->where('subject_id', $booking->id)
|
||||
->where('log_name', 'booking')
|
||||
->latest('id')
|
||||
->first();
|
||||
|
||||
expect($activity)->not->toBeNull();
|
||||
expect($activity->attribute_changes->get('attributes'))->toMatchArray([
|
||||
'driver_name' => 'U Aung',
|
||||
'driver_phone' => '+959111222333',
|
||||
'car_plate_number' => 'YGN-1234',
|
||||
'car_model' => 'Tesla Model Y',
|
||||
]);
|
||||
expect($activity->causer_type)->toBe(User::class);
|
||||
expect($activity->causer_id)->toBe($dispatcher->id);
|
||||
expect($activity->created_at)->not->toBeNull();
|
||||
});
|
||||
|
||||
test('a catalog CRUD write is recorded in the audit log', function () {
|
||||
$company = EvCompany::factory()->create(['name' => 'Original Name']);
|
||||
|
||||
|
||||
@@ -43,6 +43,11 @@ test('a super_admin can view and save app settings, writing them to .env', funct
|
||||
'back_seat_enabled' => false,
|
||||
'whole_vehicle_enabled' => true,
|
||||
'front_seat_max_per_booking' => 2,
|
||||
'booking_admin_emails' => ['ops@evbooking.test', 'dispatch@evbooking.test'],
|
||||
'sms_enabled' => true,
|
||||
'sms_server' => 'https://sms.example.test/send',
|
||||
'sms_token' => 'secret-token',
|
||||
'sms_sender' => 'EVBooking',
|
||||
])
|
||||
->call('save')
|
||||
->assertHasNoFormErrors();
|
||||
@@ -56,7 +61,23 @@ test('a super_admin can view and save app settings, writing them to .env', funct
|
||||
->toContain('APP_CURRENCY=MMK')
|
||||
->toContain('BOOKING_BACK_SEAT_ENABLED=false')
|
||||
->toContain('BOOKING_WHOLE_VEHICLE_ENABLED=true')
|
||||
->toContain('BOOKING_FRONT_SEAT_MAX_PER_BOOKING=2');
|
||||
->toContain('BOOKING_FRONT_SEAT_MAX_PER_BOOKING=2')
|
||||
->toContain('BOOKING_ADMIN_EMAILS=ops@evbooking.test,dispatch@evbooking.test')
|
||||
->toContain('SMS_ENABLED=true')
|
||||
->toContain('SMS_SERVER=https://sms.example.test/send')
|
||||
->toContain('SMS_TOKEN=secret-token')
|
||||
->toContain('SMS_SENDER=EVBooking');
|
||||
});
|
||||
|
||||
test('sms server and token are required once sms is enabled', function () {
|
||||
$superAdmin = User::factory()->create();
|
||||
$superAdmin->assignRole('super_admin');
|
||||
$this->actingAs($superAdmin);
|
||||
|
||||
Livewire::test(ManageAppSettings::class)
|
||||
->fillForm(['sms_enabled' => true, 'sms_server' => '', 'sms_token' => ''])
|
||||
->call('save')
|
||||
->assertHasFormErrors(['sms_server', 'sms_token']);
|
||||
});
|
||||
|
||||
test('front seat max per booking must be at least 1', function () {
|
||||
|
||||
Reference in New Issue
Block a user