added accept/cancel prompt to Notenvorschlag übernehmen spelling out the current benotungsdatum to the user; also added a list over all changedNoten which are about to be freigegeben in the Notenfreigabe Modal before entering a password; fixed/added some phrasen;

This commit is contained in:
Johann Hoffmann
2026-07-24 13:52:05 +02:00
parent 32de4aac6b
commit 273f00a9c4
3 changed files with 208 additions and 7 deletions
@@ -68,7 +68,8 @@ class Noten extends FHCAPI_Controller
'person',
'benotungstool',
'lehre',
'ui'
'ui',
'password'
]);
$this->load->model('education/LePruefung_model', 'LePruefungModel');
@@ -461,7 +462,7 @@ class Noten extends FHCAPI_Controller
}
if(!$this->AuthLib->checkUserAuthByUsernamePassword(getAuthUID(), $result->password)->retval) {
$this->terminateWithError($this->p->t('global', 'wrongPassword'), 'general');
$this->terminateWithError($this->p->t('password', 'wrongPassword'), 'general');
}
$lv_id = $result->lv_id;
@@ -1235,18 +1235,31 @@ export const Benotungstool = {
return value
},
saveNote(e, cell) { // Notenvorschlag freigeben
async saveNote(e, cell) { // Notenvorschlag freigeben
const row = cell.getRow()
const data = row.getData()
if(!data.note_vorschlag) return
// if vorschlag is the same as lv_note do nothing
if(data.note_vorschlag == data.lv_note) return
// if the student already has pruefungen disable this part
if(data.pruefungen.length) return
// confirm before writing the LV-Gesamtnote
const noteOption = this.notenOptions.find(opt => opt.note == data.note_vorschlag)
const noteBezeichnung = noteOption ? noteOption.bezeichnung : data.note_vorschlag
const dateLocale = this.$p.user_language?.value === 'English' ? 'en-GB' : 'de-AT'
const benotungsdatum = new Date().toLocaleString(dateLocale)
if(await this.$fhcAlert.confirm({
message: this.$p.t('benotungstool/c4notenvorschlagUebernehmenConfirm', [noteBezeichnung, data.vorname, data.nachname, data.uid, benotungsdatum]),
acceptClass: 'p-button-primary',
rejectClass: 'p-button-secondary'
}) === false) {
return
}
this.loading = true
this.$api.call(ApiNoten.saveNotenvorschlag(this.lv_id, this.sem_kurzbz, data.uid, data.note_vorschlag, data.punkte))
.then((res) => {
@@ -2596,6 +2609,24 @@ export const Benotungstool = {
}, []) : []
return cs
},
// Row-by-row preview for the Noten-freigeben modal, over the exact set that
// saveStudentenNoten will release (changedNoten). Freigabe releases the LV-Note
// (lv_note); it does not itself write the Zeugnisnote (that is a separate übernahme).
// So we compare what is currently on record in the Zeugnis (note) against the
// LV-Note that is about to be freigegeben (lv_note), and flag any mismatch.
freigabeSummary() {
return this.changedNoten.map(s => {
const zeugnisOpt = this.notenOptions?.find(opt => opt.note == s.note)
const releaseOpt = this.notenOptions?.find(opt => opt.note == s.lv_note)
return {
uid: s.uid,
name: `${s.vorname} ${s.nachname}`,
currentNote: zeugnisOpt ? zeugnisOpt.bezeichnung : (s.note || '—'),
releasedNote: releaseOpt ? releaseOpt.bezeichnung : (s.lv_note || '—'),
changed: (s.note ?? '') != (s.lv_note ?? '')
}
})
},
getNotenfreigabeHinweistext() {
return this.$capitalize(this.$p.t('benotungstool/notenfreigabeHinweistextv4'))
},
@@ -2717,6 +2748,35 @@ export const Benotungstool = {
<div class="row justify-content-center">
<div class="col-12" v-html="getNotenfreigabeHinweistext"></div>
</div>
<div v-if="freigabeSummary.length" class="row mt-3 justify-content-center">
<div class="col-12">
<div class="fw-bold mb-1">{{ $p.t('benotungstool/c4freigabeSummaryHeading', [freigabeSummary.length]) }}</div>
<div class="border rounded" style="max-height: 250px; overflow-y: auto;">
<table class="table table-sm table-hover align-middle mb-0">
<thead>
<tr>
<th class="bg-body sticky-top">{{ $capitalize($p.t('benotungstool/c4student')) }}</th>
<th class="bg-body sticky-top">{{ $capitalize($p.t('benotungstool/c4freigabeSummaryCurrent')) }}</th>
<th class="bg-body sticky-top"></th>
<th class="bg-body sticky-top">{{ $capitalize($p.t('benotungstool/c4freigabeSummaryReleased')) }}</th>
</tr>
</thead>
<tbody>
<tr v-for="row in freigabeSummary" :key="row.uid">
<td>{{ row.name }} <span class="text-muted">({{ row.uid }})</span></td>
<td>{{ row.currentNote }}</td>
<td class="text-center"><i class="fa fa-arrow-right"></i></td>
<td :class="{ 'fw-bold text-success': row.changed }">{{ row.releasedNote }}</td>
</tr>
</tbody>
</table>
</div>
<div class="small text-muted mt-1">{{ $p.t('benotungstool/c4freigabeSummaryLegend') }}</div>
</div>
</div>
<div v-else class="row mt-3 justify-content-center">
<div class="col-12 text-center text-muted">{{ $p.t('benotungstool/c4freigabeSummaryEmpty') }}</div>
</div>
<div class="row mt-3 justify-content-center">
<div class="col-auto">
<Password v-model="password" :feedback="false" showIcon="fa fa-eye" :toggleMask="true" :promptLabel="$p.t('benotungstool/passwort')"></Password>
+140
View File
@@ -59704,6 +59704,146 @@ I have been informed that I am under no obligation to consent to the transmissio
)
)
),
array(
'app' => 'core',
'category' => 'benotungstool',
'phrase' => 'c4notenvorschlagUebernehmenConfirm',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Möchten Sie wirklich die Note "{0}" für den Studenten {1} {2} ({3}) mit Benotungsdatum {4} eintragen?',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Do you really want to enter the grade "{0}" for the student {1} {2} ({3}) with grading date {4}?',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'benotungstool',
'phrase' => 'c4freigabeSummaryHeading',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Folgende Noten werden freigegeben ({0}):',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'The following grades will be approved ({0}):',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'benotungstool',
'phrase' => 'c4student',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Student',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Student',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'benotungstool',
'phrase' => 'c4freigabeSummaryCurrent',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Bisher im Zeugnis',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Currently on transcript',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'benotungstool',
'phrase' => 'c4freigabeSummaryReleased',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Wird freigegeben',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Will be approved',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'benotungstool',
'phrase' => 'c4freigabeSummaryLegend',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Grün markierte Noten weichen von der bisher im Zeugnis eingetragenen Note ab.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Grades highlighted in green differ from the grade currently on the transcript.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'benotungstool',
'phrase' => 'c4freigabeSummaryEmpty',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Es sind keine geänderten Noten zur Freigabe vorhanden.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'There are no changed grades to approve.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'benotungstool',