asd
This commit is contained in:
commit
3e4a056b14
67 files changed
+13926
No files matched your search
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/db.php';
|
||||
|
||||
const SERUBI_PRODUCTS = ['giro' => 'Giro Umum', 'simanja' => 'Tabungan SIMANJA', 'simpeda' => 'Tabungan SIMPEDA'];
|
||||
|
||||
const SERUBI_GROUPS = [
|
||||
'dana' => ['Struktur dana', 'Bagaimana dana nasabah dibagi sebelum menghasilkan pendapatan.'],
|
||||
'bunga' => ['Suku bunga pendapatan', 'Rate yang menghasilkan pendapatan bank dari dana kelolaan.'],
|
||||
'biaya' => ['Biaya', 'Biaya yang mengurangi spread sebelum dibagi ke nasabah.'],
|
||||
'pajak' => ['Pajak', 'Tarif pajak atas bunga dan cashback.'],
|
||||
'konvensi' => ['Konvensi perhitungan', 'Hari bunga, pinalti, dan batas minimal.'],
|
||||
];
|
||||
|
||||
/** Raw settings rows keyed by skey. */
|
||||
function settings_rows(): array
|
||||
{
|
||||
$rows = db()->query('SELECT * FROM settings ORDER BY sort')->fetchAll();
|
||||
return array_column($rows, null, 'skey');
|
||||
}
|
||||
|
||||
function to_num($v): ?float
|
||||
{
|
||||
return $v === null ? null : (float)$v;
|
||||
}
|
||||
|
||||
const PARAMS_CACHE_TTL = 300; // seconds; the cache is also cleared whenever an admin saves
|
||||
|
||||
function params_cache_file(): string
|
||||
{
|
||||
$dir = (string)(app_config()['app']['cache_dir'] ?? '');
|
||||
if ($dir === '') {
|
||||
$dir = sys_get_temp_dir() . '/serubi-' . substr(md5(__DIR__), 0, 12);
|
||||
}
|
||||
return rtrim($dir, '/\\') . '/params.json';
|
||||
}
|
||||
|
||||
/** Parameters in the shape assets/js/engine.js expects (cached to spare the database). */
|
||||
function load_params(): array
|
||||
{
|
||||
$file = params_cache_file();
|
||||
if (is_file($file) && time() - (int)@filemtime($file) < PARAMS_CACHE_TTL) {
|
||||
$cached = json_decode((string)@file_get_contents($file), true);
|
||||
if (is_array($cached) && isset($cached['settings'])) {
|
||||
return $cached;
|
||||
}
|
||||
}
|
||||
$params = load_params_db();
|
||||
$dir = dirname($file);
|
||||
if (is_dir($dir) || @mkdir($dir, 0700, true)) {
|
||||
$tmp = $file . '.' . bin2hex(random_bytes(4));
|
||||
if (@file_put_contents($tmp, json_encode($params, JSON_PRESERVE_ZERO_FRACTION)) !== false) {
|
||||
@rename($tmp, $file);
|
||||
}
|
||||
@unlink($tmp);
|
||||
}
|
||||
return $params;
|
||||
}
|
||||
|
||||
function params_cache_clear(): void
|
||||
{
|
||||
@unlink(params_cache_file());
|
||||
}
|
||||
|
||||
function load_params_db(): array
|
||||
{
|
||||
$pdo = db();
|
||||
$settings = [];
|
||||
$updated = null;
|
||||
foreach (settings_rows() as $key => $row) {
|
||||
$settings[$key] = (float)$row['value'];
|
||||
$updated = max($updated ?? '', $row['updated_at']);
|
||||
}
|
||||
|
||||
$tenors = $pdo->query('SELECT months, cashback FROM tenors ORDER BY months')->fetchAll();
|
||||
|
||||
$productRates = array_fill_keys(array_keys(SERUBI_PRODUCTS), []);
|
||||
foreach ($pdo->query('SELECT product, max_nominal, rate FROM product_rates ORDER BY product, sort, id') as $r) {
|
||||
$productRates[$r['product']][] = ['max' => to_num($r['max_nominal']), 'rate' => (float)$r['rate']];
|
||||
}
|
||||
|
||||
$bands = $pdo->query('SELECT id, max_nominal FROM deposito_bands ORDER BY sort, id')->fetchAll();
|
||||
$rates = [];
|
||||
foreach ($pdo->query('SELECT band_id, tenor, rate FROM deposito_rates') as $r) {
|
||||
$rates[$r['band_id']][$r['tenor']] = (float)$r['rate'];
|
||||
}
|
||||
$depositoRates = [];
|
||||
foreach ($tenors as $t) {
|
||||
$m = (int)$t['months'];
|
||||
$depositoRates[$m] = array_map(fn($b) => [
|
||||
'max' => to_num($b['max_nominal']),
|
||||
'rate' => $rates[$b['id']][$m] ?? 0.0,
|
||||
], $bands);
|
||||
}
|
||||
|
||||
$tiers = array_map(fn($r) => ['min' => (float)$r['min_nominal'], 'nasabah' => (float)$r['share_nasabah']],
|
||||
$pdo->query('SELECT min_nominal, share_nasabah FROM cashback_tiers ORDER BY min_nominal')->fetchAll());
|
||||
|
||||
$last = $pdo->query("SELECT username, created_at FROM audit_log WHERE action LIKE 'param%' ORDER BY id DESC LIMIT 1")->fetch();
|
||||
|
||||
return [
|
||||
'settings' => $settings,
|
||||
'tenors' => array_map(fn($t) => (int)$t['months'], $tenors),
|
||||
'cashbackTenors' => array_values(array_map(fn($t) => (int)$t['months'], array_filter($tenors, fn($t) => (int)$t['cashback'] === 1))),
|
||||
'productRates' => $productRates,
|
||||
'depositoBands' => array_map(fn($b) => to_num($b['max_nominal']), $bands),
|
||||
'depositoRates' => $depositoRates,
|
||||
'cashbackTiers' => $tiers,
|
||||
'updatedAt' => $last['created_at'] ?? $updated,
|
||||
'updatedBy' => $last['username'] ?? null,
|
||||
];
|
||||
}
|
||||
Reference in new issue
Block a user