added set free/paid consultation to the quick approve
This commit is contained in:
parent
c1cc24c78d
commit
0dfb2a8759
|
|
@ -22,6 +22,13 @@ new class extends Component
|
||||||
public string $dateFrom = '';
|
public string $dateFrom = '';
|
||||||
public string $dateTo = '';
|
public string $dateTo = '';
|
||||||
|
|
||||||
|
// Quick approve modal state
|
||||||
|
public bool $showApproveModal = false;
|
||||||
|
public ?int $approvingBookingId = null;
|
||||||
|
public string $consultationType = 'free';
|
||||||
|
public ?string $paymentAmount = null;
|
||||||
|
public string $paymentInstructions = '';
|
||||||
|
|
||||||
public function updatedDateFrom(): void
|
public function updatedDateFrom(): void
|
||||||
{
|
{
|
||||||
$this->resetPage();
|
$this->resetPage();
|
||||||
|
|
@ -39,22 +46,40 @@ new class extends Component
|
||||||
$this->resetPage();
|
$this->resetPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function quickApprove(int $id): void
|
public function openApproveModal(int $id): void
|
||||||
{
|
{
|
||||||
$consultation = Consultation::with('user')->findOrFail($id);
|
$this->approvingBookingId = $id;
|
||||||
|
$this->consultationType = 'free';
|
||||||
|
$this->paymentAmount = null;
|
||||||
|
$this->paymentInstructions = '';
|
||||||
|
$this->showApproveModal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function quickApprove(): void
|
||||||
|
{
|
||||||
|
$consultation = Consultation::with('user')->findOrFail($this->approvingBookingId);
|
||||||
|
|
||||||
if ($consultation->status !== ConsultationStatus::Pending) {
|
if ($consultation->status !== ConsultationStatus::Pending) {
|
||||||
session()->flash('error', __('admin.booking_already_processed'));
|
session()->flash('error', __('admin.booking_already_processed'));
|
||||||
|
$this->showApproveModal = false;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->validate([
|
||||||
|
'consultationType' => ['required', 'in:free,paid'],
|
||||||
|
'paymentAmount' => ['required_if:consultationType,paid', 'nullable', 'numeric', 'min:0'],
|
||||||
|
'paymentInstructions' => ['nullable', 'string', 'max:1000'],
|
||||||
|
]);
|
||||||
|
|
||||||
$oldStatus = $consultation->status->value;
|
$oldStatus = $consultation->status->value;
|
||||||
|
$type = $this->consultationType === 'paid' ? ConsultationType::Paid : ConsultationType::Free;
|
||||||
|
|
||||||
$consultation->update([
|
$consultation->update([
|
||||||
'status' => ConsultationStatus::Approved,
|
'status' => ConsultationStatus::Approved,
|
||||||
'consultation_type' => ConsultationType::Free,
|
'consultation_type' => $type,
|
||||||
'payment_status' => PaymentStatus::NotApplicable,
|
'payment_amount' => $type === ConsultationType::Paid ? $this->paymentAmount : null,
|
||||||
|
'payment_status' => $type === ConsultationType::Paid ? PaymentStatus::Pending : PaymentStatus::NotApplicable,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Generate calendar file and send notification
|
// Generate calendar file and send notification
|
||||||
|
|
@ -74,12 +99,13 @@ new class extends Component
|
||||||
Mail::to($consultation->guest_email)->queue(
|
Mail::to($consultation->guest_email)->queue(
|
||||||
new GuestBookingApprovedMail(
|
new GuestBookingApprovedMail(
|
||||||
$consultation,
|
$consultation,
|
||||||
app()->getLocale()
|
app()->getLocale(),
|
||||||
|
$this->paymentInstructions ?: null
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} elseif ($consultation->user) {
|
} elseif ($consultation->user) {
|
||||||
$consultation->user->notify(
|
$consultation->user->notify(
|
||||||
new BookingApproved($consultation, $icsContent ?? '', null)
|
new BookingApproved($consultation, $icsContent ?? '', $this->paymentInstructions ?: null)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,12 +118,14 @@ new class extends Component
|
||||||
'old_values' => ['status' => $oldStatus],
|
'old_values' => ['status' => $oldStatus],
|
||||||
'new_values' => [
|
'new_values' => [
|
||||||
'status' => ConsultationStatus::Approved->value,
|
'status' => ConsultationStatus::Approved->value,
|
||||||
'consultation_type' => ConsultationType::Free->value,
|
'consultation_type' => $type->value,
|
||||||
|
'payment_amount' => $this->paymentAmount,
|
||||||
],
|
],
|
||||||
'ip_address' => request()->ip(),
|
'ip_address' => request()->ip(),
|
||||||
'created_at' => now(),
|
'created_at' => now(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->showApproveModal = false;
|
||||||
session()->flash('success', __('admin.booking_approved'));
|
session()->flash('success', __('admin.booking_approved'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -259,8 +287,7 @@ new class extends Component
|
||||||
</flux:button>
|
</flux:button>
|
||||||
|
|
||||||
<flux:button
|
<flux:button
|
||||||
wire:click="quickApprove({{ $booking->id }})"
|
wire:click="openApproveModal({{ $booking->id }})"
|
||||||
wire:confirm="{{ __('admin.confirm_quick_approve') }}"
|
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
class="!bg-emerald-600 !text-white hover:!bg-emerald-700"
|
class="!bg-emerald-600 !text-white hover:!bg-emerald-700"
|
||||||
|
|
@ -290,4 +317,52 @@ new class extends Component
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
{{ $bookings->links() }}
|
{{ $bookings->links() }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Approve Modal -->
|
||||||
|
<flux:modal wire:model="showApproveModal">
|
||||||
|
<div class="space-y-6">
|
||||||
|
<flux:heading size="lg">{{ __('admin.approve_booking') }}</flux:heading>
|
||||||
|
|
||||||
|
<!-- Consultation Type -->
|
||||||
|
<flux:field>
|
||||||
|
<flux:label>{{ __('admin.consultation_type') }}</flux:label>
|
||||||
|
<flux:radio.group wire:model.live="consultationType">
|
||||||
|
<flux:radio value="free" label="{{ __('admin.free_consultation') }}" />
|
||||||
|
<flux:radio value="paid" label="{{ __('admin.paid_consultation') }}" />
|
||||||
|
</flux:radio.group>
|
||||||
|
</flux:field>
|
||||||
|
|
||||||
|
<!-- Payment Amount (if paid) -->
|
||||||
|
@if($consultationType === 'paid')
|
||||||
|
<flux:field>
|
||||||
|
<flux:label>{{ __('admin.payment_amount') }} *</flux:label>
|
||||||
|
<flux:input
|
||||||
|
type="number"
|
||||||
|
wire:model="paymentAmount"
|
||||||
|
step="0.01"
|
||||||
|
min="0"
|
||||||
|
/>
|
||||||
|
<flux:error name="paymentAmount" />
|
||||||
|
</flux:field>
|
||||||
|
|
||||||
|
<flux:field>
|
||||||
|
<flux:label>{{ __('admin.payment_instructions') }}</flux:label>
|
||||||
|
<flux:textarea
|
||||||
|
wire:model="paymentInstructions"
|
||||||
|
rows="3"
|
||||||
|
placeholder="{{ __('admin.payment_instructions_placeholder') }}"
|
||||||
|
/>
|
||||||
|
</flux:field>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="flex gap-3 justify-end">
|
||||||
|
<flux:button wire:click="$set('showApproveModal', false)">
|
||||||
|
{{ __('common.cancel') }}
|
||||||
|
</flux:button>
|
||||||
|
<flux:button variant="primary" wire:click="quickApprove">
|
||||||
|
{{ __('admin.approve') }}
|
||||||
|
</flux:button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</flux:modal>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,11 @@ test('quick approve from list works', function () {
|
||||||
$this->actingAs($admin);
|
$this->actingAs($admin);
|
||||||
|
|
||||||
Volt::test('admin.bookings.pending')
|
Volt::test('admin.bookings.pending')
|
||||||
->call('quickApprove', $consultation->id)
|
->call('openApproveModal', $consultation->id)
|
||||||
|
->assertSet('showApproveModal', true)
|
||||||
|
->assertSet('approvingBookingId', $consultation->id)
|
||||||
|
->set('consultationType', 'free')
|
||||||
|
->call('quickApprove')
|
||||||
->assertHasNoErrors();
|
->assertHasNoErrors();
|
||||||
|
|
||||||
expect($consultation->fresh())
|
expect($consultation->fresh())
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,11 @@ test('admin can quick approve guest booking from pending list', function () {
|
||||||
$this->actingAs($admin);
|
$this->actingAs($admin);
|
||||||
|
|
||||||
Volt::test('admin.bookings.pending')
|
Volt::test('admin.bookings.pending')
|
||||||
->call('quickApprove', $consultation->id)
|
->call('openApproveModal', $consultation->id)
|
||||||
|
->assertSet('showApproveModal', true)
|
||||||
|
->assertSet('approvingBookingId', $consultation->id)
|
||||||
|
->set('consultationType', 'free')
|
||||||
|
->call('quickApprove')
|
||||||
->assertHasNoErrors();
|
->assertHasNoErrors();
|
||||||
|
|
||||||
expect($consultation->fresh()->status)->toBe(ConsultationStatus::Approved);
|
expect($consultation->fresh()->status)->toBe(ConsultationStatus::Approved);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue