221 lines
8.7 KiB
PHP
221 lines
8.7 KiB
PHP
<?php
|
|
|
|
namespace App\Jobs;
|
|
|
|
use App\Models\LeaveDays;
|
|
use App\Models\Notes;
|
|
use App\Models\User;
|
|
use Illuminate\Bus\Queueable;
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
use Illuminate\Foundation\Bus\Dispatchable;
|
|
use Illuminate\Queue\InteractsWithQueue;
|
|
use Illuminate\Queue\SerializesModels;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Modules\Admin\app\Models\Category;
|
|
|
|
class UpdateTemporaryLeaveDays implements ShouldQueue
|
|
{
|
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
|
protected $month;
|
|
protected $year;
|
|
|
|
public function __construct($month = null, $year = null)
|
|
{
|
|
$this->month = $month ?? Carbon::now()->month;
|
|
$this->year = $year ?? Carbon::now()->year;
|
|
}
|
|
|
|
/**
|
|
* Execute the job.
|
|
*/
|
|
public function handle()
|
|
{
|
|
$users = User::get();
|
|
|
|
foreach ($users as $user) {
|
|
$leaveDay = LeaveDays::where('ld_user_id', $user->id)
|
|
->where('ld_year', $this->year)
|
|
->first();
|
|
|
|
$notes = Notes::where('n_reason', 'TEMPORARY_ONLEAVE')
|
|
->where('n_user_id', $user->id)
|
|
->where('n_year', $this->year)
|
|
->where('n_month', $this->month)
|
|
->whereExists(function ($query) use ($user) {
|
|
$query->select(DB::raw(1))
|
|
->from('tickets')
|
|
->where('tickets.user_id', $user->id)
|
|
->where('tickets.status', 'CONFIRMED')
|
|
->where('tickets.type', 'ONLEAVE');
|
|
})
|
|
->get();
|
|
|
|
$maxDaysPerMonth = $this->getMaxLeaveDaysPerMonth();
|
|
|
|
// Tổng ngày nghỉ sẽ dùng trong tháng
|
|
$willUsedDaysInMonth = 0;
|
|
foreach ($notes as $note) {
|
|
$willUsedDaysInMonth += $note->n_time_type == 'ALL' ? 1.0 : 0.5;
|
|
}
|
|
|
|
// Tổng phép đang có
|
|
$onleaveDaysTotal = $leaveDay->ld_day_total + $leaveDay->ld_additional_day + $leaveDay->ld_special_leave_day;
|
|
// Phép đã sử dụng tới tháng hiện tại
|
|
$usedOnleaveDaysTotal = Notes::join('categories', function ($join) {
|
|
$join->on('notes.n_time_type', '=', 'categories.c_code')
|
|
->where('categories.c_type', 'TIME_TYPE');
|
|
})
|
|
->where('n_user_id', $user->id)
|
|
->where('n_year', $this->year)
|
|
->where('n_month', "<=", $this->month)
|
|
->where('n_reason', 'ONLEAVE')
|
|
->sum('categories.c_value');
|
|
// Phép còn lại
|
|
$remainingOnleaveDays = $onleaveDaysTotal - $usedOnleaveDaysTotal;
|
|
|
|
// Log::debug("User {$user->name}\n");
|
|
// Log::debug(
|
|
// "📊 Thống kê ngày phép:\n" .
|
|
// " - Tháng: {$this->month}\n" .
|
|
// " - Tổng ngày nghỉ sẽ dùng trong tháng: $willUsedDaysInMonth\n" .
|
|
// " - Tổng ngày phép: $onleaveDaysTotal\n" .
|
|
// " - Tổng ngày phép đã nghỉ: $usedOnleaveDaysTotal\n" .
|
|
// " - Tổng ngày phép còn lại: $remainingOnleaveDays\n"
|
|
// );
|
|
|
|
$onleave_days_will_use = 0; // Ngày phép sẽ dùng
|
|
$nopay_days_will_use = 0; // Ngày ko phép sẽ dùng
|
|
|
|
// Ngày phép còn lại <= 0 (Hết phép)
|
|
if ($remainingOnleaveDays <= 0) {
|
|
$onleave_days_will_use = 0;
|
|
$nopay_days_will_use = $willUsedDaysInMonth;
|
|
|
|
Log::debug("--- Hết phép trong tháng ---");
|
|
}
|
|
|
|
// Ngày phép còn lại < ngày yêu cầu (Không đủ phép)
|
|
else if ($remainingOnleaveDays < $willUsedDaysInMonth) {
|
|
// Vượt limit
|
|
if ($willUsedDaysInMonth > $maxDaysPerMonth) {
|
|
// Phép còn lại > limit
|
|
if ($remainingOnleaveDays > $maxDaysPerMonth) {
|
|
$onleave_days_will_use = $maxDaysPerMonth;
|
|
$nopay_days_will_use = $willUsedDaysInMonth - $maxDaysPerMonth;
|
|
}
|
|
// Phép còn lại < limit
|
|
else {
|
|
$onleave_days_will_use = $remainingOnleaveDays;
|
|
$nopay_days_will_use = $willUsedDaysInMonth - $remainingOnleaveDays;
|
|
}
|
|
|
|
Log::debug("--- Không đủ phép trong tháng, vượt quá limit ---",);
|
|
}
|
|
// Không vượt limit
|
|
else {
|
|
$onleave_days_will_use = $remainingOnleaveDays;
|
|
$nopay_days_will_use = $willUsedDaysInMonth - $remainingOnleaveDays;
|
|
|
|
Log::debug("--- Không đủ phép trong tháng, ko vượt limit ---");
|
|
}
|
|
}
|
|
|
|
// Ngày phép còn lại >= ngày yêu cầu (Đủ phép)
|
|
else {
|
|
// Vượt limit
|
|
if ($willUsedDaysInMonth > $maxDaysPerMonth) {
|
|
$onleave_days_will_use = $maxDaysPerMonth;
|
|
$nopay_days_will_use = $willUsedDaysInMonth - $maxDaysPerMonth;
|
|
|
|
Log::debug("--- Đủ phép, vượt limit ---");
|
|
}
|
|
// Không vượt limit
|
|
else {
|
|
$onleave_days_will_use = $willUsedDaysInMonth;
|
|
$nopay_days_will_use = 0;
|
|
|
|
Log::debug("--- Đủ phép ---");
|
|
}
|
|
}
|
|
|
|
Log::debug("", [
|
|
"Phep" => $onleave_days_will_use,
|
|
"Khong Phep" => $nopay_days_will_use
|
|
]);
|
|
|
|
// Có nghỉ không phép
|
|
if ($nopay_days_will_use > 0) {
|
|
foreach ($notes as $note) {
|
|
$value = ($note->n_time_type === 'ALL') ? 1.0 : 0.5;
|
|
|
|
if ($note->n_time_type === 'ALL' && $onleave_days_will_use == 0.5) {
|
|
// Chỉ còn 0.5 phép, chia thành 2 bản ghi: 1 phép, 1 không phép
|
|
// Ưu tiên phép cho buổi sáng (S), không phép cho buổi chiều (C)
|
|
|
|
Notes::create([
|
|
'n_user_id' => $user->id,
|
|
'n_day' => $note->n_day,
|
|
'n_month' => $note->n_month,
|
|
'n_year' => $note->n_year,
|
|
'n_time_type' => 'S',
|
|
'n_reason' => 'ONLEAVE',
|
|
'n_note' => $note->n_note,
|
|
'ticket_id' => $note->ticket_id
|
|
]);
|
|
Notes::create([
|
|
'n_user_id' => $user->id,
|
|
'n_day' => $note->n_day,
|
|
'n_month' => $note->n_month,
|
|
'n_year' => $note->n_year,
|
|
'n_time_type' => 'C',
|
|
'n_reason' => 'LEAVE_WITHOUT_PAY',
|
|
'n_note' => $note->n_note,
|
|
'ticket_id' => $note->ticket_id
|
|
]);
|
|
|
|
$note->delete();
|
|
|
|
$onleave_days_will_use = 0;
|
|
$nopay_days_will_use -= 0.5;
|
|
} elseif ($onleave_days_will_use > 0) {
|
|
// Dùng ngày phép trước
|
|
$use = min($onleave_days_will_use, $value);
|
|
$note->update([
|
|
'n_reason' => "ONLEAVE"
|
|
]);
|
|
$onleave_days_will_use -= $use;
|
|
} elseif ($nopay_days_will_use > 0) {
|
|
// Hết phép, chuyển sang không phép
|
|
$use = min($nopay_days_will_use, $value);
|
|
$note->update([
|
|
'n_reason' => "LEAVE_WITHOUT_PAY"
|
|
]);
|
|
$nopay_days_will_use -= $use;
|
|
}
|
|
}
|
|
}
|
|
// Đủ phép
|
|
else {
|
|
foreach ($notes as $note) {
|
|
$note->update([
|
|
'n_reason' => "ONLEAVE"
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private function getMaxLeaveDaysPerMonth(): int
|
|
{
|
|
$limitLeaveMonth = Category::where('c_type', 'LIMIT_LEAVE_MONTH')->where('c_code', "LIMIT")->first();
|
|
if ($limitLeaveMonth) {
|
|
$maxDaysPerMonth = (int)$limitLeaveMonth->c_value;
|
|
} else {
|
|
$maxDaysPerMonth = 3; // default nếu k có setting
|
|
}
|
|
return $maxDaysPerMonth;
|
|
}
|
|
}
|