Compare commits

..

No commits in common. '77701e795d0ed8b1899ac989a68ed078cccfd3ba' and 'cb229086e8cabf290386d37c01a7de6bd70426c8' have entirely different histories.

2
.gitignore vendored

@ -1,6 +1,6 @@
env/
.env
.idea
__pycache__/*
venv/

@ -110,7 +110,7 @@ def fetch_param_map(cur) -> Dict[str, Param]:
'wacc_on_equity','wacc_on_project','calc_on_equity_irr','calc_on_equity_npv',
'calc_on_project_irr','calc_on_project_npv','calc_roa_all','calc_roa_current'
)
ORDER BY seq ASC
ORDER BY name
"""
)
rows = cur.fetchall()

@ -1,19 +1,14 @@
import os
import sys
# Tambah path ke config.py (seperti di kode-kode kamu sebelumnya)
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from config import get_connection # harus mengembalikan koneksi psycopg2
from math import pow
import numpy_financial as npf
import math
import uuid
def validate_number(n):
return n if n is not None else 0
def cumulative_npv(values, rate, initial_cf0=0.0):
"""
Penggunaan:
@ -29,8 +24,6 @@ def cumulative_npv(values, rate, initial_cf0=0.0):
cumulative_results.append(initial_cf0 + running_npv)
return cumulative_results
def pmt_excel_style(rate, periods, pv):
"""
Fungsi ini menghasilkan nilai setara Excel:
@ -53,17 +46,12 @@ def pmt_excel_style(rate, periods, pv):
# Excel memberi hasil negatif, tapi rumusmu pakai -PMT, maka hasilnya positif
return abs(payment)
def hitung_pv(rate, nper, fv):
pv = npf.pv(rate, nper, pmt=0, fv=fv)
return -pv
def hitung_irr(cashflows: list):
return npf.irr(cashflows)
def main():
conn = get_connection()
if conn is None:
@ -71,90 +59,14 @@ def main():
sys.exit(1)
try:
# ### LOCKING: pastikan transaksi manual (non-autocommit)
try:
conn.autocommit = False
except Exception:
# Kalau driver tidak punya autocommit, abaikan
pass
cur = conn.cursor()
# ### LOCKING: kunci tabel lcc_plant_tr_data
# Mode SHARE ROW EXCLUSIVE:
# - Menghalangi INSERT/UPDATE/DELETE di tabel ini
# - Menghalangi lock SHARE ROW EXCLUSIVE lain → script ngantri satu per satu
cur.execute("LOCK TABLE lcc_plant_tr_data IN SHARE ROW EXCLUSIVE MODE")
# 0 Mendapatkan master parameter dari tabel lcc_ms_master
cur.execute("""
SELECT name,
value_num AS value
FROM lcc_ms_master
""")
param_rows = cur.fetchall()
param_map = {name: val for (name, val) in param_rows}
# helper biar aman
def get_param(name, default=0.0):
v = param_map.get(name, default)
return float(v) if v is not None else float(default)
# 0-1 Generate New data Projection (is_actual=0) if not exist
# Hapus data projection lama (is_actual = 0)
cur.execute("""
DELETE
FROM lcc_plant_tr_data
WHERE is_actual = 0
""")
# Hitung kebutuhan jumlah baris projection baru agar total (actual + projection)
# sama dengan parameter umur_teknis
cur.execute("""
SELECT COALESCE(COUNT(*), 0)
FROM lcc_plant_tr_data
WHERE is_actual = 1
""")
count_actual = cur.fetchone()[0] if cur.rowcount != -1 else 0
umur_teknis = int(get_param("umur_teknis"))
proj_needed = max(0, umur_teknis - int(count_actual))
# Ambil seq dan tahun terakhir sebagai titik awal penomoran berikutnya
cur.execute("SELECT COALESCE(MAX(seq), 0) FROM lcc_plant_tr_data")
last_seq = int(cur.fetchone()[0])
cur.execute("SELECT COALESCE(MAX(tahun), 0) FROM lcc_plant_tr_data")
last_year = int(cur.fetchone()[0])
# Jika belum ada tahun sama sekali, gunakan tahun_cod-1 sebagai dasar
if last_year == 0:
try:
last_year = int(get_param("tahun_cod")) - 1
except Exception:
last_year = 0
if proj_needed > 0:
# Siapkan rows untuk INSERT projection baru
values = []
next_seq = last_seq + 1
next_year = last_year + 1
for _ in range(proj_needed):
values.append((str(uuid.uuid4()), next_seq, next_year))
next_seq += 1
next_year += 1
insert_sql = (
"INSERT INTO lcc_plant_tr_data (id, seq, tahun, is_actual, created_at, created_by) "
"VALUES (%s, %s, %s, 0, CURRENT_TIMESTAMP, 'SYS')"
)
cur.executemany(insert_sql, values)
# 1. Ambil data awal
select_sql = """
SELECT *
SELECT
*
FROM lcc_plant_tr_data
ORDER BY seq \
ORDER BY seq
"""
cur.execute(select_sql)
@ -166,7 +78,8 @@ def main():
# 2. Siapkan data untuk bulk UPDATE
update_sql = """
UPDATE lcc_plant_tr_data
SET net_capacity_factor = %s,
SET
net_capacity_factor = %s,
eaf = %s,
production_bruto = %s,
production_netto = %s,
@ -232,9 +145,22 @@ def main():
chart_capex_biaya_investasi_tambahan = %s,
chart_capex_acquisition_cost = %s,
chart_capex_annualized = %s
WHERE seq = %s \
WHERE seq = %s
"""
cur.execute("""
SELECT name,
value_num AS value
FROM lcc_ms_master
""")
param_rows = cur.fetchall()
param_map = {name: val for (name, val) in param_rows}
# helper biar aman
def get_param(name, default=0.0):
v = param_map.get(name, default)
return float(v) if v is not None else float(default)
# Ambil parameter dari tabel (fungsi get_param sudah kamu buat sebelumnya)
discount_rate = get_param("discount_rate") / 100
total_project_cost = get_param("total_project_cost")
@ -329,6 +255,7 @@ def main():
cost_bd_pm_nonmi = cost_bd_pm_nonmi #last value
cost_bd_bd = cost_bd_bd #last value
# ++++++ REVENUE +++++++
revenue_total = revenue_a + revenue_b + revenue_c + revenue_d
if seq > 0:
@ -564,8 +491,7 @@ def main():
calc4_free_cash_flow_on_equity_array[0]
ROA_ALL = sum(calc2_earning_after_tax_array) / sum(total_residual_value_array) * 100 # dalam %
ROA_TO_L = sum(calc2_earning_after_tax_array_sampai_sekarang) / sum(
total_residual_value_array_sampai_sekarang) * 100 # dalam %
ROA_TO_L = sum(calc2_earning_after_tax_array_sampai_sekarang) / sum(total_residual_value_array_sampai_sekarang) * 100 # dalam %
update_kpi_sql = """
UPDATE lcc_ms_master
@ -573,7 +499,7 @@ def main():
WHERE name = %s \
"""
kpi_params_raw = [
kpi_params = [
(IRR_ON_EQUITY * 100, "calc_on_equity_irr"),
(NPV_ON_EQUITY, "calc_on_equity_npv"),
(IRR_ON_PROJECT * 100, "calc_on_project_irr"),
@ -582,11 +508,6 @@ def main():
(ROA_TO_L, "calc_roa_current"),
]
kpi_params = [
(None if (value is None or isinstance(value, float) and math.isnan(value)) else value, key)
for value, key in kpi_params_raw
]
cur.executemany(update_kpi_sql, kpi_params)
conn.commit()
# ===========================================================================

Loading…
Cancel
Save