feat: 더미 데이터 시더 추가 및 회계 관련 마이그레이션

- DummyDataSeeder 및 개별 시더 추가 (Client, BadDebt, Deposit 등)
- payments.paid_at nullable 마이그레이션
- subscriptions 취소 컬럼 추가
- clients 테이블 bad_debt 컬럼 제거
- PlanController, ClientService 수정
- 불필요한 claudedocs, flow-test 파일 정리
This commit is contained in:
2025-12-24 08:54:52 +09:00
parent 71123128ff
commit 8686b199ee
30 changed files with 1278 additions and 2655 deletions

View File

@@ -2,7 +2,11 @@
namespace App\Services;
use App\Models\BadDebts\BadDebt;
use App\Models\Orders\Client;
use App\Models\Tenants\Deposit;
use App\Models\Tenants\Sale;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -34,7 +38,51 @@ public function index(array $params)
$query->orderBy('client_code')->orderBy('id');
return $query->paginate($size, ['*'], 'page', $page);
$paginator = $query->paginate($size, ['*'], 'page', $page);
// 미수금 계산: 매출 합계 - 입금 합계
$clientIds = $paginator->pluck('id')->toArray();
if (! empty($clientIds)) {
// 거래처별 매출 합계
$salesByClient = Sale::where('tenant_id', $tenantId)
->whereIn('client_id', $clientIds)
->whereNull('deleted_at')
->groupBy('client_id')
->select('client_id', DB::raw('SUM(total_amount) as total_sales'))
->pluck('total_sales', 'client_id');
// 거래처별 입금 합계
$depositsByClient = Deposit::where('tenant_id', $tenantId)
->whereIn('client_id', $clientIds)
->whereNull('deleted_at')
->groupBy('client_id')
->select('client_id', DB::raw('SUM(amount) as total_deposits'))
->pluck('total_deposits', 'client_id');
// 거래처별 활성 악성채권 합계 (추심중, 법적조치)
$badDebtsByClient = BadDebt::where('tenant_id', $tenantId)
->whereIn('client_id', $clientIds)
->whereIn('status', [BadDebt::STATUS_COLLECTING, BadDebt::STATUS_LEGAL_ACTION])
->where('is_active', true)
->whereNull('deleted_at')
->groupBy('client_id')
->select('client_id', DB::raw('SUM(debt_amount) as total_bad_debt'))
->pluck('total_bad_debt', 'client_id');
// 각 거래처에 미수금/악성채권 정보 추가
$paginator->getCollection()->transform(function ($client) use ($salesByClient, $depositsByClient, $badDebtsByClient) {
$totalSales = $salesByClient[$client->id] ?? 0;
$totalDeposits = $depositsByClient[$client->id] ?? 0;
$client->outstanding_amount = max(0, $totalSales - $totalDeposits);
$client->bad_debt_total = $badDebtsByClient[$client->id] ?? 0;
$client->has_bad_debt = ($badDebtsByClient[$client->id] ?? 0) > 0;
return $client;
});
}
return $paginator;
}
/** 단건 */
@@ -46,6 +94,30 @@ public function show(int $id)
throw new NotFoundHttpException(__('error.not_found'));
}
// 미수금 계산
$totalSales = Sale::where('tenant_id', $tenantId)
->where('client_id', $id)
->whereNull('deleted_at')
->sum('total_amount');
$totalDeposits = Deposit::where('tenant_id', $tenantId)
->where('client_id', $id)
->whereNull('deleted_at')
->sum('amount');
$client->outstanding_amount = max(0, $totalSales - $totalDeposits);
// 악성채권 정보
$badDebtTotal = BadDebt::where('tenant_id', $tenantId)
->where('client_id', $id)
->whereIn('status', [BadDebt::STATUS_COLLECTING, BadDebt::STATUS_LEGAL_ACTION])
->where('is_active', true)
->whereNull('deleted_at')
->sum('debt_amount');
$client->bad_debt_total = $badDebtTotal;
$client->has_bad_debt = $badDebtTotal > 0;
return $client;
}