|
|
|
@ -5,7 +5,6 @@ import sys
|
|
|
|
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
|
|
|
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
|
|
|
from config import get_connection # harus mengembalikan koneksi psycopg2
|
|
|
|
from config import get_connection # harus mengembalikan koneksi psycopg2
|
|
|
|
from math import pow
|
|
|
|
from math import pow
|
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
import numpy_financial as npf
|
|
|
|
import numpy_financial as npf
|
|
|
|
import math
|
|
|
|
import math
|
|
|
|
import uuid
|
|
|
|
import uuid
|
|
|
|
@ -15,13 +14,6 @@ def validate_number(n):
|
|
|
|
return n if n is not None else 0
|
|
|
|
return n if n is not None else 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def normalize_db_value(value):
|
|
|
|
|
|
|
|
"""Convert numpy scalars to native Python types for psycopg2."""
|
|
|
|
|
|
|
|
if isinstance(value, np.generic):
|
|
|
|
|
|
|
|
return value.item()
|
|
|
|
|
|
|
|
return value
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def cumulative_npv(values, rate, initial_cf0=0.0):
|
|
|
|
def cumulative_npv(values, rate, initial_cf0=0.0):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Penggunaan:
|
|
|
|
Penggunaan:
|
|
|
|
@ -73,8 +65,7 @@ def hitung_irr(cashflows: list):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
def main():
|
|
|
|
connections = get_connection()
|
|
|
|
conn = get_connection()
|
|
|
|
conn = connections[0] if isinstance(connections, tuple) else connections
|
|
|
|
|
|
|
|
if conn is None:
|
|
|
|
if conn is None:
|
|
|
|
print("Koneksi ke database gagal.")
|
|
|
|
print("Koneksi ke database gagal.")
|
|
|
|
sys.exit(1)
|
|
|
|
sys.exit(1)
|
|
|
|
@ -300,6 +291,17 @@ def main():
|
|
|
|
cost_a_pm = 0
|
|
|
|
cost_a_pm = 0
|
|
|
|
cost_a_pinjaman = 0
|
|
|
|
cost_a_pinjaman = 0
|
|
|
|
cost_a_depreciation = 0
|
|
|
|
cost_a_depreciation = 0
|
|
|
|
|
|
|
|
net_capacity_factor_v = 0
|
|
|
|
|
|
|
|
eaf_v = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Prefetch master data CF dan EAF sekali saja di luar loop
|
|
|
|
|
|
|
|
cur.execute("""
|
|
|
|
|
|
|
|
SELECT year as tahun, cf, eaf
|
|
|
|
|
|
|
|
FROM lcc_ms_year_data
|
|
|
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
year_rows = cur.fetchall()
|
|
|
|
|
|
|
|
year_data_map = {int(t): (validate_number(cf), validate_number(eaf)) for (t, cf, eaf) in year_rows if
|
|
|
|
|
|
|
|
t is not None}
|
|
|
|
|
|
|
|
|
|
|
|
for row in rows:
|
|
|
|
for row in rows:
|
|
|
|
# row adalah tuple sesuai urutan select_sql
|
|
|
|
# row adalah tuple sesuai urutan select_sql
|
|
|
|
@ -307,9 +309,15 @@ def main():
|
|
|
|
|
|
|
|
|
|
|
|
seq = data["seq"] # primary key / unique key untuk WHERE
|
|
|
|
seq = data["seq"] # primary key / unique key untuk WHERE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Ambil net_capacity_factor dan eaf dari cache berdasarkan tahun
|
|
|
|
|
|
|
|
cf_eaf = year_data_map.get(int(data["tahun"])) if data.get("tahun") is not None else None
|
|
|
|
|
|
|
|
if cf_eaf:
|
|
|
|
|
|
|
|
net_capacity_factor_v, eaf_v = cf_eaf
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
net_capacity_factor_v = 0
|
|
|
|
|
|
|
|
eaf_v = 0
|
|
|
|
|
|
|
|
|
|
|
|
if data["is_actual"] == 1:
|
|
|
|
if data["is_actual"] == 1:
|
|
|
|
net_capacity_factor = validate_number(data["net_capacity_factor"])
|
|
|
|
|
|
|
|
eaf = validate_number(data["eaf"])
|
|
|
|
|
|
|
|
production_bruto = validate_number(data["production_bruto"])
|
|
|
|
production_bruto = validate_number(data["production_bruto"])
|
|
|
|
production_netto = validate_number(data["production_netto"])
|
|
|
|
production_netto = validate_number(data["production_netto"])
|
|
|
|
energy_sales = production_netto
|
|
|
|
energy_sales = production_netto
|
|
|
|
@ -323,8 +331,6 @@ def main():
|
|
|
|
cost_bd_pm_nonmi = validate_number(data["cost_bd_pm_nonmi"])
|
|
|
|
cost_bd_pm_nonmi = validate_number(data["cost_bd_pm_nonmi"])
|
|
|
|
cost_bd_bd = validate_number(data["cost_bd_bd"])
|
|
|
|
cost_bd_bd = validate_number(data["cost_bd_bd"])
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
net_capacity_factor = net_capacity_factor # last value
|
|
|
|
|
|
|
|
eaf = eaf # last value
|
|
|
|
|
|
|
|
production_netto = net_capacity_factor * 8760 * daya_mampu_netto / 100
|
|
|
|
production_netto = net_capacity_factor * 8760 * daya_mampu_netto / 100
|
|
|
|
production_bruto = production_netto / (100 - (auxiliary + susut_trafo)) * 100
|
|
|
|
production_bruto = production_netto / (100 - (auxiliary + susut_trafo)) * 100
|
|
|
|
energy_sales = production_netto
|
|
|
|
energy_sales = production_netto
|
|
|
|
@ -338,6 +344,9 @@ def main():
|
|
|
|
cost_bd_pm_nonmi = cost_bd_pm_nonmi # last value
|
|
|
|
cost_bd_pm_nonmi = cost_bd_pm_nonmi # last value
|
|
|
|
cost_bd_bd = cost_bd_bd # last value
|
|
|
|
cost_bd_bd = cost_bd_bd # last value
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
net_capacity_factor = net_capacity_factor_v
|
|
|
|
|
|
|
|
eaf = eaf_v
|
|
|
|
|
|
|
|
|
|
|
|
# ++++++ REVENUE +++++++
|
|
|
|
# ++++++ REVENUE +++++++
|
|
|
|
revenue_total = revenue_a + revenue_b + revenue_c + revenue_d
|
|
|
|
revenue_total = revenue_a + revenue_b + revenue_c + revenue_d
|
|
|
|
if seq > 0:
|
|
|
|
if seq > 0:
|
|
|
|
@ -483,7 +492,7 @@ def main():
|
|
|
|
calc4_free_cash_flow_on_equity_array.append(calc4_free_cash_flow_on_equity)
|
|
|
|
calc4_free_cash_flow_on_equity_array.append(calc4_free_cash_flow_on_equity)
|
|
|
|
calc4_discounted_fcf_on_equity = hitung_pv(wacc_on_equity, seq, calc4_free_cash_flow_on_equity)
|
|
|
|
calc4_discounted_fcf_on_equity = hitung_pv(wacc_on_equity, seq, calc4_free_cash_flow_on_equity)
|
|
|
|
|
|
|
|
|
|
|
|
row_params = (
|
|
|
|
params.append((
|
|
|
|
net_capacity_factor,
|
|
|
|
net_capacity_factor,
|
|
|
|
eaf,
|
|
|
|
eaf,
|
|
|
|
production_bruto,
|
|
|
|
production_bruto,
|
|
|
|
@ -551,8 +560,7 @@ def main():
|
|
|
|
chart_capex_acquisition_cost,
|
|
|
|
chart_capex_acquisition_cost,
|
|
|
|
chart_capex_annualized,
|
|
|
|
chart_capex_annualized,
|
|
|
|
seq # <-- penting: ini untuk WHERE
|
|
|
|
seq # <-- penting: ini untuk WHERE
|
|
|
|
)
|
|
|
|
))
|
|
|
|
params.append(tuple(normalize_db_value(v) for v in row_params))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 3. Bulk update dengan executemany
|
|
|
|
# 3. Bulk update dengan executemany
|
|
|
|
if params:
|
|
|
|
if params:
|
|
|
|
@ -605,15 +613,13 @@ def main():
|
|
|
|
conn.close()
|
|
|
|
conn.close()
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
except Exception as e:
|
|
|
|
if conn:
|
|
|
|
conn.rollback()
|
|
|
|
conn.rollback()
|
|
|
|
|
|
|
|
print(f"Terjadi error, transaksi di-rollback. Error: {e}")
|
|
|
|
print(f"Terjadi error, transaksi di-rollback. Error: {e}")
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
cur.close()
|
|
|
|
cur.close()
|
|
|
|
except Exception:
|
|
|
|
except Exception:
|
|
|
|
pass
|
|
|
|
pass
|
|
|
|
if conn:
|
|
|
|
conn.close()
|
|
|
|
conn.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|