diff --git a/app/Services/HR/PayrollService.php b/app/Services/HR/PayrollService.php index 1fc5b300..67c04d5a 100644 --- a/app/Services/HR/PayrollService.php +++ b/app/Services/HR/PayrollService.php @@ -327,18 +327,24 @@ public function copyFromPreviousMonth(int $year, int $month): array DB::transaction(function () use ($previousPayrolls, $tenantId, $year, $month, &$created, &$skipped) { foreach ($previousPayrolls as $prev) { - $exists = Payroll::query() + // SoftDeletes 포함하여 유니크 제약 충돌 방지 + $existing = Payroll::withTrashed() ->where('tenant_id', $tenantId) ->where('user_id', $prev->user_id) ->forPeriod($year, $month) - ->exists(); + ->first(); - if ($exists) { + if ($existing && ! $existing->trashed()) { $skipped++; continue; } + // soft-deleted 레코드가 있으면 삭제 후 재생성 + if ($existing && $existing->trashed()) { + $existing->forceDelete(); + } + Payroll::create([ 'tenant_id' => $tenantId, 'user_id' => $prev->user_id, @@ -388,18 +394,24 @@ public function bulkGenerate(int $year, int $month): array DB::transaction(function () use ($employees, $tenantId, $year, $month, $settings, &$created, &$skipped) { foreach ($employees as $employee) { - $exists = Payroll::query() + // SoftDeletes 포함하여 유니크 제약 충돌 방지 + $existing = Payroll::withTrashed() ->where('tenant_id', $tenantId) ->where('user_id', $employee->user_id) ->forPeriod($year, $month) - ->exists(); + ->first(); - if ($exists) { + if ($existing && ! $existing->trashed()) { $skipped++; continue; } + // soft-deleted 레코드가 있으면 삭제 후 재생성 + if ($existing && $existing->trashed()) { + $existing->forceDelete(); + } + $annualSalary = $employee->getJsonExtraValue('salary', 0); $baseSalary = $annualSalary > 0 ? round($annualSalary / 12) : 0;