Files
financial/public/account_create.php
T
2026-06-07 00:33:58 +09:00

329 lines
14 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();
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
$accountType = $_POST['account_type'] ?? '';
$institutionName = trim($_POST['institution_name'] ?? '');
$accountName = trim($_POST['account_name'] ?? '');
$openingBalance = (float)str_replace(',', '', (string)($_POST['opening_balance'] ?? 0));
$cardKind = $_POST['card_kind'] ?? null;
$billingDay = !empty($_POST['billing_day']) ? (int)$_POST['billing_day'] : null;
$paymentDay = !empty($_POST['payment_day']) ? (int)$_POST['payment_day'] : null;
$useCreditGracePeriod = !empty($_POST['use_credit_grace_period']) ? 1 : 0;
$billingCycleMemo = trim($_POST['billing_cycle_memo'] ?? '');
$statementStartMonthOffset = isset($_POST['statement_start_month_offset']) && $_POST['statement_start_month_offset'] !== ''
? (int)$_POST['statement_start_month_offset']
: null;
$statementStartDay = !empty($_POST['statement_start_day']) ? (int)$_POST['statement_start_day'] : null;
$statementEndMonthOffset = isset($_POST['statement_end_month_offset']) && $_POST['statement_end_month_offset'] !== ''
? (int)$_POST['statement_end_month_offset']
: null;
$statementEndDay = !empty($_POST['statement_end_day']) ? (int)$_POST['statement_end_day'] : null;
if (!in_array($accountType, ['bank', 'card', 'cash', 'other'], true)) {
throw new RuntimeException('계정 유형이 올바르지 않습니다.');
}
if ($institutionName === '' || $accountName === '') {
throw new RuntimeException('기관명과 계좌명을 입력하세요.');
}
if ($accountType !== 'card') {
$cardKind = null;
$billingDay = null;
$paymentDay = null;
$useCreditGracePeriod = 0;
$billingCycleMemo = null;
$statementStartMonthOffset = null;
$statementStartDay = null;
$statementEndMonthOffset = null;
$statementEndDay = null;
} else {
if (!in_array($cardKind, ['credit', 'check'], true)) {
throw new RuntimeException('카드 종류를 선택하세요.');
}
if ($cardKind === 'check') {
$billingDay = null;
$paymentDay = null;
$useCreditGracePeriod = 0;
$billingCycleMemo = '즉시출금';
$statementStartMonthOffset = null;
$statementStartDay = null;
$statementEndMonthOffset = null;
$statementEndDay = null;
}
if ($cardKind === 'credit') {
if ($paymentDay === null || $paymentDay < 1 || $paymentDay > 31) {
throw new RuntimeException('납부일은 1~31 사이여야 합니다.');
}
if ($useCreditGracePeriod) {
if ($statementStartMonthOffset === null || $statementEndMonthOffset === null) {
throw new RuntimeException('사용기간 기준 월을 선택하세요.');
}
if ($statementStartDay === null || $statementStartDay < 1 || $statementStartDay > 31) {
throw new RuntimeException('사용기간 시작일은 1~31 사이여야 합니다.');
}
if ($statementEndDay === null || $statementEndDay < 1 || $statementEndDay > 31) {
throw new RuntimeException('사용기간 종료일은 1~31 사이여야 합니다.');
}
} else {
$statementStartMonthOffset = null;
$statementStartDay = null;
$statementEndMonthOffset = null;
$statementEndDay = null;
}
if ($billingCycleMemo === '') {
$billingCycleMemo = null;
}
}
}
$stmt = $pdo->prepare("
INSERT INTO accounts
(
user_id,
account_type,
institution_name,
account_name,
opening_balance,
current_balance,
is_active,
card_kind,
billing_day,
payment_day,
use_credit_grace_period,
statement_start_month_offset,
statement_start_day,
statement_end_month_offset,
statement_end_day,
billing_cycle_memo
)
VALUES
(?, ?, ?, ?, ?, ?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?)
");
$stmt->execute([
$uid,
$accountType,
$institutionName,
$accountName,
$openingBalance,
$openingBalance,
$cardKind,
$billingDay,
$paymentDay,
$useCreditGracePeriod,
$statementStartMonthOffset,
$statementStartDay,
$statementEndMonthOffset,
$statementEndDay,
$billingCycleMemo
]);
redirect('/accounts.php');
} catch (Throwable $e) {
$error = $e->getMessage();
}
}
require __DIR__ . '/../app/views/header.php';
?>
<div class="page-head">
<h2>계좌 / 카드 추가</h2>
<a href="/accounts.php" class="btn btn-outline-secondary">목록</a>
</div>
<?php if ($error): ?>
<div class="alert alert-danger"><?= h($error) ?></div>
<?php endif; ?>
<div class="card finance-card">
<div class="card-body">
<form method="post" class="row g-3" id="accountCreateForm">
<div class="col-12 col-md-4">
<label class="form-label">유형</label>
<select name="account_type" id="account_type" class="form-select" required>
<option value="bank">은행계좌</option>
<option value="card">카드</option>
<option value="cash">현금</option>
<option value="other">기타</option>
</select>
</div>
<div class="col-12 col-md-4">
<label class="form-label">기관명</label>
<input type="text" name="institution_name" class="form-control" placeholder="예: IBK, 우리, 농협" required>
</div>
<div class="col-12 col-md-4">
<label class="form-label">계좌명</label>
<input type="text" name="account_name" class="form-control" placeholder="예: IBK 신용카드 / IBK 체크카드" required>
</div>
<div class="col-12 col-md-4">
<label class="form-label">시작 잔액</label>
<input type="text" name="opening_balance" id="opening_balance" class="form-control" value="0" inputmode="numeric" required>
</div>
<div class="col-12" id="card_setting_wrap" style="display:none;">
<div class="loan-create-highlight">
<div class="title">카드 설정</div>
<div class="desc">
카드사마다 신용공여기간이 다르므로 직접 설정 가능합니다.
</div>
<div class="row g-3 mt-1">
<div class="col-12 col-md-3">
<label class="form-label">카드 종류</label>
<select name="card_kind" id="card_kind" class="form-select">
<option value="">선택하세요</option>
<option value="credit">신용카드</option>
<option value="check">체크카드</option>
</select>
</div>
<div class="col-12 col-md-3 credit-only">
<label class="form-label">납부일</label>
<input type="number" name="payment_day" class="form-control" min="1" max="31" placeholder="예: 25">
</div>
<div class="col-12 col-md-3 credit-only d-flex align-items-end">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="use_credit_grace_period" id="use_credit_grace_period" value="1" checked>
<label class="form-check-label">신용공여기간 계산 사용</label>
</div>
</div>
<div class="col-12 credit-only">
<hr>
<div class="fw-bold mb-2">청구월 기준 사용기간</div>
</div>
<div class="col-12 col-md-3 credit-period-only">
<label class="form-label">시작 월 기준</label>
<select name="statement_start_month_offset" class="form-select">
<option value="-2">전전월</option>
<option value="-1" selected>전월</option>
<option value="0">당월</option>
<option value="1">익월</option>
</select>
</div>
<div class="col-12 col-md-3 credit-period-only">
<label class="form-label">시작일</label>
<input type="number" name="statement_start_day" class="form-control" min="1" max="31" placeholder="예: 11">
</div>
<div class="col-12 col-md-3 credit-period-only">
<label class="form-label">종료 월 기준</label>
<select name="statement_end_month_offset" class="form-select">
<option value="-2">전전월</option>
<option value="-1">전월</option>
<option value="0" selected>당월</option>
<option value="1">익월</option>
</select>
</div>
<div class="col-12 col-md-3 credit-period-only">
<label class="form-label">종료일</label>
<input type="number" name="statement_end_day" class="form-control" min="1" max="31" placeholder="예: 10">
</div>
<div class="col-12 credit-only">
<label class="form-label">메모</label>
<input type="text" name="billing_cycle_memo" class="form-control" placeholder="예: 전월 11일 ~ 당월 10일 사용분">
</div>
<div class="col-12 check-only" style="display:none;">
<div class="alert alert-secondary mb-0">
체크카드는 즉시출금 기준으로 처리됩니다.
</div>
</div>
</div>
</div>
</div>
<div class="col-12 d-flex gap-2">
<button class="btn btn-primary">추가</button>
<a href="/accounts.php" class="btn btn-outline-secondary">목록</a>
</div>
</form>
</div>
</div>
<script>
(function () {
const accountTypeEl = document.getElementById('account_type');
const cardWrapEl = document.getElementById('card_setting_wrap');
const cardKindEl = document.getElementById('card_kind');
const useGraceEl = document.getElementById('use_credit_grace_period');
const creditOnlyEls = document.querySelectorAll('.credit-only');
const creditPeriodOnlyEls = document.querySelectorAll('.credit-period-only');
const checkOnlyEls = document.querySelectorAll('.check-only');
const openingBalanceEl = document.getElementById('opening_balance');
function comma(v) {
v = String(v).replace(/,/g, '').replace(/[^\d.-]/g, '');
if (!v) return '';
return Number(v).toLocaleString('ko-KR');
}
function show(nodes, on) {
nodes.forEach(el => el.style.display = on ? '' : 'none');
}
function refresh() {
const isCard = accountTypeEl.value === 'card';
const isCredit = cardKindEl.value === 'credit';
const isCheck = cardKindEl.value === 'check';
const useGrace = useGraceEl.checked;
cardWrapEl.style.display = isCard ? '' : 'none';
show(creditOnlyEls, isCredit);
show(checkOnlyEls, isCheck);
show(creditPeriodOnlyEls, isCredit && useGrace);
}
openingBalanceEl.addEventListener('input', function () {
this.value = comma(this.value);
});
document.getElementById('accountCreateForm').addEventListener('submit', function () {
openingBalanceEl.value = openingBalanceEl.value.replace(/,/g, '');
});
accountTypeEl.addEventListener('change', refresh);
cardKindEl.addEventListener('change', refresh);
useGraceEl.addEventListener('change', refresh);
refresh();
})();
</script>
<?php require __DIR__ . '/../app/views/footer.php'; ?>