diff --git a/frontend/src/components/diary/DiaryOverviewPanels.vue b/frontend/src/components/diary/DiaryOverviewPanels.vue
index b1ba7d52..071424d4 100644
--- a/frontend/src/components/diary/DiaryOverviewPanels.vue
+++ b/frontend/src/components/diary/DiaryOverviewPanels.vue
@@ -59,7 +59,7 @@
:checked="excludeFromBilling"
@change="$emit('update:exclude-from-billing', $event.target.checked)"
/>
- Nicht abrechnen
+ {{ $t('diary.excludeFromBilling') }}
diff --git a/frontend/src/i18n/locales/de.json b/frontend/src/i18n/locales/de.json
index fc000846..c3cd7deb 100644
--- a/frontend/src/i18n/locales/de.json
+++ b/frontend/src/i18n/locales/de.json
@@ -668,6 +668,7 @@
"trainingDayChecklist": "Abschlusscheck",
"trainingStart": "Trainingsbeginn",
"trainingEnd": "Trainingsende",
+ "excludeFromBilling": "Nicht abrechnen",
"trainingWindow": "Trainingsfenster",
"trainingWindowUnset": "Noch nicht gesetzt",
"groupsLabel": "Gruppen",
diff --git a/frontend/src/i18n/locales/en-AU.json b/frontend/src/i18n/locales/en-AU.json
index 1fefde9a..6dcbd6b8 100644
--- a/frontend/src/i18n/locales/en-AU.json
+++ b/frontend/src/i18n/locales/en-AU.json
@@ -659,6 +659,7 @@
"trainingDayChecklist": "Completion checklist",
"trainingStart": "Training start",
"trainingEnd": "Training end",
+ "excludeFromBilling": "Exclude from billing",
"trainingWindow": "Training window",
"trainingWindowUnset": "Not set yet",
"groupsLabel": "Groups",
diff --git a/frontend/src/i18n/locales/en-GB.json b/frontend/src/i18n/locales/en-GB.json
index 0b67e51c..8af833d2 100644
--- a/frontend/src/i18n/locales/en-GB.json
+++ b/frontend/src/i18n/locales/en-GB.json
@@ -660,6 +660,7 @@
"trainingDayChecklist": "Completion checklist",
"trainingStart": "Training start",
"trainingEnd": "Training end",
+ "excludeFromBilling": "Exclude from billing",
"trainingWindow": "Training window",
"trainingWindowUnset": "Not set yet",
"groupsLabel": "Groups",
diff --git a/frontend/src/i18n/locales/en-US.json b/frontend/src/i18n/locales/en-US.json
index 212b91e0..669d6a61 100644
--- a/frontend/src/i18n/locales/en-US.json
+++ b/frontend/src/i18n/locales/en-US.json
@@ -660,6 +660,7 @@
"trainingDayChecklist": "Completion checklist",
"trainingStart": "Training start",
"trainingEnd": "Training end",
+ "excludeFromBilling": "Exclude from billing",
"trainingWindow": "Training window",
"trainingWindowUnset": "Not set yet",
"groupsLabel": "Groups",
diff --git a/frontend/src/views/DiaryView.vue b/frontend/src/views/DiaryView.vue
index bc4a9e2e..bec430c3 100644
--- a/frontend/src/views/DiaryView.vue
+++ b/frontend/src/views/DiaryView.vue
@@ -71,7 +71,7 @@
@@ -97,7 +97,7 @@
@update-training-times="updateTrainingTimes"
@update:training-start="trainingStart = $event"
@update:training-end="trainingEnd = $event"
- @update:exclude-from-billing="excludeFromBilling = $event"
+ @update:exclude-from-billing="updateExcludeFromBillingImmediate"
@edit-group="editGroup"
@update-group-field="updateGroupField"
@save-group="saveGroup"
@@ -1880,6 +1880,26 @@ export default {
}
},
+ async updateExcludeFromBillingImmediate(nextValue) {
+ if (!this.date?.id) {
+ this.excludeFromBilling = Boolean(nextValue);
+ return;
+ }
+ const previousValue = Boolean(this.excludeFromBilling);
+ this.excludeFromBilling = Boolean(nextValue);
+ try {
+ await apiClient.put(`/diary/${this.currentClub}`, {
+ dateId: this.date.id,
+ trainingStart: this.trainingStart || null,
+ trainingEnd: this.trainingEnd || null,
+ excludeFromBilling: this.excludeFromBilling,
+ });
+ } catch (error) {
+ this.excludeFromBilling = previousValue;
+ this.showInfo(this.$t('messages.error'), this.$t('diary.errorOccurred'), '', 'error');
+ }
+ },
+
async loadMembers() {
const response = await apiClient.get(`/clubmembers/get/${this.currentClub}/false`);
// Erstelle ein neues Array, um Vue-Reaktivität sicherzustellen
diff --git a/mobile-app/composeApp/src/androidMain/kotlin/de/tsschulz/tt_tagebuch/app/ui/AppRoot.kt b/mobile-app/composeApp/src/androidMain/kotlin/de/tsschulz/tt_tagebuch/app/ui/AppRoot.kt
index 02cdf60b..ba3893a4 100644
--- a/mobile-app/composeApp/src/androidMain/kotlin/de/tsschulz/tt_tagebuch/app/ui/AppRoot.kt
+++ b/mobile-app/composeApp/src/androidMain/kotlin/de/tsschulz/tt_tagebuch/app/ui/AppRoot.kt
@@ -1932,7 +1932,7 @@ private fun DiaryListScreen(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
) {
- Text("Nicht abrechnen")
+ Text(tr("diary.excludeFromBilling", "Nicht abrechnen"))
Switch(
checked = newDiaryExcludeFromBilling,
onCheckedChange = { newDiaryExcludeFromBilling = it },
@@ -2794,7 +2794,13 @@ private fun DiaryDetailScreen(
initialStart = entry.trainingStart.orEmpty(),
initialEnd = entry.trainingEnd.orEmpty(),
initialExcludeFromBilling = entry.excludeFromBilling,
+ excludeFromBillingLabel = tr("diary.excludeFromBilling", "Nicht abrechnen"),
submitLabel = tr("common.save", "Speichern"),
+ onExcludeFromBillingChange = { _, start, end, excludeFromBilling ->
+ dependencies.applicationScope.launch {
+ dependencies.diaryManager.updateTimes(clubId, entry.id, start, end, excludeFromBilling)
+ }
+ },
onSubmit = { _, start, end, excludeFromBilling ->
dependencies.applicationScope.launch {
dependencies.diaryManager.updateTimes(clubId, entry.id, start, end, excludeFromBilling)
@@ -6897,6 +6903,8 @@ private fun DeleteAccountDialog(
@Composable
private fun DiaryEditForm(
submitLabel: String,
+ excludeFromBillingLabel: String,
+ onExcludeFromBillingChange: ((date: String, trainingStart: String?, trainingEnd: String?, excludeFromBilling: Boolean) -> Unit)? = null,
onSubmit: (date: String, trainingStart: String?, trainingEnd: String?, excludeFromBilling: Boolean) -> Unit,
initialDate: String = "",
initialStart: String = "",
@@ -6921,10 +6929,18 @@ private fun DiaryEditForm(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
) {
- Text("Nicht abrechnen")
+ Text(excludeFromBillingLabel)
Switch(
checked = excludeFromBilling,
- onCheckedChange = { excludeFromBilling = it },
+ onCheckedChange = {
+ excludeFromBilling = it
+ onExcludeFromBillingChange?.invoke(
+ date,
+ start.takeIf { value -> value.isNotBlank() },
+ end.takeIf { value -> value.isNotBlank() },
+ excludeFromBilling,
+ )
+ },
)
}
ErrorText(error)