108 lines
3.8 KiB
PHP
108 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\User;
|
|
use App\Services\LatePenaltyService;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Console\Command;
|
|
use Morilog\Jalali\Jalalian;
|
|
|
|
class SendMonthlyLateReport extends Command
|
|
{
|
|
protected $signature = 'late:monthly-report {--date=}';
|
|
|
|
protected $description = 'Send monthly late-penalty report to admins via Bale';
|
|
|
|
public function handle(LatePenaltyService $service): int
|
|
{
|
|
$forcedDate = $this->option('date');
|
|
|
|
// پیشفرض: ماه شمسیِ دیروز (برای اجرای روز اول ماه بعد)
|
|
$anchor = $forcedDate
|
|
? Carbon::parse($forcedDate)
|
|
: Carbon::yesterday();
|
|
|
|
// بدون --date فقط وقتی دیروز آخرین روز ماه شمسی بوده اجرا شود
|
|
if (!$forcedDate) {
|
|
$jYesterday = Jalalian::fromCarbon($anchor);
|
|
$daysInMonth = $jYesterday->getMonth() <= 6
|
|
? 31
|
|
: ($jYesterday->getMonth() <= 11 ? 30 : ($jYesterday->isLeapYear() ? 30 : 29));
|
|
|
|
if ($jYesterday->getDay() !== $daysInMonth) {
|
|
$this->info('Not end of Jalali month; skipped.');
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
}
|
|
|
|
[$start, $end] = $service->jalaliMonthBounds($anchor);
|
|
$monthName = Jalalian::fromCarbon($start)->format('%B %Y');
|
|
|
|
$users = User::query()
|
|
->whereNotNull('user_name')
|
|
->whereNull('deleted_at')
|
|
->get(['user_name', 'name']);
|
|
|
|
$lines = [
|
|
"📅 گزارش تأخیر ماهانه",
|
|
"ماه: {$monthName}",
|
|
"",
|
|
];
|
|
|
|
$any = false;
|
|
$monthTotal = 0;
|
|
|
|
foreach ($users as $user) {
|
|
$summary = $service->summarizeUserPeriod($user->user_name, $start, $end);
|
|
$weeklyAmount = (int) \App\Models\LatePeriodFine::query()
|
|
->where('user_identity', $user->user_name)
|
|
->where('period_type', 'weekly')
|
|
->whereBetween('period_start', [$start->toDateString(), $end->toDateString()])
|
|
->sum('fine_amount');
|
|
|
|
$total = $summary['daily_fine_amount'] + $weeklyAmount;
|
|
if ($summary['late_minutes'] <= 0 && $total <= 0) {
|
|
continue;
|
|
}
|
|
|
|
$any = true;
|
|
$monthTotal += $total;
|
|
|
|
$service->storePeriodFine([
|
|
'user_identity' => $user->user_name,
|
|
'period_type' => 'monthly',
|
|
'period_start' => $start->toDateString(),
|
|
'period_end' => $end->toDateString(),
|
|
'late_minutes' => $summary['late_minutes'],
|
|
'allowance_minutes' => 0,
|
|
'fine_minutes' => 0,
|
|
'fine_amount' => $total,
|
|
'daily_fine_amount' => $summary['daily_fine_amount'],
|
|
'weekly_fine_amount' => $weeklyAmount,
|
|
'total_fine_amount' => $total,
|
|
]);
|
|
|
|
$name = $user->name ?: $user->user_name;
|
|
$lines[] = "• {$name}";
|
|
$lines[] = " مجموع تأخیر ماه: {$summary['late_minutes']} دقیقه";
|
|
$lines[] = " جریمه روزانه: " . $service->formatAmount($summary['daily_fine_amount']);
|
|
$lines[] = " جریمه هفتگی: " . $service->formatAmount($weeklyAmount);
|
|
$lines[] = " جمع کل: " . $service->formatAmount($total);
|
|
$lines[] = "";
|
|
}
|
|
|
|
if (!$any) {
|
|
$lines[] = "در این ماه تأخیر مشمول جریمهای ثبت نشده است.";
|
|
} else {
|
|
$lines[] = "جمع کل جرایم ماه: " . $service->formatAmount($monthTotal);
|
|
}
|
|
|
|
$service->sendToAdmins(implode("\n", $lines));
|
|
$this->info('Monthly late report sent.');
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
}
|