Tambah tabel nilai skala poin, penanda Nilai Akhir belum lengkap, dan peringatan katrol manual

Halaman Nilai kini punya tabel per-mahasiswa dalam skala poin (bukan 0-100)
supaya terlihat berapa poin riil yang sudah didapat dari total 100 per
Sub-CPMK. Nilai Akhir juga ditandai * kalau sebagian Sub-CPMK belum
ternilai (angkanya sementara), dan sel di grid Sub-CPMK ditandai ✎ kalau
skornya pernah dikoreksi manual dan berisiko tertimpa balik saat sesi
komponen terkait disimpan ulang.
This commit is contained in:
Power BI Dev
2026-07-27 07:16:44 +07:00
parent d6469a01dc
commit b85c75bb31
2 changed files with 203 additions and 4 deletions
+116 -3
View File
@@ -99,12 +99,15 @@
min="0" max="100" step="any"
value="{{ '%g'|format(r.nilai[k.i]) if r.nilai[k.i] is not none else '' }}"></td>
{% endfor %}
<td class="tengah"><b>{{ '%.1f'|format(akhir.get(r.nim)) if akhir.get(r.nim) is not none else '—' }}</b></td>
<td class="tengah"><b>{{ '%.1f'|format(akhir.get(r.nim)) if akhir.get(r.nim) is not none else '—' }}{% if r.nim in tidak_lengkap and akhir.get(r.nim) is not none %}<span title="Belum semua Sub-CPMK ternilai — angka ini sementara">*</span>{% endif %}</b></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% if tidak_lengkap %}
<p class="keterangan" style="margin-top:6px">* Sebagian Sub-CPMK mahasiswa ini belum ternilai — Nilai Akhir dihitung hanya dari yang sudah ternilai dan bisa berubah setelah sisanya diisi.</p>
{% endif %}
<div class="aksi-baris">
<span style="color:var(--grey);font-size:13px">Disimpan atas nama <b>{{ user.nama }}</b></span>
<span class="spacer"></span>
@@ -144,9 +147,9 @@
{% for s in peta.subs %}
<td class="isian"><input type="number" name="skor_{{ i }}_{{ s.kode }}"
min="0" max="100" step="any"
value="{{ '%g'|format(m.skor[s.kode]) if s.kode in m.skor else '' }}"></td>
value="{{ '%g'|format(m.skor[s.kode]) if s.kode in m.skor else '' }}">{% if (m.nim, s.kode) in dikatrol %}<span title="Nilai ini dikoreksi manual (beda dari hasil hitung sesi/tugas komponen) — bisa tertimpa balik kalau sesi/komponen yang mengukur Sub-CPMK ini disimpan lagi"></span>{% endif %}</td>
{% endfor %}
<td class="tengah"><b>{{ '%.1f'|format(akhir.get(m.nim)) if akhir.get(m.nim) is not none else '—' }}</b></td>
<td class="tengah"><b>{{ '%.1f'|format(akhir.get(m.nim)) if akhir.get(m.nim) is not none else '—' }}{% if m.nim in tidak_lengkap and akhir.get(m.nim) is not none %}<span title="Belum semua Sub-CPMK ternilai — angka ini sementara">*</span>{% endif %}</b></td>
</tr>
{% endfor %}
{% if per_mhs and hasil %}
@@ -170,6 +173,12 @@
</tbody>
</table>
</div>
{% if tidak_lengkap %}
<p class="keterangan" style="margin-top:6px">* Sebagian Sub-CPMK mahasiswa ini belum ternilai — Nilai Akhir dihitung hanya dari yang sudah ternilai dan bisa berubah setelah sisanya diisi.</p>
{% endif %}
{% if dikatrol %}
<p class="keterangan" style="margin-top:6px">✎ = nilai sudah dikoreksi manual di sini (beda dari hasil hitung sesi/tugas komponennya) — hati-hati, koreksi ini akan tertimpa balik kalau sesi/komponen yang mengukur Sub-CPMK itu diisi/disimpan lagi.</p>
{% endif %}
<div class="aksi-baris">
<span style="color:var(--grey);font-size:13px">Disimpan atas nama <b>{{ user.nama }}</b></span>
<span class="spacer"></span>
@@ -178,7 +187,111 @@
</form>
{% endif %}
{% if tabel_poin %}
{% set ada_kelas_p = tabel_poin|selectattr('kelas')|list|length > 0 %}
{% set n_kiri_p = 4 if ada_kelas_p else 3 %}
<h2 class="bagian">NILAI PER MAHASISWA — SKALA POIN <span style="font-weight:normal;font-style:italic;color:var(--grey)">— nilai yang sama, ditampilkan sebagai poin yang didapat dari total 100 (lihat rincian bobot di bawah); hanya tampilan, bukan isian</span></h2>
<div class="gulir" style="max-height:480px;overflow-y:auto">
<table class="grid">
<thead>
<tr>
<th style="width:44px" class="tengah">No.</th>
<th style="width:112px">NIM</th>
<th style="min-width:150px">Nama</th>
{% if ada_kelas_p %}<th style="width:60px" class="tengah">Kelas</th>{% endif %}
{% for s in peta.subs %}<th class="tengah" style="font-size:11px;min-width:70px">{{ s.kode }}</th>{% endfor %}
<th class="tengah" style="width:90px">Total</th>
</tr>
</thead>
<tbody>
{% for m in tabel_poin %}
<tr>
<td class="tengah">{{ loop.index }}</td>
<td>{{ m.nim }}</td>
<td>{{ m.nama }}</td>
{% if ada_kelas_p %}<td class="tengah">{{ m.kelas or '—' }}</td>{% endif %}
{% for s in peta.subs %}
{% set p = m.poin.get(s.kode) %}
<td class="tengah" style="font-size:12px">{% if p %}{{ '%.2f'|format(p.dapat) }}/{{ '%.2f'|format(p.maks) }}{% else %}—{% endif %}</td>
{% endfor %}
<td class="tengah"><b>{{ '%.2f'|format(m.total) }}</b></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{% if bobot_komponen %}
<h2 class="bagian">RINCIAN BOBOT PENILAIAN <span style="font-weight:normal;font-style:italic;color:var(--grey)">— bobot komponen (RPS bagian G) dibagi rata ke Sub-CPMK-nya; murni dari RPS, tak bergantung nilai</span></h2>
<div class="gulir">
<table class="grid" style="max-width:820px">
<thead><tr><th>Komponen</th><th class="tengah">Bobot</th><th class="tengah">Jumlah Sub-CPMK</th><th class="tengah">Poin per Sub-CPMK</th><th class="tengah">Verifikasi (Jumlah × Poin)</th></tr></thead>
<tbody>
{% for k in bobot_komponen %}
<tr>
<td>{{ k.nama }}</td>
<td class="tengah">{{ '%g'|format(k.bobot) }}%</td>
<td class="tengah">{{ k.n_subs }}</td>
<td class="tengah">{{ '%.2f'|format(k.poin) }}%</td>
<td class="tengah">{{ k.n_subs }} × {{ '%.2f'|format(k.poin) }}% = <b>{{ '%.2f'|format(k.n_subs * k.poin) }}%</b></td>
</tr>
{% endfor %}
<tr class="total">
<td colspan="4" style="text-align:right"><b>Total</b></td>
<td class="tengah"><b>{{ '%.2f'|format(bobot_komponen|sum(attribute='bobot')) }}%</b></td>
</tr>
</tbody>
</table>
</div>
<p class="keterangan" style="margin-top:10px">Dijumlah per Sub-CPMK (karena sebagian Sub-CPMK diukur lebih dari satu komponen):</p>
<div class="gulir">
<table class="grid">
<thead><tr><th>Sub-CPMK</th><th class="tengah">Total Poin</th><th>Rincian</th></tr></thead>
<tbody>
{% for s in peta.subs %}
{% set kontribusi = bobot_sub_rincian.get(s.kode) %}
{% if kontribusi %}
<tr>
<td>{{ s.kode }}</td>
<td class="tengah"><b>{{ '%.2f'|format(kontribusi|sum(attribute='poin')) }}</b></td>
<td>{% for c in kontribusi %}{{ c.nama }} {{ '%.2f'|format(c.poin) }}{{ ' + ' if not loop.last }}{% endfor %}</td>
</tr>
{% endif %}
{% endfor %}
<tr class="total">
<td style="text-align:right"><b>Total</b></td>
<td class="tengah"><b>{{ '%.2f'|format(bobot_komponen|sum(attribute='bobot')) }}</b></td>
<td></td>
</tr>
</tbody>
</table>
</div>
{% endif %}
{% if hasil %}
<h2 class="bagian">HASIL KETERCAPAIAN SUB-CPMK <span style="font-weight:normal;font-style:italic;color:var(--grey)">(ambang {{ ambang|round(0)|int }})</span></h2>
<div class="gulir">
<table class="grid">
<thead><tr><th>Sub-CPMK</th><th class="tengah">Skor</th><th class="tengah">Maks</th><th class="tengah">Status</th></tr></thead>
<tbody>
{% for s in peta.subs %}
{% set info = hasil.sub.get(s.kode) %}
<tr>
<td>{{ s.kode }}</td>
<td class="tengah">{% if info and info.rata is not none %}<b>{{ '%.1f'|format(info.rata) }}</b>{% else %}—{% endif %}</td>
<td class="tengah">100</td>
<td class="tengah">
{% if not info or info.rata is none %}<span class="stamp stamp-draft">BELUM TERUKUR</span>
{% elif info.rata >= ambang %}<span class="stamp stamp-ok">TERCAPAI</span>
{% else %}<span class="stamp stamp-no">DI BAWAH AMBANG</span>{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<h2 class="bagian">HASIL KETERCAPAIAN MK <span style="font-weight:normal;font-style:italic;color:var(--grey)">(ambang {{ ambang|round(0)|int }})</span></h2>
<div class="gulir">
<table class="grid">