Changes to holidays and the overlap between this year and the previous year
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Morilog\Jalali\Jalalian;
|
||||
|
||||
class RemindHolidayCalendarUpdate extends Command
|
||||
{
|
||||
protected $signature = 'holidays:remind';
|
||||
|
||||
protected $description = 'یادآوری ثبت تعطیلات رسمی سالهای بعد از اتمام پوشش تقویم پروژه';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$coveredUntil = SeedIranianHolidays::coveredUntilYear();
|
||||
if ($coveredUntil < 1300) {
|
||||
$this->warn('فایل تعطیلات خالی یا نامعتبر است.');
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$now = Jalalian::now();
|
||||
$currentYear = $now->getYear();
|
||||
|
||||
// از ۲۰ اسفند سال پوششدادهشده، یا هر زمان بعد از آن سال
|
||||
$shouldRemind = $currentYear > $coveredUntil
|
||||
|| ($currentYear === $coveredUntil && $now->getMonth() === 12 && $now->getDay() >= 20);
|
||||
|
||||
if (!$shouldRemind) {
|
||||
$this->info("هنوز نیازی به یادآوری نیست (پوشش تا {$coveredUntil}، الان {$currentYear}).");
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
$yearsToRequest = [];
|
||||
for ($y = $coveredUntil + 1; $y <= max($currentYear + 1, $coveredUntil + 1); $y++) {
|
||||
$yearsToRequest[] = $y;
|
||||
}
|
||||
$yearsToRequest = array_values(array_unique($yearsToRequest));
|
||||
$yearsLabel = implode(' و ', $yearsToRequest);
|
||||
|
||||
$cacheKey = 'holidays_remind_' . implode('_', $yearsToRequest);
|
||||
if (Cache::has($cacheKey)) {
|
||||
$this->info('یادآوری اخیراً ارسال شده؛ این ماه دوباره ارسال نمیشود.');
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
$message = "📅 یادآوری تعطیلات رسمی\n\n"
|
||||
. "پوشش تعطیلات در سیستم تا سال {$coveredUntil} است.\n"
|
||||
. "لطفاً تعطیلات رسمی سال {$yearsLabel} را طبق تقویم رسمی ایران به فایل\n"
|
||||
. "database/data/iranian_official_holidays.php\n"
|
||||
. "اضافه کنید و سپس اجرا کنید:\n"
|
||||
. "php artisan holidays:seed";
|
||||
|
||||
$this->notifyAdmins($message);
|
||||
Cache::put($cacheKey, true, now()->addDays(30));
|
||||
|
||||
$this->info("یادآوری برای سال(های) {$yearsLabel} به ادمینها ارسال شد.");
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
private function notifyAdmins(string $message): void
|
||||
{
|
||||
$admins = User::query()
|
||||
->whereNotNull('is_admin')
|
||||
->whereNotNull('bale')
|
||||
->select('bale')
|
||||
->get();
|
||||
|
||||
foreach ($admins as $admin) {
|
||||
try {
|
||||
Http::withoutVerifying()->post(
|
||||
'https://tapi.bale.ai/1482838710:sYbLzby0tuLRzHvP4d3LsbcNwg2sjSDLTAU/sendMessage',
|
||||
[
|
||||
'chat_id' => $admin->bale,
|
||||
'text' => $message,
|
||||
]
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Holiday;
|
||||
use Illuminate\Console\Command;
|
||||
use Morilog\Jalali\Jalalian;
|
||||
|
||||
class SeedIranianHolidays extends Command
|
||||
{
|
||||
protected $signature = 'holidays:seed {--year= : فقط یک سال شمسی مشخص}';
|
||||
|
||||
protected $description = 'ثبت/بهروزرسانی تعطیلات رسمی ایران از فایل تقویم پروژه';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$path = database_path('data/iranian_official_holidays.php');
|
||||
if (!is_file($path)) {
|
||||
$this->error('فایل تعطیلات یافت نشد: ' . $path);
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
/** @var array<int, list<array{month:int, day:int, title:string}>> $years */
|
||||
$years = require $path;
|
||||
$onlyYear = $this->option('year') !== null ? (int) $this->option('year') : null;
|
||||
|
||||
$count = 0;
|
||||
foreach ($years as $jalaliYear => $days) {
|
||||
if ($onlyYear !== null && (int) $jalaliYear !== $onlyYear) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($days as $day) {
|
||||
try {
|
||||
$gregorian = (new Jalalian((int) $jalaliYear, (int) $day['month'], (int) $day['day']))
|
||||
->toCarbon()
|
||||
->format('Y-m-d');
|
||||
} catch (\Throwable $e) {
|
||||
$this->warn("رد شد: {$jalaliYear}/{$day['month']}/{$day['day']} — {$e->getMessage()}");
|
||||
continue;
|
||||
}
|
||||
|
||||
Holiday::updateOrCreate(
|
||||
['date' => $gregorian],
|
||||
['title' => $day['title']]
|
||||
);
|
||||
$count++;
|
||||
}
|
||||
|
||||
$this->info("سال {$jalaliYear}: " . count($days) . ' روز');
|
||||
}
|
||||
|
||||
$this->info("جمع: {$count} تعطیل رسمی ثبت/بهروز شد.");
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
/** آخرین سال شمسی پوششدادهشده در فایل داده */
|
||||
public static function coveredUntilYear(): int
|
||||
{
|
||||
$path = database_path('data/iranian_official_holidays.php');
|
||||
if (!is_file($path)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$years = array_keys(require $path);
|
||||
|
||||
return $years ? (int) max($years) : 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user