fix: [finance] 미지급금 관리 프리랜서 잔액 마이너스 수정
- 중복 journal_entry_lines 탐지 및 삭제 마이그레이션 - 동일 전표 내 같은 계정/거래처/금액의 중복 라인 정리 - 삭제 후 전표 차대 합계 재계산
This commit is contained in:
@@ -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] 중복 라인 삭제는 롤백할 수 없습니다.');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user