fix: [finance] 미지급금 관리 프리랜서 잔액 마이너스 수정

- 중복 journal_entry_lines 탐지 및 삭제 마이그레이션
- 동일 전표 내 같은 계정/거래처/금액의 중복 라인 정리
- 삭제 후 전표 차대 합계 재계산
This commit is contained in:
김보곤
2026-03-13 17:11:10 +09:00
parent 0760d38bd7
commit a053365ed5

View File

@@ -0,0 +1,92 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
return new class extends Migration
{
/**
* 중복 journal_entry_lines 정리
*
* 문제: 미지급금 관리에서 프리랜서 잔액이 마이너스로 표시됨
* 원인: 동일 전표 내 같은 계정/거래처/금액의 라인이 중복 생성됨
* 해결: 중복 라인 중 ID가 큰 것을 삭제 (원본 보존)
*/
public function up(): void
{
// 1. 동일 전표 내 중복 라인 탐지
// (같은 journal_entry_id + account_code + dc_type + trading_partner_name + debit_amount + credit_amount)
$duplicates = DB::select("
SELECT journal_entry_id, account_code, dc_type, trading_partner_name,
debit_amount, credit_amount, COUNT(*) as cnt,
MIN(id) as keep_id, GROUP_CONCAT(id ORDER BY id) as all_ids
FROM journal_entry_lines
WHERE account_code IN ('204', '205')
GROUP BY journal_entry_id, account_code, dc_type, trading_partner_name,
debit_amount, credit_amount
HAVING cnt > 1
");
if (empty($duplicates)) {
Log::info('[Migration] 중복 journal_entry_lines 없음 - 정리 불필요');
return;
}
$totalDeleted = 0;
foreach ($duplicates as $dup) {
$allIds = explode(',', $dup->all_ids);
$keepId = $dup->keep_id;
$deleteIds = array_filter($allIds, fn ($id) => (int) $id !== (int) $keepId);
if (! empty($deleteIds)) {
Log::info("[Migration] 중복 라인 삭제: journal_entry_id={$dup->journal_entry_id}, "
."account_code={$dup->account_code}, dc_type={$dup->dc_type}, "
."partner={$dup->trading_partner_name}, "
."keep_id={$keepId}, delete_ids=".implode(',', $deleteIds));
$deleted = DB::table('journal_entry_lines')
->whereIn('id', $deleteIds)
->delete();
$totalDeleted += $deleted;
}
}
Log::info("[Migration] 중복 journal_entry_lines 정리 완료: {$totalDeleted}건 삭제");
// 2. 삭제 후 전표 합계 재계산
if ($totalDeleted > 0) {
$affectedEntryIds = collect($duplicates)->pluck('journal_entry_id')->unique();
foreach ($affectedEntryIds as $entryId) {
$sums = DB::selectOne("
SELECT COALESCE(SUM(debit_amount), 0) as total_debit,
COALESCE(SUM(credit_amount), 0) as total_credit
FROM journal_entry_lines
WHERE journal_entry_id = ?
", [$entryId]);
DB::table('journal_entries')
->where('id', $entryId)
->update([
'total_debit' => $sums->total_debit,
'total_credit' => $sums->total_credit,
]);
Log::info("[Migration] 전표 합계 재계산: id={$entryId}, "
."debit={$sums->total_debit}, credit={$sums->total_credit}");
}
}
}
/**
* 데이터 정리 마이그레이션이므로 rollback 불가
*/
public function down(): void
{
Log::warning('[Migration] 중복 라인 삭제는 롤백할 수 없습니다.');
}
};