From 958a9302b013ddf1dda9528b5a0abd27cbf17342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Fri, 27 Feb 2026 18:00:18 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20[payroll]=20=EC=A0=84=EC=9B=94=20?= =?UTF-8?q?=EB=B3=B5=EC=82=AC/=EC=9D=BC=EA=B4=84=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EC=8B=9C=20SoftDeletes=20=EC=9C=A0=EB=8B=88=ED=81=AC=20?= =?UTF-8?q?=EC=A0=9C=EC=95=BD=20=EC=B6=A9=EB=8F=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - exists() 대신 withTrashed()->first()로 soft-deleted 레코드 포함 체크 - soft-deleted 레코드 존재 시 forceDelete() 후 재생성 - copyFromPreviousMonth(), bulkGenerate() 양쪽 동일 수정 --- app/Services/HR/PayrollService.php | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) 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;