Commit 108ebc7d authored by DevPilot's avatar DevPilot

fix(rentals): make the contract cycle visible on the contract page

Asked how to make a contract live, and the honest answer was that you could not
find out from the screen — so the screen now says it.

The approve card was shown only when status was exactly 'pending_approval'. A
contract created from the form lands on 'draft' (the controller even defaults to
'pending', which is not in the status list at all), so the one button that makes
a contract live was invisible on precisely the contracts that needed it. It now
appears for draft, pending and pending_approval.

Added a four-step tracker across the top — العقد اتسجّل ← اعتماد العقد ← توليد
الفواتير ← تحصيل الفاتورة — with the ticks reflecting real state and a line
naming the single next action and where its button is. Underneath it, in words:
which day of the month this contract's invoices fall due, read from the
contract's own payment_due_day rather than assumed to be the 5th, that a short
month pulls it back to the last day, and that the late fee is computed from the
due date automatically.

Invoice rows now carry a تحصيل button straight to the collection form when they
are unpaid, instead of a عرض link that gave no hint the money is taken there.

Verified rendered in draft, approved and active: the next-step line changes with
state, the due day reads from the contract, and 11 unpaid rows show تحصيل while
the paid one shows عرض.
Co-Authored-By: 's avatarClaude Opus 5 <noreply@anthropic.com>
parent 758eaebf
...@@ -255,8 +255,64 @@ $lateFeeBankRate = (float) ($contract->late_fee_bank_rate ?? 0); ...@@ -255,8 +255,64 @@ $lateFeeBankRate = (float) ($contract->late_fee_bank_rate ?? 0);
</div> </div>
<?php endif; ?> <?php endif; ?>
<!-- ── دورة العقد: فين إحنا وإيه الخطوة الجاية ─────────────── -->
<?php
$isLive = in_array($cStatus, ['approved', 'active'], true);
$hasInvoices = !empty($invoices);
$dueDay = (int) ($contract->payment_due_day ?? 5);
// Inline rather than a named function: a view can be rendered more than once
// in a request, and a second declaration would be fatal.
$anyPaid = false;
foreach (($invoices ?? []) as $inv_) {
if ((is_object($inv_) ? ($inv_->status ?? '') : ($inv_['status'] ?? '')) === 'paid') { $anyPaid = true; break; }
}
$steps = [
['n' => '١', 'label' => 'العقد اتسجّل', 'done' => true],
['n' => '٢', 'label' => 'اعتماد العقد', 'done' => $isLive],
['n' => '٣', 'label' => 'توليد فواتير الشهور','done' => $hasInvoices],
['n' => '٤', 'label' => 'تحصيل الفاتورة', 'done' => $anyPaid],
];
$next = null;
foreach ($steps as $st) { if (!$st['done']) { $next = $st['label']; break; } }
?>
<div class="card" style="margin-bottom:20px;padding:16px 20px;border-right:3px solid #0D7377;">
<div style="display:flex;gap:10px;flex-wrap:wrap;align-items:center;">
<?php foreach ($steps as $idx => $st): ?>
<div style="display:flex;align-items:center;gap:6px;padding:6px 12px;border-radius:20px;
background:<?= $st['done'] ? '#ECFDF5' : '#F3F4F6' ?>;
color:<?= $st['done'] ? '#059669' : '#6B7280' ?>;font-size:12.5px;font-weight:600;">
<span><?= $st['done'] ? '✓' : $st['n'] ?></span>
<span><?= e($st['label']) ?></span>
</div>
<?php if ($idx < count($steps) - 1): ?>
<span style="color:#D1D5DB;"></span>
<?php endif; ?>
<?php endforeach; ?>
</div>
<div style="margin-top:12px;font-size:13px;line-height:1.9;color:#374151;">
<?php if ($next): ?>
<strong>الخطوة الجاية:</strong> <?= e($next) ?>
<?php if ($next === 'اعتماد العقد'): ?>
— الزرار الأخضر تحت. من غير الاعتماد مش هتقدر تولّد فواتير.
<?php elseif ($next === 'توليد فواتير الشهور'): ?>
— زرار «توليد الفواتير» فوق. هيعمل فاتورة لكل شهر من بداية العقد لنهايته.
<?php elseif ($next === 'تحصيل الفاتورة'): ?>
— افتح أي فاتورة من الجدول تحت واضغط «تحصيل ودخول الخزنة».
<?php endif; ?>
<?php else: ?>
<strong>الدورة كاملة.</strong> باقي الفواتير بتتحصّل من الجدول تحت أول بأول.
<?php endif; ?>
<br>
<span style="color:#6B7280;">
فواتير العقد ده بتستحق يوم <strong><?= $dueDay ?></strong> من كل شهر
(من خانة «يوم استحقاق الدفع» في العقد — لو الشهر أقصر بينزل لآخر يوم فيه).
الغرامة بتتحسب لوحدها من تاريخ الاستحقاق لتاريخ الدفع الفعلي.
</span>
</div>
</div>
<!-- Action Buttons --> <!-- Action Buttons -->
<?php if ($cStatus === 'pending_approval' && can('rental.approve')): ?> <?php if (in_array($cStatus, ['draft', 'pending', 'pending_approval'], true) && can('rental.approve')): ?>
<div class="card" style="margin-bottom:20px;padding:20px;display:flex;align-items:center;gap:15px;background:#FFFBEB;border:1px solid #FDE68A;"> <div class="card" style="margin-bottom:20px;padding:20px;display:flex;align-items:center;gap:15px;background:#FFFBEB;border:1px solid #FDE68A;">
<i data-lucide="alert-circle" style="width:20px;height:20px;color:#D97706;"></i> <i data-lucide="alert-circle" style="width:20px;height:20px;color:#D97706;"></i>
<span style="font-size:14px;color:#92400E;flex:1;">هذا العقد بانتظار الاعتماد</span> <span style="font-size:14px;color:#92400E;flex:1;">هذا العقد بانتظار الاعتماد</span>
...@@ -343,8 +399,14 @@ $lateFeeBankRate = (float) ($contract->late_fee_bank_rate ?? 0); ...@@ -343,8 +399,14 @@ $lateFeeBankRate = (float) ($contract->late_fee_bank_rate ?? 0);
<?= e(RentalInvoice::getStatusLabel($iStatus)) ?> <?= e(RentalInvoice::getStatusLabel($iStatus)) ?>
</span> </span>
</td> </td>
<td style="padding:10px 16px;text-align:center;"> <td style="padding:10px 16px;text-align:center;white-space:nowrap;">
<?php if ($iStatus !== 'paid' && can('rental.manage_contract')): ?>
<a href="/rentals/invoices/<?= (int) $inv->id ?>" class="btn btn-sm btn-primary" style="font-size:12px;padding:4px 10px;">
تحصيل
</a>
<?php else: ?>
<a href="/rentals/invoices/<?= (int) $inv->id ?>" style="color:#0D7377;font-size:12px;">عرض</a> <a href="/rentals/invoices/<?= (int) $inv->id ?>" style="color:#0D7377;font-size:12px;">عرض</a>
<?php endif; ?>
</td> </td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
......
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