Commit 808c63d1 authored by DevPilot's avatar DevPilot

fix(rentals): contract page fataled for every approved contract

I broke this. The page-actions block reads $gracePeriod to build the
bulk-generate confirmation, but $gracePeriod was computed inside the content
block — and page_actions renders first, so the variable did not exist yet.
Production turns that notice into a fatal, so the contract page died outright.

It had always been wrong; it was simply unreachable, because the guard above it
requires status approved or active and until yesterday no contract could reach
those states (the approve button was hidden on drafts). Making approval possible
made the broken path reachable, and I shipped it without exercising the page in
the state I had just unlocked.

The shared variables now sit above both sections, which is where anything either
section needs has to be.

Why the test missed it: I was piping render output through `grep -v Warning:`,
which filtered out the exact notice that is fatal in production. The check now
installs an error handler that promotes every notice to an exception — the same
thing ExceptionHandler does — and renders the contract page in all eight
statuses and the invoice page in all three. All pass.
Co-Authored-By: 's avatarClaude Opus 5 <noreply@anthropic.com>
parent 108ebc7d
...@@ -3,6 +3,24 @@ use App\Modules\Rentals\Models\RentalContract; ...@@ -3,6 +3,24 @@ use App\Modules\Rentals\Models\RentalContract;
use App\Modules\Rentals\Models\RentalInvoice; use App\Modules\Rentals\Models\RentalInvoice;
use App\Modules\Rentals\Services\RentalInvoiceService; use App\Modules\Rentals\Services\RentalInvoiceService;
$__template->layout('Layout.main'); $__template->layout('Layout.main');
// Computed before any section. `page_actions` renders BEFORE `content`, so a
// variable defined inside the content block is undefined by the time the
// header buttons are built — which is how $gracePeriod fataled the page for
// every approved contract.
$cStatus = $contract->status ?? 'draft';
$depositStatus = $contract->deposit_status ?? 'pending';
$activityTypes = ['practice' => 'تدريب', 'competitive' => 'تنافسي'];
$timeTiers = ['AM' => 'صباحي', 'PM' => 'مسائي'];
$lateFeeTypes = ['none' => 'لا يوجد', 'daily' => 'يومي', 'weekly' => 'أسبوعي', 'monthly' => 'شهري'];
$escalationTypes = RentalContract::getEscalationTypes();
$utilitiesModes = RentalContract::getUtilitiesModes();
$escType = $contract->escalation_type ?? 'none';
$utilitiesMode = $contract->utilities_mode ?? 'rent_pct';
$gracePeriod = (int) ($contract->grace_period_months ?? 0);
$earlyTerm = (int) ($contract->early_termination_months ?? 0);
$paymentDueDay = (int) ($contract->payment_due_day ?? 5);
$lateFeeBankRate = (float) ($contract->late_fee_bank_rate ?? 0);
?> ?>
<?php $__template->section('title'); ?><?= e($contract->contract_number) ?><?php $__template->endSection(); ?> <?php $__template->section('title'); ?><?= e($contract->contract_number) ?><?php $__template->endSection(); ?>
...@@ -29,21 +47,6 @@ if ($gracePeriod > 0) { ...@@ -29,21 +47,6 @@ if ($gracePeriod > 0) {
<?php $__template->section('content'); ?> <?php $__template->section('content'); ?>
<?php
$cStatus = $contract->status ?? 'draft';
$depositStatus = $contract->deposit_status ?? 'pending';
$activityTypes = ['practice' => 'تدريب', 'competitive' => 'تنافسي'];
$timeTiers = ['AM' => 'صباحي', 'PM' => 'مسائي'];
$lateFeeTypes = ['none' => 'لا يوجد', 'daily' => 'يومي', 'weekly' => 'أسبوعي', 'monthly' => 'شهري'];
$escalationTypes = RentalContract::getEscalationTypes();
$utilitiesModes = RentalContract::getUtilitiesModes();
$escType = $contract->escalation_type ?? 'none';
$utilitiesMode = $contract->utilities_mode ?? 'rent_pct';
$gracePeriod = (int) ($contract->grace_period_months ?? 0);
$earlyTerm = (int) ($contract->early_termination_months ?? 0);
$paymentDueDay = (int) ($contract->payment_due_day ?? 5);
$lateFeeBankRate = (float) ($contract->late_fee_bank_rate ?? 0);
?>
<!-- Header --> <!-- Header -->
<div class="card" style="margin-bottom:20px;padding:20px;"> <div class="card" style="margin-bottom:20px;padding:20px;">
......
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