281 lines
10 KiB
PHP
281 lines
10 KiB
PHP
<?php
|
|
require_once __DIR__ . '/../app/lib/auth.php';
|
|
require_once __DIR__ . '/../app/lib/db.php';
|
|
require_once __DIR__ . '/../app/lib/helpers.php';
|
|
|
|
check_auth();
|
|
|
|
$pdo = db();
|
|
$uid = user_id();
|
|
|
|
$ym = $_GET['ym'] ?? date('Y-m');
|
|
$q = trim($_GET['q'] ?? '');
|
|
$type = $_GET['type'] ?? '';
|
|
$accountId = (int)($_GET['account_id'] ?? 0);
|
|
$categoryId = (int)($_GET['category_id'] ?? 0);
|
|
|
|
$start = $ym . '-01';
|
|
$end = date('Y-m-t', strtotime($start));
|
|
|
|
$params = [$uid, $start, $end];
|
|
$where = [
|
|
"t.user_id = ?",
|
|
"t.transaction_date BETWEEN ? AND ?"
|
|
];
|
|
|
|
if ($q !== '') {
|
|
$where[] = "(t.merchant_name LIKE ? OR t.description LIKE ? OR c.name LIKE ? OR a.account_name LIKE ?)";
|
|
$like = '%' . $q . '%';
|
|
array_push($params, $like, $like, $like, $like);
|
|
}
|
|
|
|
if (in_array($type, ['income', 'expense', 'transfer', 'card_payment'], true)) {
|
|
$where[] = "t.transaction_type = ?";
|
|
$params[] = $type;
|
|
}
|
|
|
|
if ($accountId > 0) {
|
|
$where[] = "t.account_id = ?";
|
|
$params[] = $accountId;
|
|
}
|
|
|
|
if ($categoryId > 0) {
|
|
$where[] = "t.category_id = ?";
|
|
$params[] = $categoryId;
|
|
}
|
|
|
|
$sql = "
|
|
SELECT
|
|
t.*,
|
|
a.account_name,
|
|
a.account_type,
|
|
a.card_kind,
|
|
ra.account_name AS related_account_name,
|
|
c.name AS category_name
|
|
FROM transactions t
|
|
JOIN accounts a ON t.account_id = a.id
|
|
LEFT JOIN accounts ra ON t.related_account_id = ra.id
|
|
JOIN categories c ON t.category_id = c.id
|
|
WHERE " . implode(' AND ', $where) . "
|
|
ORDER BY t.transaction_date DESC, t.id DESC
|
|
";
|
|
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute($params);
|
|
$list = $stmt->fetchAll();
|
|
|
|
$stmt = $pdo->prepare("SELECT id, account_name FROM accounts WHERE user_id = ? AND is_active = 1 ORDER BY id ASC");
|
|
$stmt->execute([$uid]);
|
|
$accounts = $stmt->fetchAll();
|
|
|
|
$stmt = $pdo->prepare("SELECT id, category_type, name FROM categories WHERE user_id = ? AND is_active = 1 ORDER BY category_type, sort_order, id");
|
|
$stmt->execute([$uid]);
|
|
$categories = $stmt->fetchAll();
|
|
|
|
/* 요약 */
|
|
$sumIncome = 0;
|
|
$sumExpense = 0;
|
|
$sumTransfer = 0;
|
|
$sumCardPay = 0;
|
|
|
|
foreach ($list as $row) {
|
|
$amt = (float)$row['amount'];
|
|
|
|
if ($row['transaction_type'] === 'income') $sumIncome += $amt;
|
|
elseif ($row['transaction_type'] === 'expense') $sumExpense += $amt;
|
|
elseif ($row['transaction_type'] === 'transfer') $sumTransfer += $amt;
|
|
elseif ($row['transaction_type'] === 'card_payment') $sumCardPay += $amt;
|
|
}
|
|
|
|
function tx_label(string $type): string
|
|
{
|
|
return match ($type) {
|
|
'income' => '수입',
|
|
'expense' => '지출',
|
|
'transfer' => '이체',
|
|
'card_payment' => '카드납부',
|
|
default => $type
|
|
};
|
|
}
|
|
|
|
require __DIR__ . '/../app/views/header.php';
|
|
?>
|
|
|
|
<div class="page-head">
|
|
<h2>거래내역</h2>
|
|
<a href="/transaction_create.php" class="btn btn-primary">거래등록</a>
|
|
</div>
|
|
|
|
<div class="card finance-card mb-4">
|
|
<div class="card-body">
|
|
<form method="get" class="row g-3">
|
|
<div class="col-md-2">
|
|
<label class="form-label">월</label>
|
|
<input type="month" name="ym" class="form-control" value="<?= h($ym) ?>">
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<label class="form-label">검색어</label>
|
|
<input type="text" name="q" class="form-control" value="<?= h($q) ?>" placeholder="사용처, 메모, 카테고리">
|
|
</div>
|
|
|
|
<div class="col-md-2">
|
|
<label class="form-label">유형</label>
|
|
<select name="type" class="form-select">
|
|
<option value="">전체</option>
|
|
<option value="income" <?= $type === 'income' ? 'selected' : '' ?>>수입</option>
|
|
<option value="expense" <?= $type === 'expense' ? 'selected' : '' ?>>지출</option>
|
|
<option value="transfer" <?= $type === 'transfer' ? 'selected' : '' ?>>이체</option>
|
|
<option value="card_payment" <?= $type === 'card_payment' ? 'selected' : '' ?>>카드납부</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="col-md-2">
|
|
<label class="form-label">계좌</label>
|
|
<select name="account_id" class="form-select">
|
|
<option value="0">전체</option>
|
|
<?php foreach ($accounts as $account): ?>
|
|
<option value="<?= $account['id'] ?>" <?= $accountId === (int)$account['id'] ? 'selected' : '' ?>>
|
|
<?= h($account['account_name']) ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<label class="form-label">카테고리</label>
|
|
<select name="category_id" class="form-select">
|
|
<option value="0">전체</option>
|
|
<?php foreach ($categories as $category): ?>
|
|
<option value="<?= $category['id'] ?>" <?= $categoryId === (int)$category['id'] ? 'selected' : '' ?>>
|
|
[<?= h($category['category_type']) ?>] <?= h($category['name']) ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="col-12 d-flex gap-2">
|
|
<button class="btn btn-primary">조회</button>
|
|
<a href="/transactions.php" class="btn btn-outline-secondary">초기화</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-md-3">
|
|
<div class="card finance-card">
|
|
<div class="card-body">
|
|
<div class="stat-label">수입</div>
|
|
<div class="stat-value text-primary"><?= won($sumIncome) ?></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<div class="card finance-card">
|
|
<div class="card-body">
|
|
<div class="stat-label">지출</div>
|
|
<div class="stat-value text-danger"><?= won($sumExpense) ?></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<div class="card finance-card">
|
|
<div class="card-body">
|
|
<div class="stat-label">이체</div>
|
|
<div class="stat-value"><?= won($sumTransfer) ?></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<div class="card finance-card">
|
|
<div class="card-body">
|
|
<div class="stat-label">카드납부</div>
|
|
<div class="stat-value"><?= won($sumCardPay) ?></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card finance-card">
|
|
<div class="card-body mobile-scroll">
|
|
<table class="table table-hover align-middle mb-0 transaction-list-table">
|
|
<thead>
|
|
<tr>
|
|
<th>날짜</th>
|
|
<th>유형</th>
|
|
<th>계좌</th>
|
|
<th>관련</th>
|
|
<th>카테고리</th>
|
|
<th>사용처</th>
|
|
<th class="text-end">금액</th>
|
|
<th>부가정보</th>
|
|
<th>메모</th>
|
|
<th>관리</th>
|
|
</tr>
|
|
</thead>
|
|
|
|
<tbody>
|
|
<?php foreach ($list as $row): ?>
|
|
<?php
|
|
$class = 'amount-transfer';
|
|
if ($row['transaction_type'] === 'income') $class = 'amount-income';
|
|
if ($row['transaction_type'] === 'expense') $class = 'amount-expense';
|
|
if ($row['transaction_type'] === 'card_payment') $class = 'amount-card';
|
|
|
|
$extra = [];
|
|
|
|
if (!empty($row['billing_year_month'])) {
|
|
$extra[] = '청구월 ' . $row['billing_year_month'];
|
|
}
|
|
|
|
if (!empty($row['is_installment']) && !empty($row['installment_months'])) {
|
|
$extra[] = $row['installment_months'] . '개월 할부';
|
|
}
|
|
|
|
if ($row['account_type'] === 'card' && $row['card_kind'] === 'check') {
|
|
$extra[] = '체크카드';
|
|
}
|
|
|
|
if ($row['account_type'] === 'card' && $row['card_kind'] === 'credit') {
|
|
$extra[] = '신용카드';
|
|
}
|
|
?>
|
|
<tr>
|
|
<td data-label="날짜"><?= h($row['transaction_date']) ?></td>
|
|
<td data-label="유형"><?= h(tx_label($row['transaction_type'])) ?></td>
|
|
<td data-label="계좌"><?= h($row['account_name']) ?></td>
|
|
<td data-label="관련"><?= h($row['related_account_name'] ?? '-') ?></td>
|
|
<td data-label="카테고리"><?= h($row['category_name']) ?></td>
|
|
<td data-label="사용처"><?= h($row['merchant_name'] ?: '-') ?></td>
|
|
<td data-label="금액" class="text-end <?= $class ?>"><?= won($row['amount']) ?></td>
|
|
<td data-label="부가정보"><?= h($extra ? implode(' / ', $extra) : '-') ?></td>
|
|
<td data-label="메모"><?= h($row['description'] ?: '-') ?></td>
|
|
<td data-label="관리" class="text-nowrap">
|
|
<a href="/transaction_create.php?copy_id=<?= $row['id'] ?>"
|
|
class="btn btn-sm btn-outline-secondary">복사</a>
|
|
<a href="/transaction_edit.php?id=<?= $row['id'] ?>" class="btn btn-sm btn-outline-primary">수정</a>
|
|
<form method="post" action="/transaction_delete.php" class="d-inline">
|
|
<input type="hidden" name="id" value="<?= (int)$row['id'] ?>">
|
|
<button class="btn btn-sm btn-outline-danger"
|
|
onclick="return confirm('삭제하시겠습니까?');">삭제</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
|
|
<?php if (!$list): ?>
|
|
<tr>
|
|
<td colspan="10" class="text-center text-secondary py-5">조회 결과가 없습니다.</td>
|
|
</tr>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<?php require __DIR__ . '/../app/views/footer.php'; ?>
|