Initial financial project import
This commit is contained in:
@@ -0,0 +1,325 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/db.php';
|
||||
require_once __DIR__ . '/helpers.php';
|
||||
|
||||
/*
|
||||
테이블 필요
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_transaction_defaults (
|
||||
user_id BIGINT UNSIGNED NOT NULL PRIMARY KEY,
|
||||
default_account_id BIGINT UNSIGNED DEFAULT NULL,
|
||||
default_card_account_id BIGINT UNSIGNED DEFAULT NULL,
|
||||
default_income_category_id BIGINT UNSIGNED DEFAULT NULL,
|
||||
default_expense_category_id BIGINT UNSIGNED DEFAULT NULL,
|
||||
default_transfer_category_id BIGINT UNSIGNED DEFAULT NULL,
|
||||
default_card_payment_category_id BIGINT UNSIGNED DEFAULT NULL,
|
||||
keep_last_values TINYINT(1) NOT NULL DEFAULT 1,
|
||||
continue_after_save TINYINT(1) NOT NULL DEFAULT 1,
|
||||
quick_amounts VARCHAR(255) DEFAULT NULL,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
ON UPDATE CURRENT_TIMESTAMP
|
||||
);
|
||||
*/
|
||||
|
||||
function get_transaction_form_defaults(int $userId): array
|
||||
{
|
||||
$pdo = db();
|
||||
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT *
|
||||
FROM user_transaction_defaults
|
||||
WHERE user_id = ?
|
||||
LIMIT 1
|
||||
");
|
||||
$stmt->execute([$userId]);
|
||||
|
||||
$row = $stmt->fetch();
|
||||
|
||||
if (!$row) {
|
||||
return get_transaction_form_default_seed();
|
||||
}
|
||||
|
||||
$row['keep_last_values'] = (int)$row['keep_last_values'];
|
||||
$row['continue_after_save'] = (int)$row['continue_after_save'];
|
||||
$row['quick_amounts'] = parse_quick_amounts($row['quick_amounts'] ?? '');
|
||||
|
||||
return array_merge(get_transaction_form_default_seed(), $row);
|
||||
}
|
||||
|
||||
function get_transaction_form_default_seed(): array
|
||||
{
|
||||
return [
|
||||
'default_account_id' => null,
|
||||
'default_card_account_id' => null,
|
||||
|
||||
'default_income_category_id' => null,
|
||||
'default_expense_category_id' => null,
|
||||
'default_transfer_category_id' => null,
|
||||
'default_card_payment_category_id' => null,
|
||||
|
||||
'keep_last_values' => 1,
|
||||
'continue_after_save' => 1,
|
||||
|
||||
'quick_amounts' => [10000, 30000, 50000, 100000],
|
||||
];
|
||||
}
|
||||
|
||||
function save_transaction_form_defaults(int $userId, array $data): void
|
||||
{
|
||||
$pdo = db();
|
||||
|
||||
$quickAmounts = normalize_quick_amounts(
|
||||
$data['quick_amounts'] ?? []
|
||||
);
|
||||
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO user_transaction_defaults
|
||||
(
|
||||
user_id,
|
||||
default_account_id,
|
||||
default_card_account_id,
|
||||
default_income_category_id,
|
||||
default_expense_category_id,
|
||||
default_transfer_category_id,
|
||||
default_card_payment_category_id,
|
||||
keep_last_values,
|
||||
continue_after_save,
|
||||
quick_amounts
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
default_account_id = VALUES(default_account_id),
|
||||
default_card_account_id = VALUES(default_card_account_id),
|
||||
default_income_category_id = VALUES(default_income_category_id),
|
||||
default_expense_category_id = VALUES(default_expense_category_id),
|
||||
default_transfer_category_id = VALUES(default_transfer_category_id),
|
||||
default_card_payment_category_id = VALUES(default_card_payment_category_id),
|
||||
keep_last_values = VALUES(keep_last_values),
|
||||
continue_after_save = VALUES(continue_after_save),
|
||||
quick_amounts = VALUES(quick_amounts)
|
||||
");
|
||||
|
||||
$stmt->execute([
|
||||
$userId,
|
||||
|
||||
nullable_id($data['default_account_id'] ?? null),
|
||||
nullable_id($data['default_card_account_id'] ?? null),
|
||||
|
||||
nullable_id($data['default_income_category_id'] ?? null),
|
||||
nullable_id($data['default_expense_category_id'] ?? null),
|
||||
nullable_id($data['default_transfer_category_id'] ?? null),
|
||||
nullable_id($data['default_card_payment_category_id'] ?? null),
|
||||
|
||||
!empty($data['keep_last_values']) ? 1 : 0,
|
||||
!empty($data['continue_after_save']) ? 1 : 0,
|
||||
|
||||
implode(',', $quickAmounts),
|
||||
]);
|
||||
}
|
||||
|
||||
function nullable_id($value): ?int
|
||||
{
|
||||
$v = (int)$value;
|
||||
|
||||
return $v > 0 ? $v : null;
|
||||
}
|
||||
|
||||
function parse_quick_amounts(string $csv): array
|
||||
{
|
||||
if (trim($csv) === '') {
|
||||
return [10000, 30000, 50000, 100000];
|
||||
}
|
||||
|
||||
$items = explode(',', $csv);
|
||||
$result = [];
|
||||
|
||||
foreach ($items as $item) {
|
||||
$v = (int)trim($item);
|
||||
if ($v > 0) {
|
||||
$result[] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$result) {
|
||||
return [10000, 30000, 50000, 100000];
|
||||
}
|
||||
|
||||
return array_values(array_unique($result));
|
||||
}
|
||||
|
||||
function normalize_quick_amounts(array $items): array
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($items as $item) {
|
||||
$v = (int)$item;
|
||||
if ($v > 0) {
|
||||
$result[] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$result) {
|
||||
$result = [10000, 30000, 50000, 100000];
|
||||
}
|
||||
|
||||
$result = array_values(array_unique($result));
|
||||
sort($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 거래 등록 화면 초기값
|
||||
*/
|
||||
function build_transaction_form_state(
|
||||
int $userId,
|
||||
array $defaults,
|
||||
?array $lastState = null
|
||||
): array {
|
||||
$state = [
|
||||
'transaction_date' => current_date_ymd(),
|
||||
'transaction_type' => 'expense',
|
||||
|
||||
'account_id' => $defaults['default_account_id'] ?: 0,
|
||||
'related_account_id' => 0,
|
||||
|
||||
'category_id' => $defaults['default_expense_category_id'] ?: 0,
|
||||
|
||||
'amount' => '',
|
||||
'merchant_name' => '',
|
||||
'description' => '',
|
||||
|
||||
'is_installment' => 0,
|
||||
'installment_months' => '',
|
||||
'installment_interest_rate' => '',
|
||||
|
||||
'continue_after_save' => $defaults['continue_after_save'],
|
||||
'keep_last_values' => $defaults['keep_last_values'],
|
||||
'save_as_defaults' => 0,
|
||||
];
|
||||
|
||||
if (!empty($defaults['keep_last_values']) && is_array($lastState)) {
|
||||
$state = array_merge($state, $lastState);
|
||||
$state['transaction_date'] = current_date_ymd();
|
||||
$state['amount'] = '';
|
||||
}
|
||||
|
||||
return $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* 유형 변경 시 기본 카테고리 자동 선택
|
||||
*/
|
||||
function apply_default_category_by_type(array &$state, array $defaults): void
|
||||
{
|
||||
$type = $state['transaction_type'] ?? 'expense';
|
||||
|
||||
if ($type === 'income') {
|
||||
$state['category_id'] = $defaults['default_income_category_id'] ?: 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($type === 'expense') {
|
||||
$state['category_id'] = $defaults['default_expense_category_id'] ?: 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($type === 'transfer') {
|
||||
$state['category_id'] = $defaults['default_transfer_category_id'] ?: 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($type === 'card_payment') {
|
||||
$state['category_id'] = $defaults['default_card_payment_category_id'] ?: 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 카드 지출이면 카드 기본계좌 우선 적용
|
||||
*/
|
||||
function apply_default_card_account(array &$state, array $defaults): void
|
||||
{
|
||||
if (($state['transaction_type'] ?? '') !== 'expense') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!empty($defaults['default_card_account_id'])) {
|
||||
$state['account_id'] = (int)$defaults['default_card_account_id'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 저장 후 마지막 상태 저장
|
||||
*/
|
||||
function remember_transaction_form_state(array $state): void
|
||||
{
|
||||
$_SESSION['tx_create_last_form'] = [
|
||||
'transaction_type' => $state['transaction_type'],
|
||||
'account_id' => $state['account_id'],
|
||||
'related_account_id' => $state['related_account_id'],
|
||||
'category_id' => $state['category_id'],
|
||||
|
||||
'merchant_name' => $state['merchant_name'],
|
||||
'description' => '',
|
||||
|
||||
'is_installment' => $state['is_installment'],
|
||||
'installment_months' => $state['installment_months'],
|
||||
'installment_interest_rate' => $state['installment_interest_rate'],
|
||||
|
||||
'continue_after_save' => $state['continue_after_save'],
|
||||
'keep_last_values' => $state['keep_last_values'],
|
||||
|
||||
'transaction_date' => current_date_ymd(),
|
||||
'amount' => '',
|
||||
];
|
||||
}
|
||||
|
||||
function get_remembered_transaction_form_state(): ?array
|
||||
{
|
||||
return $_SESSION['tx_create_last_form'] ?? null;
|
||||
}
|
||||
|
||||
function clear_remembered_transaction_form_state(): void
|
||||
{
|
||||
unset($_SESSION['tx_create_last_form']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 기본값 자동 저장용 데이터 만들기
|
||||
*/
|
||||
function make_default_payload_from_form(array $state): array
|
||||
{
|
||||
$payload = [
|
||||
'default_account_id' => 0,
|
||||
'default_card_account_id' => 0,
|
||||
|
||||
'default_income_category_id' => 0,
|
||||
'default_expense_category_id' => 0,
|
||||
'default_transfer_category_id' => 0,
|
||||
'default_card_payment_category_id' => 0,
|
||||
|
||||
'keep_last_values' => $state['keep_last_values'] ?? 1,
|
||||
'continue_after_save' => $state['continue_after_save'] ?? 1,
|
||||
];
|
||||
|
||||
$type = $state['transaction_type'] ?? 'expense';
|
||||
|
||||
if ($type === 'income') {
|
||||
$payload['default_account_id'] = $state['account_id'];
|
||||
$payload['default_income_category_id'] = $state['category_id'];
|
||||
} elseif ($type === 'expense') {
|
||||
$payload['default_account_id'] = $state['account_id'];
|
||||
$payload['default_expense_category_id'] = $state['category_id'];
|
||||
$payload['default_card_account_id'] = $state['account_id'];
|
||||
} elseif ($type === 'transfer') {
|
||||
$payload['default_account_id'] = $state['account_id'];
|
||||
$payload['default_transfer_category_id'] = $state['category_id'];
|
||||
} elseif ($type === 'card_payment') {
|
||||
$payload['default_account_id'] = $state['account_id'];
|
||||
$payload['default_card_payment_category_id'] = $state['category_id'];
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
Reference in New Issue
Block a user