|
|
{% extends "layout.html" %}
|
|
|
{% block content %}
|
|
|
|
|
|
<div class="row">
|
|
|
<div class="col-lg-4">
|
|
|
<div class="card bg-secondary mb-3">
|
|
|
<div class="card-header">پارامترهای مدل</div>
|
|
|
<div class="card-body">
|
|
|
{% if import_error %}
|
|
|
<div class="alert alert-danger">خطا در بارگذاری main.py — لطفاً فایل و وابستگیها را بررسی کنید.<pre style="white-space:pre-wrap">{{ import_error }}</pre></div>
|
|
|
{% endif %}
|
|
|
<form method="post" action="{{ url_for('run') }}">
|
|
|
<div class="mb-2">
|
|
|
<label class="form-label">نرخ تورم (مثلاً 0.015)</label>
|
|
|
<input name="inflation" type="text" class="form-control" value="{{ defaults.inflation if defaults else '0.015' }}">
|
|
|
</div>
|
|
|
<div class="mb-2">
|
|
|
<label class="form-label">نرخ مالیات (مثلاً 0.10)</label>
|
|
|
<input name="tax" type="text" class="form-control" value="{{ defaults.tax if defaults else '0.10' }}">
|
|
|
</div>
|
|
|
<div class="mb-2">
|
|
|
<label class="form-label">طول پروژه (سال)</label>
|
|
|
<input name="years" type="number" class="form-control" value="{{ defaults.years if defaults else 15 }}">
|
|
|
</div>
|
|
|
<div class="mb-2">
|
|
|
<label class="form-label">ظرفیت (KTA) - حداقل</label>
|
|
|
<input name="cap_min" type="number" step="1" class="form-control" value="{{ defaults.cap_min if defaults else 500 }}">
|
|
|
</div>
|
|
|
<div class="mb-2">
|
|
|
<label class="form-label">ظرفیت (KTA) - حداکثر</label>
|
|
|
<input name="cap_max" type="number" step="1" class="form-control" value="{{ defaults.cap_max if defaults else 600 }}">
|
|
|
</div>
|
|
|
<div class="mb-2">
|
|
|
<label class="form-label">Technology</label>
|
|
|
<select name="technology" class="form-select">
|
|
|
{% for t in techs %}
|
|
|
<option {{ 'selected' if loop.first }}>{{ t }}</option>
|
|
|
{% endfor %}
|
|
|
</select>
|
|
|
</div>
|
|
|
<div class="mb-2">
|
|
|
<label class="form-label">Export market mix (0-1)</label>
|
|
|
<input name="export_mix" type="number" step="0.01" class="form-control" value="{{ defaults.export_mix if defaults else 0.7 }}">
|
|
|
</div>
|
|
|
<div class="form-check mb-2">
|
|
|
<input class="form-check-input" type="checkbox" id="sell_byproducts" name="sell_byproducts" checked>
|
|
|
<label class="form-check-label" for="sell_byproducts">فروش محصولات جانبی (Sell byproducts)</label>
|
|
|
</div>
|
|
|
|
|
|
<hr class="my-3">
|
|
|
<label class="form-label">اعمال تغییرات پیشرفته (JSON)</label>
|
|
|
<small class="text-muted d-block mb-2">برای ویرایش / اضافه کردن تکنولوژی یا قیمتها از JSON استفاده کنید (اختیاری)</small>
|
|
|
<div class="mb-2">
|
|
|
<textarea name="tech_json" rows="6" class="form-control" placeholder='مثال: {"MyTech": {"capex_base_M": 200, "opex_base_cents_kg": 150}}'></textarea>
|
|
|
</div>
|
|
|
<div class="mb-2">
|
|
|
<textarea name="prices_json" rows="4" class="form-control" placeholder='مثال: {"pvc_s65_export": 1200}'></textarea>
|
|
|
</div>
|
|
|
|
|
|
<button class="btn btn-primary w-100" type="submit">اجرا و محاسبه</button>
|
|
|
</form>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="card bg-secondary">
|
|
|
<div class="card-header">فایل خروجی</div>
|
|
|
<div class="card-body">
|
|
|
<a class="btn btn-outline-light w-100" href="{{ url_for('download_results') }}">دانلود CSV نتایج</a>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="col-lg-8">
|
|
|
{% if top_kpis %}
|
|
|
<div class="row mb-3">
|
|
|
<div class="col-md-3">
|
|
|
<div class="card text-dark bg-light mb-2">
|
|
|
<div class="card-body text-center">
|
|
|
<h6>بهترین IRR (%)</h6>
|
|
|
<h4>{{ top_kpis.irr }}</h4>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="col-md-3">
|
|
|
<div class="card text-dark bg-light mb-2">
|
|
|
<div class="card-body text-center">
|
|
|
<h6>سود سالانه ($M)</h6>
|
|
|
<h4>{{ top_kpis.annual_profit_M }}</h4>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="col-md-3">
|
|
|
<div class="card text-dark bg-light mb-2">
|
|
|
<div class="card-body text-center">
|
|
|
<h6>CAPEX ($M)</h6>
|
|
|
<h4>{{ top_kpis.capex_M }}</h4>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="col-md-3">
|
|
|
<div class="card text-dark bg-light mb-2">
|
|
|
<div class="card-body text-center">
|
|
|
<h6>Payback (yrs)</h6>
|
|
|
<h4>{{ top_kpis.payback }}</h4>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
{% endif %}
|
|
|
|
|
|
|
|
|
<div class="card bg-secondary mb-3">
|
|
|
<div class="card-header">نمودارها و تحلیل حساسیت</div>
|
|
|
<div class="card-body text-center">
|
|
|
|
|
|
{% if kpi_img %}
|
|
|
<h6 class="text-light mb-2">KPI Dashboard</h6>
|
|
|
<img src="{{ url_for('static', filename=kpi_img) }}" alt="KPI Dashboard" class="img-fluid rounded shadow border border-secondary mb-3">
|
|
|
{% else %}
|
|
|
<div class="row">
|
|
|
<div class="col-md-6">
|
|
|
<canvas id="kpiChart" height="200"></canvas>
|
|
|
</div>
|
|
|
<div class="col-md-6">
|
|
|
<canvas id="tornadoChart" height="200"></canvas>
|
|
|
</div>
|
|
|
</div>
|
|
|
{% endif %}
|
|
|
|
|
|
{% if tornado_img %}
|
|
|
<h6 class="text-light mt-4 mb-2">Sensitivity Analysis</h6>
|
|
|
<img src="{{ url_for('static', filename=tornado_img) }}" alt="Tornado Chart" class="img-fluid rounded shadow border border-secondary">
|
|
|
{% endif %}
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<script>
|
|
|
const chartsPayload = {{ charts_json|safe if charts_json else 'null' }};
|
|
|
if (chartsPayload) {
|
|
|
const labels = chartsPayload.map((r, i) => r.Method ? r.Method : `M${i+1}`);
|
|
|
const irrs = chartsPayload.map(r => Number(r.irr) || 0);
|
|
|
|
|
|
renderKPIChart(labels, irrs);
|
|
|
|
|
|
const ranges = chartsPayload.map(r => {
|
|
|
const low = r.irr - 5; const high = r.irr + 5; return high - low;
|
|
|
});
|
|
|
renderTornadoChart(labels, ranges);
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
{% endblock %}
|
|
|
|