diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 906f44538761575dc686cb0569f9b2fb61145e94..f7b0d177ba0f73ca88d7e3c634459fa7cf0e305c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,15 @@ All notable changes to this project will be documented in this file. The format is based on `Keep a Changelog`_, and this project adheres to `Semantic Versioning`_. +`4.0.0.dev2`_ - 2024-07-10 +-------------------------- + +Added +~~~~~ + +* Support for entering personal notes for students in the new coursebook interface. +* Support for entering tardiness for students in the new coursebook interface. + `4.0.0.dev1`_ - 2024-06-13 -------------------------- @@ -41,6 +50,14 @@ Fixed * Migrating failed due to an incorrect field reference. +`3.0.1`_ - 2023-09-02 +------------------- + +Fixed +~~~~~ + +* Migrations failed on empty database + `3.0`_ - 2023-05-15 ------------------- @@ -132,7 +149,7 @@ Changed ~~~~~~~ * Use start date of current SchoolTerm as default value for PersonalNote filter in overview. - +Julia ist eine höhere Programmiersprache, die vor allem für numerisches und wissenschaftliches Rechnen entwickelt wurde und auch als Allzweck-Programmiersprache verwendet werden kann, bei gleichzeitiger Wahrung einer hohen Ausführungsgeschwindigkeit. Wikipedia Fixed ~~~~~ @@ -351,4 +368,7 @@ Fixed .. _2.1.1: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.1.1 .. _3.0b0: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/3.0b0 .. _3.0: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/3.0 +.. _3.0.1: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/3.0.1 .. _4.0.0.dev0: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/4.0.0.dev0 +.. _4.0.0.dev1: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/4.0.0.dev1 +.. _4.0.0.dev2: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/4.0.0.dev2 diff --git a/README.rst b/README.rst index 61e80f73c24aa9077218aa86a2427463f75f1f0f..53fbc493f0f1acfd35a0f893c816cfb117a27572 100644 --- a/README.rst +++ b/README.rst @@ -34,10 +34,11 @@ Licence Copyright © 2019, 2021 Dominik George <dominik.george@teckids.org> Copyright © 2019, 2020 Tom Teichler <tom.teichler@teckids.org> Copyright © 2019 mirabilos <thorsten.glaser@teckids.org> - Copyright © 2020, 2021, 2022 Jonathan Weth <dev@jonathanweth.de> - Copyright © 2020, 2021 Julian Leucker <leuckeju@katharineum.de> - Copyright © 2020, 2022 Hangzhi Yu <yuha@katharineum.de> + Copyright © 2020, 2021, 2022, 2024 Jonathan Weth <dev@jonathanweth.de> + Copyright © 2020, 2021, 2024 Julian Leucker <leuckeju@katharineum.de> + Copyright © 2020, 2022, 2023, 2024 Hangzhi Yu <yuha@katharineum.de> Copyright © 2021 Lloyd Meins <meinsll@katharineum.de> + Copyright © 2024 Michael Bauer <michael-bauer@posteo.de> Licenced under the EUPL, version 1.2 or later, by Teckids e.V. (Bonn, Germany). diff --git a/aleksis/apps/alsijil/apps.py b/aleksis/apps/alsijil/apps.py index b523b38afa08c965628afbfbe61327e8b03f7067..ab0877f2f457658463c034e09139d8098df5b8d3 100644 --- a/aleksis/apps/alsijil/apps.py +++ b/aleksis/apps/alsijil/apps.py @@ -13,8 +13,9 @@ class AlsijilConfig(AppConfig): ([2019, 2021], "Dominik George", "dominik.george@teckids.org"), ([2019, 2020], "Tom Teichler", "tom.teichler@teckids.org"), ([2019], "mirabilos", "thorsten.glaser@teckids.org"), - ([2020, 2021, 2022], "Jonathan Weth", "dev@jonathanweth.de"), - ([2020, 2021], "Julian Leucker", "leuckeju@katharineum.de"), - ([2020, 2022], "Hangzhi Yu", "yuha@katharineum.de"), + ([2020, 2021, 2022, 2024], "Jonathan Weth", "dev@jonathanweth.de"), + ([2020, 2021, 2024], "Julian Leucker", "leuckeju@katharineum.de"), + ([2020, 2022, 2023, 2024], "Hangzhi Yu", "yuha@katharineum.de"), ([2021], "Lloyd Meins", "meinsll@katharineum.de"), + ([2024], "Michael Bauer", "michael-bauer@posteo.de"), ) diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue index 5f64bdf08aef9af24722ab2708109744739e0c2e..7cdc7113c4682276e04d9ae510cbd14fcfa67fc7 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue @@ -1,83 +1,86 @@ <template> - <infinite-scrolling-date-sorted-c-r-u-d-iterator - i18n-key="alsijil.coursebook" - :gql-query="gqlQuery" - :gql-additional-query-args="gqlQueryArgs" - :enable-create="false" - :enable-edit="false" - :elevated="false" - @lastQuery="lastQuery = $event" - ref="iterator" - fixed-header - disable-pagination - hide-default-footer - use-deep-search - > - <template #additionalActions="{ attrs, on }"> - <coursebook-filters :page-type="pageType" v-model="filters" /> - <v-expand-transition> - <v-card - outlined - class="full-width" - v-show=" - pageType === 'absences' && combinedSelectedParticipations.length - " - > - <v-card-text> - <v-row align="center"> - <v-col cols="6"> - {{ - $tc( - "alsijil.coursebook.absences.action_for_selected", - combinedSelectedParticipations.length, - ) - }} - </v-col> - <v-col cols="6"> - <absence-reason-buttons - allow-empty - empty-value="present" - @input="handleMultipleAction" - /> - </v-col> - </v-row> - </v-card-text> - </v-card> - </v-expand-transition> - </template> + <div> + <infinite-scrolling-date-sorted-c-r-u-d-iterator + i18n-key="alsijil.coursebook" + :gql-query="gqlQuery" + :gql-additional-query-args="gqlQueryArgs" + :enable-create="false" + :enable-edit="false" + :elevated="false" + @lastQuery="lastQuery = $event" + ref="iterator" + fixed-header + disable-pagination + hide-default-footer + use-deep-search + > + <template #additionalActions="{ attrs, on }"> + <coursebook-filters :page-type="pageType" v-model="filters" /> + <v-expand-transition> + <v-card + outlined + class="full-width" + v-show=" + pageType === 'absences' && combinedSelectedParticipations.length + " + > + <v-card-text> + <v-row align="center"> + <v-col cols="6"> + {{ + $tc( + "alsijil.coursebook.absences.action_for_selected", + combinedSelectedParticipations.length, + ) + }} + </v-col> + <v-col cols="6"> + <absence-reason-buttons + allow-empty + empty-value="present" + @input="handleMultipleAction" + /> + </v-col> + </v-row> + </v-card-text> + </v-card> + </v-expand-transition> + </template> - <template #item="{ item, lastQuery }"> - <component - :is="itemComponent" - :documentation="item" - :affectedQuery="lastQuery" - :value="(selectedParticipations[item.id] ??= [])" - @input="selectParticipation(item.id, $event)" - /> - </template> + <template #item="{ item, lastQuery }"> + <component + :is="itemComponent" + :documentation="item" + :affectedQuery="lastQuery" + :value="(selectedParticipations[item.id] ??= [])" + @input="selectParticipation(item.id, $event)" + /> + </template> - <template #loading> - <coursebook-loader :number-of-days="10" :number-of-docs="5" /> - </template> + <template #loading> + <coursebook-loader :number-of-days="10" :number-of-docs="5" /> + </template> - <template #itemLoader> - <coursebook-loader /> - </template> + <template #itemLoader> + <coursebook-loader /> + </template> - <template #no-data> - <CoursebookEmptyMessage icon="mdi-book-off-outline"> - {{ $t("alsijil.coursebook.no_data") }} - </CoursebookEmptyMessage> - </template> + <template #no-data> + <CoursebookEmptyMessage icon="mdi-book-off-outline"> + {{ $t("alsijil.coursebook.no_data") }} + </CoursebookEmptyMessage> + </template> - <template #no-results> - <CoursebookEmptyMessage icon="mdi-book-alert-outline"> - {{ - $t("alsijil.coursebook.no_results", { search: $refs.iterator.search }) - }} - </CoursebookEmptyMessage> - </template> - </infinite-scrolling-date-sorted-c-r-u-d-iterator> + <template #no-results> + <CoursebookEmptyMessage icon="mdi-book-alert-outline"> + {{ + $t("alsijil.coursebook.no_results", { search: $refs.iterator.search }) + }} + </CoursebookEmptyMessage> + </template> + </infinite-scrolling-date-sorted-c-r-u-d-iterator> + <absence-creation-dialog /> + </div> </template> <script> @@ -90,8 +93,10 @@ import CoursebookLoader from "./CoursebookLoader.vue"; import CoursebookEmptyMessage from "./CoursebookEmptyMessage.vue"; import DocumentationModal from "./documentation/DocumentationModal.vue"; import DocumentationAbsencesModal from "./absences/DocumentationAbsencesModal.vue"; - +import AbsenceCreationDialog from "./absences/AbsenceCreationDialog.vue"; import updateParticipationMixin from "./absences/updateParticipationMixin.js"; +import { extraMarks } from "../extra_marks/extra_marks.graphql"; + export default { name: "Coursebook", @@ -103,6 +108,7 @@ export default { DocumentationModal, DocumentationAbsencesModal, InfiniteScrollingDateSortedCRUDIterator, + AbsenceCreationDialog, }, mixins: [updateParticipationMixin], props: { @@ -159,9 +165,16 @@ export default { initDate: false, currentDate: "", hashUpdater: false, + extraMarks: [], selectedParticipations: {}, }; }, + apollo: { + extraMarks: { + query: extraMarks, + update: (data) => data.items, + }, + }, computed: { // Assertion: Should only fire on page load or selection change. // Resets date range. diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/CoursebookFilters.vue b/aleksis/apps/alsijil/frontend/components/coursebook/CoursebookFilters.vue index 35cd8f12fb56552e76bbdb2a819aedbf37b1a62e..607a2160d644483992ea9f9e46c3ec3dd87f092d 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/CoursebookFilters.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/CoursebookFilters.vue @@ -3,6 +3,7 @@ <v-autocomplete :items="selectable" item-text="name" + :item-value="(item) => `${item.__typename}-${item.id}`" clearable return-object filled diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue new file mode 100644 index 0000000000000000000000000000000000000000..dbb504c393b0dc03f43b647ca305f614fd7df1da --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue @@ -0,0 +1,174 @@ +<template> + <mobile-fullscreen-dialog v-model="popup" persistent> + <template #activator="activator"> + <fab-button + color="secondary" + @click="popup = true" + :disabled="popup" + :class="{ + 'd-none': !checkPermission('alsijil.view_register_absence_rule'), + }" + icon-text="$plus" + i18n-key="alsijil.coursebook.absences.button" + > + <v-icon>$plus</v-icon> + </fab-button> + </template> + <template #title> + <div> + {{ $t("alsijil.coursebook.absences.title") }} + </div> + <span v-if="!form" class="px-2">·</span> + <div v-if="!form"> + {{ $t("alsijil.coursebook.absences.summary") }} + </div> + </template> + <template #content> + <absence-creation-form + :persons="persons" + :start-date="startDate" + :end-date="endDate" + :comment="comment" + :absence-reason="absenceReason" + @valid="formValid = $event" + @persons="persons = $event" + @start-date="startDate = $event" + @end-date="endDate = $event" + @comment="comment = $event" + @absence-reason="absenceReason = $event" + :class="{ + 'd-none': !form, + }" + /> + <absence-creation-summary + v-if="!form" + :persons="persons" + :start-date="startDate" + :end-date="endDate" + @loading="handleLoading" + /> + </template> + <template #actionsLeft> + <cancel-button @click="cancel" /> + </template> + <template #actions> + <!-- secondary --> + <secondary-action-button + @click="form = true" + v-if="!form" + :disabled="loading" + i18n-key="actions.back" + > + <v-icon left>$prev</v-icon> + {{ $t("actions.back") }} + </secondary-action-button> + <!-- primary --> + <save-button + v-if="form" + @click="form = false" + :loading="loading" + :disabled="!formValid" + > + {{ $t("actions.continue") }} + <v-icon right>$next</v-icon> + </save-button> + <save-button + v-else + i18n-key="actions.confirm" + @click="confirm" + :loading="loading" + /> + </template> + </mobile-fullscreen-dialog> +</template> + +<script> +import MobileFullscreenDialog from "aleksis.core/components/generic/dialogs/MobileFullscreenDialog.vue"; +import AbsenceCreationForm from "./AbsenceCreationForm.vue"; +import AbsenceCreationSummary from "./AbsenceCreationSummary.vue"; +import FabButton from "aleksis.core/components/generic/buttons/FabButton.vue"; +import CancelButton from "aleksis.core/components/generic/buttons/CancelButton.vue"; +import SaveButton from "aleksis.core/components/generic/buttons/SaveButton.vue"; +import SecondaryActionButton from "aleksis.core/components/generic/buttons/SecondaryActionButton.vue"; +import loadingMixin from "aleksis.core/mixins/loadingMixin.js"; +import permissionsMixin from "aleksis.core/mixins/permissions.js"; +import mutateMixin from "aleksis.core/mixins/mutateMixin.js"; + +import { createAbsencesForPersons } from "./absenceCreation.graphql"; + +export default { + name: "AbsenceCreationDialog", + components: { + MobileFullscreenDialog, + AbsenceCreationForm, + AbsenceCreationSummary, + CancelButton, + SaveButton, + SecondaryActionButton, + FabButton, + }, + mixins: [loadingMixin, mutateMixin, permissionsMixin], + data() { + return { + popup: false, + form: true, + formValid: false, + persons: [], + startDate: "", + endDate: "", + comment: "", + absenceReason: "", + }; + }, + mounted() { + this.addPermissions(["alsijil.view_register_absence_rule"]); + }, + methods: { + cancel() { + this.popup = false; + this.form = true; + this.clearForm(); + }, + clearForm() { + this.persons = []; + this.startDate = ""; + this.endDate = ""; + this.comment = ""; + this.absenceReason = ""; + }, + confirm() { + this.handleLoading(true); + this.mutate( + createAbsencesForPersons, + { + persons: this.persons.map((p) => p.id), + start: this.startDate, + end: this.endDate, + comment: this.comment, + reason: this.absenceReason, + }, + (storedDocumentations, incomingStatuses) => { + const documentation = storedDocumentations.find( + (doc) => doc.id === this.documentation.id, + ); + + incomingStatuses.forEach((newStatus) => { + const participationStatus = documentation.participations.find( + (part) => part.id === newStatus.id, + ); + participationStatus.absenceReason = newStatus.absenceReason; + participationStatus.isOptimistic = newStatus.isOptimistic; + }); + + return storedDocumentations; + }, + ); + this.$once("save", this.handleSave); + }, + handleSave() { + this.cancel(); + this.$toastSuccess("alsijil.coursebook.absences.success"); + }, + }, +}; +</script> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue new file mode 100644 index 0000000000000000000000000000000000000000..559824bdf4cb8bb214d1be3acebba38c08c836cd --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue @@ -0,0 +1,117 @@ +<template> + <v-form @input="$emit('valid', $event)"> + <v-container> + <v-row> + <div aria-required="true" class="full-width"> + <!-- FIXME Vue 3: clear-on-select --> + <v-autocomplete + :label="$t('forms.labels.persons')" + :items="allPersons" + item-text="fullName" + return-object + multiple + chips + deletable-chips + :rules=" + $rules().build([ + (value) => value.length > 0 || $t('forms.errors.required'), + ]) + " + :value="persons" + :loading="$apollo.queries.allPersons.loading" + @input="$emit('persons', $event)" + /> + </div> + </v-row> + <v-row> + <v-col cols="12" :sm="6" class="pl-0"> + <div aria-required="true"> + <date-field + :label="$t('forms.labels.start')" + :max="endDate" + :rules="$rules().required.build()" + :value="startDate" + @input="$emit('start-date', $event)" + /> + </div> + </v-col> + <v-col cols="12" :sm="6" class="pr-0"> + <div aria-required="true"> + <date-field + :label="$t('forms.labels.end')" + :min="startDate" + :rules="$rules().required.build()" + :value="endDate" + @input="$emit('end-date', $event)" + /> + </div> + </v-col> + </v-row> + <v-row> + <v-text-field + :label="$t('forms.labels.comment')" + :value="comment" + @input="$emit('comment', $event)" + /> + </v-row> + <v-row> + <div aria-required="true"> + <absence-reason-group-select + :rules="$rules().required.build()" + :value="absenceReason" + @input="$emit('absence-reason', $event)" + /> + </div> + </v-row> + </v-container> + </v-form> +</template> + +<script> +import AbsenceReasonGroupSelect from "aleksis.apps.kolego/components/AbsenceReasonGroupSelect.vue"; +import DateField from "aleksis.core/components/generic/forms/DateField.vue"; +import { persons } from "./absenceCreation.graphql"; +import formRulesMixin from "aleksis.core/mixins/formRulesMixin.js"; + +export default { + name: "AbsenceCreationForm", + components: { + AbsenceReasonGroupSelect, + DateField, + }, + mixins: [formRulesMixin], + emits: [ + "valid", + "persons", + "start-date", + "end-date", + "comment", + "absence-reason", + ], + apollo: { + allPersons: persons, + }, + props: { + persons: { + type: Array, + required: true, + }, + startDate: { + type: String, + required: true, + }, + endDate: { + type: String, + required: true, + }, + comment: { + type: String, + required: true, + }, + absenceReason: { + type: String, + required: true, + }, + }, +}; +</script> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationSummary.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationSummary.vue new file mode 100644 index 0000000000000000000000000000000000000000..17a7795e697caeed9346c3aa13fe6b10e2f54c28 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationSummary.vue @@ -0,0 +1,123 @@ +<template> + <div> + <message-box dense type="warning" class="mt-5"> + {{ $t("alsijil.coursebook.absences.warning") }} + </message-box> + <!-- MAYBE introduce a minimal variant of CRUDIterator --> + <!-- with most features disabled for this list usecase --> + <c-r-u-d-iterator + i18n-key="" + :gql-query="gqlQuery" + :gql-additional-query-args="gqlArgs" + :enable-search="false" + :enable-create="false" + :enable-edit="false" + :elevated="false" + disable-pagination + hide-default-footer + @loading="handleLoading" + > + <template #default="{ items }"> + <v-expansion-panels> + <v-expansion-panel v-for="person in items" :key="person.id"> + <v-expansion-panel-header> + <div> + {{ persons.find((p) => p.id === person.id).fullName }} + </div> + <v-spacer /> + <div> + {{ + $tc( + "alsijil.coursebook.absences.lessons", + person.lessons.length, + { count: person.lessons.length }, + ) + }} + </div> + </v-expansion-panel-header> + <v-expansion-panel-content> + <v-list-item + v-for="lesson in person.lessons" + class="px-0" + :key="lesson.id" + > + <v-row> + <!-- TODO: We should extract this display & share it --> + <v-col cols="3"> + <time :datetime="lesson.datetimeStart" class="text-no-wrap"> + {{ + $d( + $parseISODate(lesson.datetimeStart), + "shortWithWeekday", + ) + }} + </time> + </v-col> + <v-col cols="3"> + <time :datetime="lesson.datetimeStart" class="text-no-wrap"> + {{ $d($parseISODate(lesson.datetimeStart), "shortTime") }} + </time> + <span> - </span> + <time :datetime="lesson.datetimeEnd" class="text-no-wrap"> + {{ $d($parseISODate(lesson.datetimeEnd), "shortTime") }} + </time> + </v-col> + <v-col cols="3"> + {{ lesson.course?.name }} + </v-col> + <v-col cols="3"> + <subject-chip :subject="lesson.subject" /> + </v-col> + </v-row> + </v-list-item> + </v-expansion-panel-content> + </v-expansion-panel> + </v-expansion-panels> + </template> + </c-r-u-d-iterator> + </div> +</template> + +<script> +import CRUDIterator from "aleksis.core/components/generic/CRUDIterator.vue"; +import SubjectChip from "aleksis.apps.cursus/components/SubjectChip.vue"; +import { lessonsForPersons } from "./absenceCreation.graphql"; +import loadingMixin from "aleksis.core/mixins/loadingMixin.js"; + +export default { + name: "AbsenceCreationSummary", + components: { + CRUDIterator, + SubjectChip, + }, + mixins: [loadingMixin], + props: { + persons: { + type: Array, + required: true, + }, + startDate: { + type: String, + required: true, + }, + endDate: { + type: String, + required: true, + }, + }, + data() { + return { + gqlQuery: lessonsForPersons, + }; + }, + computed: { + gqlArgs() { + return { + persons: this.persons.map((person) => person.id), + start: this.startDate, + end: this.endDate, + }; + }, + }, +}; +</script> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/ManageStudentsDialog.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/ManageStudentsDialog.vue index 373fd6fcd9a63938b549b4ecfb17f006f7ebc295..02dda22073e775b30324db22ea358ff7e9924ba4 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/ManageStudentsDialog.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/ManageStudentsDialog.vue @@ -5,22 +5,31 @@ import AbsenceReasonGroupSelect from "aleksis.apps.kolego/components/AbsenceReas import CancelButton from "aleksis.core/components/generic/buttons/CancelButton.vue"; import MobileFullscreenDialog from "aleksis.core/components/generic/dialogs/MobileFullscreenDialog.vue"; import updateParticipationMixin from "./updateParticipationMixin.js"; +import deepSearchMixin from "aleksis.core/mixins/deepSearchMixin.js"; import LessonInformation from "../documentation/LessonInformation.vue"; import SlideIterator from "aleksis.core/components/generic/SlideIterator.vue"; +import PersonalNotes from "../personal_notes/PersonalNotes.vue"; +import ExtraMarkChip from "../../extra_marks/ExtraMarkChip.vue"; +import TardinessChip from "./TardinessChip.vue"; +import TardinessField from "./TardinessField.vue"; export default { name: "ManageStudentsDialog", extends: MobileFullscreenDialog, components: { + TardinessChip, + ExtraMarkChip, AbsenceReasonChip, AbsenceReasonGroupSelect, AbsenceReasonButtons, + PersonalNotes, CancelButton, LessonInformation, MobileFullscreenDialog, SlideIterator, + TardinessField, }, - mixins: [updateParticipationMixin], + mixins: [updateParticipationMixin, deepSearchMixin], data() { return { dialog: false, @@ -36,6 +45,11 @@ export default { default: false, required: false, }, + useDeepSearch: { + type: Boolean, + default: true, + required: false, + }, }, computed: { items() { @@ -109,13 +123,49 @@ export default { :loading="loadingIndicator || loadSelected" :load-only-selected="loadSelected" :disabled="loading" + :custom-filter="deepSearch" > <template #listItemContent="{ item }"> <v-list-item-title> {{ item.person.fullName }} </v-list-item-title> - <v-list-item-subtitle v-if="item.absenceReason"> - <absence-reason-chip small :absence-reason="item.absenceReason" /> + <v-list-item-subtitle + v-if=" + item.absenceReason || + item.notesWithNote?.length > 0 || + item.notesWithExtraMark?.length > 0 || + item.tardiness + " + class="d-flex flex-wrap gap" + > + <absence-reason-chip + v-if="item.absenceReason" + small + :absence-reason="item.absenceReason" + /> + <v-chip + v-for="note in item.notesWithNote" + :key="'text-note-note-overview-' + note.id" + small + > + <v-avatar left> + <v-icon small>mdi-note-outline</v-icon> + </v-avatar> + <span class="text-truncate" style="max-width: 30ch"> + {{ note.note }} + </span> + </v-chip> + <extra-mark-chip + v-for="note in item.notesWithExtraMark" + :key="'extra-mark-note-overview-' + note.id" + :extra-mark="extraMarks.find((e) => e.id === note.extraMark.id)" + small + /> + <tardiness-chip + v-if="item.tardiness" + :tardiness="item.tardiness" + small + /> </v-list-item-subtitle> </template> @@ -139,6 +189,23 @@ export default { :value="item.absenceReason?.id || 'present'" @input="sendToServer([item], 'absenceReason', $event)" /> + <tardiness-field + v-bind="documentationPartProps" + :loading="loading" + :disabled="loading" + :participation="item" + :value="item.tardiness" + @input="sendToServer([item], 'tardiness', $event)" + /> + </v-card-text> + <v-divider /> + <v-card-text> + <personal-notes + v-bind="documentationPartProps" + :participation=" + documentation.participations.find((p) => p.id === item.id) + " + /> </v-card-text> </template> </slide-iterator> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/ManageStudentsTrigger.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/ManageStudentsTrigger.vue index 572036c67955b3365bb46eb69f6ab41ee86cf074..a7854c9ae41c9fe73a7d011f60f1abd09ad42145 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/ManageStudentsTrigger.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/ManageStudentsTrigger.vue @@ -58,6 +58,7 @@ export default { v-bind="documentationPartProps" @update="() => null" :loading-indicator="loading" + v-if="!documentation.amends?.cancelled" > <template #activator="{ attrs, on }"> <v-chip diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/TardinessChip.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/TardinessChip.vue new file mode 100644 index 0000000000000000000000000000000000000000..6be1fea3942fed64d37d2a68dde699344e55c35b --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/TardinessChip.vue @@ -0,0 +1,34 @@ +<script> +export default { + name: "TardinessChip", + props: { + tardiness: { + type: Number, + required: false, + default: 0, + }, + loading: { + type: Boolean, + required: false, + default: false, + }, + }, + extends: "v-chip", +}; +</script> + +<template> + <v-chip dense outlined v-bind="$attrs" v-on="$listeners"> + <v-avatar left> + <v-icon small>mdi-clock-alert-outline</v-icon> + </v-avatar> + <slot name="prepend" /> + <slot> + {{ $tc("alsijil.personal_notes.minutes_late", tardiness) }} + </slot> + <slot name="append" /> + <v-avatar right v-if="loading"> + <v-progress-circular indeterminate :size="16" :width="2" /> + </v-avatar> + </v-chip> +</template> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/TardinessField.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/TardinessField.vue new file mode 100644 index 0000000000000000000000000000000000000000..74a85ae09018fcc810950e6b10a52a8e5a948607 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/TardinessField.vue @@ -0,0 +1,109 @@ +<script> +import { DateTime } from "luxon"; +import documentationPartMixin from "../documentation/documentationPartMixin"; +import ConfirmDialog from "aleksis.core/components/generic/dialogs/ConfirmDialog.vue"; +import PositiveSmallIntegerField from "aleksis.core/components/generic/forms/PositiveSmallIntegerField.vue"; + +export default { + name: "TardinessField", + components: { ConfirmDialog, PositiveSmallIntegerField }, + mixins: [documentationPartMixin], + props: { + value: { + type: Number, + default: null, + required: false, + }, + participation: { + type: Object, + required: true, + }, + }, + computed: { + lessonLength() { + const lessonStart = DateTime.fromISO(this.documentation.datetimeStart); + const lessonEnd = DateTime.fromISO(this.documentation.datetimeEnd); + + let diff = lessonEnd.diff(lessonStart, "minutes"); + return diff.toObject().minutes; + }, + }, + methods: { + lessonLengthRule(time) { + return ( + time == null || + time <= this.lessonLength || + this.$t("alsijil.personal_notes.lesson_length_exceeded") + ); + }, + saveValue(value) { + this.$emit("input", value); + this.previousValue = value; + }, + confirm() { + this.saveValue(0); + }, + cancel() { + this.saveValue(this.previousValue); + }, + set(newValue) { + if (!newValue) { + // this is a DELETE action, show the dialog, ... + this.showDeleteConfirm = true; + return; + } + + this.saveValue(newValue); + }, + }, + data() { + return { + showDeleteConfirm: false, + previousValue: 0, + }; + }, + mounted() { + this.previousValue = this.value; + }, +}; +</script> + +<template> + <positive-small-integer-field + outlined + class="mt-1" + prepend-inner-icon="mdi-clock-alert-outline" + :suffix="$t('time.minutes')" + :label="$t('alsijil.personal_notes.tardiness')" + :rules="[lessonLengthRule]" + :value="value" + @change="set($event)" + v-bind="$attrs" + > + <template #append> + <confirm-dialog + v-model="showDeleteConfirm" + @confirm="confirm" + @cancel="cancel" + > + <template #title> + {{ $t("alsijil.personal_notes.confirm_delete") }} + </template> + <template #text> + {{ + $t("alsijil.personal_notes.confirm_delete_tardiness", { + tardiness: previousValue, + name: participation.person.fullName, + }) + }} + </template> + </confirm-dialog> + </template> + </positive-small-integer-field> +</template> + +<style scoped> +.mt-n1-5 { + margin-top: -6px; +} +</style> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql new file mode 100644 index 0000000000000000000000000000000000000000..21ce30d0b871bcfbd9a5b40b671a8594948a2569 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql @@ -0,0 +1,61 @@ +# Uses core persons query +query persons { + allPersons: absenceCreationPersons { + id + fullName + } +} + +query lessonsForPersons($persons: [ID]!, $start: Date!, $end: Date!) { + items: lessonsForPersons(persons: $persons, start: $start, end: $end) { + id + lessons { + id + datetimeStart + datetimeEnd + course { + id + name + } + subject { + id + name + shortName + colourFg + colourBg + } + } + } +} + +# Use absencesInputType? +mutation createAbsencesForPersons( + $persons: [ID]! + $start: Date! + $end: Date! + $comment: String + $reason: ID! +) { + createAbsencesForPersons( + persons: $persons + start: $start + end: $end + comment: $comment + reason: $reason + ) { + ok + items: participationStatuses { + id + isOptimistic + relatedDocumentation { + id + } + absenceReason { + id + name + shortName + colour + } + } + } +} diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/participationStatus.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/absences/participationStatus.graphql index 81a3a5fb1eb3a99bef25eb9938cd254b9068981b..dd50495972c020550dec310081f0c8c149473d9e 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/participationStatus.graphql +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/participationStatus.graphql @@ -14,6 +14,7 @@ mutation updateParticipationStatuses( shortName colour } + tardiness } } } @@ -35,6 +36,18 @@ mutation touchDocumentation($documentationId: ID!) { shortName colour } + notesWithExtraMark { + id + extraMark { + id + showInCoursebook + } + } + notesWithNote { + id + note + } + tardiness isOptimistic } } diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql index 51194f801b641578a48a7aaea416a5bd783f3e0a..45bb295dbb453e832f86585e1b288c785ef87de9 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql +++ b/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql @@ -37,8 +37,10 @@ query documentationsForCoursebook( } amends { id + title amends { id + title teachers { id shortName @@ -81,6 +83,18 @@ query documentationsForCoursebook( shortName colour } + notesWithExtraMark { + id + extraMark { + id + showInCoursebook + } + } + notesWithNote { + id + note + } + tardiness isOptimistic } topic @@ -118,6 +132,7 @@ mutation createOrUpdateDocumentations($input: [DocumentationInputType]!) { shortName colour } + tardiness isOptimistic } } diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/DocumentationModal.vue b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/DocumentationModal.vue index 460f39f97fc15b61d0476dd99ed33d29cf43029c..630085bd593f145e5a8a15c50d686a2e48cf6a20 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/DocumentationModal.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/DocumentationModal.vue @@ -4,7 +4,12 @@ <mobile-fullscreen-dialog v-model="popup" max-width="500px"> <template #activator="activator"> <!-- list view -> activate dialog --> - <documentation compact v-bind="$attrs" :dialog-activator="activator" /> + <documentation + compact + v-bind="$attrs" + :dialog-activator="activator" + :extra-marks="extraMarks" + /> </template> <!-- dialog view -> deactivate dialog --> <!-- cancel | save (through lesson-summary) --> @@ -27,5 +32,11 @@ export default { popup: false, }; }, + props: { + extraMarks: { + type: Array, + required: true, + }, + }, }; </script> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonInformation.vue b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonInformation.vue index 652609dccaf430d3a4ab138f80ee2f810b84b4af..890e557e162c64868de3a0362b248cea4c2604d8 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonInformation.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonInformation.vue @@ -24,7 +24,11 @@ import PersonChip from "aleksis.core/components/person/PersonChip.vue"; 'font-weight-medium': largeGrid, }" > - {{ documentation.course?.name }} + {{ + documentation.course?.name || + documentation.amends.title || + documentation.amends.amends.title + }} </span> <div :class="{ @@ -38,6 +42,10 @@ import PersonChip from "aleksis.core/components/person/PersonChip.vue"; :subject="documentation.subject" v-bind="compact ? dialogActivator.attrs : {}" v-on="compact ? dialogActivator.on : {}" + :class="{ + 'text-decoration-line-through': documentation.amends?.cancelled, + }" + :disabled="documentation.amends?.cancelled" /> <subject-chip v-if=" diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonNotes.vue b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonNotes.vue index bc0da4a742917e0639a0c1983186fad29764babb..64bbb59cb8a4bffdabf9b0d641f2a6e415a2ba69 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonNotes.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonNotes.vue @@ -1,5 +1,7 @@ <script setup> import AbsenceReasonChip from "aleksis.apps.kolego/components/AbsenceReasonChip.vue"; +import ExtraMarkChip from "../../extra_marks/ExtraMarkChip.vue"; +import TardinessChip from "../absences/TardinessChip.vue"; </script> <template> @@ -35,6 +37,56 @@ import AbsenceReasonChip from "aleksis.apps.kolego/components/AbsenceReasonChip. </template> </absence-reason-chip> + <extra-mark-chip + v-for="[markId, [mark, ...participations]] in Object.entries( + extraMarkChips, + )" + :key="'extra-mark-' + markId" + :extra-mark="mark" + dense + > + <template #append> + <span + >: + <span> + {{ + participations + .slice(0, 5) + .map((participation) => participation.person.firstName) + .join(", ") + }} + </span> + <span v-if="participations.length > 5"> + <!-- eslint-disable @intlify/vue-i18n/no-raw-text --> + +{{ participations.length - 5 }} + <!-- eslint-enable @intlify/vue-i18n/no-raw-text --> + </span> + </span> + </template> + </extra-mark-chip> + + <tardiness-chip v-if="tardyParticipations.length > 0"> + {{ $t("alsijil.personal_notes.late") }} + + <template #append> + <span + >: + {{ + tardyParticipations + .slice(0, 5) + .map((participation) => participation.person.firstName) + .join(", ") + }} + + <span v-if="tardyParticipations.length > 5"> + <!-- eslint-disable @intlify/vue-i18n/no-raw-text --> + +{{ tardyParticipations.length - 5 }} + <!-- eslint-enable @intlify/vue-i18n/no-raw-text --> + </span> + </span> + </template> + </tardiness-chip> + <manage-students-trigger v-bind="documentationPartProps" /> </div> </template> @@ -51,13 +103,18 @@ export default { total() { return this.documentation.participations.length; }, + /** + * Return the number of present people. + */ present() { return this.documentation.participations.filter( (p) => p.absenceReason === null, ).length; }, + /** + * Get all course attendants who have an absence reason, grouped by that reason. + */ absences() { - // Get all course attendants who have an absence reason return Object.groupBy( this.documentation.participations.filter( (p) => p.absenceReason !== null, @@ -65,6 +122,42 @@ export default { ({ absenceReason }) => absenceReason.id, ); }, + /** + * Parse and combine all extraMark notes. + * + * Notes with extraMarks are grouped by ExtraMark. ExtraMarks with the showInCoursebook property set to false are ignored. + * @return An object where the keys are extraMark IDs and the values have the structure [extraMark, note1, note2, ..., noteN] + */ + extraMarkChips() { + // Apply the inner function to each participation, with value being the resulting object + return this.documentation.participations.reduce((value, p) => { + // Go through every extra mark of this participation + for (const { extraMark } of p.notesWithExtraMark) { + // Only proceed if the extraMark should be displayed here + if (!extraMark.showInCoursebook) { + continue; + } + + // value[extraMark.id] is an Array with the structure [extraMark, note1, note2, ..., noteN] + if (value[extraMark.id]) { + value[extraMark.id].push(p); + } else { + value[extraMark.id] = [ + this.extraMarks.find((e) => e.id === extraMark.id), + p, + ]; + } + } + + return value; + }, {}); + }, + /** + * Return a list Participations with a set tardiness + */ + tardyParticipations() { + return this.documentation.participations.filter((p) => p.tardiness); + }, }, }; </script> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/documentationPartMixin.js b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/documentationPartMixin.js index 88a8e852f8cc6e333303034fb5f590d174708886..35243ee3ca5e055c0d2fd5375fba614bbbd6e246 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/documentationPartMixin.js +++ b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/documentationPartMixin.js @@ -33,6 +33,13 @@ export default { required: false, default: () => ({ attrs: {}, on: {} }), }, + /** + * Once loaded list of all extra marks to avoid excessive network and database queries + */ + extraMarks: { + type: Array, + required: true, + }, }, computed: { @@ -46,6 +53,7 @@ export default { compact: this.compact, dialogActivator: this.dialogActivator, affectedQuery: this.affectedQuery, + extraMarks: this.extraMarks, }; }, }, diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/ExtraMarkNoteCheckbox.vue b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/ExtraMarkNoteCheckbox.vue new file mode 100644 index 0000000000000000000000000000000000000000..1f31f9ee1cf6c557ee2fe7b86134793629f9063f --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/ExtraMarkNoteCheckbox.vue @@ -0,0 +1,104 @@ +<script> +import { + createPersonalNotes, + deletePersonalNotes, +} from "./personal_notes.graphql"; +import personalNoteRelatedMixin from "./personalNoteRelatedMixin"; +import mutateMixin from "aleksis.core/mixins/mutateMixin.js"; + +export default { + name: "ExtraMarkNoteCheckbox", + mixins: [mutateMixin, personalNoteRelatedMixin], + props: { + personalNote: { + type: Object, + default: null, + }, + /** + * Extra Mark + */ + value: { + type: Object, + required: true, + }, + }, + computed: { + model: { + get() { + return !!this.personalNote?.id; + }, + set(newValue) { + if (newValue && !this.personalNote) { + // CREATE new personal note + this.mutate( + createPersonalNotes, + { + input: [ + { + documentation: this.documentation.id, + person: this.participation.person.id, + extraMark: this.value.id, + }, + ], + }, + (storedDocumentations, incomingPersonalNotes) => { + const note = incomingPersonalNotes[0]; + const documentation = storedDocumentations.find( + (doc) => doc.id === this.documentation.id, + ); + const participationStatus = documentation.participations.find( + (part) => part.id === this.participation.id, + ); + participationStatus.notesWithExtraMark.push(note); + + return storedDocumentations; + }, + ); + } else { + // DELETE personal note + this.mutate( + deletePersonalNotes, + { + ids: [this.personalNote.id], + }, + (storedDocumentations) => { + const documentation = storedDocumentations.find( + (doc) => doc.id === this.documentation.id, + ); + const participationStatus = documentation.participations.find( + (part) => part.id === this.participation.id, + ); + const index = participationStatus.notesWithExtraMark.findIndex( + (n) => n.id === this.personalNote.id, + ); + participationStatus.notesWithExtraMark.splice(index, 1); + + return storedDocumentations; + }, + ); + } + }, + }, + }, +}; +</script> + +<template> + <v-checkbox + :label="value.name" + :value="value.id" + v-model="model" + :disabled="loading" + :true-value="true" + :false-value="false" + > + <template #append> + <v-progress-circular + v-if="loading" + indeterminate + :size="16" + :width="2" + ></v-progress-circular> + </template> + </v-checkbox> +</template> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/ExtraMarksNote.vue b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/ExtraMarksNote.vue new file mode 100644 index 0000000000000000000000000000000000000000..177b21e803f073e7965815662a00727b8b8a24e4 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/ExtraMarksNote.vue @@ -0,0 +1,29 @@ +<script> +import { extraMarks } from "../../extra_marks/extra_marks.graphql"; +import ExtraMarkNoteCheckbox from "./ExtraMarkNoteCheckbox.vue"; +import personalNoteRelatedMixin from "./personalNoteRelatedMixin"; + +export default { + name: "ExtraMarksNote", + components: { ExtraMarkNoteCheckbox }, + mixins: [personalNoteRelatedMixin], + props: { + value: { + type: Array, + required: true, + }, + }, +}; +</script> + +<template> + <div> + <extra-mark-note-checkbox + v-for="extraMark in extraMarks" + :key="'checkbox-extramark-' + extraMark.id" + v-bind="personalNoteRelatedProps" + :value="extraMark" + :personal-note="value.find((pn) => pn.extraMark.id === extraMark.id)" + /> + </div> +</template> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/PersonalNotes.vue b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/PersonalNotes.vue new file mode 100644 index 0000000000000000000000000000000000000000..2a3d953f03484ef2af2f1ac7a8f876bcb658f8bf --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/PersonalNotes.vue @@ -0,0 +1,28 @@ +<script setup> +import ExtraMarksNote from "./ExtraMarksNote.vue"; +import TextNotes from "./TextNotes.vue"; +</script> +<script> +import personalNoteRelatedMixin from "./personalNoteRelatedMixin"; + +export default { + name: "PersonalNotes", + mixins: [personalNoteRelatedMixin], +}; +</script> + +<template> + <div> + <text-notes + v-bind="personalNoteRelatedProps" + :value="participation.notesWithNote" + /> + + <extra-marks-note + v-bind="personalNoteRelatedProps" + :value="participation.notesWithExtraMark" + /> + </div> +</template> + +<style scoped></style> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/TextNote.vue b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/TextNote.vue new file mode 100644 index 0000000000000000000000000000000000000000..43175c7402100c5ef9e4b84c153a8e79a9bb7f76 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/TextNote.vue @@ -0,0 +1,164 @@ +<script> +import { + createPersonalNotes, + deletePersonalNotes, + updatePersonalNotes, +} from "./personal_notes.graphql"; +import personalNoteRelatedMixin from "./personalNoteRelatedMixin"; +import mutateMixin from "aleksis.core/mixins/mutateMixin.js"; +import DeleteDialog from "aleksis.core/components/generic/dialogs/DeleteDialog.vue"; + +export default { + name: "TextNote", + components: { DeleteDialog }, + mixins: [mutateMixin, personalNoteRelatedMixin], + props: { + value: { + type: Object, + required: true, + }, + }, + computed: { + model: { + get() { + return this.value.note; + }, + set(newValue) { + if (!newValue) { + // this is a DELETE action, show the dialog, ... + this.showDeleteConfirm = true; + return; + } + const create = !this.value.id; + + this.mutate( + create ? createPersonalNotes : updatePersonalNotes, + this.getInput( + newValue, + create + ? { + documentation: this.documentation.id, + person: this.participation.person.id, + extraMark: null, + } + : { + id: this.value.id, + }, + ), + this.getUpdater(create ? "create" : "update"), + ); + }, + }, + }, + methods: { + getInput(newValue, extras) { + return { + input: [ + { + note: newValue, + ...extras, + }, + ], + }; + }, + getUpdater(mode) { + return (storedDocumentations, incomingPersonalNotes) => { + const note = incomingPersonalNotes?.[0] || undefined; + const documentation = storedDocumentations.find( + (doc) => doc.id === this.documentation.id, + ); + const participationStatus = documentation.participations.find( + (part) => part.id === this.participation.id, + ); + switch (mode.toLowerCase()) { + case "update": + case "delete": { + const updateIndex = participationStatus.notesWithNote.findIndex( + (n) => n.id === this.value.id, + ); + if (mode === "update") { + participationStatus.notesWithNote.splice(updateIndex, 1, note); + } else { + participationStatus.notesWithNote.splice(updateIndex, 1); + } + + break; + } + + case "create": + participationStatus.notesWithNote.push(note); + + this.$emit("create"); + break; + + default: + console.error("Invalid mode in getUpdater():", mode); + break; + } + + return storedDocumentations; + }; + }, + }, + data() { + return { + showDeleteConfirm: false, + deletePersonalNotes, + }; + }, +}; +</script> + +<template> + <v-textarea + auto-grow + :rows="3" + outlined + hide-details + class="mb-4" + :label="$t('alsijil.personal_notes.note')" + :value="model" + @change="model = $event" + :loading="loading" + > + <template #append> + <v-slide-x-reverse-transition> + <v-btn + v-if="!!model" + icon + @click="showDeleteConfirm = true" + class="mt-n1-5" + > + <v-icon> $deleteContent </v-icon> + </v-btn> + </v-slide-x-reverse-transition> + + <delete-dialog + v-model="showDeleteConfirm" + :gql-delete-mutation="deletePersonalNotes" + :affected-query="affectedQuery" + item-attribute="fullName" + :items="[value]" + :custom-update="getUpdater('delete')" + > + <template #title> + {{ $t("alsijil.personal_notes.confirm_delete") }} + </template> + <template #body> + {{ + $t("alsijil.personal_notes.confirm_delete_explanation", { + note: value.note, + name: participation.person.fullName, + }) + }} + </template> + </delete-dialog> + </template> + </v-textarea> +</template> + +<style scoped> +.mt-n1-5 { + margin-top: -6px; +} +</style> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/TextNotes.vue b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/TextNotes.vue new file mode 100644 index 0000000000000000000000000000000000000000..dd32164db251b16acdc8b61daa29559b9a776fde --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/TextNotes.vue @@ -0,0 +1,48 @@ +<script setup> +import SecondaryActionButton from "aleksis.core/components/generic/buttons/SecondaryActionButton.vue"; +import TextNote from "./TextNote.vue"; +</script> +<script> +import personalNoteRelatedMixin from "./personalNoteRelatedMixin"; + +export default { + name: "TextNotes", + mixins: [personalNoteRelatedMixin], + props: { + value: { + type: Array, + required: true, + }, + }, + data() { + return { + showNewNote: true, + }; + }, + computed: { + notes() { + return this.showNewNote ? [...this.value, { note: "" }] : this.value; + }, + }, +}; +</script> + +<template> + <div> + <text-note + v-for="note in notes" + :key="note.id || -1" + v-bind="personalNoteRelatedProps" + :value="note" + @create="showNewNote = false" + /> + + <secondary-action-button + i18n-key="alsijil.personal_notes.create_personal_note" + icon-text="$plus" + class="full-width" + @click="showNewNote = true" + :disabled="showNewNote" + /> + </div> +</template> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/personalNoteRelatedMixin.js b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/personalNoteRelatedMixin.js new file mode 100644 index 0000000000000000000000000000000000000000..0eda6c4ca625afb16742d9ea8e585254d041e970 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/personalNoteRelatedMixin.js @@ -0,0 +1,19 @@ +import documentationPartMixin from "../documentation/documentationPartMixin"; + +export default { + mixins: [documentationPartMixin], + props: { + participation: { + type: Object, + required: true, + }, + }, + computed: { + personalNoteRelatedProps() { + return { + ...this.documentationPartProps, + participation: this.participation, + }; + }, + }, +}; diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/personal_notes.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/personal_notes.graphql new file mode 100644 index 0000000000000000000000000000000000000000..014178c1326960f02dee24cf92f8eb5c679298f5 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/personal_notes/personal_notes.graphql @@ -0,0 +1,45 @@ +query personalNotes($orderBy: [String], $filters: JSONString) { + items: personalNotes(orderBy: $orderBy, filters: $filters) { + id + note + extraMark { + id + } + canEdit + canDelete + } +} + +mutation createPersonalNotes($input: [BatchCreatePersonalNoteInput]!) { + createPersonalNotes(input: $input) { + items: personalNotes { + id + note + extraMark { + id + } + canEdit + canDelete + } + } +} + +mutation deletePersonalNotes($ids: [ID]!) { + deletePersonalNotes(ids: $ids) { + deletionCount + } +} + +mutation updatePersonalNotes($input: [BatchPatchPersonalNoteInput]!) { + updatePersonalNotes(input: $input) { + items: personalNotes { + id + note + extraMark { + id + } + canEdit + canDelete + } + } +} diff --git a/aleksis/apps/alsijil/frontend/components/extra_marks/ExtraMarkChip.vue b/aleksis/apps/alsijil/frontend/components/extra_marks/ExtraMarkChip.vue new file mode 100644 index 0000000000000000000000000000000000000000..da5cd4182d6f25965374934a31d64691dbdf852f --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/extra_marks/ExtraMarkChip.vue @@ -0,0 +1,49 @@ +<script> +import CounterChip from "aleksis.core/components/generic/chips/CounterChip.vue"; + +export default { + name: "ExtraMarkChip", + components: { CounterChip }, + props: { + extraMark: { + type: Object, + required: true, + }, + short: { + type: Boolean, + required: false, + default: false, + }, + loading: { + type: Boolean, + required: false, + default: false, + }, + }, + extends: CounterChip, + computed: { + text() { + return this.short ? this.extraMark.shortName : this.extraMark.name; + }, + }, +}; +</script> + +<template> + <counter-chip + :color="extraMark.colourBg" + :text-color="extraMark.colourFg" + :value="extraMark.id" + :count="count" + :outlined="false" + v-bind="$attrs" + v-on="$listeners" + > + <slot name="prepend" /> + {{ text }} + <slot name="append" /> + <v-avatar right v-if="loading"> + <v-progress-circular indeterminate :size="16" :width="2" /> + </v-avatar> + </counter-chip> +</template> diff --git a/aleksis/apps/alsijil/frontend/components/extra_marks/ExtraMarks.vue b/aleksis/apps/alsijil/frontend/components/extra_marks/ExtraMarks.vue new file mode 100644 index 0000000000000000000000000000000000000000..9468ac1dba5d291abd251659586d24aa95fe0278 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/extra_marks/ExtraMarks.vue @@ -0,0 +1,138 @@ +<script setup> +import ColorField from "aleksis.core/components/generic/forms/ColorField.vue"; +import InlineCRUDList from "aleksis.core/components/generic/InlineCRUDList.vue"; +</script> + +<template> + <v-container> + <inline-c-r-u-d-list + :headers="headers" + :i18n-key="i18nKey" + create-item-i18n-key="alsijil.extra_marks.create" + :gql-query="gqlQuery" + :gql-create-mutation="gqlCreateMutation" + :gql-patch-mutation="gqlPatchMutation" + :gql-delete-mutation="gqlDeleteMutation" + :default-item="defaultItem" + > + <!-- eslint-disable-next-line vue/valid-v-slot --> + <template #name.field="{ attrs, on }"> + <div aria-required="true"> + <v-text-field + v-bind="attrs" + v-on="on" + :rules="$rules().required.build()" + /> + </div> + </template> + + <!-- eslint-disable-next-line vue/valid-v-slot --> + <template #shortName.field="{ attrs, on }"> + <div aria-required="true"> + <v-text-field + v-bind="attrs" + v-on="on" + :rules="$rules().required.build()" + /> + </div> + </template> + + <template #colourFg="{ item }"> + <v-chip :color="item.colourFg" outlined v-if="item.colourFg"> + {{ item.colourFg }} + </v-chip> + <span v-else>–</span> + </template> + <!-- eslint-disable-next-line vue/valid-v-slot --> + <template #colourFg.field="{ attrs, on }"> + <color-field v-bind="attrs" v-on="on" /> + </template> + + <template #colourBg="{ item }"> + <v-chip :color="item.colourBg" outlined v-if="item.colourBg"> + {{ item.colourBg }} + </v-chip> + <span v-else>–</span> + </template> + <!-- eslint-disable-next-line vue/valid-v-slot --> + <template #colourBg.field="{ attrs, on }"> + <color-field v-bind="attrs" v-on="on" /> + </template> + + <template #showInCoursebook="{ item }"> + <v-switch + :input-value="item.showInCoursebook" + disabled + inset + :false-value="false" + :true-value="true" + /> + </template> + <!-- eslint-disable-next-line vue/valid-v-slot --> + <template #showInCoursebook.field="{ attrs, on }"> + <v-switch + v-bind="attrs" + v-on="on" + inset + :false-value="false" + :true-value="true" + :hint="$t('alsijil.extra_marks.show_in_coursebook_helptext')" + persistent-hint + /> + </template> + </inline-c-r-u-d-list> + </v-container> +</template> + +<script> +import formRulesMixin from "aleksis.core/mixins/formRulesMixin.js"; +import { + extraMarks, + createExtraMarks, + deleteExtraMarks, + updateExtraMarks, +} from "./extra_marks.graphql"; + +export default { + name: "ExtraMarks", + mixins: [formRulesMixin], + data() { + return { + headers: [ + { + text: this.$t("alsijil.extra_marks.short_name"), + value: "shortName", + }, + { + text: this.$t("alsijil.extra_marks.name"), + value: "name", + }, + { + text: this.$t("alsijil.extra_marks.colour_fg"), + value: "colourFg", + }, + { + text: this.$t("alsijil.extra_marks.colour_bg"), + value: "colourBg", + }, + { + text: this.$t("alsijil.extra_marks.show_in_coursebook"), + value: "showInCoursebook", + }, + ], + i18nKey: "alsijil.extra_marks", + gqlQuery: extraMarks, + gqlCreateMutation: createExtraMarks, + gqlPatchMutation: updateExtraMarks, + gqlDeleteMutation: deleteExtraMarks, + defaultItem: { + shortName: "", + name: "", + colourFg: "", + colourBg: "", + showInCoursebook: true, + }, + }; + }, +}; +</script> diff --git a/aleksis/apps/alsijil/frontend/components/extra_marks/extra_marks.graphql b/aleksis/apps/alsijil/frontend/components/extra_marks/extra_marks.graphql new file mode 100644 index 0000000000000000000000000000000000000000..73e8ba4121c215dc4c3968b3ed2021b71b5ecfc1 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/extra_marks/extra_marks.graphql @@ -0,0 +1,48 @@ +query extraMarks($orderBy: [String], $filters: JSONString) { + items: extraMarks(orderBy: $orderBy, filters: $filters) { + id + shortName + name + colourFg + colourBg + showInCoursebook + canEdit + canDelete + } +} + +mutation createExtraMarks($input: [BatchCreateExtraMarkInput]!) { + createExtraMarks(input: $input) { + items: extraMarks { + id + shortName + name + colourFg + colourBg + showInCoursebook + canEdit + canDelete + } + } +} + +mutation deleteExtraMarks($ids: [ID]!) { + deleteExtraMarks(ids: $ids) { + deletionCount + } +} + +mutation updateExtraMarks($input: [BatchPatchExtraMarkInput]!) { + updateExtraMarks(input: $input) { + items: extraMarks { + id + shortName + name + colourFg + colourBg + showInCoursebook + canEdit + canDelete + } + } +} diff --git a/aleksis/apps/alsijil/frontend/index.js b/aleksis/apps/alsijil/frontend/index.js index a1dfdf84d9ec32cdb15b077c2b0da7eac3941eaa..fb69e3eacf436cc238afef95e3777f9c218f9480 100644 --- a/aleksis/apps/alsijil/frontend/index.js +++ b/aleksis/apps/alsijil/frontend/index.js @@ -16,45 +16,6 @@ export default { byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, }, children: [ - { - path: "extra_marks/", - component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), - name: "alsijil.extraMarks", - meta: { - inMenu: true, - titleKey: "alsijil.extra_marks.menu_title", - icon: "mdi-label-variant-outline", - iconActive: "mdi-label-variant", - permission: "alsijil.view_extramarks_rule", - }, - props: { - byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, - }, - }, - { - path: "extra_marks/create/", - component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), - name: "alsijil.createExtraMark", - props: { - byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, - }, - }, - { - path: "extra_marks/:pk(\\d+)/edit/", - component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), - name: "alsijil.editExtraMark", - props: { - byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, - }, - }, - { - path: "extra_marks/:pk(\\d+)/delete/", - component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), - name: "alsijil.deleteExtraMark", - props: { - byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, - }, - }, { path: "coursebook/", component: () => import("./components/coursebook/Coursebook.vue"), @@ -92,5 +53,17 @@ export default { }, ], }, + { + path: "extra_marks/", + component: () => import("./components/extra_marks/ExtraMarks.vue"), + name: "alsijil.extraMarks", + meta: { + inMenu: true, + titleKey: "alsijil.extra_marks.menu_title", + icon: "mdi-label-variant-outline", + iconActive: "mdi-label-variant", + permission: "alsijil.view_extramarks_rule", + }, + }, ], }; diff --git a/aleksis/apps/alsijil/frontend/messages/de.json b/aleksis/apps/alsijil/frontend/messages/de.json index 31ae2d9763a98f946aa896a9ab79d5fc8d514a0f..c2b56f0159cb184f5b9fd49d8505fc4771bc2d92 100644 --- a/aleksis/apps/alsijil/frontend/messages/de.json +++ b/aleksis/apps/alsijil/frontend/messages/de.json @@ -1,4 +1,7 @@ { + "actions": { + "back_to_overview": "Zurück zur Übersicht" + }, "alsijil": { "absence": { "menu_title": "Abwesenheit eintragen" @@ -7,6 +10,14 @@ "menu_title": "Alle Stunden" }, "coursebook": { + "absences": { + "button": "Abwesenheiten erfassen", + "lessons": "Keine Stunden | 1 Stunde | {count} Stunden", + "success": "Die Abwesenheiten wurden erfolgreich erfasst.", + "summary": "Zusammenfassung", + "title": "Abwesenheiten erfassen", + "warning": "Die folgenden Stunden liegen im ausgewählten Zeitraum. Bitte überprüfen Sie vor dem Bestätigen, ob Sie die Abwesenheiten für diese Stunden erfassen möchten." + }, "filter": { "courses": "Kurse", "filter_for_obj": "Nach Gruppe und Kurs filtern", @@ -22,6 +33,7 @@ "no_entry": "Für diese Stunde gibt es noch keinen Eintrag." }, "page_title": "Kursbuch für {name}", + "present_number": "{present}/{total} anwesend", "status": { "available": "Kursbucheintrag vorhanden", "cancelled": "Stunde fällt aus", @@ -49,27 +61,22 @@ } } }, - "title_plural": "Kursbuch", - "present_number": "{present}/{total} anwesend" + "title_plural": "Kursbuch" }, "excuse_types": { "menu_title": "Entschuldigungsarten" }, "extra_marks": { - "menu_title": "Zusätzliche Markierungen", + "colour_bg": "Hintergrundfarbe", + "colour_fg": "Schriftfarbe", "create": "Markierung erstellen", + "menu_title": "Zusätzliche Markierungen", "name": "Markierung", "short_name": "Abkürzung", - "colour_fg": "Schriftfarbe", - "colour_bg": "Hintergrundfarbe", "show_in_coursebook": "In Kursbuch-Übersicht zeigen", - "show_in_coursebook_helptext": "Wenn aktiviert tauchen diese Markierungen in den Zeilen im Kursbuch auf." - }, - "personal_notes": { - "note": "Notiz", - "create_personal_note": "Weitere Notiz", - "confirm_delete": "Notiz wirklich löschen?", - "confirm_delete_explanation": "Die Notiz \"{note}\" für {name} wird entfernt." + "show_in_coursebook_helptext": "Wenn aktiviert tauchen diese Markierungen in den Zeilen im Kursbuch auf.", + "title": "Zusätzliche Markierung", + "title_plural": "Zusätzliche Markierungen" }, "group_roles": { "menu_title_assign": "Gruppenrollen zuweisen", @@ -85,6 +92,17 @@ "my_overview": { "menu_title": "Meine Übersicht" }, + "personal_notes": { + "confirm_delete": "Anmerkung wirklich löschen?", + "confirm_delete_explanation": "Die Notiz \"{note}\" für {name} wird entfernt.", + "confirm_delete_tardiness": "Die Verspätung von {name} in Höhe von {tardiness} Minuten wird entfernt.", + "create_personal_note": "Weitere Notiz", + "late": "Verspätet", + "lesson_length_exceeded": "Die Verspätung überschreitet die Stundenlänge.", + "minutes_late": "pünktlich | eine Minute verspätet | {n} Minuten zu spät", + "note": "Notiz", + "tardiness": "Verspätung" + }, "persons": { "menu_title": "Meine Schüler*innen" }, @@ -92,7 +110,7 @@ "menu_title": "Aktuelle Woche" } }, - "actions": { - "back_to_overview": "Zurück zur Übersicht" + "time": { + "minutes": "Minuten" } } diff --git a/aleksis/apps/alsijil/frontend/messages/en.json b/aleksis/apps/alsijil/frontend/messages/en.json index d3a9e5c745fd89cc3e32bcbd4309f75d66f953a3..57b4501cb04b7a434b1768057212cf6f434a0822 100644 --- a/aleksis/apps/alsijil/frontend/messages/en.json +++ b/aleksis/apps/alsijil/frontend/messages/en.json @@ -19,7 +19,16 @@ "menu_title": "My overview" }, "extra_marks": { - "menu_title": "Extra marks" + "menu_title": "Extra marks", + "title": "Extra mark", + "title_plural": "Extra marks", + "create": "Create Extra mark", + "name": "Mark", + "short_name": "Abbreviation", + "colour_fg": "Foreground Colour", + "colour_bg": "Background Colour", + "show_in_coursebook": "Show in Coursebook Overview", + "show_in_coursebook_helptext": "When checked, this extra mark will be displayed in the lesson summary in the coursebook" }, "excuse_types": { "menu_title": "Excuse types" @@ -83,11 +92,31 @@ "no_data": "No lessons for the selected groups and courses in this period", "no_results": "No search results for {search}", "absences": { - "action_for_selected": "Mark selected participant as: | Mark {count} selected participants as" + "action_for_selected": "Mark selected participant as: | Mark {count} selected participants as", + "title": "Register absences", + "button": "Register absences", + "summary": "Summary", + "lessons": "No lessons | 1 lesson | {count} lessons", + "success": "The absences were registered successfully.", + "warning": "The following lessons are in the selected time period. Please check that you want to register the absences for these lessons before confirming." } + }, + "personal_notes": { + "note": "Note", + "create_personal_note": "Add another note", + "tardiness": "Tardiness", + "late": "Late", + "minutes_late": "on time | one minute late | {n} minutes late", + "lesson_length_exceeded": "The tardiness exceeds the length of the lesson", + "confirm_delete": "Delete note?", + "confirm_delete_explanation": "The note \"{note}\" for {name} will be removed.", + "confirm_delete_tardiness": "The tardiness of {tardiness} minutes will be removed for {name}." } }, "actions": { "back_to_overview": "Back to overview" + }, + "time": { + "minutes": "minutes" } } diff --git a/aleksis/apps/alsijil/frontend/messages/uk.json b/aleksis/apps/alsijil/frontend/messages/uk.json index 860e21a111aa1d70dd74c3e787bb1763fa977808..d8eb24d954b20f7624a42dc5d4cb540034d64a2b 100644 --- a/aleksis/apps/alsijil/frontend/messages/uk.json +++ b/aleksis/apps/alsijil/frontend/messages/uk.json @@ -34,6 +34,9 @@ "my_overview": { "menu_title": "Мій оглÑд" }, + "personal_notes": { + "tardiness": "ЗапізненнÑ" + }, "persons": { "menu_title": "Мої Ñтуденти" }, diff --git a/aleksis/apps/alsijil/locale/ar/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/ar/LC_MESSAGES/django.po index 48140858293ae7990bfa39c1668d1807e11f51e4..633fede75f97a2761a573e5bd129e74b4faebb62 100644 --- a/aleksis/apps/alsijil/locale/ar/LC_MESSAGES/django.po +++ b/aleksis/apps/alsijil/locale/ar/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-06-13 11:19+0200\n" +"POT-Creation-Date: 2024-07-14 16:32+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -31,8 +31,8 @@ msgstr "" msgid "Mark as {excuse_type.name}" msgstr "" -#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:29 -#: aleksis/apps/alsijil/tables.py:53 aleksis/apps/alsijil/tables.py:78 +#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:33 +#: aleksis/apps/alsijil/tables.py:58 #: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:29 msgid "Delete" msgstr "" @@ -111,7 +111,7 @@ msgid "Before" msgstr "" #: aleksis/apps/alsijil/filters.py:14 aleksis/apps/alsijil/forms.py:371 -#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:116 +#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:96 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:126 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:223 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:189 @@ -152,20 +152,20 @@ msgid "You can't select a group and a teacher both." msgstr "" #: aleksis/apps/alsijil/forms.py:193 aleksis/apps/alsijil/forms.py:291 -#: aleksis/apps/alsijil/models.py:762 aleksis/apps/alsijil/models.py:819 +#: aleksis/apps/alsijil/models.py:763 aleksis/apps/alsijil/models.py:822 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:63 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:27 msgid "Person" msgstr "" #: aleksis/apps/alsijil/forms.py:194 aleksis/apps/alsijil/forms.py:372 -#: aleksis/apps/alsijil/models.py:891 +#: aleksis/apps/alsijil/models.py:903 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:64 msgid "Start date" msgstr "" #: aleksis/apps/alsijil/forms.py:195 aleksis/apps/alsijil/forms.py:373 -#: aleksis/apps/alsijil/models.py:895 +#: aleksis/apps/alsijil/models.py:907 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:65 msgid "End date" msgstr "" @@ -178,8 +178,8 @@ msgstr "" msgid "End period" msgstr "" -#: aleksis/apps/alsijil/forms.py:198 aleksis/apps/alsijil/tables.py:117 -#: aleksis/apps/alsijil/tables.py:138 +#: aleksis/apps/alsijil/forms.py:198 aleksis/apps/alsijil/tables.py:97 +#: aleksis/apps/alsijil/tables.py:118 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:50 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:392 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:28 @@ -188,7 +188,7 @@ msgstr "" msgid "Absent" msgstr "" -#: aleksis/apps/alsijil/forms.py:199 aleksis/apps/alsijil/tables.py:146 +#: aleksis/apps/alsijil/forms.py:199 aleksis/apps/alsijil/tables.py:126 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:54 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:135 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:30 @@ -220,7 +220,7 @@ msgstr "" msgid "Has lesson documentation" msgstr "" -#: aleksis/apps/alsijil/managers.py:91 aleksis/apps/alsijil/tables.py:130 +#: aleksis/apps/alsijil/managers.py:91 aleksis/apps/alsijil/tables.py:110 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:172 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:236 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:311 @@ -277,14 +277,14 @@ msgid "Short name" msgstr "" #: aleksis/apps/alsijil/models.py:64 aleksis/apps/alsijil/models.py:438 -#: aleksis/apps/alsijil/models.py:855 +#: aleksis/apps/alsijil/models.py:867 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:20 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:12 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:25 msgid "Name" msgstr "" -#: aleksis/apps/alsijil/models.py:68 aleksis/apps/alsijil/tables.py:41 +#: aleksis/apps/alsijil/models.py:68 aleksis/apps/alsijil/tables.py:21 msgid "Count as absent" msgstr "" @@ -304,9 +304,7 @@ msgid "Year" msgstr "" #: aleksis/apps/alsijil/models.py:265 aleksis/apps/alsijil/models.py:455 -#: aleksis/apps/alsijil/tables.py:120 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:8 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:9 +#: aleksis/apps/alsijil/tables.py:100 #: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:57 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:32 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:19 @@ -382,7 +380,7 @@ msgstr "" msgid "Course" msgstr "" -#: aleksis/apps/alsijil/models.py:486 aleksis/apps/alsijil/tables.py:111 +#: aleksis/apps/alsijil/models.py:486 aleksis/apps/alsijil/tables.py:91 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:127 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:253 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:331 @@ -401,8 +399,8 @@ msgstr "" msgid "Participation touched at" msgstr "" -#: aleksis/apps/alsijil/models.py:524 aleksis/apps/alsijil/models.py:772 -#: aleksis/apps/alsijil/models.py:826 +#: aleksis/apps/alsijil/models.py:524 aleksis/apps/alsijil/models.py:773 +#: aleksis/apps/alsijil/models.py:829 msgid "Documentation" msgstr "" @@ -410,102 +408,116 @@ msgstr "" msgid "Documentations" msgstr "" -#: aleksis/apps/alsijil/models.py:765 +#: aleksis/apps/alsijil/models.py:766 msgid "Groups of Person" msgstr "" -#: aleksis/apps/alsijil/models.py:778 +#: aleksis/apps/alsijil/models.py:779 msgid "Absence Reason" msgstr "" -#: aleksis/apps/alsijil/models.py:790 +#: aleksis/apps/alsijil/models.py:791 msgid "Base Absence" msgstr "" -#: aleksis/apps/alsijil/models.py:802 aleksis/apps/alsijil/models.py:803 +#: aleksis/apps/alsijil/models.py:794 aleksis/apps/alsijil/tables.py:98 +#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:161 +#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:21 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:46 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:123 +#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323 +msgid "Tardiness" +msgstr "" + +#: aleksis/apps/alsijil/models.py:805 aleksis/apps/alsijil/models.py:806 msgid "Participation Status" msgstr "" -#: aleksis/apps/alsijil/models.py:831 +#: aleksis/apps/alsijil/models.py:834 msgid "Note" msgstr "" -#: aleksis/apps/alsijil/models.py:833 +#: aleksis/apps/alsijil/models.py:836 msgid "Extra Mark" msgstr "" -#: aleksis/apps/alsijil/models.py:840 +#: aleksis/apps/alsijil/models.py:843 msgid "Personal Note" msgstr "" -#: aleksis/apps/alsijil/models.py:841 +#: aleksis/apps/alsijil/models.py:844 msgid "Personal Notes" msgstr "" -#: aleksis/apps/alsijil/models.py:856 +#: aleksis/apps/alsijil/models.py:855 +msgid "A person got assigned the same extra mark multiple times per documentation." +msgstr "" + +#: aleksis/apps/alsijil/models.py:868 msgid "Icon" msgstr "" -#: aleksis/apps/alsijil/models.py:857 +#: aleksis/apps/alsijil/models.py:869 msgid "Colour" msgstr "" -#: aleksis/apps/alsijil/models.py:863 aleksis/apps/alsijil/models.py:878 +#: aleksis/apps/alsijil/models.py:875 aleksis/apps/alsijil/models.py:890 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:62 msgid "Group role" msgstr "" -#: aleksis/apps/alsijil/models.py:864 +#: aleksis/apps/alsijil/models.py:876 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:90 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:8 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:9 msgid "Group roles" msgstr "" -#: aleksis/apps/alsijil/models.py:865 +#: aleksis/apps/alsijil/models.py:877 msgid "Can assign group role" msgstr "" -#: aleksis/apps/alsijil/models.py:884 +#: aleksis/apps/alsijil/models.py:896 msgid "Assigned person" msgstr "" -#: aleksis/apps/alsijil/models.py:889 aleksis/apps/alsijil/tables.py:105 +#: aleksis/apps/alsijil/models.py:901 aleksis/apps/alsijil/tables.py:85 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:124 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:242 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:321 msgid "Groups" msgstr "" -#: aleksis/apps/alsijil/models.py:896 +#: aleksis/apps/alsijil/models.py:908 msgid "Can be left empty if end date is not clear yet" msgstr "" -#: aleksis/apps/alsijil/models.py:911 +#: aleksis/apps/alsijil/models.py:923 msgid "Group role assignment" msgstr "" -#: aleksis/apps/alsijil/models.py:912 +#: aleksis/apps/alsijil/models.py:924 msgid "Group role assignments" msgstr "" -#: aleksis/apps/alsijil/models.py:919 +#: aleksis/apps/alsijil/models.py:931 msgid "Can view lesson overview" msgstr "" -#: aleksis/apps/alsijil/models.py:920 +#: aleksis/apps/alsijil/models.py:932 msgid "Can view week overview" msgstr "" -#: aleksis/apps/alsijil/models.py:921 +#: aleksis/apps/alsijil/models.py:933 msgid "Can view full register" msgstr "" -#: aleksis/apps/alsijil/models.py:922 +#: aleksis/apps/alsijil/models.py:934 msgid "Can register absence" msgstr "" -#: aleksis/apps/alsijil/models.py:923 +#: aleksis/apps/alsijil/models.py:935 msgid "Can list all personal note filters" msgstr "" @@ -610,38 +622,27 @@ msgstr "" msgid "Set time range for which documentations may be edited" msgstr "" -#: aleksis/apps/alsijil/tables.py:23 aleksis/apps/alsijil/tables.py:47 -#: aleksis/apps/alsijil/tables.py:72 +#: aleksis/apps/alsijil/tables.py:27 aleksis/apps/alsijil/tables.py:52 #: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:13 msgid "Edit" msgstr "" -#: aleksis/apps/alsijil/tables.py:96 +#: aleksis/apps/alsijil/tables.py:76 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:348 msgid "Date" msgstr "" -#: aleksis/apps/alsijil/tables.py:99 +#: aleksis/apps/alsijil/tables.py:79 #: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:30 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:122 msgid "Period" msgstr "" -#: aleksis/apps/alsijil/tables.py:118 -#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:161 -#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:21 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:46 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:123 -#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323 -msgid "Tardiness" -msgstr "" - -#: aleksis/apps/alsijil/tables.py:119 +#: aleksis/apps/alsijil/tables.py:99 msgid "Excuse" msgstr "" -#: aleksis/apps/alsijil/tables.py:156 +#: aleksis/apps/alsijil/tables.py:136 #, python-brace-format msgid "{value}' tardiness" msgstr "" @@ -968,17 +969,6 @@ msgid "" " " msgstr "" -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:6 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:7 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:14 -msgid "Create extra mark" -msgstr "" - -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:6 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:7 -msgid "Edit extra mark" -msgstr "" - #: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:9 #: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:16 #, python-format @@ -1472,98 +1462,86 @@ msgstr "" msgid "Notes" msgstr "" -#: aleksis/apps/alsijil/views.py:114 +#: aleksis/apps/alsijil/views.py:112 msgid "You either selected an invalid lesson or there is currently no lesson in progress." msgstr "" -#: aleksis/apps/alsijil/views.py:147 +#: aleksis/apps/alsijil/views.py:145 msgid "You are not allowed to create a lesson documentation for a lesson in the future." msgstr "" -#: aleksis/apps/alsijil/views.py:264 +#: aleksis/apps/alsijil/views.py:262 msgid "The lesson documentation has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:298 +#: aleksis/apps/alsijil/views.py:296 msgid "The personal notes have been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:658 +#: aleksis/apps/alsijil/views.py:656 msgid "Generate full register printout for {}" msgstr "" -#: aleksis/apps/alsijil/views.py:659 +#: aleksis/apps/alsijil/views.py:657 msgid "Generate full register printout …" msgstr "" -#: aleksis/apps/alsijil/views.py:660 +#: aleksis/apps/alsijil/views.py:658 msgid "The printout has been generated successfully." msgstr "" -#: aleksis/apps/alsijil/views.py:661 +#: aleksis/apps/alsijil/views.py:659 msgid "There was a problem while generating the printout." msgstr "" -#: aleksis/apps/alsijil/views.py:664 +#: aleksis/apps/alsijil/views.py:662 msgid "Download PDF" msgstr "" -#: aleksis/apps/alsijil/views.py:1030 +#: aleksis/apps/alsijil/views.py:1028 msgid "The absence has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1051 +#: aleksis/apps/alsijil/views.py:1049 msgid "The personal note has been deleted." msgstr "" -#: aleksis/apps/alsijil/views.py:1074 -msgid "The extra mark has been created." -msgstr "" - -#: aleksis/apps/alsijil/views.py:1086 -msgid "The extra mark has been saved." -msgstr "" - -#: aleksis/apps/alsijil/views.py:1097 -msgid "The extra mark has been deleted." -msgstr "" - -#: aleksis/apps/alsijil/views.py:1119 +#: aleksis/apps/alsijil/views.py:1072 msgid "The excuse type has been created." msgstr "" -#: aleksis/apps/alsijil/views.py:1131 +#: aleksis/apps/alsijil/views.py:1084 msgid "The excuse type has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1142 +#: aleksis/apps/alsijil/views.py:1095 msgid "The excuse type has been deleted." msgstr "" -#: aleksis/apps/alsijil/views.py:1164 +#: aleksis/apps/alsijil/views.py:1117 msgid "The group role has been created." msgstr "" -#: aleksis/apps/alsijil/views.py:1176 +#: aleksis/apps/alsijil/views.py:1129 msgid "The group role has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1187 +#: aleksis/apps/alsijil/views.py:1140 msgid "The group role has been deleted." msgstr "" -#: aleksis/apps/alsijil/views.py:1221 aleksis/apps/alsijil/views.py:1253 +#: aleksis/apps/alsijil/views.py:1174 aleksis/apps/alsijil/views.py:1206 msgid "The group role has been assigned." msgstr "" -#: aleksis/apps/alsijil/views.py:1272 +#: aleksis/apps/alsijil/views.py:1225 msgid "The group role assignment has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1293 +#: aleksis/apps/alsijil/views.py:1246 msgid "The group role assignment has been stopped." msgstr "" -#: aleksis/apps/alsijil/views.py:1306 +#: aleksis/apps/alsijil/views.py:1259 msgid "The group role assignment has been deleted." msgstr "" diff --git a/aleksis/apps/alsijil/locale/de_DE/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/de_DE/LC_MESSAGES/django.po index 14c910ed3a24b89bc09e4cc6438137dfbcc92b5d..4d620eccca073c7128ab8c852d9fca83a3ca9dd9 100644 --- a/aleksis/apps/alsijil/locale/de_DE/LC_MESSAGES/django.po +++ b/aleksis/apps/alsijil/locale/de_DE/LC_MESSAGES/django.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-06-13 11:19+0200\n" -"PO-Revision-Date: 2024-06-13 09:24+0000\n" +"POT-Creation-Date: 2024-07-14 16:32+0200\n" +"PO-Revision-Date: 2024-07-14 14:42+0000\n" "Last-Translator: Jonathan Weth <teckids@jonathanweth.de>\n" "Language-Team: German <https://translate.edugit.org/projects/aleksis/aleksis-app-alsijil/de/>\n" "Language: de_DE\n" @@ -31,8 +31,8 @@ msgstr "Als unentschuldigt markieren" msgid "Mark as {excuse_type.name}" msgstr "Als {excuse_type.name} markieren" -#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:29 -#: aleksis/apps/alsijil/tables.py:53 aleksis/apps/alsijil/tables.py:78 +#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:33 +#: aleksis/apps/alsijil/tables.py:58 #: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:29 msgid "Delete" msgstr "Löschen" @@ -111,7 +111,7 @@ msgid "Before" msgstr "Bevor" #: aleksis/apps/alsijil/filters.py:14 aleksis/apps/alsijil/forms.py:371 -#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:116 +#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:96 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:126 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:223 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:189 @@ -152,20 +152,20 @@ msgid "You can't select a group and a teacher both." msgstr "Es kann nur entweder eine Gruppe oder eine Lehrkraft ausgewählt werden." #: aleksis/apps/alsijil/forms.py:193 aleksis/apps/alsijil/forms.py:291 -#: aleksis/apps/alsijil/models.py:762 aleksis/apps/alsijil/models.py:819 +#: aleksis/apps/alsijil/models.py:763 aleksis/apps/alsijil/models.py:822 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:63 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:27 msgid "Person" msgstr "Person" #: aleksis/apps/alsijil/forms.py:194 aleksis/apps/alsijil/forms.py:372 -#: aleksis/apps/alsijil/models.py:891 +#: aleksis/apps/alsijil/models.py:903 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:64 msgid "Start date" msgstr "Startdatum" #: aleksis/apps/alsijil/forms.py:195 aleksis/apps/alsijil/forms.py:373 -#: aleksis/apps/alsijil/models.py:895 +#: aleksis/apps/alsijil/models.py:907 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:65 msgid "End date" msgstr "Enddatum" @@ -178,8 +178,8 @@ msgstr "Startstunde" msgid "End period" msgstr "Endstunde" -#: aleksis/apps/alsijil/forms.py:198 aleksis/apps/alsijil/tables.py:117 -#: aleksis/apps/alsijil/tables.py:138 +#: aleksis/apps/alsijil/forms.py:198 aleksis/apps/alsijil/tables.py:97 +#: aleksis/apps/alsijil/tables.py:118 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:50 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:392 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:28 @@ -188,7 +188,7 @@ msgstr "Endstunde" msgid "Absent" msgstr "Abwesend" -#: aleksis/apps/alsijil/forms.py:199 aleksis/apps/alsijil/tables.py:146 +#: aleksis/apps/alsijil/forms.py:199 aleksis/apps/alsijil/tables.py:126 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:54 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:135 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:30 @@ -220,7 +220,7 @@ msgstr "Schuljahr" msgid "Has lesson documentation" msgstr "Hat eine Stunden-Dokumentation" -#: aleksis/apps/alsijil/managers.py:91 aleksis/apps/alsijil/tables.py:130 +#: aleksis/apps/alsijil/managers.py:91 aleksis/apps/alsijil/tables.py:110 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:172 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:236 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:311 @@ -277,14 +277,14 @@ msgid "Short name" msgstr "Kurzname" #: aleksis/apps/alsijil/models.py:64 aleksis/apps/alsijil/models.py:438 -#: aleksis/apps/alsijil/models.py:855 +#: aleksis/apps/alsijil/models.py:867 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:20 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:12 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:25 msgid "Name" msgstr "Name" -#: aleksis/apps/alsijil/models.py:68 aleksis/apps/alsijil/tables.py:41 +#: aleksis/apps/alsijil/models.py:68 aleksis/apps/alsijil/tables.py:21 msgid "Count as absent" msgstr "Als abwesend zählen" @@ -304,9 +304,7 @@ msgid "Year" msgstr "Jahr" #: aleksis/apps/alsijil/models.py:265 aleksis/apps/alsijil/models.py:455 -#: aleksis/apps/alsijil/tables.py:120 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:8 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:9 +#: aleksis/apps/alsijil/tables.py:100 #: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:57 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:32 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:19 @@ -382,7 +380,7 @@ msgstr "Zusätzliche Markierung" msgid "Course" msgstr "Kurs" -#: aleksis/apps/alsijil/models.py:486 aleksis/apps/alsijil/tables.py:111 +#: aleksis/apps/alsijil/models.py:486 aleksis/apps/alsijil/tables.py:91 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:127 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:253 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:331 @@ -401,8 +399,8 @@ msgstr "Gruppennotiz" msgid "Participation touched at" msgstr "Teilnahmestatus angelegt am" -#: aleksis/apps/alsijil/models.py:524 aleksis/apps/alsijil/models.py:772 -#: aleksis/apps/alsijil/models.py:826 +#: aleksis/apps/alsijil/models.py:524 aleksis/apps/alsijil/models.py:773 +#: aleksis/apps/alsijil/models.py:829 msgid "Documentation" msgstr "Dokumentation" @@ -410,102 +408,116 @@ msgstr "Dokumentation" msgid "Documentations" msgstr "Dokumentationen" -#: aleksis/apps/alsijil/models.py:765 +#: aleksis/apps/alsijil/models.py:766 msgid "Groups of Person" msgstr "Gruppen der Person" -#: aleksis/apps/alsijil/models.py:778 +#: aleksis/apps/alsijil/models.py:779 msgid "Absence Reason" msgstr "Abwesenheitsgrund" -#: aleksis/apps/alsijil/models.py:790 +#: aleksis/apps/alsijil/models.py:791 msgid "Base Absence" msgstr "Basis-Abwesenheit" -#: aleksis/apps/alsijil/models.py:802 aleksis/apps/alsijil/models.py:803 +#: aleksis/apps/alsijil/models.py:794 aleksis/apps/alsijil/tables.py:98 +#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:161 +#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:21 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:46 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:123 +#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323 +msgid "Tardiness" +msgstr "Verspätung" + +#: aleksis/apps/alsijil/models.py:805 aleksis/apps/alsijil/models.py:806 msgid "Participation Status" msgstr "Teilnahmestatus" -#: aleksis/apps/alsijil/models.py:831 +#: aleksis/apps/alsijil/models.py:834 msgid "Note" msgstr "Notiz" -#: aleksis/apps/alsijil/models.py:833 +#: aleksis/apps/alsijil/models.py:836 msgid "Extra Mark" msgstr "Zusätzliche Markierung" -#: aleksis/apps/alsijil/models.py:840 +#: aleksis/apps/alsijil/models.py:843 msgid "Personal Note" msgstr "Persönliche Notiz" -#: aleksis/apps/alsijil/models.py:841 +#: aleksis/apps/alsijil/models.py:844 msgid "Personal Notes" msgstr "Persönliche Notizen" -#: aleksis/apps/alsijil/models.py:856 +#: aleksis/apps/alsijil/models.py:855 +msgid "A person got assigned the same extra mark multiple times per documentation." +msgstr "Eine Person hat die gleiche zusätzliche Markierung für eine Dokumentation mehrfach zugeordnet bekommen." + +#: aleksis/apps/alsijil/models.py:868 msgid "Icon" msgstr "Symbol" -#: aleksis/apps/alsijil/models.py:857 +#: aleksis/apps/alsijil/models.py:869 msgid "Colour" msgstr "Farbe" -#: aleksis/apps/alsijil/models.py:863 aleksis/apps/alsijil/models.py:878 +#: aleksis/apps/alsijil/models.py:875 aleksis/apps/alsijil/models.py:890 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:62 msgid "Group role" msgstr "Gruppenrolle" -#: aleksis/apps/alsijil/models.py:864 +#: aleksis/apps/alsijil/models.py:876 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:90 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:8 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:9 msgid "Group roles" msgstr "Gruppenrollen" -#: aleksis/apps/alsijil/models.py:865 +#: aleksis/apps/alsijil/models.py:877 msgid "Can assign group role" msgstr "Kann Gruppenrolle zuweisen" -#: aleksis/apps/alsijil/models.py:884 +#: aleksis/apps/alsijil/models.py:896 msgid "Assigned person" msgstr "Zugewiesene Person" -#: aleksis/apps/alsijil/models.py:889 aleksis/apps/alsijil/tables.py:105 +#: aleksis/apps/alsijil/models.py:901 aleksis/apps/alsijil/tables.py:85 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:124 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:242 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:321 msgid "Groups" msgstr "Gruppen" -#: aleksis/apps/alsijil/models.py:896 +#: aleksis/apps/alsijil/models.py:908 msgid "Can be left empty if end date is not clear yet" msgstr "Kann frei gelassen werden, wenn das Enddatum noch nicht feststeht" -#: aleksis/apps/alsijil/models.py:911 +#: aleksis/apps/alsijil/models.py:923 msgid "Group role assignment" msgstr "Zuweisung von Gruppenrollen" -#: aleksis/apps/alsijil/models.py:912 +#: aleksis/apps/alsijil/models.py:924 msgid "Group role assignments" msgstr "Zuweisungen von Gruppenrollen" -#: aleksis/apps/alsijil/models.py:919 +#: aleksis/apps/alsijil/models.py:931 msgid "Can view lesson overview" msgstr "Kann die Stundenübersicht sehen" -#: aleksis/apps/alsijil/models.py:920 +#: aleksis/apps/alsijil/models.py:932 msgid "Can view week overview" msgstr "Kann die Wochenübersicht sehen" -#: aleksis/apps/alsijil/models.py:921 +#: aleksis/apps/alsijil/models.py:933 msgid "Can view full register" msgstr "Kann komplettes Klassenbuch sehen" -#: aleksis/apps/alsijil/models.py:922 +#: aleksis/apps/alsijil/models.py:934 msgid "Can register absence" msgstr "Kann eine Absenz registrieren" -#: aleksis/apps/alsijil/models.py:923 +#: aleksis/apps/alsijil/models.py:935 msgid "Can list all personal note filters" msgstr "Kann alle Filter für persönliche Notizen anzeigen" @@ -610,38 +622,27 @@ msgstr "Bearbeiten von allen Dokumentationen bis inklusive zum aktuellen Tag und msgid "Set time range for which documentations may be edited" msgstr "Zeitraum setzen, in dem Dokumentationen bearbeitet werden dürfen" -#: aleksis/apps/alsijil/tables.py:23 aleksis/apps/alsijil/tables.py:47 -#: aleksis/apps/alsijil/tables.py:72 +#: aleksis/apps/alsijil/tables.py:27 aleksis/apps/alsijil/tables.py:52 #: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:13 msgid "Edit" msgstr "Bearbeiten" -#: aleksis/apps/alsijil/tables.py:96 +#: aleksis/apps/alsijil/tables.py:76 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:348 msgid "Date" msgstr "Datum" -#: aleksis/apps/alsijil/tables.py:99 +#: aleksis/apps/alsijil/tables.py:79 #: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:30 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:122 msgid "Period" msgstr "Stunde" -#: aleksis/apps/alsijil/tables.py:118 -#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:161 -#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:21 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:46 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:123 -#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323 -msgid "Tardiness" -msgstr "Verspätung" - -#: aleksis/apps/alsijil/tables.py:119 +#: aleksis/apps/alsijil/tables.py:99 msgid "Excuse" msgstr "Entschuldigen" -#: aleksis/apps/alsijil/tables.py:156 +#: aleksis/apps/alsijil/tables.py:136 #, python-brace-format msgid "{value}' tardiness" msgstr "{value}' Verspätung" @@ -993,17 +994,6 @@ msgstr "" "Benutzen Sie diese Funktion nicht, um eine Entschuldigungsart für normale Entschuldigungen zu erstellen oder wenn Sie nicht zwischen verschiedenen Entschuldigungsarten unterscheiden möchten.\n" " " -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:6 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:7 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:14 -msgid "Create extra mark" -msgstr "Zusätzliche Markierung erstellen" - -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:6 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:7 -msgid "Edit extra mark" -msgstr "Zusätzliche Markierung bearbeiten" - #: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:9 #: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:16 #, python-format @@ -1536,104 +1526,107 @@ msgstr "KW" msgid "Notes" msgstr "Notizen" -#: aleksis/apps/alsijil/views.py:114 +#: aleksis/apps/alsijil/views.py:112 msgid "You either selected an invalid lesson or there is currently no lesson in progress." msgstr "" "Sie haben eine ungültige Stunde ausgewählt oder es\n" " läuft momentan keine Stunde." -#: aleksis/apps/alsijil/views.py:147 +#: aleksis/apps/alsijil/views.py:145 msgid "You are not allowed to create a lesson documentation for a lesson in the future." msgstr "Ihnen ist es nicht erlaubt, eine Eintragung für eine Unterrichtsstunde in der Zukunft vorzunehmen." -#: aleksis/apps/alsijil/views.py:264 +#: aleksis/apps/alsijil/views.py:262 msgid "The lesson documentation has been saved." msgstr "Die Stunden-Dokumentation wurde gespeichert." -#: aleksis/apps/alsijil/views.py:298 +#: aleksis/apps/alsijil/views.py:296 msgid "The personal notes have been saved." msgstr "Die persönlichen Notizen wurden gespeichert." -#: aleksis/apps/alsijil/views.py:658 +#: aleksis/apps/alsijil/views.py:656 msgid "Generate full register printout for {}" msgstr "Vollständigen Klassenbuchausdruck für {} generieren" -#: aleksis/apps/alsijil/views.py:659 +#: aleksis/apps/alsijil/views.py:657 msgid "Generate full register printout …" msgstr "Vollständigen Klassenbuchausdruck generieren …" -#: aleksis/apps/alsijil/views.py:660 +#: aleksis/apps/alsijil/views.py:658 msgid "The printout has been generated successfully." msgstr "Der Ausdruck wurde erfolgreich generiert." -#: aleksis/apps/alsijil/views.py:661 +#: aleksis/apps/alsijil/views.py:659 msgid "There was a problem while generating the printout." msgstr "Es ist ein Fehler beim Generieren des Ausdrucks aufgetreten." -#: aleksis/apps/alsijil/views.py:664 +#: aleksis/apps/alsijil/views.py:662 msgid "Download PDF" msgstr "PDF herunterladen" -#: aleksis/apps/alsijil/views.py:1030 +#: aleksis/apps/alsijil/views.py:1028 msgid "The absence has been saved." msgstr "Die Abwesenheit wurde gespeichert." -#: aleksis/apps/alsijil/views.py:1051 +#: aleksis/apps/alsijil/views.py:1049 msgid "The personal note has been deleted." msgstr "Die persönliche Notiz wurde gelöscht." -#: aleksis/apps/alsijil/views.py:1074 -msgid "The extra mark has been created." -msgstr "Die zusätzliche Markierung wurde erstellt." - -#: aleksis/apps/alsijil/views.py:1086 -msgid "The extra mark has been saved." -msgstr "Die zusätzliche Markierung wurde gespeichert." - -#: aleksis/apps/alsijil/views.py:1097 -msgid "The extra mark has been deleted." -msgstr "Die zusätzliche Markierung wurde gelöscht." - -#: aleksis/apps/alsijil/views.py:1119 +#: aleksis/apps/alsijil/views.py:1072 msgid "The excuse type has been created." msgstr "Die Entschuldigungsart wurde erstellt." -#: aleksis/apps/alsijil/views.py:1131 +#: aleksis/apps/alsijil/views.py:1084 msgid "The excuse type has been saved." msgstr "Die Entschuldigunsart wurde gespeichert." -#: aleksis/apps/alsijil/views.py:1142 +#: aleksis/apps/alsijil/views.py:1095 msgid "The excuse type has been deleted." msgstr "Die Entschuldigungsart wurde gelöscht." -#: aleksis/apps/alsijil/views.py:1164 +#: aleksis/apps/alsijil/views.py:1117 msgid "The group role has been created." msgstr "Die Gruppenrolle wurde erstellt." -#: aleksis/apps/alsijil/views.py:1176 +#: aleksis/apps/alsijil/views.py:1129 msgid "The group role has been saved." msgstr "Die Gruppenrolle wurde gespeichert." -#: aleksis/apps/alsijil/views.py:1187 +#: aleksis/apps/alsijil/views.py:1140 msgid "The group role has been deleted." msgstr "Die Gruppenrolle wurde gelöscht." -#: aleksis/apps/alsijil/views.py:1221 aleksis/apps/alsijil/views.py:1253 +#: aleksis/apps/alsijil/views.py:1174 aleksis/apps/alsijil/views.py:1206 msgid "The group role has been assigned." msgstr "Die Gruppenrolle wurde zugewiesen." -#: aleksis/apps/alsijil/views.py:1272 +#: aleksis/apps/alsijil/views.py:1225 msgid "The group role assignment has been saved." msgstr "Die Gruppenrollenzuweisung wurde gespeichert." -#: aleksis/apps/alsijil/views.py:1293 +#: aleksis/apps/alsijil/views.py:1246 msgid "The group role assignment has been stopped." msgstr "Die Gruppenrollenzuweisung wurde beendet." -#: aleksis/apps/alsijil/views.py:1306 +#: aleksis/apps/alsijil/views.py:1259 msgid "The group role assignment has been deleted." msgstr "Die Gruppenrollenzuweisung wurde gelöscht." +#~ msgid "Create extra mark" +#~ msgstr "Zusätzliche Markierung erstellen" + +#~ msgid "Edit extra mark" +#~ msgstr "Zusätzliche Markierung bearbeiten" + +#~ msgid "The extra mark has been created." +#~ msgstr "Die zusätzliche Markierung wurde erstellt." + +#~ msgid "The extra mark has been saved." +#~ msgstr "Die zusätzliche Markierung wurde gespeichert." + +#~ msgid "The extra mark has been deleted." +#~ msgstr "Die zusätzliche Markierung wurde gelöscht." + #~ msgid "Current lesson" #~ msgstr "Aktuelle Unterrichtsstunde" diff --git a/aleksis/apps/alsijil/locale/fr/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/fr/LC_MESSAGES/django.po index 72c9ebda41b069fb1e4116b336be8aeff1427caa..abc04d591ed842977a0e4e5edee13b3fd2ac7862 100644 --- a/aleksis/apps/alsijil/locale/fr/LC_MESSAGES/django.po +++ b/aleksis/apps/alsijil/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-06-13 11:19+0200\n" +"POT-Creation-Date: 2024-07-14 16:32+0200\n" "PO-Revision-Date: 2021-06-16 11:59+0000\n" "Last-Translator: Jonathan Weth <teckids@jonathanweth.de>\n" "Language-Team: French <https://translate.edugit.org/projects/aleksis/aleksis-app-alsijil/fr/>\n" @@ -33,8 +33,8 @@ msgstr "Injustifié(e)" msgid "Mark as {excuse_type.name}" msgstr "" -#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:29 -#: aleksis/apps/alsijil/tables.py:53 aleksis/apps/alsijil/tables.py:78 +#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:33 +#: aleksis/apps/alsijil/tables.py:58 #: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:29 msgid "Delete" msgstr "" @@ -123,7 +123,7 @@ msgid "Before" msgstr "" #: aleksis/apps/alsijil/filters.py:14 aleksis/apps/alsijil/forms.py:371 -#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:116 +#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:96 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:126 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:223 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:189 @@ -168,20 +168,20 @@ msgid "You can't select a group and a teacher both." msgstr "" #: aleksis/apps/alsijil/forms.py:193 aleksis/apps/alsijil/forms.py:291 -#: aleksis/apps/alsijil/models.py:762 aleksis/apps/alsijil/models.py:819 +#: aleksis/apps/alsijil/models.py:763 aleksis/apps/alsijil/models.py:822 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:63 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:27 msgid "Person" msgstr "Personne" #: aleksis/apps/alsijil/forms.py:194 aleksis/apps/alsijil/forms.py:372 -#: aleksis/apps/alsijil/models.py:891 +#: aleksis/apps/alsijil/models.py:903 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:64 msgid "Start date" msgstr "Date de début" #: aleksis/apps/alsijil/forms.py:195 aleksis/apps/alsijil/forms.py:373 -#: aleksis/apps/alsijil/models.py:895 +#: aleksis/apps/alsijil/models.py:907 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:65 msgid "End date" msgstr "Date de fin" @@ -198,8 +198,8 @@ msgstr "De la période" msgid "End period" msgstr "De la période" -#: aleksis/apps/alsijil/forms.py:198 aleksis/apps/alsijil/tables.py:117 -#: aleksis/apps/alsijil/tables.py:138 +#: aleksis/apps/alsijil/forms.py:198 aleksis/apps/alsijil/tables.py:97 +#: aleksis/apps/alsijil/tables.py:118 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:50 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:392 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:28 @@ -208,7 +208,7 @@ msgstr "De la période" msgid "Absent" msgstr "Absent(e)" -#: aleksis/apps/alsijil/forms.py:199 aleksis/apps/alsijil/tables.py:146 +#: aleksis/apps/alsijil/forms.py:199 aleksis/apps/alsijil/tables.py:126 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:54 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:135 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:30 @@ -244,7 +244,7 @@ msgstr "" msgid "Has lesson documentation" msgstr "Documentation de cours" -#: aleksis/apps/alsijil/managers.py:91 aleksis/apps/alsijil/tables.py:130 +#: aleksis/apps/alsijil/managers.py:91 aleksis/apps/alsijil/tables.py:110 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:172 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:236 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:311 @@ -313,14 +313,14 @@ msgid "Short name" msgstr "Prénom" #: aleksis/apps/alsijil/models.py:64 aleksis/apps/alsijil/models.py:438 -#: aleksis/apps/alsijil/models.py:855 +#: aleksis/apps/alsijil/models.py:867 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:20 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:12 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:25 msgid "Name" msgstr "" -#: aleksis/apps/alsijil/models.py:68 aleksis/apps/alsijil/tables.py:41 +#: aleksis/apps/alsijil/models.py:68 aleksis/apps/alsijil/tables.py:21 msgid "Count as absent" msgstr "" @@ -342,9 +342,7 @@ msgid "Year" msgstr "" #: aleksis/apps/alsijil/models.py:265 aleksis/apps/alsijil/models.py:455 -#: aleksis/apps/alsijil/tables.py:120 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:8 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:9 +#: aleksis/apps/alsijil/tables.py:100 #: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:57 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:32 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:19 @@ -426,7 +424,7 @@ msgstr "" msgid "Course" msgstr "" -#: aleksis/apps/alsijil/models.py:486 aleksis/apps/alsijil/tables.py:111 +#: aleksis/apps/alsijil/models.py:486 aleksis/apps/alsijil/tables.py:91 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:127 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:253 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:331 @@ -449,8 +447,8 @@ msgstr "Groupe" msgid "Participation touched at" msgstr "" -#: aleksis/apps/alsijil/models.py:524 aleksis/apps/alsijil/models.py:772 -#: aleksis/apps/alsijil/models.py:826 +#: aleksis/apps/alsijil/models.py:524 aleksis/apps/alsijil/models.py:773 +#: aleksis/apps/alsijil/models.py:829 #, fuzzy #| msgid "Lesson documentation" msgid "Documentation" @@ -462,66 +460,80 @@ msgstr "Documentation de cours" msgid "Documentations" msgstr "Documentation de cours" -#: aleksis/apps/alsijil/models.py:765 +#: aleksis/apps/alsijil/models.py:766 #, fuzzy #| msgid "Group" msgid "Groups of Person" msgstr "Groupe" -#: aleksis/apps/alsijil/models.py:778 +#: aleksis/apps/alsijil/models.py:779 #, fuzzy #| msgid "Absences" msgid "Absence Reason" msgstr "Absences" -#: aleksis/apps/alsijil/models.py:790 +#: aleksis/apps/alsijil/models.py:791 #, fuzzy #| msgid "Absences" msgid "Base Absence" msgstr "Absences" -#: aleksis/apps/alsijil/models.py:802 aleksis/apps/alsijil/models.py:803 +#: aleksis/apps/alsijil/models.py:794 aleksis/apps/alsijil/tables.py:98 +#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:161 +#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:21 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:46 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:123 +#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323 +msgid "Tardiness" +msgstr "Retard" + +#: aleksis/apps/alsijil/models.py:805 aleksis/apps/alsijil/models.py:806 msgid "Participation Status" msgstr "" -#: aleksis/apps/alsijil/models.py:831 +#: aleksis/apps/alsijil/models.py:834 #, fuzzy #| msgid "Notes" msgid "Note" msgstr "Notes" -#: aleksis/apps/alsijil/models.py:833 +#: aleksis/apps/alsijil/models.py:836 msgid "Extra Mark" msgstr "" -#: aleksis/apps/alsijil/models.py:840 +#: aleksis/apps/alsijil/models.py:843 #, fuzzy #| msgid "Personal notes" msgid "Personal Note" msgstr "Notes personnelles" -#: aleksis/apps/alsijil/models.py:841 +#: aleksis/apps/alsijil/models.py:844 #, fuzzy #| msgid "Personal notes" msgid "Personal Notes" msgstr "Notes personnelles" -#: aleksis/apps/alsijil/models.py:856 +#: aleksis/apps/alsijil/models.py:855 +msgid "A person got assigned the same extra mark multiple times per documentation." +msgstr "" + +#: aleksis/apps/alsijil/models.py:868 msgid "Icon" msgstr "" -#: aleksis/apps/alsijil/models.py:857 +#: aleksis/apps/alsijil/models.py:869 msgid "Colour" msgstr "" -#: aleksis/apps/alsijil/models.py:863 aleksis/apps/alsijil/models.py:878 +#: aleksis/apps/alsijil/models.py:875 aleksis/apps/alsijil/models.py:890 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:62 #, fuzzy #| msgid "Group" msgid "Group role" msgstr "Groupe" -#: aleksis/apps/alsijil/models.py:864 +#: aleksis/apps/alsijil/models.py:876 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:90 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:8 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:9 @@ -530,19 +542,19 @@ msgstr "Groupe" msgid "Group roles" msgstr "Groupe" -#: aleksis/apps/alsijil/models.py:865 +#: aleksis/apps/alsijil/models.py:877 #, fuzzy #| msgid "Persons in group" msgid "Can assign group role" msgstr "Personnes en groupe" -#: aleksis/apps/alsijil/models.py:884 +#: aleksis/apps/alsijil/models.py:896 #, fuzzy #| msgid "Absences" msgid "Assigned person" msgstr "Absences" -#: aleksis/apps/alsijil/models.py:889 aleksis/apps/alsijil/tables.py:105 +#: aleksis/apps/alsijil/models.py:901 aleksis/apps/alsijil/tables.py:85 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:124 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:242 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:321 @@ -551,41 +563,41 @@ msgstr "Absences" msgid "Groups" msgstr "Groupe" -#: aleksis/apps/alsijil/models.py:896 +#: aleksis/apps/alsijil/models.py:908 msgid "Can be left empty if end date is not clear yet" msgstr "" -#: aleksis/apps/alsijil/models.py:911 +#: aleksis/apps/alsijil/models.py:923 msgid "Group role assignment" msgstr "" -#: aleksis/apps/alsijil/models.py:912 +#: aleksis/apps/alsijil/models.py:924 msgid "Group role assignments" msgstr "" -#: aleksis/apps/alsijil/models.py:919 +#: aleksis/apps/alsijil/models.py:931 #, fuzzy #| msgid "Personal overview" msgid "Can view lesson overview" msgstr "Vue d'ensemble personnelle" -#: aleksis/apps/alsijil/models.py:920 +#: aleksis/apps/alsijil/models.py:932 msgid "Can view week overview" msgstr "" -#: aleksis/apps/alsijil/models.py:921 +#: aleksis/apps/alsijil/models.py:933 #, fuzzy #| msgid "Class register" msgid "Can view full register" msgstr "Registre de la classe" -#: aleksis/apps/alsijil/models.py:922 +#: aleksis/apps/alsijil/models.py:934 #, fuzzy #| msgid "Register absence" msgid "Can register absence" msgstr "Registre de Absence" -#: aleksis/apps/alsijil/models.py:923 +#: aleksis/apps/alsijil/models.py:935 #, fuzzy #| msgid "List of all personal note filters" msgid "Can list all personal note filters" @@ -694,40 +706,29 @@ msgstr "" msgid "Set time range for which documentations may be edited" msgstr "" -#: aleksis/apps/alsijil/tables.py:23 aleksis/apps/alsijil/tables.py:47 -#: aleksis/apps/alsijil/tables.py:72 +#: aleksis/apps/alsijil/tables.py:27 aleksis/apps/alsijil/tables.py:52 #: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:13 msgid "Edit" msgstr "" -#: aleksis/apps/alsijil/tables.py:96 +#: aleksis/apps/alsijil/tables.py:76 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:348 msgid "Date" msgstr "Date" -#: aleksis/apps/alsijil/tables.py:99 +#: aleksis/apps/alsijil/tables.py:79 #: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:30 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:122 msgid "Period" msgstr "Période" -#: aleksis/apps/alsijil/tables.py:118 -#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:161 -#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:21 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:46 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:123 -#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323 -msgid "Tardiness" -msgstr "Retard" - -#: aleksis/apps/alsijil/tables.py:119 +#: aleksis/apps/alsijil/tables.py:99 #, fuzzy #| msgid "Excused" msgid "Excuse" msgstr "Excusé" -#: aleksis/apps/alsijil/tables.py:156 +#: aleksis/apps/alsijil/tables.py:136 #, fuzzy, python-brace-format #| msgid "Summed up tardiness" msgid "{value}' tardiness" @@ -1105,17 +1106,6 @@ msgid "" " " msgstr "" -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:6 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:7 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:14 -msgid "Create extra mark" -msgstr "" - -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:6 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:7 -msgid "Edit extra mark" -msgstr "" - #: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:9 #: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:16 #, python-format @@ -1650,126 +1640,120 @@ msgstr "Vue de semaine" msgid "Notes" msgstr "Notes" -#: aleksis/apps/alsijil/views.py:114 +#: aleksis/apps/alsijil/views.py:112 msgid "You either selected an invalid lesson or there is currently no lesson in progress." msgstr "" -#: aleksis/apps/alsijil/views.py:147 +#: aleksis/apps/alsijil/views.py:145 msgid "You are not allowed to create a lesson documentation for a lesson in the future." msgstr "" -#: aleksis/apps/alsijil/views.py:264 +#: aleksis/apps/alsijil/views.py:262 #, fuzzy #| msgid "Lesson documentation for calendar week" msgid "The lesson documentation has been saved." msgstr "Documentation de cours pour la semaine calendrier" -#: aleksis/apps/alsijil/views.py:298 +#: aleksis/apps/alsijil/views.py:296 msgid "The personal notes have been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:658 +#: aleksis/apps/alsijil/views.py:656 msgid "Generate full register printout for {}" msgstr "" -#: aleksis/apps/alsijil/views.py:659 +#: aleksis/apps/alsijil/views.py:657 msgid "Generate full register printout …" msgstr "" -#: aleksis/apps/alsijil/views.py:660 +#: aleksis/apps/alsijil/views.py:658 #, fuzzy #| msgid "Lesson documentation for calendar week" msgid "The printout has been generated successfully." msgstr "Documentation de cours pour la semaine calendrier" -#: aleksis/apps/alsijil/views.py:661 +#: aleksis/apps/alsijil/views.py:659 msgid "There was a problem while generating the printout." msgstr "" -#: aleksis/apps/alsijil/views.py:664 +#: aleksis/apps/alsijil/views.py:662 msgid "Download PDF" msgstr "" -#: aleksis/apps/alsijil/views.py:1030 +#: aleksis/apps/alsijil/views.py:1028 msgid "The absence has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1051 +#: aleksis/apps/alsijil/views.py:1049 #, fuzzy #| msgid "Lesson documentation for calendar week" msgid "The personal note has been deleted." msgstr "Documentation de cours pour la semaine calendrier" -#: aleksis/apps/alsijil/views.py:1074 -#, fuzzy -#| msgid "Lesson documentation for calendar week" -msgid "The extra mark has been created." -msgstr "Documentation de cours pour la semaine calendrier" - -#: aleksis/apps/alsijil/views.py:1086 -#, fuzzy -#| msgid "Lesson documentation for calendar week" -msgid "The extra mark has been saved." -msgstr "Documentation de cours pour la semaine calendrier" - -#: aleksis/apps/alsijil/views.py:1097 -msgid "The extra mark has been deleted." -msgstr "" - -#: aleksis/apps/alsijil/views.py:1119 +#: aleksis/apps/alsijil/views.py:1072 msgid "The excuse type has been created." msgstr "" -#: aleksis/apps/alsijil/views.py:1131 +#: aleksis/apps/alsijil/views.py:1084 msgid "The excuse type has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1142 +#: aleksis/apps/alsijil/views.py:1095 msgid "The excuse type has been deleted." msgstr "" -#: aleksis/apps/alsijil/views.py:1164 +#: aleksis/apps/alsijil/views.py:1117 #, fuzzy #| msgid "Lesson documentation for calendar week" msgid "The group role has been created." msgstr "Documentation de cours pour la semaine calendrier" -#: aleksis/apps/alsijil/views.py:1176 +#: aleksis/apps/alsijil/views.py:1129 #, fuzzy #| msgid "Lesson documentation for calendar week" msgid "The group role has been saved." msgstr "Documentation de cours pour la semaine calendrier" -#: aleksis/apps/alsijil/views.py:1187 +#: aleksis/apps/alsijil/views.py:1140 #, fuzzy #| msgid "Lesson documentation for calendar week" msgid "The group role has been deleted." msgstr "Documentation de cours pour la semaine calendrier" -#: aleksis/apps/alsijil/views.py:1221 aleksis/apps/alsijil/views.py:1253 +#: aleksis/apps/alsijil/views.py:1174 aleksis/apps/alsijil/views.py:1206 #, fuzzy #| msgid "Lesson documentation for calendar week" msgid "The group role has been assigned." msgstr "Documentation de cours pour la semaine calendrier" -#: aleksis/apps/alsijil/views.py:1272 +#: aleksis/apps/alsijil/views.py:1225 #, fuzzy #| msgid "Lesson documentation for calendar week" msgid "The group role assignment has been saved." msgstr "Documentation de cours pour la semaine calendrier" -#: aleksis/apps/alsijil/views.py:1293 +#: aleksis/apps/alsijil/views.py:1246 #, fuzzy #| msgid "Lesson documentation for calendar week" msgid "The group role assignment has been stopped." msgstr "Documentation de cours pour la semaine calendrier" -#: aleksis/apps/alsijil/views.py:1306 +#: aleksis/apps/alsijil/views.py:1259 #, fuzzy #| msgid "Lesson documentation for calendar week" msgid "The group role assignment has been deleted." msgstr "Documentation de cours pour la semaine calendrier" +#, fuzzy +#~| msgid "Lesson documentation for calendar week" +#~ msgid "The extra mark has been created." +#~ msgstr "Documentation de cours pour la semaine calendrier" + +#, fuzzy +#~| msgid "Lesson documentation for calendar week" +#~ msgid "The extra mark has been saved." +#~ msgstr "Documentation de cours pour la semaine calendrier" + #~ msgid "Current lesson" #~ msgstr "Lecon actuelle" diff --git a/aleksis/apps/alsijil/locale/la/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/la/LC_MESSAGES/django.po index 474943af086754291a287070770f0e915f2f5c6b..7955aa4f442ce564909b05efe9e5317ea3081721 100644 --- a/aleksis/apps/alsijil/locale/la/LC_MESSAGES/django.po +++ b/aleksis/apps/alsijil/locale/la/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-06-13 11:19+0200\n" +"POT-Creation-Date: 2024-07-14 16:32+0200\n" "PO-Revision-Date: 2020-07-26 14:08+0000\n" "Last-Translator: Julian <leuckerj@gmail.com>\n" "Language-Team: Latin <https://translate.edugit.org/projects/aleksis/aleksis-app-alsijil/la/>\n" @@ -31,8 +31,8 @@ msgstr "" msgid "Mark as {excuse_type.name}" msgstr "" -#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:29 -#: aleksis/apps/alsijil/tables.py:53 aleksis/apps/alsijil/tables.py:78 +#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:33 +#: aleksis/apps/alsijil/tables.py:58 #: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:29 msgid "Delete" msgstr "" @@ -111,7 +111,7 @@ msgid "Before" msgstr "" #: aleksis/apps/alsijil/filters.py:14 aleksis/apps/alsijil/forms.py:371 -#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:116 +#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:96 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:126 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:223 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:189 @@ -152,20 +152,20 @@ msgid "You can't select a group and a teacher both." msgstr "" #: aleksis/apps/alsijil/forms.py:193 aleksis/apps/alsijil/forms.py:291 -#: aleksis/apps/alsijil/models.py:762 aleksis/apps/alsijil/models.py:819 +#: aleksis/apps/alsijil/models.py:763 aleksis/apps/alsijil/models.py:822 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:63 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:27 msgid "Person" msgstr "Persona" #: aleksis/apps/alsijil/forms.py:194 aleksis/apps/alsijil/forms.py:372 -#: aleksis/apps/alsijil/models.py:891 +#: aleksis/apps/alsijil/models.py:903 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:64 msgid "Start date" msgstr "" #: aleksis/apps/alsijil/forms.py:195 aleksis/apps/alsijil/forms.py:373 -#: aleksis/apps/alsijil/models.py:895 +#: aleksis/apps/alsijil/models.py:907 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:65 msgid "End date" msgstr "" @@ -178,8 +178,8 @@ msgstr "" msgid "End period" msgstr "" -#: aleksis/apps/alsijil/forms.py:198 aleksis/apps/alsijil/tables.py:117 -#: aleksis/apps/alsijil/tables.py:138 +#: aleksis/apps/alsijil/forms.py:198 aleksis/apps/alsijil/tables.py:97 +#: aleksis/apps/alsijil/tables.py:118 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:50 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:392 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:28 @@ -188,7 +188,7 @@ msgstr "" msgid "Absent" msgstr "" -#: aleksis/apps/alsijil/forms.py:199 aleksis/apps/alsijil/tables.py:146 +#: aleksis/apps/alsijil/forms.py:199 aleksis/apps/alsijil/tables.py:126 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:54 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:135 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:30 @@ -220,7 +220,7 @@ msgstr "" msgid "Has lesson documentation" msgstr "" -#: aleksis/apps/alsijil/managers.py:91 aleksis/apps/alsijil/tables.py:130 +#: aleksis/apps/alsijil/managers.py:91 aleksis/apps/alsijil/tables.py:110 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:172 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:236 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:311 @@ -279,14 +279,14 @@ msgid "Short name" msgstr "Primus nomen" #: aleksis/apps/alsijil/models.py:64 aleksis/apps/alsijil/models.py:438 -#: aleksis/apps/alsijil/models.py:855 +#: aleksis/apps/alsijil/models.py:867 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:20 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:12 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:25 msgid "Name" msgstr "" -#: aleksis/apps/alsijil/models.py:68 aleksis/apps/alsijil/tables.py:41 +#: aleksis/apps/alsijil/models.py:68 aleksis/apps/alsijil/tables.py:21 msgid "Count as absent" msgstr "" @@ -306,9 +306,7 @@ msgid "Year" msgstr "" #: aleksis/apps/alsijil/models.py:265 aleksis/apps/alsijil/models.py:455 -#: aleksis/apps/alsijil/tables.py:120 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:8 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:9 +#: aleksis/apps/alsijil/tables.py:100 #: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:57 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:32 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:19 @@ -388,7 +386,7 @@ msgstr "" msgid "Course" msgstr "" -#: aleksis/apps/alsijil/models.py:486 aleksis/apps/alsijil/tables.py:111 +#: aleksis/apps/alsijil/models.py:486 aleksis/apps/alsijil/tables.py:91 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:127 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:253 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:331 @@ -409,8 +407,8 @@ msgstr "Grex" msgid "Participation touched at" msgstr "" -#: aleksis/apps/alsijil/models.py:524 aleksis/apps/alsijil/models.py:772 -#: aleksis/apps/alsijil/models.py:826 +#: aleksis/apps/alsijil/models.py:524 aleksis/apps/alsijil/models.py:773 +#: aleksis/apps/alsijil/models.py:829 msgid "Documentation" msgstr "" @@ -418,60 +416,74 @@ msgstr "" msgid "Documentations" msgstr "" -#: aleksis/apps/alsijil/models.py:765 +#: aleksis/apps/alsijil/models.py:766 #, fuzzy #| msgid "Group" msgid "Groups of Person" msgstr "Grex" -#: aleksis/apps/alsijil/models.py:778 +#: aleksis/apps/alsijil/models.py:779 msgid "Absence Reason" msgstr "" -#: aleksis/apps/alsijil/models.py:790 +#: aleksis/apps/alsijil/models.py:791 msgid "Base Absence" msgstr "" -#: aleksis/apps/alsijil/models.py:802 aleksis/apps/alsijil/models.py:803 +#: aleksis/apps/alsijil/models.py:794 aleksis/apps/alsijil/tables.py:98 +#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:161 +#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:21 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:46 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:123 +#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323 +msgid "Tardiness" +msgstr "" + +#: aleksis/apps/alsijil/models.py:805 aleksis/apps/alsijil/models.py:806 msgid "Participation Status" msgstr "" -#: aleksis/apps/alsijil/models.py:831 +#: aleksis/apps/alsijil/models.py:834 msgid "Note" msgstr "" -#: aleksis/apps/alsijil/models.py:833 +#: aleksis/apps/alsijil/models.py:836 msgid "Extra Mark" msgstr "" -#: aleksis/apps/alsijil/models.py:840 +#: aleksis/apps/alsijil/models.py:843 #, fuzzy #| msgid "Person" msgid "Personal Note" msgstr "Persona" -#: aleksis/apps/alsijil/models.py:841 +#: aleksis/apps/alsijil/models.py:844 #, fuzzy #| msgid "Person" msgid "Personal Notes" msgstr "Persona" -#: aleksis/apps/alsijil/models.py:856 +#: aleksis/apps/alsijil/models.py:855 +msgid "A person got assigned the same extra mark multiple times per documentation." +msgstr "" + +#: aleksis/apps/alsijil/models.py:868 msgid "Icon" msgstr "" -#: aleksis/apps/alsijil/models.py:857 +#: aleksis/apps/alsijil/models.py:869 msgid "Colour" msgstr "" -#: aleksis/apps/alsijil/models.py:863 aleksis/apps/alsijil/models.py:878 +#: aleksis/apps/alsijil/models.py:875 aleksis/apps/alsijil/models.py:890 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:62 #, fuzzy #| msgid "Group" msgid "Group role" msgstr "Grex" -#: aleksis/apps/alsijil/models.py:864 +#: aleksis/apps/alsijil/models.py:876 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:90 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:8 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:9 @@ -480,15 +492,15 @@ msgstr "Grex" msgid "Group roles" msgstr "Grex" -#: aleksis/apps/alsijil/models.py:865 +#: aleksis/apps/alsijil/models.py:877 msgid "Can assign group role" msgstr "" -#: aleksis/apps/alsijil/models.py:884 +#: aleksis/apps/alsijil/models.py:896 msgid "Assigned person" msgstr "" -#: aleksis/apps/alsijil/models.py:889 aleksis/apps/alsijil/tables.py:105 +#: aleksis/apps/alsijil/models.py:901 aleksis/apps/alsijil/tables.py:85 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:124 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:242 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:321 @@ -497,35 +509,35 @@ msgstr "" msgid "Groups" msgstr "Grex" -#: aleksis/apps/alsijil/models.py:896 +#: aleksis/apps/alsijil/models.py:908 msgid "Can be left empty if end date is not clear yet" msgstr "" -#: aleksis/apps/alsijil/models.py:911 +#: aleksis/apps/alsijil/models.py:923 msgid "Group role assignment" msgstr "" -#: aleksis/apps/alsijil/models.py:912 +#: aleksis/apps/alsijil/models.py:924 msgid "Group role assignments" msgstr "" -#: aleksis/apps/alsijil/models.py:919 +#: aleksis/apps/alsijil/models.py:931 msgid "Can view lesson overview" msgstr "" -#: aleksis/apps/alsijil/models.py:920 +#: aleksis/apps/alsijil/models.py:932 msgid "Can view week overview" msgstr "" -#: aleksis/apps/alsijil/models.py:921 +#: aleksis/apps/alsijil/models.py:933 msgid "Can view full register" msgstr "" -#: aleksis/apps/alsijil/models.py:922 +#: aleksis/apps/alsijil/models.py:934 msgid "Can register absence" msgstr "" -#: aleksis/apps/alsijil/models.py:923 +#: aleksis/apps/alsijil/models.py:935 msgid "Can list all personal note filters" msgstr "" @@ -630,38 +642,27 @@ msgstr "" msgid "Set time range for which documentations may be edited" msgstr "" -#: aleksis/apps/alsijil/tables.py:23 aleksis/apps/alsijil/tables.py:47 -#: aleksis/apps/alsijil/tables.py:72 +#: aleksis/apps/alsijil/tables.py:27 aleksis/apps/alsijil/tables.py:52 #: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:13 msgid "Edit" msgstr "" -#: aleksis/apps/alsijil/tables.py:96 +#: aleksis/apps/alsijil/tables.py:76 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:348 msgid "Date" msgstr "dies" -#: aleksis/apps/alsijil/tables.py:99 +#: aleksis/apps/alsijil/tables.py:79 #: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:30 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:122 msgid "Period" msgstr "" -#: aleksis/apps/alsijil/tables.py:118 -#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:161 -#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:21 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:46 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:123 -#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323 -msgid "Tardiness" -msgstr "" - -#: aleksis/apps/alsijil/tables.py:119 +#: aleksis/apps/alsijil/tables.py:99 msgid "Excuse" msgstr "" -#: aleksis/apps/alsijil/tables.py:156 +#: aleksis/apps/alsijil/tables.py:136 #, python-brace-format msgid "{value}' tardiness" msgstr "" @@ -996,17 +997,6 @@ msgid "" " " msgstr "" -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:6 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:7 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:14 -msgid "Create extra mark" -msgstr "" - -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:6 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:7 -msgid "Edit extra mark" -msgstr "" - #: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:9 #: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:16 #, python-format @@ -1504,99 +1494,87 @@ msgstr "" msgid "Notes" msgstr "" -#: aleksis/apps/alsijil/views.py:114 +#: aleksis/apps/alsijil/views.py:112 msgid "You either selected an invalid lesson or there is currently no lesson in progress." msgstr "" -#: aleksis/apps/alsijil/views.py:147 +#: aleksis/apps/alsijil/views.py:145 msgid "You are not allowed to create a lesson documentation for a lesson in the future." msgstr "" -#: aleksis/apps/alsijil/views.py:264 +#: aleksis/apps/alsijil/views.py:262 msgid "The lesson documentation has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:298 +#: aleksis/apps/alsijil/views.py:296 msgid "The personal notes have been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:658 +#: aleksis/apps/alsijil/views.py:656 msgid "Generate full register printout for {}" msgstr "" -#: aleksis/apps/alsijil/views.py:659 +#: aleksis/apps/alsijil/views.py:657 msgid "Generate full register printout …" msgstr "" -#: aleksis/apps/alsijil/views.py:660 +#: aleksis/apps/alsijil/views.py:658 msgid "The printout has been generated successfully." msgstr "" -#: aleksis/apps/alsijil/views.py:661 +#: aleksis/apps/alsijil/views.py:659 msgid "There was a problem while generating the printout." msgstr "" -#: aleksis/apps/alsijil/views.py:664 +#: aleksis/apps/alsijil/views.py:662 msgid "Download PDF" msgstr "" -#: aleksis/apps/alsijil/views.py:1030 +#: aleksis/apps/alsijil/views.py:1028 msgid "The absence has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1051 +#: aleksis/apps/alsijil/views.py:1049 msgid "The personal note has been deleted." msgstr "" -#: aleksis/apps/alsijil/views.py:1074 -msgid "The extra mark has been created." -msgstr "" - -#: aleksis/apps/alsijil/views.py:1086 -msgid "The extra mark has been saved." -msgstr "" - -#: aleksis/apps/alsijil/views.py:1097 -msgid "The extra mark has been deleted." -msgstr "" - -#: aleksis/apps/alsijil/views.py:1119 +#: aleksis/apps/alsijil/views.py:1072 msgid "The excuse type has been created." msgstr "" -#: aleksis/apps/alsijil/views.py:1131 +#: aleksis/apps/alsijil/views.py:1084 msgid "The excuse type has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1142 +#: aleksis/apps/alsijil/views.py:1095 msgid "The excuse type has been deleted." msgstr "" -#: aleksis/apps/alsijil/views.py:1164 +#: aleksis/apps/alsijil/views.py:1117 msgid "The group role has been created." msgstr "" -#: aleksis/apps/alsijil/views.py:1176 +#: aleksis/apps/alsijil/views.py:1129 msgid "The group role has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1187 +#: aleksis/apps/alsijil/views.py:1140 msgid "The group role has been deleted." msgstr "" -#: aleksis/apps/alsijil/views.py:1221 aleksis/apps/alsijil/views.py:1253 +#: aleksis/apps/alsijil/views.py:1174 aleksis/apps/alsijil/views.py:1206 msgid "The group role has been assigned." msgstr "" -#: aleksis/apps/alsijil/views.py:1272 +#: aleksis/apps/alsijil/views.py:1225 msgid "The group role assignment has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1293 +#: aleksis/apps/alsijil/views.py:1246 msgid "The group role assignment has been stopped." msgstr "" -#: aleksis/apps/alsijil/views.py:1306 +#: aleksis/apps/alsijil/views.py:1259 msgid "The group role assignment has been deleted." msgstr "" diff --git a/aleksis/apps/alsijil/locale/nb_NO/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/nb_NO/LC_MESSAGES/django.po index 7e8285208907941025f0a6da310079f0e35e214e..ac6d9f2c9e90f79abbff6fad12355fb5219b3af5 100644 --- a/aleksis/apps/alsijil/locale/nb_NO/LC_MESSAGES/django.po +++ b/aleksis/apps/alsijil/locale/nb_NO/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-06-13 11:19+0200\n" +"POT-Creation-Date: 2024-07-14 16:32+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -30,8 +30,8 @@ msgstr "" msgid "Mark as {excuse_type.name}" msgstr "" -#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:29 -#: aleksis/apps/alsijil/tables.py:53 aleksis/apps/alsijil/tables.py:78 +#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:33 +#: aleksis/apps/alsijil/tables.py:58 #: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:29 msgid "Delete" msgstr "" @@ -110,7 +110,7 @@ msgid "Before" msgstr "" #: aleksis/apps/alsijil/filters.py:14 aleksis/apps/alsijil/forms.py:371 -#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:116 +#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:96 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:126 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:223 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:189 @@ -151,20 +151,20 @@ msgid "You can't select a group and a teacher both." msgstr "" #: aleksis/apps/alsijil/forms.py:193 aleksis/apps/alsijil/forms.py:291 -#: aleksis/apps/alsijil/models.py:762 aleksis/apps/alsijil/models.py:819 +#: aleksis/apps/alsijil/models.py:763 aleksis/apps/alsijil/models.py:822 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:63 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:27 msgid "Person" msgstr "" #: aleksis/apps/alsijil/forms.py:194 aleksis/apps/alsijil/forms.py:372 -#: aleksis/apps/alsijil/models.py:891 +#: aleksis/apps/alsijil/models.py:903 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:64 msgid "Start date" msgstr "" #: aleksis/apps/alsijil/forms.py:195 aleksis/apps/alsijil/forms.py:373 -#: aleksis/apps/alsijil/models.py:895 +#: aleksis/apps/alsijil/models.py:907 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:65 msgid "End date" msgstr "" @@ -177,8 +177,8 @@ msgstr "" msgid "End period" msgstr "" -#: aleksis/apps/alsijil/forms.py:198 aleksis/apps/alsijil/tables.py:117 -#: aleksis/apps/alsijil/tables.py:138 +#: aleksis/apps/alsijil/forms.py:198 aleksis/apps/alsijil/tables.py:97 +#: aleksis/apps/alsijil/tables.py:118 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:50 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:392 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:28 @@ -187,7 +187,7 @@ msgstr "" msgid "Absent" msgstr "" -#: aleksis/apps/alsijil/forms.py:199 aleksis/apps/alsijil/tables.py:146 +#: aleksis/apps/alsijil/forms.py:199 aleksis/apps/alsijil/tables.py:126 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:54 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:135 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:30 @@ -219,7 +219,7 @@ msgstr "" msgid "Has lesson documentation" msgstr "" -#: aleksis/apps/alsijil/managers.py:91 aleksis/apps/alsijil/tables.py:130 +#: aleksis/apps/alsijil/managers.py:91 aleksis/apps/alsijil/tables.py:110 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:172 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:236 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:311 @@ -276,14 +276,14 @@ msgid "Short name" msgstr "" #: aleksis/apps/alsijil/models.py:64 aleksis/apps/alsijil/models.py:438 -#: aleksis/apps/alsijil/models.py:855 +#: aleksis/apps/alsijil/models.py:867 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:20 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:12 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:25 msgid "Name" msgstr "" -#: aleksis/apps/alsijil/models.py:68 aleksis/apps/alsijil/tables.py:41 +#: aleksis/apps/alsijil/models.py:68 aleksis/apps/alsijil/tables.py:21 msgid "Count as absent" msgstr "" @@ -303,9 +303,7 @@ msgid "Year" msgstr "" #: aleksis/apps/alsijil/models.py:265 aleksis/apps/alsijil/models.py:455 -#: aleksis/apps/alsijil/tables.py:120 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:8 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:9 +#: aleksis/apps/alsijil/tables.py:100 #: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:57 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:32 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:19 @@ -381,7 +379,7 @@ msgstr "" msgid "Course" msgstr "" -#: aleksis/apps/alsijil/models.py:486 aleksis/apps/alsijil/tables.py:111 +#: aleksis/apps/alsijil/models.py:486 aleksis/apps/alsijil/tables.py:91 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:127 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:253 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:331 @@ -400,8 +398,8 @@ msgstr "" msgid "Participation touched at" msgstr "" -#: aleksis/apps/alsijil/models.py:524 aleksis/apps/alsijil/models.py:772 -#: aleksis/apps/alsijil/models.py:826 +#: aleksis/apps/alsijil/models.py:524 aleksis/apps/alsijil/models.py:773 +#: aleksis/apps/alsijil/models.py:829 msgid "Documentation" msgstr "" @@ -409,102 +407,116 @@ msgstr "" msgid "Documentations" msgstr "" -#: aleksis/apps/alsijil/models.py:765 +#: aleksis/apps/alsijil/models.py:766 msgid "Groups of Person" msgstr "" -#: aleksis/apps/alsijil/models.py:778 +#: aleksis/apps/alsijil/models.py:779 msgid "Absence Reason" msgstr "" -#: aleksis/apps/alsijil/models.py:790 +#: aleksis/apps/alsijil/models.py:791 msgid "Base Absence" msgstr "" -#: aleksis/apps/alsijil/models.py:802 aleksis/apps/alsijil/models.py:803 +#: aleksis/apps/alsijil/models.py:794 aleksis/apps/alsijil/tables.py:98 +#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:161 +#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:21 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:46 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:123 +#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323 +msgid "Tardiness" +msgstr "" + +#: aleksis/apps/alsijil/models.py:805 aleksis/apps/alsijil/models.py:806 msgid "Participation Status" msgstr "" -#: aleksis/apps/alsijil/models.py:831 +#: aleksis/apps/alsijil/models.py:834 msgid "Note" msgstr "" -#: aleksis/apps/alsijil/models.py:833 +#: aleksis/apps/alsijil/models.py:836 msgid "Extra Mark" msgstr "" -#: aleksis/apps/alsijil/models.py:840 +#: aleksis/apps/alsijil/models.py:843 msgid "Personal Note" msgstr "" -#: aleksis/apps/alsijil/models.py:841 +#: aleksis/apps/alsijil/models.py:844 msgid "Personal Notes" msgstr "" -#: aleksis/apps/alsijil/models.py:856 +#: aleksis/apps/alsijil/models.py:855 +msgid "A person got assigned the same extra mark multiple times per documentation." +msgstr "" + +#: aleksis/apps/alsijil/models.py:868 msgid "Icon" msgstr "" -#: aleksis/apps/alsijil/models.py:857 +#: aleksis/apps/alsijil/models.py:869 msgid "Colour" msgstr "" -#: aleksis/apps/alsijil/models.py:863 aleksis/apps/alsijil/models.py:878 +#: aleksis/apps/alsijil/models.py:875 aleksis/apps/alsijil/models.py:890 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:62 msgid "Group role" msgstr "" -#: aleksis/apps/alsijil/models.py:864 +#: aleksis/apps/alsijil/models.py:876 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:90 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:8 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:9 msgid "Group roles" msgstr "" -#: aleksis/apps/alsijil/models.py:865 +#: aleksis/apps/alsijil/models.py:877 msgid "Can assign group role" msgstr "" -#: aleksis/apps/alsijil/models.py:884 +#: aleksis/apps/alsijil/models.py:896 msgid "Assigned person" msgstr "" -#: aleksis/apps/alsijil/models.py:889 aleksis/apps/alsijil/tables.py:105 +#: aleksis/apps/alsijil/models.py:901 aleksis/apps/alsijil/tables.py:85 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:124 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:242 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:321 msgid "Groups" msgstr "" -#: aleksis/apps/alsijil/models.py:896 +#: aleksis/apps/alsijil/models.py:908 msgid "Can be left empty if end date is not clear yet" msgstr "" -#: aleksis/apps/alsijil/models.py:911 +#: aleksis/apps/alsijil/models.py:923 msgid "Group role assignment" msgstr "" -#: aleksis/apps/alsijil/models.py:912 +#: aleksis/apps/alsijil/models.py:924 msgid "Group role assignments" msgstr "" -#: aleksis/apps/alsijil/models.py:919 +#: aleksis/apps/alsijil/models.py:931 msgid "Can view lesson overview" msgstr "" -#: aleksis/apps/alsijil/models.py:920 +#: aleksis/apps/alsijil/models.py:932 msgid "Can view week overview" msgstr "" -#: aleksis/apps/alsijil/models.py:921 +#: aleksis/apps/alsijil/models.py:933 msgid "Can view full register" msgstr "" -#: aleksis/apps/alsijil/models.py:922 +#: aleksis/apps/alsijil/models.py:934 msgid "Can register absence" msgstr "" -#: aleksis/apps/alsijil/models.py:923 +#: aleksis/apps/alsijil/models.py:935 msgid "Can list all personal note filters" msgstr "" @@ -609,38 +621,27 @@ msgstr "" msgid "Set time range for which documentations may be edited" msgstr "" -#: aleksis/apps/alsijil/tables.py:23 aleksis/apps/alsijil/tables.py:47 -#: aleksis/apps/alsijil/tables.py:72 +#: aleksis/apps/alsijil/tables.py:27 aleksis/apps/alsijil/tables.py:52 #: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:13 msgid "Edit" msgstr "" -#: aleksis/apps/alsijil/tables.py:96 +#: aleksis/apps/alsijil/tables.py:76 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:348 msgid "Date" msgstr "" -#: aleksis/apps/alsijil/tables.py:99 +#: aleksis/apps/alsijil/tables.py:79 #: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:30 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:122 msgid "Period" msgstr "" -#: aleksis/apps/alsijil/tables.py:118 -#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:161 -#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:21 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:46 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:123 -#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323 -msgid "Tardiness" -msgstr "" - -#: aleksis/apps/alsijil/tables.py:119 +#: aleksis/apps/alsijil/tables.py:99 msgid "Excuse" msgstr "" -#: aleksis/apps/alsijil/tables.py:156 +#: aleksis/apps/alsijil/tables.py:136 #, python-brace-format msgid "{value}' tardiness" msgstr "" @@ -967,17 +968,6 @@ msgid "" " " msgstr "" -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:6 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:7 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:14 -msgid "Create extra mark" -msgstr "" - -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:6 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:7 -msgid "Edit extra mark" -msgstr "" - #: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:9 #: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:16 #, python-format @@ -1471,98 +1461,86 @@ msgstr "" msgid "Notes" msgstr "" -#: aleksis/apps/alsijil/views.py:114 +#: aleksis/apps/alsijil/views.py:112 msgid "You either selected an invalid lesson or there is currently no lesson in progress." msgstr "" -#: aleksis/apps/alsijil/views.py:147 +#: aleksis/apps/alsijil/views.py:145 msgid "You are not allowed to create a lesson documentation for a lesson in the future." msgstr "" -#: aleksis/apps/alsijil/views.py:264 +#: aleksis/apps/alsijil/views.py:262 msgid "The lesson documentation has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:298 +#: aleksis/apps/alsijil/views.py:296 msgid "The personal notes have been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:658 +#: aleksis/apps/alsijil/views.py:656 msgid "Generate full register printout for {}" msgstr "" -#: aleksis/apps/alsijil/views.py:659 +#: aleksis/apps/alsijil/views.py:657 msgid "Generate full register printout …" msgstr "" -#: aleksis/apps/alsijil/views.py:660 +#: aleksis/apps/alsijil/views.py:658 msgid "The printout has been generated successfully." msgstr "" -#: aleksis/apps/alsijil/views.py:661 +#: aleksis/apps/alsijil/views.py:659 msgid "There was a problem while generating the printout." msgstr "" -#: aleksis/apps/alsijil/views.py:664 +#: aleksis/apps/alsijil/views.py:662 msgid "Download PDF" msgstr "" -#: aleksis/apps/alsijil/views.py:1030 +#: aleksis/apps/alsijil/views.py:1028 msgid "The absence has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1051 +#: aleksis/apps/alsijil/views.py:1049 msgid "The personal note has been deleted." msgstr "" -#: aleksis/apps/alsijil/views.py:1074 -msgid "The extra mark has been created." -msgstr "" - -#: aleksis/apps/alsijil/views.py:1086 -msgid "The extra mark has been saved." -msgstr "" - -#: aleksis/apps/alsijil/views.py:1097 -msgid "The extra mark has been deleted." -msgstr "" - -#: aleksis/apps/alsijil/views.py:1119 +#: aleksis/apps/alsijil/views.py:1072 msgid "The excuse type has been created." msgstr "" -#: aleksis/apps/alsijil/views.py:1131 +#: aleksis/apps/alsijil/views.py:1084 msgid "The excuse type has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1142 +#: aleksis/apps/alsijil/views.py:1095 msgid "The excuse type has been deleted." msgstr "" -#: aleksis/apps/alsijil/views.py:1164 +#: aleksis/apps/alsijil/views.py:1117 msgid "The group role has been created." msgstr "" -#: aleksis/apps/alsijil/views.py:1176 +#: aleksis/apps/alsijil/views.py:1129 msgid "The group role has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1187 +#: aleksis/apps/alsijil/views.py:1140 msgid "The group role has been deleted." msgstr "" -#: aleksis/apps/alsijil/views.py:1221 aleksis/apps/alsijil/views.py:1253 +#: aleksis/apps/alsijil/views.py:1174 aleksis/apps/alsijil/views.py:1206 msgid "The group role has been assigned." msgstr "" -#: aleksis/apps/alsijil/views.py:1272 +#: aleksis/apps/alsijil/views.py:1225 msgid "The group role assignment has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1293 +#: aleksis/apps/alsijil/views.py:1246 msgid "The group role assignment has been stopped." msgstr "" -#: aleksis/apps/alsijil/views.py:1306 +#: aleksis/apps/alsijil/views.py:1259 msgid "The group role assignment has been deleted." msgstr "" diff --git a/aleksis/apps/alsijil/locale/ru/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/ru/LC_MESSAGES/django.po index aff00561b86b01e0dfb0862151a83a96fc6741cf..7133ed13476ff5368e850561f793109cfad418f3 100644 --- a/aleksis/apps/alsijil/locale/ru/LC_MESSAGES/django.po +++ b/aleksis/apps/alsijil/locale/ru/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-06-13 11:19+0200\n" +"POT-Creation-Date: 2024-07-14 16:32+0200\n" "PO-Revision-Date: 2023-05-26 04:38+0000\n" "Last-Translator: Serhii Horichenko <m@sgg.im>\n" "Language-Team: Russian <https://translate.edugit.org/projects/aleksis/aleksis-app-alsijil/ru/>\n" @@ -31,8 +31,8 @@ msgstr "Отметить без уважительной причины" msgid "Mark as {excuse_type.name}" msgstr "Отметить как {excuse_type.name}" -#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:29 -#: aleksis/apps/alsijil/tables.py:53 aleksis/apps/alsijil/tables.py:78 +#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:33 +#: aleksis/apps/alsijil/tables.py:58 #: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:29 msgid "Delete" msgstr "Удалить" @@ -111,7 +111,7 @@ msgid "Before" msgstr "До" #: aleksis/apps/alsijil/filters.py:14 aleksis/apps/alsijil/forms.py:371 -#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:116 +#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:96 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:126 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:223 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:189 @@ -152,20 +152,20 @@ msgid "You can't select a group and a teacher both." msgstr "Ð’Ñ‹ не можете одновременно выбрать группу и преподавателÑ." #: aleksis/apps/alsijil/forms.py:193 aleksis/apps/alsijil/forms.py:291 -#: aleksis/apps/alsijil/models.py:762 aleksis/apps/alsijil/models.py:819 +#: aleksis/apps/alsijil/models.py:763 aleksis/apps/alsijil/models.py:822 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:63 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:27 msgid "Person" msgstr "Физлицо" #: aleksis/apps/alsijil/forms.py:194 aleksis/apps/alsijil/forms.py:372 -#: aleksis/apps/alsijil/models.py:891 +#: aleksis/apps/alsijil/models.py:903 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:64 msgid "Start date" msgstr "Дата начала" #: aleksis/apps/alsijil/forms.py:195 aleksis/apps/alsijil/forms.py:373 -#: aleksis/apps/alsijil/models.py:895 +#: aleksis/apps/alsijil/models.py:907 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:65 msgid "End date" msgstr "Дата окончаниÑ" @@ -178,8 +178,8 @@ msgstr "Ðачало уроков" msgid "End period" msgstr "Окончание уроков" -#: aleksis/apps/alsijil/forms.py:198 aleksis/apps/alsijil/tables.py:117 -#: aleksis/apps/alsijil/tables.py:138 +#: aleksis/apps/alsijil/forms.py:198 aleksis/apps/alsijil/tables.py:97 +#: aleksis/apps/alsijil/tables.py:118 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:50 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:392 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:28 @@ -188,7 +188,7 @@ msgstr "Окончание уроков" msgid "Absent" msgstr "ОтÑутÑтвует" -#: aleksis/apps/alsijil/forms.py:199 aleksis/apps/alsijil/tables.py:146 +#: aleksis/apps/alsijil/forms.py:199 aleksis/apps/alsijil/tables.py:126 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:54 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:135 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:30 @@ -220,7 +220,7 @@ msgstr "Учебный год" msgid "Has lesson documentation" msgstr "Имеет в наличии учебный материал" -#: aleksis/apps/alsijil/managers.py:91 aleksis/apps/alsijil/tables.py:130 +#: aleksis/apps/alsijil/managers.py:91 aleksis/apps/alsijil/tables.py:110 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:172 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:236 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:311 @@ -277,14 +277,14 @@ msgid "Short name" msgstr "Короткое имÑ" #: aleksis/apps/alsijil/models.py:64 aleksis/apps/alsijil/models.py:438 -#: aleksis/apps/alsijil/models.py:855 +#: aleksis/apps/alsijil/models.py:867 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:20 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:12 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:25 msgid "Name" msgstr "Полное имÑ" -#: aleksis/apps/alsijil/models.py:68 aleksis/apps/alsijil/tables.py:41 +#: aleksis/apps/alsijil/models.py:68 aleksis/apps/alsijil/tables.py:21 msgid "Count as absent" msgstr "КоличеÑтво отÑутÑтвующих" @@ -304,9 +304,7 @@ msgid "Year" msgstr "Год" #: aleksis/apps/alsijil/models.py:265 aleksis/apps/alsijil/models.py:455 -#: aleksis/apps/alsijil/tables.py:120 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:8 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:9 +#: aleksis/apps/alsijil/tables.py:100 #: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:57 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:32 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:19 @@ -382,7 +380,7 @@ msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¾Ñ‚Ð¼ÐµÑ‚ÐºÐ°" msgid "Course" msgstr "" -#: aleksis/apps/alsijil/models.py:486 aleksis/apps/alsijil/tables.py:111 +#: aleksis/apps/alsijil/models.py:486 aleksis/apps/alsijil/tables.py:91 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:127 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:253 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:331 @@ -405,8 +403,8 @@ msgstr "Ð“Ñ€ÑƒÐ¿Ð¿Ð¾Ð²Ð°Ñ Ð·Ð°Ð¼ÐµÑ‚ÐºÐ°" msgid "Participation touched at" msgstr "" -#: aleksis/apps/alsijil/models.py:524 aleksis/apps/alsijil/models.py:772 -#: aleksis/apps/alsijil/models.py:826 +#: aleksis/apps/alsijil/models.py:524 aleksis/apps/alsijil/models.py:773 +#: aleksis/apps/alsijil/models.py:829 #, fuzzy #| msgid "Lesson documentation" msgid "Documentation" @@ -418,116 +416,130 @@ msgstr "Учебный материал" msgid "Documentations" msgstr "Учебные материалы" -#: aleksis/apps/alsijil/models.py:765 +#: aleksis/apps/alsijil/models.py:766 #, fuzzy #| msgid "Group roles" msgid "Groups of Person" msgstr "Роли групп" -#: aleksis/apps/alsijil/models.py:778 +#: aleksis/apps/alsijil/models.py:779 #, fuzzy #| msgid "Absences" msgid "Absence Reason" msgstr "ПропуÑки" -#: aleksis/apps/alsijil/models.py:790 +#: aleksis/apps/alsijil/models.py:791 #, fuzzy #| msgid "Absences" msgid "Base Absence" msgstr "ПропуÑки" -#: aleksis/apps/alsijil/models.py:802 aleksis/apps/alsijil/models.py:803 +#: aleksis/apps/alsijil/models.py:794 aleksis/apps/alsijil/tables.py:98 +#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:161 +#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:21 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:46 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:123 +#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323 +msgid "Tardiness" +msgstr "Опоздание" + +#: aleksis/apps/alsijil/models.py:805 aleksis/apps/alsijil/models.py:806 msgid "Participation Status" msgstr "" -#: aleksis/apps/alsijil/models.py:831 +#: aleksis/apps/alsijil/models.py:834 #, fuzzy #| msgid "Notes" msgid "Note" msgstr "Заметки" -#: aleksis/apps/alsijil/models.py:833 +#: aleksis/apps/alsijil/models.py:836 #, fuzzy #| msgid "Extra mark" msgid "Extra Mark" msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¾Ñ‚Ð¼ÐµÑ‚ÐºÐ°" -#: aleksis/apps/alsijil/models.py:840 +#: aleksis/apps/alsijil/models.py:843 #, fuzzy #| msgid "Personal note" msgid "Personal Note" msgstr "Ð›Ð¸Ñ‡Ð½Ð°Ñ Ð·Ð°Ð¼ÐµÑ‚ÐºÐ°" -#: aleksis/apps/alsijil/models.py:841 +#: aleksis/apps/alsijil/models.py:844 #, fuzzy #| msgid "Personal notes" msgid "Personal Notes" msgstr "Личные заметки" -#: aleksis/apps/alsijil/models.py:856 +#: aleksis/apps/alsijil/models.py:855 +msgid "A person got assigned the same extra mark multiple times per documentation." +msgstr "" + +#: aleksis/apps/alsijil/models.py:868 msgid "Icon" msgstr "Иконка" -#: aleksis/apps/alsijil/models.py:857 +#: aleksis/apps/alsijil/models.py:869 msgid "Colour" msgstr "Цвет" -#: aleksis/apps/alsijil/models.py:863 aleksis/apps/alsijil/models.py:878 +#: aleksis/apps/alsijil/models.py:875 aleksis/apps/alsijil/models.py:890 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:62 msgid "Group role" msgstr "Роль группы" -#: aleksis/apps/alsijil/models.py:864 +#: aleksis/apps/alsijil/models.py:876 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:90 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:8 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:9 msgid "Group roles" msgstr "Роли групп" -#: aleksis/apps/alsijil/models.py:865 +#: aleksis/apps/alsijil/models.py:877 msgid "Can assign group role" msgstr "Может назначать роль группы" -#: aleksis/apps/alsijil/models.py:884 +#: aleksis/apps/alsijil/models.py:896 msgid "Assigned person" msgstr "Ðазначенное физлицо" -#: aleksis/apps/alsijil/models.py:889 aleksis/apps/alsijil/tables.py:105 +#: aleksis/apps/alsijil/models.py:901 aleksis/apps/alsijil/tables.py:85 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:124 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:242 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:321 msgid "Groups" msgstr "Группы" -#: aleksis/apps/alsijil/models.py:896 +#: aleksis/apps/alsijil/models.py:908 msgid "Can be left empty if end date is not clear yet" msgstr "ЕÑли нет точной конечной даты, можно оÑтавить незаполненным" -#: aleksis/apps/alsijil/models.py:911 +#: aleksis/apps/alsijil/models.py:923 msgid "Group role assignment" msgstr "Ðазначение роли группы" -#: aleksis/apps/alsijil/models.py:912 +#: aleksis/apps/alsijil/models.py:924 msgid "Group role assignments" msgstr "Ðазначение ролей групп" -#: aleksis/apps/alsijil/models.py:919 +#: aleksis/apps/alsijil/models.py:931 msgid "Can view lesson overview" msgstr "Может проÑматривать обзор урока" -#: aleksis/apps/alsijil/models.py:920 +#: aleksis/apps/alsijil/models.py:932 msgid "Can view week overview" msgstr "Может проÑматривать недельный обзор" -#: aleksis/apps/alsijil/models.py:921 +#: aleksis/apps/alsijil/models.py:933 msgid "Can view full register" msgstr "Может проÑматривать веÑÑŒ журнал" -#: aleksis/apps/alsijil/models.py:922 +#: aleksis/apps/alsijil/models.py:934 msgid "Can register absence" msgstr "Может региÑтрировать отÑутÑтвие" -#: aleksis/apps/alsijil/models.py:923 +#: aleksis/apps/alsijil/models.py:935 msgid "Can list all personal note filters" msgstr "Может проÑматривать вÑе фильтры личных заметок" @@ -632,38 +644,27 @@ msgstr "" msgid "Set time range for which documentations may be edited" msgstr "" -#: aleksis/apps/alsijil/tables.py:23 aleksis/apps/alsijil/tables.py:47 -#: aleksis/apps/alsijil/tables.py:72 +#: aleksis/apps/alsijil/tables.py:27 aleksis/apps/alsijil/tables.py:52 #: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:13 msgid "Edit" msgstr "Редактировать" -#: aleksis/apps/alsijil/tables.py:96 +#: aleksis/apps/alsijil/tables.py:76 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:348 msgid "Date" msgstr "Дата" -#: aleksis/apps/alsijil/tables.py:99 +#: aleksis/apps/alsijil/tables.py:79 #: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:30 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:122 msgid "Period" msgstr "Урок" -#: aleksis/apps/alsijil/tables.py:118 -#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:161 -#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:21 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:46 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:123 -#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323 -msgid "Tardiness" -msgstr "Опоздание" - -#: aleksis/apps/alsijil/tables.py:119 +#: aleksis/apps/alsijil/tables.py:99 msgid "Excuse" msgstr "ОбъÑÑнительнаÑ" -#: aleksis/apps/alsijil/tables.py:156 +#: aleksis/apps/alsijil/tables.py:136 #, fuzzy, python-brace-format #| msgid "{value}' late" msgid "{value}' tardiness" @@ -1020,17 +1021,6 @@ msgstr "" " Ðе иÑпользуйте Ñтот функционал Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¾Ð±ÑŠÑÑнительной по-умолчанию или еÑли не ведёте разделение по типам.\n" " " -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:6 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:7 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:14 -msgid "Create extra mark" -msgstr "Создать дополнительную отметку" - -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:6 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:7 -msgid "Edit extra mark" -msgstr "Редактировать дополнительную отметку" - #: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:9 #: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:16 #, python-format @@ -1563,108 +1553,111 @@ msgstr "ÐеделÑ" msgid "Notes" msgstr "Заметки" -#: aleksis/apps/alsijil/views.py:114 +#: aleksis/apps/alsijil/views.py:112 msgid "You either selected an invalid lesson or there is currently no lesson in progress." msgstr "Ð’Ñ‹ или выбрали неправильный урок, или ÑÐµÐ¹Ñ‡Ð°Ñ ÑƒÑ€Ð¾ÐºÐ° нет." -#: aleksis/apps/alsijil/views.py:147 +#: aleksis/apps/alsijil/views.py:145 msgid "You are not allowed to create a lesson documentation for a lesson in the future." msgstr "Вам Ð½ÐµÐ»ÑŒÐ·Ñ Ñоздавать учебные материалы Ð´Ð»Ñ ÑƒÑ€Ð¾ÐºÐ¾Ð² в будущем." -#: aleksis/apps/alsijil/views.py:264 +#: aleksis/apps/alsijil/views.py:262 msgid "The lesson documentation has been saved." msgstr "Учебный материал Ñохранён." -#: aleksis/apps/alsijil/views.py:298 +#: aleksis/apps/alsijil/views.py:296 msgid "The personal notes have been saved." msgstr "Личные заметки Ñохранены." -#: aleksis/apps/alsijil/views.py:658 +#: aleksis/apps/alsijil/views.py:656 #, fuzzy #| msgid "Generate printout" msgid "Generate full register printout for {}" msgstr "Подготовить к печати" -#: aleksis/apps/alsijil/views.py:659 +#: aleksis/apps/alsijil/views.py:657 #, fuzzy #| msgid "Generate printout" msgid "Generate full register printout …" msgstr "Подготовить к печати" -#: aleksis/apps/alsijil/views.py:660 +#: aleksis/apps/alsijil/views.py:658 #, fuzzy #| msgid "The personal note has been deleted." msgid "The printout has been generated successfully." msgstr "Ð›Ð¸Ñ‡Ð½Ð°Ñ Ð·Ð°Ð¼ÐµÑ‚ÐºÐ° удалена." -#: aleksis/apps/alsijil/views.py:661 +#: aleksis/apps/alsijil/views.py:659 msgid "There was a problem while generating the printout." msgstr "" -#: aleksis/apps/alsijil/views.py:664 +#: aleksis/apps/alsijil/views.py:662 msgid "Download PDF" msgstr "" -#: aleksis/apps/alsijil/views.py:1030 +#: aleksis/apps/alsijil/views.py:1028 msgid "The absence has been saved." msgstr "ОтÑутÑтвие Ñохранено." -#: aleksis/apps/alsijil/views.py:1051 +#: aleksis/apps/alsijil/views.py:1049 msgid "The personal note has been deleted." msgstr "Ð›Ð¸Ñ‡Ð½Ð°Ñ Ð·Ð°Ð¼ÐµÑ‚ÐºÐ° удалена." -#: aleksis/apps/alsijil/views.py:1074 -msgid "The extra mark has been created." -msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¾Ñ‚Ð¼ÐµÑ‚ÐºÐ° Ñоздана." - -#: aleksis/apps/alsijil/views.py:1086 -msgid "The extra mark has been saved." -msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¾Ñ‚Ð¼ÐµÑ‚ÐºÐ° Ñохранена." - -#: aleksis/apps/alsijil/views.py:1097 -msgid "The extra mark has been deleted." -msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¾Ñ‚Ð¼ÐµÑ‚ÐºÐ° удалена." - -#: aleksis/apps/alsijil/views.py:1119 +#: aleksis/apps/alsijil/views.py:1072 msgid "The excuse type has been created." msgstr "Тип объÑÑнительной Ñоздан." -#: aleksis/apps/alsijil/views.py:1131 +#: aleksis/apps/alsijil/views.py:1084 msgid "The excuse type has been saved." msgstr "Тип объÑÑнительной Ñохранён." -#: aleksis/apps/alsijil/views.py:1142 +#: aleksis/apps/alsijil/views.py:1095 msgid "The excuse type has been deleted." msgstr "Тип объÑÑнительной удалён." -#: aleksis/apps/alsijil/views.py:1164 +#: aleksis/apps/alsijil/views.py:1117 msgid "The group role has been created." msgstr "Роль группы Ñоздана." -#: aleksis/apps/alsijil/views.py:1176 +#: aleksis/apps/alsijil/views.py:1129 msgid "The group role has been saved." msgstr "Роль группы Ñохранена." -#: aleksis/apps/alsijil/views.py:1187 +#: aleksis/apps/alsijil/views.py:1140 msgid "The group role has been deleted." msgstr "Роль группы удалена." -#: aleksis/apps/alsijil/views.py:1221 aleksis/apps/alsijil/views.py:1253 +#: aleksis/apps/alsijil/views.py:1174 aleksis/apps/alsijil/views.py:1206 msgid "The group role has been assigned." msgstr "Роль группы назначена." -#: aleksis/apps/alsijil/views.py:1272 +#: aleksis/apps/alsijil/views.py:1225 msgid "The group role assignment has been saved." msgstr "Ðазначение роли группы Ñохранено." -#: aleksis/apps/alsijil/views.py:1293 +#: aleksis/apps/alsijil/views.py:1246 msgid "The group role assignment has been stopped." msgstr "Ðазначение роли группы оÑтановлено." -#: aleksis/apps/alsijil/views.py:1306 +#: aleksis/apps/alsijil/views.py:1259 msgid "The group role assignment has been deleted." msgstr "Ðазначение роли группы удалено." +#~ msgid "Create extra mark" +#~ msgstr "Создать дополнительную отметку" + +#~ msgid "Edit extra mark" +#~ msgstr "Редактировать дополнительную отметку" + +#~ msgid "The extra mark has been created." +#~ msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¾Ñ‚Ð¼ÐµÑ‚ÐºÐ° Ñоздана." + +#~ msgid "The extra mark has been saved." +#~ msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¾Ñ‚Ð¼ÐµÑ‚ÐºÐ° Ñохранена." + +#~ msgid "The extra mark has been deleted." +#~ msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¾Ñ‚Ð¼ÐµÑ‚ÐºÐ° удалена." + #~ msgid "Current lesson" #~ msgstr "Текущий урок" diff --git a/aleksis/apps/alsijil/locale/tr_TR/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/tr_TR/LC_MESSAGES/django.po index 7e8285208907941025f0a6da310079f0e35e214e..ac6d9f2c9e90f79abbff6fad12355fb5219b3af5 100644 --- a/aleksis/apps/alsijil/locale/tr_TR/LC_MESSAGES/django.po +++ b/aleksis/apps/alsijil/locale/tr_TR/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-06-13 11:19+0200\n" +"POT-Creation-Date: 2024-07-14 16:32+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -30,8 +30,8 @@ msgstr "" msgid "Mark as {excuse_type.name}" msgstr "" -#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:29 -#: aleksis/apps/alsijil/tables.py:53 aleksis/apps/alsijil/tables.py:78 +#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:33 +#: aleksis/apps/alsijil/tables.py:58 #: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:29 msgid "Delete" msgstr "" @@ -110,7 +110,7 @@ msgid "Before" msgstr "" #: aleksis/apps/alsijil/filters.py:14 aleksis/apps/alsijil/forms.py:371 -#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:116 +#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:96 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:126 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:223 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:189 @@ -151,20 +151,20 @@ msgid "You can't select a group and a teacher both." msgstr "" #: aleksis/apps/alsijil/forms.py:193 aleksis/apps/alsijil/forms.py:291 -#: aleksis/apps/alsijil/models.py:762 aleksis/apps/alsijil/models.py:819 +#: aleksis/apps/alsijil/models.py:763 aleksis/apps/alsijil/models.py:822 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:63 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:27 msgid "Person" msgstr "" #: aleksis/apps/alsijil/forms.py:194 aleksis/apps/alsijil/forms.py:372 -#: aleksis/apps/alsijil/models.py:891 +#: aleksis/apps/alsijil/models.py:903 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:64 msgid "Start date" msgstr "" #: aleksis/apps/alsijil/forms.py:195 aleksis/apps/alsijil/forms.py:373 -#: aleksis/apps/alsijil/models.py:895 +#: aleksis/apps/alsijil/models.py:907 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:65 msgid "End date" msgstr "" @@ -177,8 +177,8 @@ msgstr "" msgid "End period" msgstr "" -#: aleksis/apps/alsijil/forms.py:198 aleksis/apps/alsijil/tables.py:117 -#: aleksis/apps/alsijil/tables.py:138 +#: aleksis/apps/alsijil/forms.py:198 aleksis/apps/alsijil/tables.py:97 +#: aleksis/apps/alsijil/tables.py:118 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:50 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:392 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:28 @@ -187,7 +187,7 @@ msgstr "" msgid "Absent" msgstr "" -#: aleksis/apps/alsijil/forms.py:199 aleksis/apps/alsijil/tables.py:146 +#: aleksis/apps/alsijil/forms.py:199 aleksis/apps/alsijil/tables.py:126 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:54 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:135 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:30 @@ -219,7 +219,7 @@ msgstr "" msgid "Has lesson documentation" msgstr "" -#: aleksis/apps/alsijil/managers.py:91 aleksis/apps/alsijil/tables.py:130 +#: aleksis/apps/alsijil/managers.py:91 aleksis/apps/alsijil/tables.py:110 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:172 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:236 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:311 @@ -276,14 +276,14 @@ msgid "Short name" msgstr "" #: aleksis/apps/alsijil/models.py:64 aleksis/apps/alsijil/models.py:438 -#: aleksis/apps/alsijil/models.py:855 +#: aleksis/apps/alsijil/models.py:867 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:20 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:12 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:25 msgid "Name" msgstr "" -#: aleksis/apps/alsijil/models.py:68 aleksis/apps/alsijil/tables.py:41 +#: aleksis/apps/alsijil/models.py:68 aleksis/apps/alsijil/tables.py:21 msgid "Count as absent" msgstr "" @@ -303,9 +303,7 @@ msgid "Year" msgstr "" #: aleksis/apps/alsijil/models.py:265 aleksis/apps/alsijil/models.py:455 -#: aleksis/apps/alsijil/tables.py:120 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:8 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:9 +#: aleksis/apps/alsijil/tables.py:100 #: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:57 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:32 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:19 @@ -381,7 +379,7 @@ msgstr "" msgid "Course" msgstr "" -#: aleksis/apps/alsijil/models.py:486 aleksis/apps/alsijil/tables.py:111 +#: aleksis/apps/alsijil/models.py:486 aleksis/apps/alsijil/tables.py:91 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:127 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:253 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:331 @@ -400,8 +398,8 @@ msgstr "" msgid "Participation touched at" msgstr "" -#: aleksis/apps/alsijil/models.py:524 aleksis/apps/alsijil/models.py:772 -#: aleksis/apps/alsijil/models.py:826 +#: aleksis/apps/alsijil/models.py:524 aleksis/apps/alsijil/models.py:773 +#: aleksis/apps/alsijil/models.py:829 msgid "Documentation" msgstr "" @@ -409,102 +407,116 @@ msgstr "" msgid "Documentations" msgstr "" -#: aleksis/apps/alsijil/models.py:765 +#: aleksis/apps/alsijil/models.py:766 msgid "Groups of Person" msgstr "" -#: aleksis/apps/alsijil/models.py:778 +#: aleksis/apps/alsijil/models.py:779 msgid "Absence Reason" msgstr "" -#: aleksis/apps/alsijil/models.py:790 +#: aleksis/apps/alsijil/models.py:791 msgid "Base Absence" msgstr "" -#: aleksis/apps/alsijil/models.py:802 aleksis/apps/alsijil/models.py:803 +#: aleksis/apps/alsijil/models.py:794 aleksis/apps/alsijil/tables.py:98 +#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:161 +#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:21 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:46 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:123 +#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323 +msgid "Tardiness" +msgstr "" + +#: aleksis/apps/alsijil/models.py:805 aleksis/apps/alsijil/models.py:806 msgid "Participation Status" msgstr "" -#: aleksis/apps/alsijil/models.py:831 +#: aleksis/apps/alsijil/models.py:834 msgid "Note" msgstr "" -#: aleksis/apps/alsijil/models.py:833 +#: aleksis/apps/alsijil/models.py:836 msgid "Extra Mark" msgstr "" -#: aleksis/apps/alsijil/models.py:840 +#: aleksis/apps/alsijil/models.py:843 msgid "Personal Note" msgstr "" -#: aleksis/apps/alsijil/models.py:841 +#: aleksis/apps/alsijil/models.py:844 msgid "Personal Notes" msgstr "" -#: aleksis/apps/alsijil/models.py:856 +#: aleksis/apps/alsijil/models.py:855 +msgid "A person got assigned the same extra mark multiple times per documentation." +msgstr "" + +#: aleksis/apps/alsijil/models.py:868 msgid "Icon" msgstr "" -#: aleksis/apps/alsijil/models.py:857 +#: aleksis/apps/alsijil/models.py:869 msgid "Colour" msgstr "" -#: aleksis/apps/alsijil/models.py:863 aleksis/apps/alsijil/models.py:878 +#: aleksis/apps/alsijil/models.py:875 aleksis/apps/alsijil/models.py:890 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:62 msgid "Group role" msgstr "" -#: aleksis/apps/alsijil/models.py:864 +#: aleksis/apps/alsijil/models.py:876 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:90 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:8 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:9 msgid "Group roles" msgstr "" -#: aleksis/apps/alsijil/models.py:865 +#: aleksis/apps/alsijil/models.py:877 msgid "Can assign group role" msgstr "" -#: aleksis/apps/alsijil/models.py:884 +#: aleksis/apps/alsijil/models.py:896 msgid "Assigned person" msgstr "" -#: aleksis/apps/alsijil/models.py:889 aleksis/apps/alsijil/tables.py:105 +#: aleksis/apps/alsijil/models.py:901 aleksis/apps/alsijil/tables.py:85 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:124 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:242 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:321 msgid "Groups" msgstr "" -#: aleksis/apps/alsijil/models.py:896 +#: aleksis/apps/alsijil/models.py:908 msgid "Can be left empty if end date is not clear yet" msgstr "" -#: aleksis/apps/alsijil/models.py:911 +#: aleksis/apps/alsijil/models.py:923 msgid "Group role assignment" msgstr "" -#: aleksis/apps/alsijil/models.py:912 +#: aleksis/apps/alsijil/models.py:924 msgid "Group role assignments" msgstr "" -#: aleksis/apps/alsijil/models.py:919 +#: aleksis/apps/alsijil/models.py:931 msgid "Can view lesson overview" msgstr "" -#: aleksis/apps/alsijil/models.py:920 +#: aleksis/apps/alsijil/models.py:932 msgid "Can view week overview" msgstr "" -#: aleksis/apps/alsijil/models.py:921 +#: aleksis/apps/alsijil/models.py:933 msgid "Can view full register" msgstr "" -#: aleksis/apps/alsijil/models.py:922 +#: aleksis/apps/alsijil/models.py:934 msgid "Can register absence" msgstr "" -#: aleksis/apps/alsijil/models.py:923 +#: aleksis/apps/alsijil/models.py:935 msgid "Can list all personal note filters" msgstr "" @@ -609,38 +621,27 @@ msgstr "" msgid "Set time range for which documentations may be edited" msgstr "" -#: aleksis/apps/alsijil/tables.py:23 aleksis/apps/alsijil/tables.py:47 -#: aleksis/apps/alsijil/tables.py:72 +#: aleksis/apps/alsijil/tables.py:27 aleksis/apps/alsijil/tables.py:52 #: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:13 msgid "Edit" msgstr "" -#: aleksis/apps/alsijil/tables.py:96 +#: aleksis/apps/alsijil/tables.py:76 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:348 msgid "Date" msgstr "" -#: aleksis/apps/alsijil/tables.py:99 +#: aleksis/apps/alsijil/tables.py:79 #: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:30 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:122 msgid "Period" msgstr "" -#: aleksis/apps/alsijil/tables.py:118 -#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:161 -#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:21 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:46 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:123 -#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323 -msgid "Tardiness" -msgstr "" - -#: aleksis/apps/alsijil/tables.py:119 +#: aleksis/apps/alsijil/tables.py:99 msgid "Excuse" msgstr "" -#: aleksis/apps/alsijil/tables.py:156 +#: aleksis/apps/alsijil/tables.py:136 #, python-brace-format msgid "{value}' tardiness" msgstr "" @@ -967,17 +968,6 @@ msgid "" " " msgstr "" -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:6 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:7 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:14 -msgid "Create extra mark" -msgstr "" - -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:6 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:7 -msgid "Edit extra mark" -msgstr "" - #: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:9 #: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:16 #, python-format @@ -1471,98 +1461,86 @@ msgstr "" msgid "Notes" msgstr "" -#: aleksis/apps/alsijil/views.py:114 +#: aleksis/apps/alsijil/views.py:112 msgid "You either selected an invalid lesson or there is currently no lesson in progress." msgstr "" -#: aleksis/apps/alsijil/views.py:147 +#: aleksis/apps/alsijil/views.py:145 msgid "You are not allowed to create a lesson documentation for a lesson in the future." msgstr "" -#: aleksis/apps/alsijil/views.py:264 +#: aleksis/apps/alsijil/views.py:262 msgid "The lesson documentation has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:298 +#: aleksis/apps/alsijil/views.py:296 msgid "The personal notes have been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:658 +#: aleksis/apps/alsijil/views.py:656 msgid "Generate full register printout for {}" msgstr "" -#: aleksis/apps/alsijil/views.py:659 +#: aleksis/apps/alsijil/views.py:657 msgid "Generate full register printout …" msgstr "" -#: aleksis/apps/alsijil/views.py:660 +#: aleksis/apps/alsijil/views.py:658 msgid "The printout has been generated successfully." msgstr "" -#: aleksis/apps/alsijil/views.py:661 +#: aleksis/apps/alsijil/views.py:659 msgid "There was a problem while generating the printout." msgstr "" -#: aleksis/apps/alsijil/views.py:664 +#: aleksis/apps/alsijil/views.py:662 msgid "Download PDF" msgstr "" -#: aleksis/apps/alsijil/views.py:1030 +#: aleksis/apps/alsijil/views.py:1028 msgid "The absence has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1051 +#: aleksis/apps/alsijil/views.py:1049 msgid "The personal note has been deleted." msgstr "" -#: aleksis/apps/alsijil/views.py:1074 -msgid "The extra mark has been created." -msgstr "" - -#: aleksis/apps/alsijil/views.py:1086 -msgid "The extra mark has been saved." -msgstr "" - -#: aleksis/apps/alsijil/views.py:1097 -msgid "The extra mark has been deleted." -msgstr "" - -#: aleksis/apps/alsijil/views.py:1119 +#: aleksis/apps/alsijil/views.py:1072 msgid "The excuse type has been created." msgstr "" -#: aleksis/apps/alsijil/views.py:1131 +#: aleksis/apps/alsijil/views.py:1084 msgid "The excuse type has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1142 +#: aleksis/apps/alsijil/views.py:1095 msgid "The excuse type has been deleted." msgstr "" -#: aleksis/apps/alsijil/views.py:1164 +#: aleksis/apps/alsijil/views.py:1117 msgid "The group role has been created." msgstr "" -#: aleksis/apps/alsijil/views.py:1176 +#: aleksis/apps/alsijil/views.py:1129 msgid "The group role has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1187 +#: aleksis/apps/alsijil/views.py:1140 msgid "The group role has been deleted." msgstr "" -#: aleksis/apps/alsijil/views.py:1221 aleksis/apps/alsijil/views.py:1253 +#: aleksis/apps/alsijil/views.py:1174 aleksis/apps/alsijil/views.py:1206 msgid "The group role has been assigned." msgstr "" -#: aleksis/apps/alsijil/views.py:1272 +#: aleksis/apps/alsijil/views.py:1225 msgid "The group role assignment has been saved." msgstr "" -#: aleksis/apps/alsijil/views.py:1293 +#: aleksis/apps/alsijil/views.py:1246 msgid "The group role assignment has been stopped." msgstr "" -#: aleksis/apps/alsijil/views.py:1306 +#: aleksis/apps/alsijil/views.py:1259 msgid "The group role assignment has been deleted." msgstr "" diff --git a/aleksis/apps/alsijil/locale/uk/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/uk/LC_MESSAGES/django.po index d3663a8befb259e29f630d7b08355882257e5e4a..f4d032ee26c75b151cedccdc4b4eb1ccf9516944 100644 --- a/aleksis/apps/alsijil/locale/uk/LC_MESSAGES/django.po +++ b/aleksis/apps/alsijil/locale/uk/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-06-13 11:19+0200\n" +"POT-Creation-Date: 2024-07-14 16:32+0200\n" "PO-Revision-Date: 2023-01-25 05:58+0000\n" "Last-Translator: Serhii Horichenko <m@sgg.im>\n" "Language-Team: Ukrainian <https://translate.edugit.org/projects/aleksis/aleksis-app-alsijil/uk/>\n" @@ -31,8 +31,8 @@ msgstr "Позначити Ñк непоÑÑнений" msgid "Mark as {excuse_type.name}" msgstr "Позначити Ñк {excuse_type.name}" -#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:29 -#: aleksis/apps/alsijil/tables.py:53 aleksis/apps/alsijil/tables.py:78 +#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:33 +#: aleksis/apps/alsijil/tables.py:58 #: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:29 msgid "Delete" msgstr "Видалити" @@ -111,7 +111,7 @@ msgid "Before" msgstr "Перед" #: aleksis/apps/alsijil/filters.py:14 aleksis/apps/alsijil/forms.py:371 -#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:116 +#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:96 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:126 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:223 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:189 @@ -152,20 +152,20 @@ msgid "You can't select a group and a teacher both." msgstr "Ви не можете обрати одночаÑно групу та викладача." #: aleksis/apps/alsijil/forms.py:193 aleksis/apps/alsijil/forms.py:291 -#: aleksis/apps/alsijil/models.py:762 aleksis/apps/alsijil/models.py:819 +#: aleksis/apps/alsijil/models.py:763 aleksis/apps/alsijil/models.py:822 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:63 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:27 msgid "Person" msgstr "ОÑоба" #: aleksis/apps/alsijil/forms.py:194 aleksis/apps/alsijil/forms.py:372 -#: aleksis/apps/alsijil/models.py:891 +#: aleksis/apps/alsijil/models.py:903 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:64 msgid "Start date" msgstr "Дата початку" #: aleksis/apps/alsijil/forms.py:195 aleksis/apps/alsijil/forms.py:373 -#: aleksis/apps/alsijil/models.py:895 +#: aleksis/apps/alsijil/models.py:907 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:65 msgid "End date" msgstr "Дата закінченнÑ" @@ -178,8 +178,8 @@ msgstr "Початок уроків" msgid "End period" msgstr "Ð—Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ ÑƒÑ€Ð¾ÐºÑ–Ð²" -#: aleksis/apps/alsijil/forms.py:198 aleksis/apps/alsijil/tables.py:117 -#: aleksis/apps/alsijil/tables.py:138 +#: aleksis/apps/alsijil/forms.py:198 aleksis/apps/alsijil/tables.py:97 +#: aleksis/apps/alsijil/tables.py:118 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:50 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:392 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:28 @@ -188,7 +188,7 @@ msgstr "Ð—Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ ÑƒÑ€Ð¾ÐºÑ–Ð²" msgid "Absent" msgstr "ВідÑутній(-Ñ)" -#: aleksis/apps/alsijil/forms.py:199 aleksis/apps/alsijil/tables.py:146 +#: aleksis/apps/alsijil/forms.py:199 aleksis/apps/alsijil/tables.py:126 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:54 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:135 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:30 @@ -220,7 +220,7 @@ msgstr "Ðавчальний рік" msgid "Has lesson documentation" msgstr "Має учбовий матеріал" -#: aleksis/apps/alsijil/managers.py:91 aleksis/apps/alsijil/tables.py:130 +#: aleksis/apps/alsijil/managers.py:91 aleksis/apps/alsijil/tables.py:110 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:172 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:236 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:311 @@ -277,14 +277,14 @@ msgid "Short name" msgstr "Коротке ім'Ñ" #: aleksis/apps/alsijil/models.py:64 aleksis/apps/alsijil/models.py:438 -#: aleksis/apps/alsijil/models.py:855 +#: aleksis/apps/alsijil/models.py:867 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:20 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:12 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:25 msgid "Name" msgstr "Повне ім'Ñ" -#: aleksis/apps/alsijil/models.py:68 aleksis/apps/alsijil/tables.py:41 +#: aleksis/apps/alsijil/models.py:68 aleksis/apps/alsijil/tables.py:21 msgid "Count as absent" msgstr "КількіÑть відÑутніх" @@ -304,9 +304,7 @@ msgid "Year" msgstr "Рік" #: aleksis/apps/alsijil/models.py:265 aleksis/apps/alsijil/models.py:455 -#: aleksis/apps/alsijil/tables.py:120 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:8 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:9 +#: aleksis/apps/alsijil/tables.py:100 #: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:57 #: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:32 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:19 @@ -382,7 +380,7 @@ msgstr "Додаткова відмітка" msgid "Course" msgstr "" -#: aleksis/apps/alsijil/models.py:486 aleksis/apps/alsijil/tables.py:111 +#: aleksis/apps/alsijil/models.py:486 aleksis/apps/alsijil/tables.py:91 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:127 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:253 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:331 @@ -405,8 +403,8 @@ msgstr "Групова нотатка" msgid "Participation touched at" msgstr "" -#: aleksis/apps/alsijil/models.py:524 aleksis/apps/alsijil/models.py:772 -#: aleksis/apps/alsijil/models.py:826 +#: aleksis/apps/alsijil/models.py:524 aleksis/apps/alsijil/models.py:773 +#: aleksis/apps/alsijil/models.py:829 #, fuzzy #| msgid "Lesson documentation" msgid "Documentation" @@ -418,116 +416,130 @@ msgstr "Учбовий матеріал" msgid "Documentations" msgstr "Учбові матеріали" -#: aleksis/apps/alsijil/models.py:765 +#: aleksis/apps/alsijil/models.py:766 #, fuzzy #| msgid "Group roles" msgid "Groups of Person" msgstr "Ролі груп" -#: aleksis/apps/alsijil/models.py:778 +#: aleksis/apps/alsijil/models.py:779 #, fuzzy #| msgid "Absences" msgid "Absence Reason" msgstr "ВідÑутноÑті" -#: aleksis/apps/alsijil/models.py:790 +#: aleksis/apps/alsijil/models.py:791 #, fuzzy #| msgid "Absences" msgid "Base Absence" msgstr "ВідÑутноÑті" -#: aleksis/apps/alsijil/models.py:802 aleksis/apps/alsijil/models.py:803 +#: aleksis/apps/alsijil/models.py:794 aleksis/apps/alsijil/tables.py:98 +#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:161 +#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:21 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:46 +#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:123 +#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323 +msgid "Tardiness" +msgstr "ЗапізненнÑ" + +#: aleksis/apps/alsijil/models.py:805 aleksis/apps/alsijil/models.py:806 msgid "Participation Status" msgstr "" -#: aleksis/apps/alsijil/models.py:831 +#: aleksis/apps/alsijil/models.py:834 #, fuzzy #| msgid "Notes" msgid "Note" msgstr "Ðотатки" -#: aleksis/apps/alsijil/models.py:833 +#: aleksis/apps/alsijil/models.py:836 #, fuzzy #| msgid "Extra mark" msgid "Extra Mark" msgstr "Додаткова відмітка" -#: aleksis/apps/alsijil/models.py:840 +#: aleksis/apps/alsijil/models.py:843 #, fuzzy #| msgid "Personal note" msgid "Personal Note" msgstr "ОÑобиÑта нотатка" -#: aleksis/apps/alsijil/models.py:841 +#: aleksis/apps/alsijil/models.py:844 #, fuzzy #| msgid "Personal notes" msgid "Personal Notes" msgstr "ОÑобиÑті нотатки" -#: aleksis/apps/alsijil/models.py:856 +#: aleksis/apps/alsijil/models.py:855 +msgid "A person got assigned the same extra mark multiple times per documentation." +msgstr "" + +#: aleksis/apps/alsijil/models.py:868 msgid "Icon" msgstr "Піктограма" -#: aleksis/apps/alsijil/models.py:857 +#: aleksis/apps/alsijil/models.py:869 msgid "Colour" msgstr "Колір" -#: aleksis/apps/alsijil/models.py:863 aleksis/apps/alsijil/models.py:878 +#: aleksis/apps/alsijil/models.py:875 aleksis/apps/alsijil/models.py:890 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:62 msgid "Group role" msgstr "Роль групи" -#: aleksis/apps/alsijil/models.py:864 +#: aleksis/apps/alsijil/models.py:876 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:90 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:8 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:9 msgid "Group roles" msgstr "Ролі груп" -#: aleksis/apps/alsijil/models.py:865 +#: aleksis/apps/alsijil/models.py:877 msgid "Can assign group role" msgstr "Може призначати роль групи" -#: aleksis/apps/alsijil/models.py:884 +#: aleksis/apps/alsijil/models.py:896 msgid "Assigned person" msgstr "Призначена оÑоба" -#: aleksis/apps/alsijil/models.py:889 aleksis/apps/alsijil/tables.py:105 +#: aleksis/apps/alsijil/models.py:901 aleksis/apps/alsijil/tables.py:85 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:124 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:242 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:321 msgid "Groups" msgstr "Групи" -#: aleksis/apps/alsijil/models.py:896 +#: aleksis/apps/alsijil/models.py:908 msgid "Can be left empty if end date is not clear yet" msgstr "Якщо немає точної кінцевої дати, можна залишити порожнім" -#: aleksis/apps/alsijil/models.py:911 +#: aleksis/apps/alsijil/models.py:923 msgid "Group role assignment" msgstr "ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ€Ð¾Ð»Ñ– групи" -#: aleksis/apps/alsijil/models.py:912 +#: aleksis/apps/alsijil/models.py:924 msgid "Group role assignments" msgstr "ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ€Ð¾Ð»Ñ– групи" -#: aleksis/apps/alsijil/models.py:919 +#: aleksis/apps/alsijil/models.py:931 msgid "Can view lesson overview" msgstr "Може бачити оглÑд уроку" -#: aleksis/apps/alsijil/models.py:920 +#: aleksis/apps/alsijil/models.py:932 msgid "Can view week overview" msgstr "Може бачити оглÑд тижнÑ" -#: aleksis/apps/alsijil/models.py:921 +#: aleksis/apps/alsijil/models.py:933 msgid "Can view full register" msgstr "Може бачити веÑÑŒ журнал" -#: aleksis/apps/alsijil/models.py:922 +#: aleksis/apps/alsijil/models.py:934 msgid "Can register absence" msgstr "Може реєÑтрувати пропуÑк" -#: aleksis/apps/alsijil/models.py:923 +#: aleksis/apps/alsijil/models.py:935 msgid "Can list all personal note filters" msgstr "Може бачити уÑÑ– фільтри оÑобиÑтих нотаток" @@ -632,38 +644,27 @@ msgstr "" msgid "Set time range for which documentations may be edited" msgstr "" -#: aleksis/apps/alsijil/tables.py:23 aleksis/apps/alsijil/tables.py:47 -#: aleksis/apps/alsijil/tables.py:72 +#: aleksis/apps/alsijil/tables.py:27 aleksis/apps/alsijil/tables.py:52 #: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:13 msgid "Edit" msgstr "Редагувати" -#: aleksis/apps/alsijil/tables.py:96 +#: aleksis/apps/alsijil/tables.py:76 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:348 msgid "Date" msgstr "Дата" -#: aleksis/apps/alsijil/tables.py:99 +#: aleksis/apps/alsijil/tables.py:79 #: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:30 #: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:122 msgid "Period" msgstr "Урок" -#: aleksis/apps/alsijil/tables.py:118 -#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:161 -#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:21 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:46 -#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:123 -#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323 -msgid "Tardiness" -msgstr "ЗапізненнÑ" - -#: aleksis/apps/alsijil/tables.py:119 +#: aleksis/apps/alsijil/tables.py:99 msgid "Excuse" msgstr "ПоÑÑненнÑ" -#: aleksis/apps/alsijil/tables.py:156 +#: aleksis/apps/alsijil/tables.py:136 #, fuzzy, python-brace-format #| msgid "{value}' late" msgid "{value}' tardiness" @@ -1020,17 +1021,6 @@ msgstr "" " Ðе кориÑтуйтеÑÑ Ñ†Ð¸Ð¼ Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ‚Ð¸Ð¿Ð¾Ð²Ð¾Ð³Ð¾ поÑÑÐ½ÐµÐ½Ð½Ñ Ð°Ð±Ð¾ Ñкщо не розділÑєте на типи поÑÑнень.\n" " " -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:6 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:7 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:14 -msgid "Create extra mark" -msgstr "Створити додаткову позначку" - -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:6 -#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:7 -msgid "Edit extra mark" -msgstr "Редагувати додаткову позначку" - #: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:9 #: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:16 #, python-format @@ -1563,108 +1553,111 @@ msgstr "Тиждень" msgid "Notes" msgstr "Ðотатки" -#: aleksis/apps/alsijil/views.py:114 +#: aleksis/apps/alsijil/views.py:112 msgid "You either selected an invalid lesson or there is currently no lesson in progress." msgstr "Ðбо Ви обрали неправильний урок, або зараз уроку немає." -#: aleksis/apps/alsijil/views.py:147 +#: aleksis/apps/alsijil/views.py:145 msgid "You are not allowed to create a lesson documentation for a lesson in the future." msgstr "Вам не дозволено Ñтворювати учбові матеріали Ð´Ð»Ñ ÑƒÑ€Ð¾ÐºÑƒ у майбутньому." -#: aleksis/apps/alsijil/views.py:264 +#: aleksis/apps/alsijil/views.py:262 msgid "The lesson documentation has been saved." msgstr "Учбовий матеріал збережений." -#: aleksis/apps/alsijil/views.py:298 +#: aleksis/apps/alsijil/views.py:296 msgid "The personal notes have been saved." msgstr "ОÑобиÑті нотатки збережені." -#: aleksis/apps/alsijil/views.py:658 +#: aleksis/apps/alsijil/views.py:656 #, fuzzy #| msgid "Generate printout" msgid "Generate full register printout for {}" msgstr "Підготувати Ð´Ð»Ñ Ð´Ñ€ÑƒÐºÑƒ" -#: aleksis/apps/alsijil/views.py:659 +#: aleksis/apps/alsijil/views.py:657 #, fuzzy #| msgid "Generate printout" msgid "Generate full register printout …" msgstr "Підготувати Ð´Ð»Ñ Ð´Ñ€ÑƒÐºÑƒ" -#: aleksis/apps/alsijil/views.py:660 +#: aleksis/apps/alsijil/views.py:658 #, fuzzy #| msgid "The personal note has been deleted." msgid "The printout has been generated successfully." msgstr "ОÑобиÑта нотатка видалена." -#: aleksis/apps/alsijil/views.py:661 +#: aleksis/apps/alsijil/views.py:659 msgid "There was a problem while generating the printout." msgstr "" -#: aleksis/apps/alsijil/views.py:664 +#: aleksis/apps/alsijil/views.py:662 msgid "Download PDF" msgstr "" -#: aleksis/apps/alsijil/views.py:1030 +#: aleksis/apps/alsijil/views.py:1028 msgid "The absence has been saved." msgstr "ПропуÑк збережений." -#: aleksis/apps/alsijil/views.py:1051 +#: aleksis/apps/alsijil/views.py:1049 msgid "The personal note has been deleted." msgstr "ОÑобиÑта нотатка видалена." -#: aleksis/apps/alsijil/views.py:1074 -msgid "The extra mark has been created." -msgstr "Додаткова позначка Ñторена." - -#: aleksis/apps/alsijil/views.py:1086 -msgid "The extra mark has been saved." -msgstr "Додаткова позначка збережена." - -#: aleksis/apps/alsijil/views.py:1097 -msgid "The extra mark has been deleted." -msgstr "Додаткова позначка видалена." - -#: aleksis/apps/alsijil/views.py:1119 +#: aleksis/apps/alsijil/views.py:1072 msgid "The excuse type has been created." msgstr "Тип поÑÑÐ½ÐµÐ½Ð½Ñ Ñтворений." -#: aleksis/apps/alsijil/views.py:1131 +#: aleksis/apps/alsijil/views.py:1084 msgid "The excuse type has been saved." msgstr "Тип поÑÑÐ½ÐµÐ½Ð½Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð¸Ð¹." -#: aleksis/apps/alsijil/views.py:1142 +#: aleksis/apps/alsijil/views.py:1095 msgid "The excuse type has been deleted." msgstr "Тип поÑÑÐ½ÐµÐ½Ð½Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð¸Ð¹." -#: aleksis/apps/alsijil/views.py:1164 +#: aleksis/apps/alsijil/views.py:1117 msgid "The group role has been created." msgstr "Роль групи Ñтворена." -#: aleksis/apps/alsijil/views.py:1176 +#: aleksis/apps/alsijil/views.py:1129 msgid "The group role has been saved." msgstr "Роль групи збережена." -#: aleksis/apps/alsijil/views.py:1187 +#: aleksis/apps/alsijil/views.py:1140 msgid "The group role has been deleted." msgstr "Роль групи видалена." -#: aleksis/apps/alsijil/views.py:1221 aleksis/apps/alsijil/views.py:1253 +#: aleksis/apps/alsijil/views.py:1174 aleksis/apps/alsijil/views.py:1206 msgid "The group role has been assigned." msgstr "Роль групи призначена." -#: aleksis/apps/alsijil/views.py:1272 +#: aleksis/apps/alsijil/views.py:1225 msgid "The group role assignment has been saved." msgstr "ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ€Ð¾Ð»Ñ– групи збережене." -#: aleksis/apps/alsijil/views.py:1293 +#: aleksis/apps/alsijil/views.py:1246 msgid "The group role assignment has been stopped." msgstr "ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ€Ð¾Ð»Ñ– групи зупинене." -#: aleksis/apps/alsijil/views.py:1306 +#: aleksis/apps/alsijil/views.py:1259 msgid "The group role assignment has been deleted." msgstr "ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ€Ð¾Ð»Ñ– групи видалене." +#~ msgid "Create extra mark" +#~ msgstr "Створити додаткову позначку" + +#~ msgid "Edit extra mark" +#~ msgstr "Редагувати додаткову позначку" + +#~ msgid "The extra mark has been created." +#~ msgstr "Додаткова позначка Ñторена." + +#~ msgid "The extra mark has been saved." +#~ msgstr "Додаткова позначка збережена." + +#~ msgid "The extra mark has been deleted." +#~ msgstr "Додаткова позначка видалена." + #~ msgid "Current lesson" #~ msgstr "Поточний урок" diff --git a/aleksis/apps/alsijil/migrations/0023_add_tardiness_and_rework_constraints.py b/aleksis/apps/alsijil/migrations/0023_add_tardiness_and_rework_constraints.py new file mode 100644 index 0000000000000000000000000000000000000000..3ca24f5865ddf5d3fb02acbd0aa7522bbc8bda13 --- /dev/null +++ b/aleksis/apps/alsijil/migrations/0023_add_tardiness_and_rework_constraints.py @@ -0,0 +1,67 @@ +# Generated by Django 4.2.10 on 2024-07-01 13:44 +# Updated for more custom logic + +from django.db import migrations, models + + +def forwards__unique_extra_mark_documentation(apps, schema_editor): + NewPersonalNote = apps.get_model("alsijil", "NewPersonalNote") # noqa + db_alias = schema_editor.connection.alias + + duplicates = (NewPersonalNote.objects.using(db_alias) + .values("documentation", "extra_mark", "person") + .annotate(count=models.Count("id")) + .filter(count__gt=1, extra_mark__isnull=False)) + + # Iterate over duplicates and delete the extra instances + for duplicate in duplicates: + pks = (NewPersonalNote + .objects + .using(db_alias) + .filter(person=duplicate["person"], documentation=duplicate["documentation"], extra_mark=duplicate["extra_mark"]) + .values_list("pk", flat=True) + )[1:] + NewPersonalNote.objects.using(db_alias).filter(pk__in=pks).delete() + + +def reverse__unique_extra_mark_documentation(apps, schema_editor): + # Nothing to do, we cannot bring back the deleted objects, but they were duplicate data, so they are not needed anyway. + pass + + +class Migration(migrations.Migration): + dependencies = [ + ('alsijil', '0022_documentation_participation_touched_at'), + ] + + operations = [ + migrations.RemoveConstraint( + model_name='newpersonalnote', + name='unique_absence_per_documentation', + ), + migrations.AddField( + model_name='participationstatus', + name='tardiness', + field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='Tardiness'), + ), + migrations.AlterField( + model_name='newpersonalnote', + name='note', + field=models.TextField(blank=True, default='', verbose_name='Note'), + ), + migrations.AddConstraint( + model_name='newpersonalnote', + constraint=models.CheckConstraint( + check=models.Q(models.Q(('note', ''), _negated=True), ('extra_mark__isnull', False), _connector='OR'), + name='either_note_or_extra_mark_per_note'), + ), + migrations.RunPython(forwards__unique_extra_mark_documentation, reverse__unique_extra_mark_documentation), + migrations.AddConstraint( + model_name='newpersonalnote', + constraint=models.UniqueConstraint( + condition=models.Q(('extra_mark', None), _negated=True), + fields=('person', 'documentation', 'extra_mark'), + name='unique_person_documentation_extra_mark', + violation_error_message='A person got assigned the same extra mark multiple times per documentation.'), + ), + ] diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py index 4ae5d601f9e03d8aee5462216e2d9d2a90442097..b80ac3e5271a6ff7f8709235d80bc4e0ef33c3df 100644 --- a/aleksis/apps/alsijil/models.py +++ b/aleksis/apps/alsijil/models.py @@ -8,6 +8,7 @@ from django.db import models from django.db.models import QuerySet from django.db.models.constraints import CheckConstraint from django.db.models.query_utils import Q +from django.http import HttpRequest from django.urls import reverse from django.utils import timezone from django.utils.formats import date_format @@ -529,6 +530,8 @@ class Documentation(CalendarEvent): @classmethod def get_documentations_for_events( cls, + datetime_start: datetime, + datetime_end: datetime, events: list, incomplete: Optional[bool] = False, absences_exist: Optional[bool] = False, @@ -539,18 +542,28 @@ class Documentation(CalendarEvent): """ docs = [] dummies = [] + + # Prefetch existing documentations to speed things up + existing_documentations = Documentation.objects.filter( + datetime_start__lte=datetime_end, + datetime_end__gte=datetime_start, + amends__in=[e["REFERENCE_OBJECT"] for e in events], + ).prefetch_related("participations") + for event in events: if incomplete and event["STATUS"] == "CANCELLED": continue event_reference_obj = event["REFERENCE_OBJECT"] - existing_documentations = event_reference_obj.amended_by.filter( - datetime_start=event["DTSTART"].dt, - datetime_end=event["DTEND"].dt, + existing_documentations_event = filter( + lambda d: ( + d.datetime_start == event["DTSTART"].dt and d.datetime_end == event["DTEND"].dt + ), + existing_documentations, ) - if existing_documentations.exists(): - doc = existing_documentations.first() + doc = next(existing_documentations_event, None) + if doc: if (incomplete and doc.topic) or ( absences_exist and ( @@ -585,7 +598,7 @@ class Documentation(CalendarEvent): ) ) - return (docs, dummies) + return docs, dummies @classmethod def get_documentations_for_person( @@ -601,7 +614,7 @@ class Documentation(CalendarEvent): """ event_params = { "type": "PARTICIPANT", - "obj_id": person, + "id": person, } events = LessonEvent.get_single_events( @@ -612,7 +625,7 @@ class Documentation(CalendarEvent): with_reference_object=True, ) - return Documentation.get_documentations_for_events(events, incomplete) + return Documentation.get_documentations_for_events(start, end, events, incomplete) @classmethod def parse_dummy( @@ -702,6 +715,7 @@ class Documentation(CalendarEvent): self.participation_touched_at or not self.amends or self.value_start_datetime(self) > now() + or self.amends.cancelled ): # There is no source to update from or it's too early return @@ -797,6 +811,36 @@ class ParticipationStatus(CalendarEvent): verbose_name=_("Base Absence"), ) + tardiness = models.PositiveSmallIntegerField(blank=True, null=True, verbose_name=_("Tardiness")) + + @classmethod + def get_objects( + cls, request: HttpRequest | None = None, params: dict[str, any] | None = None + ) -> QuerySet: + qs = super().get_objects(request, params).select_related("person", "absence_reason") + if params: + if params.get("person"): + qs = qs.filter(person=params["person"]) + elif params.get("persons"): + qs = qs.filter(person__in=params["persons"]) + elif params.get("group"): + qs = qs.filter(groups_of_person__in=params.get("group")) + return qs + + @classmethod + def value_title( + cls, reference_object: "ParticipationStatus", request: HttpRequest | None = None + ) -> str: + """Return the title of the calendar event.""" + return f"{reference_object.person} ({reference_object.absence_reason})" + + @classmethod + def value_description( + cls, reference_object: "ParticipationStatus", request: HttpRequest | None = None + ) -> str: + """Return the title of the calendar event.""" + return "" + def fill_from_kolego(self, kolego_absence: KolegoAbsence): """Take over data from a Kolego absence.""" self.base_absence = kolego_absence @@ -835,7 +879,7 @@ class NewPersonalNote(ExtensibleModel): null=True, ) - note = models.TextField(blank=True, verbose_name=_("Note")) + note = models.TextField(blank=True, default="", verbose_name=_("Note")) extra_mark = models.ForeignKey( ExtraMark, on_delete=models.PROTECT, blank=True, null=True, verbose_name=_("Extra Mark") ) @@ -847,9 +891,18 @@ class NewPersonalNote(ExtensibleModel): verbose_name = _("Personal Note") verbose_name_plural = _("Personal Notes") constraints = [ + # This constraint could be dropped in future scenarios models.CheckConstraint( check=~Q(note="") | Q(extra_mark__isnull=False), - name="unique_absence_per_documentation", + name="either_note_or_extra_mark_per_note", + ), + models.UniqueConstraint( + fields=["person", "documentation", "extra_mark"], + name="unique_person_documentation_extra_mark", + violation_error_message=_( + "A person got assigned the same extra mark multiple times per documentation." + ), + condition=~Q(extra_mark=None), ), ] diff --git a/aleksis/apps/alsijil/rules.py b/aleksis/apps/alsijil/rules.py index 9045598fdf362f0bedb57424fd73bb450d80d669..c1ffafbe856ffa64c91a17e3eaf062942debbe40 100644 --- a/aleksis/apps/alsijil/rules.py +++ b/aleksis/apps/alsijil/rules.py @@ -13,9 +13,11 @@ from aleksis.core.util.predicates import ( from .util.predicates import ( can_edit_documentation, can_edit_participation_status, + can_edit_personal_note, can_view_any_documentation, can_view_documentation, can_view_participation_status, + can_view_personal_note, has_lesson_group_object_perm, has_person_group_object_perm, has_personal_note_group_perm, @@ -169,19 +171,16 @@ add_perm("alsijil.view_week_personalnote_rule", view_week_personal_notes_predica # Register absence view_register_absence_predicate = has_person & ( - ( - is_person_group_owner - & is_site_preference_set("alsijil", "register_absence_as_primary_group_owner") - ) - | has_global_perm("alsijil.register_absence") + is_person_group_owner | has_global_perm("alsijil.register_absence") ) +add_perm("alsijil.view_register_absence_rule", view_register_absence_predicate) register_absence_predicate = has_person & ( - view_register_absence_predicate + is_group_owner + | has_global_perm("alsijil.register_absence") | has_object_perm("core.register_absence_person") | has_person_group_object_perm("core.register_absence_group") ) -add_perm("alsijil.view_register_absence_rule", view_register_absence_predicate) add_perm("alsijil.register_absence_rule", register_absence_predicate) # View full register for group @@ -281,6 +280,10 @@ add_perm("alsijil.delete_excusetype_rule", delete_excusetype_predicate) view_extramarks_predicate = has_person & has_global_perm("alsijil.view_extramark") add_perm("alsijil.view_extramarks_rule", view_extramarks_predicate) +# Fetch all extra marks +fetch_extramarks_predicate = has_person +add_perm("alsijil.fetch_extramarks_rule", fetch_extramarks_predicate) + # Add extra mark add_extramark_predicate = view_extramarks_predicate & has_global_perm("alsijil.add_extramark") add_perm("alsijil.add_extramark_rule", add_extramark_predicate) @@ -435,3 +438,21 @@ add_perm( "alsijil.edit_participation_status_for_documentation_rule", edit_participation_status_for_documentation_predicate, ) + +view_personal_note_predicate = has_person & ( + has_global_perm("alsijil.change_newpersonalnote") | can_view_personal_note +) +add_perm( + "alsijil.view_personal_note_rule", + view_personal_note_predicate, +) + +edit_personal_note_predicate = ( + has_person + & (has_global_perm("alsijil.change_newpersonalnote") | can_edit_personal_note) + & is_in_allowed_time_range +) +add_perm( + "alsijil.edit_personal_note_rule", + edit_personal_note_predicate, +) diff --git a/aleksis/apps/alsijil/schema/__init__.py b/aleksis/apps/alsijil/schema/__init__.py index 7ddf37b68b612aa04b552fbb4dd12e8802332028..35c0201f92bcf66b46f8e25583ea36522c7775af 100644 --- a/aleksis/apps/alsijil/schema/__init__.py +++ b/aleksis/apps/alsijil/schema/__init__.py @@ -11,16 +11,31 @@ from aleksis.apps.cursus.schema import CourseType from aleksis.core.models import Group, Person from aleksis.core.schema.base import FilterOrderList from aleksis.core.schema.group import GroupType +from aleksis.core.schema.person import PersonType from aleksis.core.util.core_helpers import has_person from ..models import Documentation +from .absences import ( + AbsencesForPersonsCreateMutation, +) from .documentation import ( DocumentationBatchCreateOrUpdateMutation, DocumentationType, LessonsForPersonType, TouchDocumentationMutation, ) +from .extra_marks import ( + ExtraMarkBatchCreateMutation, + ExtraMarkBatchDeleteMutation, + ExtraMarkBatchPatchMutation, + ExtraMarkType, +) from .participation_status import ParticipationStatusBatchPatchMutation +from .personal_note import ( + PersonalNoteBatchCreateMutation, + PersonalNoteBatchDeleteMutation, + PersonalNoteBatchPatchMutation, +) class Query(graphene.ObjectType): @@ -42,6 +57,7 @@ class Query(graphene.ObjectType): groups_by_person = FilterOrderList(GroupType, person=graphene.ID()) courses_of_person = FilterOrderList(CourseType, person=graphene.ID()) + absence_creation_persons = graphene.List(PersonType) lessons_for_persons = graphene.List( LessonsForPersonType, persons=graphene.List(graphene.ID, required=True), @@ -49,6 +65,8 @@ class Query(graphene.ObjectType): end=graphene.Date(required=True), ) + extra_marks = FilterOrderList(ExtraMarkType) + def resolve_documentations_by_course_id(root, info, course_id, **kwargs): documentations = Documentation.objects.filter( Q(course__pk=course_id) | Q(amends__course__pk=course_id) @@ -111,7 +129,11 @@ class Query(graphene.ObjectType): # Lookup or create documentations and return them all. docs, dummies = Documentation.get_documentations_for_events( - events, incomplete, absences_exist + datetime.combine(date_start, datetime.min.time()), + datetime.combine(date_end, datetime.max.time()), + events, + incomplete, + absences_exist, ) return docs + dummies @@ -126,8 +148,10 @@ class Query(graphene.ObjectType): else: raise PermissionDenied() - return Group.objects.filter( - Q(members=person) | Q(owners=person) | Q(parent_groups__owners=person) + return ( + Group.objects.for_current_school_term_or_all() + .filter(Q(members=person) | Q(owners=person) | Q(parent_groups__owners=person)) + .distinct() ) @staticmethod @@ -140,13 +164,21 @@ class Query(graphene.ObjectType): person = info.context.user.person else: raise PermissionDenied() - return Course.objects.filter( - Q(teachers=person) - | Q(groups__members=person) - | Q(groups__owners=person) - | Q(groups__parent_groups__owners=person) - ) + ( + Q(teachers=person) + | Q(groups__members=person) + | Q(groups__owners=person) + | Q(groups__parent_groups__owners=person) + ) + & Q(groups__in=Group.objects.for_current_school_term_or_all()) + ).distinct() + + @staticmethod + def resolve_absence_creation_persons(root, info, **kwargs): + if not info.context.user.has_perm("alsijil.register_absence"): + return Person.objects.filter(member_of__owners=info.context.user.person) + return Person.objects.all() @staticmethod def resolve_lessons_for_persons( @@ -166,7 +198,7 @@ class Query(graphene.ObjectType): datetime.combine(end, datetime.max.time()), ) - lessons_for_person.append(id=person, lessons=docs + dummies) + lessons_for_person.append(LessonsForPersonType(id=person, lessons=docs + dummies)) return lessons_for_person @@ -175,3 +207,12 @@ class Mutation(graphene.ObjectType): create_or_update_documentations = DocumentationBatchCreateOrUpdateMutation.Field() touch_documentation = TouchDocumentationMutation.Field() update_participation_statuses = ParticipationStatusBatchPatchMutation.Field() + create_absences_for_persons = AbsencesForPersonsCreateMutation.Field() + + create_extra_marks = ExtraMarkBatchCreateMutation.Field() + update_extra_marks = ExtraMarkBatchPatchMutation.Field() + delete_extra_marks = ExtraMarkBatchDeleteMutation.Field() + + create_personal_notes = PersonalNoteBatchCreateMutation.Field() + update_personal_notes = PersonalNoteBatchPatchMutation.Field() + delete_personal_notes = PersonalNoteBatchDeleteMutation.Field() diff --git a/aleksis/apps/alsijil/schema/absences.py b/aleksis/apps/alsijil/schema/absences.py new file mode 100644 index 0000000000000000000000000000000000000000..d05ac55214a36430808bd17ec22cc2f4c6767313 --- /dev/null +++ b/aleksis/apps/alsijil/schema/absences.py @@ -0,0 +1,59 @@ +from datetime import datetime + +from django.core.exceptions import PermissionDenied + +import graphene + +from aleksis.apps.kolego.models import Absence +from aleksis.core.models import Person + +from ..models import ParticipationStatus +from .participation_status import ParticipationStatusType + + +class AbsencesForPersonsCreateMutation(graphene.Mutation): + class Arguments: + persons = graphene.List(graphene.ID, required=True) + start = graphene.Date(required=True) + end = graphene.Date(required=True) + comment = graphene.String(required=False) + reason = graphene.ID(required=True) + + ok = graphene.Boolean() + participation_statuses = graphene.List(ParticipationStatusType) + + @classmethod + def mutate(cls, root, info, persons, start, end, comment, reason): # noqa + participation_statuses = [] + + persons = Person.objects.filter(pk__in=persons) + + for person in persons: + if not info.context.user.has_perm("alsijil.register_absence_rule", person): + raise PermissionDenied() + kolego_absence, __ = Absence.objects.get_or_create( + date_start=start, + date_end=end, + reason_id=reason, + person=person, + defaults={"comment": comment}, + ) + + events = ParticipationStatus.get_single_events( + datetime.combine(start, datetime.min.time()), + datetime.combine(end, datetime.max.time()), + None, + {"person": person}, + with_reference_object=True, + ) + + for event in events: + participation_status = event["REFERENCE_OBJECT"] + participation_status.absence_reason_id = reason + participation_status.base_absence = kolego_absence + participation_status.save() + participation_statuses.append(participation_status) + + return AbsencesForPersonsCreateMutation( + ok=True, participation_statuses=participation_statuses + ) diff --git a/aleksis/apps/alsijil/schema/documentation.py b/aleksis/apps/alsijil/schema/documentation.py index 63aecfdfc0e5115250e2e4d59c34d41c8375530e..39eed04a4a688c4c8c0aa0dc333fc02e852ab2a4 100644 --- a/aleksis/apps/alsijil/schema/documentation.py +++ b/aleksis/apps/alsijil/schema/documentation.py @@ -34,7 +34,6 @@ class DocumentationType(PermissionsTypeMixin, DjangoFilterMixin, DjangoObjectTyp "date_start", "date_end", "teachers", - "participations", ) filter_fields = { "id": ["exact", "lte", "gte"], @@ -78,7 +77,7 @@ class DocumentationType(PermissionsTypeMixin, DjangoFilterMixin, DjangoObjectTyp # A dummy documentation will not have any participations if str(root.pk).startswith("DUMMY") or not hasattr(root, "participations"): return [] - return root.participations.select_related("absence_reason", "base_absence").all() + return root.participations.all() class DocumentationInputType(graphene.InputObjectType): diff --git a/aleksis/apps/alsijil/schema/extra_marks.py b/aleksis/apps/alsijil/schema/extra_marks.py new file mode 100644 index 0000000000000000000000000000000000000000..2b1e3723d2c559e70ddd6793f5f2a89d9c1e6abe --- /dev/null +++ b/aleksis/apps/alsijil/schema/extra_marks.py @@ -0,0 +1,66 @@ +from django.core.exceptions import PermissionDenied + +from graphene_django import DjangoObjectType + +from aleksis.apps.alsijil.models import ExtraMark +from aleksis.core.schema.base import ( + BaseBatchCreateMutation, + BaseBatchDeleteMutation, + BaseBatchPatchMutation, + DjangoFilterMixin, + OptimisticResponseTypeMixin, + PermissionsTypeMixin, +) + + +class ExtraMarkType( + OptimisticResponseTypeMixin, + PermissionsTypeMixin, + DjangoFilterMixin, + DjangoObjectType, +): + class Meta: + model = ExtraMark + fields = ("id", "short_name", "name", "colour_fg", "colour_bg", "show_in_coursebook") + + @classmethod + def get_queryset(cls, queryset, info): + if info.context.user.has_perm("alsijil.fetch_extramarks_rule"): + return queryset + raise PermissionDenied() + + +class ExtraMarkBatchCreateMutation(BaseBatchCreateMutation): + class Meta: + model = ExtraMark + fields = ("short_name", "name", "colour_fg", "colour_bg", "show_in_coursebook") + optional_fields = ("name",) + + @classmethod + def check_permissions(cls, root, info, input): # noqa + if info.context.user.has_perm("alsijil.create_extramark_rule"): + return + raise PermissionDenied() + + +class ExtraMarkBatchDeleteMutation(BaseBatchDeleteMutation): + class Meta: + model = ExtraMark + + @classmethod + def check_permissions(cls, root, info, input): # noqa + if info.context.user.has_perm("alsijil.delete_extramark_rule"): + return + raise PermissionDenied() + + +class ExtraMarkBatchPatchMutation(BaseBatchPatchMutation): + class Meta: + model = ExtraMark + fields = ("id", "short_name", "name", "colour_fg", "colour_bg", "show_in_coursebook") + + @classmethod + def check_permissions(cls, root, info, input): # noqa + if info.context.user.has_perm("alsijil.edit_extramark_rule"): + return + raise PermissionDenied() diff --git a/aleksis/apps/alsijil/schema/participation_status.py b/aleksis/apps/alsijil/schema/participation_status.py index 246ae52a0aab7e7bf57f102ccd7e6558d4639496..335f5bc8d1c22682725563d2c3c83b88032fbc38 100644 --- a/aleksis/apps/alsijil/schema/participation_status.py +++ b/aleksis/apps/alsijil/schema/participation_status.py @@ -1,8 +1,10 @@ from django.core.exceptions import PermissionDenied +import graphene from graphene_django import DjangoObjectType -from aleksis.apps.alsijil.models import ParticipationStatus +from aleksis.apps.alsijil.models import NewPersonalNote, ParticipationStatus +from aleksis.apps.alsijil.schema.personal_note import PersonalNoteType from aleksis.core.schema.base import ( BaseBatchPatchMutation, DjangoFilterMixin, @@ -25,13 +27,37 @@ class ParticipationStatusType( "absence_reason", "related_documentation", "base_absence", + "tardiness", + ) + + notes_with_extra_mark = graphene.List(PersonalNoteType) + notes_with_note = graphene.List(PersonalNoteType) + + @staticmethod + def resolve_notes_with_extra_mark(root: ParticipationStatus, info, **kwargs): + return NewPersonalNote.objects.filter( + person=root.person, + documentation=root.related_documentation, + extra_mark__isnull=False, + ) + + @staticmethod + def resolve_notes_with_note(root: ParticipationStatus, info, **kwargs): + return NewPersonalNote.objects.filter( + person=root.person, + documentation=root.related_documentation, + note__isnull=False, ) class ParticipationStatusBatchPatchMutation(BaseBatchPatchMutation): class Meta: model = ParticipationStatus - fields = ("id", "absence_reason") # Only the reason can be updated after creation + fields = ( + "id", + "absence_reason", + "tardiness", + ) # Only the reason and tardiness can be updated after creation return_field_name = "participationStatuses" @classmethod diff --git a/aleksis/apps/alsijil/schema/personal_note.py b/aleksis/apps/alsijil/schema/personal_note.py new file mode 100644 index 0000000000000000000000000000000000000000..dfe36359d87345a0b51992e689627065638fcd4e --- /dev/null +++ b/aleksis/apps/alsijil/schema/personal_note.py @@ -0,0 +1,50 @@ +from graphene_django import DjangoObjectType + +from aleksis.apps.alsijil.models import NewPersonalNote +from aleksis.core.schema.base import ( + BaseBatchCreateMutation, + BaseBatchDeleteMutation, + BaseBatchPatchMutation, + DjangoFilterMixin, + OptimisticResponseTypeMixin, + PermissionsTypeMixin, +) + + +class PersonalNoteType( + OptimisticResponseTypeMixin, + PermissionsTypeMixin, + DjangoFilterMixin, + DjangoObjectType, +): + class Meta: + model = NewPersonalNote + fields = ( + "id", + "note", + "extra_mark", + ) + + +class PersonalNoteBatchCreateMutation(BaseBatchCreateMutation): + class Meta: + model = NewPersonalNote + type_name = "BatchCreatePersonalNoteInput" + return_field_name = "personalNotes" + fields = ("note", "extra_mark", "documentation", "person") + permissions = ("alsijil.edit_personal_note_rule",) + + +class PersonalNoteBatchPatchMutation(BaseBatchPatchMutation): + class Meta: + model = NewPersonalNote + type_name = "BatchPatchPersonalNoteInput" + return_field_name = "personalNotes" + fields = ("id", "note", "extra_mark", "documentation", "person") + permissions = ("alsijil.edit_personal_note_rule",) + + +class PersonalNoteBatchDeleteMutation(BaseBatchDeleteMutation): + class Meta: + model = NewPersonalNote + permissions = ("alsijil.edit_personal_note_rule",) diff --git a/aleksis/apps/alsijil/tables.py b/aleksis/apps/alsijil/tables.py index a0ef1734e5eea326fd9a8fd0f858b71a89089082..f17a214930f2d7f2e40a1662b491eab587bda0ad 100644 --- a/aleksis/apps/alsijil/tables.py +++ b/aleksis/apps/alsijil/tables.py @@ -11,26 +11,6 @@ from aleksis.core.util.tables import SelectColumn from .models import PersonalNote -class ExtraMarkTable(tables.Table): - class Meta: - attrs = {"class": "highlight"} - - name = tables.LinkColumn("edit_extra_mark", args=[A("id")]) - short_name = tables.Column() - edit = tables.LinkColumn( - "edit_extra_mark", - args=[A("id")], - text=_("Edit"), - attrs={"a": {"class": "btn-flat waves-effect waves-orange orange-text"}}, - ) - delete = tables.LinkColumn( - "delete_extra_mark", - args=[A("id")], - text=_("Delete"), - attrs={"a": {"class": "btn-flat waves-effect waves-red red-text"}}, - ) - - class ExcuseTypeTable(tables.Table): class Meta: attrs = {"class": "highlight"} diff --git a/aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html b/aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html deleted file mode 100644 index d0ee3a9055561df1f468692f79d794404a60c1d1..0000000000000000000000000000000000000000 --- a/aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html +++ /dev/null @@ -1,17 +0,0 @@ - {# -*- engine:django -*- #} - - {% extends "core/base.html" %} - {% load material_form i18n %} - - {% block browser_title %}{% blocktrans %}Create extra mark{% endblocktrans %}{% endblock %} - {% block page_title %}{% blocktrans %}Create extra mark{% endblocktrans %}{% endblock %} - - {% block content %} - - <form method="post"> - {% csrf_token %} - {% form form=form %}{% endform %} - {% include "core/partials/save_button.html" %} - </form> - - {% endblock %} diff --git a/aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html b/aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html deleted file mode 100644 index 7adee30a1cfd30256d70b2a823827384de331e05..0000000000000000000000000000000000000000 --- a/aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html +++ /dev/null @@ -1,17 +0,0 @@ -{# -*- engine:django -*- #} - -{% extends "core/base.html" %} -{% load material_form i18n %} - -{% block browser_title %}{% blocktrans %}Edit extra mark{% endblocktrans %}{% endblock %} -{% block page_title %}{% blocktrans %}Edit extra mark{% endblocktrans %}{% endblock %} - -{% block content %} - - <form method="post"> - {% csrf_token %} - {% form form=form %}{% endform %} - {% include "core/partials/save_button.html" %} - </form> - -{% endblock %} diff --git a/aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html b/aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html deleted file mode 100644 index 9eeb63b1a81162e6490072ca7184059be7a5193a..0000000000000000000000000000000000000000 --- a/aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html +++ /dev/null @@ -1,18 +0,0 @@ -{# -*- engine:django -*- #} - -{% extends "core/base.html" %} - -{% load i18n %} -{% load render_table from django_tables2 %} - -{% block browser_title %}{% blocktrans %}Extra marks{% endblocktrans %}{% endblock %} -{% block page_title %}{% blocktrans %}Extra marks{% endblocktrans %}{% endblock %} - -{% block content %} - <a class="btn green waves-effect waves-light" href="{% url 'create_extra_mark' %}"> - <i class="material-icons iconify left" data-icon="mdi:plus"></i> - {% trans "Create extra mark" %} - </a> - - {% render_table table %} -{% endblock %} diff --git a/aleksis/apps/alsijil/urls.py b/aleksis/apps/alsijil/urls.py index edc0b4fa81cfb50e1f268d9dd21b3d9dda2c033a..cd7367ce84973bb4eb62791e9ce5b2c7eb3a5f85 100644 --- a/aleksis/apps/alsijil/urls.py +++ b/aleksis/apps/alsijil/urls.py @@ -3,22 +3,6 @@ from django.urls import path from . import views urlpatterns = [ - path("extra_marks/", views.ExtraMarkListView.as_view(), name="extra_marks"), - path( - "extra_marks/create/", - views.ExtraMarkCreateView.as_view(), - name="create_extra_mark", - ), - path( - "extra_marks/<int:pk>/edit/", - views.ExtraMarkEditView.as_view(), - name="edit_extra_mark", - ), - path( - "extra_marks/<int:pk>/delete/", - views.ExtraMarkDeleteView.as_view(), - name="delete_extra_mark", - ), path("group_roles/", views.GroupRoleListView.as_view(), name="group_roles"), path("group_roles/create/", views.GroupRoleCreateView.as_view(), name="create_group_role"), path( diff --git a/aleksis/apps/alsijil/util/predicates.py b/aleksis/apps/alsijil/util/predicates.py index 9f06195e279b6e9bc9564731146d33ea7995498d..e1d8f8a02760b846d35672ffddeeb73d161ece72 100644 --- a/aleksis/apps/alsijil/util/predicates.py +++ b/aleksis/apps/alsijil/util/predicates.py @@ -12,7 +12,7 @@ from aleksis.core.models import Group, Person from aleksis.core.util.core_helpers import get_site_preferences from aleksis.core.util.predicates import check_object_permission -from ..models import Documentation, PersonalNote +from ..models import Documentation, NewPersonalNote, PersonalNote @predicate @@ -93,19 +93,14 @@ def is_group_owner(user: User, obj: Union[Group, Person]) -> bool: @predicate -def is_person_group_owner(user: User, obj: Person) -> bool: +def is_person_group_owner(user: User, obj) -> bool: """ Predicate for group owners of any group. Checks whether the person linked to the user is the owner of any group of the given person. """ - if obj: - for group in use_prefetched(obj, "member_of"): - if user.person in use_prefetched(group, "owners"): - return True - return False - return False + return Group.objects.filter(owners=user.person).exists() def use_prefetched(obj, attr): @@ -450,6 +445,8 @@ def can_edit_documentation(user: User, obj: Documentation): def can_view_participation_status(user: User, obj: Documentation): """Predicate which checks if the user is allowed to view participation for a documentation.""" if obj: + if obj.amends and obj.amends.cancelled: + return False if is_documentation_teacher(user, obj): return True if obj.amends: @@ -465,6 +462,8 @@ def can_view_participation_status(user: User, obj: Documentation): def can_edit_participation_status(user: User, obj: Documentation): """Predicate which checks if the user is allowed to edit participation for a documentation.""" if obj: + if obj.amends and obj.amends.cancelled: + return False if is_documentation_teacher(user, obj): return True if obj.amends: @@ -475,8 +474,14 @@ def can_edit_participation_status(user: User, obj: Documentation): @predicate -def is_in_allowed_time_range(user: User, obj: Documentation): - """Predicate which checks if the documentation is in the allowed time range for editing.""" +def is_in_allowed_time_range(user: User, obj: Union[Documentation, NewPersonalNote]): + """Predicate for documentations or new personal notes with linked documentation. + + Predicate which checks if the given documentation or the documentation linked + to the given NewPersonalNote is in the allowed time range for editing. + """ + if isinstance(obj, NewPersonalNote): + obj = obj.documentation if obj and ( get_site_preferences()["alsijil__allow_edit_future_documentations"] == "all" or ( @@ -498,3 +503,31 @@ def is_in_allowed_time_range_for_participation_status(user: User, obj: Documenta if obj and obj.value_start_datetime(obj) <= now(): return True return False + + +@predicate +def can_view_personal_note(user: User, obj: NewPersonalNote): + """Predicate which checks if the user is allowed to view a personal note.""" + if obj.documentation: + if is_documentation_teacher(user, obj.documentation): + return True + if obj.documentation.amends: + return is_lesson_event_teacher( + user, obj.documentation.amends + ) | is_lesson_event_group_owner(user, obj.documentation.amends) + if obj.documentation.course: + return is_course_teacher(user, obj.documentation.course) + return False + + +@predicate +def can_edit_personal_note(user: User, obj: NewPersonalNote): + """Predicate which checks if the user is allowed to edit a personal note.""" + if obj.documentation: + if is_documentation_teacher(user, obj.documentation): + return True + if obj.documentation.amends: + return is_lesson_event_teacher( + user, obj.documentation.amends + ) | is_lesson_event_group_owner(user, obj.documentation.amends) + return False diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py index dd010383b83ae7e28c6d98fd7de34bf9aa5432ba..0395a8bfbc54fcab81dfea092f431045d15ae134 100644 --- a/aleksis/apps/alsijil/views.py +++ b/aleksis/apps/alsijil/views.py @@ -48,7 +48,6 @@ from .filters import PersonalNoteFilter from .forms import ( AssignGroupRoleForm, ExcuseTypeForm, - ExtraMarkForm, FilterRegisterObjectForm, GroupRoleAssignmentEditForm, GroupRoleForm, @@ -62,7 +61,6 @@ from .forms import ( from .models import ExcuseType, ExtraMark, GroupRole, GroupRoleAssignment, PersonalNote from .tables import ( ExcuseTypeTable, - ExtraMarkTable, GroupRoleTable, PersonalNoteTable, RegisterObjectSelectTable, @@ -1052,51 +1050,6 @@ class DeletePersonalNoteView(PermissionRequiredMixin, DetailView): return redirect("overview_person", note.person.pk) -@method_decorator(pwa_cache, "dispatch") -class ExtraMarkListView(PermissionRequiredMixin, SingleTableView): - """Table of all extra marks.""" - - model = ExtraMark - table_class = ExtraMarkTable - permission_required = "alsijil.view_extramarks_rule" - template_name = "alsijil/extra_mark/list.html" - - -@method_decorator(never_cache, name="dispatch") -class ExtraMarkCreateView(PermissionRequiredMixin, AdvancedCreateView): - """Create view for extra marks.""" - - model = ExtraMark - form_class = ExtraMarkForm - permission_required = "alsijil.add_extramark_rule" - template_name = "alsijil/extra_mark/create.html" - success_url = reverse_lazy("extra_marks") - success_message = _("The extra mark has been created.") - - -@method_decorator(never_cache, name="dispatch") -class ExtraMarkEditView(PermissionRequiredMixin, AdvancedEditView): - """Edit view for extra marks.""" - - model = ExtraMark - form_class = ExtraMarkForm - permission_required = "alsijil.edit_extramark_rule" - template_name = "alsijil/extra_mark/edit.html" - success_url = reverse_lazy("extra_marks") - success_message = _("The extra mark has been saved.") - - -@method_decorator(never_cache, name="dispatch") -class ExtraMarkDeleteView(PermissionRequiredMixin, RevisionMixin, AdvancedDeleteView): - """Delete view for extra marks.""" - - model = ExtraMark - permission_required = "alsijil.delete_extramark_rule" - template_name = "core/pages/delete.html" - success_url = reverse_lazy("extra_marks") - success_message = _("The extra mark has been deleted.") - - @method_decorator(pwa_cache, "dispatch") class ExcuseTypeListView(PermissionRequiredMixin, SingleTableView): """Table of all excuse types."""