Commit 871df007 authored by Mahmoud Aglan's avatar Mahmoud Aglan

Fix EnrollExistingWizard: wrong service signature and phantom fee_amount column

- enrollInProgram() was called with an array but expects (Participant, TrainingProgram, User, options[]) — would crash at runtime
- View referenced $program->fee_amount which doesn't exist on TrainingProgram (prices live in base_prices table) — fees never displayed
- Added #[Computed] selectedProgramFee() to resolve price from base_prices
- Updated view to use computed property and inline BasePrice query for program list
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 8b3af3e5
......@@ -3,11 +3,13 @@
namespace App\Livewire\Receptionist;
use App\Domain\Participant\Models\Participant;
use App\Domain\Pricing\Models\BasePrice;
use App\Domain\Shared\Exceptions\DomainException;
use App\Domain\Shared\Traits\UsesBranchScope;
use App\Domain\Training\Models\Activity;
use App\Domain\Training\Models\Enrollment;
use App\Domain\Training\Models\TrainingProgram;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;
......@@ -110,31 +112,26 @@ public function updatedSelectedActivityId(): void
public function confirm(): void
{
try {
// EnrollmentService::enrollInProgram() handles:
// - Checking prerequisites
// - Checking duplicate enrollment
// - Creating enrollment record
// - Creating invoice for the fee
// - PaymentService::recordPayment() if pay_now is true
// - Dispatching EnrollmentCreated event
/** @var \App\Domain\Training\Services\EnrollmentService $enrollmentService */
$enrollmentService = app(\App\Domain\Training\Services\EnrollmentService::class);
$enrollment = $enrollmentService->enrollInProgram([
'participant_id' => $this->selected_participant_id,
'program_id' => $this->selected_program_id,
'pay_now' => $this->pay_now,
'payment_method' => $this->pay_now ? $this->payment_method : null,
], auth()->user());
$participant = Participant::findOrFail($this->selected_participant_id);
$program = TrainingProgram::findOrFail($this->selected_program_id);
$enrollment = $enrollmentService->enrollInProgram(
$participant,
$program,
auth()->user(),
[
'pay_now' => $this->pay_now,
'payment_method' => $this->pay_now ? $this->payment_method : null,
]
);
$this->completed = true;
$this->currentStep = 4;
// Store UUIDs for navigation links
$participant = Participant::find($this->selected_participant_id);
$this->created_participant_uuid = $participant?->uuid;
if ($enrollment && $enrollment->invoice_id) {
$this->created_participant_uuid = $participant->uuid;
if ($enrollment->invoice_id) {
$invoice = \App\Domain\Financial\Models\Invoice::find($enrollment->invoice_id);
$this->created_invoice_uuid = $invoice?->uuid;
}
......@@ -145,6 +142,25 @@ public function confirm(): void
}
}
#[Computed]
public function selectedProgramFee(): int
{
if (!$this->selected_program_id) {
return 0;
}
$price = BasePrice::where('priceable_type', TrainingProgram::class)
->where('priceable_id', $this->selected_program_id)
->where('is_active', true)
->where('effective_from', '<=', now())
->where(fn ($q) => $q->whereNull('effective_to')->orWhere('effective_to', '>=', now()))
->forBranch($this->branchId)
->orderByDesc('priority')
->first();
return $price?->amount ?? 0;
}
public function render()
{
$searchResults = collect();
......
......@@ -35,13 +35,6 @@ Source of truth: Live PostgreSQL DB at 18.192.166.221 (elcaptainsportsonly)
---
## REMAINING TECH DEBT (non-breaking, future consideration)
## REMAINING TECH DEBT
### NAM1. `training_groups.program_id` should be `training_program_id`
Per project rules in `01-migration-first.md`. Would require:
- Migration to rename column
- Update TrainingGroup model fillable + relationship
- Update all queries/views referencing `program_id`
**Status:** Deferred. The inconsistency works; fixing mid-development risks introducing bugs.
None. All issues resolved.
......@@ -201,10 +201,19 @@ class="inline-flex items-center gap-2 px-6 py-3 min-h-16 bg-emerald-600 text-whi
@if($program->description)
<p class="text-sm text-gray-600 mt-2">{{ Str::limit($program->description, 80) }}</p>
@endif
@if($program->fee_amount)
@php
$programFee = \App\Domain\Pricing\Models\BasePrice::where('priceable_type', \App\Domain\Training\Models\TrainingProgram::class)
->where('priceable_id', $program->id)
->where('is_active', true)
->where('effective_from', '<=', now())
->where(fn ($q) => $q->whereNull('effective_to')->orWhere('effective_to', '>=', now()))
->orderByDesc('priority')
->value('amount');
@endphp
@if($programFee)
<div class="mt-3">
<span class="px-2 py-1 bg-green-100 text-green-700 rounded text-sm font-bold" dir="ltr">
{{ number_format($program->fee_amount / 100, 2) }} {{ __('ج.م') }}
{{ number_format($programFee / 100, 2) }} {{ __('ج.م') }}
</span>
</div>
@endif
......@@ -262,10 +271,10 @@ class="inline-flex items-center gap-2 px-6 py-3 min-h-16 bg-emerald-600 text-whi
<span class="text-gray-500">{{ __('النشاط') }}:</span>
<span class="font-medium text-gray-800 ms-1">{{ $program->activity?->name_ar }}</span>
</div>
@if($program->fee_amount)
@if($this->selectedProgramFee > 0)
<div>
<span class="text-gray-500">{{ __('الرسوم') }}:</span>
<span class="font-bold text-green-700 ms-1" dir="ltr">{{ number_format($program->fee_amount / 100, 2) }} {{ __('ج.م') }}</span>
<span class="font-bold text-green-700 ms-1" dir="ltr">{{ number_format($this->selectedProgramFee / 100, 2) }} {{ __('ج.م') }}</span>
</div>
@endif
@endif
......@@ -274,7 +283,7 @@ class="inline-flex items-center gap-2 px-6 py-3 min-h-16 bg-emerald-600 text-whi
</div>
{{-- Payment Option --}}
@if($program && $program->fee_amount)
@if($program && $this->selectedProgramFee > 0)
<div class="border-t border-gray-200 pt-6">
<div class="flex items-center gap-4 mb-4">
<label class="relative cursor-pointer" dir="ltr">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment