금융 거래 기록 흐름 공통화

This commit is contained in:
seo
2026-07-20 18:27:41 +09:00
parent 8a64d993c3
commit c86e5a1481
7 changed files with 383 additions and 413 deletions
+41 -116
View File
@@ -1,7 +1,8 @@
<?php
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/account_service.php';
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/account_service.php';
require_once __DIR__ . '/transaction_record_service.php';
function add_months_keep_day(string $date, int $months, int $paymentDay): string
{
@@ -176,110 +177,10 @@ function get_category_id_by_name(int $userId, string $categoryType, string $name
return $row ? (int)$row['id'] : null;
}
function build_tx_fingerprint(
int $userId,
int $accountId,
?int $relatedAccountId,
int $categoryId,
string $transactionType,
float $amount,
string $transactionDate,
?string $merchantName,
?string $description,
?int $sourceLoanId = null
): string {
$raw = implode('|', [
$userId,
$accountId,
$relatedAccountId ?? 0,
$categoryId,
$transactionType,
number_format($amount, 2, '.', ''),
$transactionDate,
trim((string)$merchantName),
trim((string)$description),
$sourceLoanId ?? 0,
]);
return hash('sha256', $raw);
}
function insert_transaction_row(array $data): int
{
$pdo = db();
$sourceLoanId = !empty($data['source_loan_id']) ? (int)$data['source_loan_id'] : null;
$fingerprint = build_tx_fingerprint(
(int)$data['user_id'],
(int)$data['account_id'],
!empty($data['related_account_id']) ? (int)$data['related_account_id'] : null,
(int)$data['category_id'],
(string)$data['transaction_type'],
(float)$data['amount'],
(string)$data['transaction_date'],
$data['merchant_name'] ?? null,
$data['description'] ?? null,
$sourceLoanId
);
$stmt = $pdo->prepare("
SELECT id
FROM transactions
WHERE user_id = ?
AND fingerprint = ?
LIMIT 1
");
$stmt->execute([
$data['user_id'],
$fingerprint
]);
$exists = $stmt->fetch();
if ($exists) {
return (int)$exists['id'];
}
$stmt = $pdo->prepare("
INSERT INTO transactions
(
user_id,
account_id,
category_id,
transaction_type,
amount,
is_installment,
installment_months,
installment_interest_rate,
installment_interest_total,
installment_total_billed,
installment_prepay_amount,
transaction_date,
merchant_name,
description,
related_account_id,
source_loan_id,
fingerprint
)
VALUES (?, ?, ?, ?, ?, 0, NULL, 0, 0, NULL, 0, ?, ?, ?, ?, ?, ?)
");
$stmt->execute([
$data['user_id'],
$data['account_id'],
$data['category_id'],
$data['transaction_type'],
$data['amount'],
$data['transaction_date'],
$data['merchant_name'],
$data['description'],
$data['related_account_id'],
$sourceLoanId,
$fingerprint,
]);
return (int)$pdo->lastInsertId();
}
function insert_transaction_row(array $data): int
{
return insert_transaction_record($data, true);
}
function create_loan_schedule_only(
int $loanId,
@@ -928,20 +829,44 @@ function prepay_loan(
)
VALUES (?, ?, NULL, ?, ?, ?, ?, ?, ?, 'prepayment', 0, ?)
");
$stmt->execute([
$userId,
$loanId,
$accountId ?: null,
$stmt->execute([
$userId,
$loanId,
$accountId ?: null,
$paymentDate,
$principalAmount,
$interestAmount,
$feeAmount,
$totalAmount,
$description,
]);
if ($principalAmount > 0) {
$stmt = $pdo->prepare("
$description,
]);
if (!empty($accountId) && $totalAmount > 0) {
$expenseCategoryId = get_category_id_by_name($userId, 'expense', '대출상환');
if ($expenseCategoryId) {
insert_transaction_row([
'user_id' => $userId,
'account_id' => $accountId,
'category_id' => $expenseCategoryId,
'transaction_type' => 'expense',
'amount' => $totalAmount,
'transaction_date' => $paymentDate,
'merchant_name' => $loan['loan_name'],
'description' => '[대출중도상환] 원금 ' .
number_format($principalAmount, 0) .
' / 이자 ' .
number_format($interestAmount, 0) .
' / 수수료 ' .
number_format($feeAmount, 0),
'related_account_id' => null,
'source_loan_id' => $loanId,
]);
}
}
if ($principalAmount > 0) {
$stmt = $pdo->prepare("
UPDATE loans
SET current_principal_balance = GREATEST(current_principal_balance - ?, 0)
WHERE id = ?
@@ -1151,4 +1076,4 @@ function update_loan_and_rebuild_full_history(int $userId, int $loanId, array $d
}
throw $e;
}
}
}