Commit f00b5c97 authored by Mahmoud Aglan's avatar Mahmoud Aglan

Add 3% platform fee to wizard invoice + printable invoice on success

- Invoice now includes service_fee_amount via PlatformFeeService (3% env-configurable)
- Review step and payment step both show fee breakdown (subtotal + service fee = total)
- Payment records the full total (including fee), not just the program price
- Success screen shows a proper printable invoice with items table, totals breakdown,
  payment status badge, and a print button that hides nav/sidebar
- Stores invoiceId for the computed invoiceForPrint property
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent c8ba2296
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace App\Livewire\Receptionist; namespace App\Livewire\Receptionist;
use App\Domain\Financial\Models\Invoice;
use App\Domain\Financial\Services\InvoiceService; use App\Domain\Financial\Services\InvoiceService;
use App\Domain\Financial\Services\PaymentService; use App\Domain\Financial\Services\PaymentService;
use App\Domain\Identity\Models\Branch; use App\Domain\Identity\Models\Branch;
...@@ -13,6 +14,7 @@ ...@@ -13,6 +14,7 @@
use App\Domain\Participant\Services\ParticipantService; use App\Domain\Participant\Services\ParticipantService;
use App\Domain\Pricing\Models\BasePrice; use App\Domain\Pricing\Models\BasePrice;
use App\Domain\Shared\Exceptions\DomainException; use App\Domain\Shared\Exceptions\DomainException;
use App\Domain\Shared\Services\PlatformFeeService;
use App\Domain\Shared\Traits\UsesBranchScope; use App\Domain\Shared\Traits\UsesBranchScope;
use App\Domain\Training\Models\Activity; use App\Domain\Training\Models\Activity;
use App\Domain\Training\Models\TrainingProgram; use App\Domain\Training\Models\TrainingProgram;
...@@ -70,6 +72,7 @@ class NewRegistrationWizard extends Component ...@@ -70,6 +72,7 @@ class NewRegistrationWizard extends Component
public ?string $enrollment_summary = null; public ?string $enrollment_summary = null;
public ?int $invoice_amount = null; public ?int $invoice_amount = null;
public ?string $invoice_number = null; public ?string $invoice_number = null;
public ?int $invoiceId = null;
public bool $payment_recorded = false; public bool $payment_recorded = false;
// Pre-flight errors — blocks wizard from starting // Pre-flight errors — blocks wizard from starting
...@@ -351,8 +354,11 @@ public function confirm(): void ...@@ -351,8 +354,11 @@ public function confirm(): void
$actor $actor
); );
// 7. Look up the price for this program // 7. Look up the price for this program + calculate platform fee
$feeAmount = $this->resolveProgramFee($program); $feeAmount = $this->resolveProgramFee($program);
$platformFeeService = app(PlatformFeeService::class);
$serviceFee = $platformFeeService->calculate($feeAmount);
$totalWithFee = $feeAmount + $serviceFee;
// 8. Create invoice if there's a fee // 8. Create invoice if there's a fee
$invoice = null; $invoice = null;
...@@ -368,7 +374,8 @@ public function confirm(): void ...@@ -368,7 +374,8 @@ public function confirm(): void
'subtotal_amount' => $feeAmount, 'subtotal_amount' => $feeAmount,
'discount_amount' => 0, 'discount_amount' => 0,
'tax_amount' => 0, 'tax_amount' => 0,
'total_amount' => $feeAmount, 'service_fee_amount' => $serviceFee,
'total_amount' => $totalWithFee,
'currency' => 'EGP', 'currency' => 'EGP',
'issue_date' => now()->toDateString(), 'issue_date' => now()->toDateString(),
'due_date' => now()->addDays(7)->toDateString(), 'due_date' => now()->addDays(7)->toDateString(),
...@@ -389,8 +396,9 @@ public function confirm(): void ...@@ -389,8 +396,9 @@ public function confirm(): void
// Link enrollment to invoice // Link enrollment to invoice
$enrollment->update(['invoice_id' => $invoice->id]); $enrollment->update(['invoice_id' => $invoice->id]);
$this->invoice_amount = $feeAmount; $this->invoice_amount = $invoice->total_amount;
$this->invoice_number = $invoice->number; $this->invoice_number = $invoice->number;
$this->invoiceId = $invoice->id;
// 9. Record payment if paying now // 9. Record payment if paying now
if ($this->pay_now) { if ($this->pay_now) {
...@@ -403,7 +411,7 @@ public function confirm(): void ...@@ -403,7 +411,7 @@ public function confirm(): void
'method' => $this->payment_method, 'method' => $this->payment_method,
'payer_type' => Participant::class, 'payer_type' => Participant::class,
'payer_id' => $participant->id, 'payer_id' => $participant->id,
'amount' => $feeAmount, 'amount' => $invoice->total_amount,
'currency' => 'EGP', 'currency' => 'EGP',
'payment_date' => now()->toDateString(), 'payment_date' => now()->toDateString(),
'notes' => 'دفع اشتراك: ' . $program->name_ar, 'notes' => 'دفع اشتراك: ' . $program->name_ar,
...@@ -479,6 +487,24 @@ public function getSelectedProgramFeeProperty(): int ...@@ -479,6 +487,24 @@ public function getSelectedProgramFeeProperty(): int
return $program ? $this->resolveProgramFee($program) : 0; return $program ? $this->resolveProgramFee($program) : 0;
} }
public function getPlatformFeeProperty(): int
{
return app(PlatformFeeService::class)->calculate($this->selectedProgramFee);
}
public function getTotalWithFeeProperty(): int
{
return $this->selectedProgramFee + $this->platformFee;
}
public function getInvoiceForPrintProperty(): ?Invoice
{
if (!$this->invoiceId) {
return null;
}
return Invoice::with('items')->find($this->invoiceId);
}
public function render() public function render()
{ {
$activities = Activity::where('is_active', true)->orderBy('name_ar')->get(); $activities = Activity::where('is_active', true)->orderBy('name_ar')->get();
......
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