|
|
|
@ -5,18 +5,12 @@ 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
|
|
|
|
|
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 validate_number(n):
|
|
|
|
def validate_number(n):
|
|
|
|
return n if n is not None else 0
|
|
|
|
return n if n is not None else 0
|
|
|
|
|
|
|
|
|
|
|
|
@ -70,6 +64,7 @@ def hitung_pv(rate, nper, fv):
|
|
|
|
def hitung_irr(cashflows: list):
|
|
|
|
def hitung_irr(cashflows: list):
|
|
|
|
return npf.irr(cashflows)
|
|
|
|
return npf.irr(cashflows)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getproyeksilinier(years, values, iterations=30, target_years=None):
|
|
|
|
def getproyeksilinier(years, values, iterations=30, target_years=None):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Jika target_years diberikan (list[int]), fungsi mengembalikan prediksi untuk tahun-tahun tersebut.
|
|
|
|
Jika target_years diberikan (list[int]), fungsi mengembalikan prediksi untuk tahun-tahun tersebut.
|
|
|
|
@ -131,10 +126,8 @@ def getproyeksilinier(years, values, iterations=30, target_years=None):
|
|
|
|
return {start_year + i: _predict(start_year + i) for i in range(n_projection)}
|
|
|
|
return {start_year + i: _predict(start_year + i) for i in range(n_projection)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
@ -371,7 +364,7 @@ def main():
|
|
|
|
tahun_cod = get_param("tahun_cod")
|
|
|
|
tahun_cod = get_param("tahun_cod")
|
|
|
|
daya_terpasang = get_param("daya_terpasang")
|
|
|
|
daya_terpasang = get_param("daya_terpasang")
|
|
|
|
equity = get_param("equity")
|
|
|
|
equity = get_param("equity")
|
|
|
|
|
|
|
|
|
|
|
|
params = []
|
|
|
|
params = []
|
|
|
|
revenue_total_array = []
|
|
|
|
revenue_total_array = []
|
|
|
|
cost_a_acquisition_array = []
|
|
|
|
cost_a_acquisition_array = []
|
|
|
|
@ -403,8 +396,10 @@ def main():
|
|
|
|
cur.execute("""
|
|
|
|
cur.execute("""
|
|
|
|
SELECT year as tahun, cf, eaf
|
|
|
|
SELECT year as tahun, cf, eaf
|
|
|
|
FROM lcc_ms_year_data
|
|
|
|
FROM lcc_ms_year_data
|
|
|
|
|
|
|
|
order by year asc
|
|
|
|
""")
|
|
|
|
""")
|
|
|
|
year_rows = cur.fetchall()
|
|
|
|
year_rows = cur.fetchall()
|
|
|
|
|
|
|
|
print(year_rows)
|
|
|
|
year_data_map = {int(t): (validate_number(cf), validate_number(eaf)) for (t, cf, eaf) in year_rows if
|
|
|
|
year_data_map = {int(t): (validate_number(cf), validate_number(eaf)) for (t, cf, eaf) in year_rows if
|
|
|
|
t is not None}
|
|
|
|
t is not None}
|
|
|
|
|
|
|
|
|
|
|
|
@ -446,7 +441,6 @@ def main():
|
|
|
|
revenue_c = price_c * production_netto * 1000 / 1000000
|
|
|
|
revenue_c = price_c * production_netto * 1000 / 1000000
|
|
|
|
revenue_d = price_d * production_netto * 1000 / 1000000
|
|
|
|
revenue_d = price_d * production_netto * 1000 / 1000000
|
|
|
|
cost_c_fuel = fuel_consumption * harga_bahan_bakar / 1000000
|
|
|
|
cost_c_fuel = fuel_consumption * harga_bahan_bakar / 1000000
|
|
|
|
# default fallback tetap pakai last value kalau tahun kosong / prediksi tidak ada
|
|
|
|
|
|
|
|
if yr is not None:
|
|
|
|
if yr is not None:
|
|
|
|
cost_bd_om = proj_cost_bd_om.get(yr, cost_bd_om)
|
|
|
|
cost_bd_om = proj_cost_bd_om.get(yr, cost_bd_om)
|
|
|
|
cost_bd_pm_nonmi = proj_cost_bd_pm.get(yr, cost_bd_pm_nonmi)
|
|
|
|
cost_bd_pm_nonmi = proj_cost_bd_pm.get(yr, cost_bd_pm_nonmi)
|
|
|
|
@ -499,8 +493,7 @@ def main():
|
|
|
|
+ cost_a_pm
|
|
|
|
+ cost_a_pm
|
|
|
|
# + cost_a_pinjaman
|
|
|
|
# + cost_a_pinjaman
|
|
|
|
# + cost_a_depreciation
|
|
|
|
# + cost_a_depreciation
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
cost_a_replacement = 0
|
|
|
|
cost_a_replacement = 0
|
|
|
|
cost_a_pm = 0
|
|
|
|
cost_a_pm = 0
|
|
|
|
@ -525,7 +518,6 @@ def main():
|
|
|
|
cost_a_annualized = 0
|
|
|
|
cost_a_annualized = 0
|
|
|
|
cost_disposal_cost = 0
|
|
|
|
cost_disposal_cost = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
chart_capex_biaya_investasi_tambahan = 0
|
|
|
|
chart_capex_biaya_investasi_tambahan = 0
|
|
|
|
chart_capex_acquisition_cost = 0
|
|
|
|
chart_capex_acquisition_cost = 0
|
|
|
|
|
|
|
|
|
|
|
|
@ -609,9 +601,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)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
params.append((
|
|
|
|
|
|
|
|
|
|
|
|
row_params = (
|
|
|
|
|
|
|
|
net_capacity_factor,
|
|
|
|
net_capacity_factor,
|
|
|
|
eaf,
|
|
|
|
eaf,
|
|
|
|
production_bruto,
|
|
|
|
production_bruto,
|
|
|
|
@ -679,9 +669,8 @@ def main():
|
|
|
|
chart_capex_acquisition_cost,
|
|
|
|
chart_capex_acquisition_cost,
|
|
|
|
chart_capex_annualized,
|
|
|
|
chart_capex_annualized,
|
|
|
|
cost_disposal_cost,
|
|
|
|
cost_disposal_cost,
|
|
|
|
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:
|
|
|
|
@ -734,15 +723,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__":
|
|
|
|
|